# 收尾复盘

> 全书要点串联、与 llm-to-agent / Grok Build / OpenCode 的四方对照，以及可迁移的工程经验。

- 作者：David（道雾轩）
- 专栏：Kimi Code 源码解读（https://daiw.org/manual/kimi-code.md）
- 最后更新：2026-09-19
- 原文：https://daiw.org/manual/kimi-code/recap
- 转载与引用：请注明出处并附原文链接（https://daiw.org/about/copyright）

## 全景回顾

一条 prompt 从终端到模型再回到屏幕，经过的层：

```text
TUI（pi-tui 差分渲染）
  ↓ node-sdk：进程内 bootstrap 引擎
klient（契约 + zod；内存传输也做 JSON 往返）
  ↓ agentPromptService.submit
Agent scope：IAgentPromptChannel → AgentLoopService
  ↓ agent/loop/machine（适配层）
human 状态机：agent → turn → tool
  ├── generate  ← llmRequester → human/llm（四种协议基座）
  └── 工具批次  ← toolExecutor + ToolScheduler（按资源冲突并行/串行）
  ↓
事件 → IEventBus → SDK → TUI；记录 → wire.jsonl
```

## 十六条值得记住的设计

**边界与契约**

1. `human/` 是**纯内核**：不 import 任何 v2 领域代码，只有三个适配层能碰它的实现，`lint:imports` 强制。
2. klient 每个线上方法都有 **zod 契约**，schema 手工镜像引擎类型，由编译期断言钉住漂移。
3. **传输无关**：内存传输也做 JSON 往返，与 ipc 返回字节一致——同进程不是走捷径的理由。
4. 服务挂在哪一级 **Scope** 在注册时写死（`registerScopedService(LifecycleScope.Agent, …)`），看文件末尾就知道它的寿命。
5. 功能经 **Feature 接缝**进来：`features/` 下每个功能往贡献点挂配置、工具、命令，核心不必知道它们。

**类型即约束**

6. 回合结果是 `completed` / `failed` / `cancelled` 的**判别联合**；请求层 `generate` 约定错误只经事件交付、从不抛出。
7. 资源访问模型：读与搜索互不冲突，任一方写即冲突，`all` 与一切冲突；路径比较前**小写折叠**，在 Linux 上偏保守，方向安全。

**并发与安全**

8. Edit **不唯一就报错**，且错误信息带修复指引（设 `replace_all=true`，或给 `old_string` 多带上下文）。
9. 权限的 `fallback-ask` 兜底保证**默认安全**。
10. skill 与插件说明注入提示词前做 **XML 转义**防注入。
11. bash 解析有**确定性预算**，中止或出错就当「无法分析」降级。

**可恢复性**

12. wire 记录有**完整的版本迁移链**（v1.1 到 v1.5），旧会话能打开。
13. 重试与恢复是**纯策略**：`retry.ts` / `recovery.ts` 给出方案，turn 状态机执行——先试凭证恢复，再试媒体降级等替换消息。
14. 用量在模型请求结束时**立即**记录，不等工具执行。
15. 事件发射器用 `safelyCallListener` 包住每个监听者，**UI 出错不拖垮发射方**。

**工程纪律**

16. **无注释区 + 生成的清单 + 就近注册的 flag**：三个包不许写注释，wire / state / config 三份清单由脚本生成，实验开关没有中央目录。

## 四方对照

