首页 / 资讯中心 / 文章详情

AI Agent 落地瓶颈不在模型能力,而在于把资深工程师流程写成 Skill

AI Agent 落地瓶颈不在模型能力,而在于把资深工程师流程写成 Skill ★ FEATURED ARTICLE
1. 为什么“能力”不是 Agent 的瓶颈1.1 一个被反复验证的现场观察过去一年我参与过几个 AI coding agent 的落地项目从内部工具到对外产品都有。每次复盘的时候团队里总有人提出同一个问题“是不是模型能力还不够要不要换个更强的底座”但真正把日志翻出来看会发现一个很反直觉的事实绝大多数失败案例不是模型不会写代码而是它不知道该按什么顺序写、写到什么程度算完、什么情况下必须停下来问人。举个具体的例子。我们让 agent 去修一个线上 bug模型给出的补丁本身逻辑是对的但它跳过了复现步骤直接改了源码改完之后也没跑测试直接说“已修复”。从“能力”角度看它完全具备写这个补丁的水平从“流程”角度看它把一个资深工程师绝不会跳过的环节全跳了。这就是标题里说的那件事——Agent 缺的从来不是能力缺的是把资深工程师的工作流程固化下来的那套东西。这套东西现在业界比较通用的叫法是skill。你可以把它理解成一份写给 agent 看的“作业指导书”什么场景触发、按什么步骤走、每步的输入输出是什么、哪一步是质量门、不通过怎么办。它不提升模型的智力上限但它能把模型的实际表现拉到接近一个靠谱工程师的下限之上。1.2 这篇文章适合谁看如果你正在做 agent 开发、agent 框架选型或者你是一个团队里负责把 AI coding agents 推给一线工程师用的人这篇内容会对你有直接帮助。我会把“怎么把资深工程师的流程写成 skill”这件事拆开讲为什么这么设计、每一步背后的逻辑、实际写 skill 时会踩的坑以及一套可以直接抄的模板结构。如果你只是好奇 agent 是什么、agent 和 harness 有什么区别也能看懂因为我会尽量用生活化的类比来解释。但核心受众还是那些已经动手在做 agent 项目、被“模型明明很强但就是不好用”这个问题折磨过的人。1.3 先厘清几个容易混的概念在往下走之前先把几个高频词摆清楚不然后面容易绕晕。概念一句话解释类比Agent能自主决策、调用工具、多步执行任务的 AI 系统一个员工Skill固化的流程知识告诉 agent 某类任务该怎么做员工手里的 SOP 手册Harness承载 agent 运行的外壳负责调度、工具接入、上下文管理员工的工位和办公系统质量门流程中必须通过的检查点不通过就回退或中止出厂前的质检关卡很多人把 harness 和 agent 混着说其实区别挺明显harness 是“环境”agent 是“决策者”skill 是“知识”。你换一个 harnessagent 的决策逻辑可以不变你换一个 skillagent 在同类任务上的行为会立刻不一样。skill 是这三者里投入产出比最高的那一层因为它不需要动模型、不需要重构框架写一份文档就能显著改变行为。2. 把流程写成 skill 的整体设计思路2.1 核心思路把“隐性经验”变成“显性步骤”资深工程师和普通工程师的差距很多时候不在写代码的速度而在于他们脑子里有一套隐性的检查清单。拿到一个需求他们会下意识地想这个改动会影响哪些模块有没有现成的测试覆盖回滚方案是什么这些思考在人类团队里靠 code review 和口头传承但在 agent 场景下没人能站在它旁边提醒。所以写 skill 的第一性原则就是把那些“老工程师觉得理所当然、但新人包括 agent会漏掉”的步骤一条条显式写出来。注意是显式不是暗示。你不能写“注意测试覆盖”你得写“在修改任何业务逻辑前先运行现有测试套件并记录基线结果修改后必须重新运行同一套件且不允许出现新增失败用例”。这个转变听起来简单做起来很反直觉。因为人类写文档习惯写原则而 skill 需要写的是可执行的动作序列。原则是给会思考的人看的动作序列是给会执行但不会变通的系统看的。2.2 方案选型为什么是 skill 而不是 prompt 或 fine-tune有人会问为什么不直接写一段超长 prompt为什么不微调模型我实际对比过这三种路径结论很明确。Prompt 的问题是它太“软”。一段 prompt 里塞二十条要求模型大概率会漏掉其中三五条而且你没法保证每次漏的是同几条。更麻烦的是prompt 和上下文是混在一起的任务一复杂prompt 就被稀释了。Fine-tune 的问题是成本高、迭代慢。你为了固化一个流程去微调等流程改了模型又得重训。而且微调擅长的是风格和格式不擅长精确的多步流程控制。Skill 的优势在于它是结构化的、可版本管理的、可组合的。一份 skill 就是一个文件改流程就是改文件改完立刻生效。你可以给“修 bug”写一份 skill给“加新功能”写一份 skill给“做代码审查”写一份 skillagent 根据任务类型加载对应的那份。这种模块化程度是 prompt 和 fine-tune 都给不了的。2.3 设计时要避免的三个坑第一个坑是把 skill 写成百科全书。我见过有人把整个团队的编码规范、架构文档、部署手册全塞进一份 skill结果 agent 加载完上下文就爆了真正关键的步骤反而被淹没。skill 要克制一份 skill 只解决一类任务。第二个坑是只写正常路径不写异常路径。资深工程师的流程里一半的价值在于“出错了怎么办”。测试挂了怎么处理依赖装不上怎么处理权限不够怎么处理这些分支不写清楚agent 一遇到异常就会开始自由发挥而自由发挥往往就是灾难的开始。第三个坑是质量门形同虚设。有些 skill 写了“运行测试”但没写“测试不通过时必须停止并报告”。结果 agent 看到测试失败自己判断“这个失败可能不重要”然后继续往下走。质量门必须是硬性的、不可绕过的这一点后面会详细讲。3. 核心细节解析与实操要点3.1 一份合格 skill 的骨架长什么样我经过多次迭代现在用的骨架基本稳定下来了包含六个部分。这个结构不是拍脑袋定的每一块都对应着实际踩过的坑。第一部分是触发条件。明确写清楚什么情况下该加载这份 skill。比如“当任务涉及修改已有函数的行为时”或者“当用户要求新增一个 API 端点时”。触发条件写得太宽skill 会被滥用写得太窄该用的时候用不上。第二部分是前置检查。这是资深工程师的本能动作也是 agent 最容易漏的。包括当前分支是否干净、依赖是否安装、基线测试是否通过、相关配置是否存在。前置检查不通过直接中止不要往下走。第三部分是执行步骤。这是主体但要注意粒度。太粗了 agent 会自由发挥太细了会限制它的合理判断。我的经验是关键决策点写细机械操作写粗。比如“先复现问题”要写细因为怎么复现是有讲究的而“运行格式化工具”可以写粗因为没什么判断空间。第四部分是质量门。每个关键步骤后面挂一个检查点明确通过标准和不通过的处理方式。质量门是整个 skill 里最不能妥协的部分。第五部分是输出规范。告诉 agent 完成后该产出什么改了哪些文件、跑了哪些测试、结果如何、有没有遗留问题。这直接决定了人类 review 的效率。第六部分是回滚方案。万一搞砸了怎么恢复。这一块经常被忽略但在生产环境相关的任务里是必须的。3.2 触发条件怎么写才不误伤触发条件的写法直接决定了 skill 的命中率。我试过两种极端都失败了。一种是写得太抽象比如“当需要写代码时”。结果 agent 几乎每个任务都加载这份 skill上下文被占满而且很多步骤对简单任务来说是多余的。另一种是写得太具体比如“当需要修改 user_service.py 第 42 行的函数时”。这种写法完全没有泛化能力换个文件就失效了。现在我的做法是用任务类型加操作特征来定义。比如任务类型bug 修复操作特征涉及修改已有逻辑、需要理解现有行为、可能影响其他模块这两个条件同时满足才触发。这样既保证了覆盖面又避免了误伤。实际写的时候我会把触发条件写成一段自然语言描述而不是关键词列表因为 agent 对语义的理解比关键词匹配更可靠。3.3 前置检查那些“理所当然”的步骤前置检查这一块我要重点说一下因为它是区分“能用”和“好用”的分水岭。我统计过我们团队 agent 失败案例的原因分布排第一的不是模型写错代码而是在错误的环境状态下开始工作。比如当前分支有未提交的改动agent 改完代码一提交把别人的改动也带进去了比如依赖版本不对agent 跑测试跑出一堆假失败然后基于假失败做出错误判断。所以前置检查至少要覆盖这几项工作区状态是否有未提交改动、是否在正确的分支环境状态依赖是否完整、必要服务是否可用基线状态现有测试是否全绿、构建是否通过权限状态是否有必要的读写权限每一项都要有明确的检查命令和通过标准。比如“工作区状态”这一项检查命令是git status --porcelain通过标准是输出为空。不通过的话skill 要明确指示 agent 停下来报告而不是自作主张去 stash 或者 commit。提示前置检查里不要写“如果有未提交改动就自动 stash”。这个操作看起来贴心实际上很危险因为 agent 可能 stash 了不该 stash 的东西或者忘记恢复。让人类来决定怎么处理未提交改动是更稳妥的选择。3.4 执行步骤的粒度控制执行步骤的粒度是写 skill 时最需要反复调试的地方。我总结了一个简单的判断标准如果这一步存在多种合理做法且选择哪种做法会影响结果就写细如果这一步只有一种做法或者做法不影响结果就写粗。举个例子。“复现问题”这一步存在多种做法可以写一个最小复现脚本可以直接跑现有测试可以手动构造输入。选哪种会影响后续的判断所以要写细明确告诉 agent 优先用哪种方式什么情况下换另一种。而“运行代码格式化”这一步只有一种做法就是跑格式化工具那就写粗一句话带过就行。还有一个技巧是给步骤编号并标注依赖关系。有些步骤可以并行有些必须串行。标注清楚之后agent 在调度上会更合理也能避免它跳过前置步骤直接做后面的。3.5 质量门整个 skill 的灵魂如果一份 skill 只能保留一个部分我会保留质量门。因为质量门是唯一能强制 agent “停下来思考”的机制。质量门的设计要点有三个。第一是通过标准必须可量化。不能写“测试应该通过”要写“测试套件退出码为 0且失败用例数为 0”。第二是不通过的处理必须明确。是回退到上一步重做还是中止任务报告人类还是尝试修复后重试要写清楚。第三是质量门不可跳过。这一点要在 skill 里用强语气写明防止 agent 在“赶进度”的时候自作主张。我实际用下来质量门最有效的三个位置是前置检查之后、核心修改之后、最终交付之前。前置检查后的质量门防止在错误基础上开工核心修改后的质量门防止错误累积最终交付前的质量门防止半成品流出。4. 实操过程与核心环节实现4.1 从零写一份“bug 修复”skill 的完整过程光说结构有点抽象我拿一份真实的“bug 修复”skill 来演示把每一步的写法、背后的考量、以及实际运行效果都讲清楚。第一步是确定 skill 的边界。bug 修复这个任务类型其实挺宽的从改一个拼写错误到修一个并发问题都算。我一开始想写一份通用的后来发现不行因为不同复杂度的 bug 需要的流程差别太大。最后我拆成了两份一份“简单 bug 修复”一份“复杂 bug 修复”用改动范围和是否涉及多模块来区分。第二步是写触发条件。简单版的触发条件是任务描述里明确是修复某个已知问题且预期改动集中在一个文件或一个函数内。复杂版的触发条件是问题涉及多个模块、或者根因不明确、或者需要改动公共接口。第三步是写前置检查。两份 skill 的前置检查基本一致都是工作区状态、依赖状态、基线测试状态、权限状态这四项。区别在于复杂版多了一项“是否有相关的设计文档或历史 issue 可以参考”。第四步是写执行步骤。简单版的步骤是复现问题、定位根因、写修复、跑测试、自查。复杂版多了影响面分析、方案设计、分步实施、回归测试。第五步是写质量门。简单版在“跑测试”后面挂一个质量门要求所有测试通过。复杂版在“方案设计”后面也挂一个质量门要求方案经过人类确认才能继续。第六步是写输出规范和回滚方案。输出规范要求 agent 报告问题根因、修改内容、测试结果、潜在风险。回滚方案要求 agent 在开始前记录当前 commit hash以便随时回退。4.2 关键步骤的参数与判断标准在执行步骤里有几个地方的参数和判断标准需要特别设计我逐个说。复现问题这一步判断标准是“能够稳定触发问题”。什么叫稳定我的定义是连续执行三次三次都能复现。如果只能偶发复现那说明问题可能涉及并发或时序要升级到复杂版 skill 处理。定位根因这一步判断标准是“能够解释问题的完整因果链”。不能只说“这里有个空指针”要说“因为上游传入了 null而这里没有做判空导致解引用失败”。因果链不完整说明根因没找对。写修复这一步判断标准是“改动最小且不引入新依赖”。改动最小是为了降低风险不引入新依赖是为了避免连锁反应。如果确实需要引入新依赖要单独标记出来让人类确认。跑测试这一步判断标准是“原有测试全通过且新增了覆盖该 bug 的测试用例”。只跑原有测试是不够的因为原有测试没覆盖到这个 bug否则 bug 早就被发现了。新增测试用例是防止回归的关键。4.3 一次真实的运行记录我拿一个实际案例来展示 skill 运行起来是什么样。任务背景是用户反馈某个 API 在特定输入下返回 500 错误。Agent 加载了“简单 bug 修复”skill先做前置检查。工作区干净依赖完整基线测试全绿权限正常。四项全过进入执行步骤。复现问题阶段agent 根据用户提供的输入构造了请求连续执行三次三次都返回 500。复现成功。定位根因阶段agent 沿着调用链往上追发现是输入解析层没有处理某种特殊字符导致解析结果为空下游拿到空值后解引用失败。因果链完整。写修复阶段agent 在解析层加了一个判空和默认值处理改动集中在一个函数内没有引入新依赖。跑测试阶段原有测试全通过。Agent 还新增了一个测试用例专门覆盖这个特殊字符输入。新增用例也通过。质量门通过agent 输出报告根因是解析层未处理特殊字符修改内容是增加判空和默认值测试结果是原有测试加新增测试全通过潜在风险是默认值的选择可能影响其他调用方建议人类 review 时关注。整个过程大概几分钟人类只需要 review 最终报告和 diff。对比之前没有 skill 的时候agent 经常跳过复现直接改代码改完也不加测试人类 review 时要花大量时间确认它到底改对没有。4.4 复杂任务的 skill 编排单个 skill 解决单类任务但实际工作里经常遇到需要多个 skill 协作的情况。比如一个需求既涉及修 bug 又涉及加新功能或者一个任务需要先做调研再做实施。这时候就需要 skill 编排。我的做法是定义一个“任务分解”的元 skill它的职责是分析任务、拆解成子任务、给每个子任务匹配对应的 skill、确定执行顺序。这个元 skill 的关键在于依赖分析。哪些子任务可以并行哪些必须串行哪些的输出是另一些的输入都要分析清楚。分析错了轻则效率低重则结果错误。我实际用下来编排层最容易出的问题是子任务粒度过粗。比如把“实现一个新功能”当成一个子任务那它内部还是需要流程控制等于没拆。正确的做法是拆到每个子任务都能被单个 skill 完整覆盖为止。5. 常见问题与排查技巧实录5.1 Agent 不按 skill 走怎么办这是最高频的问题。你写了一份详尽的 skill结果 agent 该跳步还是跳步。我排查下来原因通常有三个。第一个是 skill 没有被正确加载。有些 harness 需要显式配置 skill 的加载时机如果配置错了agent 根本看不到这份 skill。排查方法是看 agent 的上下文里有没有 skill 内容。第二个是 skill 太长关键步骤被淹没。Agent 的注意力是有限的一份三千字的 skill它可能只记住了开头和结尾。解决办法是精简把非关键内容移到附录主体只保留核心步骤。第三个是 skill 的指令不够强硬。如果你写“建议先复现问题”agent 可能觉得没必要就跳过了。要写“必须先复现问题未复现前禁止修改任何代码”。语气上的差别实际效果差很多。5.2 质量门被绕过怎么排查质量门被绕过是很危险的信号说明 agent 在“自作主张”。排查思路是看 agent 的决策日志找到它绕过质量门的那一步看它当时的“理由”是什么。常见理由有几种。“测试失败看起来是环境问题不是我的改动导致的”——这种要检查前置检查是否做到位基线测试是否真的全绿。“这个质量门对当前任务不适用”——这种要检查触发条件是否写得太宽导致 skill 被用在了不适用的场景。“时间紧迫先跳过”——这种要在 skill 里明确写“任何情况下不得跳过质量门”。我还会在质量门后面加一个“确认步骤”要求 agent 显式声明“质量门 X 已通过证据是 Y”。这样即使它想绕过也得先编一个证据出来而编证据比直接跳过更容易被发现。5.3 常见问题速查表问题现象可能原因排查方向解决思路Agent 跳步指令不够强硬检查 skill 措辞把“建议”改成“必须”质量门被绕过通过标准不明确检查质量门定义量化通过标准加确认步骤Skill 不生效加载配置错误检查 harness 配置确认 skill 被正确加载上下文爆掉Skill 太长检查 skill 字数精简主体移除非关键内容异常处理混乱只写了正常路径检查分支覆盖补充异常路径和处理方式多个 skill 冲突触发条件重叠检查触发条件明确边界避免重叠5.4 几个我踩过的坑第一个坑是过度依赖 skill 的自动触发。我一开始觉得只要触发条件写得好agent 就能自己判断该用哪份 skill。实际用下来自动触发的准确率大概只有七八成剩下两三成要么该触发没触发要么不该触发乱触发。后来我改成“自动触发加人工确认”的混合模式关键任务由人类指定用哪份 skill准确率立刻上去了。第二个坑是skill 更新后没有版本管理。有次我改了一份 skill结果正在跑的任务用的是旧版本行为不一致排查了半天才发现是版本问题。现在每份 skill 都带版本号agent 输出报告时要注明用的是哪个版本。第三个坑是把 skill 当成万能药。有些任务确实不适合用 skill比如探索性的调研任务流程本身就不确定硬套 skill 反而限制发挥。判断标准是如果这个任务的“正确做法”是稳定的、可复现的就适合写 skill如果每次做法都不一样就不适合。5.5 怎么评估一份 skill 写得好不好我用的评估标准有三个维度。覆盖率这类任务里有多少比例能被这份 skill 正确引导。通过率用了这份 skill 的任务一次成功的比例是多少。人类干预率用了这份 skill 的任务需要人类中途介入的比例是多少。这三个指标里我最看重人类干预率。因为 skill 的终极目标就是让 agent 能独立完成那些资深工程师能独立完成的任务。干预率降下来才说明 skill 真正把流程固化住了。我实际测下来一份打磨好的 skill能把人类干预率从百分之六七十降到百分之二十以下。剩下的百分之二十通常是任务本身有歧义或者遇到了 skill 没覆盖的异常情况这些恰恰是下一轮迭代要补的地方。6. 从 skill 到工程流程的沉淀6.1 Skill 库的组织方式当 skill 数量多起来之后组织方式就变得重要了。我现在的做法是按“任务域”分目录每个目录下按“复杂度”分文件。比如 bug 修复域下面有简单版、复杂版、紧急版功能开发域下面有调研版、设计版、实施版。每个 skill 文件头部有元信息名称、版本、适用场景、依赖的其他 skill、最后更新时间。这些元信息不只是给人看的agent 在编排时也会读用来判断加载哪些 skill。还有一个实践是建立 skill 之间的引用关系。比如“复杂 bug 修复”skill 里会引用“影响面分析”skill而不是把影响面分析的步骤重复写一遍。这样改一处所有引用它的地方都生效维护成本低很多。6.2 让 skill 随团队经验一起进化Skill 不是写完就完了它应该随着团队经验的积累不断进化。我的做法是每次任务复盘时问三个问题这次有没有遇到 skill 没覆盖的情况有没有哪一步 skill 的指引是错的有没有哪一步可以优化这三个问题的答案直接变成 skill 的修改项。我统计过一份 skill 在前三个月大概会改十几版之后趋于稳定。改得最频繁的通常是异常处理部分因为异常情况是慢慢暴露出来的。还有一个技巧是把 skill 的修改和实际案例绑定。每次改 skill都在文件里记一笔“因为某次任务的某个问题而修改”。这样后人看 skill 时能理解每条规则背后的原因而不是机械遵守。6.3 团队协作中的 skill 管理如果是多人团队skill 的管理需要一些约定。我们团队的约定是skill 的修改要经过 review不能随便改重大修改要通知所有使用者skill 的版本要和 agent 的版本对应避免不兼容。还有一个约定是skill 的所有权。每份 skill 有一个 owner负责维护和答疑。Owner 通常是这个任务域里最有经验的工程师。这样保证了 skill 的质量也避免了“人人可改、人人不管”的局面。我个人的体会是skill 管理这件事技术难度不高难的是坚持。因为写 skill 不像写业务代码那样有直接的产出感它更像是“磨刀”。但磨刀不误砍柴工一份好的 skill 能省下的时间远超写它的时间。我们团队现在的状态是新来的工程师第一件事就是读相关的 skill因为那里面沉淀的是团队最核心的工作方法。6.4 一个延伸思考skill 的边界在哪里最后分享一个我一直在想的点。Skill 能固化流程但流程本身是不是也有边界有些任务资深工程师的做法是“先看看再说”这种探索性的动作能不能写成 skill我目前的答案是能写一部分但写不了全部。能写的是“探索的框架”比如“先看日志、再看代码、再看数据”写不了的是“探索的直觉”比如“看到这个日志模式我怀疑是并发问题”。后者依赖的是大量经验的隐性积累目前还没法完全显性化。所以我的判断是skill 能把 agent 的表现拉到“合格工程师”的水平但拉到“资深工程师”的水平还需要别的东西。那个东西是什么我还在摸索。但至少把流程写成 skill 这一步是绕不过去的基础工作。没有这一步谈 agent 的能力提升都是空中楼阁。
阅读完成 · 觉得有帮助?
咨询建站