之前有一段时间,我把 Claude Code 当成一个"会写代码的聊天框"来用:遇到问题就打开终端敲一句需求,问完就结束。直到项目进入频繁迭代,同样的代码审查、变更文档、发布检查每周要重复十几次,我才意识到真正拖慢效率的不是模型能力,而是我没有给工具建立一套可以复用的"协作流程"。
后来我整理出一套自用工作流,核心思路很简单:把 Claude Code 的能力拆成三个层次——命令、子代理、技能。命令负责入口和编排,子代理负责角色化的深度执行,技能负责把领域知识固化下来。三层各干各的事,组合起来就能覆盖从"提交代码到生成发布文档"这类完整闭环。
这篇文章就把这套三层分工讲清楚:每一层是什么、解决什么问题、怎么写,最后用一个"代码变更自动生成文档"的完整案例串起来。如果你已经安装了 Claude Code,但还停留在每次手动输一段 Prompt 的阶段,这篇应该适合你。
1. 背景与核心概念:为什么 Claude Code 需要一个"三层分工"
1.1 从"一问一答"到"工作流"
Claude Code 本质上是一个跑在终端里的 AI 编码代理,它能读项目文件、执行命令、写代码、调测试,比普通对话式 AI 多了"真正操作项目"的能力。
但能力大不代表效率高。很多人的使用方式仍然是:
bash复制claude "帮我看看这两个文件的差异"
这种用法没有错,但它有三个明显问题:
第一,每一个任务都要重新描述背景、目录结构、代码规范,非常啰嗦。项目越复杂,Prompt 就越长,输入成本越高。
第二,上下文容易串味。一个会话里既写前端又改后端,既分析 bug 又生成文档,模型会在各种角色和逻辑之间来回跳,输出质量会明显下降。
第三,重复劳动没有被沉淀。今天写了一遍"帮我按模板生成变更说明",明天还得再写一遍。
因此需要把高频场景拆成固定流程。命令、子代理、技能这三层,分别解决"入口重复""角色混杂""知识不沉淀"的问题。
1.2 三层分工到底各自管什么
这里先给一个直观比喻:
- 命令是快捷键。你不需要重复说一长串话,输入
/doc-change或者运行./doc-change.sh,就能触发一套既定流程。 - 技能是操作手册。它告诉模型"文档模板长什么样""提交信息按什么格式写""上线前要检查哪些项",负责补全领域知识和内部规范。
- 子代理是专职同事。它有一个独立的身份、职责和工具权限,不会干扰主对话,适合承担"安全审查""影响面分析"这类需要固定视角的任务。
三者配合的关系是:命令做编排,技能补知识,子代理做执行。
1.3 与 Coze、Dify 这类工作流平台的区别
现在工作流这个词被大量用在 Coze、Dify 这类可视化平台上。它们的特点是拖拽节点、配置大模型调用,侧重"应用搭建"。
本文讲的是 Claude Code 内部的一套分层协作机制,不涉及可视化界面,也没有复杂的节点编排,全部通过项目目录里的 Markdown 文件、脚本和终端命令实现。对写代码为主的开发者来说,这种方式更贴近日常开发环境,改起来也更直接。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 环境准备与前置知识
2.1 安装 Claude Code 的几种方式
Claude Code 目前没有"只有一种安装方式"的说法,常见的有三种,你可以根据使用习惯选择。
第一种是 npm 全局安装,适合经常用终端的开发者:
bash复制npm install -g @anthropic-ai/claude-code
安装完成后,在终端运行 claude --version 可以确认是否成功。如果提示命令不存在,通常是 Node.js 环境变量没有配置好,或者 npm 全局目录不在 PATH 里。
第二种是 VS Code 插件。安装后在编辑器侧边栏打开插件面板,登录账号即可开始使用。优点是代码上下文和编辑器结合紧密,适合本来就在 VS Code 里写代码的人。
第三种是桌面客户端。它提供了更完整的交互界面,但在纯终端自动化场景下不如 CLI 方式灵活。
版本迭代很快,不同版本的功能细节有差异。本文下面给出的目录结构和示例,以常见版本为基础,如果某条命令在你本机不生效,优先查看 claude --help 或官方更新日志。
2.2 项目级配置:CLAUDE.md 是你的"团队手册"
Claude Code 有一个很关键的项目配置文件:CLAUDE.md,放在项目根目录。会话启动时,模型会自动读取这个文件,把它当作项目的长期记忆。
很多新手会忽略它,结果就是每个会话都要重新交代"我们这个项目是什么技术栈、目录怎么组织、有什么特殊约定"。这些内容放进 CLAUDE.md 之后,模型会自动知道。
markdown复制# 项目名
## 技术栈
- 后端:Java 17 + Spring Boot 3
- 前端:Vue 3 + Vite
- 构建工具:Maven
## 目录约定
- src/main/java:后端业务代码
- src/main/resources:配置与静态资源
- docs:项目文档,所有发布相关文档统一放这里
## 注意事项
- 数据库字段变更必须同步更新 migration 脚本
- 第三方接口调用必须走 client 模块,不允许在 Controller 里直接拼 HTTP 请求
- 打印日志时禁止输出脱敏字段的明文
CLAUDE.md 写得越准确,后面的命令、子代理、技能表现就越稳定。它相当于一个项目级的知识底座,也是三层分工能跑起来的大前提。
2.3 目录约定:三层分工都放在 .claude 目录下
Claude Code 的项目级配置通常集中在 .claude 目录中。一个典型的结构是这样的:
bash复制项目根目录/
├── CLAUDE.md
├── .claude/
│ ├── commands/
│ │ └── doc-change.md
│ ├── agents/
│ │ └── change-analyzer.md
│ └── skills/
│ └── doc-template/
│ ├── SKILL.md
│ └── references/
└── docs/
目录名在不同版本中可能有细微差别,但整体思路是一致的:把自定义命令、子代理定义、技能文件全部收拢到项目里。这样做的好处是团队其他人拉取仓库后,也能直接复用同一套工作流。
3. 第一层:命令,把固定操作固化成快捷入口
3.1 系统自带的核心命令
Claude Code 本身提供了不少内置命令,先熟悉它们,再谈自定义。
常用斜杠命令包括:
| 命令 | 作用 |
|---|---|
/help |
查看帮助,列出当前会话可用的命令 |
/init |
在项目里初始化 CLAUDE.md,引导你补充项目信息 |
/clear |
清空当前会话上下文,适合任务切换时使用 |
/compact |
压缩对话历史,保留关键信息,降低上下文长度压力 |
/cost |
查看当前会话消耗情况 |
/review |
让模型对最近的代码变更做代码审查 |
命令行参数方面,常用的是非交互模式 claude -p,也就是在命令里直接给 Prompt,让模型执行完输出结果后退出。这种模式适合被脚本、CI 流程调用。还有 claude -c 继续上一个会话、claude --resume 恢复历史会话、claude --debug 打印调试信息。
理解这一层的关键是:Claude Code 本身就是命令的集合,你已经在使用它们,只是还没有把它变成自己的工作流入口。
3.2 自定义命令:把一大段 Prompt 压缩成一个短语
自定义命令的作用不是"少打几个字",而是"把容易说漏的信息固定下来"。
假设你每次发版前都要让模型生成变更说明文档,完整 Prompt 可能是:
text复制请分析当前分支和 main 分支的差异,看有哪些文件改动了,判断影响哪些模块,有没有数据库变更或者接口变更,然后按照我们团队要求的模板输出一份变更说明文档。模板是……
这段 Prompt 每次都要重新组织,而且不同人写的版本还不一样。用自定义命令就能把它固化为一个入口。
在 .claude/commands/ 下新建一个 Markdown 文件,例如 doc-change.md,内容结构大致如下:
markdown复制---
description: 生成代码变更说明文档
argument-hint: [git_range]
---
请分析指定范围内的代码变更:{{git_range}}
执行步骤:
1. 调用 doc-template 技能,获取文档模板。
2. 调用 change-analyzer 子代理,分析变更影响面。
3. 按模板输出到 docs/change/ 目录下。
之后在会话里输入 /doc-change feat/order..main,模型就会按照命令里的步骤去执行。
需要注意,不同版本对命令文件的字段支持有差异。如果你本机不识别 argument-hint 或 {{git_range}},可以先用最简格式:只写描述和正文,把参数直接放在命令后面的自然语言里。
3.3 命令层在工作流中的角色:只做编排
在整套工作流里,命令层尽量保持"薄"。它的职责是把任务拆成三个步骤:用什么技能补知识、让哪个子代理干活、最终输出到哪里。
不要在命令文件里写大段复杂的业务逻辑。如果某个步骤需要非常细致的规则判断,把它放进技能或子代理里,命令只负责引用它们。
命令层的另一个好处是团队统一。无论谁执行 /doc-change xxx,拿到的东西都是同一套流程,不会出现"文档格式五花八门"的情况。
4. 第二层:子代理,把复杂任务拆给"多角色协作者"
4.1 子代理是什么
子代理和主对话里的模型不同,它是一个独立的、带固定职责的"小模型角色"。
在普通会话中,模型只拥有一个上下文窗口、一个身份、一套工具权限。遇到多步骤复杂任务时,它要一边处理主任务,一边切换视角,上下文很容易被各种中间信息撑爆。
子代理的思路是:把一部分工作"外包"出去。比如让一个专门的子代理去读 git 历史、查文件引用关系、分析变更影响,最后只把结构化结论返回给主对话。主对话的上下文干干净净,子代理的职责清清楚楚。
4.2 子代理什么时候有价值
我总结三个典型场景:
第一,需要固定角色视角。比如"安全审查员"必须带着攻击者思维读代码,"测试工程师"必须关注边界条件和回归风险。如果让主对话随机切换视角,效果不稳定。
第二,任务适合独立执行。探索型、调研型任务会产生大量中间文本,这些内容不需要进入主对话。让子代理做完,只回传摘要即可。
第三,需要限制工具权限。你可以给子代理只读权限,比如只能 Read、Grep、执行 git 查询命令,不允许写文件和跑任意 shell,降低误操作风险。
反过来,如果任务只是"改一个函数、补一段注释",直接在主对话里做就好了。子代理不是越多越好,每多一层调用都会有额外的调用成本和上下文开销。
4.3 子代理的定义方式
子代理可以在 .claude/agents/ 目录下用 Markdown 文件定义。核心思路是:用 frontmatter 描述身份和工具,用正文写详细职责。
markdown复制---
name: change-analyzer
description: 分析代码变更范围与影响面。适合在分支合并、提交代码、发布前被调用。
tools:
- Read
- Grep
- Bash(git:*)
---
你是项目的"变更影响分析员"。
当用户交付一个变更范围(分支名、提交号或 commit 区间)后,你需要:
1. 用 git 命令获取变更文件列表。
2. 识别这些文件属于哪些业务模块。
3. 判断变更中是否包含数据库脚本、接口定义、配置文件等高风险项。
4. 输出结构化结论,至少包含:变更清单、影响模块、风险点、测试建议、回滚注意项。
约束:
- 只做分析,不修改文件。
- 对不确定的信息,必须标注"待确认"。
- 你的输出要简洁,方便主对话直接引用。
定义好之后,主对话在遇到"分析变更影响"这类需求时,就可能调用这个子代理。你也可以在命令或 Prompt 里显式指定"请调用 change-analyzer 子代理",确保它一定被触发。
4.4 子代理与主对话的配合节奏
在实际运行中,子代理不一定每次都被自动调用。模型需要根据任务描述判断"当前这个需求是不是该用某个子代理"。因此 description 字段很重要,它直接影响触发概率。
如果想让一个子代理可靠地被使用,有两种办法:一是把它写进命令文件里,让命令强制调用;二是把 description 写得更具体,明确"什么时候该用、什么时候不该用"。
5. 第三层:技能,给模型补充"领域操作手册"
5.1 Skills 与子代理的区别
如果说子代理是"专职同事",那么技能更像"操作手册"。
模型基础能力再强,也不可能知道你团队内部的文档模板、发布检查清单、命名规范。每次把这些规则贴在 Prompt 里,既不优雅也不稳定。技能就是把这类知识整理成独立模块,模型需要用到时再加载。
技能与子代理最核心的区别在于:技能不执行任务,它提供知识和方法;子代理是执行者,它可以基于技能提供的方法去执行任务。
另外一个现实原因是上下文长度。技能不能一股脑塞进会话里,否则上下文很容易超长。通过"按需调用 + 临时加载"的方式,只有真正需要某个技能时,模型才会读取对应文件,平时不占上下文。这就解释了为什么社区会讨论"上下文超长""技能里没有 OCR 类技能需要自己封装"这类问题——技能目录设计直接影响上下文占用。
5.2 一个技能的标准结构
技能通常放在 .claude/skills/ 下,一个技能对应一个文件夹。最简结构如下:
bash复制.claude/skills/
└── doc-template/
├── SKILL.md
└── references/
└── 示例文档.md
SKILL.md 是技能的核心描述和操作步骤,它通过 frontmatter 声明元信息,用正文写具体规范。references 目录放附加参考材料,只有模型确认需要时才会去读。
一个很简化的 SKILL.md 示例:
markdown复制---
name: doc-template
description: 输出"代码变更说明文档"的标准模板。适用于版本发布、分支合并、联调前生成变更说明。
---
# 变更说明文档模板
## 变更概览
- 分支/提交范围:
- 变更目标:
## 变更清单
| 文件/模块 | 变更类型 | 影响说明 |
| --- | --- | --- |
## 风险与回滚
- 风险点:
- 回滚方案:
## 测试建议
- 单元测试建议:
- 接口联调建议:
## 待确认事项
- 列出自认为不确定的点
当模型被要求"生成变更说明文档"时,它如果判断 doc-template 技能适用,就会读取这个文件,然后按照模板输出。
5.3 推荐先做的三个技能
自用工作流不需要一上来就写几十个技能,先把高频场景沉淀下来:
- 文档模板技能:包括变更说明、接口文档、周报、复盘文档的固定格式。
- 提交信息规范技能:让模型根据 git diff 生成符合团队规范的 commit message。
- 发布检查技能:把上线前要检查的数据库变更、环境变量、依赖版本、回滚方案做成清单。
每个技能初期都可以是纯 Markdown,不写脚本。等流程稳定了,再考虑在技能里加入 scripts/ 目录,用 Python 或 bash 脚本处理结构化操作。
6. 完整实战:搭建"代码变更自动生成文档"工作流
这一节把三层串起来,做一个可以复制到自己项目里改着用的工作流。场景是:每次分支开发完成后,自动生成一份变更说明文档,内容包括变更文件、影响模块、风险点、测试建议和回滚方案。
6.1 需求与设计
原本做这份文档需要人工去翻 git log、看 diff、判断模块影响,然后套模板,一套下来半小时起步。现在改成 Claude Code 工作流:
- 命令层:提供一个入口,比如
/doc-change或脚本./doc-change.sh。 - 技能层:
doc-template技能负责提供文档模板。 - 子代理层:
change-analyzer子代理负责分析变更影响。
用户只需要给定 git 范围,比如 feat/order..main。
6.2 先写好技能:doc-template
在 .claude/skills/doc-template/SKILL.md 中放入 5.2 节里的模板内容。注意 description 一定要写清楚适用场景,否则模型可能不触发它。
6.3 再定义子代理:change-analyzer
沿用 4.3 节中的 change-analyzer.md,放到 .claude/agents/。它只负责分析,不修改文件,工具权限也只开放给读操作和 git 查询。
6.4 命令层入口:命令文件与脚本二选一
如果习惯在交互式环境里用,可以放到 .claude/commands/doc-change.md:
markdown复制---
description: 生成代码变更说明文档
argument-hint: [git_range]
---
请对 git 范围 {{git_range}} 执行以下流程:
1. 调用 doc-template 技能,获取文档模板。
2. 调用 change-analyzer 子代理,分析该范围的代码变更影响。
3. 将分析结果填入模板。
4. 输出到 docs/change/ 目录下,文件名包含日期和分支名。
如果希望在非交互模式下被脚本调用,可以写一个 bash 脚本:
bash复制#!/usr/bin/env bash
set -euo pipefail
# 用法:./doc-change.sh <git范围>
# 示例:./doc-change.sh feat/order..main
RANGE="${1:?请提供 git 范围,例如 feat/order..main}"
PROMPT="请对变更范围 ${RANGE} 执行以下流程:
1. 调用 doc-template 技能获取文档模板。
2. 调用 change-analyzer 子代理分析变更影响。
3. 按模板生成变更说明文档,输出到 docs/change/ 目录。"
claude -p "$PROMPT" \
--allowedTools "Skill|Read|Write|Bash(git:*)"
这个脚本的核心就是:用 claude -p 进入非交互模式,在 Prompt 里显式指定技能和子代理,再用 --allowedTools 限制工具权限,只允许模型读取文件、写文档、执行 git 查询命令。
在实际项目里,--allowedTools 的具体写法要以你本机 claude --help 的输出为准,不同版本差异较大。万一权限控制太严格导致模型无法完成步骤,可以先放宽到允许 Write,再逐步收窄。
6.5 运行与验证
进入项目根目录,在交互模式下执行:
bash复制/doc-change feat/order..main
或者在终端直接运行脚本:
bash复制./doc-change.sh feat/order..main
预期结果是 docs/change/ 目录下生成一份结构化文档。打开文档检查:
- 变更清单是否完整,相关文件是否都列出来了;
- 风险点是否被识别,比如数据库变更、接口字段变更;
- 测试建议是否具体,而不是空话;
- 模板格式是否符合
doc-template技能的要求。
如果某次分析漏掉了一个关联模块,不用急着改代码。先回看子代理的输出,看看它是否因为上下文不够而没有做全局搜索。如果是因为工具权限不够,可以在子代理定义中增加 Grep 或更多读工具。
7. 常见问题与排查思路
| 问题现象 | 常见原因 | 解决思路 |
|---|---|---|
自定义命令 /doc-change 不存在 |
命令文件没有放在正确的 .claude/commands/ 目录 |
检查目录路径、文件名是否有拼写错误,重启会话后再试 |
| 技能一直不被触发 | SKILL.md 的 description 不够具体,模型判断不出来该用哪个技能 |
把 description 写清楚"什么时候用、解决什么问题" |
| 子代理没有被调用 | 主对话不知道什么时候该用子代理,或者上下文里没有适合的触发场景 | 在命令文件或 Prompt 里显式要求调用子代理 |
| 文档格式不符合预期 | 模板技能没有被读取,或模板本身不够细化 | 先在会话中手动要求模型读取技能内容,确认文件路径无误 |
| 上下文超长,越到后面越慢 | 任务中间过程文本太多,全部堆积在主上下文 | 用 /compact 压缩,或把中间调研任务交给子代理 |
| 脚本执行时报权限错误 | --allowedTools 限制过严 |
查看 claude --help 的权限参数说明,逐步放开读和写工具 |
| 组织账号提示已禁用 Claude Code 访问 | 当前订阅或组织策略没开放 Claude Code 权限 | 联系管理员确认订阅套餐和权限配置,使用合法授权环境 |
| 想用 LM Studio 本地模型跑 Claude Code | 本地模型可能需要额外配置,且工具调用兼容性不确定 | 先确认模型支持工具调用和长上下文,再按官方文档配置;生产环境建议仍使用官方托管模型 |
8. 最佳实践与工程建议
第一,渐进式演进,不要一开始就设计一个大而全的框架。从一个你最头疼的重复场景开始,先写一个命令。命令稳定后再拆出技能,技能复杂到需要固定角色时再引入子代理。我自己的顺序是"命令先行、技能跟上、子代理压轴"。
第二,description 就是触发器的灵魂。无论子代理还是技能,description 都直接影响模型会不会调用它。写得太泛,模型不知道该什么时候用;写得太窄,很多场景又覆盖不到。比较好的写法是"任务类型 + 适用时机 + 输出形式"。
第三,工具权限坚持最小化。子代理和 --allowedTools 都要克制,只给完成任务所必需的能力。让一个负责审查安全问题的子代理拥有执行任意 Bash 命令的权限,是完全没有必要的。
第四,CLAUDE.md 要定期维护。命令、技能、子代理本质上是基于项目知识的工具。项目技术栈换了、目录结构改了,都要回到 CLAUDE.md 里更新。否则文件越是堆得久,模型的判断越容易失真。
第五,注意成本与上下文消耗。每调用一个子代理、每读取一个技能,都会消耗一定的 token。不要在一个 prompt 里同时调用五六个子代理,先看单步骤效果,确认有必要再增加并行度。
第六,团队协作时,把 .claude 目录纳入版本管理。这样团队所有人都能使用同一套命令和技能,文档产出也保持一致。但要注意不要把密钥、token 等敏感信息写进技能或命令文件。
9. 总结与下一步
这套自用工作流的本质,是把 Claude Code 从一个"聪明但需要你反复指挥"的工具,变成了一个"有固定流程、有知识库、有专家角色"的团队系统。读完这篇文章后,你应该已经能分清:
- 命令层负责编程入口和流程编排;
- 技能层负责沉淀领域知识和模板;
- 子代理层负责承担角色型、独立型、需要限定权限的任务。
下一步建议先去翻一下你本地 Claude Code 的 /help,看看当前版本支持哪些字段和参数,再挑一个最近重复做过两三次的任务,用命令、技能、子代理这套思路重新封装一遍。等第一次跑通,剩下的场景自然就顺着长出来了。
最后提醒一句:工具迭代快,不要迷信网上任何一个固定写法。以官方文档和你本机的实际行为为准,把工作流当成"活代码"持续维护,比照搬一套看起来很酷的配置要重要得多。
