
最近这半年我几乎把所有精力都砸在了Agent落地这件事上。一个很明显的感受是大家手里的基座模型越来越强但真正拉开项目差距的往往不是模型本身而是Agent到底“会不会干活”。换句话说Agent不缺大脑缺的是手脚。这个“手脚”就是业内讨论度极高的agent-skills也就是Agent技能体系。我见过太多项目模型换成了顶配Prompt也调得花团锦簇结果Agent一上手真实任务就露怯——要么步骤做到一半卡住要么结果格式乱七八糟要么遇到异常情况就直接摆烂。问题不在于模型笨而在于我们只给了它目标和上下文却没给它一套完整、可复用、可纠错的动作体系。这篇文章我就围绕agent-skills这个主题把我从实际项目里折腾出来的经验、踩过的坑、沉淀下来的方法论系统地拆开讲一遍。无论是正在做智能客服、自动化办公流程还是在研究多智能体协作这篇文章都应该能给你一些能直接抄走的思路。1. 我为什么觉得Agent缺的不是脑子是手脚先讲一个我实际遇到过的场景。某公司内部想做一个邮件自动应答助手让Agent根据客户来信内容起草回复。一开始大家都很乐观觉得以现有模型的对话能力写一封回信还不是手到擒来。结果实测下来裸跑效果惨不忍睹。模型确实能写出文从字顺的回复但问题全藏在细节里报价相关邮件回复里漏了折扣条款投诉邮件语气过于生硬需要转给技术支持的邮件被直接按普通咨询处理了。单独看每一封回复好像都还行可一旦放到真实业务流里错误率居高不下根本不敢上线。后来我们换了个思路不再让模型“自由发挥”而是把处理一封邮件这件事拆成了稳定动作序列先判断邮件类型再抽取关键实体再套用对应模板再做敏感信息检查。每一步都有明确的规则和兜底方案。效果立刻就不一样了错误率大幅下降。这件事让我彻底想明白了一个道理大模型的强项是“理解”和“生成”但Agent要真正完成一项任务还需要稳定的“行为”。而行为不能靠模型临场发挥必须靠工程化手段固化下来。这个固化的载体就是技能。1.1 技能到底是什么我给技能下的定义比较简单技能是一段围绕“把某件事做成”而设计的完整行动方案它以文件形式沉淀包含任务拆解步骤、每步的决策规则、依赖的工具调用方式、输出格式约定、以及失败时的恢复策略。对比一下就清楚了。传统Prompt是告诉模型“结果应该长什么样”工具Tool是给模型提供“能调用什么能力”而技能则是告诉模型“这件事从头到尾该怎么做中途遇到各种情况怎么应对”。举一个生活中的例子。你请一位新手厨师“做一道红烧肉”这是Prompt。你给他准备锅、铲、调料、肉这是工具。你把一份完整的菜谱交给他告诉他先焯水、再炒糖色、加水没过肉、小火炖四十分钟、最后大火收汁中间油温太高怎么办、水加多了怎么办这就是技能。1.2 技能和日常工作流、插件的边界很多人会问我们之前不是有工作流引擎、有插件机制吗这和技能有什么区别我的理解是工作流偏重的是确定性的流程编排每一步做什么、走哪个分支都是提前定义死的。插件偏重的是能力扩展给Agent装上某个工具它就能做某事。技能则是介于两者之间的产物。它既有流程的骨架又保留了模型在每一步的自主决策空间。技能不规定每一步必须怎么走它规定的是目标、可选路径、约束条件和失败预案具体细节由模型在执行时根据上下文灵活选择。这种柔性很重要因为真实世界的任务是充满不确定性的。一个固定死的工作流遇到意料之外的输入就断了而纯靠模型自由发挥又不稳定。技能恰好在这两者之间找到了平衡这也是它成为Agent工程核心组件的原因。2. 给Agent装技能前先搞清楚技能、工具、提示词的三层关系我见过不少团队把技能、工具、提示词混为一谈结果做出来的东西既不是技能也不是工具四不像。这里我把自己的一套分层逻辑完整说一下这套逻辑已经在我们好几个项目里验证过非常管用。先说结论整个Agent的能力体系应该分成三层。最底下是工具层中间是技能层最上面是任务编排层。提示词则不是一个独立的层它分散在每一层里作为描述性的元信息存在。2.1 三层架构各自管什么工具层解决的是“能和外部世界发生什么交互”。它封装了一个个原子能力比如搜索网页、读写数据库、发送HTTP请求、操作Excel文件。工具的特点是无状态、无流程、单一职责。任务编排层解决的是“这次任务具体要达到什么目标”。它是一个相对较薄的层负责理解用户需求、选择合适的技能、监控执行进度、判断何时终止。技能层夹在中间是最关键的一层。它把多个工具调用按特定顺序和逻辑组织起来成为“一个能完成某类任务的组合动作”。层级核心问题典型产物可变性工具层能与世界发生什么交互API封装、函数调用低接口稳定技能层如何把一件事做成技能文件、动作序列中按任务调整编排层本次任务的目标是什么任务计划、状态机高随需求变化2.2 技能描述是模型选择动作的“菜单”这里有一个特别容易被忽视的点模型在面对一个任务时是怎么知道该调用哪个技能的靠的就是技能文件里的描述信息。我打一个比方。技能库就像一本餐厅菜单模型是坐在里面的食客。每道菜都有一个名字和一段介绍。菜名清楚、介绍准确食客就能一眼选中自己想要的。如果菜名模棱两可或者介绍里写的跟实际端上来的菜完全两回事食客就会点错菜。所以技能的头部描述必须高度精炼、准确。我一般会要求技能描述只回答三个问题这个技能是干什么的在什么条件下应该用它在什么条件下不应该用它比如一个“客户工单分类技能”的描述我可能会写成“用于将客服工单按问题类型划分为咨询、投诉、售后、建议四类。当输入是客户原始反馈文本时使用。如果输入已经是结构化标签数据则无需使用本技能直接进入流转环节。”这种明确的唤起条件能极大降低模型错误调用技能的概率。很多项目里技能没用好不是技能本身写得差而是入口描述写得稀烂模型压根不知道什么时候该用它。2.3 技能之间的组合关系从原子到复合技能不应该是全都平铺在一层的。我习惯把技能分成两个级别原子技能和复合技能。原子技能对应的是单一领域的单一任务比如“提取文本中的日期”、“调用OCR接口识别图片文字”、“判断一段文本的情绪倾向”。这些技能内部逻辑简单工具调用不超过一两个输出结果单一。复合技能则是由多个原子技能按照业务逻辑组合而成。比如“自动处理售后工单”这个复合技能可能包含“提取工单信息”、“查询订单状态”、“判断责任归属”、“生成处理建议”四个原子技能。在做技能设计时我建议先把原子技能做扎实再往上组合。复合技能的优势在于它可以作为一个整体被更高层的能力复用同时内部细节对外屏蔽。以后做多智能体协作时每个Agent手里握着几个复合技能就能独立承担一摊子事不需要把所有细节都暴露出来。3. 从接手一个真实任务开始四步搭建最小技能集前面讲了不少概念这部分直接来实操。我拿一个大家都能理解的任务举例做一个客服工单智能分类系统。它的目标是把用户提交的原始反馈文本自动归入正确的类别给出结构化结果并识别出需要优先处理的紧急工单。这套技能我现在已经在好几个项目里搭过整体流程已经固定成了四步。照着走基本不会翻车。3.1 第一步盘点高频、高成本、高出错率任务不要一上来就写技能文件先做任务盘点。我会把业务方拉在一起让他们列出一张表哪些任务是人工处理耗时最长、出错率最高、规则最复杂、业务影响最大的。我当时在某公司做这个项目时跟客服主管聊了一下午。最后筛出来的任务是工单分类。原因是客服每天收到几百条工单分错类会导致流转错误投诉工单被当成咨询处理用户满意度直线下降。而且分类标准本身有十几条细则新人培训成本高人工判断容易受情绪影响。筛选标准我认为有三条频次要高不然投入产出不划算规则要相对明确适合固化成技能错误代价要大这样优化后的价值才有说服力。满足这三条的任务就是最好的技能建设对象。3.2 第二步把人工处理过程拆成可描述的步骤选定任务后下一步是搞清楚有经验的客服到底是怎么完成分类的。这一步很多人会跳过去直接自己拍脑袋写步骤结果写出来的技能跟实际业务脱节。我的做法是让资深客服做现场演示拿一批真实工单一边处理一边说出自己的判断依据。我会在旁边记录把隐性的经验转成显性的规则。比如我观察到资深客服并不会逐字读完整封工单而是先扫一眼开头几句话判断语气再看是否有“退款”“投诉”“差评”这类关键词接着查一下订单信息最后才做出分类决定。把整个过程记录下来后我整理出了一套动作序列第一步清洗文本去掉重复内容和无意义字符。第二步提取关键特征包括是否含敏感词、是否有订单号、是否有激烈的情绪表达。第三步套用分类规则将特征组合映射到四个工单类型。第四步置信度校验如果特征之间相互矛盾标记为待人工复核。这一步的核心价值在于它把老师傅脑中的“感觉”变成了可以执行、可以验证的步骤序列。这也是技能工程和普通写Prompt之间最大的分水岭前者建立在真实工作流程之上后者建立在语言幻觉之上。3.3 第三步把动作编码成技能文件流程清楚了就可以写技能文件了。我习惯用YAML格式来组织技能因为结构清晰、可读性好而且方便后续做版本管理和工具化解析。一个最小可用的技能文件我建议包含以下字段技能名称、技能描述、适用场景、输入要求、执行步骤、工具依赖、输出结构、失败处理。下面是我当时为工单分类技能写的简化版模板name: ticket_classifier version: 1.3.0 description: 将客服工单文本归类为咨询、投诉、售后、建议四类并标记紧急程度。 当输入是用户原始反馈文本时使用输入已是结构化分类数据时禁用。 input: format: plain_text max_length: 2000 required_fields: [text] tools: - order_lookup: 查询订单信息 - sentiment_analyzer: 检测情绪强度 - deduplication: 去除重复工单 steps: - id: 1 action: text_clean description: 去除无关字符和重复内容 outputs: cleaned_text - id: 2 action: feature_extract description: 提取关键词、情绪强度、订单号等特征 outputs: features - id: 3 action: rule_match description: 根据特征组合套用分类规则 outputs: category, priority - id: 4 action: confidence_check description: 校验分类置信度特征冲突时标记复核 outputs: needs_review output: schema: category: string priority: low|medium|high needs_review: boolean confidence: float failure_recovery: - condition: order_lookup返回超时 action: 重试一次仍失败则跳过订单信息仅基于文本内容分类 - condition: 特征冲突如同时含投诉词和高满意度词 action: 标记needs_reviewtrue附冲突说明这里我多说一句执行步骤不建议写太细也不建议写太粗。太细会让模型失去灵活性一遇到偏差就卡住太粗则失去了技能固化的意义。我的标准是每一步都是模型能独立决策、产出可验证结果的单元步与步之间有清晰的输入输出衔接。3.4 第四步用回归集把技能“钉死”在合格线上技能写完之后绝对不能直接上线必须跑回归测试。我每次都会建一个验证集里面包含三种样本正常样本覆盖所有分类的典型工单边界样本语气模糊、特征不明显的工单刁钻样本比如用户用反讽语气写的投诉、包含多个问题的复合工单。当时我准备了四十条历史真实工单作为验证集其中正常样本二十五条、边界样本十条、刁钻样本五条。第一次运行技能文件时通过率只有六成五左右主要翻车点正集中在刁钻样本上。比如有一条工单写的是“你们的服务真是太好了好到我再也不想来了”模型直接把它分成了咨询实际上这是一条明确的投诉。针对这些问题我不停调整规则和特征组合前前后后迭代了四个版本才把通过率拉到九成以上。这个过程不可省略某种意义上技能工程就是测试驱动开发的翻版——先把验收标准定清楚再去补齐能力。4. 技能工程的核心设计原则可测试、可编排、会认错前面讲的是单个技能怎么搭这部分说说我在多轮实战里沉淀下来的设计原则。这些原则不区分具体领域做任何Agent技能建设都能用上。4.1 技能即测试用例先定义验证集再写技能我见过太多团队先写一大段技能描述写完觉得万事大吉然后上线被真实场景教做人。正确的顺序应该反过来先收集一批代表性输入和对应的期望输出再把技能写出来去满足这些用例。这个思路其实是从测试驱动开发里借来的。技能的稳定性和模型参数不同它不可能一次写对必须靠反复迭代逼近。有了验证集迭代才有方向。每次改完技能文件跑一遍验证集看通过率变化就知道改动到底是变好了还是变坏了。我把这个习惯推到了我们团队所有Agent项目里现在每个技能都会配一个专属的测试集文件。技能可以一直改但测试集只加不减每次版本升级都要全量回归一遍。这套机制虽然前期麻烦但长期价值很大它让技能的演进过程从“靠感觉”变成了“靠数据”。4.2 把失败恢复当成第一公民来设计我统计过我们项目里技能运行失败的原因大概有三分之一是模型逻辑错误剩下三分之二全都来自外部环境异常接口超时、返回格式不符、依赖的工具临时不可用、数据源字段缺失。这让我明白了一件事技能设计里如果只有成功路径那这个技能就是纸糊的。真实世界里故障和异常是常态不是意外。所以我在写技能时会把失败处理放到跟主流程同等重要的位置。具体做法是每设计一个步骤我都会强制自己回答一个问题如果这一步的输入拿不到标准的预期数据Agent应该怎么办比如工单分类技能里如果订单查询接口超时了不能让它像个无头苍蝇一样反复重试而是明确告诉它跳过订单信息、只基于文本分类如果前后特征互相矛盾就标记为待人工复核把冲突原因写进备注。这套“如果遇到什么情况就做什么处理”的兜底逻辑大大提升了Agent在非理想环境下的存活率。4.3 输入输出结构化成契约技能之间要能组合、能被上层编排调度前提是它们的输入输出格式稳定、可解析。我把技能视为“函数”输入是参数输出是返回值两边都有明确的类型和结构定义。在设计输出结构时我强烈建议输出结构化字段而不是自由文本。比如工单分类技能的输出是category、priority、needs_review、confidence四个字段上层流程拿到这四个字段就能继续做流转决策。如果输出是一段“这段工单看起来是投诉建议优先处理”这样的大白话下一个环节就没法程序化地处理它。结构化的另外一个好处是可度量。数值型字段可以用阈值做判定confidence低于某个值就走人工复核分支这是自由文本做不到的。为了做到这一点我在每个技能文件里都会明确写下输出schema及各字段的取值范围和语义这也是前面那个YAML模板里output部分存在的意义。4.4 技能的“头”要精身段要丰厚最后一条原则是关于技能文件自身形态的。技能文件的入口描述要极其精炼因为它是模型选择技能时的依据太长了模型捕捉不到关键信息。但技能内部的执行细节要尽量完整因为它是模型执行时的指导手册。一句话概括就是菜单上的一句话介绍要短后厨的菜谱要细。我见过一些团队把技能描述写成万字长文试图在一段话里把所有执行细节都塞进去结果模型看到那么长的describe字段注意力早就涣散了反而干扰了唤起判断。我的建议是入口描述控制在两百字以内执行细节全部放到body或steps字段里。这样既能保证模型正确唤起技能又能保证执行时有足够的操作依据。5. 我在实际项目里踩过的技能工程大坑讲了这么多方法论这部分把我踩过的一些知名坑拿出来说一说算是给后来者排雷。每一个坑都是真金白银买回来的教训。5.1 坑一技能文件越长越好大错特错最早做技能的时候我有个误区总觉得写得越详细越不容易出错于是一个技能文件动辄四五千字把各种边缘情况都堆在里面。结果实测下来模型调用这个技能时上下文消耗极大而且因为指令密度太低真正核心的操作步骤反而被淹没在大段冗余描述里执行效果还不如精简版。后来我逐渐摸索出了平衡点。技能文件的精简标准是拿掉任何一句话技能的可靠性都不会变差这才叫精。所有步骤说明、条件分支、示例代码、注意事项都是围绕这个标准来裁剪的。5.2 坑二示例给得太完美导致模型过度拟合为了教会模型怎么输出我一度在技能文件里贴了大量标准示例。结果模型学到的不是任务的判断逻辑而是示例的表面格式。只要真实输入和示例在措辞上稍有不同输出质量就急剧下降。这个问题的根源在认知科学里有个对应的概念叫过度拟合。模型跟人一样给它看的例子太单一它就抓不住背后的抽象规律。我的解决方案是给示例时刻意制造多样性同一种分类结果用不同语气、不同详略程度、不同结构的文本各给一遍让模型看到枝干而不是某一根具体的枝条。5.3 坑三技能命名随意模型唤起混乱有一阵子我们的技能库里同时存在“订单查询技能”和“订单状态获取技能”描述内容也高度重叠。结果模型在接到“帮我看看这个订单到哪一步了”的请求时有时调用前一个有时调用后一个输出结构还不一样下游流程直接懵了。排查之后我定了一条硬性规矩技能命名要遵循统一规范同类能力的技能只能保留一个入口所有变体全部合并技能之间的描述要做到互斥任何一个输入至多能触发一个技能如果出现两个技能都符合条件的情况说明命名或边界设计有问题必须回头重构。5.4 坑四只设计了成功的路没有设计迷路的路这个前面其实已经提到过一部分但这里想单独拿出来再强调一次因为它的重要性真的怎么强调都不为过。我前几个版本的技能文件所有步骤都是正向思维先做什么然后做什么最后输出什么。但真实线上运行时模型经常在执行中途遇到前置条件不满足的情况技能文件里又没有对应的应对说明于是模型只能自行发挥或直接卡死。比如有一次工单分类技能跑到第三步时发现输入文本里同时包含“我要退了”和“产品质量很好”两句话特征互相冲突模型不知道该信哪个直接停滞了。后来我把这类冲突检测和兜底分支写进技能文件明确规则是“特征冲突时一律标记人工复核”问题才彻底解决。5.5 坑五技能验证只测成功路径真实回归翻车我最初做回归测试时验证集里全是正常的、友好的输入结果每次自测都完美通过上线就被真实用户的花式提问打得措手不及。用户不会按你设计的标准格式提问他们可能一句话里带多个意图可能用错别字可能用反问句、省略句、还有网络用语。从那次之后我的验证集里专门开辟了一个“恶意样本”区专门收集真实世界里最难缠的输入。并且定了一条规则技能做任何改动除了验测试集里的正常样例还必须验一遍这些刁钻样本防止改动出现意外副作用。6. 技能体系的下一步从单个技能到组织能力技能建设做到一定程度后我发现真正值钱的不是某一条技能而是整座技能库。它从一个工具属性极强的东西慢慢变成了团队的资产甚至可以说是一种组织能力。6.1 把技能库当成代码库来管理技能文件本质上是一段可触发的逻辑它跟代码没什么区别所以应该享受代码的同等待遇版本控制、变更记录、评审流程、发布计划。我现在会把所有技能文件纳入统一的仓库管理每次修改都要提交变更说明。技能库的主干分支保持稳定只有经过回归测试通过、各项指标合格的版本才会合入。这样做的好处是多个Agent并行跑的时候不会出现某一条技能被临时改坏导致全线崩溃的情况。6.2 多Agent协作时的技能角色化当我们从单Agent走向多Agent协作时技能的组织方式又发生了变化。不同角色的Agent需要不同的技能配置。历如客服入口Agent只需要具备工单分类和沟通能力处理Agent则需要具备订单操作、退款审批等执行类技能。这一步可以通过给不同Agent挂载不同技能集合来实现本质上就是角色的能力画像。我越来越觉得技能体系之于Agent就像岗位职责之于员工。一个团队里不是所有人都需要会所有技能每个角色会自己那一套协作时通过调度协议衔接起来整体效率反而更高。6.3 技能积累的复利效应最后聊聊复利效应。技能跟Prompt有个很大的不同Prompt往往是一次性的这次项目写完下次换个场景可能就用不上了。但技能带有很强的复用属性因为它是按任务类型组织的而不是按某个具体项目组织的。我在一个行业里做完客服技能包换到另一个公司做同类业务时技能文件只需要调整工具调用细节和业务规则整体框架可以整套搬过去。这种跨项目复用的能力让技能库的边际成本越来越低、长期价值越来越高。我的几点实在体会写到这里该讲的技术细节都讲得差不多了最后聊几句我个人的体会。技能工程不是写几个文件就算完事它是一个持续迭代的过程。我在实际项目里的感受是前期的投入产出比并不高前两版技能文件的通过率往往很难看很容易让人打退堂鼓。但只要你把验证集立住了坚持迭代到后面每一轮的提升都会越来越明显。另外一个体会是技能文件的受众是模型不是人。我们写文件时容易下意识写得像给人看的技术文档术语堆砌、逻辑跳跃。但模型跟人不一样它更适合结构清晰、指令明确的表述。写完后最好的检验方式不是自己读一遍觉得通顺而是直接丢给模型跑真实场景看它能不能顺畅执行下来。这个领域还在快速演进但有一点我相信不会变在可预见的未来谁拥有的技能集更完备、更可靠、更精细谁的Agent就能在真实世界里干更多实事。哪怕模型内核以后变得更聪明一套沉淀下来的技能体系仍然是无可替代的工程资产。