☰
多Agent编排+闭环自愈:让Claude Code告别低效单步聊天
2026/10/8 3:51:47 网站建设 项目流程

最早用Claude Code的时候,我的用法很朴素。打开终端,输入一句需求,它回一段代码,我再贴一句报错,它再改一版……这本质上是在把一个拥有完整工具链的Agent,当成一个知识面很广但手脚被绑住的聊天机器人。单步聊天的最大问题,不是它答得不好,而是你根本不给它执行的机会。Claude Code是能直接读写文件、执行命令的,但在默认交互模式下,你每次都要等它给一个“下一步做什么”的建议,然后自己手动复制粘贴、跑命令、再把输出贴回对话。这个过程中,上下文里混进了大量中间产物,模型的有效注意力被稀释,重复劳动也多得吓人。

说个我自己的场景。有一次改一个TypeScript项目的类型错误,我对模型说“帮我看看这个ts类型错误”,它分析了一通,告诉我可能是泛型写错了。然后呢?我还得自己打开文件、改代码、跑tsc,再从一堆输出里找到下一条报错。那种用法下,一条错误要来回三个回合,差不多十分钟。后来我改成直接下命令:“找出所有tsc报错,逐个修复,修复完再跑一次tsc直到通过。”它自己封装了一个命令循环,几分钟就把24个类型错误全改完了。这就是“问题”和“任务”之间的差别。

1. 单步聊天为什么低效:从Agent的“手”和“脑”说起

1.1 默认用法:你问我答的循环

Claude Code刚火起来的时候,很多人的用法跟我最开始一模一样:把它当成一个更聪明的终端问答助手。问一个语法问题,它答得很漂亮;让它写个函数,它也能直接生成。可一旦任务变复杂,这种“你问我答”的循环就彻底露馅了——因为每次交互都在等一个“下一步”的人工判断,而Agent自己并不会往前推进。

举个例子,你让它“修复登录页面的报错”。它会先读文件、给你一个分析,然后停下来等你说“继续”。你以为它全懂了,其实它只是接到了一个新指令。在这个过程中,你不仅要不停地喂上下文,还要负责判断它说的对不对、下一步该怎么走。本质上,你把本该由Agent完成的“规划-执行-验证”拿回了自己手里,AI只负责垫话。时间一长,你自然会觉得Claude Code好像也没比ChatGPT强多少。

但问题的根源不在模型,而在交互模式。Claude Code的定位本来就是一个可以自主执行任务的Agent,它有自己的“手”和“脑”。手,是它能调用bash、读写文件、操作Git的工具链;脑,是它基于当前上下文的推理能力。单步聊天最大的问题,就是只让脑工作,不让手工作。结果是:模型在空转,你在打杂。

1.2 Agent需要的是“任务”而不是“问题”

如果你把一个具体的、可验证的任务交给Claude Code,它会把手脚当成自己想问题的方式,而不是把工具使用建议抛给你。这一点,是我觉得Claude Code和其他聊天助手最本质的区别。所谓“任务”,至少要包含三个要素:明确的目标、可执行的步骤、可验证的完成标准。比如“把src/utils/format.ts里的函数改成支持可选参数,并用npm test跑通相关单测”就是一个任务;而“帮我改一下这个工具函数”则只是一个问题。

任务化之后,你会自然遇到另一个问题:单个Agent的上下文窗口和工具边界是有限的。你要它既做需求分析、又写代码、又跑测试、又写文档,它在一棵上下文里反复切换,很快就会开始前边说过的忘了后边,或者把一个子任务的结果错误地套到另一个子任务上。这时候,从单Agent走向多Agent编排,就不是一个可选项,而是一个必选项。

我在实际项目里会把任务拆成三类:分析型、执行型、验收型。分析型Agent负责读需求、看代码结构、给方案;执行型Agent按照方案改代码;验收型Agent独立跑测试、检查lint、输出结果。拆完之后,主Agent变成一个调度者,类似于项目负责人,它不需要知道每一行代码该怎么写,只需要知道任务边界、交付物和验收标准。这个模型跑顺之后,效率是直线上升的,但它依赖一个好的编排方式,而编排的第一课,就是学会定义子Agent。

