ARTICLE DETAIL

资讯详情

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

从Function Calling到Agent Skills:大模型工具调用的设计范式与工程实践

从Function Calling到Agent Skills:大模型工具调用的设计范式与工程实践 1. 从Function Calling到Agent Skills为什么我突然开始重新思考Agent的工具设计1.1 大多数人切入Agent开发时的第一反应做AI Agent开发的同行应该都有一个共同的经历第一次把大模型接上外部工具时第一反应就是“这不就是Function Calling吗”。定义一个JSON Schema声明几个参数模型就会在合适的时机把调用意图和参数返回给我然后我执行函数、把结果塞回对话上下文一个Agent工具链路就通了。早期我也是这么干的也确实能跑通一些简单场景比如查询天气、算个加减法、拉个订单状态。但跑着跑着就发现不对劲。等到技能数量超过五六个、场景从演示变成生产整个系统的脆弱程度简直让人头皮发麻。参数传错、模型拿不到关键信息、返回结构不匹配、上下文被日志撑爆、多轮对话里技能状态错乱……这些问题不是偶发而是结构性必现。也就是从这个时候起我开始认真研究“Agent Skills”这个概念——它不是Function Calling换个名字而是一整套关于“如何让大模型可靠地使用能力”的设计范式。1.2 我理解的Agent Skills到底是什么如果非要用一句话定义我会说Agent Skills是一套“以模型认知习惯为中心”的能力封装方案它把完成某类任务的完整知识、操作步骤、输入输出规范和边界条件打包成一个独立、可复用、可被模型自主调用的模块。这个定义里最关键的是“以模型认知习惯为中心”这半句。传统软件开发是给人用的接口设计只要人能看懂就行但Agent Skills是给模型用的接口设计必须符合大模型对任务的理解方式。你定义一个严格结构化的入参对象模型反而容易搞错你给它一段自然语言描述加上示例它反而处理得非常好。这套方案的提出背景本质上是把设计视角从“开发者好写”切换到“模型好用”。这里我拿真实场景做个对比你会发现差别非常明显维度Function Calling思路Agent Skills思路接口形态JSON Schema强制结构自然语言描述为主结构为辅工具定位单点函数越原子越好完整技能包可以做多步推理调用决策模型根据函数名和描述选择模型根据技能的目标、流程、样例综合判断失败处理靠外部代码兜底技能内部自带各种边界条件说明扩展方式加函数、改Schema加技能包、升级技能版本1.3 为什么现在这个时间点特别适合重看Agent Skills大模型本身的推理能力在过去一年提升很快但工具调用的可靠性其实提升得没那么明显。这不是模型不行而是端到端的Agent任务里工具设计往往成为瓶颈。模型明明有能力做三步推理但是你的工具只支持一步调用那就只能靠外部代码来编排外部编排越多系统就越脆一旦场景变化就要改代码。Agent Skills刚好补上了这一环。它把“属于模型应该做的事情”交还给模型同时用结构化的技能描述让模型在调用时更自信、更准确。加上像Anthropic发布Agent Skills规范这类行业动作整个生态正在从“再造一个Function Calling”走向“形成一套可共享、可复用的技能资产体系”。这个趋势本质上和前端从“写页面”到“组件化”再到“组件市场”的发展路径非常像。2. 我踩过的最深的坑Function Calling的方式构建Agent越做越脆2.1 第一个坑参数地狱与必填项的魔咒Function Calling体系中最大的噩梦就是参数设计。你为了一个“查订单”的功能可能会定义order_id、customer_name、date_range、status、page_size、sort_by……十几个字段然后一大半都是可选的。可选的还好最怕的是必填项太多。模型拿着用户一句模糊的“帮我看下上周的订单”面对五个必填参数它不是去追问而是会根据自己的猜测给你填一堆五七八八的值进来。我实际遇到过一次用户说“查一下老客户的复购情况”模型给customer_name填了“老客户”给date_range填了“2024-01-01到2024-12-31”。字段类型没错语义完全跑偏最后查出来的结果当然也是无意义的。这个问题本质上不是模型的错而是我们把一个“开放式理解任务”强行塞进了“封闭式参数结构”里系统自然要出问题。2.2 第二个坑链式调用时中间状态的丢失做稍微复杂一点的Agent任务往往需要多个工具按顺序配合。比如“给客户写一封促销邮件然后发给近30天有购买记录的用户”这需要先调用户筛选工具、再调邮件模板工具、再调发送工具。如果用Function Calling方式实现每一步的结果都得想办法传给下一步模型的上下文窗口里堆满了中间数据。藏得最深的坑在这里一旦某一步返回的数据结构比较大比如几千个用户的列表模型在下一步决策时根本读不完这些数据注意力会被无关字段稀释掉。经常出现的情况是模型明明拿了用户列表写邮件时却忘了用户群体是谁逻辑完全断掉。而Agent Skills的方式把整套流程封装成一个技能模型的注意力只需要放在“最终目标”上中间的数据流转由技能内部自己消化问题就从根源上消失了。2.3 第三个坑技能越多选择越混乱函数数量在30个以内时模型的选择准确率还算能接受。但一旦超过50个情况就急剧恶化。模型开始混淆相似功能之间的边界比如“发送通知”和“发送营销邮件”在描述中长得差不多它就经常选错。你在提示词里怎么强调都不管用因为这不是提示词质量问题而是信息架构问题。我后来反思Function Calling的设计思路是“把尽可能多的能力暴露给模型”这条路对模型的工作记忆是极不友好的。Agent Skills的思路则是“把相关能力聚合成块”模型面对的不是50个函数而是七八个技能每个技能内部再去决定具体怎么执行。选择维度从50个掉到8个模型的准确率自然就上来了。3. 重新设计一个Agent Skill从目标拆解到完整落地3.1 核心原则先定义边界再写实现一个合格的技能不是写完功能就算完。它需要包含六个组成部分缺一个到生产环境都会出问题。我把这六部分列成一个检查清单每次新写技能都会逐项过一遍组成部分关键内容缺了会怎样技能目标这个技能要达成的最终效果模型不知道什么时候该用它运行条件什么情况下允许执行、什么情况下应该拒绝模型在不符合条件时也乱调输入输出规范需要哪些信息返回什么格式链式调用时数据对接不上操作步骤内部执行流程支持多步推理只能做一把梭式的单步操作知识库领域专业知识、规则、话术输出结果停留在表面边界与异常失败场景、超时处理、兜底策略出问题时整个会话直接卡死边界这一项尤其重要。很多开发者觉得“先跑通核心流程就行”边界条件后面再补。但模型的调用决策高度依赖边界描述如果没有明确写“哪些情况下不能用”模型就会把它用在所有看起来沾边的地方出了错还不自知。3.2 自然语言优先的输入输出设计设计技能时要尽量让输入输出贴近自然语言减少结构化参数的依赖。一个反直觉但非常有效的方法是让模型用自己的话描述目标而不是填充一个对象。举个例子假设我们要做一个“销售日报生成”技能。Function Calling思路下可能会定义{ type: object, properties: { report_date: { type: string, description: 报表日期 }, metrics: { type: array, items: { type: string } }, include_charts: { type: boolean } } }Agent Skills思路下会改成技能接收一段自然语言任务描述比如“生成昨天的销售日报包括收入、订单量和退款率最好附带趋势对比”然后技能内部用另一个模型调用或规则引擎去解析这个描述拆出关键要执行的动作。这样做的好处非常明显用户和模型都只需要表达意图而不需要学习接口。很多非技术用户说出来的话根本不可能贴合JSON字段与其让模型做一次“人话翻译成严格结构”的任务不如让整个调用过程都保持自然语言的一致性。3.3 Skill内部的状态管理与自包含设计优秀的技能必须做到自包含。所谓自包含就是技能的整个生命周期——从输入到执行到返回——都由技能自身管理不依赖外部系统的临时状态。这意味着技能内部要有自己的状态表达方式、任务队列和存储路径。比如做“周期性数据分析”技能它不是简单调一个查询接口而是自己在内部维护“本次分析的输入快照”“执行过程中的中间结果”“最终产出的汇总报告”三个阶段。这样即使主对话经历了多轮交互技能的状态也是完整的。我在工程实践中发现把技能状态从对话上下文中剥离出去是整个Agent系统从“demo”走向“可用”的关键一步这也是Agent Skills框架和Function Calling最底层的区别之一。4. 一个真实可跑的技能实现自定义一个“订单归因分析”Skill4.1 技能的目标与输入输出定义光讲理论太空我直接拿一个线上在跑的例子拆给大家看。我做过一个“订单归因分析”技能它的核心任务是根据用户的一个粗略诉求自动圈定订单范围、分析数据、找出规律并生成结论。假定场景是运营人员在后台对话里问“端午节促销期的订单哪类商品贡献最大”传统方式需要他手写SQL、联表、算占比、再写PPT现在他只需要把这个需求作为一条消息发给Agent就行。技能的输入只有一条自然语言诉求输出也不是一个JSON对象而是一段结构化分析报告包含数据范围、分析方法、核心结论和原始数据明细四个部分。这里的设计思路是输出要既适合人看也适合后续链路继续消费。模型拿这段报告再做下一步决策就不会缺上下文。4.2 技能内的核心执行逻辑这个技能内部其实跑了一条4步流水线但对外就像黑盒一样干净透明第一步意图解析模型基于用户的自然语言诉求提取时间范围、维度字段、指标字段。比如“端午节促销期”会被解析成一个具体日期区间“哪类商品”会被映射到商品类目维度。第二步数据探查技能自动调用数据仓库的元数据接口看看目标表和字段是否存在、是否有数据、是否有重名歧义。这一步是防止后端出错的第一道防线。第三步查询生成与执行根据前两步信息生成查询语句执行后拿到结果集同时记录执行日志和质量指标比如数据量大小、查询耗时。第四步结果归纳把数据结果交给大模型进行归因分析生成一段人话结论然后再拼装成最终报告返回。这四步全部封装在一个技能里不依赖外部编排脚本。模型端调用和代码端调用这个技能时面对的是同一个接口只是入口有所不同。4.3 技能描述文件让模型知道“什么时候用我”如果说技能实现是引擎那技能描述文件就是方向盘。模型判断“要不要用这个技能”“怎么用”全部依赖描述文件的内容质量。我用的技能描述模板一般包含这几个字段name技能的唯一标识description讲清楚这个技能用来解决什么问题不要含糊instructions被模型作为系统提示词注入的具体说明写清楚什么时候允许调用、什么时候应该拒绝input_schema尽量宽松的自然语言字段描述examples2到3个典型调用示例包含用户提问和技能正常执行后的效果描述文件里最容易翻车的是一句话概括。比如“用于订单分析”这种写法模型会把所有和订单沾边的需求都路由过来最后技能被高频错误使用。好的描述应该是这个技能用于“回答任何与订单数据归因、趋势、构成相关的问题”。当用户想了解某个时间段的销售表现、哪个商品卖得好、哪些用户贡献大或者需要解释数据变化的原因时应该使用本技能。但如果是同步订单状态这种单行查询应该调用订单详情技能而不是本技能。这种写法直接把技能的适用范围、典型时机和排除场景都说清楚了模型做路由决策时就有据可依而不是瞎猜。5. 技能跑通之后的事关于可靠性、并发与迭代我不太想回避的一些现实问题5.1 模型的指令遵循比你想的更“看心情”即便你把技能描述写得很完善模型依然有概率不按你规定的路径走。我统计过线上数据单次技能调用时模型“跑偏”的概率大约在3%到8%之间具体高低取决于任务复杂度。在To B场景下这个概率是不能接受的。我目前的应对策略不是去微调模型而是做一层“技能执行护栏”就是在技能内部对模型生成的每一步做一次规则校验。比如归因分析技能里有一个子步骤是“判断查询条件有没有包含时间范围”如果模型漏掉了规则层会拦截并自动补上。形象地说就是把模型的每一次执行当成“一个聪明的实习生”而规则层是“审核文档的老员工”模型可以提方案但最终执行必须过一遍审核。5.2 技能并发与资源隔离容易被忽视但会炸技能和函数不同它不是一毫秒就能返回的。一个数据分析技能通常要跑几百毫秒到几秒期间如果请求量上来资源会发生明显竞争。多个技能同时跑的时候如果都去查同一个数据源数据库连接池直接被打满接口报错率直线上升。做技能化改造之后我引入了一个比较简单的并发控制方案每个技能在注册时可以声明自己的资源等级和预期的最大并发数系统根据这些数据做排队。比如简单技能最多同时运行20个重技能最多同时运行3个超过的请求先进入队列。实测下来系统的稳定性改善非常明显可用性从最开始99.3%提升到99.8%别小看这0.5%对To B业务的体验影响非常大。5.3 技能版本迭代时如何不打断线上业务流程技能只要是代码就会面临迭代。Agent Skills的独特之处在于它不像普通API那样有明确的版本管理方案。你更新了一个技能描述模型在上下文里看到的还是旧描述因为你没有做好版本对齐。我的做法是给每个技能加metadata记录版本号、发布时间和变更说明并在每次新会话初始化的时候让Agent主动拉取全量技能的最新描述。长期存活的会话则要做“技能热更新”的兜底即判断当前会话中的技能版本与新版本是否兼容不兼容的会话要做标记并提示用户开启新会话避免旧会话一直拿旧技能干活。6. 从单个技能到技能系统后续演进时最值得投入的方向6.1 先建立企业级技能库而不是继续堆技能技能数量上来之后你一定会遇到复用、检索和治理的问题。不能靠每个团队各自维护自己的技能逻辑那样同一种能力会被重复开发实现还不一样模型无法做统一决策。我觉得比较值得投入的方向是建一套中心化技能仓库内部包含三样东西标准技能声明、示例库、质量评估记录。任何一个技能上线前都要过一遍“三个人”的评审——负责实现的工程师、负责模型效果的算法同学、负责业务效果的产品经理。签名通过之后编入仓库可被全公司的Agent统一检索和引用。6.2 从“单技能调用”迈向“技能编排”当前大多数Agent系统还是单技能调用为主也就是一次对话模型决定调用哪一个技能。但当业务复杂到一定程度你会发现很多真实任务天然是多个技能协作的比如“看完这份报表然后把异常项提供给风险组跟进”这就同时涉及数据分析、文本理解和消息触达三类技能。下一阶段的Agent Skills重点一定是在技能编排上。好比是给技能之间加了一种“会话式接口”不仅输出结果给用户看还要输出它的结论和下一步建议让下一个技能可以根据建议决定自己要不要参与、怎么参与。这个思路目前还在演进中但我认为它代表了Agent从“工具人”走向“协作者”的核心跳板。6.3 把评估体系前置别等上线了再补技能越做越多之后回退成了最难受的事你优化了A技能的描述结果B技能在路由选择上变差了。没有评估体系你根本不知道是哪次调整引入了问题。我现在的做法是搭一个“回归集”每个技能底下挂了30到50条典型历史请求和对应期望结果每修改一次技能就跑一遍全量回归。跑过之后看三个指标技能路由准确率、执行成功率、结果可用率。这三个指标稳定或提升改动才允许合入。这一点经验是从后端测试工程里借来的但实际效果非常好大大减少了我半夜被线上用户的尴尬时刻。最后再分享一个我个人感触最深的体会Agent Skills的真正价值不是让你把现有工具的调用变简单而是逼着你重新思考“模型适合做什么、系统该扛什么”。Function Calling时代我们习惯了把所有逻辑往外部代码堆结果系统越做越重、越做越脆Agent Skills的思路则是让模型在前面冲锋系统在后面兜底。我手上这套以技能为中心的Agent架构已经跑了近半年线上承担了订单归因、客户分级、营销复盘等十多个真实业务场景整体稳定性和可维护性比原先Function Calling方案提升了一个量级。后续我还会继续往技能编排和质量评估两个方向深挖尤其是多个技能协作时的上下文传递等有了更成熟的实践再回来和大家分享。
返回列表