news 2026/10/10 20:56:49

从LLM到Agent Skill:构建可执行智能体的关键路径与工程实践

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
从LLM到Agent Skill:构建可执行智能体的关键路径与工程实践

做过一段时间 LLM 应用的人应该都有同感:单轮对话、知识库问答这类场景,模型本身的表现已经相当能打,但如果想做一个真正“能干活的智能体”——能查数据、能调接口、能自己决定下一步做什么——光靠模型本身的聊天能力是远远不够的。这里面的分水岭,往往就在于有没有把能力“技能化”。我最近把项目从一层套一层的提示词工程,重构成了标准化的 Agent Skill 体系,整个系统的稳定性和扩展性都有了质的变化。这篇内容想把 LLM 到 Agent Skill 这条路上的底层逻辑完整梳理一遍,与其说是教程,不如说是一份踩过坑之后的总结。适合正在折腾智能体应用、函数调用、提示词工程的开发者,也适合想搞清楚“Agent 到底比 Chatbot 强在哪”的产品和技术同学。

1. 先搞清楚:LLM 原生能力和 Agent Skill 之间差了什么

1.1 大模型擅长的是“表达”,不是“执行”

很多初学者会陷入一个误区:既然 LLM 这么强,那我只要把需求描述清楚,它就应该什么都能做。这个想法在 demo 阶段基本成立,但一旦落到真实业务里,马上就露馅。

原因其实不难理解。LLM 本质上是一个基于海量文本训练出来的概率模型,它的强项是基于上下文生成符合语义逻辑的文本。你可以让它写一段营销文案、总结一份报告、甚至模拟一段代码逻辑,这些都属于“表达”的范畴。但如果你让它去查一下某个订单的物流状态、调一个第三方支付的接口、在数据库里跑一条聚合查询,它做不到——因为它没有触达外部世界的通路,也不知道你这个系统里有哪些函数、哪些表、哪些权限规则。

这时候就需要 Agent Skill 出来了。所谓 Skill,本质上是把“模型的表达意图”翻译成“系统可执行的指令”的中间层。它跟普通函数封装的最大区别在于:Skill 的调用方不是人,而是模型本身。也就是说,你要让模型知道“在什么情况下可以调用这个技能、调用时需要提供哪些参数、返回结果应该怎么解读”,并且这个“知道”还必须是通过系统设计赋予的,而不是靠运气。

1.2 Agent、Tool、Skill 三者到底什么关系

很多文章把 Tool 和 Skill 混着用,但从工程落地角度看,这俩是不同层级的东西,搞清楚之后你的系统架构会清晰很多。

我随手画个类比。Tool 就像是工具箱里的一把螺丝刀,它是单一、确定的操作单元,比如“发送 HTTP 请求”“读取本地文件”“执行一段 SQL”。而 Skill 是把螺丝刀、电钻、水平尺组合起来的一套“作业流程”——它可能包含多个 Tool 的调用、前置条件的判断、中间结果的校验、异常情况的重试策略。换句话说,Tool 是原子的,Skill 是编排过的。

Agent 则是拿着这套 Skill 手册去干活的人。它负责理解用户的诉求,拆解成子任务,按顺序去调用不同的 Skill,并把结果整合成最终回复。所以你可以认为:Agent 是大脑和调度器,Skill 是可复用的标准化作业单元,Tool 是最底层的执行部件。这三层各管各的事,职责边界清楚了,后面的调试、扩展、权限管控才做得好。

我自己在项目里的组织方式是这样的:每个 Skill 是一个独立目录,目录里有描述文件、参数 Schema、执行脚本和测试用例。Agent 启动时把这些 Skill 的“说明书”喂给模型,模型按需匹配。这样做的好处是,新增能力不需要改动 Agent 主逻辑,加一个目录就行了。

注意:千万别把 Skill 做成一个大而全的函数,否则模型在意图识别阶段会很容易“看什么都像这个技能”,最后变成所有请求都打到同一个函数上,那 Agent 就退化成了单接口转发器,非常难维护。

2. 一次讲透 Skill 设计的四个核心构成

2.1 触发条件:模型凭什么决定用这个技能