2. 多Agent编排:把工程问题拆成一支能自己开会的团队

2.1 子代理(Subagent)的分工逻辑

Claude Code本身支持子代理(subagent)机制。你可以定义不同的角色,每个角色有自己的system prompt、工具权限和任务边界。用大白话说,就是给每个Agent写一份“岗位说明书”。主Agent会扮演项目经理,把整体任务拆解后,分发给不同的子Agent。

我习惯的拆分方式是:core agent(核心执行)负责代码修改,screener agent(检查员)负责审阅代码和跑测试,docs agent(文档员)负责更新文档和生成变更日志。每个子Agent执行时拥有相对独立的上下文窗口,它只看到自己需要的输入,避免把无关信息带进来。

有一次我需要给一个老项目加一个CLI命令,同时要求不能改动现有CLI的兼容性。我拆了个执行Agent去改代码,又拆了个检查Agent专门去跑此前留下的几十个快照测试。执行Agent不知道测试细节,它只按照计划改代码;检查Agent则只看测试结果和git diff,它甚至不知道需求是什么。由于两个Agent上下文完全隔离,执行Agent不会因为看到一堆测试代码而分心,检查Agent也不会在改代码时“顺手优化”别的模块。最后主Agent把两个结果拼起来,生成一份总结。整个过程如果靠单Agent单步聊天,估计又要来回扯半天。

这里最容易被忽略的一点是:子Agent不是越多越好。每个子Agent都会消耗主Agent的调度成本和API调用额度。如果任务本身只有200行改动,拆3个角色就足够了;如果是一个跨模块的大型重构,再扩大到5到6个角色才有意义。我见过有人一个简单任务开了8个Agent,结果大部分时间都花在“向主Agent汇报”和“被主Agent追问”上,反而更慢了。

2.2 编排过程中的上下文隔离与信息汇总

上下文隔离是多Agent编排的核心收益,但它也有代价:子Agent执行完后,主Agent需要知道发生了什么,也就是日志和总结。我的做法是,在子Agent的system prompt里明确规定输出格式:改动文件列表、关键变更内容、测试结果、遗留风险。这样主Agent拿到的是一个结构化summary,而不是一大段自由文本。

我常常在Prompt中加一句:报告不超过300字,用列表列出文件路径和关键变化;如果没有变化,写no change。就这么一句,主Agent在汇总时会舒服很多,不会因为某个子Agent铺陈了一堆推理过程而挤占上下文。

编排时还要注意并行度。Claude Code的并发能力不是无限的,多个子Agent同时跑,很容易触发API配额和限流。我之前一次性开了8个并发子任务,结果中间被限流,整个任务链卡死。后来我做了个节流:分析类任务可以并行5个,执行类任务串行2个,验收类任务并行3个。这个配置不是固定的,但它确实避免了很多次队列堵塞。

关于子Agent的工具权限,我强烈的建议是给执行类Agent开权限,给分析类Agent关掉或限制执行命令。分析类Agent大部分时间只需要读代码、查文档,给它可写权限风险很大,它有可能基于某个片段“自作主张”去改代码。用Claude Code定义子Agent时,可以用allowedTools参数控制,或者在Routine里限定它只使用read-only工具。权限这件事,宁可一开始收紧,也不要事后追责。

3. 闭环自愈:让Agent在拿到失败结果后自己爬起来

3.1 自愈机制的原理

闭环自愈这个词听起来高级,其实原理非常朴素:跑命令→看结果→失败就分析原因→改代码→再跑命令→直到成功或达到上限。Claude Code天生有这个能力,因为它可以读取exit code、分析错误日志、修改文件、重新执行。问题在于,你是否把这件事设计成了一个明确的循环。

我最早遇到尴尬的场景是:Claude Code跑测试失败了,它把失败信息输出来,然后问我“要我给你继续改吗?”不是,你都看到失败了,还问我干什么?后来才意识到,这其实是交互模式的锅——默认情况下,它的很多操作被设计成需要你确认。如果你希望它自主完成“修复-验证”循环,就得给它更明确的指令和权限。

