如何让 Agent 越用越懂你

Agent Learns Cover

很多人刚开始用 Codex 或 Claude Code 时,都会经历一个很奇怪的落差。

第一天,它像一个反应很快、代码也写得不错的新同事。

几周后,项目明明已经改过几轮,它却还拿着旧架构在推理;你上周强调过的协作习惯,这周还要再说一遍;同一个 PR 范式、同一条部署边界,换一次会话又得重新解释。

最后人会很自然地得出一个结论:Agent 不会记忆。

我现在不太认同这个说法。

更准确地说,Agent 不会自动拥有你的项目记忆。 它能看代码、读文档、遵循指令,也能保存一部分工具侧的偏好;但如果项目事实、协作规则和强制边界没有被设计成一套能演进的外部系统,它就只能一次次从局部上下文里猜。

这篇文章想讨论的,不是怎么把 prompt 写得更长。

而是怎么把 Codex 和 Claude Code 培养成一个越用越顺手的开发助手:它知道项目现在是什么,知道你希望它怎样工作,也会把一次次纠正沉淀成下一次协作的起点。

一、先接受一个事实:它没有在“训练”,但可以在学习

这里的“学习”不是模型参数发生了变化。

一次对话结束后,模型不会因为你纠正过它,就在下一次天然变成另一个更懂项目的模型。真正可以积累的,是项目之外的那一层:被写下来的事实、可复用的规则、可执行的检查,以及每次任务结束后的复盘。

所以我现在更愿意把 Agent 的学习力写成一个外部循环:

任务执行
-> 发现新事实、偏好或失败教训
-> 判断它属于记忆、规则还是 Hook 候选
-> 用证据更新对应载体
-> 下一次任务先读取这些载体

这个循环少了任何一环,都会退化。

  • 只有聊天,没有沉淀:下一次还得重新解释。
  • 只有长文档,没有更新机制:文档很快也会活在过去。
  • 只有规则,没有验证:Agent 仍可能在关键操作上失手。
  • 什么都自动写:记忆会被临时结论和偶发情绪污染。

真正顺手的助手,不是“记得越多越好”,而是知道什么值得留下、应该留到哪里、什么时候必须被机器检查。

二、项目记忆、规则和 Hook,不该塞进同一个大提示词

我以前最容易犯的错,是把所有要求都加进一份越来越长的项目说明里。

架构写一点,部署步骤写一点,代码风格写一点,再补几条“不要这样做”。短期看很省事,长期一定失控:事实会过期,规则会冲突,真正关键的禁止操作又不会因此变成强制约束。

后来我把它们拆成四层。

层级 它回答的问题 典型内容 更新频率
项目记忆 项目现在是什么 架构、命令、服务边界、已确认决策
协作规则 Agent 默认怎样做 先读什么、何时提问、如何验证、如何发 PR 中低
Hook / CI 哪些事情不能靠自觉 阻止危险命令、格式检查、测试门禁
工作流模板 高频任务怎样交付 PR 描述、部署清单、故障复盘格式

这四层的职责不能互相替代。

记忆是事实,不是命令。 “生产部署由 deploy/deploy.sh 执行”是一条事实;“涉及生产部署必须先确认”才是一条规则。

规则是默认行为,不是不可绕过的安全机制。 “提交前运行构建”是合理要求,但如果构建是否通过会影响发布,就应该再交给脚本、Git Hook 或 CI 去验证。

Hook 是机器能判断的边界,不是把自然语言再写一遍。 “写得优雅一点”无法做成可靠 Hook;“推送前必须通过 npm run build”就可以。

把边界分开之后,Agent 才不会被一份臃肿的提示词拖着走;人也知道每次发现问题,应该修哪一层。

三、第一步不是写规则,而是建立一份会过期的项目记忆

“会过期”听起来像缺点,但它恰好是项目记忆最重要的属性。

项目记忆不是 README 的复制品,更不是把仓库里所有信息重新摘要一遍。它应该只保留那些会影响下一次任务判断、但 Agent 不一定能快速从局部代码恢复的事实。

我建议从一个很小的文件开始,例如 docs/agent/project-memory.md

# Project Memory

> Last verified: 2026-07-11
> Evidence: `deploy/deploy.sh`, `deploy/docker-compose.yml`, `_config.yml`

## Current Shape
- 前端是 Hexo 静态站;文章位于 `source/_posts/`。
- 生产环境同时有静态站和 Docker 后端服务。
- GitHub Pages 只负责静态构建;完整后端由自有服务器承载。

## Common Commands
- Local preview: `npm run server`
- Static build: `npm run build`
- Production deploy: `bash deploy/deploy.sh [ssh-alias]`

## Important Boundaries
- `deploy/.env` 和 SSH 私钥不进入版本控制,也不在输出中展示。
- 修改部署、Docker 或 Nginx 前,先说明影响范围并等待确认。

## Recently Superseded
- 不再把项目当作“只有 GitHub Pages 的静态博客”。

