上周我让一个 Claude Code 实例去重构一个中等规模的 Python 服务,它在没有任何人干预的情况下跑了四十分钟,中途两次卡在工具调用循环里,最后还把公共接口的签名改坏了。最初我把问题归咎于模型本身,后来把同一个任务拆成多个 Agent 并行处理、加上自动回归校验和脚本化的 Routine 封装之后,效果好了不止一个量级。这篇就把我在实战里摸索出的 Claude Code 多 Agent 编排、闭环自愈与 Routine 脚本化架构完整拆一遍,适合已经在用 Claude Code、但觉得单个会话做不了复杂任务的开发者参考。
说起 Claude Code,很多人还停留在"高级命令行助手"的印象里:给它一段自然语言,它读代码、改代码、跑命令、给解释。但一旦任务规模变大——比如重构一个多模块服务、批量迁移几百个文件、搭一套带回归测试的功能——单会话模式很快就会暴露出各种问题。这篇文章不会停留在概念层面,我会把编排的三种形态、自愈循环的具体脚本、Routine 的设计思路,以及从安装到接第三方模型再到 VS Code 联调的完整落地链路,全部讲清楚。
1. 单 Agent 的瓶颈:上下文漂移、卡死与"局部最优陷阱"
1.1 上下文漂移:越干越容易"忘了自己说过什么"
单 Agent 最大的问题不是模型不够聪明,而是会话上下文太长了。当一个会话里的文件改动、报错日志、用户指令累积到几万字之后,模型对早期决策的注意力会明显衰减。你可以想象一个人同时抱着几十个记事本开会,越往后越容易把最初的结论记串。
在我那次重构里,前五分钟定好的接口命名,做到第三十分钟变成了另一个名字;Agent 改了一个公共函数的签名,却没有去更新所有调用方。它不是故意犯错的,是早期信息被大量中间日志冲淡了。Claude Code 的上下文窗口虽然大,但大不等于够用——注意力分布是非均匀的,老信息永远比新信息更难被精确召回。
这类问题的可怕之处在于:错误不是突然出现的,而是逐渐累积的。你在前面几轮审查里看不出问题,等到攒了几处不一致之后,整个模块的行为就开始变得不可预测。单 Agent 模式下,你只能手动把关键约束一遍遍强调,或者隔一段时间开一个新会话把上下文压缩一遍。这本质上是在"用人工弥补架构缺陷"。
1.2 工具死循环:没有外部信号帮忙跳出局部搜索
Claude Code 的能力来自工具调用,但工具调用一旦失控就会变成死循环。我见过最典型的表现是:Agent 反复执行同一套测试,失败后只做微小的表面修改,然后又跑一遍,一来一回十几分钟,代码 diff 却几乎没有变化。
这不是 bug,而是模型在局部搜索里陷进去了。它每轮都能拿到"测试失败"这个负反馈,但它没有能力判断"这个失败可能不是当前文件引入的"。于是它反复在自己的可见范围内打转。单 Agent 模式下,这种死循环的终止条件只有两个:token 耗尽,或者你强行中断。
我在实践中发现,给单 Agent 加一句"如果连续两次修改没有让测试结果发生变化,就停下来分析根因"能缓解一部分问题,但依然不可靠。更根本的解法是让多个 Agent 以不同视角审视同一个失败:一个负责修故障,另一个负责审查 diff 是否合理,第三个负责验证整体行为。这其实就是多 Agent 编排的起点。
1.3 从单 Agent 到多 Agent:编排、自愈与 Routine 的关系
很多人分不清编排、自愈和 Routine 各自的职责,我打个比方你就明白了:一个团队开发功能,项目经理负责把需求拆成任务并发给不同工程师(编排);工程师写完代码要跑测试,测试挂了就自己看日志改代码再跑,直到通过(自愈);有经验的工程师会把"接手新需求时先做什么检查、代码规范怎么过、提交前跑哪些命令"写成团队文档,新人也照着做(Routine)。
对应到 Claude Code 的世界里:编排解决的是分工问题,决定谁在什么时候做什么,上下文如何隔离;自愈解决的是失败恢复问题,让系统在出现错误时自动进入修复回路;Routine 解决的是经验固化问题,把一组可复用的操作流程封装成命令,避免每次从零开始摸索。
三者不是平行的三个功能,而是同一个系统的三个层:调度层负责任务分发,执行层按 Routine 干活,异常处理层在出错时触发自愈。这也是我下面要展开的核心框架。
2. 三种编排形态怎么选:并行、主从与流水线的适用场景
2.1 并行拆分:把无依赖的模块交给不同 Agent
如果你的仓库里有几个模块彼此依赖很少,并行拆分是最直接的提速方式。比如一个服务包含 auth、payment、user 三个目录,各自有独立的测试,那就可以启动三个独立的 Claude Code 进程,每个进程只负责一个子目录。
用命令行方式做并行很简单。假设你有一个任务清单 tasks.txt,每行一个子任务,可以写一个 Python 脚本并发调用 Claude Code 的 headless 模式:
import subprocess from concurrent.futures import ThreadPoolExecutor tasks = [ "重构 auth 目录,保持公共接口不变,补充单元测试", "重构 payment 目录,保持公共接口不变,补充单元测试", "重构 user 目录,保持公共接口不变,补充单元测试", ] def run(task): cmd = [ "claude", "-p", task, "--allowedTools", "Read,Edit,Bash", "--permission-mode", "acceptEdits" ] return subprocess.run(cmd, capture_output=True, text=True) with ThreadPoolExecutor(max_workers=3) as pool: results = list(pool.map(run, tasks)) for i, r in enumerate(results): print(f"任务 {i}: exit={r.returncode}, stdout length={len(r.stdout)}")并行模式最大的收益是时间,三个模块同时跑,耗时约等于最慢的那个模块。但代价是你必须提前把边界切干净:如果两个模块都依赖同一个公共文件,它们同时改这个文件,必然产生冲突。我自己的做法是:公共文件单独抽出来,或者指定一个 Agent 负责公共层,其余 Agent 只改各自目录。
另外,并行模式不适合需要频繁交流的任务。Agent 之间不能直接对话,只能通过文件交换信息。如果你发现两个任务之间隐性依赖很多,优先考虑别的模式。
2.2 主从模式:一个调度者把关,多个执行者干活
主从模式是更可控的一种编排。一个 orchestrator Agent 只做分解和验收,不直接改代码;多个 worker Agent 分别执行具体子任务,把结果汇报给调度层。
这种模式最适合那种"需求复杂但每个子任务边界清晰"的场景。Orchestrator 把需求拆成若干条指令,每条指令对应一个 worker 进程,worker 完成后把输出写到指定目录,orchestrator 再检查产物是否满足验收标准。
我曾经用一个 Bash 脚本实现过轻量版的主从调度。核心逻辑很简单:维护一个任务队列,失败的任务重试,或者分配给另一个 worker 处理:
#!/usr/bin/env bash set -euo pipefail WORK_DIR="/tmp/agent_workspace" mkdir -p "$WORK_DIR/results" declare -a tasks=( "为 auth 模块新增登录失败锁定策略" "为 payment 模块补充金额校验逻辑" "为 user 模块补充资料更新接口" ) for i in "${!tasks[@]}"; do task_id="task_$i" echo "==> 分发 $task_id" claude -p "${tasks[$i]},输出报告保存到 $WORK_DIR/results/$task_id.md" \ --output-format text > "$WORK_DIR/results/$task_id.log" 2>&1 echo "==> $task_id 完成,exit=$?" done echo "==> 调度完成,所有结果在 $WORK_DIR/results 目录"这个脚本没有做复杂的失败判断,但它把最重要的东西固定下来了:每个任务独立跑、结果独立落盘、调度器只负责顺序和记录。真实的 orchestrator 可以在这个基础上加更多逻辑,比如任务依赖、结果校验、失败重分配。
主从模式的优点是把"决策"和"执行"分开了。Orchestrator 的上下文不会被某个具体任务的细节污染,它始终从整体视角判断结果是否合格。缺点是多了一层进程调度开销,适合任务数量在几十个以内的场景。
2.3 流水线模式:一个 Agent 的输出是下一个 Agent 的输入
流水线模式适合有明确顺序依赖的任务。最典型的例子是:代码生成 -> 静态检查 -> 测试修复 -> 文档补全。前一个 Agent 生成的代码文件,后一个 Agent 基于它继续工作,中间产物通过固定目录传递。
我拿一个实际项目来说:批量给某个服务加可观测性日志。流水线是这样跑的:
第一个 Agent 扫描代码里的对外接口,生成一份"哪些函数需要加日志、加什么级别"的清单;第二个 Agent 读取这份清单,逐文件植入日志代码;第三个 Agent 跑一遍静态检查,找出日志格式不符合规范的地方;第四个 Agent 根据静态检查结果做修复。
流水线最关键的是定义好"中间产物契约"。每个阶段写在哪个目录、什么格式、验收标准是什么,必须在启动前定清楚。否则 Agent 之间传递的信息就可能对不上。相比之下,流水线模式比并行模式慢,比主从模式简单,但它最贴近真实开发流程,也最容易做沉淀——因为每个阶段本身就可以封装成一个 Routine。
2.4 三种模式对比:什么时候选哪种
| 模式 | 适用场景 | 优点 | 风险与代价 | 典型配置 |
|---|---|---|---|---|
| 并行 | 模块间无依赖、可同时推进 | 吞吐最高,耗时最短 | 公共文件冲突,无法传递即时反馈 | 多进程同时跑,每进程限定目录 |
| 主从 | 需求复杂、子任务边界清晰 | 决策与执行分离,整体可控 | 多一层调度开销,需要验收标准 | orchestrator + worker 脚本 |
| 流水线 | 阶段之间有强顺序依赖 | 产物可追踪,阶段可复用 | 整体耗时受最慢阶段限制 | 每阶段写产物到固定目录 |
我的建议是:拿不准的时候先从流水线开始。流水线的每一步都可以单独验证,出问题你很容易定位到底哪个阶段失败了。并行和主从更像是流水线跑顺之后的优化手段,而不是起点。
3. 闭环自愈不是魔法:错误回调、回归重试与轮次上限的实现细节
3.1 自愈的闭环逻辑:执行、校验、反馈、重试
自愈的完整回路只有四步:执行任务,校验结果,反馈错误,重试修复。听起来很简单,但大多数失败的"自愈"系统其实只做了"重试",而没有做好"校验反馈"。
这就像一个体感很差的程序员写代码:写完自己编译一遍,编译没过就根据报错去改,然后继续跑。自愈的关键不在于重试多少次,而在于校验信号是否准确。校验信号越精确,重试越有效;信号模糊,重试就是在烧钱。
校验手段的优先级我一般是这么排的:编译/类型检查 > 静态检查(lint) > 单元测试 > 端到端测试 > Agent 自我检查。越靠前的越便宜、越快、越稳定。真实项目里,很多错误根本不需要跑完整套测试才能发现,一个 ESLint 或 mypy 就跑出来了。自愈循环里优先跑便宜的校验,能大幅降低修复成本。
3.2 一个可复用的自愈循环脚本
下面是实际可用的 Bash 脚本,结构不复杂,但把自愈的关键点都覆盖了:轮次上限、测试驱动修复、失败退出码。你可以直接保存为 selfheal.sh 使用:
#!/usr/bin/env bash set -euo pipefail MAX_RETRIES="${MAX_RETRIES:-3}" TARGET_DIR="$1" TEST_CMD="${2:-python -m pytest}" for i in $(seq 1 "$MAX_RETRIES"); do echo "==> 第 $i 轮:运行校验命令" if eval "$TEST_CMD"; then echo "==> 校验通过,任务完成" exit 0 fi echo "==> 校验失败,调用修复 Agent" claude -p "修复 $TARGET_DIR 下导致校验失败的问题。修复前先阅读相关代码和错误输出,定位根因;修改后先自我检查再交付,不要提交只改表面症状的代码。" \ --allowedTools "Read,Edit,Bash" \ --permission-mode acceptEdits done echo "==> 重试 $MAX_RETRIES 轮仍未通过,需要人工介入" >&2 exit 1脚本里藏了几个细节。第一,MAX_RETRIES默认 3,这是成本和安全之间的平衡点。第二,修复 prompt 里明确要求"先阅读相关代码和错误输出,定位根因",这一句话能显著减少"只改表面症状"的行为。第三,每次修复后重新跑的是同一个校验命令,保证闭环的验证标准稳定。
实际使用的时候,TEST_CMD可以不是测试,而是任何布尔判断命令。比如"python -m compileall src"做语法检查,"npx eslint src"做代码规范检查,甚至可以是"grep -q 'TODO' src/main.py && exit 1; exit 0"这种自定义规则。
你还可以把校验命令从"测试"扩展成"测试 + diff 检查"。我经常加一条:修复完成后检查 git diff 行数,如果单轮改动超过某个阈值,就判定这次修复可能跑偏了。例如:
MAX_DIFF_LINES=200 if [ "$(git diff --numstat | awk '{s+=$1+$2} END {print s+0}')" -gt "$MAX_DIFF_LINES" ]; then echo "==> 修改量过大,停止自动修复,需要人工确认" exit 1 fi有些 Agent 在修复失败时会选择"绕过问题"而不是"解决问题",比如把测试用例删掉。所以自愈脚本里还应该加一个保护:完成任务前检查测试文件是否被修改或删除。如果不检查,Agent 很容易通过"阉割测试"让校验通过,这比不修复更糟。
3.3 自愈的边界与人工介入时机
自愈不是无限重试。token 成本、时间成本、上下文污染都是现实约束。我个人的习惯是把单任务的修复轮次限制在 3 轮以内。如果 3 轮都没有命中,说明问题可能不是局部代码问题,而是需求理解、架构设计、或跨模块冲突层面的问题。再继续烧 token 只会让 Agent 在同一个局部里打转。
哪些情况适合自愈?编译错误、lint 不通过、单元测试失败、配置文件格式错误、生成的文档缺失关键章节。这些问题的特征是:有明确客观标准,Agent 可以通过反馈快速逼近正确答案。
哪些情况不适合自愈?需求歧义、架构决策、跨模块接口设计、测试用例本身的正确性。这些问题没有唯一正确答案,Agent 每轮做出的"修复"可能只是随机选择一个方向。遇到这类问题,自愈循环越快熔断越好。
我判断是否人工介入有三个信号,你们也可以参考:连续两轮修复都在修改同一个文件且校验依旧失败;Agent 修改了测试文件或跳过了部分校验;报告说"修复完成"但 git diff 内容明显偏离任务目标。出现任何一个信号,就停掉循环,自己去看一遍。
4. Routine 脚本化:把团队里最值钱的操作流程固化成命令
4.1 Routine 是什么:从"每次重新打字"到"一键执行"
Routine 就是把一段经常重复、有固定步骤的 Agent 任务固化成脚本或命令。如果说编排是调度层、自愈是异常处理层,Routine 就是标准作业层。
我见过很多人用 Claude Code 的方式是:每次想让它干个活,就在命令行里临时打一段长长的话。这就像每次做饭前都重新去菜市场现买食材、现想菜谱。而 Routine 是把你已经验证过有效的那套流程沉淀下来,下次直接调用。
一个菜谱是 Routine,厨师是 Agent,尝菜是校验,叫另一个厨师帮忙备菜是编排。菜谱要清晰到换个厨师也能做出一致的菜,Routine 也要清晰到换个新会话、换一批文件也能执行出可靠的结果。
什么样的操作值得沉淀成 Routine?我的标准有三条:高频(每周至少用一次)、步骤稳定(每次执行的流程大同小异)、可校验(有明确成功标准)。比如代码审查、环境诊断、批量迁移、依赖升级、文档生成,这些都是 Routine 的好素材。
4.2 一个 Routine 的完整设计:参数化、幂等、结构化输出
Routine 设计有三大原则:参数化、幂等、结构化输出。参数化指的是脚本能接收不同的输入,而不是把路径写死;幂等指的是同样一个 Routine 重复执行,不会产生叠加副作用;结构化输出指的是每次执行都有清晰的退出码和日志,方便上层编排判断结果。
下面是一个代码审查 Routine 的示例。它做的事情是:取最近一次提交的 diff,让 Agent 审查,把报告写到固定文件。这个 Routine 可以被任何项目复用,只要传一个参数指定 diff 范围:
#!/usr/bin/env bash set -euo pipefail DIFF_RANGE="${1:-HEAD~1..HEAD}" OUTPUT_FILE="${2:-/tmp/review_report.md}" git diff "$DIFF_RANGE" > /tmp/latest_diff.txt if [ ! -s /tmp/latest_diff.txt ]; then echo "diff 为空,没有需要审查的变更" exit 0 fi claude -p "你是代码审查员。请阅读 /tmp/latest_diff.txt 里的代码变更,按严重程度列出问题,包括:潜在 bug、安全问题、性能隐患、可维护性问题。每个问题给出文件路径、行号级定位和具体修改建议。输出为 Markdown 格式。" \ --output-format text > "$OUTPUT_FILE" echo "审查完成,报告输出到 $OUTPUT_FILE"这个 Routine 体现了参数化(diff 范围可传、输出路径可传)、幂等(不管跑多少次,只是重新生成一份报告)、结构化输出(退出码代表成功失败,报告文件是固定格式)。把你的项目里最常见的 Agent 任务都写成这种形态,你会发现团队协作时能省掉大量沟通成本。
4.3 实际 Routine 示例:环境诊断、批量迁移、依赖升级
环境诊断 Routine 是我用得最多的。它的职责是:检查当前仓库的依赖版本、Python/Node 版本、配置文件是否完整,输出一份诊断报告,如果发现问题,直接询问是否交给 Agent 修复。
批量迁移 Routine 要复杂一些,通常和自愈循环配合。它的流程是:扫描目标文件列表,逐个交给修复 Agent,迁移失败的文件记录到单独列表,最后生成迁移报告。每个文件用独立会话处理,避免上下文互相污染。
依赖升级 Routine 我强烈建议做。它要做的事情包括:读取当前依赖列表、检查最新可用版本、列出升级影响分析、按模块分组升级、跑一遍全量测试。全部用脚本固化了之后,升级依赖从"一个下午的忐忑"变成"一条命令加一杯咖啡"。
4.4 与多 Agent、自愈机制的组合方式
Routine 不是孤立存在的。在实际架构里,Routine 是 worker 的标准执行方式,自愈是 Routine 的异常处理层,编排是 Routine 的调度层。一个任务进来,编排调度器先判断应该用哪个 Routine,然后起 worker 执行,执行过程中如果校验失败,触发自愈回路,轮次用尽后上报给编排层,编排层决定是重试、换方案还是通知人工。
这种三层结构的价值在于:每层都可以独立替换。你觉得某个 Agent 能力不够,换一个入口;你觉得某个 Routine 的提示词写得不好,只改 Routine 本身;你觉得自愈太烧钱,只调轮次上限。系统各部分的耦合度低,维护起来舒服得多。
5. 环境落地:Claude Code 安装、第三方模型接入与 VS Code 联调
5.1 安装与初始化:从 npm 到终端可用的完整路径
Claude Code 的安装其实很快,麻烦的是环境不一致带来的各种小问题。最标准的安装方式是 npm 全局安装:
npm install -g @anthropic-ai/claude-code装完之后执行claude --version确认版本。如果提示找不到命令,十有八九是 npm 全局 bin 目录没加进 PATH。执行npm config get prefix拿到 npm 全局目录,再把对应的 bin 目录加入 PATH 就行。
安装完成后,第一次运行claude会引导你完成初始化。注册账号与不注册账号的主要差异在于会话管理、用量统计这些功能范围,具体以官方当前说明为准。我的建议是:正式项目开发用一个稳定的账号登录,会话恢复和用量统计会让你心里有数;临时体验或者测试脚本,不受限的轻量模式也可以先用着。
在 Ubuntu 上额外要注意 Node 版本。Claude Code 对 Node 版本有最低要求,如果你系统自带的 Node 太老,建议先用 nvm 装一个当前 LTS 版本再安装。macOS 上主要是权限问题,如果全局安装失败,检查目录写权限,必要时用sudo,但优先考虑修复 npm 目录权限而不是用 sudo 强行装。
5.2 第三方模型接入与多模型切换:合规配置与团队协作
很多团队不想只用固定模型,会考虑接入 DeepSeek、Qwen、GLM 等第三方模型服务。这一步在 Claude Code 里做起来并不复杂,核心是修改它连接的后端配置。社区里常见的做法是使用 cc-switch 这类开源配置切换工具,它可以把多套模型服务的配置保存下来,一键切换。
切换的本质是环境变量或配置文件里的接口地址和密钥。下面是一个环境变量层面的接法示意:
export ANTHROPIC_BASE_URL="https://your-service-provider.example.com" export ANTHROPIC_AUTH_TOKEN="your_api_key_here" claude接入第三方模型时,有两点必须提醒:第一,不同服务商支持的模型能力、上下文长度和工具调用格式不同,接入前先阅读对应服务商的技术文档,确认它提供的 Anthropic 兼容接口支持 Claude Code 需要的全部特性。第二,任何模型接入都必须遵守服务商的服务条款和使用规范,不要做超出授权范围的事情。这既是对平台规则的尊重,也避免你的项目埋下合规隐患。
多模型切换在团队协作里特别有用。一个模型擅长代码生成,另一个模型擅长审查,第三个模型可能成本低适合批量任务。通过 cc-switch 这类配置管理工具,你能在一条命令内完成切换,再配合前面的编排框架,不同的 worker 用不同的模型服务,很多工作流就有意思了。
5.3 VS Code 集成:把 Agent 放进编辑器
VS Code 里可以直接安装 Claude Code 扩展。装完后侧边栏会出现一个面板,可以创建会话、查看 Agent 的工具调用记录、管理权限。和命令行模式相比,VS Code 面板的优势是可视化程度高,你能看到 Agent 正在读哪些文件、执行了哪些命令,便于观察和干预。
扩展的配置项里,我最常用的是权限控制。默认情况下,Agent 执行工具需要逐次确认,这在交互式会话里是安全的,但放到自愈脚本或批量任务里就太拖沓了。你可以把某些工具设为自动允许,比如 Read、Edit、Bash,但要小心放开之后 Agent 的自主性会提高,建议先在小范围试用。
VS Code 里的会话和 CLI 是可以共存的。我通常的习惯是:探索性调试、理解代码结构用 VS Code 面板;批量任务、自动化流程用 CLI headless 模式;两者通过同一套配置文件管理权限和接口地址,切换没有摩擦。
5.4 常见安装与联调问题速查
| 症状 | 可能原因 | 处理方式 |
|---|---|---|
claude: command not found | npm 全局 bin 未加入 PATH | 执行npm config get prefix,把 bin 目录加入 PATH |
| 安装时提示 Node 版本过低 | 系统 Node 版本不满足要求 | 用 nvm 安装 LTS 版本,重新安装 Claude Code |
| 登录状态失效 | Token 过期或本地配置损坏 | 重新执行claude完成初始化登录 |
| Agent 无法执行 Bash 工具 | 权限配置限制 | 检查权限模式,按需打开 Bash 工具白名单 |
| 第三方模型接入后响应异常 | 接口地址或模型名称配置错误 | 核对服务商文档,确认兼容接口和模型名 |
| VS Code 面板找不到扩展 | 扩展未安装或版本不匹配 | 在扩展市场搜官方扩展,检查是否被禁用 |
如果你在初始化阶段看到环境可用性相关提示,请以官方的支持范围说明为准,先确认当前环境是否在支持列表内,再继续后续配置。
6. 我在真实项目里踩过的编排坑与调优心得
6.1 坑 1:并行 Agent 互相覆盖公共文件
第一次跑并行编排,我自信满满地起了四个 worker,分别处理四个目录。结果十分钟后 git 状态乱成一团:两个 Agent 同时改了一个公共工具函数文件,互相覆盖,最后半个模块处于不可编译状态。
根因在于我只按目录切分了任务,没有按"文件所有权"切分。公共文件是隐性依赖,表面上看目录独立,实际上共享了我没意识到的代码。后来的解法很简单:任务拆分时先跑一遍依赖分析,把所有公共文件单独标记,公共文件要么由调度器统一改,要么任何一个 Agent 都不允许碰,全部通过任务描述传给专人来改。
6.2 坑 2:自愈循环把 token 烧掉几千块
自愈机制刚上线时我犯过一个冒进错误:把最大重试轮数设成 10,并且校验命令用的是全量端到端测试。结果一个很小的问题触发 Agent 反复修了十轮,每轮都跑全量测试,token 消耗直接爆了。
这次教训让我把自愈循环的成本控制拆成了三层:校验命令优先用静态检查和单元测试,只有这些全绿才跑端到端;单任务重试上限默认 3 轮,绝不轻易放开;每轮修复前先记录当前 git 状态,如果 Agent 连续两轮产出几乎同样的 diff,就判定为停滞,直接熔断。
| 参数 | 我的默认值 | 说明 |
|---|---|---|
| MAX_RETRIES | 3 | 单任务最大自愈轮次 |
| FIRST_CHECK | lint / 类型检查 | 第一轮校验用最便宜的信号 |
| SECOND_CHECK | 单元测试 | 第一轮通过后再跑 |
| FINAL_CHECK | 端到端测试 | 交付前最后的门禁 |
| DIFF_LIMIT | 200 行/轮 | 单轮修改量超过则人工介入 |
6.3 坑 3:Routine 参数泛滥,最后没人愿意用
我一开始设计的代码审查 Routine 有七个参数,从 diff 范围、输出路径到审查关注点、语言偏好,应有尽有。结果团队里除了我没人愿意用它——参数太多了,背不住。
后来我把 Routine 按"场景"重新设计,而不是按"功能"设计。不再有一个通用的"审查 Routine",而是拆成了"常规 PR 审查""安全专项审查""性能专项审查"三个。每个的默认参数都设置好,用户只需要在最简单的场景里改一两个值。参数越少,采用率越高。
6.4 几条沉淀下来的调优心得
如果让我给刚起步的团队一个建议,我会说:先跑通一条最小的流水线,再加自愈,最后加编排。很多人一开始就想搭一个全自动多 Agent 平台,结果调试编排本身花的时间比真正干活的时间还多。我踩过这个坑,所以我强烈推荐从最小的闭环开始,比如就写一个脚本:一个 Agent 生成代码,一个脚本跑测试,失败就再调用一次修复 Agent。这条链路稳定了,再慢慢把并行、主从这些模式加进来。
另外,架构里一定要给 Agent 明确的"不做清单"。比如"不要修改测试文件""不要改动公共接口签名""不要删除 TODO 注释"。Agent 是不会主动遵守的,但这些约束写在 prompt 和 Routine 的固定片段里之后,能明显降低走偏概率。
最后,别把所有环节都自动化。merge 到主干、部署上线、删除旧 API 这类动作,我都会保留人工确认节点。自愈和编排解决的是"重复劳动"和"低级错误",真正关键的判断还是留给人来做比较稳妥。