agent-skills-spec — 本课题摘录
读了哪几篇: 01-spec-format(格式规范)、03-client-integration(客户端集成生命周期)。
其余两篇(参考实现走读、创作经验与边界)本轮没读。
这一家在本课题里回答的是:"工具/能力清单怎么进上下文,怎么不撑爆它"。
它对本课题回答了什么
决定一:三层加载 —— 让"挂很多"和"常驻很小"同时成立
这是整个格式的设计目的,它自己这么说的。
| 层 | 加载什么 | 何时 | token 量级 |
|---|---|---|---|
| ① 元数据 | 名字 + 一句描述 | 启动时,所有能力都加载 | 每个约 100 |
| ② 指令 | 整篇正文 | 被激活时 | 建议少于 5000 |
| ③ 资源 | 脚本 / 参考文档 / 素材 | 正文里点名用到时 | 视情况 |
(依据:协议库 · Agent Skills · SKILL.md 格式规范 —— 渐进式披露三层——tier1 所有 skill 的 name+description(约 100 token/个)启动时全加载、tier2 被激活时才加载整篇正文(建议<5000)、tier3 正文点名时才加载 scripts/references/assets)
从上往下是"越来越贵、越来越晚加载"。 第一层给所有能力付一笔小钱让模型"知道有什么";只有被选中的升级到第二层;第二层里被点名的文件才升级到第三层。
这条对本课题的意义:它给了"工具太多怎么办"一个跟 cherry-studio(折叠成元工具)、qwen-code(按需塞 schema)不同的第三种答案—— 不是把工具藏起来,而是把工具的"描述"和"正文"分层。 而且这个分层是格式层面的,不是运行时技巧。
这也解释了为什么描述必须精准、正文必须短、引用文件必须浅:每一层都是为了把贵的内容推迟到真正需要那一刻。
引用文件要保持"离主文件一层深",别搞深层嵌套引用链。
决定二:选哪个能力,靠模型自己读目录判断
绝大多数实现不在框架侧做关键词匹配,而是让模型读完目录自己决定。 两种落地:
| 方式 | 说明 |
|---|---|
| 直接读文件 | 模型用标准的读文件工具去读,零额外基础设施 |
| 专用激活工具 | 注册一个"激活某能力"的工具返回内容。模型不能直接读文件时必需 |
用专用工具时有一条建议:把工具那个参数的取值约束成合法名字的枚举,防模型瞎编。 (依据:协议库 · Agent Skills · 客户端集成生命周期 —— 激活主要靠模型自己读目录判断,两种落地是 file-read 与专用 activate_skill 工具;建议把工具的 name 参数约束成合法 skill 名的 enum 防模型瞎编)
一条很实的过滤规则:被禁用、无权限、或选择退出的能力,直接不列进目录——别列出来再在激活时拦,免得模型白白浪费一个回合。 (依据:协议库 · Agent Skills · 客户端集成生命周期 —— 被禁用/无权限/选择退出模型激活的 skill 直接不列进目录,而不是列出来再在激活时拦,免得模型白白浪费回合)
这条泛化到工具上就是:不能用的工具不该出现在清单里。 跟 deepagents 的"不支持的工具不能只报错,还得从清单里消失"是同一条,理由也一样:模型看见了就会用。
目录清单里带一个"它在哪"的字段,双重作用:既让模型能去读,又给它解析相对路径的基准。
最阴险的失败:防压缩
这条它单列成一节,而且措辞很重。
如果 agent 会在上下文满时截断或摘要旧消息,必须把能力指令豁免出去。
理由:能力指令是"持久行为指引",中途被压没不会报错,模型继续跑但悄悄丢了专长——这是最阴险的失败。 (依据:协议库 · Agent Skills · 客户端集成生命周期 —— 上下文满时截断/摘要要把 skill 内容豁免出去,因为 skill 指令是持久行为指引、中途被压没不会报错,模型继续跑但悄悄丢了专长,是最阴险的失败;可用结构化标签识别并保护)
这条要抄进配方,而且要抄成一条硬规则: 凡是"持久行为指引"性质的内容(系统提示、工具清单、能力说明),压缩时必须整块豁免。 我们前面看到 headroom 的"只改活区"、whale 的"不可变前缀"、agentscope 的"配对不拆散"——都在讲同一件事:压缩不能碰的那部分,得先划出来。
配套的两条:
- 去重: 跟踪本会话已激活的能力,重复激活就跳过,避免同一指令在上下文里出现多份;
- 子会话委派(可选): 把能力放进独立子会话跑,完事只把摘要带回主对话。
一条安全边界:项目级内容需要信任门槛
项目级能力来自"正在处理的仓库",可能是刚克隆的不可信开源项目。
规范建议:把项目级能力的加载挂在"用户已信任该目录"的检查上。 (依据:协议库 · Agent Skills · 客户端集成生命周期 —— 项目级 skill 来自正在处理的仓库可能不可信,规范建议把加载挂在「用户已信任该目录」的检查上,否则恶意仓库能往 agent 上下文里静默注入指令)
否则一个恶意仓库就能往 agent 上下文里静默注入指令——这是"可执行指令载体"的天然攻击面。
跟 openai-model-spec 的"工具输出无权威"、browseros 的"外部内容用随机标记围起来"是同一条线上的三个位置: 模型上下文里凡是来自外部的东西,都要先回答"它有多大权力"。
格式本身很小
最小单位是一个目录,里面至少有一个说明文件;元数据只有两个字段必填:名字和描述。
三个可选目录各有分工:脚本(直接跑)、参考文档(按需读)、素材(用到时)。
它没回答什么
- 循环怎么写——它规定的是能力的封装格式,不是运行时。
- 工具调用怎么解析——不在它的范围。
- 停止条件——不在它的范围。
坑与代价
- "让模型自己从目录里挑"的前提是描述写得准。 描述是唯一常驻的信息,它写不好,这个能力就永远不会被选中,而且不会报错。
- 重名冲突要有确定优先级。 通行约定是项目级压用户级;同级冲突选一个规则保持一致,并打警告告诉用户某个被遮蔽了。
这条泛化:凡是"多来源合并成一份清单",都要定优先级,而且遮蔽要可见。
- 扫描要设上限。 跳过版本控制目录和依赖目录,设深度与数量上限防失控扫描。
判断(无锚): 我们的最小原型工具是写死的,这一整套暂时用不上。但**"三层加载"和"防压缩豁免"两条现在就该记进配方**——它们跟工具是不是文件无关。 如果错,会错在: 如果第一版工具就超过十个、每个都要一段长说明,那三层加载现在就得上,否则系统提示会先撑爆。