适用工具:Claude Code · Codex · Cursor · GitHub Copilot · 验证于 2026-08
memory 文件是 agent 每次会话都要付费加载的常驻上下文:写少了 agent 重复犯错,写多了反而淹没关键指令。本章给出从起步、写法、调优,到跨工具共享与 CI 门禁的完整维护路径。每条做法都对应到四家官方文档的原文。
场景:新项目第一次写 memory 文件,或者 /init 生成了一大篇目录描述和依赖清单,不知道该留什么。
做法:
起步只保留三类,20-30 行足够:一句话项目概述、无法从代码猜出的命令、与工具默认不同的约定。Claude Code 官方给出的单文件上限是 200 行,超过会降低遵从度。
# weibo-chat-auto — Agent 指南
Node 20 CLI,抓取微博私信并生成回复草稿;核心状态机在 src/session.mjs。
## 常用命令
| 任务 | 命令 |
| --- | --- |
| 全部测试 | `npm test` |
| 单文件测试 | `node --test test/session.test.mjs` |
## 约定
- 所有网络请求走 src/http.mjs 的封装,不直接 fetch
- 提交信息用中文,首行不超过 50 字符
依据:Claude Code 官方原话:”For each line, ask: would removing this cause Claude to make mistakes? If not, cut it”,并明确警告臃肿的 CLAUDE.md 会让真正的指令被无视(Claude Code 官方指南);Cursor 官方同样把”复制整份 style guide”和”记录 agent 已知的常用命令”列为要避免的写法(Cursor Rules)。
边界:删行判据是”会不会犯错”,不是行数本身——出过事故的硬契约再长也要留;组织级 managed CLAUDE.md 的合规条款由安全团队定,不适用此判据。
反模式:把 /init 或 LLM 生成的全文直接提交——Claude Code 的 /doctor 检查会主动提议删掉其中能从代码推断的目录布局、依赖列表和架构综述(memory)。
场景:agent 每次自己猜测试命令,猜错了浪费一轮;或者明明只改了一个文件却跑全量测试。
做法:
用”任务 → 命令”两列表格组织,每条命令带 flag、带路径、带占位符示例:
## 常用命令
| 任务 | 命令 |
| --- | --- |
| 全部测试 | `pnpm turbo run test --filter <package>` |
| 单个用例 | `pnpm vitest run -t "<test name>"` |
| Lint | `pnpm lint --max-warnings 0` |
| 本地运行 | `pnpm dev`(端口 5173) |
| 重建快照 | `pnpm test -u`(警告:只在确认 UI 改动符合预期后跑) |
dead-script 规则报 error(见 1.6)。依据:Claude 官方以对比例证说明精确度要求——”Run npm test before committing” 优于 “Test your changes”(memory);agents.md 官方示例同样精确到 pnpm vitest run -t "<test name>",且 FAQ 确认 agent 会自动执行文件里列出的检查命令并修复失败(agents.md)。
边界:git、npm 的基础用法不用写——Cursor 官方明确 “Agent already knows common tools like npm, git, and pytest”(Cursor Rules),写了只是消耗上下文。
反模式:”改完请跑测试并确保通过”——没有命令,agent 只能猜 runner 和入口。
场景:agent 改了生成物目录、碰了密钥文件、擅自加了运行时依赖;或者反过来,每一步都停下来问你。
做法:
把行为边界写成三个固定小节,每条 never 附一句原因:
## 边界
### Always
- 改完 JS 文件后运行 `npm test`
- 提交前运行 `npm run lint`
### Ask first
- 新增运行时依赖
- 修改 .github/workflows/ 下的任何文件
- force push
### Never
- 修改 dist/ 与 src/generated/(构建产物,源头在 codegen 配置)
- 读取或打印 .env* 文件内容(含凭据)
对必须 100% 拦截的 never 条目,再配一层 hooks 或 permissions deny 兜底——memory 文件是 context,不是强制配置。
依据:Codex 官方示例文件本身就使用这三种句式——”Always run npm test…”、”Ask for confirmation before adding new production dependencies”、”Never rotate API keys without notifying the security channel”(Codex AGENTS.md);Claude 官方明确 memory 文件”treats them as context, not enforced configuration”,要无条件阻止某动作需用 PreToolUse hook(memory)。
边界:never 列表超过十条说明约束放错了层——可机检的(路径、命令模式)挪进 hooks 与 permissions(见 05 章),memory 里只留需要判断的边界。
场景:规则明明写了,agent 就是不遵守。
做法:
先确认文件真的加载了。Claude Code 在会话里跑 /context,检查 Memory files 列表;Codex 用一条命令让它复述:
codex --ask-for-approval never "Summarize the current instructions."
对关键条目加强调词提升遵从,这是 Anthropic 官方确认有效的手法:
- IMPORTANT: src/db/migrations/ 下已合并的文件 NEVER 修改;要改 schema 就新建迁移
依据:Claude Code 官方原话:”Treat CLAUDE.md like code: review it when things go wrong, prune it regularly, and test changes by observing whether Claude’s behavior actually shifts”,并确认 “adding emphasis (e.g., ‘IMPORTANT’ or ‘YOU MUST’)” 可提升遵从(Claude Code 官方指南)。
边界:强调词会通胀——满篇 IMPORTANT 等于没有 IMPORTANT。一条规则反复强调仍不生效、且它必须在固定时点执行(每次提交前、每次编辑后),官方的建议是改写成 hook 而不是继续加粗(memory · Troubleshoot)。
场景:团队混用多个工具,仓库里同时躺着 AGENTS.md、CLAUDE.md、.cursor/rules/,内容开始互相漂移。
做法:
AGENTS.md 做主文件:这是 60k+ 开源项目采用的开放格式,Cursor 与 Copilot 原生读取(agents.md、Cursor Rules、Copilot 支持矩阵)。Claude Code 只认 CLAUDE.md,软链过去:
ln -s AGENTS.md CLAUDE.md
git add AGENTS.md CLAUDE.md
需要追加 Claude 专属内容(或在 Windows 上,建 symlink 需要管理员权限)时,改用 import:
@AGENTS.md
## Claude Code
- src/billing/ 下的改动先用 plan mode
/context,确认 CLAUDE.md 出现在 Memory files 下。monorepo 想放嵌套文件之前,先弄清四家”就近”语义并不相同:
| 工具 | 官方定义的加载语义 |
|---|---|
| Claude Code | 从 cwd 向上收集每层 CLAUDE.md 全部拼接,越近越靠后;cwd 之下的子目录文件按需加载(memory) |
| Codex | 从项目根向下走到 cwd,每目录至多取一个文件拼接,越近越靠后;按 cwd 而不是被编辑的文件(AGENTS.md discovery) |
| Cursor | 嵌套 AGENTS.md 与父目录合并,更具体的优先(Cursor Rules) |
| Copilot | VS Code 里最近的 AGENTS.md 优先;CLI 文档只列出读取 AGENTS.md/CLAUDE.md/GEMINI.md,未定义优先级(仓库指令 · 支持矩阵) |
依据:ln -s AGENTS.md CLAUDE.md 与 @AGENTS.md import 都是 Claude 官方文档给出的方案,包括 Windows 例外(memory · AGENTS.md)。
边界:Codex 的就近按启动目录算——编辑 services/x.ts 不会加载 services/AGENTS.md,除非从那个目录启动;依赖嵌套文件做关键约束之前,先在目标工具里验证它真的加载了(1.4 的第 1 步)。
反模式:每个工具各写一份内容相似的文件——三个月后它们描述的是三个不同的项目。
场景:memory 文件随时间腐烂:模板占位符没填就提交、表里的命令随重构失效、写了标题没填内容。
做法:
把本手册的 tools/agentsmd-lint(零依赖单文件,Node ≥ 20)复制进你的仓库,本地检查:
node tools/agentsmd-lint/index.mjs AGENTS.md
node tools/agentsmd-lint/index.mjs --max-lines 150 AGENTS.md CLAUDE.md
五条规则:max-lines(超长降低遵从)、placeholder(未填的模板占位符)、vague(agent 无法执行的模糊措辞)、dead-script(引用了 package.json 里不存在的 npm 脚本)、empty-section(空标题节)。
发现 error 时退出码为 1,直接接进 CI:
# .github/workflows/agentsmd.yml
name: agentsmd-lint
on:
pull_request:
paths: ["AGENTS.md", "CLAUDE.md"]
jobs:
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with: { node-version: 20 }
- run: node tools/agentsmd-lint/index.mjs AGENTS.md
修复顺序:先 dead-script(命令必须真实可跑,对应 1.2),再 vague(把模糊措辞换成具体条件与数字,对应 1.4)。
依据:Claude 官方要求定期 review memory 文件、移除过期与冲突指令(memory · Consistency);agents.md 官方 FAQ 把该文件定位为 “living documentation”(agents.md),活文档需要门禁防腐。
边界:linter 只查得出形式问题(占位符、死命令、空节),查不出”这条规则本身还对不对”——内容层面的修剪仍靠 1.4 的行为观察。
反模式:warning 长期挂着不修——门禁只对 error 生效时,warning 堆积等于没有门禁。