MiMo Code (Xiaomi)

一句话定位

小米 MiMo 团队基于 sst/opencode fork 而来、MIT 协议公开发布的终端编码 agent harness,核心设计目标是”长程任务”(数十至数百步执行)下的决策质量与状态连续性,官方博客将其设计拆成三个主题——computation(单轮推理质量)/ memory(跨轮状态连续)/ evolution(跨会话经验沉淀)——并给出了内部人类双盲 A/B 测试数据支撑”步数越多、相对 Claude Code 优势越大”的核心叙事。

核心架构总览

Monorepo,Bun + Turborepo + TypeScript,核心业务逻辑构建在 Effect(函数式副作用框架,全部核心服务是 Effect.Service layer)之上。仓库结构(commit 7f9060ca3d7fa712421ff8987e9ccf98e085475c,2026-07-07 拉取的 shallow clone,HEAD 为 fix(compose): strengthen skill invocation prompt and fix RLHF resistance (#1598),作者 Yihan Yan,2026-07-06):

  • packages/opencode/src/ — 实际 CLI/agent 运行时,约 95% 的关键逻辑在此,src/ 下有 60+ 子系统目录
  • packages/app / packages/desktop / packages/web / packages/console / packages/enterprise — 周边产品面(Tauri 桌面端、web console、企业/团队功能)
  • packages/plugin / packages/sdk — 对外插件/SDK 面(@mimo-ai/plugin
  • packages/containers — 仅 CI 构建镜像(Ubuntu/bun-node/rust/tauri),不是 agent 执行沙箱(已读 packages/containers/README.md 确认)
  • docs/harness/ — 一手设计文档(EN/JA/FR/RU):“MiMo Orchestrator Mode”、“MiMo Token Efficient Mode”
  • docs/compose/plans/docs/compose/reports/ — 团队自用 “compose” spec-first 工作流留下的工程计划/报告文档,证明团队用自己的 Compose 工作流构建 MiMoCode 本身(dogfooding)
  • .mimocode/ — 项目级 skills/plugins/config 目录(该仓库自身的 dogfooding 配置)

LICENSE 文件明文写 Copyright (c) 2026 MiMo Code, Xiaomi Corporation + Copyright (c) 2025 opencode,坐实 fork 血统;另有 packages/opencode/src/skill/compose/LICENSE-karpathyLICENSE-superpowers 两个子归属文件,说明 Compose 模式内置技能分别衍生自 Karpathy 的 skill-guidelines 项目与 Jesse Vincent 的 obra/superpowers

官方渠道:产品站 https://mimo.xiaomi.com/coder;博客 https://mimo.xiaomi.com/en/blog/mimo-code-long-horizon(2026-06-10 发布,已在本阶段完整抓取,是本 dossier 大量论断——尤其 Max Mode/Goal 的具体数字与 A/B 数据——的来源);GitHub https://github.com/XiaomiMiMo/MiMo-Code。安装渠道:curl 一键安装、npm install -g @mimo-ai/cli、Windows PowerShell 安装器。首启配置项:MiMo Auto(免费匿名通道,基于 MiMo-V2.5,支持 100 万 token 上下文)、小米 MiMo 平台 OAuth 登录、“Import from Claude Code”(迁移鉴权)、自定义 OpenAI 兼容 provider。

Agent Loop(主循环 / 何时继续何时停)

官方博客将其称为 computation 主题——用不同粒度的算力投入换可靠性:“降低单步决策错误率、防止任务级过早终止或方向漂移、降低执行级不必要的来回开销”。源码层面是两层结构:

  • 外层循环packages/opencode/src/session/prompt.tswhile (true)(约始于 2521 行;全文 4039 行,本阶段精读 1–130 行、2380–3200 行并做了全文 grep)。每轮迭代:拉取 inbox → 按 agentID 过滤加载消息切片(让子 agent 只看到自己的切片)→ 分类上一条 assistant 步骤(classifyAssistantStep:filtered / failed / text-tool-call / think-only / invalid / continue / final)→ 按分类路由(重试 text-tool-call、重试 invalid/think-only 输出,或跳出)→ 在 continue/新一轮开始时,先过 task-gate 和 goal-gate 才会真正接受”停止”→ step++ → 第 1 步触发 title/auto-dream/auto-distill → 解析 model → 处理 subtask/compaction 边界路由 → 上下文压力达到 70%/85% 时注入 memory-flush 提醒 → 连续 N 次相同 tool call 触发”doom loop”提醒 → overflow/maxThreshold 检查触发 checkpoint 边界插入或有损压缩 → 为该 agent 解析工具集 → 构建 assistant message → 交给 SessionProcessor.create().process()
  • 内层循环session/processor.ts(984 行,全文读完)的 handleEvent ——针对流式事件的状态机(startreasoning-start/delta/endtool-input-start/delta/endtool-calltool-resulttool-errorstart-stepfinish-steptext-start/delta/endfinish),增量持久化 parts 到 session DB,按步追踪快照做文件变更 diff,并检测”doom loop”(3 次连续相同 tool call 强制 permission ask)。

“继续还是停”不是单纯看模型是否吐出停止信号:

  • Goal gatesession/goal.ts):用户通过 /goal 显式设置一个自然语言停止条件(如”所有测试通过且代码已提交”)。每当 agent 试图终止,系统自动发起一次独立的 LLM judge 调用复核该条件是否真正满足;不满足则把具体缺口反馈给 agent 继续;判定确实不可达才标记 impossible。goal.ts 里的 judge prompt 明确写”assistant claiming the goal is impossible is evidence, not proof”,要求 judge 独立确认而非直接采信 agent 自称。judge 复核次数由 MAX_GOAL_REACT(定义于 prompt.ts)设上限兜底。博客披露的量化结果:false blocking(条件已满足但 judge 误判未满足,常见诱因是测试因环境问题失败)比 false passing 更常见;整体无限循环概率 < 0.5%,到达步数上限后系统会自动退出。
  • Task gate:由 task registry 驱动的相似”cap + fallback”模式,与 goal gate 相互独立地把关循环是否可以真正结束。
  • agent.steps ?? Infinity 设置每个 agent 的最大步数上限;到达最后一步时循环会注入一条 MAX_STEPS 用户消息并把 toolChoice 设为 "none"

此外还有两个独立的”算力换质量”机制,均在博客中有具体数字:

  • Max Modesession/max-mode.ts,410 行,仅读了 header/grep 未逐行读完;行为已由博客交叉验证):每轮并行生成 N 个候选方案(默认 N=5,temperature=1,各自独立完成推理与工具调用规划但不执行),再用同一模型作为 judge 比较所有候选的推理过程与行动计划、选出最优执行。processor.tsreplay() 方法负责把胜出候选的流事件重放/合成,落败候选的 token/成本计入”overhead”、不污染上下文窗口的 token 计数。博客给出的效果:SWE-Bench Pro 上相比单采样提升 10%–20%,代价约 4–5 倍 token 消耗;当前为实验特性,需手动配置开启。
  • 文本重复检测session/prompt/text-ngram-detection.tstext-loop-recovery.ts):n-gram 检测模型退化为重复文本时可提前截断流(Result = "text-repeat")。

