☰
Agent技能化实战:从散装工具到可复用技能库的完整指南
2026/10/8 4:55:48 网站建设 项目流程

最近好几个做 Agent 应用的朋友都在问同一个问题:工具也接了,流程也搭了,为什么 Agent 用起来还是像一堆散装函数?我猜他们真正缺的不是更多 API,而是一套 agent-skills 的思路——把能力封装成可被模型按需调用的标准技能单元。这篇就聊聊为什么技能化能解决问题、技能到底怎么定义、技能库怎么分层、落地时有哪些细节,最后把我踩过的坑也一并交代。适合正在做 Agent 原型的开发者、想给团队沉淀 AI 能力的架构师,也适合对 Prompt 工程和工具调用机制好奇的爱好者。先说结论:如果你把 Agent 当成一个不断变强的实习生,技能就是它的岗位说明书;说明书不清晰,实习生的能力再强也容易把事情搞砸。

1. 先搞清 agent-skills 解决的是哪一类问题

1.1 一个失控的 Agent 调用现场

先还原一个真实场景。项目里有个语音助手,最初只挂了三个工具:查天气、设提醒、开灯。前两周挺正常,后面需求多了,加了查交通、订咖啡、播音乐、找文件、看股票等等,工具从 3 个变成 40 个。问题开始出现:用户说“明天早上九点提醒我带合同”时,模型一会儿调提醒工具,一会儿调日程工具;用户说“帮我找个文档”时,模型会连着把搜索、打开、分享三个动作一起做了,尽管我们只希望它先搜索再确认。调试的时候要同时看几百行工具定义,改一个返回值还可能影响另一个工具的语义。这不是模型变笨了,而是我们的能力组织方式跟不上:一堆平铺的函数定义,没有边界、没有层次、没有“什么时候该用”的说明书。

当时我做的事很简单:把所有工具按职责重新分组,给每组写清楚适用场景和触发条件,然后让模型先经过一个“路由层”再决定交给谁。效果立刻不一样,误调用少了,响应也稳了。这个实践后来慢慢长成了我理解中的 agent-skills:不是把 Agent 能力做成一个巨大的工具列表,而是做成一套可以独立定义、独立测试、按需加载的技能集合。

1.2 技能、工具、插件到底差在哪

很多团队分不清三者的边界,我用自己的话定义一下。

  • 工具:最底层的能力原子,负责一个确定的操作,比如“查询天气 API”“写入数据库”。它不关心怎么被调用,只关心入参出参是否符合约定。
  • 插件:围绕某个外部系统的一组工具集合,比如 IM 系统插件包含发送消息、建群、拉人。它解决的是“某个系统的接入问题”。
  • 技能:面向任务的能力封装,强调“什么场景下选我”以及“选了我之后完成什么目标”。一个技能可以只用一个工具,也可以编排多个工具甚至外部流程。

用生活类比:工具是厨房里的锅碗瓢盆,插件是整套厨具的包装箱,技能则是一道菜的完整做法——不仅包括用哪口锅,还包括什么时候开火、什么时候关火、成品长什么样才算合格。Agent 如果只会盲选厨具,做出来的菜大概率是黑暗料理;如果你给它菜谱,它才可能稳定复现。

维度函数/工具插件Agent Skill
关注点单个动作系统集成任务完成
粒度细中粗
模型需要理解什么参数接口和权限触发条件、目标、边界
可测试性容易中等需要完整场景测试
复用范围代码级系统级跨项目跨场景

这个差别解释了为什么很多 Agent 项目工具数量一多就失控:模型需要从几十个平铺的接口里猜“现在应该做什么”,而不是在一个明确的任务空间里做选择。agent-skills 的核心,就是把“猜”改成“查说明书”。技能描述做得越好,模型选择越稳定。这也是为什么我会反复和团队强调:写技能描述不是在写注释,而是在给模型做决策支持。

2. 给技能下定义:一次完整的 Skill 拆解过程

2.1 技能的最小单元:能力描述、参数契约、执行体

要落地一套技能,我最常用的拆分方式是三个部分:能力描述、参数契约、执行体。这三者缺一个,技能在真实场景里就会出问题。

能力描述是模型决定“要不要选我”的依据,也是技能里最容易被低估的部分。参数契约是技能与其他代码交互的边界,必须能校验、能报错、能兜底。执行体则是实际跑的逻辑,可以是脚本、函数、API 调用,甚至一个短暂的人工确认流程。不要把所有逻辑塞进描述里,也不要指望模型理解执行体的内部实现,它只需要知道三件事:我什么时候该用你,我需要准备哪些信息,你做完会给我什么。

