qwen-code autofix 失败路径双语交接注释:设计、实现与契约测试
【免费下载链接】qwen-codeAn open-source AI coding agent that lives in your terminal.项目地址: https://gitcode.com/GitHub_Trending/qw/qwen-code
autofix 是 qwen-code 仓库中一个全自动的"评审反馈修复循环":它监听 PR 上的评审反馈,驱动 Agent 生成修复,通过独立验证门后推送,失败则暂停并把决策权交还给维护者。本文以 2026-08-18-autofix-handoff-bilingual 计划 及其 配套设计文档 为核心,深入讲解 autofix 失败路径(failure-path)交接注释的中英双语化改造:从failure.zh.md伴生文件的 Agent 契约、HEADLINE_ZH平行变量的模板体系、3000 字节截断与标签清理管线,到 SKILL.md 规则扩展与工作流契约测试。读完本文,你将掌握这套"英文正文不变 + 折叠中文说明块"注释惯例的完整落地方法,以及如何在字节截断、HTML 标签转义与降级场景下保证注释渲染与机器解析的双重安全。
为什么失败路径最需要双语
autofix 循环中,工作流会发布多种静态注释:接管确认(takeover-ack)、重新武装(re-arm)、调度拒绝(dispatch refusal)、里程碑、base 更新、评审暂缓等。仓库的既有惯例是英文在前、中文放在折叠的<details><summary>中文说明</summary>块中。唯一例外是失败路径的交接注释(handoff comment)——它们此前是纯英文的。
这正是最需要中文的注释:失败路径会停止循环,并请求维护者做出决策(拆分 PR / 重新设计 / 接受残余问题)。一位中文维护者应当能直接读懂并行动,而不是先翻译一大段英文。设计文档 2026-08-18-autofix-handoff-bilingual.md 以 round-6 growth-brake 升级(PR #9262,comment 5321766307)为例,说明了这一痛点的实际形态。
现状:交接注释今天是如何组装的
改造前,Address review feedback作业的失败路径(qwen-autofix.yml 约 L6660–7050)构建<workdir>/report.md并通过gh pr comment发布。组装过程分四步:
- HEADLINE:约 9 种 bash 生成的英文模板,包括:
- API 错误 / 超时 / 崩溃 / 验证门崩溃的重试与终止两种形态(CAUSE × 4、LAST_FIX × 5,组合成两个句子框架);
- 过期 base 的自动更新重试;
- needs-a-human 交接("Could not produce a passing fix…")及 GATE_CLAUSE × 5(无 / 验证门拒绝 / 三种 pre-existing 对比状态);
- 无法启动(setup 失败重试、轮次上限);
- 读取反馈前终止性崩溃;
- 连续失败熔断(consecutive-failure breaker);
- 累计超时熔断(cumulative-timeout breaker,含 IDLE_CLAUSE 与 REMEDY 变体)。
- 可选摘录:
**What I found before stopping:**(或 NOT-pushed 警告)+DETAIL_FILE前 1500 字节。DETAIL_FILE取failure.md、handoff.md、address-summary.md、no-action.md中第一个非空者,经过iconv -c与<!--转义。 - 可选验证门拒绝段:
**Why it was not pushed:**+gate-rejection.md前 3900 字节(由 run-autofix-review-verification.sh 中的reject_fix()写入:静态原因句 + 不可翻译的日志证据),用<!-- autofix-gate-rejection-start/end -->围栏包裹。 - 页脚:Run log 链接、
🧠 Handled by Qwen Code签名,以及autofix-eval/autofix-growth-now/autofix-redcheck等机器标记。下一次扫描从原始评论正文中解析这些标记。
关键约束在于:Agent 写的failure.md承载了决策相关信息(选项、建议),而 SKILL.md 此前强制failure.md与handoff.md保持纯英文且不带 details 块——因为注释内嵌了字节截断的摘录,一个被截断的<details>标签会把整条注释的其余部分吞进渲染结果。
设计一:failure.zh.md伴生文件(Agent 契约)
核心思路是新增一个 Agent 输出文件,而不是改动既有文件:只要 Agent 写了<workdir>/failure.md,就必须同时写<workdir>/failure.zh.md——failure.md的逐段完整中文翻译。约束被编码进 SKILL.md 的 GitHub Actions Rules(见 SKILL.md L204–214):
- 纯 Markdown,完全不允许 HTML 标签(不能有
<details>、<summary>或任何<…>); - 不能包含
<!--序列; <details>包裹由工作流负责,不由 Agent 生成——Agent 无法越权打开/关闭折叠块。
failure.md本身保持纯英文(摘录安全性不变);handoff.md继续由 run-agent.mjs 拥有且保持纯英文。这套分工的精妙之处在于:包裹标签由工作流发出,截断的翻译最多丢失内容,永远无法吞掉注释尾部。
设计二:HEADLINE_ZH平行变量体系
在每个HEADLINE=赋值处新增HEADLINE_ZH=兄弟变量,共约 23 个静态字符串(含 CAUSE / LAST_FIX / GATE_CLAUSE 子句变体)。中英文两侧采用相同的组合结构。以 needs-human 路径为例,qwen-autofix.yml L6518 的实际代码为:
HEADLINE_ZH="🤖 未能为该反馈产生可通过验证的修复(第 ${MARK_ROUND}/${MAX_ROUNDS} 轮)${GATE_CLAUSE_ZH}。此项现在需要人工处理;循环保持在线,仍会拾取新反馈与 base 冲突,但不会自行重试此项。"平行_ZH变量在该工作流中已有先例(milestone 注释中的WIN_DESC_ZH)。从源码可以看到完整的中文模板族:
| 场景 | HEADLINE_ZH 语义(节选) | 源码位置 |
|---|---|---|
| API 错误重试/终止 | "AutoFix ${CAUSE_ZH}(第 ${DISPLAY_ROUND}/${CAUSE_MAX} 次尝试)—— 将在下次扫描时重试 / 这是最后一次自动尝试" | L6295/L6298 |
| 按指示移交人工 | "AutoFix 已按指示将此项移交人工处理(第 ${MARK_ROUND}/${MAX_ROUNDS} 轮)" | L6311 |
| 脏工作区 brake 违规 | "agent 写了 handoff 却留下了脏工作区,违反 brake 的禁止提交停止" | L6320 |
| 带提交的 brake 违规 | "agent 写了 handoff 但本轮存在提交,违反 brake 的禁止提交停止" | L6326 |
| 过期 base 自动更新 | "修复未通过验证,但本 PR 落后于 main,因此已通过 update-branch 合入" | L6484 |
| 过期 base 暂缓 | "该 PR 上仍有一轮生命周期评审在运行,现在合入 main 会取消该评审" | L6491 |
| 无法启动 | "在 agent 运行之前某个准备步骤失败…通常是与本 PR 无关的瞬时问题" | L6530/L6534 |
| 读取反馈前崩溃 | "在读取反馈之前崩溃或超时…恢复方法:删除本 bot 的终止性 autofix-eval 标记评论" | L6543 |
| 连续失败熔断 | "连续 ${CONSEC_FAIL} 轮没有进展…这通常意味着 PR 过大,或与快速变动的 main 冲突" | L6595 |
| 累计超时熔断 | "当前计数窗口内已累计 ${BUDGET_TIMEOUT_N} 次时间预算耗尽" | L6653 |
子句变量同样成对出现,例如 IDLE_CLAUSE / IDLE_CLAUSE_ZH(L6649–6650)、CAUSE / CAUSE_ZH、LAST_FIX / LAST_FIX_ZH(L6262–6274)。组合时中英文各自保持完整语法。
设计三:报告布局与中文摘录管线
英文正文完全不变,仅在Run log:行之前插入折叠块。报告块的真实实现位于 qwen-autofix.yml L6708–6734:
# Bilingual companion. Repo convention is English first, Chinese # in a collapsed <details>. failure.md itself stays English-only echo echo '<details>' echo '<summary>中文说明</summary>' echo echo "${HEADLINE_ZH}" if [[ -s "${WORKDIR}/failure.zh.md" ]]; then echo if [[ "${COMMITTED}" == "true" ]]; then echo "⚠️ 此改动未被推送 —— 下文引用的任何提交都只存在于 runner 工作区,已被丢弃。以下是 agent 的报告:" else echo "**停止前我了解到的情况:**" fi head -c 3000 "${WORKDIR}/failure.zh.md" | iconv -f utf-8 -t utf-8 -c | sed -e 's/<!--/<!\\-\\-/g' -e 's/<[dD][eE][tT][aA][iI][lL][sS]/<details/g' -e 's/<\/[dD][eE][tT][aA][iI][lL][sS]/<\/details/g' -e 's/<[sS][uU][mM][mM][aA][rR][yY]/<summary/g' || true fi if [[ -s "${WORKDIR}/gate-rejection.md" ]]; then echo echo "验证门的拒绝原因与日志证据见上方英文部分(gate-rejection 不翻译)。" fi echo echo '</details>'布局要点:
- 折叠块位于 Run log 行之前(L6737),markers(
autofix-eval、autofix-growth-now、autofix-redcheck等)保持在最后且 ASCII 不变(L6746–6767),因此下一次扫描对原始正文的解析完全不受影响。 - 中文摘录预算:
head -c 3000。中文约 3 字节/字符,3000 字节 ≈ 1000 个汉字,与英文侧 1500 字节摘录的信息量大致相当。预算旋钮与既有 1500/3900 常量放在一起并带注释维护。 - 清理管线:
head -c 3000 | iconv -f utf-8 -t utf-8 -c | sed ...。iconv -c丢弃字节级head -c可能切断的半截多字节序列,保证评论正文始终是合法 UTF-8;sed 在既有的<!--转义之外,新增<details、</details、<summary→ 全角<形式的转义,使病态翻译即使引用了标记也无法破坏包裹结构。<workdir>这类尖括号散文不受影响。 - 分区标签的处理有讲究:打开摘录的两个分支标签(
**What I found before stopping:**与 NOT-pushed 警告)在 details 块内被翻译;而**Why it was not pushed:**与 stale-base 注释不翻译——它们打开的是验证门段落,其正文保持英文,details 块内用一行指针句(L6731)告诉中文读者证据在上方。 - 无摘录回退句无需对应翻译:
DETAIL_FILE为空时failure.zh.md不可能存在(它只随failure.md一同写出,而failure.md本身就是 DETAIL_FILE 候选),details 块退化为仅有标题翻译,而该状态已由标题本身承载。
降级策略:缺失翻译绝不失败整轮
设计显式规定了三级降级路径:
failure.zh.md缺失(run-agent.mjs 在崩溃 / 循环守卫 / 缺输出路径上自行写了failure.md,或 Agent 跳过):details 块仍渲染HEADLINE_ZH单独内容。绝不为缺失翻译而失败整轮。DETAIL_FILE=address-summary.md/no-action.md:这两个文件按 SKILL 契约本身已双语,无failure.zh.md兄弟文件,因此仅标题的 details 块对它们也是正确的。它们强制的<details>尾部仍可能被 1500 字节截断——但摘录站点中和了标签形式,被截断的开启标签是惰性的。- 字节截断可能切断围栏代码块:1500/3000 字节截断落在行中,若围栏在截断前打开、截断后闭合,摘录会渲染为未终止的代码块,其后的内容(中文说明包裹)显示为其中的等宽文本。设计明确接受此情况而不做围栏平衡:这纯属渲染层面问题(循环标记从原始正文解析)、未截断的完整报告仍会进入 run-log 转储与步骤摘要,且截断落在闭合符中间时任何平衡启发式都会出错。该类问题覆盖所有字节截断摘录站点——英文 failure.md / DETAIL_FILE 摘录与两个中文摘录。
此外,issue 通道的 withdraw 注释:中文说明块无条件渲染,配每个分支的REASON_ZH兄弟变量(镜像 PR 通道的标题底线);清理过的 failure.zh.md 摘录仅在存在时加入。因此崩溃形态(run-agent.mjs 自行写 failure.md、无伴生文件)仍会显示中文撤出句。
SKILL.md:规则扩展
在 SKILL.md 的 GitHub Actions Rules 中,双语输出规则被扩展:保留failure.md/handoff.md的纯英文要求,新增failure.zh.md伴生要求及上文全部约束。规则还明确:"缺失failure.zh.md会把注释降级为仅标题翻译,因此即使停止只有一段也要写它;全文逐段翻译,不要概括或省略。"growth-brake 交接指令(workflow feedback.md 文本与 SKILL 的 defer-to-human 条目)依赖通用规则,无需按模式重复。
该规则与既有的"以 PR 评论逐字发布的文件(address-summary.md、no-action.md、e2e-report.md)必须以英文书写并以完整折叠中文翻译结尾"(SKILL.md L185–199)共同构成完整的双语输出契约。
契约测试与验证
改造配套了 qwen-autofix-workflow.test.js 中交接注释 describe 块的扩展(约 L16955 起),固定四类契约:
- needs-human 报告包含
中文说明details 块与中文标题; - 工作流中每个
HEADLINE赋值都有兄弟HEADLINE_ZH(静态结构 pin,与既有标题 pin 同风格); - 完整清理管线 pin:从 L16989–16991 可见,测试锚定整条管线字符串
head -c 3000 "${WORKDIR}/failure.zh.md" | iconv ... | sed ...,并注释说明这是 mutation 验证过的——此前只 pin 三条标签替换之一或<!--表达式时,删除另一侧同类站点会留下 177/177 全绿的假阴性,这正是九站点计数测试所要消灭的 false-green 类别; - 机器标记位于
</details>之后(indexOf顺序断言),保证后续扫描解析不受影响; - SKILL.md pin:
failure.zh.md伴生规则存在、failure.md保持纯英文。
计划文档 2026-08-18-autofix-handoff-bilingual.md 记录的完整验证过程:
npx vitest run --config ./scripts/tests/vitest.config.ts qwen-autofix-workflow.test.js qwen-fleet-shepherd-workflow.test.js除两个预先存在的本地环境失败外全部通过(macOS bash 3.2 缺少 gate 脚本所需的mapfile,已在干净树上用 stash 确认)。另有:
- YAML 解析(PyYAML)+
bash -n覆盖全部 58 个 run 块; - Smoke 测试:中文摘录清理(
<details/</details/<summary/<!--全部中和)、set -eo pipefail下的中字符截断安全、三种渲染场景(中文 + 验证门拒绝 / 无中文 / 已提交未推送); - 手工渲染检查:本地组装 report.md 样例,目检 GitHub Markdown 对 details 块的渲染。
范围外与风险
改造明确划定的范围外事项:gate-rejection.md正文不翻译(其内容是日志输出,翻译过的 GATE_CLAUSE 已足以告诉中文读者验证门拒绝了尝试);qwen-fleet-shepherd.yml的升级注释(独立工作流);run-agent.mjs 自己的handoff.md前言行(罕见回退路径)。
已识别的风险同样务实:约 23 个新中文静态字符串进入 7000 行工作流,审查负担真实但机械(契约测试 pin 的是存在性而非文笔质量);Agent 在预算压力下可能跳过failure.zh.md——降级但功能正常(仅标题 details),不改变任何轮次结果;评论体积增加不超过约 3.5 KB,远低于 GitHub 的 65 KB 限制。
小结
这套双语交接方案的技术骨架可以概括为四条原则:伴生文件分离职责(failure.zh.md只做翻译、<details>包裹归工作流所有);平行变量保证覆盖(每个 HEADLINE 必有 HEADLINE_ZH,契约测试结构性强制);字节预算与标签中和保护渲染(3000 字节 ≈ 1000 汉字、iconv 保 UTF-8、全角转义封死标签逃逸);降级优先于失败(缺翻译只损失内容、不损失轮次,机器标记永远保持可解析)。对于任何需要"机器可解析 + 人类可读 + 多语言"三要素并存的自动化注释系统,这套从契约、实现到测试的完整闭环都值得直接借鉴。
【免费下载链接】qwen-codeAn open-source AI coding agent that lives in your terminal.项目地址: https://gitcode.com/GitHub_Trending/qw/qwen-code
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考