
1. 项目背景与核心问题Agent 到底卡在了哪里做了几年大模型应用开发我最深的感受是单论对话能力现在的模型已经强得离谱可一旦想让它真正“干活”完成多步骤、跨系统、需要记忆状态的任务立刻就露馅了。要么逻辑链条断掉要么每一步都要人盯着喂上下文体感跟使唤一个记性不好的实习生似的。这也是我去年立项做agent-skills的初衷。1.1 开发 Agent 时遇到的真实现状我见过太多团队把 Agent 做成“玩具”模型收到指令调一两个 API拿到结果就结束。复杂一点的把提示词写成长篇大论塞进系统 Prompt看起来规划得井井有条实际跑起来全是幻觉——模型根本记不住那么多约束一旦任务跨度变长就开始自由发挥。更深层的问题在于“技能无法沉淀”。我最早用 LangChain 那套写应用时每个业务逻辑都散落在代码里今天写个send_email函数明天写个query_order函数每次新项目都要重新复制粘贴。更糟的是这些能力跟对话流程深度耦合模型调用的方式、参数格式、返回结构全靠约定没有任何标准化的注册和发现机制。时间一长代码越来越难维护Agent 也越来越笨——不是模型不行是你根本没给它搭好“手脚”。1.2 agent-skills 想解决的三个关键痛点做 agent-skills我不打算再糊一个演示 Demo而是想把它做成一套真正能让 Agent“长出手脚”的可复用技能框架。拆解下来核心要解决三件事第一技能标准化。每个能力都要有清晰的名字、描述、参数 Schema、执行逻辑和返回结构让模型看完描述就知道什么时候该用、怎么用。第二技能的注册与发现机制。Agent 不能靠人肉把函数写死在代码里而是要能在运行时按需加载匹配的技能库就像手机装应用一样需要什么装什么。第三技能编排与状态管理。单个技能只是零件真正的 Agent 需要把零件组装成流水线过程中要传参数、记状态、做取舍、处理异常。这套东西不搞定技能再多也是一堆散沙。我拿一个实际场景来说明。假设你要做一个“客户工单自动处理 Agent”它至少要会查订单、查库存、查物流、写回复、升级人工。那这五件事就是五个技能它们各自独立但在这个任务里要按顺序、按条件被调度起来。agent-skills 要解决的就是怎么定义这五个技能怎么让 Agent 知道什么时候调哪个以及中间出现意外怎么办。下面的内容全部围绕这条主线展开。2. 技能框架的整体设计与核心思路拆解在设计 agent-skills 时我给自己定了几条原则。与其一上来堆概念不如先明确这套体系到底长什么样。2.1 为什么选择“技能”而不是“工具”或“插件”大模型领域里工具Tool、插件Plugin、技能Skill这几个词经常混用。但我刻意选择了“技能”这个说法背后有实际考量。工具是函数级别的抽象强调的是“能被调用”插件是集成层面的概念强调的是“能装进宿主”而技能更接近“能力”的语义——它自带使用条件、适用场景、输入输出约束甚至包含内部状态的转换逻辑。用我自己的话说工具是零散的招式技能是成套的功夫。比如“发送邮件”是个工具但“处理客户催单”是个技能。后者需要查上下文、判断紧急程度、决定措辞、甚至可能升级人工。一个技能内部可能串起多个工具调用也可能自己就带了小型决策逻辑。这种粒度Agent 才能真正理解并复用。另一个重要原因是技能的抽象层级更高天然适合跨项目复用。我在项目 A 里写好的“订单状态查询技能”只要接口不变在项目 B、C 里都能直接挂载不需要改 Agent 主逻辑。2.2 技能的四层架构注册表、描述、执行体和运行时最初的版本我写得异常简陋——一个 Python 字典存函数引用一个 Prompt 列功能列表。结果模型经常选错工具参数也老传错。复盘之后我重构出四层结构这也是 agent-skills 的骨架。第一层是技能注册表Registry。这是所有技能的中枢数据库记录每个技能的名字、版本、描述、参数 Schema、依赖关系、状态属性。Agent 在做规划时首先查注册表看当前任务能匹配哪些技能。第二层是技能描述Descriptor。这是给大模型看的说明书。它决定模型能不能在正确时机选中正确的技能。写得好不好直接决定整个 Agent 的智商上限。描述里一般包含触发条件、典型用法、参数解释、返回值说明、注意事项。注意描述要写得让模型“一看就懂”但不是堆字数关键是把适用边界讲清楚。第三层是执行体Executor。这是真正干活的部分接受标准化输入调用真实 API 或业务逻辑返回结构化结果。它可以是本地函数可以是远程 HTTP 服务也可以是另一个 Agent。第四层是运行时Runtime。这层负责技能之间的上下文传递、状态快照、异常捕获和重试机制。它是 Agent 能力的“后勤部门”没有它技能再多也调度不顺。我画了个简单的数据流Model 发出规划意图 → Registry 检索候选技能 → Descriptor 指导选择 → Executor 执行动作 → 结果回传 Runtime → 更新上下文 → 模型继续下一步。这个循环就是整个体系运转的基础。2.3 设计技能时的三个关键取舍做这套框架的过程中我反复纠结过三个问题每个取舍都直接影响了最终效果。第一个取舍是技能的粒度。技能定得太粗比如“处理所有客户问题”模型根本不知道该从哪下手定得太细比如“解析字符串”“获取当前时间”也算技能注册表会膨胀到失控模型的选择负担急剧上升。我最后的经验是技能的粒度要让模型在一步决策内能说清“调它干嘛”。一个技能应恰好对应一个业务动作比如“查询订单状态”是一个技能而“执行数据库查询”就不该是技能。第二个取舍是技能之间是否允许互调。最开始我严格禁止技能内部调用别的技能想着逻辑越简单越安全结果发现很多任务被迫在 Agent 主流程里写复杂编排代码。后来我改成了允许技能互调但必须声明依赖关系运行时通过依赖注入的方式把技能句柄传给 Executor。效果很明显——复杂任务被拆得更自然代码重复也少了。第三个取舍是技能状态存哪里。很多场景需要技能保存中间状态比如“根据多轮对话内容更新工单优先级”。如果把状态全存内存进程一重启就全丢存外部数据库又增加复杂度。我最终采取的方案是每个技能自带一个可选的 State Store默认用内存快照 定期序列化落盘。这么做的原因是大部分技能其实不需要持久化状态强制做持久化反而影响性能。3. 技能定义规范让模型一看就懂的接口设计讲完架构进入最实在的部分一个技能到底怎么定义。早期我在这方面吃过太多亏现在这套规范是踩坑踩出来的。3.1 技能描述文件的字段设计与写法每个技能都有一个描述文件可以是 JSON、YAML 或 Markdown 格式最终都会转成模型友好的文本片段注入上下文。我强烈推荐 YAML可读性比 JSON 好注释也方便。一个标准的技能描述长这样伪代码示范name: query_order_status description: 根据订单编号查询订单的当前状态与物流进度。 当用户询问我的订单到哪了发货了吗订单状态时使用该技能。 该技能仅适用于查询不包含修改订单操作。 version: 1.2.0 domain: ecommerce tags: [order, logistics, query] dependencies: [] state_store: optional parameters: order_id: type: string required: true description: 订单编号通常为数字或字母组合示例ORD2024010142。 pattern: ^ORD\\d{10}$ include_logistics: type: boolean required: false default: false description: 是否同时返回物流轨迹默认 false。 returns: order_status: type: string enum: [pending, paid, shipped, delivered, cancelled] logistics_tracking: type: array description: 物流轨迹列表仅当 include_logistics 为 true 时返回。 error_cases: - code: ORDER_NOT_FOUND description: 订单不存在或无权访问。 suggestion: 请向用户确认订单编号是否正确。 - code: API_TIMEOUT description: 查询超时。 suggestion: 可以稍后重试或为用户提供客服联系电话。字段拆解一下name是技能唯一标识我用蛇形命名法全小写description前 200 字最关键模型做意图匹配时主要看这部分所以我刻意把“什么时候用”“什么时候别用”都写进去parameters里每个字段都要有description否则模型很容易传空值或臆造值。error_cases这块经常被忽略但它特别重要——模型遇到错误后能不能优雅处理全看这里有没有引导。3.2 参数 Schema 中的类型约束与枚举提示写参数时最容易犯的错是只写类型不写取值范围。你要知道模型在生成参数时是“猜”的你不给它边界它就瞎猜。我的经验是所有参数必须写明以下几项中的至少三项type、required、default、description、pattern、enum。举个例子用户只说“查一下单号 20240101”模型可能分不清这个数字是订单号还是日期。你需要在description里写清楚“订单编号通常以 ORD 开头遇到纯数字时可先通过上下文判断无法确定时向用户追问”。这种提示带虽然朴素但对模型的实际表现提升是巨大的。对于枚举类型一定要给全所有可能值。我遇到过模型硬是把“cancelled”拼成“canceled”的查错半天才发现在enum里漏了一个 d。这种低级错误定义严谨了就不会发生。3.3 灵活使用参数的 required 策略我建议把参数分成三个档位必须提供、可选提供、上下文自动填充。必须提供的参数模型没有就要追问用户可选提供的参数模型可以根据上下文推断上下文自动填充的参数则隐藏在 Agent 运行时的内部状态里模型不需要感知。比如查询订单状态时如果 Agent 已经在对话里确认过用户身份user_id就不需要模型操心运行时自动塞进去。这套策略能明显减少模型的多余追问让交互更顺滑。但有个前提——你自己要清楚哪些字段真的能自动拿到不要在生产环境里想当然。测试时我曾经以为 Session 里一定有user_id结果上线后发现三分之一请求拿不到整个 Agent 直接降级成“查无此人”。4. 技能注册表与动态发现机制让 Agent 学会按需选型技能定义好之后要注册进系统让 Agent 在规划阶段能“看见”它们。这里有很多细节直接关系到系统的扩展性和稳定性。4.1 注册表的数据结构与索引策略我用 Redis 作为注册表的存储层原因很简单技能描述是读多写少的典型场景而且需要毫秒级查询延迟Redis 的 Hash 结构天然适合存“技能名 → 描述信息”的映射。具体存储设计每个技能描述序列化成一个 JSON 字符串作为 Hash 的一个 field 存进去。同时建几个索引集合比如按domain分域索引、按tags打标索引、按version做版本链。查询时优先走索引缩小候选集再拉出完整描述做精排。这里要说一个我踩过的坑切忌把全部技能的描述一次性塞进 Prompt。模型对超长上下文的注意力会衰减技能超过十个之后就开始乱选。我的做法是两层检索先用轻量的关键词匹配技能名 标签 描述的摘要向量定位候选技能数量控制在 3~5 个再把这几个技能的完整描述展开给模型。这样既保证了准召率又控制了 Prompt 长度。4.2 技能加载的时机与上下文预算管理技能不是注册了就自动加载加载策略直接影响模型的决策质量。我采用的是“预加载 按需加载”组合方案。预加载在会话开始阶段把高频技能加载进上下文。比如电商客服 Agentquery_order_status、cancel_order、initiate_return这几个是必加载项因为大多数会话都会用到。按需加载模型在规划阶段发现某个低频技能的摘要被触发时再展开完整描述。上下文预算要提前规划好。假设当前模型的上下文窗口是 128K tokens我会给“技能描述区”预留最多 30% 的预算绝不让技能描述挤占对话历史和中间推理的空间。设计了一套简单的预算机制预加载技能各 200~400 tokens按需加载技能各 800~1500 tokens超过预算就触发注册表淘汰策略把不常用的技能先摘出去。4.3 版本管理与灰度发布Agent 技能是活的业务代码肯定要迭代。我在注册表里加了一个版本字段支持同一技能多版本共存运行时通过?versionv1.2.0或?versionlatest指定使用哪个版本。灰度发布流程是新版本先在小流量会话中使用跑一段时间观察调用成功率和用户反馈再逐步放量。这里有个非常容易出问题的点同一技能不同版本之间必须保证参数兼容。模型是记不住你昨天刚改的参数的如果我昨天定义了order_id今天改成orderId那么所有还没升级上下文的会话都会报错。我的对策是参数名改动必须同步改版本号并做 3.1 那种完整的参数映射兼容层。改参数名这种操作至少要保留旧名称作为别名再过渡两个版本再删。5. 技能编排与运行时调度多技能协作的实战推演技能定义得再规范真正测出功力的是编排层。这一步要把模型想法落地成可执行动作序列还要处理各种中途幺蛾子。5.1 编排引擎的两种模式顺序执行与状态机早期我图省事所有任务都写成顺序调用链step1 调技能 A拿结果step2 调技能 B用 A 的结果做入参。遇到分支任务就傻眼了比如“如果订单已发货就不能申请改地址要推荐联系物流”顺序链写出来像一大坨面条代码。后来重构时引入了轻量状态机。设计了一个workflow描述文件用states和transitions来定义步骤及跳转条件。每个步骤代表一次技能调用跳转条件可以是“上一步结果的某个字段等于什么值”“某参数是否为空”“用户是否确认了某个选项”。这样分支、循环、重试都能自然表达。状态机的核心是让 Agent 的每一步都有明确的“当前状态”。比如初始状态是collecting_intent识别出用户要退换货就跳到checking_order,订单状态合法再跳到initiating_return不合法就跳到escalate_to_human。每跳转一步运行时都会更新状态快照异常时能从容回滚到上一个稳定状态。5.2 上下文传递不要让模型猜上一轮发生了什么编排中最容易翻车的就是上下文传递。模型在生成下一次技能调用时需要知道上一次调用的结果但不可能把整个历史都原样交给它信息太多噪声也大。我实现了一个ContextBuffer机制。每次技能返回结果后运行时把结果按结构化摘要“注入”到上下文中——不是存原始 JSON而是由该技能定义里预先写好的context_summary模板生成一段人类可读的文本。比如查询订单技能返回了大量物流轨迹上下文里只留存“订单已签收签收时间为 2024-01-15 14:20包裹完好”这几十个字。模型看这段摘要就已经足够决策了。这里有个细节上下文注入位置要稳定。我固定在每次技能调用前的“最新工具结果”区域插入并保证旧的摘要会被新摘要覆盖不累积、不膨胀。否则模型会被越来越长的历史摘要带偏注意力发散。5.3 错误重试与降级策略的工程实现技能调用不可能永远成功网络抖动、接口限流、参数校验失败都是家常便饭。Agent 的错误处理要比普通后端服务更复杂因为模型必须理解失败原因并给出用户可以接受的反馈。我实现了三级重试策略第一级框架自动重试。针对网络超时、瞬时 5xx 这类可重试错误自动重试最多 2 次间隔指数退避。第二级模型感知重试。如果重试仍失败框架把error_cases里的提示交给模型模型可以调整入参再次调用。比如参数格式不对模型可以从错误信息中提取正确格式后重新生成。第三级降级或转人工。若连续三次失败模型根据技能描述里的suggestion字段给出兜底话术或者调用escalate_to_human技能移交人工客服。这套策略上线后工单系统的技能调用成功率从 82% 提升到 97%大部分损失都靠框架自动修正兜住了。实践心得很明确Agent 的错误处理不能只靠模型随机应变框架要把错误分类和决策路径先铺好。5.4 长任务的中断恢复状态快照的意义有一类任务是真正折磨人的比如“帮我对比三家供应商的报价并生成推荐报告”。这需要调用多个技能耗时可能几分钟甚至更久。期间一旦模型进程崩溃或用户中途切走所有进度全丢。我用状态快照机制解决这个问题。每个工作流的每个状态转换都会记一个checkpoint包含当前步骤、已完成步骤、已收集的参数片段、上下文摘要等。当用户回来说“继续刚才那个任务”运行时从最近的 checkpoint 恢复不需要重新开始。实现上我用 SQLite 存 checkpoint每条记录带 session_id、workflow_id、state_name、payload、created_at。恢复时直接按 session_id 拉最新记录重放上下文然后让模型从断点继续编排。这里需要注意重放时一定要告诉模型“你已经完成了什么”否则模型会重复执行已经做过的步骤用户体验极差。6. 从零构建一个技能工单自动处理全程实录讲到这里不如直接走一遍完整的技能构建实战。我以“客户工单自动处理 Agent”为例把从定义技能到调试完成的全程记录下来。6.1 需求拆分把工单流程拆成可复用技能客户工单处理的需求一句话自动接收用户的售后请求判断类型能自助处理就自助处理不能就转人工。但我不会直接给 Agent 写一个“智能工单处理”大技能而是拆成五个独立技能categorize_query把用户问题归类为退款、退换货、物流查询、技术咨询等。query_order_status查订单状态用于判断订单是否满足售后条件。initiate_refund发起退款需要订单号、退款金额、退款原因。escalate_to_human转人工附带上下文摘要和推荐处理建议。send_notification给用户发送处理结果通知。这五个技能相互独立但通过工作流组合出完整的售后服务闭环。为什么拆这么细因为退款与退货的审批逻辑不同物流查询和订单查询的字段重叠度也不同。每个技能都能被其他场景复用比如查询订单在售前咨询中也会用到。6.2 每个技能的描述、参数与返回结构规范以initiate_refund为例描述文件要和真实的财务系统安全接轨name: initiate_refund description: 为用户的订单发起退款申请。 仅当用户明确要求退款且订单状态允许退款时使用。 发起前必须已确认订单编号且校验过订单归属权。 如果退款金额超过 1000 元或订单超过 7 天需要升级人工处理。 version: 1.0.0 domain: ecommerce state_store: required parameters: order_id: type: string required: true description: 订单编号以 ORD 开头共 13 位字符。 pattern: ^ORD\\d{10}$ refund_amount: type: number required: true description: 退款金额单位元最多两位小数。 minimum: 0 maximum: 5000 reason_code: type: string required: true enum: [not_received, damaged, wrong_item, quality_issue, change_mind] refund_channel: type: string required: false default: original enum: [original, balance, alipay, wechat] returns: refund_id: type: string description: 退款单号用于后续查询例如 RFD20240115001。 estimated_arrival: type: string description: 预计原路退回时间格式为 YYYY-MM-DD。 error_cases: - code: ORDER_NOT_REFUNDABLE description: 订单不在可退款状态。 suggestion: 检查订单状态告知用户当前状态为何无法退款。 - code: AMOUNT_EXCEEDS_LIMIT description: 退款金额超过单笔限额。 suggestion: 升级人工客服处理。看到description里的限定条款了吗我把“超过 1000 元要转人工”“超过 7 天要转人工”这类业务规则直接写进技能描述让模型在调用技能前自行判断是否合规。这比在代码里堆if要灵活得多因为模型的判断可以结合对话上下文里更丰富的情绪和意图信息。6.3 工作流定义从语言指令到技能调用序列用户说一句“我买的手机壳颜色不对想退”模型需要依次走这些步骤调用categorize_query识别出“退换货意图”。调用query_order_status确认订单最近签收时间、状态。若订单状态是“已签收”且签收时间在 7 天内进入initiate_refund否则跳转escalate_to_human。退款发起成功后调用send_notification通知用户。这条链路对应的工作流定义节选如下workflow: refund_process start_state: collect_intent states: - name: collect_intent execute: categorize_query transitions: - condition: {category} after_sale_refund target: check_order_status - condition: {category} pre_sale_consult target: handle_consultation - name: check_order_status execute: query_order_status transitions: - condition: {order_status} received {days_since_received} 7 target: initiate_refund - condition: {order_status} ! received || {days_since_received} 7 target: escalate_to_human - name: initiate_refund execute: initiate_refund transitions: - condition: {refund_result} success target: notify_user - condition: {refund_result} AMOUNT_EXCEEDS_LIMIT target: escalate_to_human - name: escalate_to_human execute: escalate_to_human transitions: []这套定义配合运行时解释器就能把模型“一句话指令”翻译成可执行的多技能协作流程。实际使用时条件里那个{days_since_received}字段由query_order_status技能的context_summary模板生成运行时自动替换成真实数值模型不需要自己算日期差异。6.4 调试时的 Prompt 模板与上下文组织实现这个 Agent 时系统 Prompt 的组织也有讲究。我不会把所有技能细节都写进系统提示而是让系统提示只负责“定义角色 解释规则 引导调用流程”技能信息则动态注入。系统提示里需要强调的核心规则只有几条只使用已列出的技能完成用户请求不要编造或猜测不存在的技能。在调用技能前先确认是否缺少必要参数缺少时优先向用户追问。技能调用失败时阅读错误信息按建议调整参数或转人工。每次技能调用只做“当前最需要的一步”不要试图一次调用多个技能。最后一条尤其重要。我见过模型一个回合内连续调用四五个技能的结果中间某步参数错了整个链条全部作废。强制“一次一步”之后虽然交互轮次变多了但成功率显著上升。7. 常见问题与排查技巧实录那些反直觉的坑这部分我要专门展开把我在开发和测试过程中反复踩到的坑整理成速查。这些问题在官方文档里基本找不到答案但每一类都足以让项目陷入停滞。7.1 模型老是选错技能优先级怎么调现象用户问“能不能帮我看看物流”模型却调了“订单查询”技能而不是“物流查询”技能。表面看是描述写得不够清楚实际排查后发现是技能间存在描述“语义打架”。我见过最典型的场景两个技能的description里都包含“订单”这个词模型在意图匹配时出现混淆。解决思路不是把描述改得更长而是给技能加“优先级”和“排他条件”。在注册表里加一个priority字段数值越小越优先被选中。同时要求每个技能的描述里声明“本技能不处理什么”——这是很多人都忽略的负向约束。比如物流查询的 description 末尾加一句“本技能仅提供物流轨迹与配送进度不处理订单金额、退款等问题”。别小看这一句负向声明实测能把技能选择准确率从 89% 拉到 96%。7.2 参数传递错乱模型把上一轮的输出当入参这是让我最头疼的问题之一。Agent 连续调用两个技能时模型常常把第一个技能返回里的某个字段直接当成第二个技能的入参但字段名对不上。排查思路仔细观察运行时日志里的这次调用入参。我发现很多参数错乱是因为返回结构太长模型在上下文里“找错字段”。解决方案是精简返回结构。不相关字段不要全塞给模型技能返回前加一个response_filter只保留模型决策需要的字段和摘要。另外我强制每个技能在返回时都带一个_description字段用一句话概括本次返回内容。比如“订单已签收签收时间 2024-01-15”。模型读摘要比读结构化 JSON 更不容易出错这是一个微小的改动但收益非常可观。7.3 上下文膨胀导致模型“遗忘”怎么处理长会话里技能调用记录一多上下文开始膨胀模型渐渐只看最近的调用忘了前面已经确认的信息。比如用户先说了地址信息五个技能调用之后模型开始问用户“请问收货地址是什么”——这是极其尴尬也极其常见的问题。这个问题不能靠加长上下文窗口解决因为窗口越大噪声越大。我的方案是维护一个“持久化事实清单”把对话中用户明确提供的关键信息真实姓名、地址、订单号、期望时间抽离到独立存储区每次触发新技能前把清单摘要固定注入到上下文顶部。模型在任何步骤都能看到这份摘要自然不会再忘。抽取事实的操作我用的是一个小提示词任务不是正则匹配。正则只能处理“下单”“地址是”这类显式表达面对“我那个在某某路的房子”这种隐含表达就失效了。模型抽取则能结合语义理解准确率高得多。7.4 技能反复失败是重试还是彻底放弃无脑重试是最糟糕的策略用户感受极其煎熬。如果一个技能连续失败三次每次耗时 10 秒用户要等半分钟才能听到“转人工”的反馈这个体验基本算废了。我的策略是给不同错误码配置不同重试上限。网络超时类错误可以重试 3 次参数校验错误重试 2 次业务规则拒绝比如订单不可退款则完全不重试直接让模型读取元信逻辑后向用户解释。另外重试间隔不能太激进首次失败后等 1 秒第二次 3 秒第三次 8 秒指数退避。如果应用要求实时响应那干脆第一重试直接跳过立即降级转人工。还有一个细节重试时模型是否参与修正要视错误类型而定。网络错误是环境问题模型修正参数也没用不该打扰模型参数错误则必须让模型看看错误提示调整入参后再调用。分类处理而不是一刀切全都交给框架或全都交给模型。7.5 技能库越来越大选型性能下降怎么办技能数量超过 50 个时即使两层检索模型偶尔还是会选错。尤其在两个技能描述相似度很高的情况下。我的应对方案分三步第一步定期对技能描述做向量化建立 embedding 索引。查询时先把用户意图做向量检索召回最相似的 10 个技能再做精排。这一步能显著减少语义干扰。第二步对同类技能做“分组折叠”。比如“查询订单”“查询物流”“查询退款进度”三个技能折叠成一个“查询服务”技能内部再根据业务参数分流。这样描述更集中模型选择压力更小。注意折叠后的技能描述要清楚说明二级分流规则。第三步给高频场景配置“推荐技能路径”。比如工单处理这类高频场景直接在会话开始时就预置整套工作流不让模型从零规划。预置路径相当于给模型配了股骨它只需要做局部决策容错率大幅提高。8. 聊聊后续扩展从单机技能到组织级能力沉淀agent-skills 这个项目目前已经跑在我自己的几个业务场景里但我的规划远没有止步于当前的“技能注册 编排调度”。实际上日常维护中我发现了几条值得继续深入的方向这里一并分享。8.1 技能质量评估需要一套自动化度量指标技能写得再好也会在实际调用中暴露问题——调用成功率低、参数错误率高、用户反馈差。目前我的做法是给每个技能记录一份运行指标调用次数、成功率、平均耗时、平均修正次数、降级率。每周跑来一份榜单把明显有问题的技能捞出来重新打磨描述或修参数 Schema。指标里我比较看重“平均修正次数”这个数字。它指每次调用中模型第一次生成的参数有多少比例需要被框架自动修正。修正次数高说明参数 Schema 和描述对模型不够友好需要优化。这个指标比成功率迟钝但更能反映设计质量。8.2 多 Agent 协作时的技能互借单 Agent 能承载的技能有限但一个组织内的技能库完全可以做到共享。下一步我想在 agent-skills 上做一个“技能市场”模式让不同业务线的 Agent 按权限互相挂载、发布技能。比如客服 Agent 可以借用售后 Agent 的“退款进度查询”技能无需重复实现。这需要额外解决权限控制和数据隔离问题。技能在跨 Agent 调用时业务数据的归属、敏感字段的脱敏都是必须想清楚的边界。我在实现时准备引入一个技能代理层所有跨 Agent 调用都走代理校验权限、记录审计日志、做字段级脱敏不允许让模型直接触达对方系统的底层接口。8.3 与我个人的真实体会整个项目开发下来我最深的体会有两点。一是 Agent 的智能程度并不只取决于模型选择还取决于你给它搭建的“脚手架”。把技能定义清楚、注册表搞对、编排层做稳即使是相对弱一些的模型也能干出像样的活。反之模型再强技能描述一团糟照样把任务做成一锅粥。二是技能的复用收益是长期且复利的。我最早搭好的几个通用技能查订单、查库存、发通知现在已经在三个不同项目里重复使用。每次新项目启动技能注册表里拖着这些存量能力产品上线速度肉眼可见地快。这大概就是沉淀的价值——开始慢后期越跑越快。如果你也在做 Agent 类应用我真心建议别把所有逻辑塞进 Prompt 里。花时间把技能层搭起来短期看是费工夫长期看是省下一整个团队的重复劳动。这套东西不需要一次到位从一个最简单的高频技能开始注册跑通流程再逐步扩充比憋大招稳妥得多。