博客还披露一项尚未落地到代码的方向——工具调用语法:观察到部分模型(尤其 GPT-5.5 系列)输出结构化 JSON 的格式错误率较高,XML 略优于 JSON,团队认为一种受限的类 shell 命令行语法(不支持管道/重定向/变量展开)能用更少 token 表达同等工具调用意图且格式错误更少,原因是多数模型在密集的 shell 环境数据上训练过;但博客原文明确注明”MiMo Code has not yet migrated tool calls to this format”,即这只是设计方向声明,非已实现能力,写作时须与已验证的源码事实分开标注。

记忆与上下文管理(压缩、长期记忆、会话持久化)

这是本 fork 中最深度定制的子系统,官方博客将其作为 memory 主题单列一节,核心论点是”目标不是更好的压缩,而是显式的存储-检索机制”,源码与博客可相互印证,具体数字以博客为准(源码侧只读了 header/grep,未逐行验证阈值常量):

  • Cycle(周期)概念:博客定义”一段带 checkpoint、最终以 rebuild 收尾的 turn 序列”为一个 cycle;单个 cycle 受物理窗口大小限制,但逻辑会话是 cycle 的链条,链条长度无上限。
  • Checkpoint 系统session/checkpoint.ts,1560 行;本阶段只读了 header/imports 并做了 grep,未逐行读完):后台”checkpoint-writer” subagent(prompt 见 agent/prompt/checkpoint-writer.txt,167 行,已读但未逐行核对)在 token 阈值越过时周期性写入结构化 checkpoint/memory/notes 文件(模板见 session/checkpoint-templates.ts,未读)。主 agent 上下文溢出时,循环插入一个指向最新 checkpoint 的”rebuild boundary”,而不是删除 DB 历史——消息从不被销毁,只是从边界起重新切片(filterCompactedEffect)。博客给出的具体触发点:checkpoint 大致在配置预算的 20%、45%、70% 处触发,每次都是对上一次的增量更新而非一次性摘要;最终 rebuild 不是仓促压缩,而是把沿途积累的结构化记录变成工作上下文的时刻。博客给出的理由是”lost in the middle”效应——上下文利用率越高,模型的结构化抽取可靠性越差,因此把最关键的压缩工作放在利用率最高(最不擅长)的时刻是一笔坏交易;同时抽取本身需要空间,95% 利用率下没有思考余地,30% 利用率下则空间充裕。
  • Writer 独立性约束:博客明确”the main agent does not maintain its own memory”——抽取被整体移出主循环,由不共享主 agent 注意力/token 预算的独立 writer subagent 完成。Writer 写入的 checkpoint 文件是固定结构,11 个字段:当前意图、下一步动作、工作约束、任务树、当前工作、涉及文件、跨任务发现、错误与修复、运行时状态、设计决策、杂项笔记;对每个结构化文件强制单一写者(single-writer invariant)防止并发写不一致。主 agent 对结构化文件只有只读权限,唯一例外是会话级自由格式草稿 notes.md——主 agent 可随时追加发现,每次 checkpoint 时由 writer 读取、归类进结构化字段后清空,这是主 agent 唯一的写入通道。
  • 四层记忆(博客 3.4 节):Session memory(checkpoint.md,仅存活于当前逻辑会话)→ Project memory(MEMORY.md,跨会话持久化的架构决策/用户规则/反复验证过的技术事实,writer 在某观察在多次 session checkpoint 间稳定后才从 session 层提升到此层)→ Global memory(跨项目的用户级偏好)→ History(每个会话的完整 SQLite trace,未索引的原始消息与工具调用文本,作为结构化记忆之外的兜底)。上层更精炼、更持久、更小;下层更完整、更大、更慢。
  • Compactionsession/compaction.ts,561 行,未读全文):仅在尚无 checkpoint 或子 agent/actor 上下文溢出时使用的 LLM 驱动有损摘要兜底(子 agent 没有 checkpoint 机制,走按-actor 切片压缩)。
  • 持久化可搜索记忆memory/service.ts,145 行全文读完 + tool/memory.ts/memory.txt):markdown 文件存于 <data>/memory/<scope>/<scope_id>/<key>.md(scope 有 global/projects/sessions/cc),索引进 SQLite FTS5 表(memory/fts.sql.ts)做 BM25 排序、OR-拼接分词查询、相对分数下限过滤噪声。值得关注的细节memory.cc_index 选项开启后会额外索引 ~/.claude/projects/<slug>/memory/*.md(scope=“cc”),即可选导入 Claude Code 自身的项目记忆;memory 工具描述里带有明确隐私警告——type: user/type: feedback 的 CC 记忆一旦被索引,会变成任何 MiMoCode agent(包括暴露给 prompt injection 风险的子 agent)都可检索到的内容。
  • 上下文压力提醒:70%/85% 阈值处,作为 synthetic system-reminder 文本注入到 user message,提示 agent 在可能被 reset 前把重要发现刷入 memory;一旦会话有任何 memory/task 产物,之后每轮都会收到指向 <data>/memory/sessions/<sessionID>/ 的简短提醒,避免模型中途忘记 recall 工具的存在。
  • Rebuild 注入结构(博客 3.5 节):rebuild 时把持久化文件组装成分层 prompt 注入新窗口,各段有独立 token 上限,大致顺序为:任务列表 → 会话 checkpoint → 最近用户消息的逐字切片(防止 writer 改写偏离用户原意)→ 项目记忆 → 全局记忆 → notes → 可按需读取的记忆文件路径索引 → 告知下一步该做什么的结尾提醒。即使每段都打满上限,总注入内容也控制在约 65K token 以内——这是本阶段唯一的一手量化数字,需与源码里的具体常量交叉核对(本阶段未在 checkpoint.ts 中逐行核实该 65K 数字对应的具体代码位置)。

工具体系(定义/调用协议/注册/权限)

  • 工具通过 tool/tool.ts(167 行全文读完)的 Tool.define(id, init) 契约定义:{ id, description, parameters: ZodType, execute(args, ctx), formatValidationError?, shell? }wrap() 自动注入 Zod 校验(参数错误 → RecoverableError,UI 静默但模型可见错误信息并重试)与输出截断。Effect.withSpan("Tool.execute", ...)tool.ts:137 附近对每次执行做 span 包裹。
  • 两种调用风格:JSON 参数(默认)与shell 风格tool.shell.parse(script)——工具可接受单行类 shell 命令字符串,经 tokenize 后映射为结构化参数;用于 actorbashsessiontaskcron,见各 *.shell.txt 描述变体与 shell-tokenize.ts/shell-wrap.ts)。调用风格按工具通过配置解析(resolveInvocationStyle)。
  • 内置工具集(tool/registry.ts,447 行全文读完):invalid、question(条件性)、bash、read、glob、grep、edit、write、notebookedit、actor、fetch(webfetch)、search(websearch,限定给 opencode/xiaomi provider 或 flag 开启)、code(codesearch)、skill、patch(apply_patch——GPT 系模型用它替代 edit/write)、changedir、lsp(flag-gated)、planexit/planenter、memory、history、task、cron(flag-gated)、session(仅 orchestrator,flag-gated)、workflow(flag-gated)。
  • 自定义工具加载:glob 配置目录下的 {tool,tools}/*.{js,ts} 并动态 import;同时拉取已加载插件贡献的工具(Plugin.list())。
  • 每个 agent 的工具可见性由 agent.toolAllowlist 过滤;session 工具额外硬性限定 agent.name === "orchestrator",不受 allowlist 影响。工具集按 {providerID, modelID, agent} 动态解析,同一注册表能为不同模型呈现完全不同的可见工具集(如 GPT 系模型拿到 apply_patch 而非 edit/write)。
  • Bash 工具tool/bash.ts,821 行,本阶段仅读前 140 行 + tool/bash.txt 描述):用 tree-sitter(web-tree-sitter)解析命令 AST 提取文件路径/模式用于权限系统;破坏性命令检测(rmgit reset --hardgit push --force 等);处理 PowerShell 别名。
  • Token Efficient Modedocs/harness/MiMo Token Efficient Mode.en.md,实现文件为 packages/opencode/src/tool/bash_token_efficient.ts,本阶段未直接读取该 ts 文件,仅读了设计文档):实验特性(flag MIMOCODE_EXPERIMENTAL_TOKEN_EFFICIENCY,默认关闭),针对 bash 工具输出的通用过滤管线(清 ANSI/OSC/DCS 控制序列、折叠 \r 进度条多帧、正则脱敏 PEM/Bearer/JWT/AWS/GitHub/OpenAI/Anthropic/Slack 密钥、超长行压缩为 160 字符头+省略提示)+ 启发式过滤管线(按命令名/内容指纹识别 pytest/npm/make/gitdiff/tsc/kubectl/gostest/md 等 10 种输出”形状”分别定制裁剪规则,文档给出的预期压缩率从 50%(gh pr view)到 95%(JSON 输出/git diff)不等)。核心约束:只清洗 LLM 可见的 inline 输出,磁盘归档与 TUI 实时预览保留原始字节;“never-worse gate”——任何清洗阶段若导致字节数不降反升则整体回退到 Raw 路径。该模式默认关闭,是实验性设计,不代表当前默认行为

Prompt 设计(系统提示结构、动态组装)

  • 系统提示是动态组装而非静态:session/system.ts(130 行全文读完)的 environment() 构建一个基础块(“You are MiMo Code Agent, built by Xiaomi MiMo Team…”、model ID、环境信息),环境信息块锚定在会话创建时刻而非请求时刻,使该块跨轮字节级一致,以保住 Anthropic prompt cache 前缀;当前模型不支持图片输入时追加一个条件性视觉能力说明块。
  • 按模型家族分文件的系统提示变体位于 session/prompt/ 下:default.txt(通用)、anthropic.txt(claude)、beast.txt(gpt-4/o1/o3)、codex.txt(gpt+codex)、gpt.txt(其他 gpt)、gemini.txtkimi.txtdeepseek.txtglm.txtminimax.txttrinity.txt,兜底 default.txt——在 session/system.tsprovider() 函数里纯靠 model.api.id 子串匹配选择,共 9+1 个变体。
  • Skills 块在 agent 具备 skill 权限时追加:系统提示中渲染详细描述,工具描述里则精简——代码注释说明这种顺序经过实测更优。
  • Compose 模式有额外的结构化 <system-reminder> 块(session/prompt/compose.txt,131 行全文读完),强制技能调用:明确的指令优先级阶梯(用户 CLAUDE.md > compose skills > 默认系统提示)与”Mid-Way Recovery”协议(模式切换后恢复 skill 驱动工作)。这与本次拉取到的 HEAD commit 标题(“strengthen skill invocation prompt and fix RLHF resistance”)直接对应。
  • Orchestrator 有独立的 orchestrator.txt 提示(已读,确认存在),确立”delegator,自己不做实质工作”的身份设定。
  • 运行时动态插入的合成 system-reminder(不烘焙进静态提示文件):recall 提醒、上下文压力提醒、重复步骤/doom-loop 提醒、“用户在本轮中途发来后续消息”包装——均作为 synthetic text part 插入 prompt.ts 内的 user message。

Router / 编排(任务分解、多 agent、子 agent)

  • Subagent(actor)层——tool/actor.ts(845 行,本阶段读了前 150 行 + tool/actor.txt 描述):动词 run(阻塞等待结果)、spawn(异步立即返回)、statuswaitcancelsend(actor 间通过 inbox 消息通信)、models(发现可用模型引用,如支持视觉的模型)。Actor 共享父会话的 sessionID,但各自拥有独立 agentID 的消息历史切片(filterCompactedEffectagentID 过滤)。
  • Orchestrator peer 层——一套更重的独立机制,由 MIMOCODE_EXPERIMENTAL_ORCHESTRATOR(默认关闭)flag 门控:session 工具(tool/session.ts,659 行,本阶段仅通过设计文档引用、未直接读取实现代码)提供 8 个动词(create/switch/list/cancel/ask/setmode/approve/grant-approval),生成完整独立子会话(独立 session ID、任务面板、记忆),作为后台 peer 运行,以 git worktree 隔离(--isolate 创建专属 worktree + mimocode/<task> 分支,避免并发写冲突)。无轮询设计——子会话完成后通过 inbox 通知唤醒 orchestrator。后台子会话的 permission ask 默认无人值守会自动拒绝,但对 orchestrator peer 特别设计了转发审批(转发给用户或经预授权委托 grant 转给 orchestrator本身),并设 5 分钟拒绝超时安全阀(permission/index.ts 中的 FORCED_DENY_TIMEOUT_MS/FORWARD_DENY_TIMEOUT_MS)防止转发的 ask 永久悬挂。设计依据一手文档:docs/harness/MiMo Orchestrator Mode.en.md(141 行全文读完)。
  • Fork agent(contextMode: "full"):被 spawn 的 actor/peer 可继承父级系统提示+消息历史的冻结快照(ForkContext),保住 prompt-cache 前缀一致性,而非重新计算自己的 agent 身份。
  • Task registry(task/registry.ts,394 行;task/gate.ts,116 行,均未读全文)提供共享任务看板(todo-list 式),独立于 goal gate 把关循环继续(taskGate)。
  • 官方博客补充的编排方向——Dynamic Workflow(动态工作流):定位为解决”数十上百并行工作单元协同”这类超出逐轮工具调用能力范围的大规模并行编排问题。核心论点:传统做法是把流程写进 SKILL.md 靠自然语言告诉模型”先做 A 再做 B,遇到 C 就做 D”,在复杂工作流下会系统性失败(压缩可能吞掉步骤、模型可能跳过阶段、分支/重试逻辑依赖模型判断而非代码保证、同一工作流两次运行路径可能不同)。Dynamic Workflow 把编排逻辑从 prompt 变成代码:主 agent 生成一段 JavaScript 脚本,在隔离沙箱内确定性执行,通过 agent() 派发子 agent,parallel()/pipeline() 控制并发。博客称其”与 Anthropic Dynamic Workflow 的核心语义兼容并做了扩展”:workflow() 原语允许脚本调用其他脚本(可组合);每次 agent() 调用结果同步落盘,支持中断后从日志恢复而非从头重跑;脚本可直接读写文件。该沙箱执行环境即前述 workflow/sandbox.ts(QuickJS-WASM,见”沙箱”节)。这是一个重要设计方向声明,源码侧已确认 workflow 工具与 sandbox 存在(flag-gated),但本阶段未逐行核对 agent()/parallel()/pipeline()/workflow() 这些具体 API 在源码中的实现细节,落地程度需要后续对 packages/opencode/src/workflow/ 目录做更完整的读码验证。

Skill / 插件体系

  • Skills:带 YAML frontmatter(namedescription)的 Markdown SKILL.md 文件,通过 skill/index.ts(356 行全文读完)glob 发现,路径覆盖项目 .mimocode/{skill,skills}/**/SKILL.md以及外部工具互操作目录.claude/skills/**/SKILL.md.agents.codex.opencodeEXTERNAL_SKILL_PATTERN = "skills/**/SKILL.md")——即 MiMoCode 可以直接消费 Claude Code / Codex / OpenCode 编写的 SKILL.md,无需转换。按需通过 skill 工具加载(而非通过 Read,compose.txt 明确要求走 skill 工具而非 Read)。远程 skill 包可通过 URL + index.json 清单拉取(skill/discovery.ts,116 行)。
  • Compose 模式内置的技能衍生自两个外部开源技能项目(各自带 LICENSE 归属声明):Karpathy 的 “Simplicity” 指南与 Jesse Vincent 的 “superpowers” 项目。
  • 插件:plugin/index.ts + plugin/loader.ts 等——@mimo-ai/plugin 包定义 ToolDefinition 契约;插件可注册自定义工具、挂载生命周期钩子(tool.definitionexperimental.chat.messages.transformexperimental.text.completesession.userQuery.pre/post、文件钩子)。内置一方插件:cloudflare.tscodex.tsgithub-copilot/mimo.tscheckpoint-splitover.tssubagent-progress-checker.ts
  • MCP 客户端支持:mcp/index.ts(939 行)+ OAuth 流程(mcp/oauth-provider.tsmcp/oauth-callback.tsmcp/auth.ts)——完整的外部 MCP server 集成,带自有 OAuth 交互,不只是一个 stub。

