回顾
全书要点串联:一条消息沿途多出的挂载点、值得记住的设计、与上游 OpenCode 的对照、文档与代码的出入,以及可迁移的经验和这份源码的短板。
读到这里,MiMo Code 在 OpenCode 之上做的事可以归成一句话:让一个会话能跑得很久。上下文会满,就把状态写进文件、按需重建;模型会过早收工,就另请一次调用来判定;Agent 会原地打转,就检测轨迹的形状并暂停;活太多,就拆给子智能体和脚本化的工作流。这一篇把前面各部分串起来。
一条消息,沿途多了什么
对照一条消息的旅程,上游原有的骨架——TUI 提交、服务端路由、runLoop 主循环、流处理器调模型与工具——都还在,MiMo 在沿途加了这些挂载点:
- 每轮开头:先排空收件箱,把其他智能体发来的消息变成一条合成的 user 消息(收件箱、团队与进度检查);只取本 actor 的消息切片,从最近的压缩或检查点边界读起;会话有记忆时临时追加召回提醒(分层记忆)。
- 组装请求之前:用量跨过新档位就在后台拉起检查点写手(检查点写手);越过触发线就插入重建边界、按分段预算拼出新的上下文,写不出检查点才退回压缩(周期、上下文重建);复读的思考步骤可以整段裁掉(复读检测与重试);技能目录放在系统提示词尾部(内置技能包与技能检索)。
- 调模型时:Max 模式开启就改走多候选加裁判(Max 模式);流里出现 n-gram 复读就提前截断;Try-Best 开启时每个工具调用结束都喂给检测器,命中就暂停本轮(Try-Best 检测与 Hand-off)。
- 想收尾时:挂着
/goal就先请裁判判定,没达成就把缺口写回去接着干(Goal);每一步的结果先分类,再决定续跑、重试还是放弃。
值得记住的设计
长程上下文
- 一个逻辑会话,多段物理窗口。检查点按窗口大小分档在后台维护,触发线默认是有效窗口的 90%;越线后从检查点重建,而不是当场写摘要(周期)。
- 写状态的是另一个智能体。checkpoint-writer 分叉复用父请求的缓存前缀,按 11 节模板改写
checkpoint.md,写入范围被路径守卫限死(检查点写手)。 - 重建是分段预算,不是一个总数。检查点、用户原话与各级记忆各有上限,水位线之后的尾部折叠成活动清单(上下文重建与预算化注入)。
- 为提示词缓存冻结请求前缀。修剪按缓存冷热与压力分级,前缀快照让连续请求尽量命中缓存(压缩、修剪与请求前缀)。
记忆与自主运行
- 文件是真相,索引是缓存。记忆是磁盘上的 Markdown,FTS5 索引只是从磁盘同步过来的检索副本;写入要过闸门(分层记忆、历史轨迹与全文检索)。
- 整理记忆也交给隐藏智能体。
dream把近期会话里经得起核对的知识并进MEMORY.md,distill把重复流程打包成可复用的资产;自动运行默认关闭(Dream 与 Distill)。 - 停不停,另请一次调用来判。裁判读完对话再裁决,一个目标最多踢回 12 次(Goal)。
- 看轨迹的形状识别打转。近似编辑、同一命令反复失败、无进展的同类动作三条规则,命中后暂停并把选择权交给用户(Try-Best 检测与 Hand-off)。
- 任务是持久化的工作项。T1、T1.1 式编号落进 SQLite,子智能体收尾时名下还有没做完的任务,会被完成闸门催着再跑(最多 2 轮)(树状任务);定时任务与循环靠跨进程锁调度(定时任务与循环)。
多智能体与编排
- 用 actor 注册表取代 task 子代理。前台后台、同会话切片与独立子会话共用一套数据模型,后台的结果经收件箱送回父会话(Actor)。
- 一个会话调度一群会话。Orchestrator 的子会话是可以随时接管的 peer,开了隔离就各占一个 worktree,权限请求转发回来由用户或 Orchestrator 批准(Orchestrator)。
- 把编排写成脚本。Workflow 在 QuickJS 里跑,子智能体、并发、重试都有上限,中断后能续跑(Workflow 运行时、四个内置 Workflow)。
- 给不同模型不同的工具 ABI。GPT 类模型顶层只看到
exec,脚本在同一个沙箱里调宿主工具,权限仍由宿主把关(exec 与 QuickJS 沙箱);四个控制类工具还能改用命令行式语法调用(命令行式工具调用与 Token 精简)。
与上游 OpenCode 对照
| 维度 | OpenCode v1.14.19 | MiMo Code v0.1.14 |
|---|---|---|
| 上下文用满 | compaction agent 当场写摘要 | 分档维护检查点,越线后重建,写不出才压缩 |
| 跨会话状态 | 无 | MEMORY.md、会话笔记、任务进展文件,FTS5 检索 |
| 子智能体 | task 工具,新建子会话,只有前台 | actor 注册表,前后台、切片与子会话,收件箱回传 |
| 何时停 | 模型不再调工具就结束 | 可挂 /goal 裁判,另有复读与打转检测 |
| 编排 | — | Workflow 脚本、Orchestrator(均为实验开关) |
| 工具调用 | JSON | JSON,可配成命令行式;GPT 类模型走 exec |
| 技能 | 用户自己配置 | 内置技能包,skill_search 检索 |
引擎规模(src 下 TS,不含测试) | 443 个文件、约 8 万行 | 674 个文件、约 14.1 万行 |
底座没变的部分——服务端与 TUI 分离、Effect 的 Service 与 Layer、提供方适配、权限规则——依然可以对照《OpenCode 源码解读》来读,只是那本对照的是更新的 v1.18.30。
文档与代码的出入
MiMo 的 README、官方博客和仓库里的设计文档写得很用心,但落后于代码的地方不少。本书逐条对照后,凡不一致都写代码的实际行为:
- 检查点档位:博客说约 20%、45%、70% 触发;代码按窗口大小分档,20 万 token 以内是 20%、40%、60%、80%(周期)。
- 重建注入:博客说约 65K token;代码没有总上限,只有各段上限(上下文重建)。
- Max 模式的裁判:博客说用低温;代码没有为裁判单独设温度(Max 模式)。
- Dream 与 Distill:博客说每 7 天、每 30 天自动触发;代码里自动运行默认关闭,7 和 30 只是间隔的默认值(Dream 与 Distill)。
- Try-Best:设计文档说开关默认打开、支持五种编排模式;代码默认关闭,落地的只有 Fallback 一种(Try-Best 检测与 Hand-off)。
- Orchestrator:设计文档说
session工具有 8 个动作,代码里是 12 个(Orchestrator)。
可迁移的经验
把状态从上下文里搬出去。 上下文窗口是易失的,文件不是。检查点、记忆、任务进展都落盘,模型看到的上下文随时可以从它们重建——这比“压缩得更聪明”更可靠。
让另一个视角来判断“做完了没有”。 同一次调用既干活又给自己打分,天然偏乐观。Goal 裁判只读对话、只回答达没达成,代价是多一次调用。
失败信号藏在轨迹的形状里。 单看某一步很难说它错了;连续几次近似的编辑、原样重试的失败命令,才是该停下来换思路的证据。
大功能挂在开关后面,关掉就真的不存在。 Orchestrator、Workflow 等能力关闭时,连智能体和工具都不注册,而不只是界面上藏起来,读代码时也更容易分清主干与实验。
文档要跟代码一起评审。 设计文档、提示词、工具说明都会被当成事实来源——给人看,也给模型看。本书记下的出入里,有好几处是提示词还在描述已经改掉的行为,模型照着做就会出错。
这份源码的短板
- 大文件集中在引擎核心:
session/prompt.ts有 5600 多行,session/checkpoint.ts、workflow/runtime.ts也都在 1600 行以上,改动主循环时牵一发而动全身。 - 实验开关多:Orchestrator、Workflow、Max 模式、Try-Best、Token 精简、MCP 工具检索都默认关闭或需要显式打开,读某个功能之前得先确认它有没有被注册。
- 与上游脱节:Effect 写法停在 v1.14.19 那一套,上游之后的依赖组装改造没有跟进(怎么读这份源码),对照上游新版读代码时要留意差异。
- 默认上报使用统计:模型调用、工具调用等事件默认上报,需要用环境变量显式关闭(从 OpenCode 分叉:增量全景)。
- 只维护终端:
AGENTS.md写明 Web、App 与 Desktop 目前不维护,继承自上游的这些界面代码仍在仓库里。
继续读什么
- 想看底座:《OpenCode 源码解读》。
- 想从零理解 Agent 该做什么:《从 LLM 到 Coding Agent》。
- 想看 Rust 生产实现:《Grok Build 源码解读》。
- 想对照另一种 TypeScript 架构:《Kimi Code 源码解读》。
- 想了解 MiMo 能接管、也能交接的两家工具:《Claude Code 中文手册》、《Codex 中文手册》。