第 3 章 · Agent 文件层 / Agent Files
本章观点
很多教程讲 Agent 时只讲代码:怎么调 API、怎么写 tool、怎么跑 loop。但真去做一个能跑稳的 Agent 项目,你会发现代码只占 30%,剩下 70% 是文件——一组 markdown 和 json,规定 Agent 在这个项目里该怎么做事。
这一章的核心判断:
Prompt 是临时指令,md 文件是长期上下文。Agent 越复杂,越需要用文件沉淀规则、记忆、技能、测试和验收标准。
为什么必须用文件而不是塞进 prompt?三个原因:
- 持久:文件跨会话存在,关掉终端再开还在。
- 可版本化:进 git,每次改规则都有 diff,能 review 能回滚。
- 分层加载:Agent 按需读相关文件,不用每次把所有规则塞进 context。
这一章讲 Agent 项目里常见的 13 种文件,以及每个文件该写什么、不该写什么。
3.1 文件层全景图
先一张表看完所有文件:
| 文件 | 类别 | 作用 | 谁读 |
|---|---|---|---|
README.md | 项目说明 | 项目是什么、怎么跑 | 人 + Agent |
SPEC.md | 项目说明 | 需求、目标、约束、验收标准 | Agent 主读 |
CHANGELOG.md | 项目说明 | 版本变更记录 | 人 + Agent |
AGENTS.md | Agent 指令 | 通用 Coding Agent 项目规则 | 所有 Coding Agent |
CLAUDE.md | Agent 指令 | Claude Code 专属上下文 | Claude Code |
.cursor/rules | Agent 指令 | Cursor 专属规则 | Cursor |
Codex instructions | Agent 指令 | OpenAI Codex 专属指令 | Codex CLI |
SKILL.md | Agent 指令 | 单个 Skill 的说明文件 | Claude(按需触发) |
.mcp.json | Agent 指令 | MCP Server 配置 | Host(Claude Code 等) |
PLAN.md | 过程记录 | 当前任务计划 | Agent 写 + 读 |
TASKS.md | 过程记录 | 任务拆解清单 | Agent 写 + 读 |
EVALS.md | 过程记录 | 测试与评估标准 | 人写 + Agent 跑 |
MEMORY.md | 过程记录 | 项目长期记忆索引 | Agent 读 + 写 |
三类文件分工不同:
- 项目说明类:人维护为主,Agent 读来理解"这是个什么项目"。
- Agent 指令类:人写规则,Agent 严格遵守"在这个项目里该怎么做事"。
- 过程记录类:Agent 写为主,记录"现在做到哪了、试过什么、记住了什么"。
3.2 项目说明类
README.md:项目入口
这是最传统的文件,但 Agent 项目里它的作用变了:
- 对人:怎么装、怎么跑、怎么测
- 对 Agent:项目是干什么的、技术栈是什么、关键目录在哪
Agent 项目的 README 应该比传统项目多写两件事:
## Agent 使用须知
本项目使用 Claude Code / Cursor / Codex 进行开发。Agent 在动手前请先:
1. 读 `SPEC.md` 理解项目目标和验收标准
2. 读 `AGENTS.md` 理解项目规则
3. 读 `MEMORY.md` 看历史决策
4. 改代码前先跑 `pnpm test` 确认基线
5. 改完跑 `pnpm test` + `pnpm evals` 确认无回归SPEC.md:需求 + 验收标准
SPEC.md 是 Agent 项目里最重要的文件,没有之一。它回答四个问题:
- 目标:这个项目要解决什么问题?
- 需求:必须实现哪些功能?
- 约束:技术栈、性能、安全、合规边界
- 验收标准:怎样算"做完了"?
一个最小 SPEC.md 模板:
# PromptLens SPEC
## 目标
做一个 AI 视频提示词分析工具:用户上传视频,AI 自动反推提示词。
## 需求
- F1: 视频上传(≤500MB,mp4/mov)
- F2: AI 反推提示词(支持智谱/Gemini/OpenRouter)
- F3: 音频识别(AssemblyAI)
- F4: 历史记录 + 用户系统
## 约束
- 前端:Next.js 15 + React 19 + TypeScript
- 数据库:Supabase PostgreSQL
- 部署:Vercel
- 单次分析成本 ≤ $0.5
## 验收标准
- AC1: 上传 100MB mp4,30 秒内开始处理
- AC2: 反推结果可在 60 秒内返回
- AC3: 历史记录可分页加载,≤200ms 响应
- AC4: 通过 EVALS.md 里所有测试用例Agent 干活时,SPEC.md 就是它的"北极星"——任务跑偏了,回看 SPEC;不确定要不要做某个功能,看 SPEC 的需求清单;做完一个功能,对 SPEC 的验收标准自检。
第 4 章(Spec Engineering)会专门讲 SPEC.md 怎么写、怎么和 Agent 配合。
CHANGELOG.md:变更记录
Agent 项目里 CHANGELOG 有个特殊作用:让 Agent 知道最近改了什么。Agent 读了 CHANGELOG 能避免重复劳动("这个 bug 上周已经修过了")。
格式遵循 Keep a Changelog:
## [Unreleased]
### Added
- F2: Gemini 反推支持
### Fixed
- 上传超过 200MB 偶发 OOM
## [0.2.0] - 2026-06-20
### Added
- F1: 视频上传3.3 Agent 指令类
这一类是 Agent 项目特有的:写给 Agent 看的规则文件。
AGENTS.md:通用 Coding Agent 规则
AGENTS.md 是 2024 年社区形成的开放约定,所有 Coding Agent(Claude Code、Cursor、Codex、Aider、OpenHands)都会读。它放在项目根目录,内容是这个项目里所有 Agent 必须遵守的通用规则。
# AGENTS.md — PromptLens 项目规则
## 项目结构
- `app/` — Next.js App Router 页面
- `components/` — React 组件
- `lib/` — 工具函数
- `db/` — Drizzle schema 和迁移
## 代码风格
- TypeScript strict mode
- 函数式优先,避免 class
- 命名:camelCase 函数,PascalCase 组件
- 注释只在逻辑不直观时加
## 提交规则
- commit message 格式:`type: 简短描述`
- type ∈ feat/fix/docs/refactor/test/chore
- 不要 commit `.env` / `*.log` / `node_modules`
- pre-commit hook 失败时不要 `--no-verify`
## 测试规则
- 改任何 lib/ 下函数必须同步改对应测试
- 测试跑通才能 commit
- 新增 API 路由必须加 e2e 测试
## 禁止操作
- 不要直接改 db/ schema,先在 drizzle studio 改再生成迁移
- 不要 push 到 main,必须走 PR
- 不要删除 `.example` 文件AGENTS.md 的关键设计:通用 + 简洁。所有 Coding Agent 都读,所以不要写工具专属的东西(如 Claude Code 的 Skill 调用),那些放进 CLAUDE.md。
CLAUDE.md:Claude Code 专属上下文
CLAUDE.md 是 Claude Code 自动加载的项目上下文。它会和 AGENTS.md 一起被读,但只对 Claude Code 生效。
# CLAUDE.md — Claude Code 专属
## 继承
本文件不重复 AGENTS.md 内容。Claude Code 在本项目工作时,先读 AGENTS.md,再读本文件。
## Skill 使用
- 提交代码用 `/commit`
- 代码审查用 `/code-review`
- 数据库迁移用 `/db-migrate`
## MCP 配置
本项目使用以下 MCP server(见 `.mcp.json`):
- `playwright` — E2E 测试
- `supabase` — 数据库查询
## 常用命令
- `pnpm dev` — 开发服务器
- `pnpm db:push` — 推送 schema
- `pnpm test:e2e` — E2E 测试
## 项目历史决策
- 2026-05 选 Drizzle 而非 Prisma,因为类型推导更好
- 2026-06 选 better-auth 而非 NextAuth,因为 API 更简洁.cursor/rules:Cursor 专属规则
Cursor 用 .cursor/rules 目录(或 .cursorrules 文件,新版已废弃)。每个 rule 是一个 markdown 文件,可以指定 globs 控制何时触发:
---
description: React 组件规则
globs: ["components/**/*.tsx"]
---
# React 组件规则
- 用函数组件 + hooks
- props 用 interface,不用 type
- 默认导出
- 样式用 Tailwind,不用 CSS moduleCodex instructions:OpenAI Codex 专属
Codex CLI 读 codex.md 或 AGENTS.md(兼容)。如果你同时用 Claude Code 和 Codex,建议把通用规则放 AGENTS.md,把 Codex 专属的差异放 codex.md。
SKILL.md:单个 Skill 的说明
SKILL.md 是 Skills 系统的核心文件,每个 Skill 一个目录 + 一个 SKILL.md。第 7 章详细讲,这里先看结构:
---
name: commit
description: 智能生成 commit message 并提交。当用户说"提交代码"、"commit"时使用。
allowed-tools:
- Bash
- Read
---
# Commit Skill
## 流程
1. `git status` 看变更
2. `git diff` 看具体改动
3. 生成 commit message(type: 描述格式)
4. `git commit -m "..."`.mcp.json:MCP Server 配置
.mcp.json 在项目根目录,告诉 Host 启动哪些 MCP server。第 5 章详细讲,这里看格式:
{
"mcpServers": {
"playwright": {
"command": "npx",
"args": ["-y", "@playwright/mcp@latest"]
},
"supabase": {
"command": "npx",
"args": ["-y", "@supabase/mcp-server"]
}
}
}3.4 过程记录类
这一类由 Agent 写为主,记录任务进行中的状态、计划、记忆。这是 Agent 从"一次性执行"变成"持续协作"的关键。
PLAN.md:当前任务计划
PLAN.md 是 Agent 接到任务后写的执行计划。它不是最终方案,而是思考过程。
# PLAN — 加 Gemini 反推支持
## 任务来源
用户:视频反推支持 Gemini 2.0
## 分析
- 现有架构在 `lib/analyze.ts`,已抽象 `Analyzer` 接口
- 需新增 `GeminiAnalyzer implements Analyzer`
- 需在 `app/dashboard/page.tsx` 加模型选择
- 需在 `.env.local` 加 `GEMINI_API_KEY`
## 步骤
1. [ ] 在 `lib/analyzers/` 新增 `gemini.ts`
2. [ ] 在 `lib/analyzers/index.ts` 注册
3. [ ] 前端加模型切换 UI
4. [ ] 加测试 `lib/analyzers/gemini.test.ts`
5. [ ] 更新 SPEC.md F2
6. [ ] 更新 CHANGELOG
## 风险
- Gemini API 限流:需加 retry
- 视频格式支持比智谱少:需在 UI 提示Agent 写 PLAN.md 的好处:
- 强制思考:写计划过程就是 self-reflection
- 可中断续跑:关掉再开,读 PLAN.md 知道做到哪了
- 可审查:用户看 PLAN 觉得方向不对,可以提前叫停
TASKS.md:任务拆解清单
TASKS.md 是 PLAN.md 的执行版——把每个步骤拆成可勾选的 checklist。格式参考 TaskMaster:
# TASKS — Gemini 反推支持
## 进行中
- [ ] T1: 新增 `lib/analyzers/gemini.ts`(@agent,进行中)
## 待办
- [ ] T2: 注册到 `lib/analyzers/index.ts`
- [ ] T3: 前端模型切换 UI
- [ ] T4: 测试 `gemini.test.ts`
## 完成
- [x] T0: 调研 Gemini API(@agent, 2026-07-07)Agent 每完成一个任务就勾选,用户随时能看到进度。
EVALS.md:测试与评估标准
EVALS.md 是 Agent 项目的"考试卷"——人写标准,Agent 跑测试。第 6 章(E2E Testing)会详细讲,这里看格式:
# EVALS — PromptLens
## 评估维度
1. 准确率:反推提示词和原提示词的语义相似度 ≥ 0.7
2. 延迟:P95 ≤ 30s
3. 成本:单次 ≤ $0.5
4. 安全:不输出原始视频内容
## 测试集
| ID | 输入 | 期望输出关键词 |
|---|---|---|
| E1 | 15s 猫咪视频 | cat, animal, furry |
| E2 | 30s 城市夜景 | city, night, neon |
| E3 | 10s 抽象动画 | abstract, colorful |
## 跑法
`pnpm evals --set default --model gemini-2.0`EVALS.md 和 SPEC.md 的验收标准呼应:SPEC 说"应该做到什么",EVALS 说"怎么验证做到了"。
EVALS.md 设计的 4 类框架 07-09
写 EVALS.md 时最常见的困惑是"评估该用代码还是 LLM 裁判?要不要标注?"。吴恩达 Agentic AI 课程给了一个二维决策框架(来源:Andrew Ng Agentic AI Course,Module 4):
| 类型 | 判断方式 | 是否需要标签 | 典型例子 |
|---|---|---|---|
| 代码 + 有标签 | 代码判断对错 | 需要 | 发票到期日期提取 |
| 代码 + 无标签 | 代码检查规则 | 不需要 | 文案 ≤ 10 词 |
| LLM 裁判 + 有标签 | LLM 判断覆盖度 | 需要 | 文章是否覆盖 5 个黄金标准点 |
| LLM 裁判 + 无标签 | LLM 按统一标准评分 | 不需要 | 图表是否清晰 |
选型原则:能用代码判断就别用 LLM 裁判(便宜、可复现、无偏差)。只有任务本质是主观的(覆盖度、风格)才上 LLM 裁判。
主观评估的反直觉:用 LLM-as-Judge 时,二元评分(0/1)往往比 1-5 分更稳定。把"打几分"拆成多个二元子问题(覆盖核心点?逻辑清晰?有数据支撑?),每个子问题 0/1 判断,总分自然累加。这比让 LLM 直接打 1-5 分偏差更小、可解释性更强。
第 8 章(评估与安全)和第 14 章(E2E Testing)会详细展开这个框架的工程化。EVALS.md 里写测试集时,每个 case 标注它属于 4 类中的哪一类,方便后续维护和扩展。
MEMORY.md:长期记忆索引
MEMORY.md 是 Agent 的长期记忆入口。它本身是个索引文件,指向 memory/ 目录下的具体记忆文件。
# Memory Index
- [gemini-rate-limit](memory/gemini-rate-limit.md) — Gemini API 限流处理经验
- [drizzle-migration-pitfall](memory/drizzle-migration-pitfall.md) — Drizzle 迁移常见坑
- [user-preference-terse](memory/user-preference-terse.md) — 用户偏好简洁回复每个记忆文件单独成文,按主题组织(不是按时间)。Agent 在新会话开始时读 MEMORY.md 索引,按需加载具体记忆。
这正是本教程 CLAUDE.md 里 "auto memory" 系统的设计思路。
3.5 文件之间的关系
这 13 个文件不是孤立的,它们形成一张关系网:
┌─────────────┐
│ README.md │ ← 项目入口
└──────┬──────┘
↓
┌─────────────┐
│ SPEC.md │ ← 目标 + 验收
└──────┬──────┘
↓
┌───────────┴───────────┐
↓ ↓
┌────────┐ ┌──────────┐
│AGENTS.md│ │ EVALS.md │ ← 验收怎么测
└────┬───┘ └────┬─────┘
↓ ↓
┌─────────────────────────────┐
│ CLAUDE.md / .cursor/rules │ ← 工具专属规则
└────┬────────────────────────┘
↓
┌────────────┐ ┌──────────┐ ┌───────────┐
│ PLAN.md │→ │ TASKS.md │ │ SKILL.md │
└────┬───────┘ └────┬─────┘ └───────────┘
↓ ↓
┌────────────────────────┐
│ MEMORY.md / CHANGELOG │ ← 沉淀
└────────────────────────┘典型工作流:
- Agent 接到任务 → 读 README + SPEC + AGENTS + MEMORY
- 写 PLAN + TASKS
- 执行时按 SKILL 调用流程
- 跑 EVALS 验证
- 更新 CHANGELOG + 写新 MEMORY
3.6 一份最小 Agent 项目模板
启动一个新 Agent 项目时,至少要有这 5 个文件:
my-agent-project/
├── README.md # 项目说明
├── SPEC.md # 目标 + 验收
├── AGENTS.md # 通用 Agent 规则
├── EVALS.md # 测试标准
└── .mcp.json # MCP 配置(可选)跑起来后再加上:
├── PLAN.md # 当前任务计划
├── TASKS.md # 任务清单
├── MEMORY.md # 记忆索引
├── CHANGELOG.md # 变更记录
└── memory/ # 具体记忆文件如果用 Claude Code,加 CLAUDE.md。如果用 Cursor,加 .cursor/rules/。如果用 Codex,加 codex.md。
3.7 前人智慧 / Prior Art
agents.md 开放约定
agents.md 是 2024 年社区形成的开放标准,发起者包括 Cognition(Devin 出品方)、Anthropic、Cursor 等团队。它的核心主张:
"A project root
AGENTS.mdfile is the universal way to give coding agents context about your project."
翻译:项目根目录的 AGENTS.md 是给所有 Coding Agent 项目上下文的通用方式。
这个约定的价值在跨工具复用:你写一份 AGENTS.md,Claude Code / Cursor / Codex / Aider / OpenHands 全都读。不用为每个工具写一遍规则。
Anthropic Claude Code 的 CLAUDE.md 设计
Claude Code 文档里有一段关键说明:
"CLAUDE.md is loaded into context at the start of every session. Keep it concise—under 500 lines. Use it for project-specific instructions, not general coding rules."
翻译:CLAUDE.md 每次会话开始就加载进 context。保持简洁(500 行以内)。写项目专属指令,不写通用编码规则。
这条建议背后是 Context Engineering 的核心原则:始终加载的内容要尽量小。500 行 markdown 大概是 2-3k tokens,已经是不小的常驻开销。第 5 章(Context Engineering)会详细讲这个取舍。
OpenAI Codex 的 codex.md 约定
Codex CLI 的文档说明它会读 codex.md(或回退到 AGENTS.md)。OpenAI 没有强推自己的格式,而是兼容 AGENTS.md,这是个好信号——社区标准正在收敛到 AGENTS.md。
Cursor 的 .cursor/rules 演化
Cursor 的规则系统经历过一次大改:
- 旧版:根目录
.cursorrules单文件 - 新版:
.cursor/rules/目录,每个文件带 frontmatter,可指定globs触发条件
新版的好处是按需加载:编辑 *.tsx 才加载 React 规则,编辑 *.py 才加载 Python 规则。这和 Skills 的渐进式加载是同一个思路:别把所有规则都常驻 context。
Lilian Weng 的 Memory 拆解
Lilian Weng 的 Agent 博客 把 Memory 拆成两种:
- Short-term(短期):context window,当前任务的 working memory
- Long-term(长期):向量库 / 文件,跨会话的知识
本教程的文件层对应:
- 短期 =
messages列表(第 3 章 Agent Loop 讲过) - 长期 =
MEMORY.md+memory/*.md+CHANGELOG.md
文件层让 Long-term Memory 可读、可版本化、可审查——这是比纯向量库更工程友好的方案。向量库适合海量检索,文件层适合"项目级"的精炼记忆。
Anthropic Computer Use 的文件使用模式
Anthropic 在 Computer Use 演示里展示了一个有意思的模式:Agent 会在执行任务时主动写文件记录进度。比如让 Agent 做"调研 X 公司",它会自己创建 research-notes.md 边查边写。
这个行为不是人教的,是模型自己涌现的——因为它发现"写到文件里"比"记在 context 里"更不容易丢。这印证了文件层不只是人维护的,Agent 也应该被鼓励主动写文件。
Pattern: "文件即上下文" vs "Prompt 即上下文"
前人智慧可以总结成一条对比:
| 模式 | Prompt 即上下文 | 文件即上下文 |
|---|---|---|
| 时代 | 2023 早期 | 2024+ |
| 代表 | 早期 ChatGPT + 长 prompt | Claude Code + AGENTS.md |
| 持久性 | 一次性 | 跨会话 |
| 可版本化 | 难 | git |
| 可审查 | 难 | PR review |
| 适合规模 | 小项目 | 中大型项目 |
演化方向非常清晰:从塞 prompt 转向写文件。这也是为什么 Skills、AGENTS.md、MEMORY.md 在 2024-2025 集中爆发——行业共识已经形成。
3.8 常见误区
误区 1:把所有规则塞进 CLAUDE.md。 错。CLAUDE.md 是常驻 context,每行都消耗 token。通用规则进 AGENTS.md(跨工具共享),项目专属规则进 CLAUDE.md,按需触发的进 Skill。
误区 2:MEMORY.md 写成长篇大论。 错。MEMORY.md 是索引,不是内容。具体记忆拆到 memory/*.md,按主题组织。索引行控制在 150 字符内。
误区 3:PLAN.md 写完就不更新。 错。PLAN.md 是动态的,每完成一步就勾选,遇到新情况就修订。它反映当前思考,不是"初始计划"。
误区 4:EVALS.md 和 SPEC.md 重复。 不重复。SPEC 说"应该做到什么"(需求 + 验收),EVALS 说"怎么测做到没"(测试集 + 跑法)。两者呼应但不重复。
误区 5:AGENTS.md 写代码风格细节。 不必要。代码风格用 .editorconfig + prettier + eslint 配置文件,让工具自动管。AGENTS.md 写工具管不了的项目级规则:测试要求、提交规则、禁止操作。
3.9 课后练习
- 给你正在做的项目写一份 SPEC.md,包含目标、需求、约束、验收标准。验收标准至少 3 条,可量化。
- 写一份 AGENTS.md,覆盖:项目结构、代码风格、提交规则、测试规则、禁止操作。
- 设计一个 MEMORY.md 索引,至少 5 个条目,每条一行,包含链接和一句话描述。
- 解释为什么 PLAN.md 应该是动态更新的,而不是写完就不动。
- 对比 AGENTS.md 和 CLAUDE.md:如果同一条规则两边都写了,会发生什么?该怎么避免?
3.10 小结
- Agent 项目有 13 种常见文件,分三类:项目说明(README/SPEC/CHANGELOG)、Agent 指令(AGENTS/CLAUDE/.cursor/Codex/SKILL/MCP config)、过程记录(PLAN/TASKS/EVALS/MEMORY)。
- AGENTS.md 是通用 Coding Agent 规则,跨工具复用。
- CLAUDE.md / .cursor/rules / codex.md 是工具专属规则,按需加载。
- SPEC.md 定义"做什么",EVALS.md 定义"怎么测",PLAN.md + TASKS.md 记录"怎么做",MEMORY.md + CHANGELOG.md 沉淀"做过什么"。
- 核心原则:Prompt 是临时指令,文件是长期上下文。Agent 越复杂,越要把规则、记忆、计划、验收从 prompt 挪到文件。
下一章我们深入 Spec Engineering——SPEC.md 怎么写才能让 Agent 真正按你的意图做事,而不是"做完了但不是你要的"。