做智能体这几年来,我最头疼的问题从来不是模型能力,而是团队里交付的“技能模块”到你手里总像拆盲盒。接口文档写得很完整,模型一调用就崩;代码在演示环境跑得飞起,换一个业务场景直接失灵。后来我们把这一类可复用的工具、提示词、接口编排统称为“技能”,用一套开放标准统一生命周期管理,内部代号就叫 Hermes Skills System。这套东西的核心其实只有两个部分:渐进式技能和 Skills Hub。前者解决“技能如何被定义、验证、成长”,后者解决“技能如何被发现、分发、沉淀”。这套方案开放给团队之后,技能复用率提了不少,今天把设计思路和落地细节完整拆出来,希望对正在折腾智能体应用的朋友有参考价值。
1. 为什么智能体需要一套“渐进式技能”标准
1.1 现在的技能交付方式,问题出在哪
大多数团队做智能体技能,本质上还是老一套:把一段工具代码封装成函数,给模型写一大段调用说明,再塞进 system prompt 里。运气好的项目,技能能跑通一两个固定流程;运气不好的,模型在几百条工具描述里反复横跳,幻觉频繁,技能互相干扰。
这里有一个很隐蔽的认知误区:很多人把技能当成“代码资产”,觉得写完了、调试通过了,它就是稳定的。实际上,技能是模型和真实世界之间的中间层。它既要被程序执行,也要被模型“阅读理解”。同一个技能,代码本身没问题,但描述语义模糊,模型就可能在错误的时机调用;输入字段太多,模型反而不会填参数;输出结构不稳定,下游解析直接报错。这些都不是纯软件工程问题,而是人机交互问题。
更麻烦的是,技能完全没有生命周期管理。一段预置脚本叫技能,一个复杂的多步骤工作流也叫技能,一个能自我纠错的外部 Agent 还叫技能。大家用同一个词,背后却是完全不同的复杂度和信任要求。没有分层,就没有办法制定统一的验证、评测和准入规则,更别提跨团队复用了。
1.2 渐进式技能到底在定义什么
“渐进式”这个词,我第一次听到的时候也以为是把技能按功能复杂程度分个级,简单功能算低级,复杂工作流算高级。真正动手设计以后才意识到,这里说的渐进式,不是按功能规模分级,而是按成熟度分级。
一个技能哪怕只做一件事,也要经历“声明 → 单步执行 → 组合运行 → 自适应优化”这几个阶段。每个阶段对接口稳定性、权限边界、可观测性、评测方式的要求完全不同。
我整理了一张表,可以直观看到成熟度阶梯:
| 成熟度 | 定义 | 典型表现 | 可验证性 |
|---|---|---|---|
| L0 声明级 | 有描述、有接口,未经充分验证 | 代码能跑通,但没人知道模型会不会正确调用 | 仅语法和 schema 校验 |
| L1 单步执行级 | 在受控环境里,一个步骤可稳定执行 | 给定标准输入,能拿到标准输出 | 单元测试 + 用例回归 |
| L2 组合运行级 | 可以和其他技能编排协作,状态可管理 | 多技能工作流稳定完成业务目标 | 端到端场景测试 + 上下文一致性测试 |
| L3 自适应优化级 | 能根据反馈自动调整行为,具备自检能力 | 出错后自我修正,动态选择执行策略 | 强化学习闭环 + 线上指标追踪 |
这套分级的价值在于,它把“技能好不好”从一个模糊感受,变成了可判断的具体标准。发布方可以对照标准自评,使用方可以根据需要的成熟度筛选技能,评测系统可以针对不同阶段采用不同深度的手段,而不是一刀切地说“跑过两遍没问题”。
提示:渐进式不是禁止复杂技能存在,而是要求复杂技能必须建立起从简单到复杂的信任阶梯。你可以在 Hub 上看到一个 L3 技能,但它最初一定是从 L0、L1 一步步长上来的。
2. 开放标准的核心设计:一份技能包的自白
2.1 技能清单与目录结构
技能标准的第一件事,是定义交付物的物理结构。我们参考了常见的包管理生态,最后采用了一个包含清单、代码、评测、文档四个部分的布局,整包称为“技能包”。
技能包目录结构大致是这样:
skill-image-batch/ ├── manifest.yaml # 技能清单,机器可读的元数据 ├── code/ │ ├── entrypoint.py # 技能入口,统一调用协议 │ └── requirements.txt ├── eval/ │ ├── cases/ # 评测用例,覆盖边界和异常 │ ├── scenarios/ # 端到端场景剧本 │ └── criteria.yaml # 评测通过标准 ├── docs/ │ ├── usage.md # 面向模型和开发者的用说明 │ └── changelog.md └── signature.sig # 签名信息和校验哈希所有内容都围绕 manifest.yaml 展开。没有清单,其他目录都只是散装文件。清单使用 YAML 而不是 JSON,原因很实际:YAML 支持注释,作者可以在字段旁边写设计说明,审查者也能留批注。对机器解析来说两种格式等价,但对人写出差率来说,YAML 门槛更低。
下面是一个精简后的技能清单示例:
apiVersion: hermes.skills/v1 kind: Skill metadata: name: image-batch-processor displayName: 图片批处理 version: 1.2.0 maturity: L2 author: 某算法团队 tags: [image, batch, thumbnail] spec: description: | 批量处理本地图片目录,支持缩放、裁剪、格式转换, 输出结果以 JSON 清单返回。 interface: inputs: - name: source_dir type: string required: true description: 待处理图片目录路径 - name: ops type: object required: true description: 处理操作定义,包含 scale/crop/convert 三种模式 outputs: - name: results type: array description: 处理结果列表,包含每张图片的状态与输出路径 permissions: scope: filesystem access: read-write sandbox: container evaluation: criteria: eval/criteria.yaml cases: eval/cases scenarios: eval/scenarios lifecycle: created: 2024-06-01 updated: 2024-12-10 status: stable2.2 接口、权限与可评价性
我见过很多技能规范,卷的地方在元数据写了一大堆,核心接口反而含糊。实际上整个标准里最不能含糊的就三样:接口契约、权限边界、可评价机制。
接口契约要回答一个实际问题:模型要能看懂这个技能什么时候该用、参数怎么填、结果怎么读。所以我们在 interface 里强制要求每个参数都写清楚类型、是否必填、语义描述。这个描述不是给人看的,是给模型看的。描述写得太抽象,模型会瞎猜;写得太具体,又会在参数组合上死板。经验是每条描述包含“允许的值范围 + 常见的错误示例”,例如“source_dir 必须是已存在的目录,如果不存在直接返回错误码,不要尝试自动创建”。这种带约束的描述,能显著减少模型在参数上的幻觉。
权限边界是所有后端服务对接时最容易绕开的一环。很多技能发布时只声明“需要读文件”,结果代码里写成递归遍历整个磁盘,甚至尝试联网下载模型文件。我们在权限声明里做了三层约束:
- scope 声明能力域:filesystem、network、runtime、database;
- access 声明操作强度:read、read-write、execute;
- sandbox 声明运行环境:process、container、vm。
发布后,Skills Hub 会按声明生成沙箱配置,实际执行环境被限制在声明范围内。声明是“只读目录”,执行时写其他路径会被拦截。这套机制先不管能不能防住恶意攻击,至少能拦住绝大多数“我没想到还有这种操作”的无心之过。
可评价性决定了技能能不能进入信任体系。每个技能必须附带 eval/criteria.yaml,里面定义清楚“通过”和“不通过”的边界。举个例子,一个图片批处理技能,评价标准不能只写“能处理图片”,而要写成“100张测试图片处理成功率不低于99%”“异常格式图片必须返回结构化错误码”“单张处理时长不超过2秒”。标准越具体,自动化评测越容易跑,技能的可信度也越高。
注意:如果你准备接入这套标准,第一条硬性要求就是给技能配置 eval 目录。没有评测标准的技能,Hub 可以收录,但只会标记为 L0,不会进入推荐列表。这不是为了卡人,而是为了给下游用户提供一致的信任预期。
2.3 版本、签名与生命周期
技能包还有一个容易被忽视但会反复出事故的东西:版本与签名。
版本号我们采用“语义化版本”的规则,主版本号代表不可兼容的接口变更,次版本号代表向后兼容的功能更新,补丁号代表内部修复。这套规则对普通软件适用,对技能更适用,因为技能的消费者有两个:程序运行时和模型上下文。接口一改,模型对工具描述的理解就得重新适应。主版本升级等于告诉大家,“你得重新评估这个技能能不能用了”,擅自变更接口但不升主版本,相当于埋雷。
签名机制解决的是来源问题。每个技能包发布前,用发布方的私钥对 manifest.yaml 和 code 目录生成签名,Skills Hub 验证公钥和签名一致之后才接受发布。这个流程做得很轻,但非常必要。技能本质上是一段要运行在别人环境里的代码,如果没有来源校验,任何人都可以发布一个同名技能来诱导安装,供应链攻击就发生在这种地方。
生命周期字段记录了技能的创建时间、更新时间、维护状态。Hub 上会展示一个技能的维护活跃度,长期未更新的技能会被标记为“维护停滞”,供使用方做风险判断。这里有个真实教训:我们内部有一个图像增强技能,曾经在 L2 阶段稳定运行很久,后来某个底层依赖踩了已知漏洞,因为技能没有声明依赖版本范围,修复整个下游系统花了很长时间。现在技能包里强制声明依赖锁文件,支持产出一个 hash 清单,任何依赖变动都要求触发版本更新。
3. Skills Hub 的落地架构:从注册到分发
3.1 注册与发现的完整链路
Skills Hub 是整个开放标准的基础设施。它解决的场景很朴素:技能包做好之后,给别人用什么途径找?找到之后怎么确认它是可信的?安装之后怎么更新和卸载?
Hub 在形态上模仿了大家熟悉的包仓库,但几个关键环节完全不同。一个技能包的“安装”不只是把代码拉到本地,还要写入模型可读取的技能描述索引,生成权限白名单,注册接口路由。这意味着 Hub 不只是文件仓库,还要负责元数据解析、兼容性检测和运行环境的配置下发。
流程上分成四步:
- 发布者通过命令行工具做本地打包和自检,生成签名,上传到 Hub;
- Hub 解析 manifest,校验 schema、权限声明、eval 目录是否存在;
- 通过机器校验后,进入人工或半自动审核;审核通过后按成熟度自动打标;
- 使用者在目标环境执行安装命令,Hub 根据目标环境返回适配版本并生成锁文件。
我规划的第一版 Hub 做成了中心化注册表加分布式缓存的混合结构。中心注册表维护技能元数据和签名,降低发现成本;各业务团队内部部署轻量缓存节点,加速安装并支持内网隔离。之后可以考虑联邦化,但第一版不建议做纯分布式,因为技能生态的核心瓶颈不是存储,而是信任和共识。中心化能更快积累审核经验,形成可信基线。
3.2 信任模型与三层审核机制
生态能不能起来,关键靠信任。Skills Hub 里我没有设计成“上传即上架”,而是做了一个三层审核模型。
第一层是机器校验。检查格式、必填字段、schema 合法性、签名有效性。这一层只能挡住工业化制造的低质量内容,挡不住精心构造的逻辑漏洞。
第二层是沙箱验证。Hub 的评测集群会按照技能声明的权限边界,在一个一次性容器里跑 eval/cases 下的测试用例。这里有个关键细节:所有评测用例也必须来自技能包本身,这存在“作者自评”的偏差。所以沙箱验证还会额外注入一组 Hub 平台生成的黑盒样例,用来验证接口契约是否诚实。比如某个技能声明了支持十种图片格式,平台会随机选一个不在作者测试目录里的畸形文件扔进去,看错误处理是否符合标准。
第三层是社区反馈。技能上线后,使用者可以上报成功率和异常率,这类运行时数据会反过来影响技能的显示排名和成熟度徽章。一个技能如果长期保持高成功率、低错误率,即使作者自己标的是 L2,平台也可以给它升到 L3。反过来,作者标了 L3 但线上频繁失败,人工审核会介入并处理降级。
这三层合起来,既避免了“系统外评审人员不懂业务,过度卡审”的问题,也避免了“作者说什么就是什么”的问题。实际操作中,第一层机器校验会在发布时实时跑完,第二层沙箱验证在三分钟内给出结果,第三层则是持续运行的。
4. 从零接入:把老技能改造成标准技能包
4.1 第一步:定义边界
前面理论讲了这么多,关键还是动手。这里分享一个实际改造案例。
我们之前有一个图像批处理能力,本质是一个 Python 脚本,接受目录路径和操作参数,把目录下所有图片处理后输出到另一个目录。旧版代码大概是函数式写法,所有逻辑混在一个文件里,异常处理比较粗暴,很多情况直接抛字符串。这种状态没法进 Hub,因为模型拿到之后既不知道参数语义,也没有可靠的错误信息可以解析。
改造第一步不是写 schema,而是想清楚边界。图像批处理这个技能,边界是什么?是“接收一个目录,处理后返回结果清单”。它不应该负责扫描磁盘找目录,不应该负责网络下载,不应该负责持久化日志。把边界收敛之后,接口定义就清楚了:
- 输入只有 source_dir 和 ops;
- 输出只有 results,每条包含文件名、状态、输出路径、错误码;
- 权限只有读源目录、写输出目录;
- 错误码需要固定枚举,例如 E001 表示输入目录不存在,E002 表示图片格式不支持。
固定错误码这件事,对普通函数来说无关紧要,但对模型消费端来说非常关键。模型拿到错误码后,可以自主决定下一步动作:是修正参数重试,还是报告用户缺少依赖。如果没有结构化错误输出,模型只能对着原始异常文本瞎猜,幻觉概率直线上升。
4.2 第二步:补评价体系
边界定好之后,下一步是把评测补起来,这是整个改造里最费时间也最有价值的工作。
我们在 eval/cases 里放了几组用例,覆盖正常场景、边界场景和异常场景:
- 正常场景:包含 JPEG、PNG、WebP 三种格式的图片各 50 张,验证转换成功率;
- 边界场景:空目录、目录中有隐藏文件、文件名带空格和 Unicode、超大分辨率图片;
- 异常场景:目录不存在、图片损坏、权限不足、磁盘空间不足。
每一类用例都会记录输入和预期输出,最终落到 criteria.yaml 里。比如“图片损坏”这条,预期输出不能是“程序崩溃”,而是返回错误码 E003,并在 results 中跳过损坏文件,继续处理其他图片。这个标准把“健壮性”从形容词变成了可自动验证的指标。
补评测体系时我建议按“优先级从高到低”的顺序来做:先补异常场景,再补边界场景,最后补正常场景。很多工程师习惯先跑主流程,跑通了就交付,导致技能上线后总是在奇葩输入上翻车。对技能来说,模型本身就擅长生成各种不按套路出牌的输入,你不在评测环节把异常兜住,模型就会在线上用随机输入帮你测。
4.3 第三步:评分与发布
评测补齐后,整个包就具备了发布条件。我们通过命令行工具做本地自检,确认 manifest 字段完整、依赖锁文件存在、eval 目录没有遗漏,然后签名上传。
上传之后,Hub 自动跑了机器校验和沙箱验证。机器校验一次性通过,但沙箱验证第一次没通过:我们的代码声明的是 read-write 权限,测试时却尝试读取源目录之外的一个缓存目录,被沙箱拦截了。问题出在代码里用了环境变量去定位临时目录,而沙箱没有声明对环境变量的读取权限。
解决方式是修改代码,把所有运行依赖的路径都收敛到显式参数,不读隐式环境变量。这个调整看起来很小,但价值很大:它让技能变得可复现、可解释。以后在别的环境部署,不会因为环境差异出现“我明明能跑,你怎么跑不了”的问题。
评分上,这个技能最终定级在 L2。原因很简单:它已经可以稳定完成单步批处理任务,也具备作为组合技能参与更大工作流的状态管理能力,但它没有自我纠错和自适应优化的机制。按照标准降一档标记为 L2,比虚标 L3 然后被打回重新走流程要划算得多。
5. 常见问题与避坑清单
5.1 五类高频问题
标准落地过程中,我整理了五类反复出现的问题,不一定覆盖所有团队,但大概率能对号入座。
第一类是 schema 越设计越重。有人往清单里塞了一大堆字段,比如计费方式、SLA、推荐模型列表、算力需求。字段多不是坏事,但如果没有配套的消费端真正使用,这些字段就是纯负担。每增加一个字段,发布者的填写成本、Hub 的校验成本、使用者的理解成本都会同步上升。我的建议是先把最小可用字段定下来,其他字段用扩展属性承载,等到确有人消费再提级。
第二类是权限声明与实际执行不一致。声明了只读,代码里改配置文件;声明了不联网,代码里偷偷拉权重。这类问题在沙箱测试里很容易被揪出来,但关键是不能只在发布时检查一次。运行环境变了,依赖版本昇级,权限行为也会变化。Hub 的锁文件和审计日志要能追踪到具体版本的权限执行记录。
第三类是版本同步问题。技能包升级之后,下游工作流的引用没有同步更新,模型还在按旧接口生成参数。这是开放生态里的老难题,没有银弹。我们的缓解手段是在 Hub 安装时生成依赖锁定清单,升级主版本必须显式执行迁移命令,不允许静默覆盖。
第四类是只重代码不重描述。很多人把精力放在实现逻辑上,description 写一句话就交差。事实上对智能体来说,描述就是技能的“产品说明书”,模型根据它来决定要不要调用。描述写不好,代码再稳定也没机会被执行。我们把描述质量纳入评测指标,要求至少包含边界条件、返回结构、常见误用场景三个部分。
第五类是评测集与真实分布脱节。作者自己攒的评测集往往太“干净”,线上真实输入千奇百怪。应对方法有两种:一是建立线上流量回放机制,把匿名化后的真实请求补充进评测集;二是引入对抗性样例库,由平台统一维护一套高难度用例,分发给所有同类型技能做横向对比。
5.2 三点实操忠告
第一,不要为了推广标准而强制所有团队立刻迁移。渐进式的标准也应该用渐进式的方式落地。先选两三个成熟度足够的技能做改造试点,跑通发布、安装、反馈闭环,再向更大范围扩散,比一刀切下命令顺利得多。
第二,重视命令行工具的使用体验。Hub 后端做得再好,发布者天天面对的也是命令行工具,工具难用,所有人都会软抵抗。自检、签名、上传、回滚这些高频操作,必须做得足够“无脑”。一个能用一条命令完成自检和上传的工具,比一份几十页的平台操作文档管用得多。
第三,把失败案例保留下来,不要清理掉。Hub 里的失败记录、降级记录、沙箱拦截记录,都是最好的调研素材。我们后来做权限评测模型时,训练数据基本都来自这类历史拦截记录。失败的样本里,信息密度往往比成功样本高得多。
最后说几句
从设计 Hermes Skills System 到现在,我最深的体会是:技能标准化这件事,技术难度不高,治理难度很高。它需要你在“约束”和“自由”之间找平衡:约束太少,标准形同虚设;约束太多,生态就会失去活力。渐进式技能和 Skills Hub 这一套组合,本质上是在尝试找一个各方都能接受的公约数。它有大量细节需要持续打磨,评测标准、信任机制、版本策略,每一项都需要跟着真实使用场景迭代。如果你也在设计类似的技能广场或者工具开放平台,我的建议是先不要纠结宏大架构,找三个真实技能,跑通一遍发布、安装、评测、反馈的闭环。闭环能转起来,标准就活了。