智能体技能:让AI能力从Prompt堆砌走向工程化编排
我最近帮一个朋友调试他团队做的智能体项目来回改了几个晚上发现一个很扎心的问题他的 prompt 写得已经足够长、足够细大模型偶尔也能跑出不错的结果但只要换一批数据、换个环境输出就完全乱掉。问题不在 prompt而在于整个系统没有把“能力”变成可以独立管理、单独验证、随时替换的资产。后来我给他们建议了一件事把智能体能做的事从 prompt 里抽出来做成独立的技能模块。也就是把“让模型自由发挥”改成“让模型按技能文件来执行”。做完之后效果好得离谱——不只是输出稳定了连调试、升级、出问题时定位根因的方式都完全不一样了。这就是“agent-skills”这套思路的由来。本文就用我在实际项目里踩过的坑、验证过的方法把什么是智能体技能、技能内部应该有什么结构、怎么注册调度、怎么做版本管理以及一个完整的“内容排期助手”案例全部拆开来讲。不管你是在做个人助手、客服系统还是企业内部的知识平台这套做法都能直接用上。1. “agent-skills”不是提示词工程而是一套基础设施先说清楚一个认知技能skill不是把更长的 prompt 塞给模型而是一个可独立维护、可被检索、可被调用的工程实体。1.1 为什么 prompt 堆砌解决不了智能体泛化问题我见过非常多团队一开始的思路都是“把需求写详细一点”。比如做一个客服智能体就把产品文档、FAQ、话术规范全部拼进 prompt指望模型自己从中找出正确答案。这在小范围demo里没问题一旦规模化就会遇到三重困境第一是上下文窗口的物理限制。文档一多prompt 塞不下模型开始截断然后漏掉关键信息。第二是输出稳定性极低。同样的一句话今天回复长篇大论明天回复一句话今天语气客气明天语气生硬。你没法把“稳定输出”交给概率。第三是更新代价高。改一句业务规则就要重新调试一整段 prompt而且要担心改动会不会影响其他部分的回答逻辑。这种“牵一发而动全身”的感觉做过的都懂。而技能体系的思路完全不同。它的核心假设是智能体不该只有“一个大脑”而应该像一家运转良好的公司背后有明确的岗位、流程、工具和检查机制。大脑负责做决策和调度技能负责把具体活儿干完。1.2 技能、工具、子代理到底是啥关系这个是讨论最多也最容易混淆的问题。我直接给出我在项目里沉淀下来的定义技能skill一项面向“输出结果”的完整能力。它可能调用多个工具、经过多个步骤、执行多次模型推理但对外只暴露一个目标完成某类任务。工具tool智能体可调用的原子能力。比如搜索、读文件、发HTTP请求。工具本身不做决策只执行动作。子代理sub-agent带有独立上下文和独立目标的执行单元。它有自己的提示词、工具集和终止条件敏捷度更高。打个不严谨但好懂的比方工具是螺丝刀技能是“装好一把椅子”的施工方案子代理是“你这样装椅子装了三年、老师傅看一眼就知道问题在哪”的执行者。现实项目里技能可以自己调用工具也可以委托给子代理。一个技能里也可以组合多个子代理来并行处理分支任务。它们不是竞争关系而是不同层级的组织结构。搞清楚这层关系之后你在设计阶段就不会反复犹豫“这个功能到底该做成技能还是做成工具”了。1.3 技能目录才是智能体的“部门架构”一个好的技能体系最大的作用并不是让单次执行更准而是让整个智能体变成一张可以盘点的能力地图。在我搭建过的智能体系统里我会维护一份技能清单每个技能包含名称、用途、所属领域、输入参数、调用方式、失败策略、版本号。这一步本质上就是在给智能体搭建“组织架构”。当你想看看“这个智能体到底能干什么”不需要猜翻技能清单就可以了当你想评估“能不能新增一个能力”本质就是“要不要新增一个技能”。这种可盘点性在协作开发时尤其重要。不同人负责不同技能互相之间只用约定接口不需要理解别人的全部实现细节。这就是工程化。2. 拆开一个技能声明、描述、实现与校验四段式设计才是稳定的最小单元很多人写的“技能”其实就是一大段描述性文字让模型照着做。这种根本扛不住真实场景。我在多次迭代之后沉淀出一套四段式结构技能声明、自然语言描述、可执行实现、输出校验逻辑。缺一个这个技能就很容易变成“薛定谔的可用”。2.1 技能声明让智能体知道这个技能什么时候该用技能声明的本质是一段结构化的元数据最简单的形式长这样skill: name: article_summarizer version: 1.2.0 description: 对长文进行结构化摘要支持摘要生成和要点提取 domain: content_processing inputs: - name: content type: string description: 原始正文内容 required: true - name: max_points type: integer description: 最多提取的要点数量 required: false default: 5 outputs: - name: summary type: string - name: key_points type: array on_error: - retry_with_shorter_input - fallback_to_first_n_chars初看这只是一串字段但它解决了一个非常实际的问题智能体在决策时不再需要在几百行 prompt 里“猜”这个技能是干嘛的。它只需要看声明就能判断当前任务该不该调用这个技能、输入该传什么、失败后该怎么办。这也是我给所有技能定的硬性要求声明必须写清楚“在什么场景下使用”和“在什么场景下不要使用”。后者重要程度不亚于前者因为很多误调用问题就是声明里写了“能做什么”但没写“别拿它做什么”。2.2 自然语言描述不是给模型背诵的是给模型导航的技能描述的核心不在于细致到了什么程度而在于给模型一个“判断依据”。我当时踩过好几次坑一开始把描述写得特别长恨不得把实现细节都写进去结果模型反而抓不住重点。后来我调整成“三层法”来写描述第一层用一两句话说清楚这个技能解决什么问题写给决策模块看。第二层写清它在执行时的重要约束例如涉及日期时一律以北京时间为准、引用数据时必须保留来源字段。第三层列出典型边界情况例如输入为空时怎么处理、输入超过上限时怎么处理。举个例子同样是“内容合规检查”技能低质量的描述是“检查输入内容是否违规”高质量的描述是“承接内容发布前的合规过滤任务。如果文本包含联系方式或者外部平台导流线索判定为违规如果是正常业务名词请放行无法判断时返回 pending 而不是直接拒绝”。这里面的关键词是“无法判断时返回 pending”——它给了模型一个安全出口避免模型为了完成任务而硬下结论。这种细节没法靠长文本堆出来只能靠对真实场景的理解一点点磨。2.3 可执行实现从“模型自由发挥”到“流程分步执行”技能实现有两种思路一种是全交给模型另一种是流程编排。我现在的原则是能编排的绝不裸奔。什么叫裸奔就是定义一个函数里面就一行“请模型做某某事”。非常灵活但输出不稳定。什么叫编排就是把任务拆成多个步骤每一步都有明确约束、中间结果都进入一个结构化的上下文。就拿做会议纪要来举例。裸奔式实现的输出你永远不知道它会把重点放在哪里。编排式实现我一般分成三步第一步原始转写清洗去掉语气词、打断、重复形成干净文本。第二步结构化提取按固定字段把发言人、决策、待办项、截止时间抽出来。第三步纪要生成用标题列表的模板把信息组织成最终格式。每一步都单独验证、单独调试。中间哪一步出问题了你直接定位到那一步而不是对着最终输出猜。而且分步实现有个大好处每一步都可以接入不同的模型甚至可以一部分用规则、一部分用模型、一部分用外部接口。这不只是性能优化更是成本控制的手段。2.4 输出校验技能“完成”和“真的可用”是两回事我见过太多场景模型自信地说“已完成”结果输出里缺字段、格式不对、内容截断。所以在我现在的体系里任何一个技能跑完都必须过校验校验不过直接走失败分支。输出校验的逻辑有三个层次第一层是结构校验字段是否齐全、类型是否匹配、必填项是否为空。第二层是语义校验例如酒店预订技能最终输出的日期是否和用户输入的入住日期一致。第三层是业务规则校验例如金额字段是否为负数、状态字段是否为合法枚举值。输出校验不是可选项它决定了技能的失败率。一个没有校验逻辑的技能就等于把错误留到下游。而下游一旦出问题排查成本瞬间翻倍。3. 设计技能时先定三元组领域、工具、工作流三者缺一不可很多人一上来就问“这个功能怎么做成技能”其实问错了。应该先问“这个技能的领域在哪、需要哪些工具、工作流怎么编排”。我把它总结成技能设计的三元组每一项都直接决定技能最终是否可落地。3.1 领域定位限定范围越窄越好使领域的本质是“这个技能在哪个边界内是专家”。同样一个文本改写技能用在营销文案领域和用在学术论文润色领域提示词、校验规则、成功标准都是完全不同的。如果你贪方便一个技能包打天下结果往往是所有场景都能用但所有场景都用不顺。我的建议是宁可多一点小而专的技能也不要搞一个什么都管的大杂烩。原因很简单窄领域的技能声明容易写、实现容易验证、模型也更容易“懂”这个技能。而且窄技能可以自由组合反而比一个大技能更灵活。3.2 工具依赖不是越多越好是刚刚好每个技能在设计时就要想清楚它到底依赖哪些外部能力。我把工具依赖分成三种必需工具没有它整个技能跑不动。比如天气查询技能的定位接口。可选工具有它效果更好。比如同一个天气技能如果也能访问历史数据可以做趋势判断。禁用工具绝对不要碰。比如合规审查技能就应该声明不调用任何外部模型服务。这里最容易被忽略的就是“禁用工具”。它虽然没有实际调用逻辑但它的存在让调度器有更明确的决策依据避免了模型“手痒”乱调工具的情况。我一度有个技能在跑的时候莫名其妙调用了网页搜索加了禁用声明之后才消停。3.3 工作流编排技能内部也要画“主流程分支”技能设计到最后一定会落到一张执行流程图上。我先用文字梳理主流程再列分支情况。主流程很好理解就是完成任务需要的核心步骤。分支情况要重点盘点五类输入缺失时的分支中间结果异常时的分支输出校验失败时的分支外部依赖超时或报错时的分支用户中途修改需求时的分支这五类情况在真实场景里必踩而且往往是决定技能稳不稳的关键。我倾向于把分支逻辑直接写进技能配置里而不是指望模型在执行时临场发挥。宁可写得机械一点也不要让模型自由判断。稳定性在真实业务里永远优先于创造性。4. 技能注册与调度让智能体在正确的时间调用正确的技能技能设计得再好如果没有一个可靠的注册和调度机制依然只是纸上谈兵。这一章聊工程落地也是最容易被低估的部分。4.1 注册中心所有技能的统一入口当技能数量超过十几个之后靠人工维护就是灾难必须建注册中心。本质上它就是一张技能表不过字段设计决定了后续调度是否能跑顺。我这边的注册中心一般长这样{ 技能名: schedule_creator, 触发领域提示词: [排期, 日程, 时间安排], 请求示例: [ 帮我排一个下周的会议计划, 把周三的培训挪到周五 ], 依赖技能: [calendar_lookup, meeting_room_check], 调用成本等级: high, 是否允许并行: false, 版本策略: stable, 负责人: 某开发者 }这么设计的目的是尽量降低“调度器误选技能”的概率。触发领域提示词和请求示例写得越多模型匹配时越不会跑偏。还有一个经验注册中心里的“技能名”一定要起得像一个动词短语例如“generate_weekly_report”或“check_inventory_before_ship”。这样调度器在判断时语义上更好关联。如果技能名起得过于抽象比如“common_utils”调度模型大概率会一脸迷茫。4.2 分阶段调度先判断领域再选技能最后传参数调度智能体的逻辑我建议分成三级不要一个 prompt 同时干三件事第一级判断用户意图属于哪个领域比如“数据处理”“日程管理”“知识问答”。第二级在对应领域的技能列表里筛出候选技能并按匹配度排序。第三级为选中的技能填充参数并确认参数不缺失、不冲突。为什么要分阶段因为如果一次性让模型“判断领域选技能填参数”它极容易在后半段忘掉前半段的信息。单步骤拆解之后每一阶段只需负责一个小目标准确率明显提升也便于后期排查是哪一级出了问题。4.3 技能调用时的并发与资源竞争这块很容易翻车当多个技能在同一个智能体里并行运行时必须统一管理资源。技能本身不管资源资源管理是调度层的事。我遇到过最典型的问题是两个技能同时开启长上下文把模型请求队列堵死了最后所有技能都超时。后来我制定了三条硬性规则每个技能声明最高调用成本预算超过预算的请求排队执行。并行任务数设上限所有新增请求进入待执行队列。设置全局超时超时后统一走降级路径比如返回“当前忙请稍后再试”。这些听起来很基础但缺一个就会在日常运营中反复折腾人。5. 从调试到版本化技能生命周期里最容易踩的三个坑技能不是写完就完事了它有自己的生命周期。这一节我分享的是在调试和迭代过程中最常碰到的三个实际问题一个比一个隐蔽。5.1 第一个坑技能内部状态不一致输入参数被“污染”这种情况出现在一个技能会同时被多个任务调用的时候。比如一个“订单校验”技能既被客服流程调用又被订单导入流程调用。结果两个流程传入的参数格式不一样技能内部又没有做格式兼容导致同一个技能在两个流程下表现得像两个完全不同的技能。后来我要求所有技能在设计时都必须定义严格标准化的输入格式并在技能内部第一行就做格式归一化。这一步看似增加了一点开销却避免了大量莫名其妙的“灵异bug”。很多人在调试时只盯着某个具体请求其实根源在输入污染。5.2 第二个坑技能依赖外部服务一旦超时就把整个流程卡住技能一旦依赖外部服务就要考虑外部服务的可用性问题。曾经我负责的某个终端应用里一个技能里同时调用了搜索接口和文件读取接口如果搜索接口超时整个技能流程就卡住无法返回。现在我的处理习惯是三步超时时间从上到下递减快速失败优先所有外部调用都加熔断器连续失败到阈值后直接走降级分支技能里明确标注哪些外部依赖是主路径不能绕过的哪些可以跳过。技能设计阶段就要考虑依赖故障不然上线后只能在工单里见。5.3 第三个坑技能版本混乱线上跑的代码和本地调试的完全不一样版本管理这件事在技能数量少时真的一点也不起眼但能力一多就会失控。最典型的场景是本地调试时改了一个参数效果显著然后就直接在线上改了配置文件完全没有走版本流程结果出了问题找不到是谁改的、什么时候改的。我现在的做法非常工程化每个技能有独立的版本号并使用类似“1.2.0”这样的三段式线上只允许部署稳定版本新能力统一在测试版验证通过后再提升为稳定版本。如果一个技能版本回退必须连带回退对应依赖技能避免不兼容。技能迭代的流程最好是设计样本用例、跑测试、验证输出命中率、走版本提升流程。把这个流程固定下来之后整个技能体系才能谈得上“可持续演进”。6. “内容排期助手”案例拆解从提示词构想到五个技能串成一条流水线前面讲的都是方法论这里走一个完整案例。当初我用 agent-skills 思路重新改造了一个“内容排期助手”功能听起来不复杂根据热点事件和过往选题自动生成一周内容排期表。但它涉及的环节挺多是一个适合展示全流程的案例。6.1 整体拆解把排期这件事拆成五个技能排期看起来是“一个功能”实际上至少包含五个不同认知环节信息收集、主题判断、时间安排、格式生成、发布确认。所以我把“内容排期助手”拆成了五个技能热点事件解析技能历史内容盘点技能主题相关性判断技能排期表生成技能发布前检查技能每个技能都具备四段式结构并接入技能注册中心。整个智能体的工作就是根据用户请求一次性调度这五个技能结果自然比一个巨型 prompt 可控得多。6.2 技能一热点事件解析这个技能接收任意内容源里的新闻资讯输出结构化事件信息字段包括事件名称、爆发日期、涉及平台、核心人物或机构脱敏处理、热度趋势预测。它的核心难点在于热度评估。我在这里做了一个规则与模型混合的校验模型给出初判规则库负责兜底比如某些词出现在标题中时必须提高热度等级。这个技能看起来简单但如果没有结构化输出后面无法衔接任何下游。6.3 技能二历史内容盘点这个技能的核心职责是避免选题重复。它接收过往内容列表然后按主题聚类、按时间排序标记出哪些方向近期已经覆盖过。它其实是最被低估的环节。很多人做排期时只关心“明天发什么”完全忘了“这个内容三个月前发过”。做运营的人都知道重复感是非常影响阅读意愿的。这个技能跑完之后输出的是一份“建议避开”的选题线索而不是直接给结论。6.4 技能三主题相关性判断这个技能负责把热点事件和历史内容做相关性计算。它不只看关键词重不重合还要看语义层面是否接近以及时间窗口是否合理。当初我把这个技能的校验逻辑专门做了打磨如果一个热点事件爆发时间距今天少于一天且事件源来自正规内容源则相关性评级自动上调半级无论模型给出的原始评分是多少。这种硬规则的作用是给模型判断加一道保险。6.5 技能四排期表生成前三个技能完成后排期表生成就变成了一件“填空”的活儿把事件填入对应时间点再参考相关性判断结果填入具体内容方向。为什么把生成放在靠后的位置因为排期表本质上是一个执行决策结果它需要建立在判断充分的基础上。如果一开始就让模型直接生成排期表它很可能跳步、猜答案、自作主张。先做判断再做生成是保证稳定的关键。6.6 技能五发布前检查最后的技能是一道防弹门检查排期表里是否有重复选题、时间是否冲突、文案是否有敏感词等问题。这是个典型的“校验型技能”所有规则都写在实现里。当检查不通过时它会明确指出是哪一行、哪一个字段、违反了哪条规则而不是给一个笼统的“有问题”。这一点非常值得每一个校验类技能学习定位到具体问题才能迅速修复。6.7 联调实测改造前后差异明显改造前这个助手的排期表基本靠运气模型容易漏掉重复解、忽略热点事件的时间窗口输出格式也经常不统一。改造后五个技能串成流水线单技能失败可以单独重跑。由于每个技能都有独立校验整体输出质量一下子稳定下来。尤其是热点事件解析技能跑完后调度层就能快速判断后续流程要不要继续减少了大量无效计算。如果你正在做的智能体还停留在“一个大 prompt 包打天下”的阶段强烈建议用这种拆法重做一遍。7. 让技能体系真正运转起来的三个保障机制最后聊三个保障机制它们虽然不属于技能本体却决定了技能体系能否长期运转。7.1 技能清单需要持续更新像呵护产品一样呵护它技能清单不是建完就一劳永逸的它需要持续维护。每当业务发生变化第一步永远是先看技能清单而不是直接写新的 prompt。新需求来了先判断已有技能能不能覆盖覆盖不了再决定是新建技能还是修改现有技能。这个动作看起来普通但真正坚持下来的人不多。技能清单本质上是智能体的产品路线图你维护它的频率基本等同于你对系统的掌控程度。7.2 技能要有可观测性每一步都能被追溯有一次线上技能效果不佳排查了半天都不知道问题出在哪。后来加了完整日志和追踪链路从上到下记录了每个技能的输入输出、耗时、校验结果和模型调用情况这才定位到问题是“某个中间技能依赖的接口改了返回字段”。如果你在设计技能时还没有考虑可观测性那你的调试一定会被折磨。技能内部要做详细的日志记录记录关键输入输出、分支决策原因、调用链路 trace_id。这样每次输出异常你都能顺着链路快速定位。7.3 技能自身也要测试不只是智能体整体要测试最后给技能体系建立一个独立的测试机制不要让测试依赖整个智能体的流程。每个技能单独出测试用例集每次版本更新都能快速判断这次改动有没有破坏原有能力。标准测试集长这样一组输入、预期输出和边界情况。比如日期类技能测试就必须包括月末、年末、闰年、跨时区这些场景。这种单测式的保障能让技能体系经得起长期迭代而不崩坏。按这种方式跑下来“agent-skills”这套思路带给我最大的变化不是输出质量提升而是整个项目从“玄学”变成了“工程”。每一个能力都可受控、可追踪、可迭代、可交接。如果你正在被智能体的不确定输出折磨我建议你也别急着加 prompt 了先把自己的技能列表列出来看看。你会惊讶地发现很多问题在列清单的那一刻就已经暴露了。