法不净空,觉无性也。

第6章 三分架构——Tool、Skill、Capability

2026.07.29

Tool、Skill、Capability——三种不同的能力增长机制。不是一种,不是四种,恰好三种。


模式层

6.1 三种基本模式

Agent 的能力增长不是一维的。一个 agent 可以学习新的知识,可以掌握新的方法,可以长出新的执行能力。但三种不同的"增长"需要三种不同的机制——不能用一个机制覆盖所有场景。

三种模式之间的关系和交互流程如下:

graph TB
    subgraph "Tool(编译时固定)"
        T_RF[read_file]
        T_WF[write_file]
        T_RC[run_command]
        T_GB[glob / grep]
        T_CT[commit]
        T_PL[plan / milestone]
        T_RV[review]
        T_GN[generate_*]
        T_AG[agent]
    end

    subgraph "Skill(注入式知识)"
        SK_DIR[skills/ 目录]
        SK_SCAN[Registry 扫描]
        SK_INJ[注入 system prompt]
        SK_USE[use_skill<br/>按需激活]
        SK_PR[prompts/ 草稿层]
    end

    subgraph "Capability(可执行产物)"
        CA_DIR[capabilities/ 目录]
        CA_MAN[manifest<br/>Environment × Lifecycle]
        CA_GEN[generate_capability<br/>write_file 级]
        CA_RUN[run_capability<br/>权限检查]
        CA_SHL[Shell 执行]
        CA_WASM[Wasm 执行]
        CA_DOCK[Docker 执行]
    end

    T_RF -->|Permission::None| EXEC[工具执行]
    T_WF -->|Permission::Ask| PERM[权限检查]
    T_RC -->|Permission::Ask| PERM
    T_CT -->|Permission::Ask| PERM

    SK_DIR --> SK_SCAN
    SK_SCAN --> SK_INJ
    SK_USE --> SK_INJ
    SK_PR -->|promote_prompt| SK_DIR

    CA_DIR --> CA_RUN
    CA_GEN -->|写文件| CA_DIR
    CA_RUN --> PERM
    PERM -->|通过| CA_SHL
    PERM -->|通过| CA_WASM
    PERM -->|通过| CA_DOCK

    style T_RF fill:#e8f5e9
    style T_WF fill:#e8f5e9
    style T_RC fill:#e8f5e9
    style SK_DIR fill:#fff3e0
    style SK_INJ fill:#fff3e0
    style CA_DIR fill:#f3e5f5
    style CA_RUN fill:#f3e5f5
    style PERM fill:#fce4ec

Tool:编译时固定。

Tool 是 agent 天生就会的东西——代码写死的、编译进二进制的、运行时不可增删的原语。read_filewrite_filerun_commandglob——这些是 agent 能力的原子操作。

Tool 的关键特性是不可伪造性。你不能通过对话注入一个假工具。不能通过写一个 .md 文件就创造一个新的 run_command。Agent 手里的工具集是确定的、可枚举的、可审计的。你可以在二进制中数出 26 个工具,每一个都有完整的实现和测试。

Tool 的安全隐含是:信任来自编译时。 编译器和类型系统保证了工具的实现不会在运行时被篡改。你不用担心 agent 突然多了一个不该有的工具。

Tool 的局限是:它们不学习。 工具的数量和功能在编译时确定,运行时不能增删。要给 agent 增加新的原子操作,必须改代码、编译、部署。

Skill:注入式知识。

Skill 是 agent 的程序性知识——存在 skills/ 目录下的纯文本 Markdown 文件。每个文件是一套方法论:代码审查步骤、调试流程、工作计划方法。

Skill 的关键特性是注入式。它不是 agent 天生的知识——它是从文件读进来的。Agent 在启动时通过 Registry 加载 skills/ 目录下的所有文件,内容拼入 system prompt。新增一个 Skill 文件,agent 下次 turn 就多了一份方法论。

Skill 的安全隐含是:信任来自文件系统。 Skill 的内容是纯文本,不包含可执行代码。写入 skills/ 目录的文件最多改变 agent 的推理路径,不能改变 agent 的实际操作能力。

Skill 的局限是:它们不执行。 Skill 只能告诉 agent "怎么做",不能给它"做什么新的事"的执行能力。一个 Skill 可以规定代码审查的步骤,但不能执行审查——执行需要 Capability。

Capability:可执行产物。

Capability 是 agent 写的可执行代码——存在 capabilities/ 目录下,附带一个 manifest 声明环境和生命周期。