自进化能力(自我改进 / 学习型记忆 / eval 驱动纠错)

首要、显式命名的一对功能——dreamdistill——均实现为原生隐藏 subagent,带专用 prompt 与自动调度,官方博客将其列为独立的 evolution 主题:

  • Dreamagent/prompt/dream.txt,156 行全文读完;博客 4.2 节交叉印证):每 7 天自动触发一次的记忆巩固 pass。把原始 SQLite trajectory DB 当作真相来源,memory .md 文件视为派生索引;读取近期 checkpoint/session notes,用 SQL 查询模板(针对 assistant/tool-call/task/actor_registry 表,模板直接烘焙进 prompt)对候选”durable facts”做交叉验证后编辑项目 MEMORY.md(章节:Rules / Architecture decisions / Discovered durable knowledge / Patterns / Gotchas),有大小预算(<200 行 / <10KB)约束,且明确要求仅在强证据(用户明确陈述、设计决策、或跨会话重复模式)下才提升事实置信度,无法验证的声明须标 [unverified]。博客侧的表述更聚焦”合并去重、路径有效性校验、压缩收敛”这一操作层面描述,两者互补但视角不同(源码 prompt 强调证据强度门槛,博客强调维护动作类型),未见冲突。
  • Distillagent/prompt/distill.txt,200 行全文读完):每 30 天窗口的工作流打包 pass。先盘点现有 skills/agents/commands/plugins 避免重复,从 trajectory DB 中挖掘重复工具/命令序列(SQL 模板已内置),仅对高置信、≥2 次出现的候选创建最小充分产物:SKILL.md、自定义 subagent(.mimocode/agent/<name>.md)、命令模板,或(较少见)插件生命周期钩子。明确禁止发明调度器;明确鼓励把”Created nothing”当作合法的成功结果输出。博客侧表述一致:“聚焦流程而非知识,识别重复工作模式并固化为可复用技能、CLI 命令、自定义 agent、SOP 文档等”。
  • 自动触发调度session/auto-dream.ts,130 行全文读完):dream 每 7 天触发(配置 dream.interval_days,除非 dream.auto === false 否则默认开启),distill 每 30 天(distill.interval_days);两者都受项目年龄门槛与最小 10 秒 spawn 间隔约束;在一个新顶层会话的第一步通过动态 import 的 AppRuntime 以后台 detached session 形式触发。
  • 这与任务简报中”eval 驱动自我纠错”的提法有出入:这是记忆/工作流沉淀式的自我改进(策展 agent 记住什么、打包了什么工作流),而非基于梯度的微调或 benchmark 驱动的 prompt 搜索——本阶段未在代码中发现自动化 eval-harness 对系统提示或模型权重打分迭代的证据。

