首页 / 文章

Claude Code子代理详解:它们是什么以及何时使用它们。

Claude Code子代理与技能及代理团队的区别:上下文隔离、首个自定义子代理、描述与工具的最佳实践,以及何时可以省略这些内容。

发布者:REACTAPP.TOP阅读约 15 分钟3351 词

来源: Claude Code agents: what they actually are

智能体并非伪装起来的技能

人们对 Claude Code 智能体的常见初步反应是,它们不过是带有额外步骤的技能,是一种“更智能的技能”,因为其指令表述方式不同而能更自主地运行。这种看法是错误的。实际上,智能体与技能一样,本质上都是提示语。关键的区别在于它们的运行方式:智能体不会在主对话中执行操作,而是拥有独立的上下文窗口、系统提示语、工具访问权限以及相应的权限设置,在后台运行后返回结果。

接下来的内容将从基础讲起:这些智能体是什么,如何创建一个智能体,以及何时会看到成效。它假设你已经使用过 Claude Code,并希望在修改任何配置之前充分了解该功能。讲解顺序是先介绍术语概念,再说明子智能体存在的原因,接着创建第一个自定义子智能体,然后解释它们与技能的区别,之后是实际使用方法、简要介绍智能体团队,最后是选择智能体不合适的情形。

人们所说的“智能体”包含四层含义

