☰
Claude Code自定义Agent完全指南:从定义文件到工具权限配置
2026/10/21 13:05:21 网站建设 项目流程

1. 为什么需要为 Claude Code 自定义 Agent

聊 Claude Code 的自定义 Agent 之前,我先说说自己在用默认模式时遇到的几个很别扭的场景。默认情况下,Claude Code 就像一个全科医生,你叫它改 bug 它去改,你叫它写测试它去写,看起来无所不能,但只要项目一复杂,这种"什么都会"反而成了问题。

举个例子。某次我在一个中大型项目里做重构,需要把好几处重复的业务逻辑抽成公共模块。我让 Claude Code 直接处理,它倒是很勤快,一会儿改这个文件,一会儿查那个引用,但经常干着干着跑偏:我明明只想让它动某一层的代码,它顺手把别的模块的格式也调整了;我让它先分析调用链再动手,它分析到一半就开始改代码。整个过程你需要不停在对话里纠正它,心累程度不亚于自己动手。

后来我开始研究 Agent 定义,才意识到问题出在哪:我没有给 Claude Code 划定明确的行为边界,也没有用 Agent 机制把某一类任务单独拆出来。自定义 Agent 的本质,是把一类频繁出现的任务固化成一个"专职员工"——它有明确职责、明确工具权限、明确的工作流程,主程序只需要把活派给它,它按自己领域内的高标准干完活再把结果交回来。这种模式下,主对话负责统筹调度,子 Agent 负责垂直深度执行,配合起来比让一个全科医生干所有专科件要靠谱得多。

所以这篇内容,我按自己的实际使用经验把 Agent 定义这件事拆开讲清楚:定义文件怎么写、每个字段到底影响什么、描述怎么写才能让主程序正确"选人"、工具权限边界怎么划,最后用一个完整的代码评审 Agent 案例带你把流程走一遍。如果你已经用 Claude Code 写过一阵子代码,又觉得它"不够听话",那这篇内容应该能帮你打开一个新局面。

2. Agent 定义文件的基础结构

2.1 定义文件放在哪里

Claude Code 的 Agent 定义,本质上是一些 Markdown 文件,放在项目的.claude/agents/目录下。一个 Agent 对应一个.md文件,文件名就是 Agent 的名字(不加.md后缀的那部分就是调用时的名称)。比如你新建一个.claude/agents/code-reviewer.md,那这个 Agent 的 name 字段通常就叫code-reviewer。

如果你用的是 Claude Code 的桌面版或云端版,入口不太一样——有的版本在设置里直接有一个 Agent 管理面板,你可以在界面上新建、编辑、删除 Agent。但不管用哪种入口,底层生成的都是一样的 Markdown 定义文件,所以搞清楚文件格式永远是最核心的。

目录结构大概长这样:

项目根目录/ └── .claude/ └── agents/ ├── code-reviewer.md ├── test-generator.md └── docs-writer.md

很多刚开始接触的人会有个误区:以为 Agent 文件要放在全局配置里才能"所有项目通用"。其实 Claude Code 支持两类位置——项目级.claude/agents/和用户级~/.claude/agents/。项目级只对当前项目生效,用户级对当前账号下的所有项目生效。我个人的建议是:通用型的 Agent(比如代码审查、提交信息生成)放用户级,项目专属的 Agent(比如针对某套内部框架的代码生成)放项目级。这样既能跨项目复用通用能力,又不会让不相干的 Agent 干扰其他工程。

2.2 文件里的两个组成部分

一个完整的 Agent 定义文件,由两部分组成:frontmatter(元信息区)和正文(行为指令区)。

frontmatter 是文件最上方用---包裹起来的一段 YAML 配置,定义 Agent 的名字、职责描述、可用工具、模型等元信息。正文则是 Markdown 格式的指令描述,告诉这个 Agent 它具体应该怎么干活、遵循什么原则、输出什么格式。

我拿一个极简示例说明:

--- name: test-generator description: 当需要为函数或模块编写单元测试时使用;侧重于边界条件和异常场景覆盖。 tools: Read, Grep, Glob, Write --- 你是一位专业的单元测试工程师。当你收到一个函数或模块的代码时,你需要: 1. 先阅读目标代码,梳理输入、输出和副作用。 2. 列出至少 5 个测试用例,包括:正常路径、边界值、空值/缺失参数、异常输入、副作用验证。 3. 用目标项目已有的测试框架编写测试代码。 4. 写完测试后,运行测试并确认全部通过;如果有失败的用例,修复测试本身的问题,但不要修改被测代码的公共行为。

