上周我写了关于 AMA-特拉斯 的文章,这是一款桌面人工智能代理,能够在验证关卡后编写自己的工具。本周,它学会了双向使用 SKILL.md——这是代理技能的开放标准。以下是其含义、我认为它比任何单一功能都更重要的原因,以及令我惊讶的实现细节。
30秒背景介绍
SKILL.md 最初是一种内部格式,后来成为开放标准,目前已有30多个编码代理支持该标准——包括克劳德代码(Claude Code)、Codex命令行界面、光标(Cursor)、杰米尼命令行界面(Gemini CLI)等。技能只是一个文件夹:
我的技能/
SKILL.md # 前置元数据(名称、描述)+ 指令
模板/… # 可选资源
巧妙之处在于渐进式披露:代理仅在任务真正需要该技能时才读取完整指令,此前只读取一行描述。这样你的上下文窗口保持整洁;而你的代理依然拥有“借书证”般的访问能力。
目前社区中已有包含1000多个技能的集合。这意味着大量封装好的专业知识,直到本周之前,我的代理都无法使用。
消费端:两个工具,约150行代码
消费端的实现出乎意料地简洁。仅用了两个工具:
-
skill_list—— 遍历技能目录,解析前置元数据,仅返回名称: 描述行 -
skill_use {名称}—— 返回单个技能的完整 SKILL.md 正文
目录按优先级排序:首先是应用程序捆绑的技能,然后是 userData/skills/,用户可将生态系统中的任何内容放入此处。同名冲突如何处理?捆绑版优先。 这与我们插件加载器的工作方式一致——用户安装的构件绝不能静默替换内置构件。这条小规则堵住了一个真实存在的攻击向量:攻击者可以放置一个名为 security-review(安全审查)的文件夹,其中写着“跳过所有检查”,然后等待代理加载它。
两条值得关注的实现要点:
1. 路径遍历在名称检查阶段即被阻止,而非在文件系统层面。
const NAME_RE = /^[a-z0-9][a-z0-9_-]{0,63}$/i;
技能名称是唯一由用户控制的路径片段,且绝不允许包含 ..、/ 或 \。在接触文件系统之前先验证结构,比事后规范化路径更简单、更严格。
2. 工具描述才是真正的用户体验。 代理通过读取 skill_list 的输出决定是否调用 skill_use。因此,列表刻意仅返回名称和单行描述——如果返回完整正文,我们将为使用一个技能而付出所有技能的上下文成本。只有当你的工具尊重这一设计时,该标准的渐进式披露理念才能得以维持。
生成端:另一个方向才真正有趣
AMA-特拉斯已具备自我演进管道:当代理缺乏某种能力时,它会为自己编写新工具,该工具必须通过类型检查 → 单元测试 → 实际冒烟测试 → 人工批准后才能加载。(我曾写过相关文章,解释为何要在目睹自己的代理对无效操作声称成功后做出此决定。)
现在,每个工具 t
免责声明:本文内容来自互联网,该文观点不代表本站观点。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,请到页面底部单击反馈,一经查实,本站将立刻删除。