ARTICLE DETAIL

资讯详情

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

AI Agent技能命中率治理:四层方案从63%提升到94%

AI Agent技能命中率治理:四层方案从63%提升到94% 做AI Agent最怕什么不是模型不够聪明而是该调用的技能没调对。我这边负责的是数据分析方向的AI基础平台说白了就是给业务同学配一个“会做数据分析的助手”。我们把数据读取、缺失值处理、趋势图绘制、统计检验这些能力都封装成了Skill让Agent按需调用。结果技能库从12个扩到86个之后Skill命中率一路从82%掉到63%。用户问“帮我看看销售表空值多不多”模型居然去调了缺失值填充技能直接把一列数据给填了差点出大事故。这就是典型的Skill命中率下降。所谓命中率就是用户发出一次请求后Agent是否在正确的时机选到了正确的Skill。这个问题如果不治理技能越多错得越离谱。我后来用了一套“四层治理”的方案标准化定义、意图路由、执行校验、反馈闭环。三周时间把命中率从63%拉回到94%端到端成功率从55%提升到92%。这篇文章就把整个治理过程、技术细节、参数调法以及踩过的坑都拆开讲一遍希望能给同样在做AI基础建设的朋友一些参考。1. 先看清问题Skill命中率到底在哪个环节掉的1.1 命中率怎么算才科学在聊治理之前得先把“命中率”这个指标定义明白。很多团队只看一个笼统的“调用成功率”结果出了问题也说不清是路由错了还是技能本身执行失败了。我的习惯是拆成三个独立指标。路由命中率Agent在候选技能集中选中的技能是否就是用户当前真正需要的那个技能。执行成功率技能被调用后参数校验、运行过程、结果输出是否全部正常。端到端成功率从用户请求到最终结果返回整个链路都正确且可用的比例。路由命中率是核心。它反应用户意图到技能映射的准确度也是我们这次治理的主战场。计算方式也很简单拿一段时间内的请求人工或抽样标注出每个请求的“黄金技能Golden Skill”再对比Agent实际调用的技能。如果一样算一次命中。注意不能只算“有没有调出一个技能”因为调出来一个错技能比不调更致命。衡量口径统一之后再去分析下降的原因就很清晰了。1.2 我从82%掉到63%的真实过程一开始技能库只有12个每个功能差异很大模型几乎不会认错。后面业务侧不断提需求今天要加一个“描述性统计”明天加一个“异常值检测”后天又加一个“重复值处理”。很多技能在语义上是邻居比如“缺失值统计”和“缺失值填充”第一眼看上去都是处理空值。模型在embedding向量空间里很容易把这两个技能挤在一起。再加上数据分析场景里用户说法特别随意。有人会说“看一下缺失情况”有人说“有空值的帮我处理掉”还有人直接贴一段数据说“这里怎么这么多NaN”。同一个意图表达方式千差万别。如果Skill的描述里只写了“处理缺失值”那模型大概率会把这个技能当作万能答案凡涉及空值就往这里调。再叠加一个因素embedding模型不是一成不变的。某次我们升级了向量模型后整体命中率又掉了5%。原因就是新的模型对某些短语的语义理解发生了变化导致原本区分度很高的技能描述变得模糊。所以我把这次下降归为四类原因技能定义不标准、检索排序不精准、执行前缺少校验、迭代反馈不及时。这正好对应后面的四层治理。2. 第一层治理标准化定义把模糊打在源头上2.1 一套可以直接抄的Skill元数据模板很多团队定义Skill就是写一个name加一句description这远远不够。第一层治理要解决的是“源头模糊”必须让每个Skill都有一张结构化的“身份证”。我整理了一套元数据模板每个字段都有明确要求。以“缺失值处理”技能为例name: handle_missing_values description: 当用户需要检测、统计或处理数据表中的缺失值空值时使用。 category: data_cleaning intent_keywords: - 缺失值 - 空值 - NaN - 缺失统计 - 填充缺失 input_schema: type: object required: - dataset_path properties: dataset_path: type: string description: 数据集文件路径或表名 strategy: type: string enum: [drop, fill_mean, fill_median, forward_fill] description: 缺失值处理方式不传则默认只统计 output_schema: type: object properties: missing_summary: type: object description: 每列缺失数量与占比 processed_dataset: type: string description: 处理后数据集路径仅执行填充时返回 examples: - user: 客户表里空值太多帮我看看哪些列缺失严重 intent: 缺失值统计报告 output_summary: 返回每列缺失数量与占比这里面最容易被忽略的是intent_keywords和examples。keywords用于给模型一个粗糙的语义锚点examples则给出精细的参考范例。input_schema和output_schema不是为了写代码而是为了让路由层和校验层有据可依。还有一个很重要的原则一个Skill只做一件事。比如“处理缺失值”这个技能就不应该同时负责“去重”和“类型转换”。职责越单一语义边界越清晰命中率越高。2.2 描述怎么写才不容易被“认错”description是整个技能定义里最关键的一个字段但很多人写得像产品功能介绍。我看到过最典型的错误写法是“该技能支持对数据表进行缺失值处理包括均值填充、中位数填充等多种方法同时支持对异常值进行检测……”这句话的问题在于把多个意图混在一起而且“支持”“包括”这类词会让模型抓不住触发场景。我的固定句式是“当用户需要X时使用此技能。” 一句话说清触发条件。推荐“当用户需要统计或报告缺失值时使用此技能。”不推荐“本技能可以完成缺失值处理相关任务。”第二种写法在向量检索里很容易跟“异常值处理”这类技能撞车。因为“处理”这个词太泛了。另外description里不要出现“其他”“等等”这类模糊补充词。你一旦写了“等功能”模型就会把这个技能当成兜底选项。我们后来专门做了一次清理把所有description中的泛化后缀全部删除这一项动作就让命中率提升了5个百分点。第一层治理的前期工作量不小86个技能我们花了大概一周做标准化。但很值得因为后面的路由、校验、监控全都依赖这套元数据。3. 第二层治理意图路由和检索排序让选择过程可控3.1 先分类再检索的两步路由第一层做完之后命中率从63%提升到了74%。但这还不够。原因是技能库仍然很大直接在86个技能里做向量检索容易出现相似技能之间的“抢单”。我把单一检索改成两步路由先粗分类再细检索。第一步用一个轻量级意图分类模型判断用户请求属于哪个技能域。比如“data_cleaning”“visualization”“statistical_test”“report_generation”四大类。这个分类模型不需要很强的能力一个基于BERT的小模型或甚至规则加embedding分类器都可以。重点是先把搜索空间缩小到二十几个技能以内。第二步在分类域内做embedding检索加重排。检索拿到Top-K个候选再用一个更强的cross-encoder模型逐对打分选出最优技能。代码逻辑大致是这样的def route_skill(user_query, skill_index, domain_model, reranker): domain domain_model.predict(user_query) if domain not in skill_index: return None candidates skill_index.search(user_query, domaindomain, top_k5) if not candidates: return None scores reranker.score(user_query, candidates) best_skill max(candidates, keylambda x: scores[x]) if scores[best_skill] 0.62: return None # 置信度不足拒答或追问 return best_skill这套设计的好处是分类器可以捕捉领域级的语义差异重排器可以捕捉技能级的细微差别。比如“统计缺失值”和“填充缺失值”在数据清洗域里是邻居但重排器看了完整描述后能分清“统计”和“填充”这两个动作的区别。3.2 阈值怎么调Top-K怎么选这一步很多人会卡在参数上。我先说阈值。阈值的作用是防止低置信度时还硬选一个技能。我们测试过不同阈值下的命中率和拒答率。阈值命中率拒答率未匹配任何技能0.5085%1%0.6090%4%0.7093%11%0.8096%23%看起来阈值越高命中越高但拒答率也暴涨。业务场景里23%的请求直接没有结果用户早就跑了。这其实是一个精确率和召回率的权衡。结合线上反馈我最终把阈值定在0.62命中率能保持在93%左右拒答率控制在5%以内。而且一旦拒答我们会触发一个“澄清追问”让用户补充信息而不是干巴巴地报错。Top-K的选择也有讲究。K太小正确技能可能不在候选集里K太大重排器的负担和噪音都会增加。我试过K从1到10最后定在5。原因是通过分类器过滤后同一个域内的相似技能一般不超过7个Top-K5能覆盖绝大多数正确项同时不会把不相干的技能拖进重排阶段。第二层治理完成后命中率从74%提升到了87%。但还有一个问题没解决就算技能选对了执行时也可能因为参数不对而失败。4. 第三层治理调用前后两道质检拦下错误执行4.1 参数和输出Schema校验路由命中不代表万事大吉。我们遇到过很多次模型正确选择了“绘制销售额趋势图”技能但传入的日期字段名称是“create_date”而技能要求参数必须是“date_column”。结果技能直接抛异常用户只看到一行红色错误提示。所以第三层治理必须在调用前做严格参数校验在调用后做输出结构校验。调用前使用input_schema做校验。以缺失值处理技能为例import jsonschema with open(handle_missing_values.yaml) as f: skill_schema yaml.safe_load(f) input_schema skill_schema[input_schema] user_params {dataset_path: /data/customer.csv, strategy: drop} jsonschema.validate(user_params, input_schema)校验失败时有两种处理方式。一是直接向用户索要缺失参数二是使用该技能的默认参数。我们一般优先“追问补参”因为默认值可能不符合用户真实意图。比如用户希望统计缺失情况结果默认填了“drop”就会变成直接删数据。调用后要对输出结构做二次校验。比如技能返回的是一个文件路径还是一个统计表如果黄金技能约定返回missing_summary但实际返回了一堆调试日志说明技能内部逻辑可能已经出错这时不能直接把结果抛给用户要转到一个兜底路径。4.2 沙箱试运行与兜底降级这一层里最有价值的动作是给“有写操作”的技能加沙箱试运行。数据分析场景里很多技能会改写数据表填充缺失值、删除重复行、聚合汇总。一旦误操作数据恢复成本非常高。我们的做法是凡是包含写入行为的Skill先把目标数据集复制一份到沙箱环境在副本上执行观察影响行数、字段变化、运行时间。如果影响行数异常大到超过预设阈值比如本来预计影响500行结果改了5万行系统就会中止操作并要求人工确认。同时还要准备兜底降级策略。比如一个技能因为外部依赖崩溃而失败时不能整个流程就断了。我们会把结果转为一个“只读报告技能”至少把数据情况讲清楚。用户如果后续确认要写操作再重试。这样做到“宁可少做不可错做”。第三层治理落地后执行成功率从91%提升到97%端到端成功率明显改善。但我们的目标不止于此。要想让命中率长期稳定还得依靠第四层反馈闭环。5. 第四层治理反馈闭环和持续迭代5.1 全链路监控该看哪些指标治理到了第三层本质上已经是一个相对完善的系统。但Skill命中率是一个会动态变化的值用户表达会变模型会升级业务也会新增技能。如果不做反馈闭环过一个月命中率又会悄悄掉回去。所以第四层治理的核心是建立全链路监控。我们在每次请求中记录一个trace_id并把以下字段存下来用户原始请求路由分类结果检索候选技能列表最终选中的技能参数校验结果执行结果用户是否有后续追问或纠正端到端耗时然后每周汇总一次指标。除了命中率我特别关注两个衍生指标一是“用户纠错率”。如果用户问完“缺失值统计”后又补一句“不是要填充我要看报告”说明Agent第一次就选错了。这个指标比单纯看命中率更灵敏因为它反映的是真实反馈。二是“技能空转率”。有些技能被路由选中了参数也对执行也成功但出来的结果用户根本没用直接关闭了页面。这说明这个技能的用户价值存疑可能需要调整入口或者下架。5.2 失败案例如何变成训练语料监控只能发现问题真正解决问题要靠迭代。我把所有路由失败的案例汇总后每周做一次失败聚类分析。按用户请求和黄金技能进行分组找出哪些表达方式经常被分错。举个例子我们有一批请求说“把这个表里面的缺失值补齐”模型总是选成“缺失值统计”。但人工看这些请求其实用户确实想执行填充。原因是原Skill描述里“填充”这个词权重不够。于是我们在keywords和examples里补充了“补齐”“填上”“不要留空”等说法。下一周再看这组请求的命中率明显回升。这些被修正的案例也是微调分类模型的黄金数据。每两周攒一批大概400到600条用来做一轮轻量级微调。不需要很多数据重点是难区分的边界case。这样做下来模型的分类能力会逐步对齐真实使用习惯。另外不要每次都期望由算法自动完成所有迭代。该人工介入时必须人工介入。我们的流程是算法先聚类和排序再由一位懂数据分析的同学逐条看案例判断是改skill描述、加示例还是需要拆分技能。这个“人机协作”的环节看起来原始但效果最好。第四层治理上线后路由命中率稳定在了94%端到端成功率到了92%。6. 落地数据、避坑清单和扩展想法6.1 三周治理的效果对比整个四层治理不是一次性做完的我是按周推进的。你可以按这个顺序参考它背后是一个从定义到路由、再到执行和反馈的完整闭环阶段路由命中率执行成功率端到端成功率用户满意度5分制治理前63%88%55%3.8第一层标准化定义74%89%66%4.0第二层意图路由87%91%79%4.3第三层执行校验88%97%85%4.5第四层反馈闭环94%98%92%4.7需要说明的是第3阶段路由命中率只提升了一个点但执行成功率的提升非常明显。这说明第三层的主要价值不在“选对”而在“把对的技能变成可用结果”。端到端成功率是用户感知最明显的指标从55%到92%业务侧基本可以用起来。6.2 踩过的坑和排查速查表这里分享几个我踩过比较深的坑。第一坑描述词加太多“高质量”“智能”这类形容词。模型会把形容词当成能力锚点反而忽略了任务动词。清理之后命中率反而回升。后来我们规定description只能用短句说触发条件禁止使用形容词。第二坑阈值一开始设到0.8命中率好看但拒答率20%以上业务同学直接炸了。参数调优必须结合拒答率一起看不能只看命中率。第三坑沙箱试运行没有做超时控制。有些技能在大数据集上跑得慢沙箱挂起半天不返回。后来给所有沙箱任务加了超时和资源限制超过30秒直接降级为只读报告。下面是一份常见问题速查表你可以直接拿去排查现象可能原因排查思路总是命中同一个技能该技能description写得太泛检查是否包含“其他”“等等”等兜底词某个技能几乎不被选中描述与真实使用场景脱节人工对照业务需求重写description路由正确但执行失败参数Schema缺字段或枚举值不全查看trace中的参数校验日志同义表达时有时中有时不中技能examples太少补充该场景的典型用户说法升级模型后命中率骤降embedding语义空间变化用历史失败案例回归测试必要时回滚模型版本6.3 这个方案还能怎么延伸四层治理虽然是在数据分析AI基础平台上验证的但思路完全可以迁移到其他Agent场景。比如智能客服场景的技能中心代码生成助手里的工具链都可以用同样的框架标准化定义、意图路由、执行校验、反馈闭环。后续我准备引入主动学习机制。当路由置信度低于阈值时不再只是拒答而是让用户从几个候选技能里点选一个。用户的点选结果就是高质量训练数据。这样可以持续降低拒答率同时不牺牲命中率。还有一个方向是把治理过程中的黄金案例沉淀成一个基准集以后每次升级模型或者技能库变更都先跑一遍基准回归测试。这样能提前发现问题不用等线上命中率掉了再去救火。我个人最大的体会是Skill命中率问题本质上不是模型问题而是技能工程和内容治理问题。模型的能力越来越强但如果我们交付的是一个定义混乱、无校验、无反馈的技能库再强的模型也救不回来。四层治理听起来是四个步骤其实是一套工程纪律。先让每个Skill有清晰的身份再给Agent一个理性的选择过程最后靠数据和反馈持续修正。这套纪律一旦建立技能库从几十个涨到几百个我心里也是有底的。
返回列表