第 2 课

AGENTS.md 规则、权限配置与 build / plan 模式

写 AGENTS.md 项目规则并了解全局规则与 CLAUDE.md 兼容,用对象语法配 allow / ask / deny 权限并用 mimo debug config 确认,让 build 模式写 hello.py 并运行、观察规则遵守情况,用 --agent plan 只读规划,再用 mimo debug agent 看懂合并后的权限表与 hardPermission。

图文24 分钟

课程目录第 2 / 3 课

学习位置仅保存在当前浏览器,有效期 180 天。

01 / 图文教材

图文教材

本课依据:MiMo Code 官方文档「规则」https://mimo.xiaomi.com/zh/mimocode/rules 、「权限」https://mimo.xiaomi.com/zh/mimocode/permissions 、「模式」https://mimo.xiaomi.com/zh/mimocode/modes 、「CLI 子命令」https://mimo.xiaomi.com/zh/mimocode/cli-subcommands (2026-10-29 核对,MiMo Code 0.1.16)。实验接着第 1 课的 ~/mimo-demo 项目和本地模型做。

这一课做完你会得到什么

给项目写一份 AGENTS.md 规则,用对象语法配好「哪些命令自动放行、哪些要问、哪些禁止」,然后让 MiMo Code 在 build 模式下真正写文件、跑命令,再切到只读的 plan 模式做规划,最后用 mimo debug 看清规则和权限最终是怎么生效的。

第 1 步:写项目规则 AGENTS.md

AGENTS.md 里的内容会被放进模型的上下文,作用类似 Cursor 的规则。在项目根目录建一份:

cd ~/mimo-demo
cat > AGENTS.md <<'EOF2'
# mimo-demo 项目规则
- 始终用简体中文回复。
- Python 代码必须带类型注解,只用标准库。
- 新增函数时同时在 test_*.py 里写 unittest 测试。
EOF2

规则文件的几个要点(来自官方「规则」页):

位置作用
项目根目录 AGENTS.md项目规则,建议提交到 Git 和团队共享
~/.config/mimocode/AGENTS.md全局个人规则,所有会话都生效
CLAUDE.md、~/.claude/CLAUDE.md兼容 Claude Code,只在没有对应 AGENTS.md 时使用
  • 查找顺序:先从当前目录向上找 AGENTS.md / CLAUDE.md,再找全局文件;同一类里第一个找到的生效。
  • 在 TUI 里运行 /init,MiMo Code 会扫描项目自动生成 AGENTS.md;已有文件时会在原文件基础上补充。
  • 不想读 Claude Code 的文件,设置环境变量 MIMOCODE_DISABLE_CLAUDE_CODE=1。

第 2 步:用对象语法配权限

每条权限规则的结果只有三种:allow 直接运行,ask 先问你,deny 阻止。把下面的 permission 合并进第 1 课的 .mimocode/mimocode.json(和 model、provider 并列):

{
  "permission": {
    "edit": "allow",
    "bash": {
      "*": "ask",
      "python3 *": "allow",
      "rm *": "deny"
    }
  }
}

读法:

  • edit 管所有改文件的工具(edit、write、patch、multiedit),这里全部放行。
  • bash 用对象语法按命令匹配:默认每条命令都要问,python3 开头的直接跑,rm 开头的一律禁止。
  • 多条规则都匹配时,最后匹配的那条生效。所以通配的 "*" 写在最前面,具体规则写在后面。
  • * 匹配任意多个字符,? 匹配一个字符。注意 "python3 *" 能匹配 python3 hello.py,但单写 "python3" 只匹配不带参数的命令。

不写任何配置时,官方默认值相当宽松:大多数权限是 allow;只有 doom_loop(同一个工具用相同输入连续调用 3 次)和 external_directory(访问项目目录之外的路径)默认是 ask。遇到 ask 时,TUI 提供三个选项:once 只批这一次,always 本会话内放行同类请求,reject 拒绝。

用下面的命令确认配置已经被读到:

mimo debug config | grep -A 8 '"permission"'

对照结果(2026-10-29 实测,节选):

  "permission": {
    "edit": "allow",
    "bash": {
      "*": "ask",
      "python3 *": "allow",
      "rm *": "deny"
    }
  },

第 3 步:build 模式写文件、跑命令

build 是默认模式,所有工具都可用。用 mimo run 交给它一个完整的小任务:

mimo run "创建 hello.py:定义函数 greet(name) 返回 \
'Hello, <name>!',在 __main__ 里打印 greet('MiMo')。\
然后运行 python3 hello.py 并告诉我输出。"

对照结果(实测,本地 Gemma 4 E2B,节选):

> build · gemma-4-e2b

← Write hello.py
Wrote file successfully.

$ python3 hello.py
Hello, MiMo!

脚本已创建并运行。输出如下:
Hello, MiMo!

生成的 hello.py:

def greet(name: str) -> str:
    return f"Hello, {name}!"

if __name__ == "__main__":
    print(greet("MiMo"))

可以看到:

  • 回复是中文,函数带了类型注解,说明 AGENTS.md 的前两条规则生效了。
  • python3 hello.py 匹配 "python3 *": "allow",没有弹出确认就直接执行了。
  • 第三条规则「同时写 unittest 测试」被这个 2B 小模型忽略了,项目里没有生成 test_*.py。规则是写给模型的指令,不是强制约束;模型越强,遵守得越好。下一课会用技能和自定义命令把「补测试」变成一步明确的操作。
  • 实测时这个小模型在同一轮里连发了 3 次相同的写文件和运行命令,结果一样所以无害。换成官方 mimo-v2.6 模型或更大的本地模型就不会这样;如果同一调用连续重复 3 次,doom_loop 权限会弹出确认。

