首页
/ DeerFlow Maintainer Orchestrator:基于“评论面”安全模型的 GitHub Issue/PR 分诊与评审 Agent 技能

DeerFlow Maintainer Orchestrator:基于“评论面”安全模型的 GitHub Issue/PR 分诊与评审 Agent 技能

2026-09-03 15:32:51作者:江焘钦

本文基于 DeerFlow 仓库中 deerflow-maintainer-orchestrator 技能契约 及其设计说明文档 展开,完整讲解这一维护者专用 Agent 技能如何把一组 Issue/PR 的分诊范围,通过固定工作流转化为有证据支撑的评论:涵盖 GitHub 工件解析命令、Issue 评论模板、PR 评审的 Diff 基准规则、置信度/严重度双轴发布闸门、批量聚合与竞争 PR 对比机制,以及 DeerFlow 特有的审查启发式与验证命令矩阵。读完本文,你可以直接运行该技能完成维护者级分诊,也可以复用其“评论面 + 双轴闸门 + 幂等重跑”的设计模式为自己项目搭建类似的 Issue/PR 自动分诊能力。

1. 技能定位:把分诊收敛到“评论面”

该技能是 DeerFlow 仓库 .agent/skills/ 目录下的一个 Agent 技能(Skill),与 smoke-testblocking-io-guardengineer-system-change 并列,面向维护者和受信本地 Agent,而非普通贡献者。其 frontmatter 声明了触发场景:当维护者需要“仅评论”地处理 GitHub Issue 或 PR 时使用——解析范围、分析、发布或起草 Issue 评论、执行 PR 评审、对比针对同一 Issue 的竞争性 PR、给出修复策略、风险分级与验证指引。

技能的第一条核心规则(SKILL.md 第 8-10 行)划定了它的能力边界:

这是一个评论面(comment-plane)技能:解析 GitHub 范围、检视证据、准备或发布 DeerFlow 的 Issue 评论与 PR 评审评论。工作必须停留在评论范围内;不得扩展为写代码、分支管理、发布操作、制品关闭或其他维护者操作。

设计文档(maintainer-orchestrator-design.md 第 17-21 行)解释了这是刻意设计的信任边界:评论是 Agent 能在仓库上执行的风险最低、最可逆的动作——错误的评论代价是一条更正,而错误的合并、force-push 或发布代价大得多。正是“只碰评论面”这一点,使得该技能可以安全地批处理真实 PR 而不必对每一步做不可逆风险审计。其目标被明确表述为“杠杆,而非自主性”:维护者仍拥有每个关键决策,技能负责跑腿,并在每条评论内部给出具体、可辩护的建议。

两条运行约定同样重要:

  • 无追问授权:当维护者要求处理/评论/评审一个有界集合时,视为对“每个入选 Issue 一条公开评论、每个有高置信发现的 PR 一条评审评论”的授权,直接执行、不再追问(第 12 行)。维护者与技能的标准交互是:给范围 → 收到已发布评论 URL、PR 评审 URL、干净结果、跳过项、失败项或草稿。
  • 语言跟随制品:中文 Issue/PR 用中文输出,英文用英文输出;混合制品以正文语言为准,而不是以日志或代码为准。

2. 工件解析(Artifact Resolution):12 条固定规则