要让闭环跑起来,至少要满足三个条件。第一,验证命令必须是明确的、可自动执行的,比如npm test、pytest、tsc --noEmit,而不是那种需要人工判断的“你感觉对不对”。第二,Agent要有修改文件的权限,否则它只能提建议。第三,给一个“重试上限”和“失败退出条件”,避免它在同一个坑里无限循环。

我的一个实际做法是,在任务里写死循环规则:“运行npm test;如果失败,分析第一段报错,定位到具体文件和行号,修改对应代码;每次只修一个错误;修完重跑;重复最多3次;3次后仍然失败,停止并输出一份错误归类报告。”把这段话作为Routine或直接写进prompt,效果立竿见影。

3.2 用Routine把自愈循环固化成流程

自愈循环如果每次都是手动写在prompt里,久了还是会不一致。所以我把它做成一个Routine,叫fix-and-verify。这个Routine包含四段内容:诊断命令、修复策略、验证命令、重试限制。

诊断命令指什么?先用静态检查指令,比如tsc --noEmit,快速找到所有可疑点;如果静态检查没有报错但测试失败,再跑测试命令看堆栈。这样分两步,能避免Agent在还没搞清楚问题的时候就乱改代码。

修复策略要注意,不要让它“改到成功为止”,而要让它“根据失败原因针对性修复”。两者差别很大。很多Agent在反复失败后,会开始随机尝试各种做法,最后代码改得面目全非但测试刚好过了,这其实是最危险的结果。我在Routine里会加一句:“每次修改前,先列出可能的根因,选择一个最可能的,并说明你改了哪个文件、为什么;禁止为了通过测试而绕过测试,禁止删除测试或修改测试预期值。”这句话堪称保命。

验证命令我一般拆成两步:第一步是快速校验,比如eslint、tsc,几秒钟出结果;第二步是完整测试,可能需要几分钟。快速校验能提前拦截大量低级错误,省得Agent每次都等完整测试跑完才发现语法错误。

重试上限建议设置在3到5次。超过上限之后,不要再继续硬试,而是让Agent停下来输出一份“失败模式分析”,内容包括:尝试过的修复、每一次失败的现象、怀疑的根因、下一步建议。这份分析的价值很大,它能把决策权交回给你,而不是让Agent继续做无意义的空转。

这条自愈循环还可以设置一个“成功标准”:只有当验证命令的退出码为0,且没有改动任何测试文件本身时,才算是真正修复成功。否则不管测试过没过,都要重新审查。我踩过几次“测试被注释掉所以通过了”的坑之后,就把这条写进了所有自愈Routine里。

4. Routine脚本化:把重复工作沉淀成可复用的行为模板

4.1 Routine和普通Prompt的区别

Routine这个词,你可以理解成给Agent的一套“可复用操作手册”。普通Prompt只表达一次意图,而Routine表达的是一个固定的执行框架。比如“帮我看看这个项目的README”是Prompt;“检查仓库、提取项目配置、纠正文档与脚本不一致之处、输出变更摘要”这是一个Routine。

Routine最有价值的地方在于,它能沉淀个人经验。我团队里最常用的一个Routine叫pre-push-check,在git push之前自动跑一遍:格式化、lint、类型检查、单测、更新CHANGELOG。以前这些事要么靠人手动做,要么写shell脚本。现在写成Routine之后,Agent能根据实际报错自己修复,比shell脚本智能得多。

Routine的设计原则是:输入明确、步骤可执行、输出有约束。可以用Claude Code支持的CLAUDE.md文件来定义全局规则,再把更细粒度的流程写在项目里。比如全局规则规定“不要修改测试文件”,而具体流程里的“先跑lint再跑单测”则放在Routine中。

4.2 如何编写一个可维护的Routine

我写Routine的习惯是:每个Routine只干一件事,长度控制在30行以内。超过30行就拆成两个子Routine,再让父Routine调用它们。不要写那种什么都管的“万能流程”,那样不仅容易出错,后期还特别难维护。

一个典型的Routine配置会包含name、description、steps、constraints。下面是一个非常简化的参考,用YAML写:

