ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

用Skills任务拆分防止AI编码跑偏:从需求拆解到工程实践

用Skills任务拆分防止AI编码跑偏:从需求拆解到工程实践 用 AI 写代码这件事我在真实项目里断断续续试了快半年。最让人头疼的不是模型写不出代码而是写着写着就跑偏你要它修一个按钮的样式问题它顺手把整个组件重写了你让它加个筛选功能它把数据结构也给改了。每次看到这种“自由发挥”我都得花更多时间去回滚和返工。直到我把 Matt Pocock 那套 skills 的思路真正用在项目里才找到问题的关键AI 跑偏不是因为模型笨而是因为需求没有被拆成任务。你给它一个模糊目标它就只能靠猜。你给它一份明确的任务清单它反而能老实干活。这篇文章我会把这套“先把需求拆成任务再让 AI 动手”的方法完整记录下来包括目录怎么建、技能文件怎么写、实测对比结果怎么样以及我踩过的一些坑。适合正在用 Claude Code、Codex、Cursor 这类 AI 编码工具的前端、全栈开发者参考尤其是那种“明明让 AI 干活最后还得自己改半天”的人。1. 先把需求拆成任务这种思路到底在解决什么问题1.1 跑偏的本质模型不是全知助手它在“尽量合理”地猜很多人误以为大模型是在“理解需求”。其实从工程角度看它更像一个下一 token 预测器你给它一段输入它根据已有上下文和训练数据生成一个概率上“最像样”的后续输出。如果你给的输入是一个模糊的意图那它生成的就是一个模糊意图的“合理还原”而不是你心里想的那个精确结果。举个例子。我在一个 React 项目里发现待办列表有个 bug编辑完一项内容之后列表里的排序会随机变。我当时的原始 prompt 是“修复待办列表状态更新导致排序错乱的问题”。模型给了我一个很完整的新组件代码把原来的 useReducer 换成了 useState还加了副作用。表面上看很努力但实际上完全没有定位到问题源头反而把原本稳定的状态管理逻辑推翻了。这就是跑偏的本质。模型没有能力“分清主次”它在每一行代码上的选择都近似于“当前上下文下最合理的结果”。当整体目标不清晰时它就只能用“动得更狠”来替代“动得准”。真正的解法是把模糊目标变成一串足够小、足够具体的子任务让模型不必在每个环节里猜下一步要做什么。1.2 任务拆分不是嘴上说说要变成可复用的“技能”可能你会说“我也知道要拆任务每次我都把需求写得很细。”但问题在于手工拆任务这件事你自己写 prompt 的时候还能控制得住一旦对话变长、上下文变多拆出来的任务就逐渐被稀释最后模型又回到了自由发挥的状态。我看到的 Matt Pocock 那套 skills 思路核心不是“教你怎么拆任务”而是把拆任务这件事固化成技能文件让 AI 在动手前必须执行一次。这就好比训练一个新人光告诉他“你处理事情要有条理”是不够的你得给他一张 checklist告诉他每一步必须做什么、完成到什么样才算通过。在实际操作里一个任务拆分技能文件长这样--- name: task-breakdown description: 在开始编码前把需求拆解为可执行的任务列表 --- # 技能说明 收到需求后禁止直接写代码。你必须先完成以下步骤 1. 提取需求的输入、输出和约束条件判断这是新增功能、修复问题还是重构。 2. 将需求拆解成不超过 8 个小任务每个任务必须是一个独立可验证的改动点。 3. 为每个任务明确验收标准改动什么文件、应有的行为、需要覆盖的边界情况。 4. 按依赖关系排列任务顺序先做数据层/接口层再做 UI 层最后做联调和自测。 5. 把任务列表展示给用户等用户确认后再开始动手。如果每个需要 AI 动代码的场景都先过一个这样的技能文件模型的行为就从“生成一个最可能的大改动”变成了“按清单走流程”。区别是巨大的。2. 实操准备我把 skills 用成了自己的外挂工作流2.1 目录结构别把技能文件全塞在一个文件夹里Matt Pocock 的系统让我受益最大的地方是把 skills 做成了人人都能复制粘贴的目录。它不是一个只能跑在你某个特定 IDE 里的魔法而是以普通 Markdown 文件为载体的提示词模板只要你的 AI 工具支持读取文件上下文就能用起来。我第一次搭目录的时候非常冲动把十几个技能文件全放在一个文件夹里想着“越多越好”。结果模型反而迷失了它不知道该用哪个技能偶尔还会把两个技能文件里的规则混在一起执行。后来我改成下面这种结构问题立刻少了很多。~/.claude/skills/ ├── task-breakdown/ │ ├── SKILL.md │ └── examples/ │ └── bug-fix-example.md ├── code-review/ │ ├── SKILL.md │ └── rules/ │ └── react-hooks.md ├── spec-writer/ │ ├── SKILL.md │ └── templates/ │ └── feature-spec.md └── commit-helper/ └── SKILL.md注意这里的关键点每个技能不是单个 Markdown 文件而是一个带说明文件的目录。说明文件里写清楚“什么时候用、怎么用、步骤是什么”可选的 examples 子目录用来放实际案例。模型在遇到对应场景时会优先读取描述再决定是否加载整个技能。这样既不会把无关内容塞进上下文也能保证规则完整。2.2 三个我实测下来最有用的技能先说task-breakdown。这是最核心的一个也是本次测试的主角。它的作用是在 AI 动手前强制完成需求拆解。我把它放在每个项目的根目录里并要求 AI 每次开工前先找这个技能文件。它看起来是一套简单的提问框架实际上是在帮 AI 建立“先计划后行动”的思维路径。然后是code-review。这个技能用来约束 AI 在改完代码后必须做一轮自检。它不是简单的“检查代码是否有问题”而是要求模型对照任务清单逐一核验这个改动是否超出了任务范围、是否有未覆盖的边界条件、是否存在引入回归的风险。很多 AI 生成的 bug其实就是在没人做这轮自检的情况下溜进去的。最后是commit-helper。这个技能的价值不在生成规范 commit message而在于强迫模型自己看清 diff 里到底改了什么。如果 diff 里出现了任务清单之外的文件它会在 commit 信息里标出“意外改动”。有了这个反馈机制我就能及时发现 AI 又跑偏了。这三个技能组合起来相当于给 AI 装了一圈围栏任务拆分阻止它乱跑代码审查发现它跑偏commit 记录让跑偏的痕迹无处可藏。2.3 在不同 AI 客户端里的加载方式虽然我叫它们 skills但实际上手方式取决于你用的工具。Claude Code 和类似的 CLI 工具通常支持把技能目录放在某个全局配置路径下模型会自动检索可用技能Cursor 这类 IDE 插件则是通过规则文件和 MCP 配置来加载Codex 也有自己的 skills 市场。如果你用的工具暂时不支持自动发现技能也可以把它降级为“项目规则”来使用把技能说明放进项目的 AGENTS.md 或者 CLAUDE.md 里再在 prompt 中指名道姓地要求模型“先执行 task-breakdown 技能再动手”。实测下来效果并不差因为关键不是技能文件被谁发现而是模型在动手前有没有真正看到那一串步骤。3. 实测记录同样的需求三种不同喂法差距比我预想的大3.1 基线测试直接给出需求让 AI 自由发挥为了验证“skills 到底有没有用、有多大用”我做了一组很朴素的对比测试。测试项目是一个 TypeScript 编写的待办事项管理应用需求是我从真实项目里抽出来的一个 bug修复更新待办事项完成后列表的顺序会错乱应该保持原来添加的顺序。第一种喂法是最常见的把这句话直接丢给模型没有附加任何技能文件。模型给出的方案是把列表渲染处的 sort 逻辑删掉改用一个新的字段来记录创建时间。这个方案本身不算错但它做了三个我没有要求的事改了接口返回结构、给每一条待办数据新增了一个字段、顺带调整了另一处过滤逻辑。结果一次修改牵动了四五个文件测试跑完还挂了一条原有的用例。这就是 AI 跑偏的真实写照模型并不是不理解需求而是它在“修复 bug”这个模糊指令下自动假设了一大堆额外需求。它从概率分布里挑了一个“看起来周全”的答案而不是你要的“最小改动”。3.2 测试一我手动把需求拆成 5 个任务再交给 AI第二次测试我没用技能文件而是自己先把需求拆成了带验收标准的任务清单1. 定位找到更新待办完成后排序错位的根因 2. 修复在状态更新层保持原数组顺序不变 3. 验证添加三条待办分别完成第一条确认顺序不变 4. 回归跑一遍现有测试确保没有破坏其他行为 5. 提交给出修改文件和原因看起来足够具体了对吧但真实执行结果被打脸了。模型在完成第 2 步之后跳过了第 3 步直接去执行第 4 步并且在第 4 步里为了“让测试更完整”额外新增了两个测试文件。我反复往回拉它才承认“为了覆盖更多场景而加东西”。为什么手动拆任务还不行因为任务清单虽然被模型看到了但它没有被编进强约束的流程里。模型看到第 4 步“跑一遍现有测试”很自然地联想到了“我还可以顺手加几个测试”。在缺少“禁止做清单之外任何事”这条规则的时候模型总会在下一步选择那个概率最高的“看起来合理”的动作。3.3 测试二让 task-breakdown 技能先接管流程第三次测试我启用了 task-breakdown 技能并且给它配了一条硬性指令所有步骤必须逐项执行任何一步没有完成都不允许进入下一步。模型先调用了技能文件输出了一个任务列表。它比我自己手写的清单更克制每个任务都带了“不要做什么”的禁区描述。比如说在第 2 项里它写了“禁止新增字段、禁止修改接口结构、禁止改动其他组件”。看到这个输出的时候我就知道这次大概率稳了。实际结果也确实没让我失望。模型完成修改后只动了两个文件状态处理函数和对应测试文件。没有额外字段没有重构没有多余的“顺手优化”。我把测试跑了一遍原有用例全部通过。这才是“把需求拆成任务再让 AI 干活”该有的效果。三种喂法的核心差异我在下面的表格里整理了一下喂法是否拆分任务是否强制顺序改动文件数是否超出任务范围直接给需求否否4 个以上是顺带修了无关逻辑手动拆任务是否3 个是新增了测试文件task-breakdown 技能是是2 个否严格限定范围4. 拆任务为什么能防止 AI 跑偏从机制层面拆解4.1 窄化任务空间模型的选择面变小很多人以为技能文件只是“把话说清楚了”这种理解不完整。真正起作用的是任务拆分把模型的生成空间一步一步压缩了。大语言模型在每一步生成的时候都会面对一个巨大的候选空间。直接让它“修复 bug”它可以重写组件、改数据结构、加依赖、调样式甚至重构整个文件夹。但当它先执行 task-breakdown把目标定义为“在状态更新层保持原数组顺序”模型每一步的选择面就窄多了候选方案里不太可能出现“重构整个组件”这种选项。打个简单的比方你让一个实习生“整理这块业务”他大概率会把文档结构、代码注释、甚至团队协作流程都改一遍。但你让他“把第 38 行那个变量名拼写错误改掉”他能做的就只有一件事。任务拆分在 AI 场景里干的就是这事把“整理业务”拆成“修变量名”“补注释”“更新文档”它就不会越界。4.2 制造验收点让模型每一步都有“回头确认”的机会技能文件里的验收标准不仅仅是给模型读的也是给模型的一个“强制暂停点”。每完成一个子任务模型必须重新阅读下一个子任务的目标和验收条件。这一步看起来多余实际上非常关键。在没有验收点的情况下模型的注意力会逐渐漂移。对话越长它越只看得到最近的上下文老早就忘了最开始的约束。而任务列表就像给代码变更打了一个个锚点每一步开始时模型都会回头看一眼“我这一步要做到什么样才算完”。从这个角度看task-breakdown 技能真正提供的不是“计划”而是注意力管理。这也解释了一个有意思的现象有时候我们手动写的任务清单比模型自己拆出来的还细致但效果反而不如技能生成的好。因为手动清单没有内置“每步开始前重新确认范围”的触发器模型只是把任务清单当背景信息而技能文件是把每步都变成了强制跳转点。5. 实测中踩过的坑这些细节不注意技能也会失效5.1 常见的失效模式和处理方法技能文件不是写出来就有用的。我在一周多的实测里遇到过好几次“明明用了技能AI 还是跑偏”的情况。后来我把这些情况整理成了问题清单基本覆盖了新手可能遇到的绝大多数问题。症状常见原因处理方式AI 只读技能前两行后面步骤完全没执行技能文件太长模型在上下文窗口有限的情况下丢失了后半部分规则把最重要的一句放在文件第一行比如“禁止直接写代码先拆任务”同时控制单个技能文件不超过 60 行任务拆出来了但每个任务内部还是自由发挥任务没有附带“禁止做什么”的边界描述每个任务后面都要写“禁改范围”明确列出不改的模块和文件拆完任务后 AI 依然跳步先写了后一步的代码技能里缺少强制顺序的措辞在技能文件最前面写明“必须按任务编号顺序执行未完成当前任务不得进入下一个任务”模型把所有技能文件的内容都混在一起加载了太多无关技能上下文里全是互相冲突的规则按项目最小化技能集合只保留 task-breakdown 和当前任务需要的技能5.2 写技能文件时最容易犯的一个错误规则太空“确保代码质量”这种描述等于没有描述。模型无法把“代码质量”映射到具体的操作。好的技能文件里每个规则都应该是一个模型可确认的动作而不是一个抽象的品质要求。我举一个简单的例子。如果你在代码审查技能里写“注意代码规范”模型只会点点头然后继续按它的习惯输出。但如果你写“逐行检查新改动是否引用了未定义的变量发现一处就给出一处修改建议”模型就有了明确的操作抓手。我后来写技能文件都遵循一个模板触发条件、执行步骤、每步验收标准、禁用列表。前三个决定模型敢不敢做禁用列表决定它做的时候敢不敢乱来。这个模板可以直接复制去用我是在 Matt Pocock 那套 skills 仓库的启发下逐步打磨出来的。--- name: custom-skill description: 一句话说明这个技能在什么场景下使用 --- ## 触发条件 在什么情况下模型必须走这个流程。 ## 执行步骤 1. 第一步要做什么做到什么程度。 2. 第二步要做什么做到什么程度。 ## 验收标准 - 完成的标志是什么可以用什么命令或测试验证。 ## 禁止事项 - 不许做超出步骤范围的事情。 - 不许跳过任何一步。 - 不许在未确认前修改其他文件。6. 把 skill 工程变成常用能力给团队的建议6.1 先建立“技能库”再让每个成员按需加载单人使用 skills 是提高效率多人使用 skills 是统一行为标准。在我实践这个玩法的第二周我把一套基础的 skills 文件放进了项目仓库的.claude/skills目录并且让团队里的其他人也拉取一遍。效果比我想象中更好。原本每个开发者向 AI 描述需求的方式千奇百怪有人给一段话有人只发一个截图。但现在大家共用同一个 task-breakdown 技能AI 收到的输入结构就一致了先拆任务、再写代码、最后自测。产出的代码风格和边界控制也因此变得更可预测。团队使用技能库有一个额外的好处技能文件可以被持续迭代。某个成员在项目里发现 AI 经常犯某一类错误他就可以把这个错误写进对应的禁用列表。比如我们在一个后端项目里发现模型总爱自己改数据库索引就在 code-review 技能里加了一条“未经需求确认不得修改数据库 schema 文件”。下次再遇到同类任务模型就不会踩同样的坑。6.2 把业务常识封装进技能而不是每次重复解释关于 skills 扩展我还有一个小方法把项目里的业务规则也做成技能文件。这样新开发者加入项目时可以快速获得上下文而且随时更新团队共识就沉淀在技能里而不是散落在群聊里朝令夕改。测试驱动开发的团队可以做一个 test-first 技能要求模型在实现功能前先根据验收标准产出测试用例做接口联调的团队可以做一个 api-mock 技能把 mock 数据格式和字段约束写死在技能文件里。最重要的一点是技能文件不是静态的。我建议每个月回头整理一次删掉不再适用的规则补充新踩坑时发现的问题。技能是活的AI 的工作方式才能跟着变稳。用 skills 这个思路还有一个隐藏好处你不用换更强的模型也能提升结果质量。每次跑偏背后都是概率问题而技能文件把随机冒险变成了有边界的流程这也是“大模型时代”里我目前看到的最实用的工程化手段。最后再分享一个小小的收尾经验新写完一个技能文件别急着用到真实任务上。先拿一个“故意挖坑的需求”去测它比如给一个前后矛盾的描述或者一个超出它文件范围的请求。技能文件如果在对抗测试里都不跑偏那它才真正有资格进入你的工作流。我就是靠这个方法把一次次的“AI 跑偏”变成了“AI 按章办事”。
返回列表