技能不依赖维护者澄清,而是用 GitHub 工具链(gh CLI 与 GitHub API)自行解析工件类型与范围。SKILL.md 第 20-39 行 给出了 12 条规则,完整继承如下:

  1. 默认仓库为 bytedance/deer-flow,除非 URL 或显式仓库名另有说明;
  2. URL 路由:/issues/<number> 走 Issue Flow,/pull/<number> 走 PR Review Flow;
  3. 带类型的编号使用对应命令:
    • Issue:gh issue view <number> --repo <repo> --json number,title,url,state,body,labels,author,comments
    • PR:gh pr view <number> --repo <repo> --json number,title,url,state,body,author,files,comments,reviews,statusCheckRollup,baseRefName,headRefName
  4. 多个显式引用(#123# 123、裸 123)归一化为编号列表,保序并去重;
  5. 未带类型的编号先试 gh pr view ... --json number,url,失败再试 gh issue view ... --json number,url——不问维护者这是什么类型;
  6. Issue 批量用 gh issue list(而非 GitHub 混合 issues 端点),PR 批量用 gh pr list
  7. 尊重维护者给定的数量或时间窗,没有硬性 5 条上限;范围过宽且欠明确时,自行选取一个务实的近期切片、声明所用切片、按“最新 + 最高风险”排序,并汇报未处理的剩余部分;
  8. “recent/latest” 无数量时用小默认近期切片,“recent hours” 无数字时默认 6 小时,均不追问;
  9. 需要 timeline 事件、review threads 或精确搜索过滤等 view/list 缺少的字段时,用 gh api
  10. GitHub 搜索仅作为无法用 view/list/API 表达的自然语言过滤条件的兜底;GitHub 工具可用时不用 web 搜索做工件路由;
  11. 一个 Issue 存在多个候选解决 PR 时,先收集全部候选再评审:Issue 的 linked/Development PR、通过 gh api timeline cross-reference 事件找到的关闭关键字(Closes/Fixes #<issue>)、以及提及该 Issue 的 PR,然后进入竞争 PR 对比流程;
  12. 若类型、编号、URL、数量、时间窗或可搜索的 GitHub 范围均无法解析,输出精简的 “scope unresolved” 报告并停止,不追问。

报告与评论中的引用约定:维护者报告和评论里用简洁的仓库内引用(#123PR #123);完整 GitHub URL 只出现在 GitHub 返回的已发布评论/评审链接,或维护者显式提供的 URL 中。

3. 既有覆盖与重跑:压制重复发布,不压制分析

这是该技能幂等性的核心(第 41-52 行):既有评论压制的是重复“发布”,不是重复“分析”。完整流程每次都必须做:

  1. 把既有维护者/受信 Agent 的评论与评审读作“先验覆盖”;
  2. 无论已有什么,都完整分析该制品——先前的评论可能只抓到 A、漏了 B;
  3. 只保留未被子质性覆盖的净新增(net-new)、高置信条目;
  4. 净增量非空:发布一条明确构建在先验覆盖之上的评论(例如以 Adding to @reviewer's review: 开头),只陈述新条目,不复述已覆盖内容;
  5. 净增量为空:不发布任何公开内容,向维护者报告 Already covered 并附既有评论/评审 URL;
  6. 幂等性:把自己早先以技能身份发布的评论视为已覆盖。重跑时绝不叠加重复的第二条评论——只发真正的新增量,或者什么都不发。

唯一硬性跳过的类别是 RFC Issue:除非维护者显式覆盖,否则不分析、不发布。

4. Issue Flow:前置检查、双维分类与评论模板

Issue Flow 适用于 GitHub issues、bug 报告、feature request、支持类问题与 issue 批量。每个 Issue 先做廉价前置检查(第 54-64 行):拉取元数据、标签、作者、正文与既有评论;若标签/标题/正文标记为 RFC(rfc[RFC]RFC:Request for Comments),归类为 rfc-no-comment,跳过深度分析,除非维护者显式覆盖;既有维护者/受信 Agent 评论是先验覆盖而非自动跳过;普通报告者回复、致谢、无关讨论、不完整猜测一律视为非阻塞;已覆盖或跳过的 Issue 只以“紧凑标识符 + 原因或既有评论 URL”上报维护者。

4.1 面向:9 类表面(Surface)分类

对不跳过的 Issue,先读足上下文(正文、评论、截图、日志、复现细节、关联制品、相关 DeerFlow 代码与文档)再分类表面:

  • Frontend UI
  • Backend API
  • Agents / LangGraph
  • Sandbox
  • Skills
  • MCP
  • Dependencies
  • Default behavior
  • Docs / tests / CI only

4.2 可操作性(Actionability)分类

  • ready-to-fix:边界清晰、证据充分、验证路径明确;
  • needs-more-evidence:缺少复现、日志、环境、截图、精确的预期行为或失败用例;
  • defer-or-close:重复、过期、不支持、不可操作或超出范围;
  • rfc-no-comment:RFC Issue,默认跳过公开评论。

4.3 公开评论模板与措辞约束

评论从分析结果生成,而不是从分类标签生成(第 84-105 行)。措辞约束相当细:

  • 以一个自然的开场句连接 Issue 上下文;对报告者本人发起的 Issue,若读起来自然,优先 Thanks @author.;对 bot、维护者自建的跟踪 Issue 或会显得多余的场景省略提及;
  • 开场句必须对“下一步或边界”说点具体的,禁止泛化措辞,如 "This is actionable"、"I would treat this as"、"ready to fix",也禁止直接暴露 surface/actionability/risk 标签。

最小稳定模板:

Thanks @author. <one specific sentence that frames the fix, investigation, or missing evidence.>

Recommended solution:
- ...

Validation:
- ...

按需追加的可选段:

  • Evidence: 仅在引用具体代码、日志、复现细节等证据有助于作者行动时追加;
  • Risk: 仅在架构、安全、公共 API、默认行为或兼容性影响必须显式指出时追加,且风险必须具体;
  • Missing info: 仅在缺少证据无法诊断时追加,且只索取最小的有用数据;
  • 相关文件/组件写进 Evidence:Recommended solution: 的条目里,不单列元数据字段;
  • 除非唯一有用的回应就是 Missing info:,每条已发布的 Issue 评论都应包含具体修改指引与验证指引

发布前还有一道即时校验:发布前的最后一刻刷新评论,把分析期间新出现的等价评论并入先验覆盖,只发布剩余增量;获得发布授权时发布一条,否则以 Reply draft 返回同样文本。红线:不暴露私有推理、凭据、内部上下文,不做未支持的承诺;若没有独立编码工作流真正改过代码,不得声称“已修复”。

5. PR Review Flow:前置检查、Diff 基准规则与发现模板

PR Review Flow 适用于 PR 与 PR 批量。前置检查(第 109-119 行):拉取 PR 元数据、变更文件列表、checks 摘要、既有评审与评审线程;既有维护者/受信 Agent 评审是先验覆盖,不是自动跳过。

一个关键立场:statusCheckRollup 读作信号而非判决。失败的必选检查本身就是可报告发现(构建失败 = P0;测试或 lint 失败按影响定 P1/P2);全绿检查降低风险,但绝不豁免阅读实际变更代码路径——可疑逻辑要靠读源码确认,而不是信任绿色 CI;测试通过不证明变更分支被实际执行。

5.1 Diff 基准规则(Diff Base Rule)

评审本地 PR 分支或本地 diff 前,必须先获取基仓库的目标分支,对照新鲜的远端跟踪 ref 比较,而不是可能过期的本地 main第 121-133 行)。完整规则:

  • fork 检出时,若 upstream 指向基仓库,优先 upstream/<base-branch>
  • 直接上游检出时,用基远端已拉取的分支,通常是 origin/<base-branch>
  • 目标分支优先取 GitHub PR 的 base 元数据;非 PR 本地 diff 用基仓库默认分支;元数据不可用时,仅在拉取基远端后才默认 main
  • 显式刷新比较 ref,例如:
git fetch <base-remote> +refs/heads/<base-branch>:refs/remotes/<base-remote>/<base-branch>
BASE=$(git merge-base HEAD <base-remote>/<base-branch>)
git diff "$BASE"...HEAD
  • 若改用单分支拉取产生的 FETCH_HEAD,必须立刻对照该已验证的 FETCH_HEAD 做 diff,之后不得再替换成可能过期的远端跟踪 ref;
  • fork PR 的 head 分支不在基仓库上,必须显式拉取 PR ref:git fetch <base-remote> pull/<n>/head:pr-<n>(fork 自身分支 ref 和 gh api .../contents?ref=<fork-branch> 对基仓库会 404);记录被评审的 head SHA;
  • 发布前再次核对 head SHA:若分析期间 PR head 前移,必须对新 diff 重新评审或放弃——绝不发布一条针对 PR 已不再拥有的 diff 的评审;
  • 未提交的本地变更:先对照新鲜 base 评审已提交的分支变更,再单独纳入工作区变更;
  • 若基远端或基分支无法确立,以 GitHub PR 的 files/diff 为准;本地与 GitHub diff 都读不到时,返回紧凑失败报告且不发布评审。

5.2 发现(Finding)模板与严重度

发布评审评论前的七条检查:只评审相对新鲜 base 的当前 diff 与变更文件,除非 diff 使其新近存在风险,否则不评论无关既有代码;不报告低置信猜测,证据不足直接省略;正确性、安全性、可维护性、生产风险、兼容性、关键测试缺失优先于风格;当 diff 造成或暴露时,把具体的架构、安全、公共 API、默认行为、兼容性问题作为发现上报;检查变更行为、边界情况、错误路径、状态变更、事务、锁、缓存失效、清理、安全边界、缺失测试、性能/可靠性与 API 兼容性;发布前最后刷新评审/评论并折入期间新出现的等价评审;最后应用发布闸门。

每个发现的固定格式:

[P0/P1/P2] Title

- Location: file and line/range
- Problem: what can go wrong
- Evidence: why the diff causes it
- Suggested fix: concrete minimal fix
- Test: what test should cover it

严重度定义:

  • P0:导致宕机、数据丢失、安全漏洞或构建失败;
  • P1:高概率生产 bug、严重回归、破坏兼容性,或高风险安全/架构问题;
  • P2:正确性、可维护性或测试层面的较低风险问题。

公开 PR 评审的开场句要与发现数量一致:恰好一条用单数(Thanks @author. I found one issue that should be addressed before this is ready.),多条用复数(...I found a few issues...);对 bot 或会显得多余的场合省略提及。

5.3 发布闸门(Posting Gate)

发布同时取决于置信度(问题是否真实?)与严重度(若真实有多严重?)两个独立轴第 165-174 行):

  • 只有高置信且至少 P2 的条目可公开发布;“没有高置信发现”指 P0/P1/P2 全没有,而不是“没有 P0”;
  • 公开 P2 还多一道守卫:diff 本身必须引入或恶化了该问题——不对“diff 只是碰到”的既有行为说教,也不对相对旧状态是净改进的变更提公开 P2;
  • 高置信的 P0/P1 永远值得发布;低置信的 P1 不值得——省略,或作为待验证假设路由到 Maintainer notes
  • 低于门槛但真实的观察(净改进级小问题、有界/低风险关注、既有问题、低置信假设)一律进运行结果中的 Maintainer notes 通道,永不进公开评论。

设计文档将其概括为“刻意很高的门槛”:公开评审噪音腐蚀信任的速度快于偶发漏掉一个小问题。此外:不写溢美之词、不做总结、不给泛泛建议;涉及安全的敏感问题只描述影响与修复,不给利用步骤。

6. 批量处理与竞争 PR 对比

6.1 按相关性聚类,不按类型

多工件范围必须先聚类、后评审、再综合(第 176-189 行)。聚类依据是相关性而非类型:共享文件、接口或同一 issue/feature 的制品归为一个簇;同类型但触碰不相交文件的制品相互独立。

  • 相关簇:必须在一个共享上下文中评审,使跨制品推理成为可能——并行 Agent 互相看不到对方的发现。若装不进一个上下文,按子组扇出、在综合阶段对账;绝不允许没有再聚合就盲目拆分;
  • 独立簇:可以并行。把大型或独立批次按簇各交给一个子 Agent 能保持主上下文干净——大批次时优先考虑,且优先向维护者提议而非静默启动;两三个相关项、或冷启动成本不划算时不启动子 Agent。

每工件评审之后,对整个批次跑一次综合(synthesis)pass,仅向维护者报告(决策支持,不是公开评论),覆盖三点:

  • 重叠文件与合并顺序/冲突面——哪些 PR 触碰相同文件、会两两冲突;
  • 对同一问题的重复或竞争性解决方案;
  • 组合风险——各自单独安全的变更相互作用后不安全(例如两个 PR 编辑同一模块或同一张表)。

设计文档对此的原则是:“孤立地评审相关 PR,就是修好一个、弄坏另一个的典型方式。”

6.2 竞争 PR 对比

多个 PR 指向同一 Issue 时,对比着审,而不是逐个孤立审:

  1. 取 Issue 的验收标准(报告的问题与预期行为)作为评分锚点;
  2. 每个 PR 按以下维度打分:是否真正解决 Issue 诉求;正确性与边界/错误路径覆盖;测试质量;爆炸半径与兼容性;可维护性。评分使用与单次评审相同的 DeerFlow 审查启发式与发布闸门;
  3. 向维护者输出对比报告——最强 PR 及原因、各自缺什么;
  4. 公开面保持建设性且逐 PR 独立:每个 PR 照常发布自身过闸门的发现;不公开给 PR 排名,不告诉作者“你的 PR 比竞争对手差”——胜出者选择只留在维护者报告里。

7. 无追问策略(No-Question Policy)

技能通过固定工作流把范围变成评论,从而为节省维护者时间而设计,不做例行澄清提问。仅在以下四种情况停止且不追问:URL、编号、gh view/list、gh api 或 GitHub 搜索兜底都解析不出 issue/PR 范围;GitHub 认证、仓库访问或评论发布失败;请求的动作超出仅评论范围;发布需要私有凭据、私有安全细节或非公开上下文。这些情况下返回一份紧凑失败报告,包含尝试过的命令路径与最小下一步动作——除非维护者明确要求被提问,否则不以问句形式表达。

8. DeerFlow 审查启发式:高信号审查区域

这些是 Issue 评论与 PR 发现的高信号区域(第 213-223 行),每一条都能在仓库中找到实体对应:

  • backend/packages/harness/deerflow/ 不得导入 app.*——仓库中确实存在该包目录 backend/packages/harness/deerflow/,且有一条专门守护此边界的测试 backend/tests/test_harness_boundary.py
  • App 可以依赖 harness,harness 必须保持可发布、与 app 无关(app-agnostic);
  • 前端 thread/message 行为与 Gateway/LangGraph 兼容的 SSE 是契约面(contract surfaces);
  • 沙箱权限、bash/文件写入工具、技能安装与远程执行是安全敏感区;
  • 默认模型/provider 行为、配置迁移、持久化 schema、公共 API/SSE、LangGraph thread/run 生命周期是兼容性敏感区;
  • 运行时文档应跟随面向用户或开发者的行为变化同步更新;
  • 安全敏感评论必须给出证明与修复路径,而非模糊断言。

值得注意的是刻意不做的事:设计文档指出,阻塞 IO(event loop 上的 blocking IO)检测由 CI 的 blocking-IO 门禁与专门的 blocking-io-guard 技能负责(仓库中有对应的 backend/tests/blocking_io/ 测试目录与 backend/docs/BLOCKING_IO_DETECTION.md 文档),因此本技能的启发式刻意不重复覆盖——关注点分离让每个工具保持锋利。

9. 验证指引矩阵:按触碰面推荐检查

评论中的验证指引按触碰的代码面给出(第 225-238 行),完整矩阵如下:

表面 建议验证
Backend API / harness / agents / MCP / skills runtime cd backend && make lint && make test
Blocking IO 或异步文件/网络工作 cd backend && make test-blocking-io 或聚焦的 blocking-IO 回归
Harness/app 边界 cd backend && uv run pytest tests/test_harness_boundary.py
Frontend UI/core cd frontend && pnpm format && pnpm lint && pnpm typecheck && BETTER_AUTH_SECRET=local-dev-secret pnpm build && make test
前后端 thread 或 SSE 契约 可行的话跑 backend replay golden 与全栈 replay 渲染
前端用户工作流 Playwright E2E 或带截图/DOM 断言的浏览器证明
Docker/sandbox/provisioner 聚焦的 backend 测试,可行的话加 Docker/provisioner 冒烟
仅文档 定向 markdown 审查

这些命令与仓库实际工具链一致:后端 backend/Makefile 定义了 linttest(默认排除 live 标记并忽略 tests/blocking_io)、test-blocking-io(运行 pytest tests/blocking_io)等目标;前端 frontend/package.json 的 scripts 中 format(prettier --check)、lint(eslint)、typecheck(tsc --noEmit)、test(rstest)、build(next build)与矩阵中的 pnpm 命令一一对应,前端 frontend/Makefile 也提供 test/lint/format 目标。

10. 运行结果输出格式

技能只输出维护者运行结果或评论草稿,不主动宣告技能名、模式或“没有改代码”(除非维护者询问流程细节)。

Issue Flow 的结果模板:

Run result:
Posted:
Skipped:
Already covered:
Failed:
Maintainer notes:
Per issue:
  Issue:
  Surface:
  Actionability:
  Risk:
  Comment:
  Validation:
  Comment status:

PR Review Flow 的结果模板:

Run result:
Reviewed:
Skipped:
Clean:
Already covered:
Failed:
Maintainer notes:
Per PR:
  PR:
  Public review:
  Findings:
  Review status:

仅分析(analysis-only)请求把 Posted/Reviewed 替换为 Drafted,并附带未发布的评论/评审文本。批量结果在头条计数之后优先给一张紧凑的维护者视角表格:

| Artifact | Status | Public action | Notes |
| --- | --- | --- | --- |
| #123 | posted | comment URL | short reason |
| PR #456 | reviewed | review URL | P1: finding title |
| PR #789 | clean | none | No high-confidence review findings. |
| #321 | already covered | none | existing maintainer comment |

多工件批次在表格之后追加 Batch synthesis 块(重叠文件、合并顺序/冲突面、重复或竞争性解决方案、组合风险)与(如 Issue 存在竞争 PR 时)Competing PR comparison 块,二者均仅面向维护者。空类别、无操作字段、例行命令输出与原始日志一律省略;只报告有意义的变化、证据与选项。

11. 设计原理与复用建议

设计文档 声明自己不是规则参考——精确的解析命令、评论模板、严重度定义与验证矩阵都在 SKILL.md 中,后者是权威可执行契约;两者不一致时以技能为准。它提炼的四条审查原则值得单独强调:

  • 证据优先于绿色勾:CI 状态是信号不是判决;全绿绝不豁免读变更代码路径,失败的必选检查本身就是发现;
  • 评审正确的 diff:发现的可靠性取决于它所对照的 diff。对照新鲜拉取的 base 而非过期本地分支,显式解析 fork PR 的 head,记录被评审的 head SHA 并在发布前复核——“针对一个 PR 已不再拥有的 diff 发布的评审,比不评审更糟”;
  • 按批次推理,而非仅按工件:相关 PR 聚簇、单上下文评审,综合 pass 报告跨 PR 交互;
  • 公平对比竞争 PR:以 Issue 验收标准为评分基准,排名只给维护者,公开面保持逐 PR、建设性。

若要为自己的项目复用这一模式,设计文档给出三个可迁移的关键选择(第 61-67 行):

  1. 在建立信任之前,把 Agent 留在可逆表面(评论)上——可逆性正是它能无人值守运行的原因;
  2. 置信度 + 严重度双轴共同闸门公开输出,低于门槛的一切走私有通道——什么都发的评审者会很快被静音;
  3. 让 Agent 在开口之前证明自己评审的是当前 diff

其余部分——表面分类、严重度标签、验证命令、输出格式——是项目特定的,应写进技能本身,而不是写进设计文档。

12. 如何运行该技能

维护者只需给出范围:issue 或 PR 编号、URL、数量或时间窗。技能用 GitHub 工具链解析工件,返回已发布的评论/评审 URL、干净结果、已覆盖说明、仅维护者可见的 notes、批次综合,或在仅分析模式下返回发布前可供审阅的草稿。它不做例行澄清提问,只在范围真正无法解析、访问失败、请求超出仅评论范围、或发布需要非公开上下文时停止并报告。输出语言跟随制品:中文 Issue/PR 得到中文评论,英文得到英文评论。

适用前提与限制:该技能面向维护者与受信本地 Agent,依赖可用的 gh 认证与目标仓库访问权限;默认仓库为 bytedance/deer-flow;它不修改任何代码或仓库状态,全部公开动作限于 Issue 评论与 PR 评审评论两类。仓库中可查看的完整契约见 .agent/skills/deerflow-maintainer-orchestrator/SKILL.md,设计背景见 docs/agents/maintainer-orchestrator-design.md,同目录下的 smoke-testblocking-io-guardengineer-system-change 展示了 DeerFlow 技能体系中“部署验证、静态门禁、系统变更决策”等互补能力,可作为延伸阅读。

登录后查看全文
热门项目推荐
相关项目推荐