name: fix-and-verify description: 修复测试失败并自动验证,最多尝试3次 context: repo: {{repo_path}} test_command: {{test_command}} steps: - run: "{{test_command}}" - on_fail: analyze the first error block - on_fail: locate file and line, modify source code - on_fail: rerun "{{test_command}}" - repeat: until success or attempt >= 3 - on_exhaust: write failure-analysis.md constraints: - never modify test files - never skip failing tests by commenting them out - max_attempts: 3

当然,实际使用时不一定要写严格YAML,Claude Code更习惯自然语言指令。但把这样的结构放在prompt或者Routine文件里,能极大减少Agent对任务理解的偏差。

参数化很重要。同一个fix-and-verify,可能今天跑的是pytest,明天跑的是jest。如果我把命令写死,Routine就失去了通用性。我前面用的{{test_command}}这类模板变量,在实际使用中可以用环境变量或者前置prompt填充。比如:

运行 fix-and-verify,test_command 设置为 npm run test:unit,repo 路径是 /path/to/project

这样Agent会将Routine模板实例化,再按实例执行。一次编写,多次复用,团队里其他人也能直接用。

4.3 多Agent与Routine的组合

把多Agent和Routine结合起来,是我目前用得最顺手的一种生产模式。简单来说,Agent是“角色”,Routine是“技能”,主Agent负责给每个角色发对应的技能。

比如我定义一个reviewer Agent,它不会写代码,只做代码审查。它的“岗位说明书”里写了:读取git diff、跑静态检查、对照需求文档、输出审查意见。它每次执行时调用的,其实就是一个review-routine。如果需求变了,我只需要改review-routine的检查项,不用动Agent定义。这种“角色不变,技能可替换”的架构,维护成本非常低。

再一个例子是docs-bot Agent。它不碰业务代码,只负责在每次功能合并后,根据commit message和git diff生成CHANGELOG。这个Agent的Routine里规定了格式、分类标准(feat/fix/docs/refactor)、中文还是英文输出。写新功能的同事完全不用操心文档,合并后自动生成草稿,人工过一遍就行。

这个组合最深的收益是:多Agent负责“把对的人放到对的任务上”,Routine负责“让每个人按最熟练的流程干活”。两者叠加之后,大量重复性的项目杂事从我的待办清单上消失了。当然,这个组合也不是没有坑。最大的坑是流程文件膨胀:如果你每个Agent都带上三四个Routine,整个项目的CLAUDE.md会变得特别长,导致每次请求消耗的上下文token直线上升。我现在的策略是,把公共规则放在全局CLAUDE.md,把具体流程拆成独立的Routine文件,Agent按需加载,而不是一次性全塞进去。

5. 环境准备与模型接入实战:从安装到切换DeepSeek/Qwen/GLM

5.1 安装与基础配置

先说安装。Claude Code的官方形态是一个终端CLI工具,也可以用VS Code扩展来嵌入IDE工作流。最常见的安装方式是用npm全局安装:

npm install -g @anthropic-ai/claude-code

安装完成后,在终端里直接敲claude就能进入交互式会话。VS Code版本可以在扩展市场里搜索Claude Code,装完后它会复用同一个底层的认证和配置。

如果你之前已经装过旧版本,可以随时用claude update检查并升级到最新版本。命令行工具的好处是升级特别轻量,不会像IDE扩展那样需要反复重启窗口。不过要提醒一句:Claude Code迭代速度很快,版本之间配置文件的兼容性偶尔会出问题,升级后如果发现某些自定义命令失效,优先检查~/.claude/下的配置是否被重置了。

环境变量是配置的核心。这里列出几个最常用的:

环境变量作用示例值
ANTHROPIC_API_KEY官方API密钥sk-xxx
ANTHROPIC_MODEL指定模型名claude-sonnet-4-xxx
ANTHROPIC_BASE_URL自定义API端点https://api.xxx.com
ANTHROPIC_AUTH_TOKEN第三方兼容接口的令牌与API密钥类似

我在团队里会专门写一个.env文件管理这些变量,再用shell的export加载。不推荐把密钥直接写进CLAUDE.md里,那个文件会被Agent读取,可能被包含进发出去的prompt中,存在泄露风险。更麻烦的是,如果团队仓库里不小心提交了密钥,用git history都能翻出来。建议把所有密钥放到gitignore的本地文件中,比如写到~/.bashrc。