确认结果并提交,方便后面对比:

python3 hello.py
git add -A && git commit -qm "build step"
Hello, MiMo!

第 4 步:plan 模式只读规划

plan 模式用来分析和出方案。按官方「模式」页,在 plan 下 write、edit、patch、bash 默认被禁用,唯一例外是可以编辑 .mimocode/plans/*.md 来写计划本身。命令行里用 --agent plan 选择它,TUI 里按 Tab 切换:

mimo run --agent plan "阅读 hello.py,给出让 greet 支持\
命令行参数 --name 的修改计划,只列步骤。"
git status --short

实测对照(2B 本地模型,节选;git status --short 无输出):

> plan · gemma-4-e2b

• Understand the current implementation of the greet
  function in hello.py, focusing on its signature and
  argument handling. Unknown Agent
✗ actor failed
Error: Invalid arguments for the actor tool:
✖ Invalid option: expected one of "explore"|"general"
  → at operation.subagent_type

这一轮要如实说明:

  • plan 模式想把「阅读代码」派给子智能体,但这个 2B 小模型填错了子智能体类型(只允许 explore 或 general),工具调用被拒,它又反复重试同一个错误调用。实测等了约 6 分钟仍没有给出计划,我们按 Ctrl+C 结束了它(脚本里用的是 kill)。官方 mimo-v2.6 模型或更大的本地模型不会这样。
  • 重点在第二行命令:git status --short 没有任何输出,hello.py 原样未动。也就是说,即使模型表现不好,plan 模式也没有改动项目文件,这正是它适合「先看方案再动手」的原因。
  • 如果你的模型也卡在类似的循环里,换更强的模型,或在提示里写明「不要调用子智能体,直接读 hello.py」。

第 5 步:用 mimo debug 看权限最终怎么合并

模式、全局默认、你的配置会合并成一张规则表。mimo debug agent <名字> 能直接看到这张表,不用调模型:

mimo debug agent plan > /tmp/plan-agent.json
python3 - <<'EOF2'
import json
d = json.load(open("/tmp/plan-agent.json"))
for r in d["permission"]:
    if r["permission"] != "external_directory":
        print(r["permission"], r["pattern"], r["action"])
print("--- hardPermission")
for r in d["hardPermission"]:
    print(r["permission"], r["pattern"], r["action"])
EOF2

对照结果(实测):

* * allow
doom_loop * ask
skill * allow
plan_exit * deny
question * deny
read * allow
read *.env ask
read *.env.* ask
read *.env.example allow
question * allow
plan_exit * allow
edit * allow
bash * ask
bash python3 * allow
bash rm * deny
--- hardPermission
edit * deny
edit .mimocode/plans/*.md allow
edit ../.local/share/mimocode/plans/*.md allow

看懂这张表:

  • 普通的 permission 列表从上往下合并,最后匹配的生效(question、plan_exit 是 plan 模式用来向你提问、退出计划的内部工具);我们在 mimocode.json 里写的 edit 和 bash 规则排在最后,所以覆盖了前面的默认值。
  • plan 模式的只读限制写在单独的 hardPermission 里:edit 一律拒绝,只放行项目里的 .mimocode/plans/*.md(和数据目录里的 plans)。所以即使项目配置写了 "edit": "allow",plan 也改不了代码。
  • 实测 0.1.16 对 .env 文件的默认是 ask(先问你),官方「权限」页写的是 deny。想要稳妥,在自己的配置里显式写上 "read": {"*.env": "deny"}。

再看一下本机有哪些主代理和子代理:

mimo agent list

对照结果(实测,每行下面的权限明细省略):

build (primary)
checkpoint-writer (subagent)
compaction (subagent)
distill (subagent)
dream (subagent)
explore (subagent)
general (subagent)
plan (primary)
summary (subagent)
title (subagent)

primary 是你能直接对话的主模式;explore、general 是主模式委派任务用的子代理;其余几个负责压缩上下文、生成标题、整理记忆等后台工作。实测 mimo run 打印完回答后,进程又过了约 2 分钟才退出,这段时间服务端还在继续生成,应该就是这些后台代理在调用同一个模型。用慢速本地模型时这段等待尤其明显。

官方「模式」页还介绍了第三个主模式 compose:它带 13 个 compose: 开头的内置技能(测试驱动开发、调试、写计划、执行计划、代码审查等),在 TUI 里按 Tab 循环或在消息里写 @compose 调用。实测 0.1.16 的 mimo agent list 里没有列出 compose,本课没有对它做实测。

小结

  • AGENTS.md 写项目规则,~/.config/mimocode/AGENTS.md 写个人规则,/init 可以自动生成;规则是给模型的指令,小模型不一定全遵守。
  • permission 三种结果 allow / ask / deny;对象语法按命令或路径匹配,最后匹配的生效,通配写前面。
  • build 能写能跑;plan 由 hardPermission 锁死只能写 .mimocode/plans/*.md。命令行用 --agent plan,TUI 用 Tab。
  • mimo debug config 看合并后的配置,mimo debug agent <名字> 看某个模式最终的权限表。