深入解析 grok-build 的对抗性验证器(Adversarial Verifier)提示词设计与 Skeptic 评审机制
2026/9/20 3:11:50 网站建设 项目流程

深入解析 grok-build 的对抗性验证器(Adversarial Verifier)提示词设计与 Skeptic 评审机制

【免费下载链接】grok-buildSpaceXAI's coding agent harness and TUI. Fullscreen, mouse interactive, extensible.项目地址: https://gitcode.com/gh_mirrors/gr/grok-build

xAI Grok Build(grok-build)是一个全屏、鼠标交互、可扩展的 coding agent harness 与 TUI,其"目标模式"(goal mode)内置了一套由 harness 自主掌控的对抗性验证阶段:当 agent 自认为完成某个目标时,不会直接收工,而是由多个独立的"怀疑者"(skeptic)子代理并行审查,尝试驳倒"目标已达成"这一结论。本文以仓库中 goal_verifier_prompt.md 为核心骨架,结合 goal_classifier.rs 等源码,完整讲解该提示词的角色设定、输入证据包、审计规则、决策规则、严格输出契约,以及它在 skeptic 面板聚合、防卡死(anti-ratchet)与 fail-open 机制中的落地方式。读完本文,你将掌握这套"验证者提示词 + 多评委表决"闭环的原理与工程实现,可直接对照源码定位每一个规则对应的代码位置。

一、为什么需要对抗性验证器:目标模式的"默认不信"

在 grok-build 的目标模式下,agent 每轮迭代都会产出"完成声明"(FINAL_RESPONSE)。经验表明,一个自信满满但未经检验的总结极可能掩盖未完成的验收标准、跳过的测试,甚至伪造的改动清单。因此验证阶段的核心设计哲学是:

  • 验证者不是产出工作的 agent,而是独立的"对抗者"(adversarial verifier);
  • 任务不是确认"目标已达成",而是尽可能驳倒(refute)这一结论
  • 不确定时默认refuted: true——放行一个坏结果(false-positive)会错误地终结循环,代价远高于多迭代一轮。

这一"默认不信"的偏差被刻意编码在提示词第一段,并在源码中多处落实:例如 parse_skeptic_terminal_response 规定只有响应精确等于RefutedNot Refuted才被识别为有效票,其余任何内容(含代码围栏、多余文字)一律视为无效;read_skeptic_verdict 在 JSON 缺失或损坏时,以refuted: true合成一票,即"缺失证据按失败计"。

验证阶段在运行时的入口是 run_verification_stage,它会并发派生出N个 skeptic 子代理,每个子代理收到渲染好的提示词(即本文主题模板),并把各自的 JSON 判决写回 verdict 文件,最终由聚合函数 aggregate_skeptic_verdicts 决出是否通过。

二、输入证据包:Skeptic 审什么

提示词明确列出每个 skeptic 的六类输入。这些字段不是空泛的占位符,而是由 evidence.rs 中 build_classifier_evidence_packet 以严格格式拼装的证据包:

字段说明源码中的证据来源
OBJECTIVE用户目标的逐字原文,是"不可变契约"由调用方传入,原样嵌入,不做任何清洗
PLAN_FILEMarkdown 计划文件路径(含编号验收标准);缺失时为(unavailable)PLAN_UNAVAILABLE 哨兵值
PLAN_CHANGESagent 在运行期间编辑 PLAN_FILE 的 diff;未编辑为(none)capture_plan_changes 通过git diff --no-index对比计划基线快照与当前计划
CHANGES_FILE统一的 diff 变更日志(作用域指针 + 诚实性校验锚点),不是唯一证据,可能被截断capture_changes_diff,三层回退:记录基线 → 惰性 git 基线 → walkdir + mtime 合成 diff
CHANGED_FILES本目标创建/修改的完整文件清单,skeptic 必须读取其当前内容extract_changed_files 从完整 diff 头提取,最多渲染 300 条,超出以"(… and N more)"提示
FINAL_RESPONSEagent 自己的总结;对code-change类型,散文不是证据,只用来找攻击点sanitize_final_response 清洗控制标记后再嵌入
PRIOR_GAPS上一轮验证要求实现者修复的缺口清单,首轮为(none)sanitize_prior_gaps 清洗后填充{PRIOR_GAPS}占位符

