首页
/ 基于 Issue 与 PR 合成「Golden Workable Spec」:Gemini CLI caretaker-agent 分诊评测的黄金基准生成方法论

基于 Issue 与 PR 合成「Golden Workable Spec」:Gemini CLI caretaker-agent 分诊评测的黄金基准生成方法论

2026-09-06 18:04:26作者:魏侃纯Zoe

导读:本文围绕 tools/caretaker-agent 评测体系中的一份核心 System Prompt 规格 —— generate_golden_spec.md 展开。它定义了一种从真实 GitHub Issue + 关联 PR diff 合成 高保真、公平(fair)的 Golden Workable Spec JSON 的两阶段推理流程,是自动分诊机器人(triage worker)评测基准中「真值/黄金答案」的生成依据。读完本文,你将掌握这套方法的公平性剪枝规则、Workable Spec 合成的七条硬性约束、输出 JSON 结构,以及它如何被 Python 编排器加载、schema 校验并接入评测跑批全链路。

一、文档定位:它不是写给人类看的 README,而是一份「模型系统提示词」

这份文件名为 Golden Workable Spec Generator System Instructions,从字面与用途上都很特殊——它是一份面向 LLM Agent 的系统指令规格,由评测链路中负责生成黄金基准的合成器(spec synthesizer)直接加载并作为 system instruction 使用。

从仓库结构看,tools/caretaker-agent/evals/triage/ 下包含一整套针对「Gemini CLI Issue 分诊 Worker」的评测套件:

其中 generate_golden_spec.py 第 29 行将本 md 定义为 PROMPT_FILE,并在第 49-54 行将其整体读入作为系统指令;随后用 LocalAgentConfig(system_instructions=system_instruction, ...) 构造 Agent 上下文。因此,本文件的实际读者是运行在评测流水线中的合成器 Agent,它的最终交付物是一份可直接落盘为基准真值的 JSON 对象,外加一份公平性说明 golden_spec_rationale

二、两阶段强制推理流程(REQUIRED REASONING WORKFLOW)

文档要求合成器在输出最终 JSON 之前,必须严格执行两阶段推理,这是保证黄金基准「100% 公平、高精度」的前提。

阶段一:PR 文件与修复点分析(PR File & Fix Analysis)

先通读 PR 标题(title)、PR 正文(body)与代码 diff,识别本次 PR diff 中改动的每一个文件,以及每个文件内部的具体改动(改了什么逻辑、新增了什么常量、调整了哪条正则等)。这一阶段的目标是建立「改动清单」,为下一阶段的甄别提供素材。

阶段二:公平性剪枝通道(Fairness Pruning Pass,基准公平性的关键)

阶段二要求对 PR diff 中修改的每一个文件,逐一回到原始 Issue 描述进行交叉比对,并对每个文件回答两个问题:

  1. 「这个文件是解决用户在 Issue 文本中报告的症状所严格必需(strictly required)的吗?」
  2. 「还是说,这是 PR 作者顺手夹带的次要重构(secondary refactoring)、未被报告的扩展功能(un-reported feature extension),或内部架构清理(internal architecture cleanup)?」

由此导出文档中的严格剪枝规则(STRICT PRUNING RULE)

必须把所有「次要重构类文件」从 files_to_modify 中剪掉;只保留直接负责解决所报告 Bug 的主目标源码文件

这条规则在工程语义上非常关键:人类提交的 PR 往往混入了与 Issue 无关的额外改动,而评测基准的目标是检验分诊 Agent 能否像「理想的、最小化的修理工」一样定位病灶。如果基准把夹带文件也当作答案的一部分,就会诱导 Agent 输出过度扩散、不可落地的修改清单,降低基准的诊断精度与可执行性。

三、Workable Spec 合成的五条硬性规则

在推理完成之后,合成器需要依据以下规则把结论组织进 JSON。这五条共同定义了「什么是高质量、无手挥(no hand-waving)的可执行规格」。

1. 黄金规格理由(golden_spec_rationale)只谈「被剪掉的文件」,不谈显而易见的规则

理由文本必须严格聚焦于:哪些源文件被从 files_to_modify剪除了、以及为什么。例如:若 PR diff 中夹带了次要重构、未报告的功能扩展或内部架构清理,就要逐一写出被剪文件名并解释为何出于基准公平性将其排除;若没有任何源文件被剪除,则应明确陈述:

"No source files were pruned; all PR modifications directly address the reported issue."

同时文档特别要求不要复述显而易见的规则(例如「测试文件被排除在 files_to_modify 之外」这类常识),理由只应聚焦于非显而易见的剪枝决策。换言之,golden_spec_rationale 的价值在于解释「那些看起来像源码、实际上属于范围外的东西」,而非照抄排除清单。

2. 只允许源码文件(Source Files Only)

workable_spec 内的 files_to_modify 必须且只能包含主源码文件,严格排除:

  • 测试文件(如 *.test.ts);
  • 锁文件(package-lock.jsonyarn.lockpnpm-lock.yaml);
  • 文档类 Markdown;
  • 版本号 bump 文件。