Capability 的关键特性是可执行性。它不是知识,是代码。agent 用 generate_capability 写一段代码和 manifest,用 run_capability 执行它。执行环境根据 manifest 的声明路由到 Shell / Wasm / Docker 后端。

Capability 的安全隐含是:信任来自执行闸门。 generate_capability 只是写文件(write_file 级权限),真正的闸门在 run_capability(触发权限检查)。写廉价、执行昂贵——这个原则贯穿了整个三分架构。

Capability 的局限是:它们需要环境。 Capability 的执行依赖声明环境是否可用。如果 Docker 不可用,声明 Docker 的 Capability 无法执行。

维度ToolSkillCapability
修改时机编译时运行时运行时
内容形式Rust 代码Markdown代码 + manifest
安全隐含不可伪造改变推理路径改变执行能力
审计追踪看二进制看 git log看 git log + 执行记录

6.2 为什么恰好三分

三分不是架构师的设计洁癖——它是三个不同的安全边界催生的自然分类。

从安全边界推导:

  • 编译时安全需要一个不可伪造的原语层 → Tool
  • 注入安全需要一个不执行代码的知识层 → Skill
  • 执行安全需要一个带权限闸门的执行层 → Capability

每一层对应一个不同的"信任如何建立"的问题。Tool 的信任来自编译器和类型系统。Skill 的信任来自文件系统的只读性(文件不会自己变成代码)。Capability 的信任来自执行闸门(写文件不触发权限检查、执行文件触发)。

少于三分:

  • 只有 Tool:agent 无法学习新知识。每次遇到同样的问题,它都要从头思考。没有地方存放"这个项目的编码偏好"、"这个团队的首选方案"
  • 只有 Tool + Skill:agent 可以学习和思考,但学到的知识不能变成可执行的能力。如果 agent 发现"每次部署都需要这几步",它不能把它写成脚本然后复用

多于三分:

理论上可以增加第四类——比如"可配置的 Tool"(运行时加载的插件)、"动态 Skill"(从网络远程加载的知识)等。但每增加一个分类,就增加了一个"这个新能力应该归哪一类"的判断边界。三分恰好是"一个人能用手跟踪所有类别"的上限。当一个新的能力增长需求出现时,绝大多数情况下可以用三分框架找到归属:

  • 需要新的原子操作 → 加 Tool(需要编译)
  • 需要新的决策方法 → 写 Skill(需要注入)
  • 需要新的可执行能力 → 生成 Capability(需要闸门)

如果不在三分中——那说明这个能力可能不应该由 agent 自己管理。

6.3 三分之外的草稿层

三分之外还有一个"准分类":Prompt 草稿层。

prompts/ 目录存放 Skill 的草稿态。它的存在是因为从"知识是 agent 临时生成的"到"知识成为正式 Skill"之间需要中间状态。

成熟度模型:

消息(临时) → Prompt 草稿(一次使用,prompts/) → Skill(正式化,skills/) → 常驻(注入 system prompt)
  • 消息:agent 在对话中生成的知识,一次使用,不持久
  • Prompt 草稿:agent 用 generate_prompt 写入 prompts/ 的草稿。通过 use_skill 按需激活一次,不会随启动自动注入
  • Skill:通过 promote_prompt 从草稿晋升为正式 Skill。从 prompts/ 移动到 skills/,启动时自动注入
  • 常驻(注入 system prompt):Skill 被标记为"高频使用",在 system prompt 中永久存在

每个晋升步骤都有明确的工具操作。generate_promptpromote_prompt → 自动注入。没有"随口说了一句话就变成永久行为"的隐式升级。

草稿层不是第四类——它是 Skill 的"未成熟状态"。草稿和正式 Skill 共享同一个工具路径(use_skill),区别在于加载时机(按需 vs 自动)。


案例层

6.4 Registry 扫描与激活流程

Registry 是三分架构的文件系统接口。它负责扫描、索引和注入三类能力。

struct Registry {
    skills: HashMap<Name, SkillEntry>,      // skills/ 下的正式 Skill
    prompts: HashMap<Name, PromptEntry>,    // prompts/ 下的草稿
    capabilities: HashMap<Name, CapabilityEntry>, // capabilities/ 下的 Capability
}

enum RegistrySource {
    Skill { path: PathBuf, promoted: bool },
    Prompt { path: PathBuf, created_at: Instant },
    Capability { path: PathBuf, manifest: Manifest },
}

