☰
Claude Code子代理配置与实战:从入门到避坑
2026/10/19 8:08:33 网站建设 项目流程

用 Claude Code 时间一长,你就会发现一个很微妙的规律:任务越小,产出质量越稳;任务一大,主代理就开始变得有点"莽"。你让它改一个支付接口的超时逻辑,它能顺手把整个模块的重构方案都吐出来;你让它查一个报错原因,它把上下文里的二十几个文件全翻了个底朝天。这未必是模型笨,而是它缺少一层"角色边界"。一个人如果又当产品、又当开发、又当测试,精力迟早被撕碎——大模型也一样。

Claude Code 的子代理系统(Subagents)就是冲着这个痛点来的。你可以给主 Claude 配备一批各自专精某一块业务的"专家",让它学会在合适的时机把任务拆出去,而不是自己从头硬扛到底。这一篇通关手册,我打算把子代理的目录结构、配置文件写法、调用时机设计,以及我这几个月实际跑下来踩过的坑,一次性讲清楚。无论你是刚开始玩 Claude Code,还是已经在生产项目里天天用它,这部分内容都能让你的 Agent 利用率上一个台阶。

1. 子代理到底解决的是哪一类问题

1.1 主代理的"全科医生困境"

先说说我之前遇到的一个典型场景。某次我需要在一个老项目里加一个新接口,顺便兼容历史数据。我把需求一股脑丢给主 Claude,它的第一反应是把整个 src 目录扫一遍,然后从数据模型、接口层、前端调用、测试文件全部列了一份"影响清单"。听起来很负责对不对?问题是,它一边在改接口,一边还在纠结老数据迁移方案,最后改到一半,上下文窗口的早期内容已经被各种扫描结果挤掉了,它开始反复读同一批文件,产出的代码也出现了自相矛盾。

这就是主代理的"全科医生困境":它没有专科边界,默认会对所有信息一视同仁。Claude Code 的上下文窗口虽然不算小,但塞进大量无关扫描结果之后,真正留给"精修某个文件"的注意力会急剧下降。你需要的不是让它更全能,而是让它学会把活儿分包出去。

1.2 子代理的本质是一次有边界的任务委托

子代理在设计上很像"外包团队":主代理是甲方,子代理是乙方。甲方接到一个大需求后,拆成几个小的、定义清晰的子任务,分发给不同乙方去做。乙方在各自的工作上下文里只处理自己那一摊事儿,干完之后给甲方一份简报,然后退出。

和直接让主代理"多角色扮演"相比,子代理有一个关键差异——工具边界和上下文隔离。主代理只能通过子代理暴露的工具名和描述来决定要不要调用它,子代理在执行过程中只能使用你给它白名单里放行的那些工具。这就意味着,一个代码审查子代理默认没有写文件的权限;一个文档子代理默认不会去跑你的构建命令。这种隔离从源头上避免了"顺手把别的事情也干了"的连锁反应。

另外,子代理执行完返回给主代理的是一个精简的文本结果,而不是把整段内部思考过程全部塞回上下文。这个设计对长会话非常友好:主代理只需要知道"审查结果是什么",不需要知道子代理看了哪几个文件、中途走了什么弯路。

2. 子代理的目录、配置文件和工具边界

2.1 子代理到底放在哪里

子代理的定义方式不复杂:就是一个 Markdown 文件,文件名是代理名,文件内容里有一部分配置元信息,剩下的是系统提示词。你不需要写任何代码,Claude Code 会在启动时自动扫描这些目录。

  • 项目级目录:.claude/agents/,放在项目根目录下,跟着项目走。适合存放和这个项目强相关的专家,比如"这个仓库特有的数据迁移规则"。
  • 用户级目录:~/.claude/agents/,放在你的用户主目录下。适合存放跨项目通用的专家,比如代码审查、提交信息生成、文档规范化这类角色。

这两个目录是叠加生效的,同名冲突时项目级的优先级更高。实际使用中我的习惯是:通用专家放用户级,项目特化的放项目级。否则每个人 clone 仓库之后都少几个 agent,体验很割裂。