测试文件唯一的归宿是 testing_strategy.test_file 字段。这条规则与 generate_golden_spec.py 第 65-78 行的 diff 预处理逻辑相互呼应——该模块在把 diff 拼进 prompt 前,会逐行丢弃命中 package-lock.json / yarn.lock / pnpm-lock.yamldiff --git 文件块,从源头减少噪声输入。

3. 测试文件落地(Test File Grounding)

  • 若 PR diff 修改或新建了自动化测试文件,则将 testing_strategy.test_file 设置为该精确路径
  • 若 PR diff 没有触碰任何自动化测试文件,则 testing_strategy.test_file 必须严格写为 "N/A"

4. 具体命名(Concrete Names,如适用)

summary.root_causeimplementation_plan.steps 必须引用修复所涉及的具体函数名、正则表达式、常量或数据结构。文档明确禁止“约等于手挥”的写法,如 "update the code as needed""fix the logic""adjust accordingly" —— 每一步都必须给出明确、无歧义的技术指引。

5. 禁止手挥(No Hand-Waving)

与第 4 条一体两面:含糊、泛化、无法被代码生成器直接执行的表述都属于不合格内容。Workable Spec 的最终消费者(分诊修复 Agent / 评测器)依赖步骤清单去评估“能否照做”,因此文字越具体,基准越可靠。

四、输出 JSON 模板与字段语义

合成器的最终响应必须是严格匹配下列结构的裸 JSON 对象,且不得包裹在 Markdown 代码块中(该约束本身是写给 Agent 的行为要求):

{
  "golden_spec_rationale": "Focus strictly on what source files were PRUNED and why (or state 'No source files were pruned; all PR modifications directly address the reported issue').",
  "workable_spec": {
    "issue_id": "{owner}/{repo}#{issue_number}",
    "summary": {
      "problem": "Concise statement of reported problem strictly matching the issue description.",
      "root_cause": "Analysis of root cause referencing specific functions/regexes modified in the PR diff if applicable.",
      "context": "Additional technical context from issue and PR."
    },
    "implementation_plan": {
      "files_to_modify": ["path/to/primary_source_file.ts"],
      "steps": [
        "Ordered step-by-step instructions strictly required to implement the fix for reported issue."
      ]
    },
    "testing_strategy": {
      "test_file": "path/to/test_file.test.ts",
      "expected_behavior": "Description of expected behavior after fix.",
      "verification_steps": [
        "Specific test assertions to add/modify or manual CLI verification steps."
      ],
      "framework": "Testing framework used (e.g. Vitest or 'N/A' if no automated test file is present)."
    }
  }
}

对模板逐字段拆解:

  • golden_spec_rationale:字符串,承载第三节第 1 条的剪枝说明。
  • workable_spec.issue_id:采用 {owner}/{repo}#{issue_number} 格式,作为黄金条目的唯一身份标识。
  • summary.problem:对报告问题的精炼陈述,必须严格贴合 Issue 原文,不得改写题意。
  • summary.root_cause:根因分析,若适用则引用 PR diff 中修改的具体函数/正则。
  • summary.context:来自 Issue 与 PR 的额外技术上下文。
  • implementation_plan.files_to_modify:仅主源码文件的路径数组(见规则 2)。
  • implementation_plan.steps:严格围绕报告 Issue 的有序修复步骤(见规则 4、5)。
  • testing_strategy:测试文件路径(或 "N/A")、修复后期望行为、需新增/修改的具体断言或手工 CLI 验证步骤、测试框架名(如 Vitest)。

模板末尾还要求:不得包含 spam 评估、effort 标签等元数据,输出须完全聚焦于「代码生成与测试」的指令本身。文档的这一限制与其说是在约束格式,不如说是在约束合成器不要夹带判断噪音,让基准真值保持纯净。

五、源码侧的落地:schema 强校验与黄金条目落盘

5.1 结构化校验器如何兜底

模板产出后,generate_golden_spec.py 第 108-118 行会调用 validator.pyvalidate_triage_result硬校验,校验失败即抛错,不会进入数据集。从校验器源码可见其规则粒度:

  • triage_metadata.quality 必须是 ["SPAM", "EMPTY", "NEEDS_INFO", "FEATURE", "OK"] 之一;
  • quality == "OK" 时,effort_estimate 必须为 SMALL / MEDIUM / LARGE 之一,且必须携带 workable_spec
  • workable_spec.issue_id 必须匹配正则 ^[a-zA-Z0-9_.-]+/[a-zA-Z0-9_.-]+#[0-9]+$(校验器第 76-84 行);
  • summaryproblem/root_cause/context 均为 str)、implementation_planfiles_to_modify/steps 均为字符串列表)、testing_strategy(四个字段类型逐一断言)三段结构缺一不可。