看起来挺简单对吧?但这里面的每一项都有讲究,尤其是 description 和 tools 这两个字段,它们直接影响 Agent 能不能被正确调度、能不能在限定范围内安全执行。下一节我逐个拆开讲讲。

3. 字段详解:每个配置项背后的实际作用

3.1 name:注意命名习惯

name是这个 Agent 的唯一标识。它应该简洁、能表意,并且最好和文件名保持一致的命名习惯(通常是小写字母加连字符,比如code-reviewer、test-generator)。

有一点值得注意:主 Claude Code 实例在调度 Agent 时,会通过 name 来引用它。你在对话里换着一个 Agent 让它干活,它才知道去读哪个文件。如果你的项目里 Agent 多了,建议在description里也带上 name 的自然语言描述,这样调度准确率高很多。

3.2 description:决定 Agent 何时被"选中"

这是整个定义文件里最容易被低估、但实际影响最大的一个字段。原因是:Claude Code 的主 Agent 在决定要不要调用某个子 Agent 时,主要靠的是你的自然语言请求和各个 Agent 的description之间的语义匹配。

换句话说,description写得好不好,直接决定了这个 Agent 会不会在合适的时机被正确调用。

什么算写得好?我总结下来需要包含三个信息:

  • 使用时机:什么时候应该用这个 Agent?最好写清楚触发条件。
  • 任务边界:它负责什么、不负责什么?
  • 期望效果:它处理完之后应该输出什么?

举个例子,同样是一个代码审查 Agent,两种描述写法:

写法一(不推荐):

description: 用于代码审查。

写法二(推荐):

description: 在提交 Pull Request 之前,需要检查代码质量、发现潜在 bug 和安全问题时使用;不适合用于修复已发现问题。

第二种写法让主 Agent 能更清楚地把"我要 review 代码"这个请求和这个 Agent 关联起来。实测下来,写清楚使用时机之后,调度准确率提升非常明显。

3.3 tools:明确工具权限,别给太多

tools字段控制这个 Agent 可以使用哪些工具。常见的工具包括:

  • Read:读取文件内容
  • Grep:按正则搜索文件内容
  • Glob:按通配符匹配文件名
  • Write:写入或覆盖文件
  • Edit:对文件做精准编辑
  • Bash:执行 shell 命令
  • Task:调用子子 Agent(如果你的 Agent 还要再往下分级)

我在实际项目里的经验是:工具权限宁少勿多。给一个"只读型" Agent(比如代码审查)配上 Write 和 Bash,它很容易在审查过程中顺手改代码,或者执行一些高风险命令。更好的做法是:明确这个 Agent 的工作到底是分析、生成,还是修改,然后按需配工具。

如果你想让 Agent 使用 MCP 工具或其他自定义工具,也可以在tools里声明。不过这类工具的名字必须以mcp__或实际注册名为准。具体情况取决于你的 MCP 服务配置,这里不展开了。

3.4 model:指定底层模型

model字段可以指定这个 Agent 使用哪个模型。比如有的 Agent 偏简单、只做文本处理,你可以用轻量模型,响应更快更省钱;有的 Agent 任务复杂、需要很强的推理能力,就指定更强的模型。

这个字段不是必填的,不填的时候会继承主会话的默认模型。我目前的习惯是:基础类 Agent 显式指定一个标准模型,复杂类 Agent 指定更强模型。这样做的好处是,即便主对话里临时切换了模型,也不会影响 Agent 行为的稳定性。

需要说明的是,模型的具体代号和可用性在不同版本、不同账号上可能不一致,配置前最好先确认自己账号支持哪些模型。这在官方文档里一般有列表,或者你直接在对话里问一下当前可用的模型也行。

3.5 正文部分:行为指令怎么写才有效

正文是 Agent 的核心"岗位说明书",用 Markdown 形式编写。这部分没有绝对模板,但我写下来觉得有几个原则很关键。

第一,用第二人称直接下达指令。正文开头一般写"你是一位……",明确它的身份。

第二,写清楚工作流程,但不要写死到不能变通。Claude Code 的 Agent 不是机械执行命令的脚本,它有自己的推理能力,所以正文要给原则、给顺序,但不用每一条都事无巨细。比如你写上"先搜索相关代码,再制定修改方案,最后再动手改",比写"第一步执行 grep,第二步打开文件第 5 行,第三步……"要灵活得多。