这份文件最重要的不是措辞,而是三个字段:最后验证时间、事实证据、被淘汰的旧认知。

前两个字段会逼着人和 Agent 区分“我以为”与“我确认过”;第三个字段专门处理升级中的项目。很多错误并不是 Agent 完全不知道,而是它知道的版本已经过时,却没人告诉它旧结论已经失效。

哪些信息应该进项目记忆

我会优先记录四类。

  1. 项目形态发生变化:单体拆成多服务、部署方式迁移、新增关键数据源。
  2. 任务入口不直观:构建、测试、部署、索引更新到底从哪个脚本走。
  3. 会影响风险判断的边界:生产环境、密钥、数据迁移、外部服务。
  4. 已经确认的架构决策:为什么不用某个方案,而不是只写最后选了什么。

相反,临时日志、一次性排错过程、尚未确认的猜测,不应该急着进入长期记忆。它们最多先留在任务记录里。

一个很实用的判断标准是:下次换一个全新会话,如果没有这条信息,Agent 会不会大概率做出不同且更差的判断? 如果会,就值得记。

四、让 Agent 在任务收尾时维护记忆,而不是等你想起来

项目记忆最常见的失败方式,不是文件不存在,而是它再也没人更新。

我现在会在根目录规则里加入一条元规则:每次任务完成后,Agent 必须做一次轻量复盘。它不需要把整段思考过程写下来,只需要判断这次任务有没有产生值得跨会话保留的内容。

下面这段可以直接放进 AGENTS.md,也可以被 CLAUDE.md 导入:

## Agent Learning Loop

任务完成前,检查是否产生了可复用的新信息:

1. 已验证的项目事实、命令、服务边界或架构决策发生变化时,
更新 `docs/agent/project-memory.md`,并写明证据文件或验证命令。
2. 用户明确表达的稳定偏好,或同一类纠正第二次出现时,
提出一条简短的规则候选;未经明确条件或确认,不直接扩张全局规则。
3. 当规则可以由脚本可靠判断时,提出 Hook、Git Hook 或 CI 候选,
不在未经确认的情况下新增或修改强制拦截。
4. 不要记录临时猜测、敏感信息、完整日志或一次性对话内容。
5. 在最终交付中说明:更新了什么,或为什么没有更新。

这段规则的价值,不是让 Agent “每天都写记忆”。

恰恰相反,它要求 Agent 允许什么都不更新。如果一次任务没有改变项目事实,也没有暴露出稳定协作偏好,那么最正确的动作就是不制造噪声。

一个特别值得写进规则的场景

当用户只是告诉 Agent“项目有变化,之后工作按这个理解”,这类任务的默认动作应该是:更新项目认知、确认理解、等待下一次具体工作。

它不自动等于审查,不自动等于改代码,更不自动等于把服务器和部署流程跑一遍。

这看起来像沟通细节,实际上是一条很高价值的协作规则:先识别任务类型,再决定是否行动。 对一个长期合作的助手来说,知道什么时候什么都不要做,和知道怎样写代码一样重要。

五、记忆可以自动更新,规则必须更难改变

如果允许 Agent 自己维护项目记忆,下一步很自然会问:那能不能让它自己改规则?

可以,但两件事的门槛不能相同。

记忆通常描述的是已经验证的事实。代码、配置或部署脚本已经变了,Agent 可以根据 diff、命令结果和明确的用户说明去更新事实库。

规则则会改变它之后每次工作的行为。一次偶发情况被写成全局规则,往往比没有规则更糟。

我会把升级门槛设计成这样:

候选内容 默认动作 触发条件
已验证项目事实 自动更新记忆 有文件、命令或用户明确说明作证据
用户稳定偏好 提议写入规则 用户明确说“以后都这样”,或重复出现
重复的评审反馈 提议写入规则 同类反馈至少出现第二次
可机器验证的规则 提议 Hook / CI 规则成熟、误报成本可接受、人工确认
临时错误和猜测 不沉淀 没有可复用价值或证据不足

这里的“第二次”并不是数学定律,它只是一个对抗过度学习的缓冲器。

Agent 很擅长从一次对话中总结规律,也很擅长把一次异常说得像普遍原则。给规则加门槛,就是在告诉它:不要因为一个样本就重写协作宪法。

如果项目对自动化要求更高,可以把“规则候选”单独记在 docs/agent/rule-candidates.md,由人定期合并。这样 Agent 依然在持续学习,但最终规则的演进是可审查、可回滚的。

六、Hook 的作用不是让它更聪明,而是让成熟经验不再靠记性

很多人把 Hook 当成一种高级提示词,其实不是。

Hook 最有价值的地方,是把已经成熟、而且机器能判断的经验从“建议”变成“门禁”。例如:

  • 推送前必须能构建。
  • 改动部署文件时必须检查配置格式。
  • 提交中不能包含密钥、私钥或生成目录。
  • 创建 PR 前必须带上测试结果和影响范围。

一个跨工具的最小做法,是把检查留在仓库脚本里:

