资讯动态

智能体技能体系实战:从工具调用到技能编排的完整指南

发布时间:2026/10/14 10:17:44 来源:尧图企业网站定制
从一次失控的对话说起。我在做某智能体项目的时候遇到一个特别尴尬的情况用户问了一句“今天上海适合穿什么衣服”我的智能体先调了天气接口拿了温度然后信心满满地回复“建议穿羽绒服”结果那天的实际体感温度是28度。翻日志一看智能体把“今天最高气温18度”里的“18”和“最低气温14度”里的“14”混在一起得出了“全天都在14到18度”的结论又错误地把“18度”当成“推荐穿厚外套”的触发条件。问题的根源不在模型推理能力而在技能调用这一层——技能没有写明输入参数的单位、量纲和典型取值范围模型只能靠猜。这个场景让我真正开始重视一件事agent-skills也就是智能体的技能体系。它不是简单的“给模型塞几个函数”而是一整套关于技能定义、组织、检索、编排、评测和迭代的方法。过去一年我在某团队里专门负责这部分工作从技能数量不到20个的小项目做到技能库接近300个的复杂系统中间踩了不少坑也积累了一些可以复用的经验。这篇内容适合三类人正在搭智能体但感觉技能调用不太稳定的开发者、想把已有的工具集合改造成技能库的团队以及想系统理解“智能体为什么这么笨”的技术爱好者。1. 技能的定义先搞清楚“技能”和“工具”的区别1.1 从“调用工具”到“拥有技能”的转变很多人觉得技能就是工具其实差别很大。工具是一段代码、一个API、一个Python函数描述里写着“输入城市名返回天气”。技能是模型能理解、能调用、能评估效果的一等公民它包含对触发条件的描述、对输入输出的约束、对使用边界的说明、对失败时的处理建议。换句话说技能是给模型看的一份完整“说明书”而工具只是这份说明书背后的执行者。举个例子。一个“查天气”工具描述可能是“get_weather(city: str) - dict”。一个“查天气”技能描述则会是这样name: weather_query description: 查询指定城市当前或指定日期的天气信息适用于用户询问天气、穿衣建议、出行规划等场景。 trigger_conditions: - 用户明确提到城市和天气如“北京今天下雨吗” - 用户提到穿衣建议、是否需要带伞等间接需求 - 用户提到出行安排需要天气作为辅助判断 parameters: city: type: string description: 城市名支持中文和拼音如“上海”或“shanghai” required: true date: type: string description: 日期格式为YYYY-MM-DD默认今天 required: false unit: type: string enum: [celsius, fahrenheit] default: celsius description: 温度单位默认摄氏度 outputs: temperature: 当前温度单位摄氏度注意与体感温度的区别 high: 当日最高气温 low: 当日最低气温 condition: 天气现象描述如晴、雨、多云 wind_level: 风力等级数值范围0-12 failure_handling: - 城市不存在时返回提示“未找到该城市请确认名称是否正确” - 当日无预报时返回最近一个可查询日期的数据这个格式不一定标准但思路很清楚技能描述里最关键的不是“能干什么”而是“什么时候该用”“参数怎么传才安全”“结果怎么解读才不出错”。我在实战中最大的体会是模型对技能的误用几乎都是因为描述里的信息不够具体模型不知道单位的含义、不知道参数的边界、不知道结果的解读方式。1.2 技能的三个核心组成部分我把技能拆成三个部分这三个部分缺一不可第一个是元信息包括名称、唯一标识、版本号、所属域。元信息解决的是“这个技能怎么被索引找到”的问题。技能库到一定规模后重名和语义相近的情况特别多。比如“查询城市天气”和“根据城市获取日出日落时间”前者返回的数据里其实包含日出日落字段但后者是独立技能。如果元信息设计不合理模型容易选错。第二个是行为契约描述技能的输入、输出、副作用和约束。行为契约要详细但不能写得太机械。我见过有人把技能描述写成严格的“当且仅当用户输入匹配某正则时才允许调用”这种写法在真实对话里会导致大量漏触发。更好用的是把约束写成人话比如“当用户只说了‘今天’没有说城市时不要调用此技能需要先让用户补充城市名”。第三个是质量属性包括预估调用延迟、失败率、依赖的其他技能或服务。质量属性不是给模型看的更主要是给人维护用的。某个技能上周的失败率突然从3%升到20%排查的时候如果能定位到是底层接口波动还是技能描述变化导致模型选错了参数处理起来会快很多。2. 技能描述的语言怎么和模型“说清楚”一件事2.1 描述的正向信息与负向信息写技能描述最容易被忽略的是负向信息。正向信息告诉模型“你可以做什么”负向信息告诉模型“你不该做什么”。我的经验是负向信息在真实场景里比正向信息更重要因为模型倾向于过度调用技能——只要用户的表述有一点相关它就跃跃欲试。举一个具体场景。项目里有个“获取用户账户余额”的技能描述里明确写了触发条件是“用户询问自己的余额”。但有一次用户说“我这个月的账单很奇怪你帮我看看是怎么回事”模型居然调用了余额查询技能然后报了一个余额数字出来根本没有解决“账单奇怪”的问题。原因是账单相关的技能描述里没有把“注意区分账单明细和余额查询”写进去。加上这句负向提示之后误调用率从31%降到了9%。所以在写描述的时候我会专门留一个“not_for”字段not_for: - 用户询问账单明细或消费记录时不要使用此技能 - 用户询问转账、还款等操作流程时不要使用此技能 - 需要历史余额或特定时间点余额时请使用余额历史查询技能这个字段看着简单但对实测指标的改善非常明显。模型在决定是否调用技能时本质上是在做一个分类决策负向样本和正向样本一样重要。2.2 参数描述给模型留出判断空间参数描述是另一个容易出问题的地方。很多人在写参数时只给名字和类型比如“city: string”这远远不够。模型需要知道这个参数的值该怎么填边界是什么有没有默认值不同取值会导致什么结果。拿城市名来说如果只写“string”模型可能会把一句话里的多个地名都填进去比如“我想比较杭州和苏州的天气”它可能同时填city为“杭州”和“苏州”但技能本身只支持单个城市查询。参数描述里就不好写死“只允许一个城市”因为那样模型可能直接不调用技能而是自己瞎编天气。更好的方式是写“该参数接受一个完整城市名不支持多个城市如果用户提到多个城市请拆分为多个调用”。这样一来模型调用技能的概率更高同时行为也更合理。参数的数量也是一个关键变量。我做过一个统计在我们的实验环境里技能参数从3个增加到7个时模型正确调用的准确率从88%下降到61%。这很好理解参数越多模型需要理解的东西就越多出错概率越大。所以设计技能时尽量把参数控制在5个以内。实在多的拆成多个技能或合并参数。2.3 描述风格对性能的直接影响同一个人写技能描述写得“啰嗦”和写得“干练”模型表现差距很大。一开始我习惯把描述写得很详细怕模型理解不了结果反而让模型抓不住重点。后来我学会了“结构化分层级”的方式第一层是一句话概括第二层是场景说明第三层是参数详述第四层是约束和边界。模型在选技能时主要依赖第一层和第二层的信息参数详述反而是模型选定技能之后才细看的。这说明技能描述里最核心的那两句话必须直击要害。比如“根据用户描述的城市和日期查询天气信息并返回温度、降雨和风力预报”比“这是一个功能强大的天气查询工具可以获取全球各地的气象数据支持多种语言”有用得多。把最关键的触发场景写在最前面模型选中的概率会大幅提升。顺便提一下技能描述的篇幅控制在200到500字之间比较合适。太短了信息量不够太长了模型在长上下文中容易丢失关键信息。这里没有特别精确的公式但我在项目里靠这两个数字做粗略控制效果还不错。3. 技能库的组织分类怎么分数据才不乱3.1 按领域分还是按场景分技能数量少的时候分类无所谓。超出100个技能之后分类方式直接决定检索效果。我试过两种常见分法领域分法和场景分法。领域分法按业务域划分比如“财务域”“天气域”“行程域”优点是边界清楚但缺点是用户的表达往往跨领域。用户问“明天去上海出差天气怎么样带多少预算合适”这至少横跨天气、行程、财务三个域领域分法对这类请求的检索帮助不大。场景分法则按用户意图划分比如“出行规划”“账单查询”“信息咨询”优点是和用户的表达习惯契合缺点是一个技能可能适用于多个场景同一技能会被重复归类维护成本高。我的最终方案是“场景为主、领域为辅”的混合分类。技能库顶层用场景组织——出行类、消费类、信息获取类、操作执行类。每个场景内部再做领域细分。比如出行类下有天气查询、航班查询、酒店预订、路线规划等子域。这样模型召回技能时可以先用场景缩小范围再按领域精确筛选整体效率高很多。3.2 标签体系与多级索引光有目录结构不够还需要标签体系。我用的是“功能标签上下文标签难度标签”三个维度。功能标签描述“这个技能做什么”例如“天气”“翻译”“计算”“提醒”。上下文标签描述“这个技能适合什么对话状态”例如“需要用户确认后执行”“适合多轮追问”“自主完成不需要用户确认”。难度标签描述“技能实现的复杂度”主要给人看和模型调用关系不大。标签体系做好之后技能检索就不再只是靠描述的文本相似度了。比如用户说“提醒我明天早上九点开会”功能标签命中“提醒”上下文标签命中“需要用户确认后执行”模型就可以先调用确认逻辑而不是直接创建一个闹钟。没有标签体系时模型容易在“设置提醒”和“创建日程”之间犹豫加上标签后命中路径清晰了很多。3.3 技能去重和冲突裁决技能库一膨胀重复和冲突是不可避免的事。一个“查询天气”的技能可能被不同人写成好几个版本表述不同但功能重叠。冲突的情况更麻烦同一个用户指令两个技能都声称自己可以处理好。去重不能全靠人肉看我写了一个简单的相似度检测流程定期用文本嵌入模型给所有技能描述向量化然后做聚类把相似度超过阈值的技能组挑出来人工审核。这个流程不复杂但很有效。印象最深的一次系统提示某两个技能描述相似度达到0.94我一看一个是“获取当前GPS位置”另一个是“根据IP定位获取城市”功能确实重叠合并后召回精读提高了不少。冲突裁决的核心是定义优先级规则。我的规则很简单具体技能优先于通用技能。比如“获取AirPods电量”和“获取蓝牙设备列表”“获取AirPods电量”更具体当用户提到AirPods时优先选它。如果两个技能同样具体保留版本号最新的那个。4. 技能编排的组合逻辑单技能稳定不代表系统稳定4.1 串行编排与并行编排的边界技能数量单拎出来每个都能正常调用但连在一起执行复杂任务时经常出问题。这是技能编排要解决的事。我碰到过的典型情况是用户说“帮我规划周末两天一夜的杭州行程包括景点、住宿和餐饮预算2000以内”。这个任务需要至少四个技能景点推荐、酒店查询、餐厅推荐、预算计算。如果排成串行一步一步来那么每一步的输出都要作为下一步的输入。问题在于景点推荐的输出是一串景点名字和门票价格酒店查询要的是入住日期和区域偏好两者之间的字段对不上模型需要在中间做一次“语义翻译”翻译的过程特别容易出错。并行编排也不是万能的。如果四个技能同时调用最终结果合并时可能出现“景点在城西、酒店在城东、餐厅在城东”这类规划不合理的结果。所以我现在的基本原则是信息型技能可以并行决策型技能尽量串行。信息型技能只是把数据拿回来比如天气、门票价格、酒店房价决策型技能需要综合多个信息源做判断或者需要用户确认偏好的这一类不能并行。4.2 上下文传递别把上一个技能的垃圾倒给下一个技能技能编排里最常见的错误是把上一个技能的完整输出直接塞给下一个技能的输入。比如景点推荐技能返回了一个很长的JSON包括评分、简介、开放时间但下一个技能“酒店查询”只需要“城市”和“区域”两个字段。模型如果没意识到这一点把整个JSON塞进参数里轻则多消耗token重则因为参数不符合约束导致调用失败。我的解决办法是在编排层加一个“上下文裁剪”模块。每一个技能执行完我会记录它的输出里哪些字段是“有效载荷”哪些只是“附属信息”。下一个技能发起调用时只把有效载荷传入。这相当于在人脑里你不会把和同事聊天的完整记录复述给另一个人而是只说对方需要知道的那部分。模型也是一样给它无用的上下文它就可能被带偏。有个实测数据可以参考加上上下文裁剪之后多技能编排任务的端到端成功率从43%提升到72%。提升的主要来源是模型不再被多余的字段干扰调参时也更容易聚焦。4.3 技能的退避与降级策略任何真实系统里技能都会失败。接口超时、参数错误、模型误判都可能导致一个技能调用失败。低级的做法是失败后直接回复“操作失败请稍后再试”高级一点的做法是设计退避策略。退避分两层。第一层是“重试”适用于瞬时故障比如网络抖动。重试不是无脑多试几次要带指数退避第一次等200毫秒、第二次等500毫秒、最多三次。第二层是“降级”适用于技能本身不可用比如天气接口挂了。降级不是放弃任务而是找到替代方案。比如没有天气接口的实时数据就用历史同期的平均气温代替同时告诉用户“我采用了近五年同一天的平均数据仅供参考”。降级策略在设计技能之初就应该想好。每创建一个技能我都会问自己一个问题如果这个技能今天用不了我的智能体能给用户一个什么样的“次优答案”如果答不出来说明这个技能的边界设计有问题——它太依赖单一数据源了。5. 评测体系光靠感觉调技能是不靠谱的5.1 构建评测集覆盖度比数量更重要评测是技能工程里最容易被跳过但最不能跳过的部分。没有评测集你根本不知道某个技能描述是变好了还是变差了。我见过太多团队“凭感觉”改描述改完上线用户反馈变差回滚再改陷入死循环。有了评测集每一次改动都能得到一个可对比的数值。评测集怎么搭数量不是首要的覆盖度才是。一份好的评测集至少要包含四类样本正常触发样本用户意图和技能功能一致模型应该调用这个技能。边缘触发样本用户意图模糊模棱两可但结合上下文判断调用技能是合理的。不应触发样本用户意图和技能功能无关或弱相关模型不应调用。对抗触发样本故意设计成看起来像要触发技能但实际用户是不需要技能的比如“你帮我看看明天的天气顺便推荐一本好看的小说”——这里模型应该只调用天气技能而不是连小说推荐一起调。我用过的一个评测集大概有600条样本其中正常触发240条、边缘触发120条、不应触发180条、对抗触发60条。每轮技能改动跑一遍评测集看触发准确率和分类F1值的变化。这比“感觉好多了”靠谱得多。5.2 三个核心指标触发准确率、完成率、人工修正率评测指标我只看三个。第一个触发准确率也叫调用决策准确率。模型判定“该调用某技能”时它是否真的该调用该调用时有没有漏调用这两个数字放在一起看。漏调用比误调用更隐蔽因为用户问“帮我记一下明天下午三点开会”模型可能说一句“好的已记录”但什么技能都没调用这种失败反馈日志里根本查不到。第二个完成率。技能被调用之后是否成功完成执行并返回预期结果这个指标反映的是技能本身的可靠性不涉及模型的调用决策。完成率低说明技能实现在某些输入条件下有退化需要去修技能代码或补充边界描述。第三个人工修正率。在所有被调用的技能中有多少比例需要人工客服介入修正这个指标衡量的是端到端的真实用户价值。有时候自动调用成功了但结果对用户没用本质上是“有用但不对”。人工修正率高说明智能体的答案虽然表面成功但内在质量不行。三个指标按顺序排查很管用先看触发准确率解决“模型选没选对技能”再看完成率解决“技能本身干没干成”最后看人工修正率解决“结果到底有没有用”。5.3 迭代节奏不要频繁修改技能描述技能描述不是代码它的改动影响是分散的。我吃过一个亏某天因为两个用户反馈“换不了城市”我立刻改了一个技能描述把“支持城市切换”写了进去。结果三天后评测集跑出来整体触发准确率降了6个百分点——原来新版描述让模型在更多场景下误触发了这个技能。从那以后我给自己定了一个规矩技能描述改动至少攒够三个独立反馈或者评测集指标显著下降才动手改。单个用户的反馈可能是偶发问题也可能是模型某个版本本身的行为波动不是技能描述的问题。攒多了再改能减少很多无效迭代。同时每一次改动都要记录版本保留上一版的描述方便随时回滚。6. 维护与沉淀技能库的长期健康不能靠救火6.1 没用的技能要及时下线技能库里的每一个技能长期维护都是有成本的。模型在决策时要在所有技能里做筛选即使有索引和检索机制技能数太多也会拉低准确率。所以我定期做“技能使用率统计”重点看两个指标一定周期内被调用的次数以及调用后人工修正的比例。如果一个技能90天内零调用基本可以判定为废弃技能直接下线。如果一个技能的调用次数很高但人工修正率超过50%说明这个技能一开始就没建好需要重写而非修补。这种“不健康的技能”比“废弃技能”更需要处理因为它还在持续消耗用户好感。我印象很深的一个案例是某团队保留了一个“汇率查询”技能描述写得非常标准参数也规范但业务根本不需要这个功能。模型的触发准确率评测里异常结果有将近三分之一是这个技能带偏的。下线之后整体准确率提升了3个百分点。技能不是越多越好而是越贴合真实用户需求越好。6.2 建立技能变更日志技能变更日志听起来像是个形式主义的东西但真出了问题时它是救命工具。我养成了一个习惯每一次技能定义或描述的改动都记录五件事——变更时间、变更内容、被修改技能的名称和版本、修改原因、评测集指标对比。这个日志解决了一个特别实际的问题当你发现评测指标一周内下降了能很快定位“是不是某次技能描述改动引起的”。没有日志你只能靠猜而猜的代价是可能回滚一个不该回滚的改动或者找不到真正的罪魁祸首。6.3 沉淀可复用的技能模板最后说说沉淀。项目做了大半年我发现好的技能描述之间存在一些共性于是总结了一套“技能描述模板”团队成员写新技能时直接套用避免每次从零开始。通用模板大概长这样master_schema { name: 技能名尽量简短避免歧义, description: 一句话概括说明何时使用、解决什么问题, scenarios: [适用的用户表达示例1, 适用的用户表达示例2], not_for: [不该触发的情况1, 不该触发的情况2], parameters: [...], outputs: [...], failure_handling: [...] }这个模板不是死的实际每个场景会做调整。比如操作执行类技能会对require_confirmation字段做特殊处理信息查询类技能会更强调数据新鲜度和来源说明。模板的价值在于保证同一批技能的风格高度统一。模型对统一风格的信息解析更稳定实测下来不同作者写的技能在模型触发准确率上的方差显著降低了。6.4 一个关于治理的提醒技能库规模超过100之后人就管不过来了。我的做法是给技能库加“所有权”概念——每个技能有一个负责人。负责人不一定要写代码但要负责该技能的评测指标、反馈收集和迭代计划。没有主人、没有任何人维护的技能最后的结局就是上线之后腐烂没有人注意到它的存在直到某一天突然拖垮一次评测成绩。这个习惯救过我一次。某次一个“新闻摘要”技能在无任何通知的情况下被外部接口改版导致返回格式变了模型的解析逻辑全乱了。如果不是我有技能负责人及时接到告警日志这个问题至少要三天后才能被发现。技能库的健康本质上靠的不是某个人的细心而是明确的归属和节奏化的巡检。关于agent-skills我现在最大的体会是技能不是写出来的是测出来的。任何一段描述在没有跑过评测集之前都只是你个人的自信。而技能库的长期稳定靠的不是某一次大改造而是每一次小改动时的克制、记录和验证。如果你正在做智能体建议你先从一件小事开始——挑一个你最有把握的技能把它描述里的负向信息补全跑一遍评测集看看效果。这个动作看起来简单但它是整个技能工程体系的起点。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