第三,输出格式要求写明确。如果你希望 Agent 最后返回一个清单、一个表格或一段总结,在正文里直接要求它这样做。否则它可能会返回一段冗长的自由文本,不好阅读。

下面是一个正文示例片段:

你是一位严谨的代码审查专家。收到审查任务后: - 先读取需求描述和变更文件列表。 - 检查每一项变更:是否有逻辑错误、是否有明显安全隐患、是否有性能隐患。 - 按照严重程度从高到低列出问题清单。 - 每个问题必须给出:文件路径、问题描述、整改建议。 - 不得直接修改代码文件,只输出审查报告。

这个写法在"该干什么、不该干什么、输出什么格式"上都给了明确约束,Agent 跑起来非常省心。

4. description 是调度命脉:如何让主程序准确"选人"

我前面提过,description 决定 Agent 是否在合适的时机被调用。这一节我想就这个问题多展开一点实操层面的思考,因为这是很多人定义完 Agent 后发现"没生效"的最常见原因。

4.1 主 Agent 是如何"选人"的

Claude Code 的调度机制核心是你的请求和各个 Agent 描述之间的语义匹配。你可以把主 Agent 想象成一个前台经理,它手底下有几个"专科专家",每个专家递上来的简介(description)写得越清楚,这个经理就越知道"这个问题该派给谁"。

如果你的 description 只写了"用于代码审查",那经理面对"帮我看看这段逻辑有没有问题"时,可能并不确定该不该派这个专家——因为"看看"和"审查"之间没那么直接。反过来,如果你写的是"在代码变更完成后,需要系统性检查逻辑正确性、安全性和性能时使用",那匹配成功率就高很多。

4.2 多 Agent 场景下的描述排错

当你的.claude/agents/目录里有五六个 Agent 时,偶尔会出现"该用 A 的时候,主程序调了 B"的情况。这时候不要急着改代码,先回去看两者的 description 是不是有语义重叠。

我遇到过最典型的例子是:我定义了一个bug-fixer和一个code-reviewer,前者的描述是"当发现代码缺陷时使用",后者的描述是"在审查代码、发现缺陷时使用"。结果主 Agent 经常把 bug 修复任务派给 code-reviewer,因为两边都在说"发现缺陷"。

后来我把两者的描述重写了一下:

  • bug-fixer:当代码运行结果不符合预期,需要定位根因并修改实现时使用。
  • code-reviewer:在提交前或重构后,需要人工审视代码质量、排查潜在风险时使用;只输出审查结论,不修改代码。

改完后调度准确率立竿见影。所以我的经验是:不要靠"名词不同"来区分 Agent,要用"动词不同"来区分——一个强调"修复",一个强调"审视",语义距离一下就拉开了。

4.3 任务边界也要写进 description

还有一点,description 里除了写"何时使用",最好也写一句"何时不要用"。例如:

description: 在需要为新代码生成单元测试时使用。如果只是对已有测试做小改动,请直接在主会话处理,不要调用本 Agent。

这种"负例提示"很有用,它能在语义匹配阶段直接排除错误调度。我在加入负例提示后,调错 Agent 的次数明显减少。

5. 工具选择与安全边界

5.1 为什么工具要"限量供应"

自定义 Agent 和全功能主实例之间最大的差别,就是你可以精确控制它手里的工具。对 Agent 来说,工具就是它的"手脚";手脚越多,它能惹的事也越多。

我见过一些朋友定义 Agent 时习惯把所有工具都堆上去,理由是"万一用到呢"。但实际跑下来,工具太多有两个坏处:

一是容易分散 Agent 的注意力。它本来只需要读文件和搜索代码,结果因为它有写文件的能力,就总想顺手"优化"一下代码,最后产出物完全变味。

二是风险变高。如果 Agent 拥有 Bash 权限,它可能在你自己没注意的时候执行了项目清理、依赖安装、甚至 git 操作。虽然大部分时候不会出事,但一旦出事,排查成本不低。

所以我现在每个 Agent 都会先问一个问题:这个 Agent 的产出物是"建议"还是"改动"?如果是建议(审查报告、分析文档),只给只读工具;如果是改动(生成代码、修 bug),才给写工具和必要的执行工具。

5.2 常见工具分配参考

下面是我根据自己的使用经验总结的一个工具分配参考表,你可以按自己项目的情况调整:

Agent 类型推荐工具原因
代码审查 AgentRead, Grep, Glob只需要读取和分析代码,不直接修改
单元测试生成 AgentRead, Grep, Glob, Write需要读取被测代码,并写入测试文件
代码迁移/重构 AgentRead, Grep, Glob, Edit, Bash需要读取、修改多处代码,可能要跑测试
文档撰写 AgentRead, Grep, Glob, Write读取代码结构,输出文档文件
运维排查 AgentRead, Grep, Glob, Bash需要查看日志、执行诊断命令

需要说明的是,这个表只是我的个人习惯,Claude Code 本身的工具还有很多细分,不同版本支持的完整工具清单也有差异。建议你在定义 Agent 时先看一眼当前版本支持哪些工具名,再按需配置。

5.3 需要谨慎分配的工具

有两类工具,我建议默认不给 Agent 配上:Bash和Edit(或Write)。

Bash是双刃剑:它能帮你执行测试、跑脚本,但也可能让 Agent 在错误的时间执行破坏性命令。如果你确实需要 Agent 跑一下测试,可以给它 Bash 权限,但最好在正文里用强约束语言限制它只能执行哪些类型的命令,例如"只允许运行测试命令,禁止执行 git 操作、禁止安装依赖、禁止删除文件"。

Edit/Write同理:如果 Agent 的核心产出不是代码改动,就别配。宁可让它在报告里给出修改建议,再由主对话去执行,也不让它直接动手。

5.4 用禁止列表兜底

除了按需分配工具,还需要考虑"如何防止 Agent 越界操作"。Claude Code 里有一个全局的权限控制机制,你可以在配置文件里指定允许和禁止的操作路径。例如禁止 Agent 修改node_modules目录、禁止写某些配置文件等。

建议把这类规则写进 Agent 的正文或项目级权限配置里。虽然大部分情况下一句"不要修改 xxx"就够用,但配置一条硬规则,心里更踏实。

6. 完整案例:从零定义一个代码评审 Agent

理论讲了一堆,这里我拿一个实际能用的案例,带你把整个流程走一遍。这个案例我实际在项目里跑过,效果挺稳定,你可以直接照着改成自己的 Agent。

6.1 场景描述

假设场景是这样的:团队使用某个跨平台项目,每次提交代码之前,想用一个 Agent 快速过一遍变更代码,输出一份分级问题清单。这个 Agent 不需要修改代码,只做分析和报告。

6.2 定义文件

在.claude/agents/目录下新建一个文件,命名为code-reviewer.md:

--- name: code-reviewer description: 在代码变更完成之后,需要系统检查逻辑正确性、安全风险和性能隐患时使用。本 Agent 仅做审查和输出报告,不修改任何代码文件。 tools: Read, Grep, Glob, Edit model: sonnet --- 你是一位资深代码审查专家。接到审查任务后,按以下流程执行: 1. 先查看本次变更涉及的文件清单,用 Read 逐个阅读变更内容。 2. 结合上下文,依次检查每个文件: - 逻辑正确性:是否存在边界条件未处理、空值判断缺失、循环终止条件错误等问题; - 安全风险:是否存在注入风险、敏感信息硬编码、不安全的文件操作; - 性能隐患:是否存在不必要的重复计算、N+1 查询、阻塞关键路径的操作。 3. 整理问题清单,每个问题按以下格式输出: - 严重级别(高/中/低) - 文件路径和行号 - 问题现象 - 整改建议 4. 最后输出一段总体评价,说明本次变更的整体质量、主要风险点和建议是否通过。 注意:你只输出审查报告,严禁直接修改任何源码文件。

6.3 实际运行效果

定义好之后,正常使用 Claude Code 时,如果你对它说:

"帮我把这次改动的代码 review 一下,重点看看有没有并发问题。"

主 Agent 会根据 description 的语义匹配,把这个任务分派给code-reviewer这个子 Agent。它会独立读取相关文件、按正文里定义的流程走一遍、输出一份带分级问题的报告。

你不需要手动指定"调用 code-reviewer",它是被主 Agent 自动调用的。这一点在使用时要注意——你也可以在对话里显式说"让 code-reviewer 来审查",两种方式都行。

6.4 让 Agent 在特定场景自动触发

Claude Code 还支持一些触发条件,比如在提交前自动执行某些 Agent 任务。不过这属于进阶玩法,简单提一下:你可以在项目的配置或 hook 里,把code-reviewer挂到 commit 前的流程里,实现"每次提交自动审查"。具体配置语法不同版本不太一样,我建议你先手工调用跑通,再考虑自动化。

7. 实测中的踩坑记录与调试建议

7.1 坑一:description 写得太泛,Agent 进入"幻觉调度"