以我自己项目里的“会议纪要生成”技能为例。能力描述只有两行:“当用户提供会议录音或文字稿,希望生成结构化纪要时使用。不适用于实时转写。”参数契约包含 source_type、content、meeting_title 这三个字段,其中 source_type 只能是 audio/transcript/text。执行体是一个 Python 脚本,负责转写、分段、抽取结论。这样模型做决策时负担很小,执行体也能独立测试。

2.2 描述不是写给人看的,是写给模型决策的

这是 agent-skills 设计里最关键的一条心得。很多人写技能描述像写 README,会写“这个模块负责会议纪要的生成,支持音频转文字、文本摘要、结构化输出,内置了基于大模型的抽取逻辑”。模型看完知道这个技能存在,但不知道什么时候调用最合适,也不知道哪些情况不该用它。

我建议把描述拆成三个独立块:

  • What:这个技能完成什么任务,用一句动词短语说清楚。
  • When:什么场景下必须用我,什么场景下千万别用我。
  • Output:我给回什么结构,是否保证成功,失败时怎么办。

When 这块尤其重要。明确写“不适用于……”能显著降低误调用率。比如“日程管理”技能里写“不要用于纯提醒场景,提醒请走 reminder 技能”,模型在“明天九点提醒我带合同”这种句子上就不会纠结。真实项目里我统计过,加上负向声明之后,误调用率能降一到两成。这是个很值得先做的低成本优化。

2.3 一个可以照抄的 Skill 定义骨架

下面是我目前在用的一个简化模板,字段可以根据场景增删,但这个结构本身很稳:

skill: schedule_event description: > 当用户希望创建日程、修改日程或查询日程安排时使用。 不要用于创建提醒事项;提醒请使用 reminder 技能。 如果没有明确的时间,必须先询问再创建。 params: - name: title type: string required: true description: 日程标题 - name: start_time type: string required: true description: 开始时间,ISO 8601,例如 2025-06-01T09:00:00 - name: end_time type: string required: false description: 结束时间,ISO 8601;缺省时按一小时计算 - name: attendees type: array required: false description: 参与人邮箱列表 output: type: object fields: [event_id, title, start_time, end_time, status] on_error: 返回 error_code 与可读提示,不假装成功

注意模板里我故意不写实现细节。执行体是 Python 脚本、云函数还是一个标准 API 请求,都无所谓。技能层只关心接口契约,执行层只关心实现,这两个关注点分开之后,技能库才能规模化。

3. 技能库的分层设计:原子、组合与路由

3.1 原子技能:一个动作只做一件事

规模上来以后,光有“会议纪要”这种任务级技能还不够,它内部可能还要拆成转写音频、会议分段、抽取结论、写草稿这四个动作。我会先把每次只做一件事的动作沉淀成原子技能:明文规定输入输出,没有复杂的业务分支,模型或上层代码随时可以调用。

原子技能的测试成本最低,往往用一个单元测试就能覆盖。比如“转写音频”技能,输入是音频路径,输出是带时间戳的文本,没有其他副作用。这种技能可以在所有高层技能里被任何组合复用,也是整个技能库稳定性的底座。我见过一些团队跳过了这一层,直接写大而全的技能,结果技能与技能之间互相调用时参数还要做各种适配,那已经不是技能系统,而是另一个意大利面条项目。

3.2 组合技能:把原子技能编排成工作流

组合技能负责把多个原子技能串起来,体现业务闭环。“会议纪要生成”可以定义为:转写音频 -> 分段 -> 抽取行动项 -> 写入指定文档。组合技能里的每一步都可能失败,所以要定义清楚中止条件:是继续还是报错,是跳过还是重试。模型通常不需要感知组合内部的每一步,它只需要知道调用组合技能能够拿到什么结果;组合技能在内部可以自己判断状态机。

实际项目中,我一般会用状态流转对象来管理组合技能的执行。比如“生成纪要”状态从 pending、transcribing、segmenting、finalizing 到 done,任何一步失败都记录到上下文字段里,方便模型向用户解释“卡在哪个环节”。有了这层编排,上层 Agent 就不需要具备复杂的工作流管理能力,技能自己就能把任务吃掉。

3.3 路由技能:让模型学会找谁干活

当技能库超过十几二十个时,模型在每一步都做全局选择会越来越犹豫。我的做法是加一个路由技能,它的能力描述不是某个具体任务,而是“判断用户意图并把请求交给合适的技能”。

路由技能的输入是用户当前的意图和上下文,输出是一个 skill_name 和置信度。它不需要执行具体业务,只做分发。比如用户的“帮我参加会议并记录结论”,路由会先匹配到“会议参与”技能和“会议纪要”技能,再根据场景顺序编排。有一个好的路由技能,后面新增技能时,只需要在路由描述里加一行匹配规则,全局的稳定性不会被破坏。