2.2 一个能直接跑起来的最小配置

先把最重要的放前面:子代理文件的格式长这样。

--- name: code-reviewer description: 在代码提交前审查变更,查找潜在 bug、安全隐患和可维护性问题。当需要审查 diff、排查代码质量问题、或准备提交合并请求时使用。 tools: Read, Grep, Glob, Bash model: sonnet --- 你是一名拥有十年经验的资深代码审查员。你的任务是审查给定的代码变更,找出真正值得修改的问题。 审查流程: 1. 先阅读变更涉及的源文件,理解代码意图。 2. 寻找以下类别的问题:逻辑错误、边界条件缺失、安全漏洞、可读性差、过度设计。 3. 每个问题必须给出:文件路径、行号区间、问题描述、修改建议。 输出格式: - 按严重程度从高到低排列。 - 如果没有发现问题,直接输出"未发现需要修改的问题"。 - 不要修改代码,只输出审查意见。

这个文件你保存成.claude/agents/code-reviewer.md,然后在任意一次对话里让主代理"审查一下当前的改动",它就会读取这个文件,然后通过子代理机制把任务委派出去。

2.3 四个核心字段到底怎么填

文件开头---包裹的部分是 front matter,四个字段各有各的讲究。

字段作用填写要点
name子代理的短名称用字母数字和下划线,避免特殊符号
description主代理判断是否调用你的依据写清适用场景,明确"何时用、何时别用"
tools子代理在任务期间可访问的工具遵循最小权限原则,不用的工具一律不给
model子代理跑任务使用的模型档位速度和质量的取舍,后面详细说

先说name。它相当于子代理在队伍里的编号,主代理偶尔会在对话里复述这个名字,但真正的调用判断主要靠description。description是整个配置里最重要的字段,因为它直接决定了主代理"愿不愿意把活儿交出去"。记住:主代理不会读你的系统提示词来决定要不要调用你,它只读你的描述。

tools字段填的是 Claude Code 的工具名,常见的有Read、Edit、Write、Glob、Grep、Bash、WebFetch、WebSearch等等。这里我强烈建议按最小权限来:如果子代理只需要读代码,那就只给它Read, Grep, Glob;如果还需要查依赖关系,再把Bash加上。给多了,等于没有边界。

model字段可以指定当前可用的模型。实践下来,常规子代理用标准档位就够,涉及高难度架构分析或安全审查时再上更强的档位。模型档位会直接影响响应速度和账单金额,这个后面单开一节说。

2.4 子代理和自定义指令、MCP 到底是什么关系

很多人第一次听说子代理时会问:这和"自定义指令"、"MCP 服务器"有什么区别?我的理解是这样:

  • 自定义指令是把一段"价值观"注入主代理的系统提示词,让它全程都遵守,但不会改变它的执行边界。
  • MCP 服务器是给它接外部工具和数据源,解决的是"它能不能访问某些东西"的问题。
  • 子代理是给主代理增加"可分派的专业角色",解决的是"它该让谁来干"的问题。

三者不是替代关系。实际项目里它们常常同时出现:子代理需要访问某个内部知识库时,可以在工具白名单里配上对应的 MCP 工具;子代理的系统提示词里也可以引用项目规范,让它在特定任务里严格遵守。

3. 让主代理"愿意"把活儿交出去的调用时机设计

3.1 description 是主代理的委派决策依据

我调试子代理时,遇到最多的问题是"我配了十来个专家,主代理一个都不用"。查到最后,十有八九是 description 写得太空洞。你写一句"负责代码审查",主代理根本不知道什么时候该用它。

更好的写法是把这个字段当成"采购需求清单"来写:先说什么时候触发,再说什么时候不要触发。一个强描述大概长这样:

description: 当用户要求审查代码变更、查找 bug、评估安全风险、或准备提交合并请求时使用。当任务仅为简单问答或与代码无关时不使用。