可观测性(日志 / trace 格式)

  • 结构化 bus 事件用于指标:metrics.model_call(ttft_ms、latency_ms、cached_read_tokens、tokens in/out、model/provider id、finish_reason)、metrics.tool_call(输入/输出字节数、status)、metrics.agent_request(phase、task_type、surface、files_changed、validation_status)——定义于 metrics/event.ts(43 行全文读完),经内部 Bus 发布,由 metrics/subscriber.ts/metrics/client.ts 消费(本阶段未读,具体后端未知,可能是小米自有遥测系统,所读文件里未见外部 exporter 配置)。
  • 纯文本轮转日志(util/log.ts,本阶段读了前 90/234 行):数据目录下按 session/day 加时间戳分文件,DEBUG/INFO/WARN/ERROR 级别,单文件 50MB / 总量 200MB 上限,dev 模式归档前一份 dev.log
  • Effect 框架 tracing:Effect.withSpan("Tool.execute", {attributes: {"tool.name", "session.id", "message.id", "tool.call_id"}}) 式 span 与命名的 Effect.fn("Service.method") 包裹在代码库中普遍出现,提供结构化、命名的执行 span,但本阶段所读文件范围内未发现显式 OpenTelemetry collector/exporter 接线——tracing 更像内部/Effect-native,而非导出到外部 APM。
  • Trajectory 序列化(session/trajectory.ts,99 行全文读完)通过 session.userQuery.post 钩子 payload 向插件暴露完整 session 消息/part 历史(data: URL 会被摘要以保持 JSON 安全)——这是插件向外部 eval/训练管线转运轨迹数据的机制,但本阶段未发现有第一方插件在做这件事(已看到的内置插件 cloudflare/codex/github-copilot/mimo/checkpoint-splitover/subagent-progress-checker,从命名看均非训练数据导出器,未逐个打开确认)。

