
近一年我做Agent相关项目的时间加起来可能比过去三年写业务代码的时间都长。从一开始兴致勃勃地堆Prompt到逐渐意识到单纯的提示词根本撑不起复杂任务再到把目光转向技能系统——这个转变过程里踩的坑比我想象中要多得多。所以当看到agent-skills这个主题我第一反应就是得把这段实战经历好好梳理一遍。先说清楚这篇文章要聊什么。我这里说的技能Skill不是那种给Agent写一段提示词让它会写邮件的小打小闹而是把Agent需要的能力封装成可注册、可发现、可组合的独立模块让大模型在面对复杂任务时能像搭积木一样把多步操作串联起来。这套思路适合正在做Agent应用开发的工程师、刚接触LLM应用层架构的技术负责人以及那些已经发现提示词越写越复杂但效果越来越不稳定的朋友。这篇文章不聊理论框架只聊我在真实项目里验证过的设计决策、踩过的坑以及沉淀下来还能复用的套路。1. 技能不是工具重新理解Agent的能力边界很多团队做Agent的第一版都是给模型塞一堆Function Calling的工具定义。这个方向没错但做到后面就会撞上一堵墙工具数量一多模型就开始选择困难要么调错工具要么干脆忽略某些可用能力。技能系统解决的正是这个问题。1.1 工具与技能的本质差异如果只说一个最核心的差异那就是——工具是原子的技能是完整的。工具解决的是单次操作比如查天气、发邮件、算一道数学题。你给它参数它返回结果一次调用就结束。但真实世界里的任务几乎从来不是单次操作就能完成的。以帮用户安排一次商务出差为例这个任务需要查航班、比价格、看日程冲突、预订酒店、生成行程单——每一步是一个工具但组合起来才是一个技能。技能系统做的事情是把多个工具调用加上中间的逻辑判断、异常处理和状态流转封装成一个模型可以直接理解和调用的完整能力单元。模型不再需要操心先调哪个工具、拿到结果后怎么处理、失败了怎么办它只需要说我调用出差规划技能输入是出差人、目的地和时间范围剩下的都由技能内部消化。我在项目里的实际体会工具模式下的Agent本质是一个被动的执行器每一步都需要模型自己思考下一步做什么。而技能模式下的Agent更像是一个主动的调度者它能在更抽象的层面规划和决策。这个转变带来的直接收益是——复杂任务的成功率显著提升因为模型的负担从每一步都要想清楚变成了只需要选对一条路。1.2 技能系统的三层架构我最终落地的架构分三层这个分层不是我拍脑袋想的而是被项目里的实际问题逼出来的。第一层是技能定义层。这一层负责描述一个技能是什么、能做什么、需要什么输入、会产生什么输出。关键是把技能的描述文本写好这是后面模型能不能正确发现和调用技能的基础。描述文本写得模糊模型就会在多个相似技能之间犹豫。第二层是技能执行层。这一层是技能的内部实现包括工具调用序列、条件分支、异常处理、状态管理。这一层对模型是黑盒——模型不需要知道技能内部怎么跑但技能执行过程中的关键节点状态需要能传回给模型让模型保持对全局的感知。第三层是技能编排层。这一层负责在多个技能之间做协调。复杂任务很少是单个技能能搞定的往往需要先做A技能再根据A的结果决定做B还是C技能。编排层就是处理这种跨技能的流程逻辑。一个很形象的类比技能定义层是菜谱上的菜名和介绍技能执行层是后厨做菜的具体流程技能编排层则是服务员决定先上哪道菜、什么时候上。模型在其中的角色既是点菜的顾客也是决定菜单顺序的领班。这套三层架构跑通之后我才真正理解了为什么那么多Agent框架都在往技能库的方向做——因为把能力封装好了换模型、换应用场景时技能库可以直接复用不需要重写业务逻辑。2. 技能描述与注册让技能库可被Agent感知的核心设计技能系统能不能跑起来有超过一半的功劳要记在技能注册这一步。这一步做得糙后面所有的编排和组合都是在沙滩上盖楼。2.1 技能描述的质量决定召回率你可能觉得描述不就是写一段话吗但这段话怎么写直接决定模型能不能在关键时刻想到这个技能。我从大量实测里总结了一个经验技能描述要回答四个问题——这个技能解决什么问题、什么场景下该用、什么场景下不该用、用的时候大概需要提供哪些关键信息。很多人只写了前两个导致模型在边界场景下会误用技能。举个例子。我做过一个文档处理Agent里面有两个技能一个是文档格式转换另一个是文档内容提取。一开始的注册描述写得比较简单结果模型在处理一份PDF时明明需要的是提取关键信息却调用了格式转换把PDF转成了Word——结果当然不是用户想要的。后来我把两者的描述重新区分格式转换明确写明用于改变文档的存储格式不改变内容的语义内容提取则写明用于从文档中抽取指定类型的信息如关键字段、摘要、结构化数据。修改之后误用率下降得非常明显。另外还有个实操细节描述里要写输入参数的口语化别名。模型在理解用户请求时用的通常是自然语言的表达而技能的输入参数往往是比较正式的名称。比如技能名叫差旅规划用户说的是帮我安排一下下周三去上海的出差里面没有差旅两个字但描述里如果写了安排出差、订行程、商务出行这类别名模型就能更精准地关联到这个技能。这一步很多人忽略但实测效果提升很显著。2.2 技能版本化与依赖隔离技能不是写完就固定的。业务变化、提示词优化、关联的工具接口变更都会让技能内容持续迭代。如果没有版本管理很容易出现模型上个月还能正确调用技能这个月突然不行了的问题——大概率是技能实现被改了但模型侧的注册信息没同步更新。我现在的做法是给每个技能都带上版本号和变更日志。模型加载技能注册表时优先加载每个技能的最新稳定版本如果需要灰度测试新版本可以在技能注册表里加一个候选版本字段让特定会话或特定场景使用新版本其他流量还是走旧版本。这套机制虽然简单但在生产环境里极其救命——它让你能放心地持续优化技能而不用每次改动都担心把线上搞挂。依赖隔离也是容易被忽视的点。一个技能可能依赖特定版本的Python库、外部API的特定参数格式、甚至某个模型的能力阈值。我的建议是尽量把技能实现做成独立的服务或者独立目录每个技能有自己的依赖声明而不是把所有技能的代码和依赖都堆在一个文件里。一旦技能之间出现依赖冲突排查成本会高到让你怀疑人生。3. 多技能编排与上下文管理从单技能调用到任务分解技能系统单体的能力再强也得靠编排才能应对真实世界的复杂任务。这一节聊我在编排链路里的两个关键决策——流程控制和上下文管理。3.1 线性编排与分支编排的取舍早期做编排我倾向于把流程写得很细——第一步做什么、第二步做什么每一步都是固定顺序。这种线性编排的好处是稳定但坏处是灵活性差任务稍微偏离预设路径就卡住了。后来我改成尽量让模型自主编排只在关键节点做强制约束。具体来说对于必须按顺序执行、中间不能跳过的流程我在编排层写死顺序模型不能改变对于可以灵活组合、执行顺序不影响最终结果的流程我放开控制让模型根据任务的具体情况自由选择技能。这个改动的动因来自于一个实际场景。我的Agent要处理数据分析报告生成这类任务链条很长拉数据、清洗数据、做统计分析、生成图表、写结论。其中拉数据必须在清洗数据之前这个顺序不容置疑但生成图表和写结论的顺序其实无所谓——有的用户希望先看图表再读文字有的用户文本偏好更强烈。如果强制线性编排Agent的灵活性就差遇到个性化需求只能硬着头皮按既定顺序执行效果自然打折扣。如果完全放开又可能出现数据没清洗就开始统计这种灾难性错误。所以核心思路是识别流程中的强约束步骤在这几处设卡其他步骤交给模型自己判断题型和上下文。3.2 上下文窗口管理的坑多技能编排还有一个非常实际的问题——上下文窗口。每个技能都有自己的中间过程输出如果把这些输出全部塞进模型的上下文很快就爆了。我之前犯过一个错误让每个技能把详细的执行日志全部返回给模型理由是让模型能掌握全局信息。结果就是上下文越滚越长模型回应越来越慢而且注意力被大量无关日志分散反而忽略了对用户真正重要的核心结果。后来我调整了策略采用分级上下文策略高优先级最终结果、关键中间结论、错误信息——这些必须呈现在模型上下文中中优先级技能的简要执行摘要包括做了什么、用了多长时间、产出了什么低优先级详细日志、原始数据片段、调试信息——这些写到本地文件或者单独存储除非模型需要排查问题否则不进入上下文。这个策略还有一个关键设计——按需拉取。模型如果需要对某个技能的内部过程做进一步分析它可以主动调用一个查看技能执行详情的能力去读取低优先级数据。这样既保住了上下文的轻量化又保留了对细节的追溯能力。实际测试下来上下文量级控制住了模型响应速度和准确度都有明显提升。这个经验在所有Agent类项目里都适用不管你是用什么框架。4. 技能冲突与侥幸存活的陷阱构建技能库的实战复盘点做技能系统做到中后期真正折磨人的不是技能不够用而是技能太多了但模型用不对。这个阶段有三个高频坑值得单独拿出来说。4.1 技能冲突名字相似但行为不同的陷阱技能库一多很容易出现功能上有重叠的技能。比如我在一个内容创作Agent里做过两个技能写一篇技术博客和写一个产品宣传文案。从名字上看两个技能都跟写作有关但适用场景完全不同——前者侧重逻辑结构和深度技术解析后者侧重卖点提炼和用户痛点引导。如果不做冲突消解模型在收到一条帮我写个东西这种含糊请求时会随机选中一个技能——运气好选对了运气不好就输出一个完全不合用户预期的东西。我的解法是三层在技能描述里明确不适用场景让模型在模糊请求下也能做出相对精准的排除在注册表里给技能打标签比如技术写作营销文案代码生成模型在理解用户请求时可以按标签做初筛给冲突技能设置优先级当模型难以判断时默认调用高频/高优先级技能把决策风险降下来。这三层叠加之后技能误选率大幅下降。但说实话最治本的办法还是从源头上控制技能库的重复建设——新增技能前先做一次相似度检索确定现有技能确实覆盖不了再说。4.2 技能膨胀库越大Agent越糊涂技能数量过百会进入一个尴尬阶段——召回率开始显著下滑。技能描述加总起来的Token数太大模型在推理时无法同时考虑所有技能容易出现漏召回。我在一个项目里遇到过很离谱的事Agent明明有发邮件技能用户明确说发一封邮件给张三模型却在嘀咕用户是不是想创建一个待办事项完全跑偏。后来一查技能库里积压了太多跟发送、通知、提醒相关的技能模型在相似技能之间短路了。应对技能膨胀我现在坚持两个原则高频技能优先注册。不是所有技能都放在模型的主检索范围里低频技能可以放到扩展技能库模型只有在主库中没有匹配项时才去扩展库检索。定期做技能归档。每个季度检查一次技能调用频率调用次数长期垫底的技能就标记为停用或合并。这听起来很简单但很多团队做不到原因大家心知肚明——没人愿意删自己辛苦做出来的东西。但我想说技能库就像衣橱只塞不扔最后想找件衣服都翻不到。4.3 技能评估没有度量就没有改进技能到底好不好用不能靠感觉得有数据。我搭的评估体系包含四个指标实践下来比较有效调用成功率技能执行期间是否抛异常、是否返回预期结果召回命中率在N个相似技能存在时模型是否能正确选出目标技能执行效率从调用到返回结果的平均耗时以及消耗的Token数用户体验评分用户对技能产物的显性或隐性反馈。这里我想多说一句很多团队把评估重点放在调用成功率上但召回命中率和用户体验评分才是技能库健康的真正晴雨表。一个技能可能每次调用都不报错但用户根本不觉得输出有用——这种技能留着就是纯消耗资源。我每个技能都配上调用链路的追踪日志一段时间后拉出来看哪些技能是高频高满意度哪些是高频低满意度哪些是低频可有可无。这个视角比任何KPI都诚实。技能评估这件事没有终点。语言模型在变用户的需求在变技能库也必须跟着迭代。我把这个过程固化成了月度例行工作——每月抽半天时间对着评估数据决定每个技能的留存、优化或者下线。这个习惯坚持了小半年技能库的质量一直在提升。5. 技能设计时的隐性成本模型能力边界与Token开销最后想聊一个经常被忽略、但迟早会撞上的话题——技能设计不是免费的。5.1 模型能力边界决定技能粒度技能设计有一个很实际的考量技能的粒度应该多大粒度太小比如一个技能只做一次加法运算模型调用它的意义不大浪费上下文还增加了延迟粒度太大比如一个技能把全网收集信息-分析-生成报告全包了模型对中间产物的控制力就很弱一旦某个子步骤出错整个技能失败排错成本高。我的经验是技能的粒度应该对齐模型能够独立完成的决策单元。一个技能内部包含的步骤应该是模型不需要介入太多就能跑完的但技能与技能之间的衔接应该留给模型做决策。这样既保证了执行效率又保留了模型的控制力。用一句话概括就是——让模型做判断让技能做执行。判断与执行的边界就是技能设计的边界。5.2 Token开销被忽视的隐性成本技能注册表里的描述每次请求都要和用户输入一起发给模型。当技能数量多了之后注册表本身的Token开销会变得相当可观。我在一个生产项目里测过注册表有40多个技能时描述文本就占掉了每次请求约2千Token——如果每天有上万次请求这个成本很吓人。优化手段主要有三种精简描述每条技能描述控制在150字以内只保留最核心的信息分层召回把技能注册表拆成主表和副表主表只放高频技能副表放长尾技能模型先看主表没有匹配再查副表动态加载根据任务类型预筛技能比如用户明确要做数据分析时只加载数据分析相关的技能子集而不是全库加载。这三个手段叠加起来我项目里的单次请求Token开销降低了大约一半而且召回率没有明显下跌。Token这件事平常不觉得一旦规模上来它就是压死成本的最后一根稻草。6. 落地建议与个人小结如果你正准备在项目里引入技能系统我的建议是从小处起步先挑选2-3个最高频的场景把它们的技能完整做出来——包括注册描述、内部实现、评估指标——跑通一遍闭环。技能系统的价值不在于数量多而在于每个技能都足够可靠。与其一口气搭50个用不上的技能不如把5个核心技能打磨到稳定。做技能系统这件事最让我感触的一点是——它本质上是在给模型减负。模型不需要记住每一步操作怎么做不需要在几十个工具之间纠结不需要操心异常处理它只需要理解任务、选择路径、校验结果。而技能系统则把这些确定性强的逻辑固化下来让模型只做它最擅长的事。这比堆Prompt要优雅得多也稳定得多。最后分享一个真实心得这些经验没有哪一条是看书看来的全都是在项目里被现实教育之后总结出来的。早期我也走过弯路——开始是模型频繁调错工具改了描述又遇到上下文爆炸处理了爆炸又开始头疼技能膨胀——每一步都是在发现问题-定位原因-修正系统的循环里打磨出来的。偶尔回头看看第一次写的那版蹩脚技能注册表真的会感慨再复杂的方案也都是从一个不太完美的起点一点一点改出来的。