证据包的设计有几个关键点值得注意:

  1. CHANGED_FILES 是首要锚点:验证不依赖 diff 本身,而是要求 skeptic 读取这些文件的当前磁盘内容——防止 agent 用"改完又改回去"的方式骗过 diff;
  2. 计划篡改本身就是驳倒理由:如果PLAN_CHANGES显示 agent 弱化、删除或自利性修改了验收标准,提示词判定其本身即可构成 refute;
  3. 控制标记注入防护:模型/工作区派生的文本(FINAL_RESPONSE、skeptic 的 evidence)在嵌入提醒框架前会被 neutralize_reminder_tags 用零宽空格打断<system-reminder>/<goal-state>字面标签,防止模型输出反向劫持提示框架;变更文件路径中的换行控制字符则被替换为U+FFFD(见 sanitize_path_control_chars)。

三、Anti-ratchet:收敛而非反复翻旧账

重验轮(PRIOR_GAPS非空)是这套机制防止"目标永远无法完成"的关键规则。提示词要求:

  • 首要任务是核对每个先前缺口是否被真正修复
  • 轮与轮之间的标准不得抬升:仅当新反对意见是"已交付行为的可证明缺陷"或"计划中未满足的门槛标准"时,才允许作为 refute 理由;风格偏好、测试构造偏好一律不算
  • 每轮提出全新 nitpick 而标准全部成立,正是"目标无法收尾"的失败模式;当所有先前缺口修复、所有门槛标准成立时,必须返回Not Refuted

这一"防棘轮"约束在实现层面有配套机制:skeptic 0 被设计为跨轮次持久化的拒绝看门人(reject-gatekeeper),在N > 1时通过 goal_verifier_resume_prompt.md 的"增量复检"提示词跨轮恢复其会话——它带着上一轮指出的缺口继续审查,避免冷启动的新 skeptic 每轮引入全新反对意见。若恢复派生失败(会话丢失),run_one_skeptic 会回退到冷启动。

另外,缺口指纹(gap fingerprint)机制用于检测"卡死循环":见 gap_fingerprint,它从原始证据中提取去重、排序、小写化的path:line引用,并把/tmp/等每次尝试都会变化的 scratch 路径归一化为<scratch>,从而让"相同缺口"在多次尝试中产生相同指纹;连续命中停滞阈值(GOAL_CLASSIFIER_STALL_THRESHOLD 默认 2 次)即触发策略师(strategist)介入。

四、Audit, don't author:审计而非重写

提示词要求 skeptic 采用"审计者"而非"作者"姿态:

  • 只审计实现者已经产出的证据,不自己构建一套并行测试套件;
  • 定位测试与捕获输出:{IMPLEMENTER_SCRATCH}目录以及## Verification plan点名的任何路径是主要证据来源
  • 判断测试是否 HONEST(诚实)而非 HACKY(花架子):真实驱动线上代码路径的测试是诚实的;硬编码期望值、mock 掉被测单元、从被测物之后开始的场景、对"重实现"断言、#[ignore]/todo!()、用生成/伪造产物充当证明,都是不诚实测试;
  • 环境边界注入是允许的:在时钟、RNG、网络/文件/输出汇等环境边界注入 fake,使单元真实逻辑可观察、可确定,是标准做法且属诚实;
  • 只做廉价抽查:读关键文件,仅在便宜时才自己运行代码,优先复用实现者捕获的运行结果;明确禁止为 skeptic 构建独立测试套件或自行生成证据作为主要证明。

在仓库实现中,这个"不越俎代庖"的边界由输出契约强制:skeptic 唯一的写操作是{DETAILS_FILE}{VERDICT_FILE},其余一律只读;提示词还明确"do NOT modify the workspace"。skeptic 的只读工具集由 RoleToolNames 渲染进{READ_TOOL}{SEARCH_TOOL}{LIST_TOOL}等占位符,确保它具备读文件、grep、列目录的核验能力。