Skill 设计里最容易被忽略、但坑最深的就是触发条件。你需要在描述文档里写清楚:这个 Skill 是干什么的、在什么场景下被激活、什么情况下绝对不要用它。写不清楚的话,模型就会出现两类错误,一类是该用的时候不用,另一类是不该用的时候乱用。

触发条件写得好不好,很大程度取决于你能不能站在模型的“视角”去想问题。模型只能根据你给的描述文本做语义匹配。比如你写“查询天气”,模型可能理解成“任何跟天气有关的对话都触发”,这就过度触发了。但如果你写成“当用户明确提供或暗示一个具体地点,并表达了获取实时天气信息的需求时,可调用此技能;日常闲聊关于天气好不好的话题,不需要调用”,模型的理解就会精准很多。

我还习惯在描述里加一个“优先级说明”字段,用来处理同一意图下有多个 Skill 可选的场景。比如用户说“帮我找一下上个月销售额”,可能涉及“订单查询”“报表生成”“数据透视分析”三个候选。这时候我会在描述里写明各自的适用场景和优先级,让模型优先匹配最精准的那个,而不是随便抓一个。

2.2 参数规范:把自然语言的模糊性格式化

Skill 的输入不能是自然语言,必须是结构化参数。这是跟普通提示词工程最不一样的地方。你在设计 Skill 时,需要给每个参数规定名称、类型、是否必填、取值范围、默认值,甚至还需要写清楚参数之间的依赖关系。

参数规范的价值在于:它把模型的“自由发挥空间”压缩到最小。模型的任务只是做“信息抽取”,把用户话语里的关键信息填到对应的 Slot 里,而不是自由组织一个调用语句。Slot 抽取这件事,模型做得比传统 NLU 好得多,但前提是你的字段定义清楚。

举个例子。我做一个“定时任务”的 Skill,参数里面有一个schedule_type,可选值有once、daily、weekly、custom。光写这些还不够,你还要告诉模型:如果用户说“每天上午十点”对应的是daily,并且要额外抽取出执行时间点time。如果用户只说了频率没说明具体时间,那就视为参数缺失,Skill 应该主动向用户追问,而不是用一个默认值蒙混过去。这个“追问还是不追问”的判断规则,最好也写进描述里,因为模型在参数不全时往往倾向于自己猜一个结果,这是很多线上事故的来源。

2.3 执行逻辑:Skill 内部也是分步骤的

一个 Skill 不等于一个函数调用,它内部往往有多个环节。以我常用的“信息抽取与结构化存储” Skill 为例,它的执行顺序是:先接收原始文本和抽取规则,模型做语义解析,然后把抽取结果跟一套校验规则做比对,不通过就二次修正,最后落库。这几个步骤里,校验和修正属于常规提示词工程里不容易实现的部分——因为提示词是一次性生成的,但 Skill 可以通过代码控制“模型生成→程序校验→不合格再生成”的循环。

这就引出一个关键点:Skill 的执行逻辑里,模型和代码是交替参与的。模型负责需要语义理解的部分,代码负责确定性逻辑的部分,两者各干各擅长的活儿,然后通过统一的输入输出接口衔接。这个设计原则特别重要。你千万不要让模型去干纯计算或者纯格式化的活,也别用代码去硬解析那些需要语义理解的内容,否则整个系统会又慢又脆弱。

我在项目里给每个 Skill 的执行脚本规定了统一的函数签名,比如execute(params: dict, context: dict) -> dict。这样无论内部实现多复杂,对 Agent 来说都是一个黑盒,输入输出稳定,异常也能在统一层捕获。

2.4 描述文档:写给模型看的“说明书”要这么写

Skill 的描述文档是整个体系的灵魂。我见过很多团队把描述写得像内部 API 文档,字段名、路由、示例值一大推,但模型根本不懂你在说什么,因为描述的服务对象不是开发者,而是模型。

写给模型看的描述,我总结下来有几个要点:第一,用完整的短句描述功能,不要用短语清单;第二,明确边界,什么情况不算本技能的范围;第三,给出至少两个典型调用示例,包括用户说的一句话和对应的结构化参数;第四,说明返回结果会怎么被用户感知到,也就是模型读到这个返回值之后该跟用户说什么。