安全与权限(审批门、密钥管理)

  • 权限模型(permission/index.ts,480 行全文读完):{permission, pattern, action: allow|deny|ask} 规则集,按工具调用模式逐条评估。显式 deny 永远优先,即便存在已持久化的”always approve”规则。FORCED_ASK 集合(目前仅 bash_delete)永远不能被通配符 allow 规则预授权,始终需要一次现场人工 ask(仅可通过工具侧显式环境变量 opt-out 如 MIMOCODE_AUTO_APPROVE_DELETE 绕过)。
  • 每次 ask 的三级解析顺序:(1) 规则集本身、(2) forced-ask 覆盖、(3) 此前已持久化的”always”批准。非交互式调用方(系统生成的后台 agent:checkpoint-writer/dream/distill)会被标记 interactive: false,遇到需要 ask 的场景直接干净地以 DeniedError 失败而不是挂起——代码注释称之为”provably cannot hang”。
  • Orchestrator-peer 转发:后台子会话的 ask 可以转发给人类/orchestrator 而非自动拒绝,direct-user reply 路径与 orchestrator 的 session approve 路径之间做了幂等去重,并设硬性 5 分钟拒绝超时,确保无人应答的转发 ask 也会终止。
  • processor.ts 中的 doom-loop 检测:3 次连续相同工具调用强制发起 permission.ask({permission: "doom_loop", ...}),即便该工具本应被自动允许。
  • bash.ts 中的破坏性命令检测:硬编码的删除命令集(rmrmdir、PowerShell Remove-Item 别名)与破坏性 git 子命令集(reset --hardclean -f*branch -Dpush --forcestash drop/clear 等)驱动比通用模式匹配更严格的权限门控。
  • 凭证存储(auth/index.ts,98 行全文读完):auth.json 存于数据目录,文件权限 0o600;三种鉴权类型(oauth refresh/access/expires、api key、wellknown key+token);MIMOCODE_AUTH_CONTENT 环境变量允许 CI/无头环境注入凭证而不落盘。