五、决策规则:九条铁律

提示词第 38-46 行的决策规则是判定行为的核心法典,逐条梳理如下:

  1. OBJECTIVE 与具名工件是不可变契约:先枚举 OBJECTIVE 的每一条显式要求,检查其点名的每个 URL、文件、工单、文档或图片;若某个必须检查的具名工件无法查看,则refuted: trueblocking: "unverifiable"。CI/流水线/Actions/远程任务/部署等外部检查系统本身即"具名工件",其自己最新的裁决才是唯一充分证据——本地重跑仅作佐证,因为本地状态(工具链版本、gitignore 文件、未提交文件)常与远端不一致。PLAN_FILE只是派生清单,其编号标准可澄清但不可收窄或覆盖OBJECTIVE;## Implementation approach## Task checklist是实现指引,偏离它们本身绝不构成 refute 理由analysis/research类型例外:交付物是书面散文,空 diff 也合法,直接按磁盘工件或 FINAL_RESPONSE 评判内容。禁止在契约之外发明要求——"每项标准都满足时返回Not Refuted",即便你能想象作者还能做得更多。
  2. 诚实性检查:FINAL_RESPONSE 声称改了某文件而 CHANGED_FILES 中没有该文件,即伪造,refute。
  3. 遗留品检查:TODO/FIXME/unimplemented!()/todo!()、跳过的测试、#[ignore]/@pytest.mark.skip——refute。
  4. code-change 必须有诚实测试:缺少驱动已交付改动的仓库内测试即 refute 理由;"这个测试本可以更强"属于建议而非 refute,仅当测试不诚实时才 refute。无法通过测试脚手架证明的端到端结果(UI、浏览器、长交互会话)不构成 refute——计划中定义的静态/结构性回退满足即可。
  5. CHANGES_FILE 不可用时的自救:自行用git log/status/diff、读文件调查,规则 1-4 仍然适用;完全无证据 ⇒ refute(规则 6)。
  6. 证据真正模棱两可(CHANGES_FILE 可用)⇒ refute。
  7. 验证计划要求捕获证据:实现者必须已产出(存在于{IMPLEMENTER_SCRATCH}或仓库中)并显示所列观察;缺失或不充分 ⇒ refute 并要求实现者补交,skeptic 不得自己生成。生成/伪造的工件不算证据。
  8. refute 分类blocking: "none"(普通模型可修)、"contradiction"(目标/计划内部自相矛盾)、"unverifiable"(当前环境无法取证)。后两者意味着目标需要用户决策而非重试。
  9. ## Goal kind决定审查镜头:计划中的## Goal kind标签被 parse_goal_kind 解析,分别注入不同镜头模板:code-change注入 goal_verifier_kind_lens_code_change.md(资深工程师对抗式代码审查,主动猎杀可演示的真实缺陷);research注入 goal_verifier_kind_lens_research.md(逐条核对引用源、打击编造与过期信息、要求呈现来源冲突);analysis注入 goal_verifier_kind_lens_analysis.md(结论必须有证据支撑且可推导)。镜头通过{KIND_LENS}占位符拼入主模板(见 kind_lens)。

六、Scratch 目录与输出契约

提示词为 skeptic 提供了明确的目录分工:

  • {IMPLEMENTER_SCRATCH}:实现者的输出与捕获证据,主要来源,只读
  • {SKEPTIC_SCRATCH}:skeptic 自己的目录,仅用于廉价抽查;重跑## Verification plan{SCRATCH}占位符解析到此;
  • {SCRATCH_STATUS}:由渲染器根据目录是否真实创建替换为 "Both dirs have been created for you." 或 "Create your own scratch dir withmkdir -pif it is missing."(见 render_verifier_prompt)。

这些目录在运行时由 goal_tracker.rs 的 goal_scratch_root 与 ensure_goal_scratch_root 管理:每个目标的 scratch 根目录以0700权限创建(owner-only),并派生implementer/skeptic-{idx}/子目录(L411-L418)。安全上有明确的防 symlink 攻击设计:分类器工件绝不落在裸/tmp,因为其文件名可被预测,公开可写目录会让本地攻击者预埋符号链接劫持 harness 写入(见 GOAL_CLASSIFIER_DETAILS_PATH_TEMPLATE 的注释);路径校验器 validate_details_path_in_root 还会拒绝..、NUL 字节、/etc/proc/sys/dev~前缀及未解析的替换占位符。