5.2 用cc switch接入第三方模型

很多团队不用官方API,因为成本和额度不好控制,会选择接入DeepSeek、Qwen(通义千问)、GLM(智谱)这类第三方模型。这个思路本身没问题,但要注意:Claude Code一开始是为Anthropic官方API设计的,第三方模型必须走兼容端点才能被识别。说得直白点,Claude Code内部用的是Anthropic Messages API和Tool Use协议,第三方模型服务商需要提供一个兼容这个协议的端点,才能完全替代官方API。

目前社区里常见的做法是用cc switch这类工具来管理多套API配置。它的核心能力就是快速切换不同的模型提供商,免去手动改环境变量的麻烦。你可以在一个配置文件里预置几套端点:一套指向官方API,一套指向DeepSeek,一套指向Qwen,然后一条命令切过去。我自己的配置大概是这样的:

cc switch use deepseek # 当前已切换到 DeepSeek 接入配置 ANTHROPIC_BASE_URL=https://api.deepseek.com/anthropic ANTHROPIC_AUTH_TOKEN=sk-xxx ANTHROPIC_MODEL=deepseek-chat

如果不用cc switch,手动改环境变量也完全可以。只要保证ANTHROPIC_BASE_URL和ANTHROPIC_AUTH_TOKEN这两个变量指向对应的第三方端点,再通过ANTHROPIC_MODEL指定要用的模型名就行。接入Qwen或GLM时的套路完全一样,只是Base URL和模型名不同。这类第三方接入我测试下来的整体感受是:日常代码生成、代码解释、文档编写这些场景没问题,但工具调用的稳定性和官方模型相比还是有一点差距。

具体来说,如果你想真正跑起前面说的多Agent编排和闭环自愈,Agent需要反复调用终端命令、读取返回结果、再决定下一步动作。这非常依赖Tool Use协议。官方模型在这个协议上经过大量对齐,第三方模型有时候对工具调用的格式理解不准确,会出现返回结果无法被Claude Code解析、或者Agent不敢调用工具的情况。碰到这种情况,我通常两条路选一条:要么改用对Tool Use支持更好的模型版本,比如偏Agent的GLM-4.5系列、Qwen3-Max;要么把Routine里的任务拆小,减少单次会话里对工具的依赖。

5.3 让Claude Code直接执行终端命令

关于“Claude Code如何直接执行终端命令”,我得多说几句。这个能力是真正的生产力来源,也是很多新手不敢用、老手乱用的分水岭。

Claude Code执行命令需要权限认可。默认情况下,它会把要执行的命令列出来等你确认;如果你想让它完全自主运行,可以切到YOLO模式(也就是全自动执行模式)。我强烈建议在整套流程跑顺之前,不要开YOLO模式。我第一次用的时候开了,结果它在我还没看清楚的情况下,执行了一串不该执行的命令。虽然没出大事,但那一下就让我意识到权限控制不能省。

我的习惯是先给Agent一个allow列表,把项目内常用的npm、git、python等命令放进去,其余命令仍然每次确认。用Claude Code配置时,可以使用设置文件里的permissions字段,比如:

{ "permissions": { "allow": ["npm test", "npm run lint", "git status", "git diff"], "deny": ["rm", "git push", "npm publish"] } }

deny列表同样重要,尤其要把git push、删除文件这类命令挡在自动执行之外。我见过有同事让Agent自动跑脚本,结果它想把一条测试分支直接推送到生产分支。幸好deny列表拦了一下。

执行记录也值得留意。Claude Code会在~/.claude/projects下按项目保留会话历史,你可以在这里看到每个Agent实际执行过的命令。排查问题时,这个目录能给出很多线索。如果Agent做了一些你无法理解的操作,别急着下结论,先翻一下执行记录,大概率能找到它判断依据的来源。

6. 一套可落地的参考架构:多Agent编排×闭环自愈×Routine

6.1 架构总览

最后用一个实际跑过的例子把这些概念串起来。我们的目标是从一句需求出发,自动完成“分析-实现-验证-修复-文档”全流程,不需要人工在中间反复确认。