这样主代理在对话过程中做"任务拆解"时,就能明确匹配到你的专家。你还可以在 description 里加一些否定条件,比如"不要用于解释代码逻辑""不要用于生成新功能代码"。这些否定条件在实战中特别管用,能有效减少误调用。

3.2 系统提示词是"说明书"不是"身份证明"

很多人在写子代理的 system prompt 时,会花大量篇幅铺陈"你是一个经验丰富的 XX 专家,你有 XX 年的经验……"这类身份描述。有用吗?有一点,但性价比极低。真正重要的是任务执行的流程和输出格式。

我把 system prompt 拆成三个部分来写:角色一句话带过,流程按编号写清楚,输出格式单独成段。举个例子,我的一个"数据库迁移助手"子代理,角色只有一句"你是专注数据库迁移的工程师",后面全是执行流程:先读 schema 文件、再核对迁移脚本、然后检查数据兼容性、最后输出风险清单。为什么这么做?因为模型对"角色"的响应宽度很大,但对"流程"的响应会更收敛。你给它的指令越像操作手册,它的输出就越稳定。

3.3 工具白名单和输出长度是两个隐藏杠杆

除了描述和提示词,还有两个大家容易忽略的杠杆:工具白名单和输出长度限制。

工具白名单的意义不仅仅是安全,它还是一种"注意力引导"。当你把一个子代理的工具限制成Read, Grep, Glob时,它就只能做"读代码、搜代码"这件事,自然不会顺手改文件。这一点在复杂任务里效果非常明显:子代理不会因为"反正我能改文件"而顺手做一些不该做的修改。

输出长度限制的作用则是控制主代理的上下文消耗。子代理返回给主代理的内容是有长度上限的,这一点反而成了优点:既然只能输出有限长度,你更要强制它在最后给一个凝练结论。我在所有子代理的 system prompt 里都会加一句"最终结论控制在 300 字以内",这样即使子代理中途分析了大量内容,回传时也不会挤爆主代理的上下文。

4. 三个拿来就能用的子代理配置与效果

4.1 代码审查子代理:把"找茬"交给专职角色

代码审查是我用子代理最频繁的场景。以前让主代理直接审查,它会边看边改,经常把"审查"变成"重写"。配置了专门子代理之后,审查和修改彻底分开了。

--- name: code-reviewer description: 审查代码 diff,发现逻辑错误、边界问题、安全漏洞和代码异味。当用户说"审查""review""看看这段代码有什么问题"时使用。不要用于直接修改代码。 tools: Read, Grep, Glob model: sonnet --- 你是专注代码审查的工程师,只做审查,不修改代码。 审查步骤: 1. 先读取变更涉及的文件,理解原始意图。 2. 按严重度检查:功能性逻辑错误、边界条件遗漏、安全隐患、可维护性问题、命名与注释。 3. 对每个问题标注所在文件和行号区间。 输出格式: - 按严重度从高到低列出问题。 - 每个问题说明"为什么是问题"和"建议的改法"。 - 如果无问题,明确写"未发现需要修改的问题"。

这个子代理跑出来的结果,和直接让主代理 review 最大的区别是:它不会给出"重写整个模块"的大建议,而是一条一条的具体问题清单。我拿到清单后,可以自己决定哪些改、哪些忽略,而不是被动接受一份大改方案。

4.2 架构影响分析子代理:大改动前的"风控部门"

改代码最怕的不是写错,而是改了一处、炸了三处。比如你改了一个工具函数的入参,所有调用方都得跟着变。肉眼数调用点容易漏,让主代理自己找又会把上下文翻烂。这时候就需要一个专门的"架构影响分析"子代理:

--- name: impact-analyst description: 当需要评估某段代码变动对全项目的影响、查找函数调用方、梳理依赖关系时使用。例如"改这个函数会影响哪些地方""先帮我分析一下这个重构的风险"。不要用于直接修改代码。 tools: Read, Grep, Glob, Bash model: sonnet --- 你是架构影响分析专家。你的任务是在代码改动之前,分析潜在影响范围。 分析步骤: 1. 定位目标代码的定义位置。 2. 用 Grep 查找所有引用目标代码的地方。 3. 区分直接调用与间接调用,记录调用方的文件和函数。 4. 分析目标代码的依赖项,评估下层变更的连带影响。 5. 输出受影响模块清单,按风险等级排序。 输出格式: - 高风险:直接依赖目标代码且逻辑耦合紧密的模块。 - 中风险:间接调用或仅在特定流程中调用的模块。 - 低风险:仅引用常量、类型定义或注释的模块。 - 最后给出修改建议,但不要替你改代码。

