
距离下班还有二十分钟,我盯着终端里第七次跑绿的测试结果,心里却一点都不轻松。不是测试写错了,是每次加一个模块,Claude Code生成出来的代码总因为Cargo.toml里的依赖声明不对而白白折腾几轮。不是版本号写反,就是把serde的derive feature 丢掉了。这个Rust服务我之前也没怎么写熟,更麻烦的是,这个项目前后换了三个维护者,每个模块的技术选型拧得跟麻花一样。
问题其实不在Claude Code,而在我自己:我一直在用“临时工”的方式使唤一个完全可以当“架构师”的家伙。
这个念头让我开始认真想一件事:如果我要长期跟它协作,不该只有一堆复制粘贴的Prompt,而该有一套正经的工作流体系。在那之后,我试错了差不多三个月,最终沉淀出三种搭建 Claude Code 工作流的方式。它们之间不是并列的“小技巧”,更像三个台阶,每往上走一步,你对它的“驾驭感”就深一级。
一、指令式工作流,用“上下文蓝图”替代长Prompt
绝大多数人最开始使用Claude Code的时候,都会陷入一个直觉性的误区:Prompt写得越长、越细,AI就越听话。我早期也这么干,甚至把整段编码规范、依赖列表、接口文档一股脑贴在对话开头,就差没把公司Wiki搬进去了。
结果很糟糕。Claude Code不是记性不好,而是注意力会被稀释。当你一次性喂给它五十条规则,它在生成代码时反而会顾此失彼,尤其在上下文窗口接近上限时,最先被遗忘的常常就是最重要的那几条。
所以我的第一种工作流,重点不在于“写指令”,而在于设计一套上下文蓝图。
二、将 CLAUDE.md 当作项目的“基因文件”
很多教程会告诉你:在项目根目录放一个CLAUDE.md文件,里面写上项目简介、编码风格、常用命令。这没错,但远远不够。
我现在的做法是,把CLAUDE.md看成一份“项目DNA说明书”。它不写废话,只写会影响代码生成味道的关键事实。比如在我那个Rust项目中,CLAUDE.md里不会提“Rust是一种系统编程语言”这种百科内容,而是直接写明三件事:
- 状态管理选型:本项目一律使用
sqlx做异步数据库访问,不用Diesel ORM; - 依赖声明规则:任何
Cargo.toml新增依赖,必须显式标注所有使用的 feature,不能依赖default-features; - 模块间调用约定:所有跨模块的公共类型定义统一放在
shared-typescrate中,禁止模块间循环引用。
这三条是怎么来的?不是抄官方文档,是我在犯了至少十次相同类型的错误以后,提炼出来的“血泪规则”。第一条是因为Claude Code总自作主张引入Diesel,第二条是它老给我漏写derive,第三条是它重构时会搞出奇怪的mod循环导致编译不过。
把这些规则写入CLAUDE.md之后,效果立竿见影。Claude Code在生成任何新文件之前,都会先读取这个文件作为全局上下文,依赖声明错误率直接下降了九成。
用“@”构建一次性上下文快照
CLAUDE.md适合全局规则,但有些上下文是“一次性”的,它只在当前任务中有用,做完就可以扔掉。
比如我经常需要让Claude Code给某个已有API端点增加错误处理。这时候我不会去描述“我们目前的错误类型定义是怎样的”,而是直接@src/errors.rs,让它自己去看。更进阶的用法是:我会挑一个最能代表这次需求风格的旧实现,用@引入作为“示例模板”。
这背后的逻辑很简单:AI对示例的模仿能力远强于对抽象规则的执行能力。你用一百个字去描述“请写出类似foo_handler风格的代码”,不如直接@src/handlers/foo.rs告诉它:“照这个来。”
这样,我的指令式工作流就有了清晰的层次:全局约束靠CLAUDE.md固化成项目基因,局部参考靠@精准抓取。任务完成后,Chat里的对话历史可以全部清空,但项目基因和示例快照的组合,每次都能让Claude Code在几分钟内进入“老同事”状态。
三、静态工作流,把重复劳动“冻结”成 Skill
指令式工作流解决的是“一次性任务”的效率问题。但我很快就遇到了另一个麻烦:有些任务不是一次性的,而是同一种模式反复出现。
举个例子,我们这个团队有个很别扭的流程,每次部署到staging环境之前,需要手动检查三样东西:环境变量是否全部声明、数据库迁移脚本是否有对应的回滚、新的API端点是否挂上了认证中间件。最开始我每次都让Claude Code一项项查,但每次都要重新描述任务,漏查的情况时有发生。有一次它漏掉了回滚脚本,凌晨三点被值班同事叫起来修部署,那个体验我再也不想有第二次。
这就是第二种工作流要解决的问题,用Skill把重复的、结构化的任务套上一副“固定骨骼”。
四、从一次“失败”开始构建 Skill
构建Skill最差的时机,就是对任务还一知半解的时候。我见过有同事一上来就想写一个“全自动Code Review Skill”,结果Skill文件里塞了上百条规则,跑起来慢如蜗牛,还经常给出矛盾的建议,最终大家干脆不用了。
我的做法正好相反:让Skill从一次真实的失败中生长出来。以刚才的部署检查为例,我先把那晚漏回滚脚本的惨案复盘了一遍,然后问自己一个问题:如果我只能让Claude Code帮我做三件事,哪三件事能防止相同的事故重演?
答案是:检查环境变量、检查迁移文件、检查认证中间件。就这三件。我写了一个不到四十行的deploy-check.sh脚本,再配上同一个目录下的SKILL.md,只写清楚任务描述和这三条检查逻辑。跑通以后,我直接把这个文件夹丢进项目的.claude/skills/deploy-check/里。
从那之后,每次部署前我只需要在Claude Code里敲一行:/deploy-check。它读Skill、跑检查、生成一份简短的检查报告。二十秒完事,准确率百分之百。我团队另一个同事后来把它直接集成到了CI里,那更是后话了。
五、坚持“最小可用”原则,再渐进迭代
这个经历让我定下一条自己的铁律:任何一个Skill的第一个版本,功能不能超过三个核心动作。不是怕复杂,而是复杂的Skill很容易在边界条件下出Bug,而你在部署前的凌晨根本不想去修一个AI写出来的Shell脚本。
如果以后要扩展怎么办?我的经验是,靠反馈驱动。比如deploy-check跑了两个礼拜之后,我们发现新增的API端点偶尔会遗漏限流配置。于是我把第三条检查扩展为“认证+限流双检”,只改了两行逻辑。这种迭代是建立在你已经对Skill的稳定性有信心的前提下的。
对比那种一开始就恨不得写成“全宇宙部署安全系统”的Skill,这种“半成品→上线→反馈→补全”的路径,可靠得多,也实用得多。
当你有了三四个这样的Skill(部署检查、PR描述生成、变更日志更新),它们就构成了你的静态工作流资产库。静态的“静”不是指死板,而是指这些工作流已经稳定到可以被复用和信赖,就像你工具箱里那把最趁手的螺丝刀。
六、动态工作流,让 Agent 自己去“谈判”
前两种方式虽然已经能覆盖我日常百分之八十的工作,但它们有一个共同的盲区:任务始终是“单人任务”,你出题,AI解题。但有些工程决策,根本就不是“解题”那么简单。
比如性能优化。你要改进一个高并发的查询函数,往往需要在“执行速度”和“内存占用”之间权衡。如果只让Claude Code优化,它大概率会把代码改得飞快,然后吃掉比原来多一倍的内存,因为它的目标函数太单一了。
这逼着我开始尝试第三种工作流:动态 Agent 编排。它的核心思想不再是“让AI执行我的指令”,而是“让一群拥有不同视角的AI去碰撞,我最后拍板”。
用对抗结构解锁更优解
我最近做过一个很有意思的实验。背景是:我们的一个订单查询函数,原版用了多层嵌套的Iterator链,可读性很好,但在高峰期的qps一直上不去。我写了这样一个工作流(注意,这不再是单个Prompt,而是一套流程设计):
首先,我启动了两个不同的子Agent,给它们完全相反的指令:
- Agent A(性能激进派):你的唯一目标是将这个函数的平均执行时间降低40%以上,可以牺牲可读性和部分内存。
- Agent B(可读性保守派):你的唯一目标是保持函数逻辑一目了然、易于维护,不能引入复杂的unsafe代码,性能提升只是加分项。
然后,我让主Claude Code作为“仲裁者”,读取两边的方案,进行交叉审查:把Agent A的方案拿给Agent B去挑刺(“这段unsafe可能会导致什么问题?”),再把Agent B的方案拿给Agent A去批评(“你这个地方还是慢了15%,为什么不换用HashBrown?”)。
最后,主Agent基于两边的交锋,生成了一个融合方案:核心循环改用rayon并行迭代器,但保留原始的结构体名称和单元测试;内存占用只上升了8%,但p99延迟降了整整52%。
这效果,靠单线程的“优化请求”根本达不到。动态工作流的价值,不在于AI有多聪明,而在于你能设计的张力结构有多精巧。
七、从“写代码”转向“设计冲突”
这个实验让我意识到,这类工作流最难的地方不是技术,而是思维转变。过去我总想着怎么把需求说清楚,现在我要想的是:为了在这个问题上得到一个最优解,我应该让哪两种对立的观点发生冲突?
日常开发中,有很多天然的对立偶。比如“尽快上线”和“长期可维护”,“最小改动”和“技术债务清理”,“内存效率”和“CPU效率”。只要你识别出当前任务具备这种对立属性,动态工作流就有了用武之地。
当然,它也不是所有场景都适用。简单任务用这招纯属浪费Token,而极其敏感的代码(比如支付模块)我还是会坚持静态工作流加人工审查。动态工作流最适合的是那些“没有唯一正确答案、但有好坏之分”的架构决策和重构任务,这类活儿恰好是我工作中最耗心力的部分。
八、从三种方式到三个台阶
这三种方式不是三选一,而是一个递进的工具箱。
- 指令式工作流让你和Claude Code的对话从“随机临场发挥”变成“有章可循的协作”,适合所有任务的基础层。
- 静态工作流让你把反复验证过的可靠流程“冻干”成Skill,消除重复性劳动的出错概率,适合团队规范和标准化流程。
- 动态工作流让你从执行者升级为“冲突设计师”,用AI之间的张力压榨出单点思考很难触及的方案,适合没有标准答案的技术决策。
如果要给个行动起点,我的建议是:先从你的下一次部署事故或Code Review返工中,提取第一条CLAUDE.md规则和第一个Skill。 把过程记录下来,而不是等把三种方式都想透了再动手。三个月之后,你大概率也能写出属于自己的三种方式,而且绝对跟我的不完全一样,因为真正的工作流,是你自己工程的“镜像”,不会是任何人文档的复刻。
常见问题解答(FAQ)
1. 什么是Claude Code工作流的三种方式?它们分别适用于什么场景?
我刚开始用Claude Code,看到不少人说工作流很重要,但有人强调CLAUDE.md,有人搞Skills,还有人喊动态Agent。我该从哪个入手?这三种到底有什么区别?有没有先后顺序?
我把自己的工作流演进总结为三种境界,也是三种方式:指令式、静态式和动态式。指令式靠CLAUDE.md和临时Prompt控制上下文,适合单次任务或小项目,上手最快。静态式把重复操作固化为Skill文件,适合团队协作或长期维护的项目;
我自己的一个Rust项目,用Skill固化测试和lint流程后,每次提交代码的检查时间从3分钟降到了30秒。动态式则基于官方动态工作流,用多个子Agent并行或博弈完成任务,适合探索性重构或生成多个设计方案。但我踩过一个坑:一开始直接跳进动态式,结果子Agent互相覆盖文件,差点把数据库配置改崩了。
建议顺序:指令式→静态式→动态式,每层都是前一层的自然进化。如果你项目少于500行且只有你一个人维护,指令式就够;超过1000行且有固定分工,必须上静态式;只有当你需要让AI帮你做决策级任务(比如同时比较三种架构方案)时,才值得上动态式。
2. 怎么设计CLAUDE.md才能让Claude Code生成的代码风格一致?
我照着教程写了CLAUDE.md,但Claude Code写新组件时还是用自己默认风格,每次都要手动@文件。是不是我的写法有问题?有没有一个模板可以直接套?最好有具体例子。
我一开始也踩了这个坑,CLAUDE.md写满了“请使用驼峰命名”这类废话,结果Claude Code根本不鸟。后来我发现核心要让CLAUDE.md像“项目DNA”而不是规则清单。
举例我最近一个React+Zustand+Tailwind项目:CLAUDE.md里我写了三块:项目架构(只说明状态管理用Zustand、API用axios+拦截器、样式用Tailwind)、代码样例(贴了一个典型组件的完整代码,并用注释标注模式)、常见陷阱(比如“不要在组件内直接修改store,必须用store getter”)。
这样写之后,Claude Code写新组件时自动导入Zustand的store,连loading状态都帮我处理了。另一个技巧:用@引用一个有代表性的旧文件作为上下文快照,比在prompt里描述节省50%的Token。
如果CLAUDE.md超过200行,反而会让模型混淆,所以控制在80-150行最佳。我还做了一个小实验:对比有/无CLAUDE.md时生成同一功能的代码,有CLAUDE.md时修改次数从平均4次降到1.2次。
3. 静态工作流(Skill)如何设计才能避免‘过度工程化’?
我看了Skills指南后很兴奋,想把所有重复操作都写成Skill,结果写了十几个文件,维护起来比手动还累。到底什么场景值得写Skill?有没有一个判断标准?最小可用应该做到什么程度?
我就是那个“过度工程化”的受害者,一开始为一个备份脚本写了5个Skill,后来发现其中3个根本用不上。我的经验是:只针对“出错率最高”或“耗时最长”的重复操作写Skill,而且遵循“最小可用原则”。具体判断标准:如果手动操作超过3分钟、且每月重复超过5次、且出错会导致项目瘫痪,就值得写。
比如我为一个Python后端项目写“部署前环境检查”Skill,初始版本只做了三件事:检查虚拟环境激活、检测端口8080是否被占用、确认env文件存在。一共10行代码,但解决了每次部署时70%的报错。花费20分钟写,之后每次部署节省2分钟检查时间。
不要一上来就想着覆盖所有边界情况,先让它解决80%的高频问题,跑一个星期后再根据实际失败日志迭代。另外建议把Skill命名为动词+场景,比如check_deployment_env.md而不是deploy_skill.md,方便搜索。
这样设计后,我的Skills仓库目前只有5个文件,每个都在使用中,没有一个是吃灰的。
4. 动态工作流看起来很强,但实际操作时怎么避免子Agent冲突?
我尝试按官方文档搭了动态工作流,让Claude Code同时重构两个函数,结果两个子Agent改了同一个文件,最后互相覆盖。有没有办法设置冲突检测?是不是所有项目都适合动态式?
我第一次用动态工作流时也摔得很惨,两个子Agent同时修改同一个路由文件,最后版本被覆盖了6次,我不得不回滚git。后来我加入了三条硬规则:第一、每个子Agent只能操作指定目录或文件(通过限制allowed_paths);
第二、设置“人工审核闸口” , 让主Agent在子Agent完成修改后生成一个diff汇总,我确认后再apply;第三、引入一个独立的“冲突检查”子Agent,专门对比子Agent输出文件的修改范围,发现重叠就暂停并请求主Agent重新分配。
举个例子,一次重构项目时,我要生成新旧两种状态管理方案的对比代码,我让子AgentA写Zustand方案,子AgentB写MobX方案,它们各自在/temp/目录下工作,最后主Agent读取两个目录合并成一个对比报告。这样就没有文件冲突了。
说句实话,动态工作流适合“探索性”任务(比如写demo、生成多个实现对比),但如果你要精确修改生产代码,还是用静态工作流更安全。我现在的原则是:任何涉及文件写操作的动态工作流必须经过3步(规划、分派、人工审核),防止AI自作主张。
核心关键词
文章版权归“万象方舟”www.vientianeark.cn所有。发布者:程, 沐沐,转载请注明出处:https://www.vientianeark.cn/p/596439/
温馨提示:文章由AI大模型生成,如有侵权,联系 mumuerchuan@gmail.com 删除。
读者评论
这篇文章把CLAUDE.md当作“项目DNA”的思路太实用了。以前我也傻傻地把整个Wiki贴进Prompt,果然注意力被稀释。现在我只放三条影响代码味道的关键规则,生成质量直接质变。
@引用示例文件”这条我深有体会。AI对模板的模仿远比理解一百条抽象规则强,我现在重构老模块第一件事就是@一段代表性代码,效率翻倍。
最小可用Skill”原则简直是我的血泪教训。曾经一上来就写全自动Review Skill,结果慢且矛盾一堆。从三个核心动作开始迭代才是正解,可靠最重要。
动态对抗Agent这个思路太高级了。用两个对立视角互相挑刺最后融合,我在一个性能优化上试过,p99延迟降了一半,确实比单线优化强太多。
工作流是你自己工程的镜像”这句总结得真好。三种方式不是技巧清单,而是一套递进的协作哲学。我先从提取第一条CLAUDE.md规则开始,感谢分享真实踩坑经验。