也就是说,前文模板中所有“看起来像约定”的字段,在这里都变成了强类型、强结构断言——生成器即使收到格式漂移的模型输出也会在入口处被拦截。例如 _parse_llm_json(第 32-46 行)会先剥掉 Markdown 围栏、用 json.loads(strict=False) 解析,失败时再通过正则兜底反转义非法字符,最后仍要求顶层是 dict 对象。

5.2 生成器的运行环境与输入装配

generate_golden_spec 函数(第 57-123 行)展示了整条链路的运行时细节:

  • 它需要 owner / repo / issue_number / issue_data / pr_data 五元输入,其中 issue_datapr_data 由 GitHub API 层预先抓取(见 generate_golden_issue.py 第 28-34 行);
  • prompt 由 Issue 标题/正文、PR 标题/正文以及过滤后的 diff(去掉三类锁文件块)拼装而成;
  • 合成器 Agent 使用 policies = [deny("*")],即以「拒绝一切工具调用」的安全策略运行,因为该任务纯粹是「读文本 → 写 JSON」的推理型任务,不需要触碰文件系统或网络;
  • Agent 的 API Key 来自环境变量 GEMINI_API_KEY

5.3 如何产出黄金 Issue 数据集

tools/generate_golden_issue.py 看,generate_golden_issue 是数据集工厂的编排器,其 CLI 用法为:

python3 -m evals.triage.tools.generate_golden_issue --issue <number> [--pr <number>]

它把合成的 workable_specgolden_spec_rationale 连同 issue_titleissue_bodytarget_versionexpected_quality(默认在关联了 PR 时为 "OK")、expected_effort(从 effort/small|medium|large 这类 label 解析)写入 dataset/golden-issues/gemini_cli_{issue_number}.json。其中默认 owner/repo 为 google-gemini/gemini-cli(第 80-81 行),若带 --pr 则触发本文件描述的整条 Golden Spec 合成流程,否则只生成不含预期规格的 Issue 记录。

5.4 黄金规格如何回流进评测闭环

黄金条目最终被 runner.py 的基准跑批消费:runner 用 Git worktree 为每个 Issue 建立隔离 checkout(add_worktree/remove_worktree),对真实 triage orchestrator 执行一次完整分诊,再调用 judge.pyevaluate_categorization 做 quality/effort 精确匹配,并用 judge_workable_spec 把「分诊 Agent 预测的 spec」与「本文档产出的 golden spec」交给 LLM-as-a-Judge 按 judge.md 的四维 0-2 评分量表(target_files_scoreroot_cause_and_summary_scoreimplementation_plan_scoretesting_strategy_score)外加 human_pr_match 综合判定。值得注意的是,judge.md 内含一条与本文档剪枝思想同源的公平性规则:不允许因为候选 spec 遗漏了超出报告 Issue 范围的额外重构而扣分

六、实战操作:手工复现一次黄金规格合成

作为评测维护者,可以按如下方式在本地复现这条流水线(仓库为只读状态,仅演示运行/查看方式,不修改任何仓库文件):

  1. 准备环境:在 tools/caretaker-agent 下安装 requirements.txt 所列依赖,并确保 .env 中存在 GEMINI_API_KEY
  2. 确认 generate_golden_spec.mdgenerate_golden_spec.py 同目录(脚本第 29 行硬依赖该相对路径);
  3. 执行 python3 -m evals.triage.tools.generate_golden_issue --issue 28052 --pr 28500(示例参数)抓取 Issue/PR 数据并触发合成;
  4. dataset/golden-issues/ 下检查生成的 gemini_cli_{issue_number}.json:若 golden_spec_rationale 为空且 expected_workable_spec 为空对象,说明调用时未提供 --pr;若脚本抛 ValueError,通常意味着模型输出未通过 validator.py 的 schema 校验。

想验证生成器本身的行为,也可以直接阅读 generate_golden_spec.py 的单元级路径:第 32-46 行是「剥围栏 + 容错解析」的容错兜底,第 65-78 行是「锁文件 diff 预过滤」,第 95-123 行是 Agent 执行与校验封装——这三段几乎一一对应本文第四节、第三节与第五节讲述的约束。

七、小结:这份 System Prompt 为什么值得作为方法论文档阅读

generate_golden_spec.md 表面上是「写给模型的话」,本质上却是一份可审计的基准构建协议:它把「公平」从口号翻译成可执行的剪枝规则,把「高质量」翻译成源码-only 白名单、具体命名、禁手挥和测试文件落地规则,把「可验证」翻译成严格 JSON schema 与 N/A 兜底语义。再叠加 generate_golden_spec.py 的输入净化、validator.py 的结构校验、runner.py + judge.md 的回环打分,整条链路构成了一个「由人类 PR 提炼真值 → 用真值校准分诊 Agent」的自洽基准体系。

若你要在类似的开源 Agent 项目中搭建「Issue 分诊评测基准」,本文件连同其所在目录的 Python 编排代码(见 helperscloudrun/triage-worker)提供了可直接借鉴的三样东西:一份把公平性显式化的提示词规格、一套强 schema 校验器、以及一个 worktree 隔离的并行跑批与裁判框架

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