使用这个子代理之后,我的重构流程变成了:先让 impact-analyst 出影响清单,再自己确认改哪些文件,最后才动手。相比以前直接让主代理全网搜索,这个流程无论准确度还是上下文消耗都好了很多。

4.3 回归测试补全子代理:专治"覆盖不全"的心虚

很多项目里测试覆盖率看着还行,但实际新增代码经常没配套用例。回归测试补全子代理解决的就是这个问题:给它一个功能模块,它负责找出哪些函数没有测试,然后生成对应的测试代码。

--- name: test-writer description: 当需要为已有代码补充单元测试或回归测试时使用。例如"给这个模块补测试""这个函数没有覆盖,写个测试"。当用户只需要解释代码时不要使用。 tools: Read, Grep, Glob, Edit, Write model: sonnet --- 你是测试开发专家,专门为已有代码补充高质量测试。 工作流程: 1. 读取目标模块的源码和现有测试文件。 2. 用 Grep 找出测试覆盖率明显不足的函数。 3. 针对高风险函数优先编写测试:边界条件、异常路径、核心业务逻辑。 4. 测试代码风格必须和项目现有测试保持一致。 5. 不改变源码逻辑,只新增测试文件或补充测试用例。 输出格式: - 列出新增了哪些测试文件、覆盖了哪些函数。 - 标注哪些高风险函数暂时无测试方案及原因。

测试生成这个场景,子代理的价值在于"标准一致"。你把项目已有的测试风格写进 system prompt,它生成的测试代码会和老代码保持高度一致,省掉了大量让主代理自由发挥带来的风格漂移问题。

5. 实践中最常见的三种"翻车"与完整排查链路

5.1 症状一:主代理死活不调用子代理,什么事都自己干

表现:你配置了五个专家,但在对话里无论怎么提需求,主代理都自己埋头干,一个子代理都不派。

排查链路:

  1. 先检查 description 里有没有明确的触发词。主代理的调用判断本质是"语义匹配",如果你的 description 里全是"架构""风险评估"这种大词,而用户说的是"改一下登录逻辑",匹配度可能不够。把 description 改成包含用户常用词的说法,比如"登录""权限""接口"。
  2. 再检查是不是有多个子代理的 description 互相覆盖。两个代理都写了"代码有问题时使用",主代理就会陷入选择困难,最后直接不选。给每个代理划定更细的边界。
  3. 还可以直接在主提示词里指名道姓:"先调用 impact-analyst 分析影响范围,再给出修改方案。"显式点名能绕过匹配失败的问题。

我这里说的排查链路,是验证"主代理到底是被哪个字段卡住"的思路。你可以先打开调试输出,看主代理在决策时是否提到子代理名称。如果没提,问题基本出在 description;如果提了但没用,问题可能出在工具白名单或模型档位。

5.2 症状二:子代理很快就"交差",结果却没法用

表现:子代理确实被调用了,但返回的内容空洞,要么只有一句话总结,要么漏掉了关键部分。

排查链路:

  1. 检查 system prompt 里是否给了明确的"完成标准"。如果你只写"分析这个模块",它可能分析到一半就觉得"差不多了"。给了流程后,还要给"什么时候算完成"的标准,例如"必须列出每个函数的调用方,没有调用方也要写'未找到引用'"。
  2. 看是不是任务范围太大。子代理虽然独立,但它的上下文也是有限的。让它分析"整个支付系统",不如拆成"分析结算接口的调用链"。范围越小,结果越可用。
  3. 确认输出格式里有没有兜底描述。比如"如果没有发现问题,也要写明'未发现'"。这样即使结果为空,你也知道它是认真查过还是没有查到。