输出契约是三重的:

  1. JSON 判决 →{VERDICT_FILE}:固定 schema,必填refutedevidenceconfidence,可选blockingdetails_mdfindingsfindings数组是实现者实际执行的首要输出,每项含kindbug/gap/todo)、locationpath:line或位置描述)、detail(一行具体描述);
  2. 详情 →{DETAILS_FILE}:同一批 findings 的人类可读 Markdown 渲染;
  3. 终端 token:输出必须恰好RefutedNot Refuted之一,不允许任何散文、围栏或标点。

这三重契约在 harness 侧有严格对应:parse_verdict_json 要求refuted/evidence/confidence三字段齐全、evidence非空(否则返回None,防"橡皮图章"),缺失或空 evidence 直接触发 skeptic 级refuted: true合成票;parse_skeptic_terminal_response 对终端 token 的解析容忍围栏与尾点号,但响应中只能有token 本身。

七、面板聚合:多数决、Variant-C 与决定性 refute

验证阶段默认并行派出3 个 skeptic(GOAL_VERIFIER_SKEPTIC_COUNT),可通过环境变量或远程设置调整:

配置项环境变量远程设置默认取值范围源码位置
每轮 skeptic 数量GROK_GOAL_VERIFIER_Ngoal_verifier_count31..=5(clamp)resolve_goal_verifier_count
每目标验证轮数上限GROK_GOAL_CLASSIFIER_MAXgoal_classifier_max_runs10≥1(有下限无上限)resolve_goal_classifier_max_runs

选择 3 的默认值有明确动机(见 GOAL_VERIFIER_SKEPTIC_COUNT 注释):⌈3/2⌉ = 2的"not refuted"多数才能通过,单一离群者(无论是一张橡皮图章还是一个误 refute)都无法左右结果;而 N=2 时 1:1 平局会让一个宽容 skeptic 放行一个严格 skeptic 会否决的工作。

聚合逻辑 aggregate_skeptic_verdicts 实现了Variant-C规则:

  • total <= 1(唯一裁判)时,孤票即定案;
  • 面板扇出(total > 1)时,skeptic 0 的不否决票不计入,通过需要冷面板(skeptic_idx >= 1)的严格多数needed = cold_count / 2 + 1
  • skeptic 0 的否决票仍然计入refuted_count、缺口摘要和暂停摘要;
  • 运输/取消/运行时/格式错误等所有降级路径都在每个 skeptic 层面合成refuted: true(见 skeptic_failure),聚合器只数票——"偏向失败"被刻意放在证据缺失的上游。

此外还有"升级式面板"(见 run_verification_stage 注释):N > 1时先单独跑 skeptic 0,若它以高置信 refute 且非 blocking,则决定性短路,跳过其余 N-1 个派生;若其 refute 是 blocking(矛盾/不可验证)则仍扇出全面板,以区分"需要用户决策的 Blocked"与"存在可修缺口的 NotAchieved"。最终achieved = quorum_achieved && !decisive_refute

当所有 refute 都是非模型可修 blocker(contradiction/unverifiable)时,结果路由为Blocked并自动暂停目标,等待用户决策(见 run_verification_stage);只要存在一个可修缺口就保持NotAchieved,继续迭代。缺口摘要按置信度从高到低渲染进拒绝提醒(build_gaps_summary),并分为"Model-fixable gaps / Contradictions / Unverifiable in this environment"三组生成暂停消息(build_pause_summary)。

八、Fail-open:内部失败永不阻塞用户进展