沙箱与执行隔离

  • Bash 工具没有 OS 级沙箱——命令通过 ChildProcessSpawner/cross-spawn 直接跑在宿主机上。隔离完全依赖权限门层(对命令做 tree-sitter AST 解析以提取文件路径与破坏性命令模式),而非容器化、命名空间隔离或虚拟机。
  • Workflow 工具有真实沙箱workflow/sandbox.ts(286 行全文读完)通过 QuickJS-WASM(quickjs-emscripten-core,singlefile 编译,使 bun build --compile 能产出单一自包含二进制)运行任意 JS,带可配置墙钟截止时间(默认 12 小时)与内存上限(默认 64MiB),以及确定性 PRNG 播种(seed = hash(runID)),专门用于保证恢复/重放的工作流运行得到相同的伪随机序列。
  • packages/containers/ 的 Docker 镜像只是 CI 构建加速镜像(Ubuntu 24.04 基础 + bun-node + rust + tauri-linux + publish 变体),不用于 agent 工具执行
  • Orchestrator 子会话通过 git worktree 获得文件系统级隔离(--isolate flag → <data>/worktree/<projID>/<task-slug> 下专属 worktree + 分支),这是 git 层面而非进程层面的隔离机制(防止并行子会话编辑同一仓库产生并发写冲突,不是安全沙箱)。