5.3 症状三:子代理因为工具权限不足中途崩溃

表现:子代理在执行过程中频繁报错,比如Bash命令被拒绝、找不到某个文件路径、或者读不了某个目录。

排查链路:

  1. 先看错误类型。如果是工具被拒绝,就说明 tools 白名单没给够。比如分析依赖需要执行 grep -r,但你只给了Read,那它就没法搜代码。把Grep、Glob补上。
  2. 如果是路径找不到,多半是因为子代理默认的工作目录和主代理不一致。你可以在 system prompt 里写明"所有相对路径均以项目根目录为基准",或者直接给绝对路径示例。
  3. 还有一个常见坑:子代理在某个环节需要写临时文件,但你只给了Read和Grep。如果它的流程里包含"先生成一个中间文件",那就得把Write、Edit加上,或者把流程改成"不落盘,直接输出结果"。

工具权限这个坑,我的建议是宁缺毋滥,但也别抠得太死。如果任务里明说了要跑测试,就大大方方把Bash放开;如果不确定,可以在第一次跑的时候故意不给,让子代理报错后你再补。这样反而能帮你验证哪些工具是真正必需的。

6. 把子代理体系融入日常项目后的几点体会

6.1 不是所有任务都适合沉淀成子代理

子代理不是越多越好,判断标准很简单:这个任务是否高频、是否稳定、是否有明确的输入输出边界。我见过有人把"帮我写一个 Python 爬虫"也封装成子代理,结果每次需求都不一样,子代理的 system prompt 写了一长串分支判断,最后执行效果比直接让主代理干还差。

反过来,适合做子代理的任务有这些特征:流程固定、评价标准清晰、重复出现。代码审查、影响分析、提交信息生成、接口文档更新、数据库迁移脚本检查,这些都是教科书式的子代理场景。那种"一次性探索型"的任务,比如"帮我看看这个奇怪报错是什么意思",直接让主代理处理反而更快。

6.2 模型档位和 token 成本要心里有数

子代理每被调用一次,就是一次独立的模型请求。如果你把十个子代理全部设成最高档位,一次大任务的费用会非常可观。我的做法是分档管理:常规子代理用标准档,高难度分析(架构影响、安全审查)才用更高档位。

另一个成本控制点是输出长度。前面提过,子代理返回给主代理的内容有限,但你在 system prompt 里不写"控制输出长度"的话,它可能把整段分析报告都回传,直接消耗主代理后续的上下文空间。我统一在子代理的 system prompt 末尾加一句"最终结论务必精简,超出部分不予查看",效果立竿见影。

6.3 团队协作时,子代理的版本管理值得认真对待

如果你是在多人项目里用 Claude Code,子代理配置的稳定性会直接影响团队效率。我建议把通用子代理放在独立仓库里管理,用软链或同步脚本分发到每个开发者的~/.claude/agents/,而不是让每个人各自维护一份。项目特有的子代理则放在项目目录的.claude/agents/下,跟随代码一起走。

还有一个容易被忽略的规则:不要把任何敏感信息写进子代理的 system prompt。子代理的配置文件是纯文本,会跟着仓库同步。内部 API 地址、账号口令这类东西,要么通过环境变量传递,要么让子代理在运行时读取 git 忽略的文件,千万不能直接写在 md 里。

子代理真正让我上头的时刻,是它开始承担那些"主代理能做但总做不稳"的任务。以前改一个跨模块功能,我全程围观主代理翻文件、试错、改错、再改;现在我只是说一句"让 impact-analyst 先分析一下",它就会带着清单回来,我再决定下一步。这种"指挥专家团队"而不是"事必躬亲"的感觉,大概就是 Claude Code 的正确打开方式。如果你的工作流里也有那种流程重复、边界清晰、每次都要花半小时盯着做的活儿,试着把它封装成一个子代理——你大概率会发现,原来可以让 AI 帮你把 AI 管好。

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

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

立即咨询