比如我写“查询物流”这个 Skill 的描述时,不会只写“查物流”,而是写:“当用户提供快递单号或电商订单号,并希望了解包裹当前位置、派送状态或预计送达时间时,使用本技能。如果用户只是提到物流过程、快递服务优劣等话题,不需要调用。”后面的示例部分我还会放上几个真实用户话语和对应的参数抽取结果,帮助模型快速建立“用户话术→参数组合”的映射。

3. 从一段提示词到标准 Skill 的实操路径

3.1 第一步:把想法落实成最小可运行版本

我建议你从现有项目里挑一个使用频率最高的提示词场景,把它做成第一个 Skill。别一上来就设计那种几十个参数、跨多个系统的超级技能,那样你大概率会在中途失去耐心。

具体的迁移方法是:先把你现有的提示词内容拆成两层,一层是“任务描述和约束”,另一层是“输入模板”。任务描述保留,作为 Skill 描述文档的底稿;输入模板改成 JSON Schema 的结构化参数。然后写一个最小的执行脚本,接收这些参数,拼接成模型请求,返回结果。整个过程不要超过半天,否则说明你的拆分粒度有问题。

3.2 第二步:接一个真实 API 的完整流程

以我做过的一个“汇率换算查询” Skill 为例,完整走一遍这个流程。

需求很清晰:用户说“100 美元换成人民币多少钱”,模型需要调用一个汇率接口,完成换算,再回复用户。

参数 Schema 我定义为{ amount: float, from_currency: str, to_currency: str }。描述文档里写清楚:金额必须是正数,币种用 ISO 标准三字母代码,如果用户没有明确目标币种,默认转成人民币。

执行脚本里的逻辑是:先用一个内部函数校验参数合法性,然后请求汇率服务,拿到实时汇率后计算金额,最后把结果连同“汇率为 7.24,数据更新于 xx 时间”这样的说明一起返回。模型收到返回值后,用自然语言组织成给用户的答复。

这套流程跑通之后,我建议你加上一层“参数修正逻辑”。比如用户说“1 万美金”,模型抽取出来的amount可能是10000,但也可能是1,因为用户用的是“万”这个单位。这时候脚本里可以判断:如果字段值过小或过大,结合上下文做修正;没有把握时,宁可回复一个澄清问题,也不要输出错得离谱的答案。

3.3 第三步:Skill 的复用和上下文压缩

Skill 一旦建多了,另一个问题就冒出来了:你不能把所有 Skill 的描述都塞进每次请求里,那样上下文爆炸不说,模型反而会因为信息过载而选错技能。这里就得做检索增强式路由。

我的做法是把每个 Skill 的描述文档向量化,用户请求进来时先做一次召回,只把相关的 Top K 技能描述放进上下文。这一步跟 RAG 的底层逻辑是一样的,但检索的对象从知识文档换成了技能描述。实测下来,召回之后的效果非常直观:同样的模型,技能命中率能提高三成以上,响应时间也明显降下来。

上下文压缩在 Skill 内部同样适用。如果你的技能执行过程中依赖了多轮历史信息,别一股脑全传给模型,先把历史里跟当前参数相关的字段抽取出来,拼一个精简版上下文,再送模型。模型对精简上下文的依赖一般不会受影响,因为真正干活的是你传给它的结构化参数,而不是冗长的对话记录。

4. 工具调用的底层机制:模型是怎么“知道”该调哪个函数的

4.1 从文本补全到函数调用的范式转变

理解 Agent Skill 绕不开一件事:模型内部的工具调用机制到底是怎么工作的。很多初接触的人会误以为模型“自己会调用函数”,其实严格来说不是。

以当前主流模型的做法为例,它在训练和微调阶段学会了“在特定情况下生成一段符合特定格式的结构化文本”的能力。开发者把工具列表以特定格式传给模型,模型经过推理,输出一个“我需要调用工具X,参数是Y”的标记序列,而真正执行工具的还是你本地代码。也就是说,模型的“函数调用”本质上是它在生成回复时选择了一个特殊格式的输出,而不是真的在模型内部执行了什么代码。

