# 扩展模型 · 如何新增一种能力

> 技术参考 · 深入原理(架构师向)。承接《[组件全图](43-components.md)》《[运行时与事件流](44-runtime.md)》。
> 这是架构师最该懂的一篇:ClawCreek 的可扩展性是**结构性**的——新能力可以直接 slot in,**不需要重写一个中心**。想提"给平台加个 X"的提案,先想清楚 X 属于四层里的哪一层、以及怎么把它接上去。

---

## 先分层:X 到底是什么?

提案第一步,是把你想加的东西**归到正确的层**(放错层,提案就站不住):

| 你想加的 | 它是 | 关键判据 |
|---|---|---|
| 一种**器官/能力**(有 per-Agent 状态、订阅事件、有自己的世界观) | **Module** | 它需要"记住 per-Agent 的东西"吗?需要在每个事件上表态吗? |
| 一种**平台共享服务**(实例不持有某个 Agent 的可变状态,被调用) | **Infra** | 它应由全局 InfraRegistry 持有一份吗? |
| 一个**动作**(LLM 能主动调用去做一件事) | **Tool** | 它是"让 LLM 做 X"的一个动词吗? |
| 一段**行为模式 / 知识**(不需要新代码) | **Skill / Directive / Playbook** | 它能用配置/提示表达,而不是写代码吗? |

> 最容易混的是 Module vs Infra。通常:**Module 实例拥有单个 Agent 的生命周期状态;全局 Infra 实例不把某个 Agent 的可变状态留在自身字段里**,而是接收 `agent_id`,按需读写共享数据库。当前 EventBus 是例外:类型上继承 Infra,但实际每个 AgentLoop 一份。架构提案应明确是在延续这个过渡实现,还是进入全局 InfraRegistry。

---

## 自描述:每样东西都带一份 Spec

ClawCreek 的每一层都是**自描述**的——启动后冻结、全局唯一的一份契约:

- **Module** → `ModuleSpec`(name / roles / priority / 订阅的事件 / 拥有的 tools / `owner_docs` …);
- **Infra** → `InfraSpec`;
- **Tool** → `ToolDef`(name / description / parameters / handler / risk_level);
- **Event** → 有自己的类型定义。

**为什么这对架构师重要:** 名称、角色、世界观、事件、工具归属和说明尽量集中在对应 contract 里,供 introspection、Brain UI 和注册表消费。运行时状态仍在 Module/数据库中,具体工具权限主要由 `ToolDef` 和 handler 的执行检查保证,不能假定一份 ModuleSpec 包办所有边界。

> 特别地:`owner_docs` 是**必须手工写准确**的 Agent 自我说明。平台启动时还不能读取任何 per-Agent ModuleRegistry,所以当前由 `core/module_doc_provider.py::_migrated_module_classes()` 静态收集这些 class-level 文档,再写入平台知识库。漏掉 provider 注册会让 Module 已经运行、Agent 却搜不到说明;CI 的 drift test 只是兜底。

---

## slot-in:怎么接上去

- **加 Module**:定义 `ModuleSpec`,在 `install_defaults()` 注册;若订阅事件,声明 `events_subscribe` / 必要的 `EventTypeSpec`,并按 band 并行语义选择 priority。再编写 `owner_docs`,把 class 加进 module doc provider,让 Agent 的知识检索真正看得到它。
- **加 Infra**:定义 `InfraSpec` + 在全局 InfraRegistry 注册;通过 `agent_id` 访问共享存储,不要把某个 Agent 的可变状态留在全局实例字段里。
- **加 Tool**:定义 `ToolDef` + 由某个 module 在 `spec.tools` 里"认领" + 注册。工具走**联邦式认领 + 自适应加载**,LLM 在相关场景自动拿到它。

通常不需要修改 consciousness 或重写事件循环,但仍要更新明确的装配点(默认 Module/Infra 注册表、Tool 注册与 owner-doc provider)。这里的"不改中心"是**核心执行器保持稳定**,不是"零中心装配改动"。

---

## 这份"先难后易"的取舍

把每样东西都做成自描述、分层、可 slot-in,**比"一个中心挂一堆工具"复杂**。这份复杂是**刻意的投资**:它换来的是——平台可以**持续长出新能力**,而不需要谁去重写那个中心。一个任务执行器加到第 20 个能力时会变成意大利面;这套结构加到第 200 个仍然是"再插一个器官"。

> 这正是《[平台架构](40-architecture.md)》说的"是生命而非工具"在**工程上**的含义:结构本身为成长而设计。

---

## 提案 checklist(架构师自查)

提一个"加能力"的架构设计前,先答清楚:

1. **它属于哪一层?**(module / infra / tool / skill-directive-playbook)
2. **如果是 Module**:priority 多少?同 band 并行是否安全?订阅/发出哪些事件?是否要新增 `EventTypeSpec`?持什么 per-Agent 状态?拥有哪些 Tool?
3. **它在事件流的哪个位置贡献?** 要读哪个更高优先级 band、被谁读?
4. **成本**:它会让多少事件唤醒 LLM / 加多厚的 prompt?(见《[一次思考的生命周期](45-chain.md)》)
5. **边界**:它碰不碰安全红线(动钱/群聊/权限)?(见《[owner 权限与安全边界](11-permissions.md)》)
6. **它的自我描述**怎么落地?写好 `owner_docs` / description,注册 module doc provider,添加防漂移测试,部署后确认知识库同步。

答得清楚,才是一个"有据"的架构提案——拿去《[本源](05-source.md)》走流程。

---

*这一篇属于「深入原理(架构师向)」。回看全部零件《[组件全图](43-components.md)》、运行机制《[运行时与事件流](44-runtime.md)》、执行链路《[一次思考的生命周期](45-chain.md)》;想把提案落到治理流程,看《[本源](05-source.md)》。*