路由技能听起来像一个“分发器”,确实如此。它和前端的网关很像:不做业务,只做寻址。但这层存在让整个技能库形成了清晰的层次:路由在最上层,组合在中间,原子在最底部。模型需要做的决策空间被压缩得很小,因此准确率也更容易提升。

3.4 目录与命名规范

技能多了以后,命名和目录会成为第一个影响开发效率的地方。我当前使用的结构是:

skills/ schedule_event/ SKILL.md handler.py tests/ meeting_notes/ SKILL.md handler.py actions/ transcribe_audio/ segment_text/ tests/ router/ SKILL.md handler.py tests/

命名统一用动词开头的 snake_case,表示“做什么事”。目录名就是技能名,SKILL.md 是模型可读的描述,handler.py 是执行入口。子技能放在 actions 子目录里,表示它们是内部编排的一部分,不直接对外暴露。这个约定不一定适合所有团队,但它是我们踩了很多坑之后沉淀下来的,至少能保证一个新同学接手技能库时不用猜。

4. 落地细节:两个高频技能的实现思路

4.1 日程管理:时间解析与冲突校验是最大的坑

日程管理是几乎所有 Agent 都会接的技能,但也是最容易做得想摔键盘的技能。原因是自然语言里的时间表达太灵活,“下周一上午”“明天晚上八点”“周四之前”都可能是日程时间。如果直接把字符串丢给日历 API,一定会在真实用户场景里炸。

我的做法是在技能内部做两层解析。第一层是时间表达式识别,用本地化的时间解析库把“下周一上午”转成候选时间窗口;第二层是候选时间校验,和现有日程做冲突检查,并把冲突结果并入返回值。如果模型在参数里没有给出完整时间,技能要先返回一个“需要信息”的错误码,让 Agent 去追问用户,绝对不要在时间缺失时猜测。有一个我反复强调的细节:技能返回给模型的信息里,不仅要包含“创建成功”,还要包含“在哪一天、几点到几点”。因为 Agent 后续很可能要跟用户复述确认,你没有完整的回显,它就只能编。

日程技能的参数契约里,我会把 start_time 和 end_time 都设计成字符串而不是时间戳,因为模型更容易输出 ISO 字符串,解析成功后再在代码里转成时间戳。这里不要做“模型会自己处理格式”的假设,接收端要宽容,发送端要明确,宁可多写一行校验也不要相信输入。

4.2 信息检索:搜索、提取、引用三段式

信息检索是另一个高频需求。常见错误是只做一个“搜索并返回结果”的技能,让模型去阅读所有链接。这在 token 消耗、延迟、可信度上都是灾难。我把检索类能力拆成三段独立技能:search_web 只拿到候选标题和链接;extract_content 拿到具体网页正文并去重;cite_sources 把最终答案中的每句话对应到证据链接。

search_web 的输出是一个列表,每条包含 title、url、snippet 和 content_hash。extract_content 接收一个 url,输出净化后的文本、标题和抓取时间。cite_sources 接收答案文本和证据列表,输出带引用的 Markdown。模型在使用这三个技能时,逻辑变得非常透明:先搜,再读,最后引用。任何一步失败都可以定位到具体技能,而不是“搜索功能坏了”这种模糊状态。

这个三段式设计还有一个额外收益:它可以单独做缓存。url 和 content_hash 不变时,extract_content 的结果可以直接复用,减少重复抓取。我在项目里用这个方式把重复查询的成本降了一半。如果你只是把“搜索”写成一个全能技能,这些优化基本无从下手。

4.3 返回值里要带“证据感”

4.1 里提到回显,4.2 里提到引用,这两者背后其实是同一个原则:技能返回给模型的数据要带有“证据感”,让模型知道结果是从哪来的。原因很简单,模型在开放式对话里很容易自信地补全缺失信息,而如果它的每一步都基于技能返回的明确字段,幻觉率会低很多。

具体来说,任何技能的输出都应该包含一个不太占 token 但足够说明来源的字段:创建时间、来源 URL、记录 ID、执行状态等。这样即使 Agent 后面做了自由发挥,至少核心事实是被约束住的。这一点越早设计越好,等技能上线后再补输出字段,代价会是想象不到的大,因为所有调用场景都要回归。

5. 技能不是写完就完:评估、回归与灰度

5.1 埋点:记录每一次技能被选择和不被选择

技能上线之后,测试不是跑一遍 handshake 就结束了。真正能让技能越用越稳的是埋点。我会在每个技能的入口和出口打三类日志:模型是否选择了这个技能、技能执行是否成功、执行结果是否被后续对话使用。模型“选择了但最后没用上”往往比“没选择”更值得关注,它说明描述可能过度承诺了能力。

