ARTICLE DETAIL

资讯详情

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

AI 干活总跑偏?把需求拆成任务,实测可控性提升一个档次

AI 干活总跑偏?把需求拆成任务,实测可控性提升一个档次 先说个结论AI 干活跑偏大概率不是模型不行而是你没把需求拆成任务。两周前我在项目里真正落地了 mattpocock skills 升级方案用同一批任务做了改造前后对比实测下来跑偏这事的可控性提升了不止一个档次。这篇文章就把我踩过的坑、拆解的方法和最终配置完整记录一遍给同样被 AI自由发挥折磨的人一个可以照抄的参考。整件事的起因是一次翻车。当时我在做一个内部项目的 TypeScript 迁移任务本身不复杂就是把一个长期没维护的 JavaScript 工具模块迁到 TS行为保持一致。我偷了个懒把需求原封不动丢给 AI补了一句尽量保持逻辑不变。结果它一口气改了六个文件自作主张重构函数命名合并了两个功能相似的函数还加了一堆它觉得未来用得上的类型守卫。编译不过原有测试挂了一半项目延期两天。复盘的时候我意识到问题从来不在模型而在我给模型的输入——需求太模糊任务边界太弱AI 的自由发挥空间自然就大。后来我按照 Matt Pocock 分享的 skills 方法论做了升级核心就一条先把需求拆成任务AI 干活不再跑偏。1. 先聊那次跑偏问题往往出在需求而不是模型1.1 一次让项目延期两天的实测翻车那次翻车对我的冲击不小不是因为 AI 能力不行而是它错得特别自信。我发过去的原话是把这个模块迁移成 TS尽量保持逻辑不变处理好类型定义它回了一段很漂亮的总结已完成迁移新增了类型定义重构了部分冗余逻辑。听起来一切正常打开 diff 一看问题全来了。它把对外接口改了两个函数被合并成一个理由是功能有重叠它给每个函数都加了 JSDoc 和泛型原模块根本没这个需求最关键的是它搞的是一次性重写而不是逐步迁移中间没有任何可审查的节点。我想确认行为是否一致根本无从下手。最后编译不过、测试挂了一半我还得从头跟它掰扯到底哪一步改错了。这种往返沟通比我自己动手写还累。之后我又用同样的一句话需求 直接开干方式试了三个任务两个都跑偏了。跑偏的形态很统一不是完全做错而是往我以为你想要的那个方向跑。这时候我才真正想明白一个道理——AI 在任务执行里的问题绝大多数不是模型能力问题而是我们对任务的表达能力问题。1.2 为什么模型越强、跑偏越离谱这里有个值得展开的机制大模型天生有意图补全的倾向。当你给的指令信息不足时模型会自动用训练数据里的先验知识去填空把缺失的部分猜出来。这在对话场景里是优点——你说帮我看看这段代码它知道你要的是 review 而不是重写。但到了执行类任务这个能力就成了双刃剑它越自信填补的细节就越多跑偏的幅度就越大。我后来打了这么一个比方新来的实习生老板跟他说把部门的事理顺。平庸的实习生会频繁回来问您说的理顺具体指什么而能力很强的熟手大概率会按自己的理解大刀阔斧地改因为他不觉得自己理解错了。我们和 AI 协作遇到的正是后者。所以那次之后我给所有 AI 任务定了一条铁律**需求必须拆成任务任务必须有产物和验收标准否则不开工。**这也是 mattpocock skills 方法论落地在我项目里的第一块基石。2. mattpocock skills 升级实测它到底改了什么2.1 Skills 的本质给 AI 写操作手册而不是愿望清单Matt Pocock 在 AI 工程实践里反复强调过一个观点和 AI 协作的正确方式不是把它当成有求必应的万能工具而是当成能力很强但需要明确工作手册的执行者。他这套体系里最核心的东西就是 skills——你可以理解成给 AI 预装的可复用流程文件。skills 和普通提示词最大的区别在于提示词是每次临时说一遍愿望而 skill 是把某类任务的标准做法沉淀成一个独立文件里面包含适用场景、执行步骤、每步的输入输出、验收标准和禁区。AI Agent 在执行时一旦识别到相关任务就会主动加载这个操作手册而不是凭感觉自由发挥。说白了一个 AI 没有 skills就像熟手程序员没有项目规范文档——能干活但每次都按自己的习惯干最后出来的东西全看运气。我这次做的升级实测就是先把项目里最常用的几类 AI 任务TS 迁移、代码审查、文档生成改造成 skills 体系然后拿之前跑偏过的真实任务重新跑一遍。结果非常直观跑偏没有完全消失但可控了而且这种可控性是结构性的不是靠运气。2.2 升级前后的一场对照测试为了避免凭印象说话我专门用同一个JS 模块转 TS需求做了对照测试。升级前直接把需求作为一次性提示词扔给 AI升级后先把需求拆成任务清单把执行流程写进 skill 文件再让 AI 按 skill 流程走。两次使用同一个基础模型、同一个代码仓库、同一个验收基准。升级前AI 直接在对话里输出一大段代码声称已完成迁移但没有中间过程可审查编译和测试实际跑不下来。升级后AI 先输出结构分析再输出类型设计然后分阶段迁移最后自测编译和运行测试每步之间我都可以介入确认。结果对比如下观察维度升级前一句话需求升级后skills 任务流改动文件数6 个3 个无关代码改动大量重命名、合并函数几乎为零编译首测失败失败但由 AI 在任务内定位修复原有测试通过率60%100%单步可审查性差好返工次数4 次1 次这只是一个小样本实测说明不了提升了几倍这种普适结论。但它清清楚楚暴露了一个事实AI 不是不能干好活而是需要你先告诉它怎么把活拆成一件件干得好的小事。3. 需求拆任务三步法把模糊指令变成可执行流程3.1 第一步把需求里的隐藏动作全挖出来很多人拆任务时容易犯一个毛病把需求做了个同义改写就当成拆解。比如把这个模块改成 TS拆成把模块改成 TS处理好类型保持行为一致这等于没拆。真正的拆解是问自己一个问题要交付一个合格结果中间必须经过哪些可以被检查的中间产物还拿迁移模块举例。我最终拆出来的任务是这样的T1 结构梳理列出模块全部导出函数、内部函数、跨模块依赖T2 类型设计设计实体类型、参数类型、返回值类型形成类型文件T3 代码迁移把 JS 实现逐函数迁移到 TS替换为类型化版本T4 行为验证编译检查、跑通原测试、对比行为差异每个任务背后都是一个原本被改成 TS四个字吞掉的隐藏动作。AI 在原始需求里看不到这些动作只能自己猜执行顺序和完成标准猜错了就是跑偏。把隐藏动作挖出来显性化跑偏的第一步就被堵死了。这一步的操作技巧是把需求里的每个动词圈出来然后问自己这个动词背后还有哪些动词。比如迁移背后有梳理设计改写验证。直到动词列表里每一个都对应一个可独立验收的产物拆解才算到位。3.2 第二步给每个任务定义输入、输出和验收标准拆出任务清单之后如果只给 AI 一个任务名它照样会跑偏。关键在给每个任务明确三件事输入是什么、输出是什么、凭什么算完成。我习惯用一张表把它们定义清楚任务输入输出验收标准T1 结构梳理模块源码函数清单 调用关系覆盖全部导出函数标注未使用导出T2 类型设计T1 输出types.ts无 any所有导出类型被 T3 引用T3 代码迁移T2 输出 源码迁移后的 .ts 文件tsc --noEmit 通过无显式 anyT4 行为验证T3 输出测试运行报告原有 12 条测试全部通过测试代码零改动这里有个容易被忽略的原则验收标准必须是客观、可脚本化检查的。代码质量好行为保持一致这类描述AI 无法客观判断它只会顺着自己的理解说没问题。但tsc --noEmit 通过原有 12 条测试全部通过这种标准AI 能自己执行并给出确定结果你也能复核。这是把期望变成约束的关键转折点。3.3 第三步排依赖顺序定义并行边界任务定义好之后还要确定执行顺序和并行边界。迁移这个例子里T1 到 T4 是强依赖关系没有结构梳理就没有类型设计没有类型设计就谈不上迁移不迁移自然不用验证。所以这四条任务是严格串行的AI 必须等上一步产物确认后再进入下一步。但并不是所有任务都该串行。如果两个任务改的是不同文件、输入互不依赖让 Agent 并行跑反而效率更高。比如写文档和改代码可以并行因为产物不共享但改 A 模块和改引用了 A 的 B 模块绝对不能并行。我的判断规则很简单**如果两个任务会触碰同一批文件就串行如果产物完全独立才考虑并行。**串行还有个额外好处上一步的产物会作为下一步输入写进上下文目标更聚焦也不容易把两个任务的目标串味。4. 改造前后同一需求实测拆解真的能止住跑偏4.1 改造前一次性丢入的原始表现再复盘一次改造前那次典型的跑偏过程这次看得细一点。我把把这个 JS 模块迁移到 TS尽量保持逻辑不变发给 AI它很快回复了一段自信满满的已完成迁移。实际打开 diff四个问题摆在面前改了对外接口、合并了两个函数、给每个函数加了 JSDoc 和泛型、整个改动是一次性重写。最关键的就是一次性重写这四个字。它没有给我任何中间节点去确认行为是否一致我只能在几百行 diff 里大海捞针。等到编译不过、测试挂了一半我根本说不清是哪一步引入的问题只能从头开始跟它逐段核对。这种体验相信做过 AI 辅助开发的人都懂**跑偏最伤人的不是方向错了而是你不知道它在哪一步开始错的。**一次性输出天然没有过程没有过程就没有回溯点。4.2 改造后按任务清单执行的过程与结果升级 skills 体系后同一个需求走了完全不同的路径。AI 加载 ts-refactor 这个 skill 后按 T1 到 T4 逐步执行。T1 结构梳理完成后它交出一份覆盖全部导出函数的清单。我核对时发现它漏了一个未被调用的工具函数让它补上它只补了那一项没有扩散任何改动。T2 类型设计里对两个外部传入的参数它选了宽松的 unknown 而不是 any这符合 skill 里禁止新增 any的红线。到 T3 迁移阶段第一次编译报了 3 个错误全部集中在两个私有类型定义上。AI 在任务边界内定位、修正、复测没有再碰其他文件。T4 跑原测试12 条全部通过。最让我意外的是出了问题之后AI 不再顺手修复了。放在改造前它很可能一边修类型错误一边再重构点什么但在任务边界约束下它只处理当前任务验收失败的原因处理完就停下等待确认。这种自愈但不越界的行为就是拆任务带来的直接收益。4.3 三个可复用的输出观察这次实测之后我总结出三个对任何 AI 任务都适用的观察可以直接拿去对照自己的项目任务边界内自愈而不是扩散问题拆解后 AI 遇到失败倾向于在当前任务内解决不拆解时遇到失败倾向于换个思路大改往往引发连锁问题。可审查性决定纠错成本每步都有中间产物时你能在五分钟内定位问题出在哪一步没有中间产物时你得在几百行 diff 里大海捞针。失败可回退任务化之后任何一步失败都只需要回退到上一步的产物而不是整个需求重来。这对长任务尤其重要——AI 干活跑偏不可怕可怕的是回退成本高到让你只能硬着头皮继续。5. 配置 Skills 时的三个坑和我的最终配置5.1 坑一任务切得太粗或太细两个极端都翻车第一次写 skill 的时候我把整个迁移流程只分了两个任务分析结构 完成迁移。结果 AI 在完成迁移这个任务里又回到了自由发挥状态——粒度太大等于没拆。第二次我矫枉过正把每个函数都拆成一个任务结果 AI 频繁在任务间切换上下文反复读取同一份源码费用翻倍而且因为任务之间缺少完整的中间产物整体质量反而下降了。我的经验是**每个任务要有一个可以被人类审查的产物作为边界。**如果一个任务做完你拿不到任何新的可检查产物那粒度就是错的。粒度太大产物不可审查粒度太小产物没有信息增量。找到中间那个每次交付都能确认、每步确认都有价值的粒度任务化就成功了。这个标准听起来抽象实际操作时很好判断你问自己一句这一步的输出我单独检查会浪费时间吗会说明切得太碎不会但检查时不知道在看什么说明切得太粗。5.2 坑二验收标准写成正确高质量等于没写我最开始在 skill 里写了保证代码质量确保迁移正确这种话实测等于没说。AI 面对主观描述时会自己定义一个达标标准而且它通常认为自己达标了。后来我把所有验收标准改成客观描述效果立刻不一样。举个具体例子。保持行为一致改成原有 12 条测试用例全部通过测试代码零改动对外导出签名不变。处理好类型改成tsc --noEmit 通过禁止新增 any禁止使用 ts-ignore。这些标准 AI 能自己执行、能给出明确结果我也能复核。写 skill 时宁可多花十分钟把标准写硬也不要让 AI 去猜那个模糊的好字。主观标准是跑偏的温床客观标准是跑偏的隔离墙。5.3 坑三技能之间互相污染实际用起来之后我还踩了一个 Agent 特有的坑技能之间的串味。我同时写了 ts-refactor 和 code-review 两个 skill因为它们的描述里都出现了TypeScript代码这些词AI 经常在我让它做代码审查时加载了重构技能反过来也有。技能一加载错执行流程全跟着错比没有 skill 还乱。我的处理方案是两点。第一description 里写清楚仅在什么场景下使用并加上反向排除条件比如适用于 JS 到 TS 的迁移任务不适用于已有 TS 代码的审查。第二给 skill 加禁区段落明确列出这个技能不该做的事。这样即使描述词有重叠Agent 也能根据场景信息选择正确的技能。还有一个经验不要在同一个 skill 文件里塞多个职责技能单一职责触发准确率会明显高很多。5.4 我最终在用的 skill 配置骨架最后把我目前在用的 skill 配置骨架贴出来可以直接按这个结构改自己的版本--- name: ts-refactor description: 将 JavaScript 模块迁移到 TypeScript。仅用于 JS 到 TS 的迁移任务不用于已有 TS 代码的审查或重构。 --- ## 适用场景 - 接到把 JS 模块改成 TS迁移到 TypeScript类需求 - 前提目标模块有可运行的测试或可对比的输入输出 ## 执行步骤 1. T1 结构梳理列出全部导出函数、内部函数、跨模块依赖输出函数清单 2. T2 类型设计在独立文件中设计实体、参数、返回类型禁止 any 3. T3 代码迁移逐函数迁移实现保持对外导出签名不变 4. T4 行为验证执行 tsc --noEmit 和原测试输出测试报告 ## 任务边界 - 每步完成后暂停等待确认后再进入下一步 - 只允许修改目标模块相关文件禁止改动测试文件和非目标模块 - 遇到验收失败仅修复当前任务的失败原因禁止扩展到其他优化 ## 验收标准 - tsc --noEmit 通过无显式 any无 ts-ignore - 原有测试全部通过测试代码零改动 - 对外导出函数的签名、默认导出、副作用顺序保持不变几个细节值得注意name 和 description 要能精确触发执行步骤里写的是输出什么产物而不是做什么过程任务边界要写禁区验收标准全部可脚本化检查。这套结构我从迁移任务复制到文档生成、数据清洗等场景只需要替换步骤和验收标准框架本身是通用的。6. 防跑偏的底层机制想让 AI 不跑偏先给它跑道的边界6.1 用任务闭环对抗注意力漂移拆任务之所以能止住跑偏背后是有实际机制的。大模型是逐 token 预测的当上下文里混着大量目标之外的代码、说明和对话历史时模型对原始目标的注意力会被逐渐稀释这就是注意力漂移。一句话需求在长对话里就像跑道上的一条线跑着跑着就看不见了。而任务清单机制把长目标切成了短目标每个任务启动时模型的注意力只聚焦在当前这一步和明确产物上。每一段任务都是一个闭环开局目标清晰结束有验收AI 的跑道从一根线变成一条条有边界的短跑道。这也是为什么 skills 体系比单纯多写几句提示词更有效——提示词里的约束是静态的读完就忘而 skill 里的步骤和验收在每个节点反复强调上下文结构本身就是约束。6.2 护栏设计与失败回退另一个容易被忽略的防跑偏机制是护栏。任务清单管住的是AI 该做什么护栏管住的是AI 不该做什么。我在 skill 里固定写三类护栏文件范围护栏只允许改哪些文件明确禁止改测试文件、配置文件、无关模块行为边界护栏禁止新增依赖、禁止改变对外接口、禁止顺手做无关优化失败回退护栏验收失败时AI 必须输出失败原因和定位不允许自行扩大修改范围硬修第三类护栏尤其关键。没有失败回退机制时AI 遇到编译错误会倾向于继续改更多地方试图修复到底结果往往是错误的雪球越滚越大。有了护栏AI 会停下来报告人类在明确的节点介入错误被隔离在当前任务内。跑偏不可怕停不下来才可怕。6.3 这套方法能平移到的其他场景写到这里有人可能会觉得这套东西只适合代码任务。其实不是只要任务有中间产物就能套用。我最近在三个非代码场景上验证过竞品调研报告拆成搜集资料 → 提炼要点 → 结构化大纲 → 逐节写作 → 数据来源校验五个任务每个任务都有独立产出文件。改造后编造数据来源这种老问题基本消失了因为生成结论时必须引用前面任务的产出。用户反馈分析拆成反馈清洗 → 问题分类 → 高频问题统计 → 建议生成每条必须附证据建议质量明显提升因为 AI 生成建议时必须拿着前面的分类结果说话而不是空谈。数据可视化拆成数据探查 → 清洗规则确认 → 图表代码生成 → 渲染验证每步都有可检查的中间产物返工率大幅下降。所以我的结论很直接AI 干不好活很多时候真不是模型的问题而是我们交付需求的方式问题。先花十分钟把需求拆成任务给每个任务定义产物和验收标准再沉淀成可复用的 skillAI 的跑偏率会有肉眼可见的下降。最后分享一个实操上的小技巧拆任务时不要自己闷头拆。先把你的任务清单草稿丢给 AI让它补充遗漏项你再人工确认。AI 在挑错和补全这件事上表现相当不错但在自觉这件事上依然靠不住。你负责定边界它负责补细节两边各干各擅长的这个搭配我实测下来效率最稳。
返回列表