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

Agent技能工程实战:从场景拆解到LoRA微调与上线评估的完整指南

Agent技能工程实战:从场景拆解到LoRA微调与上线评估的完整指南 ★ FEATURED ARTICLE
做Agent有一阵子的人应该都体会过同一个尴尬模型能力已经很强了但业务落地的时候总觉得差一口气。工具函数写了一大堆Agent调用起来却时灵时不灵要么拿错参数要么绕了大半天没回到正题。这两年我花了大量时间在agent-skills这个方向上说白了就是研究怎么让Agent真正拥有一项“干某类活”的能力而不是简单地会调用几个API。这篇文章想把我在技能设计、训练、评估和上线维护里踩过的问题以及沉淀下来的流程系统性地整理出来给准备把Agent推向实际场景的团队和个人一个可以参照的路线。1. 先搞清楚Agent技能到底是什么1.1 技能与工具的本质区别很多团队一开始会把“技能”和“工具函数”混为一谈觉得注册了一批API接口就算给Agent配齐了技能。实际上这两者的差别非常大。工具函数回答的是“我能调用什么”而技能回答的是“我知道什么时候该调用什么调用完怎么判断结果失败了怎么补救”。一个技能应该是一个完整的、可以独立交付价值的能力闭环而不只是一个接口的薄封装。我用一个生活化的类比来解释给一个人一把菜刀他只会“用刀”这不叫技能给他一把菜刀、一块砧板、一份菜谱他能在40分钟内做出一道红烧肉这才能叫技能。中间的差距包括了对食材的判断、对火候的把握、对突发情况的处理。Agent的技能也是一样它至少应该包含四个部分触发判断什么时候启用这个技能、调用序列先做什么后做什么、参数决策每个调用传什么参数、结果校验做完之后怎么确认结果是对的。工具函数只覆盖了其中很小的一段剩下的大量逻辑如果全部靠模型现场推理大概率会出错。1.2 为什么“技能化”比“堆工具”更适合Agent我见过一些项目为了追求功能齐全一口气给Agent挂上两百多个工具函数。结果模型在决策时既要理解用户意图又要在庞大的工具列表里做检索匹配面临的选择太多反而容易选错。这里有一个认知科学里的概念可以借鉴选择过载。人在选项过多时的决策质量会下降模型在工具过多时也会出现同样的问题。技能化做的第一件事就是把这些细碎的工具按业务场景重新打包让Agent面对的不是几百个平铺的函数而是几十个语义清晰的技能模块。技能化还有两个被很多人低估的好处。第一个是上下文的节省。每个技能的内部实现细节不需要全部暴露给模型对外只需要暴露触发条件和输入输出格式这大大减少了Token消耗也降低了模型被无关参数干扰的概率。第二个是可复用性。一个成熟的技能比如“生成周报”“整理会议纪要”“提取合同关键条款”可以被复制到不同的项目里。同一套技能库在多个Agent间共享维护成本会显著下降。说白了技能化解决的不是单个接口的连通问题而是整个Agent系统的工程组织问题。2. 前期设计场景拆解与技能边界2.1 先拆场景再定义技能我在做技能设计时有个原则永远从业务场景出发不要从现有接口出发。很多团队犯了反过来的错误手里有什么API就定义什么技能结果技能边界完全跟着接口走实际业务根本覆盖不住。正确做法是先收集一段时间的用户真实请求然后做归类分析。具体操作可以分三步走。第一步拉取一段较长周期内的用户对话日志至少覆盖一个月最好包含不同时段和不同用户群体。第二步把用户请求按照业务目标分组比如在某个企业内部助手项目里我们可以把请求分成“信息查询类”“内容生成类”“数据分析类”“流程办理类”几大组。第三步对每个组继续细分找出每组里高频出现的操作序列。比如“内容生成类”里很多请求会涉及“确定格式-找参考素材-写初稿-按模板套用-校对”这一连串动作。把这些共性动作序列提炼出来就是技能定义的雏形。这个流程听起来不复杂但做和不做的差别极大。跳过这一步直接写技能描述的团队后面大概率要返工。2.2 技能粒度怎么定技能粒度是设计阶段最容易纠结的问题。我一般把技能分成三个层级原子技能单次可完成的最小动作单元比如“发送邮件”“查询库存”、复合技能多个原子技能的组合比如“处理客户退款申请”、工作流跨模块的完整业务流程比如“新员工入职办理”。粒度太细Agent需要调度大量技能才能完成一个任务中间的衔接错误会成倍增加粒度太粗技能变得又重又臃肿复用性很差稍微换个场景就套不上。这里给一个我常用的判断标准一个技能的触发条件应当足够清晰完成状态应当可以被明确校验。举例来说“发送邮件”触发条件清晰、完成后可以校验发送状态适合做原子技能“处理客户邮件诉求”边界就很模糊得拆成“意图识别”“信息提取”“回复生成”“审核发送”几个环节再看。实际操作中我倾向于先粗后细。第一次定义技能时尽量往复合层级靠跑通之后再根据失败案例拆细。一开始就拆得过细的团队往往在流程调试上消耗大量时间。2.3 技能描述与命名规范技能描述写得好不好直接决定模型能不能在正确时机选中它。很多团队写技能描述时过于简单只写“提供XX功能”模型根本分不清该在什么场景下调用。我的建议是一份合格的技能描述至少要包含四个字段适用场景什么时候应该用这个技能、输入要求需要哪些参数、输出格式返回什么样的结果、边界说明哪些情况不要用这个技能。举个例子一个“总结会议纪要”的技能描述可以这样写适用于输入一段会议转写文本、需要输出结构化纪要的场景输入要求是包含发言人和发言内容的文本输出格式是“会议主题-关键结论-待办事项”三个板块边界说明是“如果输入内容不是会议转写文本直接拒绝处理”。命名上尽量统一风格用“动词宾语”的格式比如“生成月度报告”“查询订单状态”“校验合同编号”。这样的一致性对整个技能库的维护帮助很大模型对命名模式的稳定性会产生依赖。3. 技能落地的完整流程从数据准备到上线更新3.1 数据准备技能专用数据集的构建技能定义好之后真正让Agent“学会”这个技能靠的是数据。这个环节是整个流程里最花时间、也最容易被低估的部分。我这里说的数据不是随便拉一批对话记录扔给模型而是要为每一个技能专门构建一套训练和评估用的数据集。数据来源主要有三条线。第一条线是历史对话中的真实案例把过去已经在业务里跑通的对话抽出来标注出每一步用了哪些技能、参数怎么填、结果怎么判。第二条线是标准操作流程文档很多业务本身就有SOP把这些SOP转化成模型的输入输出对是质量最高的数据来源之一。第三条线是人工演绎找业务专家按场景模拟用户提问让Agent试跑之后再人工校正形成覆盖边界情况的补充数据。数据量上每个技能不求多但要求覆盖度足够。我通常会让每个技能至少有200-500条正样本20-50条明确的负样本即不应该触发该技能的场景。负样本的价值经常被忽视但对训练模型的“拒绝能力”至关重要。一个什么都敢答的Agent比一个偶尔说“不会”的Agent危险得多。数据准备阶段还有一个容易踩的坑忘记去隐私。真实业务数据里全是客户信息不脱敏就用轻则违规重则出安全事故。这一步没有捷径只能一条一条过。3.2 训练与微调的关键选择数据准备好了下一步是把技能注入模型。目前主流做法有两种一种是全参数微调一种是低秩适配LoRA。我的实践经验是大多数团队不应该一上来就做全参微调。全参微调对数据量、算力和调参经验的要求都非常高而且有较大概率破坏模型原有的通用能力出现“灾难性遗忘”——模型学会了新技能却忘了怎么正常对话。相对稳妥的路线是在基座模型上使用LoRA做一个面向技能集的适配层。LoRA的可训练参数量很小训练速度快而且可以给不同技能方向单独训练多个适配器上线时按需加载。比如我可以训练一个“文档处理技能”适配器再训练一个“数据分析技能”适配器两个适配器分开维护互不干扰。这个灵活性对业务持续迭代尤其友好每次只改技能库不需要重新训一个大模型。训练过程中有几个细节值得留意。一个是数据的配比技能数据和通用指令数据的比例最好不要超过1:1否则模型会变得偏科。另一个是训练轮次不要贪多一般1-3个epoch就够了重复训练太多轮会让模型对训练集死记硬背失去泛化能力。训练完一定要做一轮“退化测试”把技能加入前模型能够正常完成的基础任务重新跑一遍确认核心能力没被削弱。3.3 技能评估先自动化后人工很多团队训练完模型之后跑几个示例觉得效果不错就直接上线了这是很危险的做法。技能评估应该是一套分层级的流程至少分成自动化评估和人工评估两轮。自动化评估跑的是大规模回归集人工评估看的是真实业务感受。自动化评估的指标我建议关注三个维度调用准确率该调的时候调了没有、不该调的时候调了没有、参数正确率调用了技能但参数填得对不对、任务完成率调用完技能之后最终输出是否达到了业务目标。这三个指标是递进的哪怕前两个都达标任务完成率低说明技能内部的执行逻辑还有问题。评估集本身最好是和训练集完全隔离的不能复用否则指标虚高得让你产生错觉。自动化评估筛过之后人工评估要模拟真实用户的提问方式尤其要覆盖长尾的、模糊的、口语化的表达。我习惯让业务同事和开发同事分两拨分别做评估。业务同事关注的是“这个回复客户接受吗”开发同事关注的是“技能调用链路有没有出错”。两拨人关注点完全不同合在一起看才全面。评估时用盲评评估人不知道哪个回答来自新模型、哪个来自旧模型这样得到的结论更客观。3.4 上线与更新技能是有生命周期的技能上线不是终点而是另一个起点。一套技能库上线之后要持续监控其运行状态。我使用的方案是“影子模式”灰度新技能先在小流量上并行运行不直接接管真实请求记录它的决策和输出和线上正式技能做对比。跑一段时间确认新技能的决策正确率和任务完成率不低于旧方案再逐步放量切换。上线之后的监控也要分层。最底层看系统层指标比如响应耗时、报错率业务层看调用量、成功率、用户反馈更细一层要看“技能被错误触发”和“技能该触发却未触发”这两个逆向指标。这两个指标最能反映技能边界是否清晰如果数字持续偏高就需要回到设计阶段去修订技能描述和触发条件。技能库的更新节奏我建议每月做一次小迭代每季度做一次大重构。业务是动态的技能库长期不动就像不更新的地图一定会在某个岔路口带错路。迭代不只是加新技能还要定期清除那些已经没人调用的僵尸技能。技能库的体积膨胀会让整体的调度准确率下降保持精简和精准比不断增加新功能更重要。4. 常见问题与排查实录4.1 技能冲突多个技能同时被触发我在实际项目里遇到最多的问题就是技能冲突。用户一句话里包含多个意图时模型可能同时触发好几个技能。比如“帮我把这周的数据整理成Excel发给经理”这句话既涉及“数据分析”技能又涉及“生成Excel”技能还可能涉及“发送邮件”技能。如果技能边界设得模糊模型可能会把三个技能都触发一遍生成一堆没有逻辑关系的中间结果最后乱成一团。排查这类问题的思路是先看日志里模型到底选择了哪些技能再对比技能描述的语义覆盖范围。冲突的根源通常是技能描述里写了重叠的适用场景。解决方式是给技能增加优先级或者在复合技能层面做一次合并调度。我把“数据分析”“生成Excel”“发送邮件”这三个技能做了一个上层路由判断先做数据分析生成结果后自动传递到生成Excel再由发送邮件技能发出。这样就规避了并行触发带来的混乱。4.2 技能不生效训练后模型行为无变化训练跑完了评估却发现模型的表现跟训练前几乎没有差别这种情况我也经历过好几次。第一反应先别怀疑训练代码大概率是数据或调用环节出了问题。最常见的原因是提示词中没有显式引入技能。很多Agent框架在调用模型时会拼接一份系统提示词如果提示词里列出的可用技能列表没有更新模型根本不知道新技能的存在自然不会用。我在这个坑上栽过一次排查了两天才发现是配置文件名写错了。另一个常见原因是数据量太少或者样本太单一。几十条样本训练出来的LoRA很难让模型真正学到抽象的触发规则。检查一下训练数据看是不是全都是一种提问方式。如果是模型大概率只是死记硬背了那个句式换个说法就不认识了。这种情况下需要扩充数据的表达多样性而不是加大训练轮次。最后还要检查训练时的学习率。LoRA学习率设得太低训练等于没跑设得太高模型权重被破坏得面目全非。我一般起始学习率取1e-4到2e-4之间具体根据损失曲线调整。4.3 评估指标虚高模型“背”答案有一种很隐蔽的情况训练数据里包含了不少评估集的相近样本导致评估指标一路飘红真实业务效果却惨不忍睹。这个问题的根子是数据泄漏。训练和评估在数据层面没有严格隔离或者去重不够彻底。我在数据管线里加了两道防线。第一道是重复样本检测用近似匹配算法把训练集和评估集中相似度超过阈值的样本挑出来从训练集里剔除。第二道是逻辑隔离设计评估集时不用历史真实数据原样而是用改写和换场景的方式重新构造。这样即使信息被记忆也不可能原封不动地命中。另有一个经验人为盯着指标看没用定期用完全随机的新问题做抽查比依赖任何固定评估集都靠谱。4.4 几个容易被忽略的实操细节最后一个部分分享几个零零碎碎但非常影响体验的细节。第一技能内部调用的超时设置。Agent技能执行过程中外部接口可能很慢甚至卡死。之前我处理一个“查询物流信息”技能时接口偶尔要等30秒以上用户直接流失。后来统一给技能内部的所有外部调用加上了5秒超时超时就返回“暂时无法获取”并提示稍后再试体验好了很多。第二技能参数的类型约束。模型填参数时字符串和数字之间的转换经常出错。我习惯把所有技能参数定义成带类型的JSON Schema并且在框架层做一次参数校验不符合就触发重试而不是让错误参数直接打进业务系统。第三技能版本记录。每次改动技能都要记录技能版本号、对应模型版本号、上线时间、回滚方案。这个习惯在某些需要“追责”和复盘的时候特别有用。没有版本记录出了问题只能靠猜排查成本会高得离谱。第四多轮对话里的技能记忆。Agent经常需要在多轮对话里持续使用同一个技能。比如用户先问“上季度营收是多少”再问“环比呢”这里的“环比”指的是上季度和更早一个季度的对比。如果技能设计时没有考虑上下文记忆模型会当成一个孤立问题来回答。解决办法是在技能之间传递一个轻量的上下文摘要把前序关键信息带到下一轮而不是让技能每次都从零开始。我个人的体会是Agent技能这件事难的不是某一个单独环节而是整条链路的工程化程度。技能定义、数据、训练、评估、上线、维护每个环节都有各自容易出错的地方但它们是互相影响的定义不好数据就难标数据不干净训练就白跑评估不全面上线就踩雷。踩过几次坑之后我现在做任何新技能都会先老老实实走完一遍全流程哪怕前期多花点时间也好过后面反复返工。最后再提一个建议技能库一定要定期回头看把那些半年都没人调用的僵尸技能清掉。保持技能库的精简和边界清晰比不停堆新功能重要得多。
阅读完成 · 觉得有帮助?
咨询建站