#!/usr/bin/env bash
# scripts/verify-before-pr.sh
set -euo pipefail

git diff --check
npm run build

然后让 Codex、Claude Code、Git Hook 和 CI 都调用这同一份脚本。

这样做的好处是,规则的核心不属于某个 Agent。哪怕明天换模型、换编辑器、换 CI 平台,项目仍然有一条统一的可验证路径。

工具原生 Hook 仍然有价值。

Codex 可以在受信任项目的 .codex/hooks.json.codex/config.toml 中配置生命周期 Hook;Claude Code 也支持 PreToolUsePostToolUse 等事件。它们适合给 Agent 额外提示、拦截危险工具调用或在写文件后立即触发检查。

但我会保留一条原则:工具 Hook 做增强,仓库脚本和 CI 做事实上的最终裁判。

因为“不要对生产环境误操作”可以被 Agent 的工具 Hook 提前拦住;而“这个改动到底能不能发布”最终还是应该由任何人、任何 Agent 都能运行的验证命令回答。

七、Codex 和 Claude Code 怎么共用一套项目认知

两个工具的入口不同,但不需要维护两份事实。

Codex 的项目级持久指令是 AGENTS.md。官方文档也明确建议把反复出现的错误和评审反馈沉淀进去,并和 pre-commit、lint、类型检查这类基础设施配合。Codex customization 文档

Claude Code 使用 CLAUDE.md 作为项目级持久指令,也可以通过 @AGENTS.md 导入共享规则;它还提供自动记忆,但那更适合作为个人效率增强,而不是团队共享的唯一事实源。Claude Code memory 文档

所以我的推荐目录是:

my-project/
├── AGENTS.md # 跨 Agent 的协作规则与记忆维护机制
├── CLAUDE.md # @AGENTS.md + 少量 Claude 特有补充
├── docs/
│ └── agent/
│ ├── project-memory.md # 已验证的当前项目事实
│ ├── decisions.md # 需要保留理由的关键决策
│ └── workflows/
│ └── pull-request.md # PR 的交付模板
├── scripts/
│ └── verify-before-pr.sh # 所有入口共享的验证命令
├── .codex/ # 可选:Codex 专有 Hook / 配置
└── .claude/ # 可选:Claude Code 专有规则 / Hook

CLAUDE.md 可以非常薄:

@AGENTS.md

## Claude Code
- 涉及 `deploy/` 的修改先进入 Plan Mode,再等待确认。

这样项目事实只有一份,跨工具规则只有一份;只有确实无法通用的行为,才留给各自的配置层。

这也避免了一个隐蔽问题:如果 Codex 的记忆文件和 Claude 的记忆文件各写各的,半年后你很难判断哪一份才代表项目现状。

八、我的博客项目给了我一个很具体的提醒

我的博客一开始很容易被理解成“一个 Hexo 静态站”。

现在它仍然有 Hexo 和主题,但完整形态已经包含自有服务器部署、Nginx、搜索、评论、AI 聊天和邮件订阅等服务。静态构建与完整生产部署也不是一回事:前者可以走 GitHub Pages,后者还要同步静态文件、更新 Docker 配置并重启后端服务。

如果 Agent 停在旧认知里,它未必会立刻写出语法错误。

它更可能做出一种“局部合理、整体错误”的操作:只按静态站思考部署,忽略后端依赖;把一次项目说明当作授权审查或修改;不知道文章更新还影响 AI 检索索引。

这类错误靠更长的单次提示词解决不了。

我需要的,是让项目记忆明确记录当前形态,让规则要求它先判断“这是信息同步、诊断还是修改任务”,再让部署脚本和服务检查守住真正的操作边界。

这就是我理解的“Agent 越用越懂你”:

不是它变得更敢行动,而是它对你的项目、偏好和边界有了更稳定的判断;需要行动时能走对路径,不需要行动时也知道停下来。

九、从最小闭环开始,不要先造一套记忆平台

如果你准备今天就开始,我建议只做下面五件事。

  1. 新建一份不超过两页的项目记忆,写当前形态、常用命令和高风险边界。
  2. AGENTS.md 写清默认协作方式,并加入任务收尾复盘规则。
  3. CLAUDE.md 导入 AGENTS.md,只放 Claude Code 专有内容。
  4. 选一个最有价值的检查写成仓库脚本,让发 PR 前必须执行。
  5. 每隔一段时间删除过期记忆和冲突规则,而不是只追加。

别一开始就把所有聊天记录向量化,也别急着让 Agent 自动改所有规则。

先让它在每次完成真实任务后,能准确回答三个问题:项目现在变成什么样了、我下次应该怎样工作、哪些地方必须交给机器验证。

当这三个问题都有稳定答案时,Codex 和 Claude Code 才会从一次性工具,慢慢变成真正像助手的存在。

它们未必拥有人的记忆。

但你可以为它们搭建一套,比人的记忆更可验证、更可更新、也更不容易被旧版本拖住的协作系统。