与模型的协同设计

  • session/system.tsprovider() 派发表按 model-ID 子串硬编码 9 种不同系统提示变体(见 Prompt 设计一节)——这是针对多个模型家族的 prompt 级协同调优的直接证据,不只针对 MiMo 自家模型。
  • Provider 层发现的 MiMo 专属调优:
    • provider/provider.tsDEFAULT_CHUNK_TIMEOUT = 480_000 毫秒(8 分钟),注释明确写”Tuned for mimo-v2.5-pro on MiMo Router whose cold-path TTFT after context rebuild can dip to ~5 minutes silent”
    • provider/transform.tsmaxOutputTokens()providerID === "mimo" || "xiaomi" || model.id.includes("mimo") 特殊处理,使用专属 MIMO_OUTPUT_TOKEN_MAX 常量而非通用的 min(model.limit.output, OUTPUT_TOKEN_MAX)
    • provider/error.tsMIMO_GATEWAY_PROVIDERS = new Set(["xiaomi", "mimo"]) 用于网关专属错误解析
    • 多个 provider 配置(类 OpenRouter 风格)的出站请求携带 HTTP-Referer: https://mimo.xiaomi.com/coder/ 品牌归属 header
  • GPT 系模型拿到结构上不同的工具:apply_patch 替代 edit/writeregistry.tsusePatch 检查基于 modelID 含 “gpt-” 且不含 “oss”/“gpt-4”)——这是模型专属的工具面适配,不只是 prompt 适配。
  • README 显示 MiMo-V2.5 作为 CLI 默认/免费通道(“MiMo Auto”)随附,同时支持多 provider(OpenAI/Anthropic/DeepSeek/Kimi 等)——与 provider/* 所见一致:一个多 provider 抽象层,MiMo/Xiaomi 是其中一个一等公民 in-house provider,而非 MiMo 专属 harness。
  • 本阶段(含博客)未发现任何训练时协同设计的证据(如文档化的 RL 环境规格、模型专门为之微调的工具调用格式、引用 MiMo-V2.5 训练的联合 eval harness)。已确认的都是推理时协同设计(prompt、超时、token 上限、工具面),而非联合训练的证据。

轨迹利用(session/trajectory 是否反哺训练/评测)

  • 完整 session trajectory(消息+parts、工具调用/结果、推理、token、成本)持久化到本地 SQLite DB(<data>/mimocode.db)——这正是 dream/distill 用只读 SQL 直接查询用于自我改进的同一份 DB(见”自进化”节)。
  • session/trajectory.ts 提供 serializeTrajectoryMessages() 函数,经 session.userQuery.post 钩子 payload(trajectory: trajectoryForStep(msgs, handle.message))暴露给插件——即任何插件都可以消费每轮的全保真轨迹。
  • 本阶段未发现将轨迹对外输出用于模型训练或 benchmark 构建的一方管线证据(插件目录名称与已读文件中均未见 HF-dataset 导出器或 eval-harness 提交代码)。share/ 目录(会话分享)存在但未打开读取——更可能与”把会话链接/转录分享给另一个人类”有关,而非训练管线;本阶段标注为未读/未确认,不做断言。
  • 内部已确认的三条轨迹消费路径:(a) checkpoint-writer subagent(上下文压缩)、(b) dream(记忆巩固)、(c) distill(工作流打包)——即轨迹被复用于harness 自身记忆/技能状态的自我改进,而非(就本阶段所见)用于重训底层 LLM。
  • 官方博客的评测方法论本身也构成一种”轨迹利用”的外部证据:人类双盲 A/B 测试——在开发者真实项目里并行启动两个匿名 coding agent 做同一任务,开发者独立打分,辅以自动轨迹打分与 diff 量化做三角验证。内测覆盖 576 名开发者、474 个真实私有仓库,产生 1213 组有明确胜负判定的 A/B pair。核心结论:执行步数 ≤200 时两个系统胜率接近 50%;步数 >200(含多轮用户交互)时 MiMo Code 胜率升至 超过 65%。这类评测数据本身依赖对轨迹的自动打分,但博客未披露该评测管线是否与 dream/distill 共享同一条数据流,本阶段不做推断。

与同类 harness 的关键差异(初步观察,留待 synthesis 阶段做跨 harness 系统对比)

  1. Goal gate 是本 fork 相对 OpenCode 上游最显眼的加法——用户显式声明自然语言停止条件、由独立 LLM judge 复核是否真的做完,而不是依赖模型自我声明停止;这类”完成度验证”机制在同类 harness 中并不常见(多数只做步数上限/超时兜底)。
  2. Checkpoint-writer + 分层 rebuild 是一套比”单纯摘要式压缩”更结构化的长程上下文管理方案——固定 11 字段模板、单写者不变量、20%/45%/70% 分级触发、rebuild 时约 65K token 的分层注入预算,这套设计在博客里被明确对标”经典摘要压缩的信息稀释困境”,是该团队认为的核心差异化卖点。
  3. Dream/Distill 双周期自我进化(7 天记忆巩固 + 30 天工作流蒸馏)把”自我改进”限定在记忆策展与工作流打包层面,而非训练/eval 驱动的模型层自我改进——这是一个务实但边界清晰的自进化定位,dossier 撰写时不应把它与”agent 自我训练/RL 自我提升”混为一谈。

原始源码定位

  • repo: https://github.com/XiaomiMiMo/MiMo-Code
  • commit/version analyzed: 7f9060ca3d7fa712421ff8987e9ccf98e085475c(shallow clone --depth 1,默认分支,拉取时间 2026-07-07;HEAD commit message: fix(compose): strengthen skill invocation prompt and fix RLHF resistance (#1598),作者 Yihan Yan yanyihan@xiaomi.com,2026-07-06 23:16:52 +0800)
  • 关键文件列表(相对 repo 根目录,均见于 packages/opencode/src/ 下除非另注明):
    • session/prompt.ts(4039 行,主循环 while(true)
    • session/processor.ts(984 行,流事件状态机)
    • session/system.ts(130 行,系统提示装配/per-model 选择)
    • session/goal.ts(goal gate)、session/max-mode.ts(410 行)、session/compaction.ts(561 行)、session/checkpoint.ts(1560 行)
    • session/auto-dream.ts(130 行,dream/distill 调度)
    • session/trajectory.ts(99 行,轨迹序列化)
    • tool/tool.ts(167 行)、tool/registry.ts(447 行)、tool/actor.ts(845 行)、tool/bash.ts(821 行)、tool/bash_token_efficient.ts(未直接读,仅经设计文档确认存在)
    • memory/service.ts(145 行,SQLite FTS5 BM25)
    • permission/index.ts(480 行)、auth/index.ts(98 行)
    • skill/index.ts(356 行)、skill/discovery.ts(116 行)
    • mcp/index.ts(939 行)、mcp/oauth-provider.tsmcp/oauth-callback.ts
    • metrics/event.ts(43 行)、metrics/subscriber.ts/metrics/client.ts(未读)
    • util/log.ts(234 行,读前 90 行)
    • workflow/sandbox.ts(286 行,QuickJS-WASM 沙箱)
    • agent/prompt/dream.txt(156 行)、agent/prompt/distill.txt(200 行)、agent/prompt/checkpoint-writer.txt(167 行)
    • session/prompt/compose.txt(131 行)、session/prompt/{default,anthropic,beast,codex,gpt,gemini,kimi,deepseek,glm,minimax,trinity}.txt
    • docs/harness/MiMo Orchestrator Mode.en.md(141 行)、docs/harness/MiMo Token Efficient Mode.en.md
    • LICENSEnix/opencode.nixpackages/opencode/src/skill/compose/LICENSE-karpathyLICENSE-superpowers

一手源存档(sources/)

/Users/zhao/projects/self-wiki/ai-research/sources/harness/mimo-code/ 下已保存(clone 本身已清理,不占用磁盘):

  • NOTES.md(179 行,逐维度调研笔记,本 dossier 大部分源码引用的一手依据)

  • key-files/agent-prompt/agent.tscheckpoint-writer.txtdistill.txtdream.txt

  • key-files/docs/MiMo Orchestrator Mode.en.mdMiMo Token Efficient Mode.en.md

  • key-files/memory/service.ts

  • key-files/permission/index.ts

  • key-files/session-prompt/anthropic.txtcompose.txtdefault.txtorchestrator.txt

  • key-files/session/auto-dream.tsgoal.tsprocessor.tsprompt.main-loop-excerpt.L2380-3200.tssystem.tstrajectory.ts

  • key-files/skill/index.ts

  • key-files/tool/actor.txtbash.txtmemory.txtregistry.tsskill.txttool.ts

  • blog-long-horizon.md:官方博客 https://mimo.xiaomi.com/en/blog/mimo-code-long-horizon(2026-06-10 发布,“MiMo Code: Scaling Coding Agents to Long-Horizon Tasks”)的完整抓取存档(本阶段 2026-07-07 通过 CloakBrowser 抓取),内容已消化进本 dossier 各节(Max Mode/Goal 具体数字、四层记忆、checkpoint 触发阈值、Dynamic Workflow 设计动机、人类双盲 A/B 测试方法论与数据)。