这个理解很重要,因为它能解释很多现象:为什么工具描述写得不好模型就不调?为什么模型有时候会生成根本不存在的参数?为什么加入一个工具之后整个对话的质量会波动?答案都指向一个核心——工具调用也只是一个文本生成任务,它的质量上限取决于你的“文本提示”质量。

4.2 Schema 设计直接决定工具调用的成败

既然工具调用本质是文本生成,那你的参数 Schema 写得越规整,模型就越不容易“发挥失常”。我自己的经验是,Schema 里要特别注意三件事:枚举值的约束、必填项的标注、参数语义的澄清。

枚举值约束很好理解——告诉模型这个字段只能从这几个值里选,通常用字符串枚举比自由字符串可靠得多。必填项标注也很关键,因为模型在有些场景下会偷懒,少填参数,你得在 Schema 里明确哪些不能省。参数语义澄清是写好描述文字,比如一个字段叫limit很容易跟“限制”混在一起,你要写明它在这里指的是“返回结果的最大条数”,并给一个示例值。

4.3 多轮对话里的 Skill 状态管理

工具调用还有一个隐藏的难点:状态管理。第一次调用返回了一个 token,第二次调用要用这个 token 查状态,第三次调用要基于前两次的结果做汇总。这种链路长、状态多的场景,特别容易出问题。

我的做法是把中间状态写进一个独立的会话状态缓存里,而不是塞回给模型让它记住。模型每次只接收当前这一步所需的必要信息,另外在系统提示里加一行:“如果需要之前步骤的某个数据,可以从状态容器中读取。”状态容器对模型来说是只读的,这能有效避免模型在长时间多轮对话中忘掉关键变量的情况。

日常经验:跨 Skill 的状态共享要格外小心。我建议 Skill 之间只通过最终返回值传递信息,不要搞共享内存式的全局变量。否则两个技能的排查会互相纠缠,定位问题的成本成倍上升。

5. 实战中常见的坑和排查技巧

5.1 模型“幻觉式调用”怎么办

最典型的坑:用户只是随口问一句“你们支持退款吗”,模型直接调用了“发起退款申请”的 Skill,还自己编了个订单号填了进去。这就是幻觉式调用——条件不满足时触发了技能,参数是编造的。

遇到这种问题,我的排查思路是先看触发条件写没写清楚,再检查参数 Schema 有没有给足约束。如果两者都没问题,那就是描述文档本身有歧义,需要用“负面示例”去兜底。比如在描述里明确写:“除非用户表达的意图是立即执行退款操作,否则不要调用本技能;仅询问退款政策时,应直接根据已有知识回答。”这个负面示例比加十条正面描述都管用。

5.2 上下文膨胀导致选择漂移

技能多了以后,模型常常出现上下文越长越“飘”的现象,明明用户说的意思很明确,它却跳到了一个完全不相关的技能上。原因通常是系统提示里塞了太多冗余信息,模型丢失了焦点。

我的一个经验是:把系统提示拆成“固定的核心提示”和“动态的技能路由提示”两部分。核心提示负责设定模型的角色、输出风格、安全边界,这部分尽量短。动态部分只放当前会话实际需要的技能描述和示例,并按照上一个交互的意图排序,让最新最相关的信息靠前。这样做之后,技能选择漂移的发生率明显下降。

5.3 技能冲突和优先级设计

技能多了,难免出现两个 Skill 的能力边界有重叠。比如一个是“查快递”,一个是“通用查询”,两个都能处理“我的东西到哪了”。模型会随机选一个,用户体验就会不稳定。

处理冲突的办法是在每个 Skill 描述里加一个conflict_resolution段,专门说明自己在什么场景下优先于哪些技能。同时,在路由层维护一个手工编排的优先级表。这个表不复杂,本质上是一个 map,key 是意图标签,value 是技能 ID 列表,按优先级排列。日常维护成本很低,但对稳定性帮助极大。

5.4 可观测性:给每个 Skill 装一台“行车记录仪”

