
Claude Code 真正值得花时间的不是“问一句、答一句”的单步聊天而是多 Agent 编排、闭环自愈和 Routine 脚本化这三件事。把它们串起来之后你会发现 Claude Code 从一个“会写代码的对话助手”变成了“能自己拆任务、自己检查结果、自己修复问题”的半自动流水线。这篇内容适合正在折腾 Claude Code 工作流、或者准备把 AI 编程从“人肉驱动”升级为“流程驱动”的人我会从原理讲到可直接套用的脚本尽量少讲空话。我最早用 Claude Code 时其实和大多数人一样在终端里发一段任务描述等它输出再人工判断结果是否可用。这个阶段处理“改一个小函数”“写一段脚本”很舒服但一旦任务变成长链条比如“为模块补完整测试、跑回归、修问题、再回归”人就立刻成了瓶颈。不是说 Claude Code 能力不够而是你没有给它一套运行和约束机制。多 Agent 编排解决的是任务怎么拆闭环自愈解决的是质量怎么兜底Routine 脚本化解决的是流程怎么复用。这三个机制配合起来才能把“聊一次改一次”的模式彻底换掉。1. 先看清瓶颈为什么单步聊天模式撑不起真实任务1.1 单步聊天的本质局限它只是一个临时状态机很多人的第一反应是Claude Code 本身能力很强我一步一步问它不就行了问题恰恰出在“一步一步”上。单步聊天本质上是一个临时状态机。状态不在任何地方持久化只存在于当前会话的上下文窗口里。你让它改完 A 文件再让它改 B 文件它能知道 A 文件当前长什么样但如果中间隔了几十轮、塞进了大量代码片段和讨论前面关于 A 文件的关键约束就可能被上下文挤掉。更隐蔽的是单步聊天没有“任务进度”的概念。你没法告诉它“当前处于第 3 步第 1 步已经验收通过现在从第 3 步继续”因为每一步对话结束后除了屏幕上的输出什么都不会沉淀下来。这种模式的代价不只是“多费点 token”而是把开发者的精力大量消耗在维护上下文上。任务小的时候你还能靠自己的记忆兜底任务一大Agent 就会开始遗忘前面的关键决策甚至推翻自己之前的结论。这时候你通常只能做两件事要么开一个新会话把上下文重新喂一遍要么直接放弃继续调教。两条路都很浪费。1.2 三个单步模式下的典型痛点踩过几次坑之后我把单步聊天的痛点归纳成三个上下文不可复用。每开一个新会话项目背景、历史决策、技术约束都要重新交代一遍。Claude Code 虽然有会话恢复能力但恢复出来的上下文并不等于结构化任务状态它只是把聊天记录重新加载回来而已。任务不可追踪。复杂任务在单步聊天里没有“进度”概念你不知道当前是处于“已编码、待测试、已修复、待回归”中的哪一步更没法要求系统“从上次失败的地方继续”。流程不可固化。就算这次你通过几十轮对话把一个功能调通了这套调通过程也无法沉淀成下一次能自动执行的东西。下次遇到类似任务你还是从头聊起。这三个痛点指向同一个根因对话模式把“任务”和“执行过程”混在了一起。要解决它就得从“过程”里把“任务状态”抽出来让它持久化、可追踪、可恢复。后面三节分别对应这个问题的三条解法多 Agent 编排管“任务怎么拆”闭环自愈管“质量怎么保证”Routine 脚本化管“流程怎么固化”。2. 多 Agent 编排把大任务拆成可以接力的小任务2.1 为什么需要多 Agent而不是一个超级 Agent既然 Claude Code 已经具备很强的能力让一个 Agent 干到底行不行我的答案是可以但不划算。一个 Agent 的上下文窗口和注意力都是有限资源。同一场会话里塞的任务边界越模糊、涉及文件越多、角色要求越混乱它的输出就越不稳定。让它在同一段时间里既是架构师、又是编码者、还是测试者它很难在所有角色上都保持同样高的水准。多 Agent 编排解决的核心问题是“角色隔离”把原本属于一个超长提示词里的不同职责拆开放进不同 Agent每个 Agent 只关心自己那一小段狭窄任务。这样做的收益非常直接。首先是每个 Agent 的上下文负担明显变轻专注度更高其次是职责边界清晰之后审查者不会替执行者找补执行者也不会被审查者的思路带偏最后是不同 Agent 之间通过文件系统交换中间产物整个流程天然可审计、可重放后面哪个环节出了错看中间文件就能定位。2.2 三种主流编排模式流水线、并行、主管-子任务我从实际项目中总结了三种足够覆盖大多数场景的编排模式。第一种是流水线模式。任务被切成多个阶段前一个 Agent 的输出是后一个 Agent 的输入。典型结构是“规划 Agent → 执行 Agent → 验证 Agent → 审查 Agent”。流水线适合有明确依赖关系的任务比如先写接口定义、再实现、再测试。它的好处是每一段职责单一坏处是链路较长时前面阶段的质量问题会传导到后面。第二种是并行模式。把互不依赖的子任务分给多个 Agent 同时跑。比如一个项目同时要改前端组件、后端接口、数据库迁移脚本这三个任务只要边界清晰完全可以并行。并行模式能大幅缩短整体耗时但对拆解能力要求很高你必须在任务开始前就把依赖关系梳理干净否则并行跑着跑着发现互相改了同一个文件合并时就要吃苦头。第三种是主管-子任务模式。由一个“主管 Agent”负责任务分配和结果汇总多个“执行 Agent”分别承接子任务。Claude Code 的上下文管理能力可以支撑这种“领导 下属”的结构。主管 Agent 不需要写具体代码它只需要拆解任务、派出执行者、收集结果、判断是否达到完成条件。这种模式最适合任务边界经常变化、需要频繁决策的场景代价是会比流水线多消耗一些 token因为主管需要反复阅读中间产物。选择哪种模式没有绝对答案但要记住一条原则每个 Agent 的上下文占用越少、职责越单一整体输出的稳定性就越高。我在实际项目里最常用的是流水线 主管-子任务的混合结构对外部需求用主管拆解对内部执行用流水线推进这样既保留了灵活性又控制了复杂度。2.3 用文件系统做 Agent 之间的“消息总线”多 Agent 编排里最容易忽略的是通信机制。很多初学者想的是“让 Agent A 把结果告诉 Agent B”但 Agent 之间并没有可靠的直接通信通道你也不应该依赖聊天记录来传话。最稳的做法是把文件系统当成消息总线。具体操作很简单约定好目录和文件命名规则让不同 Agent 读写各自负责的文件。比如项目下固定维护docs/tasks/、docs/reviews/、logs/三个目录规划 Agent 写docs/tasks/plan.md执行 Agent 读plan.md、写docs/tasks/progress.md验证 Agent 把结果写进logs/verify-latest.log审查 Agent 最后产出docs/reviews/final-review.md。所有中间状态都以文件形式存在谁该读什么、该写什么一目了然。这个设计还有一个额外好处任务断点恢复变得极其简单。如果跑到第 3 轮验证时超时了你不需要重新跑整个流程只需要检查logs/里已经生成了哪些文件然后从缺失的那一步继续即可。文件系统的天然持久性恰好弥补了聊天上下文“聊完即焚”的缺陷这是我认为整个架构里最值得先落地的一点。3. 闭环自愈让工作流建立“验证-修复”回路3.1 自愈回路的基本单元Plan → Do → Verify → Fix多 Agent 编排把任务拆开了但拆开之后还有一个问题怎么保证每个环节的输出质量靠人工盯着每一轮结果太累靠写死规则又太僵硬所以要引入闭环自愈。自愈回路的基本单元只有四步Plan、Do、Verify、Fix。Plan由规划 Agent 拆解任务明确验收标准和边界条件。Do由执行 Agent 完成编码、配置、文档等具体产出。Verify用真实命令验证产出比如跑测试、跑静态检查、检查文件是否生成。Fix如果验证失败让修复 Agent 读取失败日志、定位根因、修复代码然后再次进入 Verify。这四步形成一个循环直到验证通过或达到止损条件。核心思想是“把验证当成第一公民”代码写完不等于任务完成只有通过可复现的验证命令才算真正交付。我在最初实践时犯过一个典型错误只让 Agent 自己检查自己。执行 Agent 写完代码后让它“检查一下有没有问题”它十次有九次都会说没问题。这不是它撒谎而是它缺少独立验证的视角。所以 Verify 这一步一定要独立于 Do要么让另一个 Agent 来做要么直接跑外部命令pytest、eslint、go vet、tflint 等无论如何都不能让执行者自己给自己背书。3.2 验证条件与止损机制的关键设置闭环自愈最容易翻车的点是两个验证条件不明确和没有止损机制。验证条件要尽量具体并且必须可命令行判断。不要写“检查代码质量”而要写“运行 pytest退出码为 0 才算通过”不要写“确认接口没问题”而要写“curl 指定接口响应里包含预期的 JSON 字段”。验证条件一旦模糊自愈循环就会变成猜谜游戏。实际操作中我会在规划阶段就把验证命令写在任务文件里执行 Agent 和验证 Agent 都读同一份文件确保标准一致。止损机制同样重要。典型参数有三个最大重试轮数MAX_ROUNDS、单轮超时时间TIMEOUT、最大消耗 token 上限。我自己常用的默认值是最大重试 3 轮、单轮命令超时 300 秒。设定这个值的原因是超过 3 轮还没修好通常是 Agent 根本没定位到根因继续修只会循环与其让它继续烧 token不如停下来换人换思路。另外要留意修复范围的控制。修复 Agent 只能修验证失败暴露出来的问题不能借机重构、改无关代码、升级依赖。这个约束必须写进任务提示词里。不然你会发现一个很有意思的现象每次验证失败Agent 都顺手把周边代码“优化”一遍验证可能过了但你压根不知道它改了什么这种不确定性比报错更可怕。3.3 用日志和状态文件打造可观测性闭环自愈驱动起来之后最直观的问题是它现在像一个黑盒出了问题我没法判断卡在哪里。解决办法是提前铺好观测设施。每一次验证执行都要把标准输出和标准错误重定向到带序号的日志文件比如logs/verify-01.log、logs/verify-02.log。每一次修复也要把修复 Agent 的产物摘要写进logs/fix-01.md。每一个环节结束更新一次状态文件docs/tasks/status.md记录当前阶段、最近一次验证结果、剩余重试次数。这套观测设施的价值在排障时会充分体现。比如某个测试在第三轮才通过你想知道前两轮到底修了什么打开fix-01.md和fix-02.md就能复盘。比如某个功能上线后又出现回归状态文件可以告诉你当时是哪一轮验证通过的、通过前有哪些修改这些信息比单步聊天的聊天记录可靠得多。状态文件本身也是给 Agent 看的主管 Agent 只需要读status.md就能知道下一步该派哪个子 Agent 出去而不用重新读一堆日志和代码。4. Routine 脚本化把约定俗成的流程固化成可复用命令4.1 Routine 与普通提示词的根本差异多 Agent 编排解决了任务怎么拆闭环自愈解决了质量怎么兜底但还有一个问题没解决这套流程难道每次都要人肉重写一遍吗这就是 Routine 脚本化要做的。我习惯把 Routine 理解为一组预置好的、参数化的工作流模板。它和普通提示词的差异是本质性的提示词是一次性的Routine 是结构化的、带参数的、可复用的。提示词写的是“请你帮我看一下这段代码有没有问题”Routine 写的是“收到目标目录后依次执行列表、通读、分级、输出报告且过程中不允许修改源码”。后者把思考过程、执行步骤、验证标准全部固化成模板同一个 Routine 可以反复使用也可以在不同项目之间搬移。在 Claude Code 里Routine 的载体主要有两个一个是项目级的CLAUDE.md指引文件它为所有 Agent 提供了通用的项目背景和工作约定另一个是自定义命令放在.claude/commands/目录下的 Markdown 文件。这两者叠加起来就能把“约定俗成的流程”变成“可调用的命令”。我自己的项目里CLAUDE.md负责写“我是谁、这个项目怎么跑、代码风格是什么”自定义命令负责写“针对某类任务按什么步骤执行”。4.2 编写一个可复用的审查 Routine下面我用一个实际的代码审查 Routine 来做演示。在.claude/commands/review.md里写上--- description: 对指定目录执行一次多视角代码审查 argument-hint: 目标路径 allowed-tools: Read, Glob, Grep, Write --- 你是一名严格的代码审查者。请遵循以下步骤完成审查 1. 用 Glob 和 Grep 列出 目标路径 下的全部源码文件忽略构建产物、依赖目录和历史备份 2. 逐文件通读重点检查命名是否自解释、异常处理是否覆盖、边界条件是否有遗漏、是否残留调试输出 3. 将发现的问题按严重程度分为 P0必须修复、P1应该修复、P2建议优化三级 4. 在 docs/reviews/ 下生成 review.md内容包括 - 被审查文件清单 - 每个问题的文件路径、大致行号、源码摘要、出现原因、修改建议 - 一句话总体结论 你全程只读源码、只输出审查报告不得直接修改任何源文件。保存之后在 Claude Code 交互终端里输入/review src/它就会自动进入审查流程。这里的核心是 front matter 里的argument-hint和allowed-tools前者让你能把目标路径作为参数传进去后者限制了它只能读文件、不能乱改源码从机制上防止审查 Agent 越权。我每次新建项目都会把这套命令拷进去再配一个/test命令专门负责跑测试并把结果整理成报告时间长了就形成一套个人工作流工具箱。4.3 从交互式到批处理把 Routine 接进无人值守流程Routine 的进阶用法是脱离交互终端直接走批处理。Claude Code 提供了非交互式的打印模式可以用claude -p接一段提示词直接执行结果输出到标准输出。这就意味着 Routine 可以被 shell 脚本、定时任务、持续集成流程调用变成无人值守的自动化环节。实际项目里我是这么用的在持续集成里加一个“AI 审查”步骤拉取代码后调用审查 Routine把生成的问题清单作为 MR 的评论发布出来在提交代码前加一个“提交信息生成”Routine读取git diff按约定格式输出 commit message。这些 Routine 不需要人坐在终端前交互只是作为一个环节被管道式地调用。做这一步改造时有三个细节要注意。第一批处理模式下 Agent 看不到交互提示所有必要信息都必须塞进提示词和上下文文件里所以提示词要写得比交互模式更自包含。第二退出码处理要明确claude -p执行失败不能静默吞掉否则流水线会在错误结果上继续跑。第三批处理模式的输出是纯文本不适合长对话更适合“生成报告”“生成提交信息”“生成测试计划”这类短结果任务涉及多轮自愈的复杂任务还是交给编排脚本更合适。5. 实操示例一个可复用的多 Agent 编排脚本5.1 场景设定与目录约定我把前面提到的三套机制组装成一个完整的编排脚本。场景设定如下需求方在一个 Markdown 文件里描述了一个功能需求我们需要让 Claude Code 完成“拆解计划 → 编码实现 → 测试验证 → 自愈修复 → 最终审查”的完整流程。项目目录统一约定为docs/tasks/存放需求、计划、状态文件docs/reviews/存放审查报告logs/存放验证与修复日志初始化时先创建这些目录并把需求写在docs/tasks/current-task.md里。5.2 一个完整的编排脚本骨架下面是可以直接放到项目根目录执行的脚本我把它整理成了骨架#!/usr/bin/env bash set -euo pipefail PROJECT_DIR$(pwd) MAX_ROUNDS${MAX_ROUNDS:-3} TASK_FILE${TASK_FILE:-docs/tasks/current-task.md} STATUS_FILEdocs/tasks/status.md mkdir -p docs/tasks docs/reviews logs echo 当前阶段: plan $STATUS_FILE # 阶段 1规划 Agent把需求拆成实现步骤和验收标准 claude -p 阅读 $TASK_FILE把需求拆解为实现步骤和验收标准输出到 docs/tasks/plan.md每一步都要给出可执行的验证命令 \ --allowedTools Read,Glob,Grep,Write,Edit echo 当前阶段: implement $STATUS_FILE # 阶段 2执行 Agent按计划完成编码 claude -p 阅读 docs/tasks/plan.md按计划完成全部编码工作不要修改验证命令和测试逻辑如有依赖缺失记录到 docs/tasks/deps.md \ --allowedTools Read,Write,Edit,Glob,Grep,Bash || true # 阶段 3验证 自愈循环 for round in $(seq 1 $MAX_ROUNDS); do echo 验证轮次: $round $STATUS_FILE # 读取计划中的主验证命令执行并记录日志 VERIFY_CMD$(grep -A1 主验证命令 docs/tasks/plan.md | tail -n1) echo 执行验证命令: $VERIFY_CMD if eval $VERIFY_CMD logs/verify-$round.log 21; then echo 验证结果: passed (round $round) $STATUS_FILE break fi echo 验证结果: failed (round $round) $STATUS_FILE # 修复 Agent只修验证暴露的问题 claude -p 阅读 logs/verify-$round.log、docs/tasks/plan.md 和相关源码定位失败根因并修复只修复该问题禁止无关重构修复后把改动摘要写入 logs/fix-$round.md \ --allowedTools Read,Write,Edit,Glob,Grep,Bash || true done echo 当前阶段: review $STATUS_FILE # 阶段 4审查 Agent输出最终审查意见 claude -p 阅读 docs/tasks/plan.md、全部源码改动和 logs/ 下的日志输出最终审查意见到 docs/reviews/final-review.md包含问题清单和交付结论 \ --allowedTools Read,Glob,Grep,Write,Edit这个脚本的骨架逻辑是先让规划 Agent 产出带验证命令的详细计划再让执行 Agent 实现然后用外部命令做验证。验证失败时进入修复循环最多重试MAX_ROUNDS次。全部验证通过后再由审查 Agent 做最终把关。5.3 关键参数与执行过程拆解脚本里最值得留意的是三个设计细节。第一验证命令来自规划阶段生成的plan.md。这样规划 Agent 写下的验收标准会被真实执行整个任务从源头就有“如何判定完成”的定义。我在plan.md里要求规划 Agent 输出一行可执行的主验证命令脚本通过grep把它抽出来用eval执行。实际项目里你可以把这一行换成pytest -q、npm test、go test ./...或者任何项目真实的验证命令。第二修复 Agent 的提示词里强制加了两条约束“只修复验证暴露的问题”和“禁止无关重构”。这看起来像废话但如果你不加修复 Agent 很可能会顺手改掉一堆它觉得“不够优雅”的代码导致你在最终审查时面对一大坨来源不明的改动。脚本里还把修复摘要写入logs/fix-$round.md这些摘要不仅是审计记录也给后续轮次的修复 Agent 提供了上下文避免它重复踩同一个坑。第三set -euo pipefail配合|| true的控制。脚本里执行 Agent 和修复 Agent 调用都加了|| true是因为 Claude Code 命令遇到某些预期内的情况可能返回非零退出码而你并不想让整个编排在规划之外中断但验证命令那边不能加|| true它返回非零就代表验证失败必须进入修复循环。哪些环节“允许失败”哪些环节“不允许失败”这个边界一定要提前想清楚。整个脚本执行结束后你可以在docs/tasks/status.md里看到完整的时间线哪个阶段开始、哪一轮验证失败、哪一轮通过、最终审查什么时候做完。基于这套状态文件你甚至可以把脚本做成支持断点续跑的版本检查STATUS_FILE里的当前阶段跳过已经完成的部分直接从失败点继续。这个改造在任务时间特别长、容易超时断线的时候非常实用。6. 常见问题与排查技巧实录6.1 症状排查速查表下面是实操中最常遇到的几类问题和排查思路我整理成了速查表。症状可能原因排查思路与方案自愈循环修了三轮还在反复失败修复 Agent 没有真正拿到失败日志或代码里存在多个叠加问题逐个修永远修不干净先检查logs/fix-*.md确认修复 Agent 每次是否真的读取了上一轮日志如果是叠加问题应在验证命令里先加一条“快速定位”指令把多个失败用例一次性暴露给修复 Agent编排脚本跑到一半就中断某个claude -p调用退出码非零被set -e捕获后终止确认该环节是否“允许失败”对允许失败的环节显式加 执行结果和计划不一致执行 Agent 没有严格按plan.md执行自作主张改了设计在提示词里要求执行 Agent 每个文件改动前先对照计划并把“与计划不一致的地方”写入单独文件由审查 Agent 复核多个 Agent 同时改同一个文件导致冲突编排阶段没有做好依赖隔离在拆解计划时对每个子任务标注“涉及文件”字段不同子任务尽量分配不同文件实在要共享文件就强制串行输出大量“它以为验证通过了”验证命令太弱比如只检查进程退出码没检查真正结果强化验证命令除了退出码还要 grep 输出里的关键断言或直接跑测试用例并检查测试报告会话超时或上下文爆掉单个 Agent 处理范围超出上下文极限缩小 Agent 职责范围把大任务拆成更多子任务用文件系统中转中间产物不要把所有历史都塞进提示词6.2 几条独家避坑经验第一永远让验证独立于修复。最理想的状态是验证用真实的外部命令完全不依赖任何 Agent 的判断。如果实在没有测试框架至少也要用grep检查关键标记、用构建命令检查编译、用脚本检查目录结构是否完整。让 Agent 自己检查自己的后果我已经在前面说过不会再上第二次当。第二给每个 Agent 的“权限”立规矩。执行 Agent 允许读写源码审查 Agent 只给只读工具规划 Agent 只写docs/目录验证阶段不调 Agent 直接用命令。这样每个 Agent 出问题的影响面都被限制在最小范围。我在自定义命令的 front matter 里配置allowed-tools就是干这件事的。第三状态文件和日志目录要纳入版本管理。很多人觉得日志是临时产物不值得提交但在这个架构里它们是任务状态的一部分。项目中断之后我是靠docs/tasks/status.md和logs/里的文件来决策要不要继续、从哪一步继续的。这些文件的沉淀也会变成你调优流程的第一手数据翻一遍历史日志你很快就会发现哪个 Agent 的提示词表述不清楚、哪类任务的重试率特别高。第四不要在一个脚本里把所有 Agent 都串成一条不可打断的长链。我踩过这个坑之后的做法是每个阶段之间留一个检查点检查点只判断“关键产物是否生成”“验证文件是否存在”不判断内容好坏。坏不坏留给后面的审查 Agent但流程不能因为一个格式不对的中间文件就整体卡死。我自己在过去这段时间把 Claude Code 从“一个聪明的聊天窗口”调教成“一套能自动运转的代码流水线”之后最大感受其实不是工具本身变强了而是我对“分工”和“退出条件”的理解变清晰了。Agent 之间的职责一旦模糊流程就会乱自愈循环一旦没有止损就会变成无限烧 token 的绞肉机。现在我跑任何一条 Claude Code 流水线都会先花十分钟把四个问题想清楚谁拆任务、谁执行、谁验证、最多重来几次。想清楚之后剩下的事情反而很简单。如果你也在折腾类似的工作流不妨从文件系统中转和“验证独立于执行”这两点先入手你会发现整个架构立刻稳了一大截。