| 维度 | [llm-to-agent](https://daiw.org/manual/llm-to-agent) | [Grok Build](https://daiw.org/manual/grok-build) | [OpenCode](https://daiw.org/manual/opencode) | Kimi Code |
| --- | --- | --- | --- | --- |
| 定位 | 教学最小实现 | 生产实现 | 生产实现 | 生产实现 |
| 语言 | 教学用 | **Rust** | **TypeScript + Effect** | **TypeScript** |
| 规模 | 小 | 约 85 万行（非测试）/ 96 个 crate | 近 50 万行 / 36 个包（agent 相关约 17 万行） | **38 万行 / 19 个单元**（引擎约 13.6 万行） |
| 前端 | 1 | 3（TUI、headless、ACP） | 8（TUI、Web、桌面、VS Code、ACP、GitHub、run、SDK） | **7**（TUI、`-p`、Web、Remote Control、VS Code、ACP、SDK） |
| 依赖组织 | 无 | 显式传参 | Effect 的 Service、Layer 与 LayerNode | **VS Code 式 DI × Scope** |
| TUI | — | 自研 | OpenTUI + SolidJS | **pi-tui（vendored 自 pi-mono）** |
| 存储 | — | — | SQLite + Drizzle + 事件投影 | **wire.jsonl 追加日志 + minidb 索引** |
| 引擎代数 | 1 | 1 | 2 代并存（V1 现役、V2 迁移中） | **2 代 → 1 代（v1 已删除）** |

最大的结构差异来自**前端数量**。Grok Build 以 TUI 为中心，headless 与 ACP 只是同一个二进制的另外两种入口，agent 核心可以与 UI 贴得很近；Kimi Code 要喂七种形态，于是必须有 SDK 宿主层、klient 契约、transcript 独立包。

同为 TypeScript，Kimi Code 与 OpenCode 的依赖组织走了两条路：一边是 VS Code 式的装饰器 DI 加三级 Scope，一边是 Effect 的 Service 与 Layer。更值得对照的是换代：OpenCode 还在 V1 现役、V2 迁移的中途，Kimi Code 已经走完——服务端先切（v0.24）→ CLI 默认新引擎、留回退开关（v0.33）→ `kimi acp` 不再认回退开关（v0.40）→ 到 v0.43.0 旧包与开关都已删除。这条路径正好可以拿来参照。

**这不是谁更好，是约束不同。** 读源码时若不理解这个前提，会觉得 Kimi Code「过度设计」。

## 可迁移的经验

不写 agent 也用得上的几条：

**提示词是资源文件。** 引擎里 63 个源文件以 `?raw` 导入 `.md`，提示词可 diff、可 review、可由非工程同事编辑。

**换代要有兼容层。** node-sdk 的 v2 客户端逐方法对齐 v1 语义，差异写进注释并「pinned in the migration tracker」，前端几乎无感地换了引擎。

**边界要能被机器检查。** 导入边界、无注释区都有脚本把关；`AGENTS.md` 还专门提醒 `flake.nix` 的同步检查只覆盖 CLI 的依赖闭包、其余必须手工维护——知道检查的盲区，和有检查同样重要。

**配置不静默忽略。** 改名的旧键会在启动时提示改名，永远匹配不到任何工具的 allow/deny 条目会告警；llm 设计指南的原则之一就是「No silent fallback」。

**vendored 代码的本地改动要登记。** `pi-tui` 的 `AGENTS.md` 逐条列出与上游的差异，每条都有守护测试，重新同步上游时不会被悄悄覆盖。

**文档也会漂移。** `AGENTS.md` 因为天天被用而大体准确，但这次复核仍发现它与代码有出入——所以仓库自己强调「代码才是真相」。

## 这份源码的短板

诚实地说几条：

- **文档与代码有出入**：根 `AGENTS.md` 写 `agent-core-v2` 有四级 `LifecycleScope`，枚举里只有三级；提到的 `IWorkspaceLifecycleService.handlerFor` 在引擎代码里找不到；minidb 的包描述还停在 KV 数据库。
- **v1 的残留**：`kosong`、`kaos` 引擎已不用却仍在仓库（kaos 只剩类型引用）；SDK 里还有「the v1 engine throws `not_implemented`」一类已无对应实现的说明。
- **无注释的代价**：13 万多行的引擎没有一行注释，新读者只能靠命名、类型和测试建立心智模型。
- **巨型文件**：`kimi-tui.ts` 4190 行、`sdk-rpc-client-v2.ts` 2807 行、`loopService.ts` 2260 行。
- 自维护的底座（minidb、vendored 的 pi-tui、tree-sitter-bash）长期维护成本不低。

## 继续读什么

- **想对比另一种语言与架构**：[《Grok Build 源码解读》](https://daiw.org/manual/grok-build)。
- **想看同为 TypeScript、另一套依赖组织的实现**：[《OpenCode 源码解读》](https://daiw.org/manual/opencode)。
- **想从零理解 agent 该做什么**：[《从 LLM 到 Coding Agent》](https://daiw.org/manual/llm-to-agent)。
- **想深入模型侧**：[《AI 大模型解构》](https://daiw.org/manual/llm-anatomy)。

回到[专栏首页](https://daiw.org/manual/kimi-code)可查任意章节。源码基准 `ffa94fa`（v0.43.0，2026-09-14）——从 v0.29.1 到这里只隔七周，引擎就完成了换代，读时请以当前 HEAD 为准。