Skill 系统最怕的是黑盒。用户反馈说系统答得不对,你连模型调了哪个技能、传了什么参数、返回了什么结果都看不到,那就只能瞎猜了。

所以我强烈建议,从第一天就给所有 Skill 接入统一的日志回放体系。每次调用记录五样东西:输入的原始话术、召回命中的技能列表、模型最终选中的技能、解析出来的完整参数、执行结果得分。这套日志平时不觉得有什么,一到排查问题的时候,简直是救命稻草。

如果你有预算,还可以把这些日志丢回到一个大模型里做离线分析,让它找出“哪些用户话术经常匹配到错误技能”“哪些参数的默认值设置不合理”等模式,然后针对性优化。这是能力提升的正循环。

6. 一些经验与体会

好几个项目做下来,我的一个很深的感觉是:LLM 应用开发里,模型的选型只是起点,真正见功夫的地方是把模型接入业务的那一层设计。Agent Skill 的魅力在于,它把不可控的模型行为,一点点约束成了可控的、可测试的、可演进的功能单元。你不需要把模型训练得多聪明,只需要给它一套清晰的规则和好用的工具,它就能在你设定的边界内做得很漂亮。

最后分享一个小技巧:Skill 描述文档的迭代千万别靠“感觉”,每条改动都应该留一个 A/B 测试记录。我习惯把每个版本的描述文档连同它对应的 30 组典型测试用例存在一起,每次改动都跑一遍全集,确保修复了一个问题没有引出两个新问题。这套笨办法帮我避开了太多回归问题,值得每个人试试。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/10 20:56:43

NTP时间同步原理与高可用部署实战

1. 什么是NTP时间同步服务?它为什么不是“配个时区就完事”的小事你有没有遇到过这样的情况:服务器日志里同一笔交易的时间戳,前端显示是09:58:23,后端记录却是09:58:17,数据库审计表里又跳成了09:58:25?三…

作者头像 李华
网站建设 2026/10/10 20:54:31

品牌宣传素材网站哪个靠谱?商用正版素材平台推荐

在品牌宣传与内容创作日益高频的今天,选择素材平台已不仅仅是“找张好看的图”那么简单。对于自媒体创作者、电商运营、设计师及企业市场团队而言,版权合规是商业使用的安全底线。一张来源不明的图片、一段未获授权的背景音乐,都可能让精心策…

作者头像 李华
网站建设 2026/10/10 20:52:37

keepalived+LVS高可用负载均衡实战:从原理配置到故障切换

刚接手这套系统的时候,我其实对keepalivedLVS是有点抵触的——毕竟公司里不少人在推云负载均衡,谁还愿意自己搭一套四层转发呢。直到有一次半夜接到电话:后端两台Web服务器一张网卡傻掉,前面那台单点Nginx直接把所有流量拒之门外&…

作者头像 李华
网站建设 2026/10/10 20:45:50

Agent平台超时故障剖析:从同步编排到异步化改造实践

1. 项目背景:Agent Platform 到底在做什么1.1 这个平台解决的核心问题先说背景。我接手的是一个面向企业客户的 Agent Platform,简单来说,就是把多个大模型 Agent 编排起来,对外提供统一的对话与任务执行接口。业务方通过这个平台…

作者头像 李华
网站建设 2026/10/10 20:42:22

PHP微信支付v3完整实现:签名验签、证书管理与回调解密

简介:本资源是面向PHP后端开发者与微信支付接入初学者的V3版完整实践方案,聚焦最新微信支付接口集成中的证书管理、API签名、统一下单、异步回调及沙箱测试等核心环节,解决生产环境中常见的配置混乱、签名失败、通知验签异常等痛点。压缩包共…

作者头像 李华
网站建设 2026/10/10 20:41:39

Ceph运维实战:从核心指标到故障排查与自动化落地

接手过Ceph的人都有一个共识:这系统不是装完就完事的,真正的活儿全在运维。我在生产环境里折腾Ceph也有几年了,从最初的三节点小集群一路扩到几百个OSD,期间经历过PG卡在activeremapped的焦虑,也见过一块慢盘拖得整个集…

作者头像 李华