Registry 的启动流程:

  1. 扫描 skills/ 目录,收集所有 .md 文件 → skills HashMap
  2. 扫描 prompts/ 目录,收集所有 .md 文件 → prompts HashMap
  3. 扫描 capabilities/ 目录,收集各子目录中的 manifest 文件 → capabilities HashMap
  4. 构建常驻目录表:skills 的内容 → 摘要列表 → 注入 system prompt
  5. prompts 和 capabilities 的内容不注入 system prompt,仅在 agent 按需调用时加载

/reload 命令重新执行步骤 1-5,但不重启 daemon。

6.5 目录 → 常驻目录 → system prompt 注入路径

skills/ 目录的文件进入 system prompt 的路径如下:

skills/security-review.md
Registry 扫描 → 读取文件内容
构建常驻目录表:
  - name: security-review
  - source: Skill { path: skills/security-review.md, promoted: true }
  - content: "审查代码时按这个顺序:1) 输入验证  2) …"
注入 system prompt 的尾部:
  "你有以下可用 Skill:\nsecurity-review: 审查代码时按这个顺序:…"
agent 在 turn 中可以直接引用"按 security-review 的步骤做"

capabilities/ 的路径不同——它的内容不注入 system prompt,只注入可用性提示:

capabilities/daily-report/
├── manifest.yaml
└── main.sh
Registry 扫描 → 读取 manifest
构建可用能力列表(只列名称,不注内容):
  "你有以下可用 Capability:daily-report (Shell/OnDemand)"
agent 只有调用 run_capability daily-report 时,才读取 manifest 和代码

这种"只注名称、不注内容"的设计避免了 Capability 的代码占用 system prompt 的 token 预算。

6.6 完整的自我进化循环示例

以下是一个 agent 从发现问题到沉淀为 Skill 的完整循环:

步骤 1: agent 在代码审查中发现一个重复出现的模式
  → "每次审查 Python 代码,都需要检查 import 顺序"

步骤 2: agent 用 generate_prompt 写草稿
  → generate_prompt(name: "python-import-review", content: ...)
  → 文件写入 prompts/python-import-review.md

步骤 3: agent 在下一次审查中试用草稿
  → use_skill("python-import-review")
  → 草稿内容注入当前上下文

步骤 4: 经过几次试用,确认这个 Skill 值得正式化
  → promote_prompt("python-import-review")
  → 文件从 prompts/ 移动到 skills/
  → Registry 更新,下次启动自动加载

步骤 5: agent 在后续审查中自动使用这个 Skill
  → skills/python-import-review.md 在 system prompt 中
  → agent 每次审查 Python 代码时都会检查 import 顺序

这个循环的关键是步骤 3 和步骤 4 之间的间隔。草稿不是一次生成就自动转正的。agent 需要在实际使用中验证这个 Skill 的价值,然后显式决定是否晋升。晋升是一个独立的 agent 操作——不是自动的、不是隐式的。

如果 agent 生成的 Skill 质量不高,或者适用场景太窄,它可以在草稿阶段被废弃——prompts/ 中的文件可以被删除,不会影响 skills/ 的正式知识库。


ADR 深度阅读

Prompt 草稿层的引入动机(ADR 0025)

ADR 0025 记录了一个从实践暴露的问题:agent 生成的 Skill 质量不稳定。

在草稿层出现之前,agent 用 generate_skill 直接写文件到 skills/。问题在于:agent 第一次生成的 Skill 几乎总是需要修改的。 术语不一致、步骤顺序不合理、验收标准模糊。

最初的做法是让 agent 重复生成——生成 → 审查 → 发现问题 → 修改 → 重新生成。但 agent 在修改时可能引入新的问题,而且"修改 Skill"和"使用 Skill"的界限在 agent 的上下文中模糊。

解决方案是引入中间态:prompts/ 草稿目录。agent 的首先生成物进入 prompts/,只有经过 promote_prompt 显式晋升后才进入 skills/。这个变化的核心不是新增了一个目录——是在"写"和"用"之间加了一道晋升门

晋升门的意义在于:它不是人肉审批,但也不是自动通过。Agent 做了生的动作(generate_prompt),做了晋升决策(promote_prompt),中间还有试用验证(use_skill 从草稿加载)。每一次独立操作都是 agent 自主决策的——但每一步都可以被用户审计。

这条 ADR 的另一个动机是:防止 skills/ 中出现大量未经验证的 Skill。如果每个 agent 生成的粗稿都直接进入正式知识库,skills/ 会很快膨胀到难以管理。草稿层是一个"缓冲池"——高质量的内容晋升,低质量的内容随时间被清理。


下一章深入 Skill 系统的设计——程序性知识的注入时机、溯源机制、草稿晋升的完整实现。