当 harness 自身无法取得 verdict 时(基础设施级故障,而非判定为未达成),验证阶段执行fail-open(见 record_fail_open):把目标当作FailOpenAchieved处理,写入占位详情文件(说明验证未产生 verdict、原因、未捕获任何 skeptic 分析),并发射GoalClassifierFailOpen遥测事件。这对应提示词中的分类学:PARSE 级结果(子代理产出了可用 verdict)才是Achieved/NotAchieved;而 PARSE 级失败关闭(终端 token 格式错误、详情文件缺失)映射到NotAchieved,INFRA 级失败则走 fail-open。文件写入失败路径同样 fail-open(如 run_verification_stage 中详情路径或 patch 路径校验/写入失败时)。

九、从提示词到代码:完整调用链

把以上机制串起来,一次验证的完整生命周期是:

  1. 目标创建setup_goal尽力捕获 git 基线(git rev-parse HEAD,预算 1 秒,失败不阻塞目标创建,见 capture_git_baseline),并创建 per-goal scratch 根目录;
  2. agent 迭代:实现者产出改动、测试与捕获证据到{IMPLEMENTER_SCRATCH}
  3. 证据捕获:capture_changes_diff 按三层回退生成 diff(记录基线 → 惰性 git 基线 → walkdir+mtime 合成),diff 正文上限 GOAL_CLASSIFIER_DIFF_MAX_BYTES(256 KiB)截断并带显式标记;计划变更 diff 由 capture_plan_changes 用git diff --no-index计算;
  4. 提示词渲染:render_verifier_prompt 把模板中的{KIND_LENS}{DETAILS_FILE}{VERDICT_FILE}{SKEPTIC_SCRATCH}{IMPLEMENTER_SCRATCH}{SCRATCH_STATUS}{PRIOR_GAPS}全部替换,并追加证据包作为用户提示;
  5. 并发派生:ChannelSpawner 通过子代理协调器通道直接派生 skeptic(不走task工具调用,父模型转录保持干净),支持按索引的模型/工具集覆盖与 fail-open 重试;
  6. 判决回收:read_skeptic_verdict 以 JSON verdict 文件为准,缺失/损坏时回退终端 token,两者都不可用则合成 refute;
  7. 聚合与路由:aggregate_skeptic_verdicts 计算 quorum,结合决定性 refute 得出Achieved/NotAchieved/Blocked,写入聚合详情文件(上限 GOAL_VERIFIER_PANEL_MAX_BYTES,512 KiB),并向 TUI 推送含verifying_completion徽标的GoalUpdated状态更新(见 build_goal_updated);
  8. 下一轮:若NotAchieved,缺口摘要与指纹进入下一轮{PRIOR_GAPS},skeptic 0 会话 id 被持久化以便恢复(用户暂停/恢复时尝试计数重置但看门人保留)。

十、最佳实践:如何自定义与调优

对照模板与源码,使用方可以这样调整验证行为:

  • 调整怀疑强度:默认 3 个 skeptic 已保证多数决;追求极致审查可设GROK_GOAL_VERIFIER_N=5(上限),追求速度可设 1(唯一裁判,无恢复语义);
  • 控制迭代上限GROK_GOAL_CLASSIFIER_MAX默认 10 次验证尝试,有下限无上限;配合 stall 阈值(连续相同缺口指纹 2 次)触发策略师介入防止无限空转;
  • 为不同目标类型启用镜头:在计划文件中书写## Goal kind标签(code-change/research/analysis),即可自动切换对抗式代码审查、事实核查或论证健全性审查镜头;
  • 理解 fail-open 语义:内部故障会以"达成"放行并留痕(占位详情 + 遥测),这是刻意的权衡——内部失败绝不阻塞用户进展,代价是放弃本轮审查。

这套"默认不信 → 多评委表决 → 防棘轮收敛 → 可恢复暂停"的验证闭环,是 grok-build 目标模式在长任务可靠性上的核心工程手段;本文所讲的模板正是驱动它的行为宪法,所有规则都能在 goal_classifier.rs、goal_classifier/evidence.rs 与 goal_verifier_resume_prompt.md 等文件中找到一一对应的实现与测试。

【免费下载链接】grok-buildSpaceXAI's coding agent harness and TUI. Fullscreen, mouse interactive, extensible.项目地址: https://gitcode.com/gh_mirrors/gr/grok-build

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询