整个流程可以拆成下面几个环节:

  1. 主Agent接收需求,拆成代码改动、测试验证、文档更新三块。
  2. 分析Agent先读一遍仓库结构和相关代码,输出改动方案。
  3. 执行Agent依据方案修改代码,此时它只处理自己负责的文件。
  4. 验收Agent独立运行lint、类型检查和测试,输出通过或失败的结论。
  5. 如果验收失败,触发fix-and-verify Routine,进入闭环自愈循环。
  6. 自愈循环达到重试上限仍未通过时,输出失败分析报告,停下等人处理。
  7. 全部通过后,docs Agent根据git diff生成CHANGELOG草稿。
  8. 主Agent汇总所有子Agent的结果,输出最终报告。

我在项目里把这套东西组织成一个叫auto-task的Routine,在主会话里执行:

请运行 auto-task: 需求:给订单模块增加导出CSV的功能,保留原有接口兼容性

之后我只需要盯最终汇总就行。实际跑下来,一次完整的自动任务,大概需要消耗两倍于单步聊天的token,但人工介入时间从半小时压到了五分钟。这也就是我标题里说的“告别低效单步聊天”的真正含义——不是让AI说话更快,而是让它自己把事情做完。

6.2 我实际用过的配置片段

这里给出一个简化的subagent配置示例,用JSON格式。它定义了一个验收Agent,专门负责跑测试并输出结构化结果:

{ "name": "verifier", "description": "独立运行测试与静态检查,不修改源码", "allowedTools": ["bash", "read_file", "list_dir"], "systemPrompt": "你是验收Agent。你只负责执行验证命令并反馈结果。不要修改代码。输出格式:pass/fail、失败命令、失败摘要、失败文件与行号。报告不超过200字。" }

在会话中,主Agent通过任务指令把需求与文件范围传给它。我记得最开始的版本没有加“fail摘要必须包含文件与行号”这条,导致验收Agent只报“测试没过”就交差,执行Agent拿不到定位信息,白白多跑了一次自愈循环。加了这个约束后,整个链路顺畅很多。

6.3 踩坑记录与性能优化

这套架构跑得久了,有几个问题比较突出,我说点真实的踩坑记录。

第一个是上下文膨胀。每个子Agent都会把报告传回主Agent,如果主Agent不加筛选地把所有报告塞进上下文,几十个来回后窗口基本就满了。解决方法是让子Agent的报告尽量精炼,并在主Agent汇总时做增量摘录,而不是保留完整历史。

第二个是并发阈值的把握。Claude Code支持同时跑多个子任务,但不是无限并发。我实测过,5个并发是比较舒适的档位,超过8个很容易触发API速率限制,导致任务失败。建议在编排时设置一个简单的信号量,比如同时最多4个,防止整条流水线因为多个任务同时限流而全部重启。

第三个是自愈循环要有“止损线”。我之前提过最多3次重试,这个数字不是拍脑袋定的。重试次数太多,Agent会开始做无意义的探索式修改,既烧token又容易把好代码改坏;重试次数太少,又处理不了偶发性的环境问题。3次是我在大多数项目里试出来的平衡点。如果你跑的是很稳定的项目,可以到5次;如果是在依赖很多的老项目上,2次比较稳妥。

第四个是环境一致性。Agent执行命令的环境和你本地必须保持一致。如果你在README里告诉Agent用npm install装依赖,但本机已经用了pnpm,那Agent跑出来的结果很可能和你的预期完全不一致。我在项目里会把包管理器、Node版本、Python版本这些信息写进CLAUDE.md,让Agent不要自行切换工具链。

最后再分享一个小习惯:每次跑完一个完整流程,我会把主Agent的总结和所有子Agent的关键输出存成一个markdown报告。这些报告既是团队的知识沉淀,也是后面排查问题的对照样本。时间久了你会发现,这套组合拳最核心的价值不是省了某一次操作,而是让你从一个个点地去盯AI,变成只负责决策和验收,把执行彻底交给这套编排体系。跑过几次完整流程之后,你就再也不想回到那种一句话一句话喂AI的低效状态了。

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

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

立即咨询