在 Claude Code 中,“智能体”一词至少涵盖四种不同的概念,将它们混为一谈会让人更难理解这一功能。在这里稍加注意术语区分是值得的,因为这有助于将概念与实际可使用的功能对应起来。

  1. Claude Code本身就是一个智能体环境。Anthropic将其定位为一种智能体编码助手:它拥有各种工具和执行循环,能够自主规划多步操作而无需在每一步都收到提示。即便在您进行任何配置之前,它就已经具备智能体功能。
  2. 子智能体是该产品中自定义的智能体基础单元。当开发者表示要在Claude Code中构建智能体时,他们指的几乎总是子智能体。根据官方文档,这些子智能体是用于处理特定类型任务的专用助手,每个都有独立的上下文窗口、自定义的系统提示、特定的工具访问权限以及独立的许可设置。
  • Agent团队属于另一项多会话功能。根据相关文档的明确说明:子代理存在于单个会话中,而团队则需要在多个会话之间协同工作。团队是一组独立的Claude Code实例,它们通过共享的任务列表以及成员间的直接消息进行交流。该功能目前仍处于实验阶段,默认处于关闭状态,需通过环境标志才能启用。它并非“更多的子代理”,而是位于架构的不同层级上。
  • Claude Agent SDK属于第四层。它以Python和TypeScript库的形式,提供了与Claude Code相同的工具和代理循环机制,供那些不在命令行界面之外开发自己代理应用的团队使用。
  • 其余内容集中在第二个议题——子代理上。稍后应该专门讨论团队相关问题;从详细解释一个子代理开始是合适的切入点。

    为何需要子代理

    根本原因在于语言模型的上下文容量是有限的,长会话迟早会达到这个极限。如果不采取相应措施,这种情况就会反复出现。

    Anthropic关于上下文管理的文章将这种管理方式描述为对有限窗口内容的筛选。每一次工具调用、文件读取以及未完成的分析都会被添加到上下文中并保留下来。会话持续的时间越长,用于获取答案但之后毫无用处的内容就会占据更多空间。这些杂乱信息会降低质量,这种现象常被称为上下文中的“腐败”。模型可用的空间随之减少,更多无关内容会争夺其注意力。

    子代理是一种解决方案。Claude Code的功能概要中明确指出:子代理可以读取数十个文件或进行大规模搜索,但主对话仅会收到总结,因此中间处理过程不会占用主要上下文。当中间步骤无需显示时,这非常方便。

    举个具体例子:你让Claude查明某个测试套件为何失败。在主会话中执行这项调查时,需要读取二十个文件、查找错误模式、检查测试配置并扫描最近的提交记录。所有这些内容都会被纳入你的上下文中。到任务结束时,你已经为中间处理过程消耗了数千个标记,而这些内容几乎不会影响你接下来的操作。

    子代理会重新定义问题。调查在它自己的上下文窗口及令牌预算内进行,最终输出的是简短的结论,类似“故障源于 CI 环境中缺失的某个环境变量;有三项测试受到影响,修复方法如下”。主线程永远不会受到搜索过程中的干扰。

    上下文隔离是主要原因,此外还有三个次要原因:

    1. 专业化。子代理拥有自己的系统提示词。一个明确了解团队标准的专注审核者,会比一个需要同时兼顾各种任务且还要遵循相同标准的通用助手更为可靠。
  • 约束执行。你可以决定子代理可以使用哪些工具。一个只能读取数据、无法写入文件或运行shell命令的研究型代理,其风险特征与主助手有很大不同,而这些限制是通过明确规定并强制执行来实现的,而非依靠自觉遵守。
  • 成本控制。子代理可以在不同的模型上运行。将轻量级任务交给Haiku处理,而主会话则使用Sonnet,这是一种控制开支的实用方法,但很多人往往在收到高额账单后才意识到这一点。
  • 创建第一个自定义子代理

    从技术上讲,子代理不过是一份带有YAML标题的Markdown文档。有两种有效存放位置:

    • 项目内的.claude/agents/目录,用于存储与该代码库相关的代理。应将这些文件提交版本控制,以便团队共享和优化。
  • 主目录下的~/.claude/agents/,其中存放每个项目可使用的个人智能体。
  • 前置信息值得关注

    人们通常会快速浏览 YAML 格式的前置信息,但 Claude Code 会将这些内容保留在主会话的内存中,以便了解每个智能体的功能。实际上它就是智能体的概要说明。其中有两个字段是必填的,还有几个为可选字段。以下是一个简单的示例,展示这些字段是如何组合在一起的:

    ---
    name: code-reviewer
    description: Reviews code changes for quality, security, and best practices.
                 Use proactively after any significant code change.
    tools: Read, Glob, Grep
    model: sonnet
    ---
    
    You are a code reviewer. When invoked, read the changed files and provide
    specific, actionable feedback on code quality, security, and best practices.
    Focus on what matters. Don't restate what the code does — say what's wrong
    or good about it. Flag security issues first, then logic problems, then style.
    

    逐项说明:

    • name 是唯一标识符,仅由小写字母和连字符组成。日志会显示该标识,Claude也会用它为智能体内部命名。
    • description 最为重要。Claude会参考它来判断任务是否属于该智能体,因此应描述智能体的功能及其被调用的场景。若加入“主动使用”这类提示,即可告知 Claude 无需等待明确请求即可激活该智能体;若智能体只需在直接被询问时才作出响应,则无需添加此表述。
  • tools决定了智能体能够执行的操作范围。上述的审核者可以读取文件和进行搜索,但无法编辑、运行shell命令或发起网络请求。这是有意为之:只具有读取权限的审核者不会意外更改正在审查的内容。相关文档也建议仅授予智能体所需的工具权限,以此保障安全并使其行为可预测。
  • model用于将智能体定向到特定的模型:sonnet、opus、haiku,或是像claude-opus-4-6这样的完整标识符。如果没有设置该参数,智能体将使用inherit模式,即采用与主会话相同的模型。
  • frontmatter部分的所有内容都会成为智能体的系统提示语。该提示语连同工作目录,就是智能体从主会话中接收到的全部信息。
  • 可选字段的完整列表显示了还有多少参数可以调整:permissionMode、maxTurns、skills、mcpServers、effort、memory、hooks、disallowedTools、color以及其它参数。

    看到某个智能体后,你可能会认为它已经接近于一种技能。这种看法有一定道理,但同时也忽略了关键点,接下来的章节将会详细说明。

    文件存放位置

    将示例保存为项目中的.claude/agents/code-reviewer.md。最终的文件结构如下所示:

    your-project/
    ├── .claude/
    │   ├── agents/
    │   │   └── code-reviewer.md          ← your new agent file
    │   ├── skills/
    │   └── rules/
    ├── src/
    ├── tests/
    ├── README.md
    └── package.json
    

    保存后,Claude会识别出该智能体。要求其审查代码变更时,它会根据请求与描述的匹配程度自行将任务分配给code-reviewer。对于需要在所有项目中使用的个人智能体,可将文件移至~/.claude/agents/code-reviewer.md。文件的格式和内容保持不变,仅位置有所改变。

    智能体与技能

    为何两者容易混淆

    三种相似之处导致了大部分的混淆:

    1. 两者都是通过.claude/skills或.claude/agents目录下的普通文件夹结构来设置的。
    2. 两者都使用前置信息,且描述是其中最重要的设置项。
    3. 两者都是指令集合,也就是提示词。一个技能和一个智能体可能包含完全相同的文字。

    从这个角度看,它们的结构似乎很相似。

    工作执行的位置

    然而,有一个显而易见且实际的区别将它们区分开来:即工作是在何处完成的,也就是令牌被消耗在何处。这是最容易理解的差异。

    • 技能会被整合到正在进行的对话中。它的指令、模板及辅助文件会加入当前上下文,Claude会在同一对话流中处理这些内容,每一步都会显示在主窗口中。
    • 子代理会在独立的上下文窗口中运行。它负责执行任务,主对话则会收到相应的结果。

    调优界面

    早些时候列出了代理可在其前置信息中设置的众多字段。相比之下,技能所支持的字段列表要短得多,且部分内容也有所不同。这体现了代理所赋予的控制力差异。并非所有功能都需要转化为代理形式。关键在于,用于设计可靠系统的思维模型可能需要重新审视。

    同一任务,两种方案

    以希望团队代码审查标准得到一致应用为例。

    如果要求Claude在整个会话期间都了解这些标准,在编写代码时加以运用,在提供建议时引用这些标准,并在出现违规时指出来,那么技能模式更为合适。只需将标准编写一次,Claude在相关场景中便会自动调用这些标准,从而使会话中的所有操作都能以此为依据。

    如果您希望一次性审核四十个文件,同时避免主界面被文件读取内容、临时评论和搜索结果占满,那就需要使用子代理。配置一个代码审查代理,让它在独立的窗口中运行,然后获取结构化的总结报告。您甚至可以同时启动四十个子代理,每个文件对应一个。主界面只会收到最终结果,而无需看到生成这些结果的详细过程。

    一句话就能概括二者的区别:技能决定了Claude所掌握的知识或处理工作流程的方式,而子代理则决定了由谁在何种环境下使用何种工具来完成工作。

    经得起时间考验的工作方法

    将描述视为路由接口

    这一点没有得到应有的重视。Claude会阅读子代理的描述来决定何时进行任务委托,但在做出决定之前并不会读取提示内容中的其他信息。因此,你在提示内容中输入的任何具体描述在子代理被创建之前都是不可见的。所以,描述必须包含足够的信息,让Claude知道何时需要该代理。

    • 使用具体、明确的表述方式。
    • 说明该代理的功能以及应在何种情况下使用它。
    • 列出它擅长处理的任务类型,以及在适当的情况下指出它不应处理的任务。
    • “在代码更改后主动使用”是一种经过验证的模式,文档中也提到过这种方法可以在没有明确请求的情况下促使任务委托。对于仅应在直接调用时运行的代理,则无需使用此描述。
  • 避免使用能表明智能体身份的描述,比如“拥有二十年经验的资深审核员”。这类信息应放在系统提示中。描述是为路由模型服务的,而非智能体。
  • 要看出其中的差异,可以在用于路由的描述旁加上一个模糊的描述:“协助处理代码质量和审核任务”,而用于路由的描述则是:“检查已提交的更改是否存在安全漏洞、逻辑错误和风格问题。在每次重大修改后主动运行该智能体。它从不编写代码或编辑文件。”

    有意限制工具使用

    如果智能体继承了主会话中的所有工具,出现问题时就很难分析原因。只需授予完成任务所需的权限即可。

    • 审核员应仅具备读取功能,除此之外不得拥有其他权限:不能编写代码、不能使用shell命令、也不能访问网络。
    • 研究工作需要搜索和获取信息,但不允许编辑文件。
    • 运行测试需要使用 Bash,但没有理由去操作网页。

    限制工具使用有助于提升安全性与清晰度。有限的工具集能让行为更加可预测,当智能体出现故障或返回异常结果时,简短的可用工具列表能加快诊断速度。此外,这也能让故障模式变得有限且易于理解。disallowedTools字段允许智能体继承主会话中的工具,然后排除特定的工具,非常适合“除Bash之外的所有工具”或“除写入功能之外的所有工具”这类需求。

    为每个智能体分配一项任务

    子代理的文档明确指出,每个子代理应专注于单一任务。像“审查代码、编写测试用例、更新文档以及处理部署检查”这样的描述实际上将四项功能混在了一个字段中。Claude可能无法均衡地处理这些任务,而系统提示词则必须同时应对这四种操作模式。

    应缩小范围,创建三个独立的文件,每个文件对应一项明确的职能描述。在数据科学领域,可以是模型验证代理、数据质量检查工具和笔记本审查器;在软件开发领域,则可以是代码审查员、测试用例生成器和文档更新工具。这一原则适用于所有领域——每个代理都有唯一的任务、专属的文件以及能明确指引其功能的描述。

    利用模型字段控制成本

    那些尚未因使用账单而感到惊讶的人往往最容易忽略这一选项。在单次会话中运行多个智能体时,为轻量级智能体设置model: haiku可显著降低成本。而对于需要在较大上下文中进行复杂推理的智能体,设置model: opus则其高昂的价格也就合情合理了。保持默认值inherit意味着每个智能体都会使用主会话所采用的模型,通常是性能最强的那个,即便某些任务并不需要如此强大的模型也会被同样使用。

    社区公认的方案

    VoltAgent子代理集合收录了上百种专业子代理,涵盖语言专家、安全审查员、调试器、基础设施辅助工具以及协调器等。另一个优秀的集合则存在于Everything Claude Code仓库中。实际上很少有人需要其中五分之一的功能,因此数量并非关键所在,其结构才是重点。这些集合中的每个条目都专注于某一特定领域,无论是TypeScript专家、SQL专家、Kubernetes操作员还是安全审计师,没有一种试图覆盖多个领域。经过一年多的实际使用后,人们达成了共识:众多专注型代理比单一通用型代理更出色。

    简要了解代理团队

    代理团队值得了解,但它们与子代理是不同的功能。

    子代理仅存在于单个会话中。主 Claude Code 实例负责创建它们,这些子代理独立工作并返回结果,而你则担任协调者。

    代理团队是由多个独立的 Claude Code 会话组成,它们通过共享的任务列表和直接的点对点消息进行交流。每个团队成员都有自己独立的上下文窗口和会话状态,既可以分配任务给他人,也可以接收任务。

    团队文档说明了这些额外机制的适用场景:多名团队成员共同从不同角度进行研究或审查;通过相互对比假设来调试问题,让团队成员对彼此的理论提出质疑;以及在开发新模块时,让每个成员负责自己的部分,避免相互冲突。

    设置它们并非易事,因此不在本文讨论范围内,也没有必要出于怕错过的心理而跟风使用。团队功能会增加协调成本,并消耗更多令牌,因为每个团队成员都有自己的上下文窗口,需要单独计费。它们目前仍处于实验阶段,默认处于禁用状态,需通过环境变量才能启用。

    一个实用原则:只要子代理能够向你汇报结果且无需相互交流,就不需要使用团队功能。只有当某个子代理需要将发现结果传递给另一个子代理,或对后者的结论提出质疑时,才需要考虑使用团队功能,否则子代理就已足够。

    何时该选择其他工具而非代理

    Anthropic 自身关于构建高效智能体的指导值得认真对待。它建议先寻找最简单的可行方案,仅在必要时再增加复杂性,这甚至意味着根本无需构建智能体系统。

    这一原则直接适用。以下是一些子智能体会增加负担且毫无收益的情况:

    • 一次性任务。子智能体需要承担诸多创建工作:命名、撰写描述、选择工具、测试、维护。对于只需完成一次的任务,这些成本实在不值得,因此最好直接编写合适的提示词。只有当某项工作流程频繁出现,足以值得维护其定义时,这些投入才会有所回报。
  • 上下文并非问题的情况。使用子智能体的主要目的是让主上下文免于承担繁重工作。如果任务较轻,无需占用过多资源,也不需要特殊的工具限制,那么子智能体只会增加不必要的复杂性。在主会话中直接进行提示语交互在速度、简洁性以及调试便利性方面更具优势。
  • 单体智能体的陷阱。试图同时处理研究、实现、审查和文档编写工作的单一智能体并不全面,既难以测试,选择方式也不一致。更为具体、细致的描述能带来更高的一致性。
  • 基本原则是选择能够解决实际问题的最简单工具。只有在需要上下文隔离、特殊约束或专用执行环境时才添加智能体,而非因为智能体本身被认为更强大。

    简版总结

    简单来说,子代理负责管理上下文并界定执行边界,不过大多数人认为它们能提升功能表现。

    精心配置一个代理就足以完成一项合理的下午工作。这里并不需要编排系统来发挥作用:清晰的描述、有限的工具集以及一个明确的任务就足够了。复杂性可以在此基础上进一步增加,但并非必须从这里开始。

    有一些问题值得自己思考。在当前的工作流程中,哪项任务最适合交给独立的工作者处理?是什么阻碍了你这样做?如果你已经在使用子代理,那么第一个真正需要独立运行的任务是什么?在主会话中执行它又会带来什么实际问题?另外,你是如何控制工具访问权限的:是按代理限制,还是从主会话继承后再进行限制?