我在最早定义 Agent 时,写过一个 description 为"用于代码质量相关工作"的 Agent,结果它几乎什么都没被调用过——因为"代码质量相关工作"这个描述跟任何请求的语义匹配度都不够高,主 Agent 总是觉得"还是我自己来更保险"。

后来我把 description 改成"当用户要求对已完成代码进行质量打分、缺陷检查或优化建议时使用",才真正激活了这个 Agent。

所以如果你定义了 Agent 却从来没见它被调用,第一个要检查的就是 description 是不是写得太泛或者太模糊。把它改成"动词+场景+产出物"的组合,调度率通常会上来。

7.2 坑二:工具权限给太大,Agent 越权操作

某次我定义了一个"文档撰写 Agent",为了让它能读取项目里所有代码,我给了它 Read、Grep、Glob、Write、Edit 全套工具。结果它在一次写文档的过程中,看到某处代码风格不一致,顺手就把那段代码改掉了,而且改动里还有个逻辑错误。那次事故导致我不得不回滚代码。

从那以后,我的工具分配策略变得保守得多:凡是产出物是文档或报告的 Agent,绝不给 Edit/Write。

7.3 坑三:正文写成了"步骤清单",Agent 过于死板

还有一个反面教训:我曾在正文里用"第一步必须 xxx,第二步必须 xxx"的方式把一个 Agent 的流程写得非常死,结果它在遇到特殊情况时不会变通,比如它发现某一步需要先查一下上下文,但"流程"没有这一项,它就愣在那里不知道怎么办。

Claude Code 的 Agent 本身有推理能力,正文更好的角色是"设定目标和边界",而不是"穷举步骤"。给原则、给顺序、给约束,但保留一点让 Agent 自己安排细节的空间,效果反而好很多。但反过来,如果你的 Agent 是高度流程化的任务(比如固定格式的批量文件处理),那流程写死一点也没问题。这个分寸需要你自己根据任务类型把握。

7.4 调试建议:怎么确认 Agent 定义是否生效

如果你改了定义文件却感觉"没起作用",有几个常见的检查步骤:

第一步,确认文件位置和文件名没问题:必须在.claude/agents/目录下(或用户级目录),文件名和 name 字段一致。

第二步,在对话里显式调用一下它,比如"用 code-reviewer 审查这段代码"。如果这样能正常返回结果,说明定义本身没问题,更多是 description 的调度问题;如果显式调用都报错,那就得看具体报错信息,通常是工具名写错、模型名不支持这类问题。

第三步,在定义文件里加一点独有的输出标记,比如"你的报告末尾必须加上一句话:本报告由 code-reviewer 生成"。然后看实际输出里是否出现这句话。这是个笨办法,但验证"到底有没有生效"非常直观。

7.5 进阶思路:Agent 之间的协作

当你定义的 Agent 多了之后,还可以让 Agent 之间互相调用。比如test-generator生成完测试之后,可以让主 Agent 再指派code-reviewer审查一遍测试代码。这种多级协作的配置,本质上就是在 Agent 的 tools 里加入Task工具,然后引用另一个 Agent 的 name。

不过我的建议是:先别急着搞复杂协作。一个 Agent 能稳定跑通、产出符合预期,再把注意力放到多 Agent 组合上。否则一旦出问题,排查链路会很长。

8. 我对 Agent 定义的一些后续想法

其实自定义 Agent 这东西,初期你可能感受不到太大差别,因为直接让主对话干活也能完成很多事情。但用久了你会发现,它真正解决的问题不是"能不能干",而是"稳定不稳定"——同一类任务每次跑出来的流程、风格、输出格式是否一致。

我目前比较常用的几个 Agent 包括:代码审查、测试生成、文档维护、提交信息生成。每个 Agent 的描述和工具都花了不少心思调整,现在基本能达到"按一下按钮就出活"的稳定程度。尤其是代码审查那个 Agent,我几乎每次有较大的代码改动都会自动过一遍,明显减少了不少低级失误。

如果你准备开始用自定义 Agent,我的建议是:先挑一个你最常见、最重复的任务下手,照着上面的结构写一个最小可用的定义,跑通之后就知道了。别一上来就规划七八个 Agent 的大体系,那样维护成本会高到让你放弃。

最后分享一个小技巧:Agent 的正文是可以用中文写的,不一定要用英文。Claude Code 对描述语言没有硬性要求,中文表达反而有时候更精准。我自己就全部用中文写,省心不少。

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

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

立即咨询