Agent Note: Skill 系统——面向 agent 的渐进式指令披露
Status: implemented Archived: 2026-09-04
English | 中文
问题
agent(智能体)产品已趋同于一种 skill(技能)模式:保持请求提示词精简,仅列出可用的指令包,当模型判定某任务匹配时再加载完整正文。Codex、Claude Code、OpenCode 与 Kimi Code 在细节上各有不同,但都将发现元数据与完整指令分离,使工作区能承载可复用的行为而无需在每个轮次支付全量提示词开销。
DeepSeek Harness 使用同一原语,使项目特定的评审、插件编写和工具使用指南存放在工作区或用户的 agent 配置旁,而非硬编码到 agent loop(智能体循环)中。
决策
@deepseek-ai/dsh-skill 是纯提供方注册表(ctx.skills),@deepseek-ai/dsh-skill-filesystem 是随附的本地文件系统提供方,@deepseek-ai/dsh-tool-skill 负责持久化会话目录与面向模型的 loader 工具。dsh-base 将注册表、本地提供方和消费方作为独立配置行加载,使其各 profile 获得相同行为,同时嵌入式或远程提供方可在不修改注册表或消费方的前提下贡献 skill。每个配置行只暴露其所属包的配置。
专用的随包提供方可以贡献不可变的 skill,无需文件系统发现。交付的 CLI(命令行界面)默认将 @deepseek-ai/dsh-skill-badge 声明为禁用;启用其组合配置行,就会通过同一个注册表和消费方贡献官方徽章指令(见包约定)。
提供方插件在 apply() 期间同步注册。提供方成员资格是由直接 effect 持有的状态:注册与 dispose(资源释放)同步地使已完成的目录失效,发现操作按需读取当前提供方映射而非监听注册表变更事件。提供方目录从等待的 list() 调用返回排序后的候选项,远程提供方在此过程中执行初始化、认证和发现,同时遵守查找的 abort 信号。注册表校验每个候选项,按排名、提供方注册顺序和提供方内部顺序以先到先得方式解决同名 skill 冲突,然后按 skill 名称排序摘要以保证消费方获得确定性结果。它仅缓存已完成的目录快照,并在发现过程中提供方/运行时修订版本发生变化时重试,因此卸载操作不会将一个陈旧且不可解析的 skill 冻结到会话目录中。运行时 ctx.skills.register(...) 仍作为嵌入式进程内 skill 的便捷方式保留,使用 project 优先于 user 的优先级;runtime 保留为注册表拥有的提供方名称。
本地提供方按先到先得的排名顺序扫描 cwd 敏感的项目根目录、自定义根目录和用户根目录:项目 .dsh、项目 .agents、customSkillDirs、用户 .dsh,然后是用户 .agents。用户 .dsh/skills 扫描跳过 .system,以免系统拥有的目录被当作普通用户内容处理。本地提供方不会合成内置系统 skill;已配置的 bundled 根目录和专用提供方会提供额外 skill。
每个 skill 是带 YAML frontmatter 的 <name>/SKILL.md 或 <name>.md。name 和 description 为必填;whenToUse、metadata、disable-model-invocation 和 user-invocable 为可选。名称采用 kebab-case。调用字段会投影到类型化的嵌套策略中,具体由模型与用户独立调用决策定义;解析器会拒绝旧的驼峰拼写。YAML frontmatter 使用 yaml 包解析,而非 js-yaml 或手写解析器:yaml 是本包已声明的现代解析器,足以满足有限的 frontmatter 需求,窄解析器要么拒绝用户预期可用的合法 YAML,要么膨胀为一个未经评审的 YAML 子集。
本地 skill 的文件系统 I/O 在加载了文件系统服务时通过 ctx.fs 进行:项目根目录查找使用 resolve 和 stat 探测 .git,根目录发现使用 listDir,skill 读取使用 readText。Node 文件系统作为后备,供在不挂载 fs seam 的最小上下文中加载 dsh-skill-filesystem 时使用。缺失的根目录、不可读或格式错误的 skill 文件、以及提供方 list() 的瞬态失败均降级为警告并跳过,使一个坏源不会导致所有 agent 请求失败;格式错误的候选项仍然快速失败,因为它们违反了提供方约定。