另外还要记录“负向选择”:在包含相似功能的技能并存时,模型是否频繁选错。比如用户问“下午四点提醒我开会”,结果模型调了 schedule_event 而不是 reminder。这类误用如果高频出现,就去检查两个技能描述的边界是否足够清晰。埋点不需要一开始就做得很重,我一般先用结构化的 JSON 日志,后面再根据分析需要建看板。

5.2 用一个人工标注的回归集当“技能守护者”

每个技能都应该有一组真实场景的回归用例。这不是单元测试,而是“给模型看的场景问答对”:用户会怎么说、期望触发哪个技能、参数填什么、返回值怎么被使用。我通常在新增一个技能时,至少准备 20 条人工标注用例,其中 15 条正向、5 条负向。负向用例专门写“类似但不该触发”的表达,比如“查看天气”不该触发日程技能,“叫我起床”不该触发日程技能。

回归集在每次技能描述或路由规则变更后自动跑一遍。我经历过一次改了参数描述导致“添加待办”误触发“日程创建”的问题,正是回归集在 CI 里拦住了。没有这套回归的话,模型层的回归很难被发现,因为单看代码根本看不出问题。

5.3 灰度:先小流量验证,再全量铺开

技能改动和普通代码改动一样,需要灰度。我的策略是给技能版本加一个 enable_rate,新版本跑 5% 流量,观察触发率、成功率和误用率,稳定后再逐步放量。放量时尤其关注一个指标:成功率持平甚至上升,但触发率可能因为描述改动而变化,需要人工判断变化方向是否符合预期。如果触发率大幅下降,很可能描述里的某个关键词把模型带偏了。

灰度发布还有一个实操细节:新旧版本要能同时存在,且被路由正确分流。所以技能版本号要写进参数契约和日志,不能靠改文件名区分。我见过团队直接把技能逻辑覆盖了,结果灰度时想回滚只能靠 git revert,非常被动。正确做法是每个技能包带上版本号,发布系统按版本号加载,回滚只是改指针。

6. 我踩过的几个坑,希望你绕开

6.1 别让描述变成大杂烩

第一次设计技能时我犯过最蠢的错误:为了让模型“理解得更深”,把技能的背景、历史、相关项目、使用范例全写进描述。结果模型反而抓不住重点,选择率变差。后来我把描述压到 300 字以内,只留 What、When、Output,并且把负向声明单独放一行。描述不是文档,是模型在一堆选择里快速识别你的“标签”。标签越清晰,命中越准。

6.2 参数校验写不严,模型会给你“惊喜”

另一个高频坑是参数校验只做类型检查,不做业务约束。日程技能一开始没有校验 end_time > start_time,结果有一次模型把结束时间写成了开始时间的前一天,接口竟然创建成功,用户差点收到一条来自过去的日程。后来我在参数契约里明确规定值域范围、依赖关系和业务规则,凡是不满足的直接返回错误码并给出可读的修正建议。模型看到错误码以后通常会自我纠错,但前提是我们的错误信息要足够明确。

6.3 权限与技能耦合,上线时进退两难

第三个坑是把权限控制写在技能内部。比如文件操作技能里,管理员能删文件、普通用户只能读,这个判断如果混在 handler 里,技能复用时就得复制一份带权限的版本,维护成本翻倍。现在我把权限放到路由层或网关层统一处理,技能只负责“能不能做成”,权限负责“该不该让这个人做”。两者解耦以后,同一套技能可以安全地服务于不同用户角色。

6.4 给技能做版本管理,包括描述和测试

最后是版本管理。技能仓库里要管的不仅是 handler.py,还有 SKILL.md 和回归用例集,因为影响模型行为的主要是描述。我现在的习惯是:技能包采用 Git 仓库按目录管理,每次描述调整必须带上对应回归结果,merge 之前先看 diff,不光是代码 diff,还有描述 diff。很多隐蔽的行为漂移都是某一次“只改两个字”的描述优化引起的。

6.5 小步快跑比憋大招靠谱

我在早期倾向于把一个技能写得很完美再上,结果要么拖很久,要么一上线就发现真实场景和预期完全不一样。后来改成“最小可用技能先行”:先保证核心路径能跑通、描述只有一个明确触发点、参数只留必需项,然后靠埋点去迭代。技能系统最怕的不是不完善,而是不透明;有了日志、回归和灰度,不完善的技能也能越改越好。等一个技能被反复使用后,再逐渐补边界能力和更细的参数校验,反而比一次性设计高效得多。

就我个人实际操作而言,agent-skills 最大的价值倒不是某个技能写得多漂亮,而是它逼着我把 Agent 的能力从“模型自由发挥”变成“系统化组织”。现在凡是在三个以上场景里出现的重复能力,我都会第一时间抽成独立技能;凡是上线超过一周的技能,必须有对应的回归用例和埋点。这套习惯已经帮我省下了大量排查时间,如果你正准备整理自己的技能库,不妨也从这三个动作开始。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询