ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

Claude Code 失忆破解:三文件外置大脑实战指南

Claude Code 失忆破解:三文件外置大脑实战指南 1. 同事那句灵魂拷问点破了多少人的隐忧事情是这样的上个月我们组里推进一个内部工具的重构我连着几天把活儿都交给 Claude Code 去干。每次开工前先让它读一遍项目说明再把当前要改的模块喂给它它干得倒是又快又利索。结果有位同事在旁边盯了半天冷不丁问我一句“这玩意不是经常失忆吗你让它改这么多轮不怕它哪次心血来潮把项目搞炸了”我当时就乐了但仔细一想这确实是所有重度使用者绕不开的痛。先说结论Claude Code 确实会“失忆”或者说它的记忆机制远没有我们想象的那么智能。它每一次响应都受上下文窗口限制当对话轮数变多、代码片段变长早期的关键信息就会像水一样从筛子里漏掉。你对它说过的话、它自己做出的决策都可能随着对话推进被遗忘。这种失忆带来最典型的几个现场你上午让它确定了项目的目录结构是src/lib下午再让它新增一个模块它可能又重新创造出一套lib/src俩目录并存。你明确禁止它改动某个配置文件交代谢过三次了它在下一次重构中继续踩雷。你之前让它实现一个工具函数的接口定义过几轮后它调用的时候连参数名都变了。它自己写过的常量值、依赖版本、端口号一翻脸就全都不认识了。这些问题的本质是什么不是 Claude Code 不够聪明而是它默认不维护任何长期记忆。每轮对话虽然能看到历史消息但当上下文超限后就只能“选择性失明”。指望靠聊天记录来延续项目心智等同于用便利贴管理一份 10 万行的代码库翻着翻着就丢页了。我当时给同事的回答很简单怕当然怕。所以我从来不把 Claude Code 当成一个“靠聊天推进项目”的工具而是让它成为一个“按文档执行项目”的工具。这中间的差别非常关键——聊天会失忆但文件不会。我给它配了三个 Markdown 文件作为外置大脑相当于给一个记忆力不稳定的同事准备了一份永远可以翻看的工作手册、项目档案和变更日志。它每次开工前先读这三个文件干完活就更新这三个文件循环往复。这样无论对话怎么变、上下文怎么抖、窗口怎么清核心信息都安全地躺在磁盘上一次写入永久有效。这篇文章我结合自己的实际使用习惯把整套方案完全拆开来讲。从为什么三个文件、每个文件里写什么、目录怎么组织、怎么最小化 token 开销到实际跑了一个小项目后的前后对比都会覆盖到。无论你是已经装了 Claude Code 但总觉得它不好使还是正准备入坑还没想清楚工程化玩法这套东西都能直接抄作业。2. 先摸清楚 Claude Code 的“失忆”到底丢的是哪类记忆在讲外置大脑之前有必要先把“失忆”这件事掰开揉碎。很多人以为 Claude Code 失忆是因为“模型不行”这话对了一半但更准确的原因是它没有一套结构化记忆管理策略。2.1 上下文窗口不是无穷大的遗忘是物理规律每个 Claude Code 会话都有一个上下文窗口当前模型大约能承载 20 万 token 左右的上下文。听起来很多对吧但实际用起来完全不够看。一段 1000 行的源代码大概 8000 到 10000 token一个模块的 README 又要 1000 token再加上你的指令、它的回复、中间过程的报错信息几轮对话下来20 万 token 就见底了。上下文窗口占满之后会发生什么Claude Code 的处理机制是较早的消息会被“挤掉”或者被压缩。也就是说你在第 3 轮说的“这个项目必须遵守目录结构 A到了第 20 轮可能已经被挤出视窗它只记得最近十几轮的对话内容。于是它基于残缺的信息做决策自然就会产出偏离预期的代码。这里有个很反直觉的点很多时候不是 Claude Code 故意犯错而是它真的“没看见”你以前说过的话。就像一个人走进会议室手里只有最后 20 分钟的开会记录前两个小时的结论完全没看过那你不能怪他把之前敲定的事搞砸了。2.2 它失忆的往往是“项目级约束”而不是“对话级内容”如果把记忆分成两类一类是会话内短期记忆一类是跨会话长期记忆你会发现 Claude Code 真正缺的不是短期记忆因为它在正常窗口内表现还是不错的它缺的是对项目约束、全局约定和状态变更的持久化能力。举个例子我让它在config.py里添加一个新参数。它如果记得本项目所有配置项都必须放到Config类中且通过环境变量覆盖那就叫项目级记忆。但现实是这话你可能只在项目开头说了一次几轮之后它可能就自己新建一个settings.py因为它在窗口里再也找不到相关的约定内容了。再比如接口风格。你定了所有 API 返回格式为{ code: 0, data: ..., msg: ... }如果这个约束不在“硬盘上的文档”里而在“对话历史里”那基本等于没有约束早晚会被违反。失忆的坏处不只是“它会写错代码”更危险的是它会在无意识中破坏之前已经写好的正确代码。因为记不住之前的接口签名它会用新的方式去调用旧的函数导致大面积重构错误。这才是同事说“怕它把项目搞炸”背后的真实担忧——不是担心它写不出来新功能而是担心它忘了旧约定把原本稳定的部分改得面目全非。2.3 一个实验同样一个任务有无记忆文件的差别有多大我给自己做了一次小试验。用两个全新的会话让 Claude Code 完成同一个任务为一个小型 Python 项目增加一个数据校验模块。第一个会话没有挂任何记忆文件我直接说“帮我在项目里加一个数据校验模块”。它很快做完了模块文件是validators.py里面实现了一个validate_email()函数入参是字符串返回布尔值。第二个会话我提前在项目根目录放了一个AGENTS.md这个文件名下文会详细讲里面写清楚了本项目所有组件放src/utils目录模块用名词复数命名函数返回统一为(success, error_msg, data)三元组新增代码必须补测试。同样的指令“帮我在项目里加一个数据校验模块”结果它把模块放到了src/utils/validators.py实现了validate_email()函数返回的是(True, , {...})这样的三元组还顺带写了三个单元测试用例全部通过。差别肉眼可见。一个靠猜一个靠翻阅档案再动手。这不就是真实团队里“老手”和“萌新”的区别吗萌新凭感觉干活老手先查规范和文档再按规律执行。所以想让 Claude Code 稳定输出你要做的不是祈祷它别忘而是把它从“靠记忆干活”的状态强行扭转到“靠查阅干活”的状态。外置大脑就是这么个东西——它把“记忆”从易失的对话历史中抽离出来放进了可靠的持久化存储里。3. 方案总览为什么是“三个”文件而不是一个总控文档明确了问题根源之后接下来就是设计解法。很多人在网上搜到过类似的方案大多数是“用一个 AGENTS.md 文件给 Claude Code 当项目说明”。这个思路是对的但实操下来我发现只有单个文件远远不够。原因很简单一个文件承担了太多职责它会越长越臃肿最后变得既不适合高频更新也不适合快速定位反而成为一个大杂烩。我的方案是三个 Markdown 文件相互配合构成一套完整的外置记忆系统。本质上是参考了软件工程里的“关注点分离”思想不同性质的信息放到不同的存储位置各司其职互不干扰。三个文件的角色如下文件核心职责更新频率一句话类比AGENTS.md全局规则与偏好约定低偶尔修改员工手册PROJECT.md项目专属事实、结构、约束中随项目演进更新项目档案LOG.md操作记录与变更历史高每次会话结束都更新工作日志上面这个表格是快速概览接下来我把每个文件的设计逻辑和内容模板展开来讲。3.1 为什么留了 CLAUDE.md 不用而选择 AGENTS.md这里有个细节值得先说清楚。现在官方的 Claude Code 实际上支持一个名为CLAUDE.md的项目记忆文件会自动被加载进每次会话的上下文中。按理说直接用它不就行了吗为什么我用的是AGENTS.md因为我的工作流并不是只在 Claude Code 里玩我平时会切换不同的 AI 编码工具比如各种兼容层、其他 CLI 助手、甚至是我自己写的脚本。用AGENTS.md这个文件名意味着同样一份项目规则可以被更多工具共享而CLAUDE.md则过于绑定单一产品。当然如果你只用 Claude Code直接采用CLAUDE.md也完全没问题。两者语法上都是 Markdown内容组织方式一模一样。我这里的核心方法论是“外置大脑由三个文件构成”文件具体叫什么根据自己的工具链取舍即可。下文为了叙述统一仍然以AGENTS.md为例展开。3.2 AGENTS.md给 Claude Code 配备“员工手册”第一个文件解决的是行为基准问题。它的作用范围是“无论你在这个项目的任何模块里做什么事都得遵守这些约定”。员工手册里写的不是具体怎么完成某一项工作而是通用的做事原则。所以AGENTS.md里应该放这些内容项目的整体技术栈和语言偏好是 Python 还是 TypeScript是 ESM 还是 CommonJS。代码风格上的硬性要求缩进、命名规范、错误处理方式。测试要求新代码要不要强制带测试测试框架是哪个。提交信息格式、分支命名规则。一些通用的“不要做”条款比如“不要修改生成器输出的代码”“不要动migrations/目录下的文件”。这里的关键是内容必须精炼不能写成大而全的百科。因为 AGENTS.md 是每次会话开头都会读一遍的内容太长会直接拉高每次任务的 token 消耗而且稀释重点。一个合格的做法是控制在 100 到 200 行之内只写“涉及整个项目所有改动都必须知道的规则”。我自己的 AGENTS.md 长这样这是一段示例去掉了我项目里真正的敏感细节# 项目全局规则 ## 技术栈 - Python 3.11 - FastAPI SQLAlchemy 2.x PostgreSQL - 前端使用 React TypeScript Vite ## 代码风格 - Python 代码使用 Black 默认格式行宽 88 - 类型注解必须完整禁止使用裸 dict 作为函数返回值类型 - 所有 API 返回统一包裹为 ApiResponse 模型 ## 测试 - 新增或修改后端逻辑必须补充对应的 pytest 测试 - 测试文件放在 tests/ 目录下与被测模块路径对齐 - 涉及数据库的操作一律使用 testcontainers 启动真实 PG不能 mock ## 约定与红线 - 禁止修改 alembic/versions/ 下的已发布迁移脚本 - 禁止把密钥、密码硬编码到代码中环境变量统一由 pydantic-settings 管理 - 所有被 router.get 装饰的接口都必须写 OpenAPI 摘要 ## 工作流偏好 - 每次完成一个功能点后主动运行 make lint make test - 提交信息格式type(scope): subject例如 fix(auth): handle token expiry这样的文件写完后基本就不会频繁变。只有当项目发生了技术栈切换、全局规则调整时才需要动它。3.3 PROJECT.md让所有项目专属信息活在文档中第二个文件是项目档案。如果说 AGENTS.md 回答的是“在我们这个团队里一般怎么干活”那 PROJECT.md 回答的就是“我们这个项目具体长什么样、现在处于什么状态”。这里放的信息比 AGENTS.md 更具体、更易变包括项目定位与核心功能模块清单。目录结构说明特别是哪些目录是可以动的哪些是生成物不能动。数据库表清单及关联关系或至少是 ER 结构的文本描述。关键的领域模型User、Order、Product 这些实体的核心字段和状态机。外部服务依赖有没有 Redis、RabbitMQ、S3 之类的中间件。当前迭代正在做什么、接下来要做什么。PROJECT.md 的更新频率比 AGENTS.md 高很多但也不至于每次对话都改。它更像是“项目从一个阶段进入下一个阶段时你同步更新档案”。比如你新增了一个模块那就往 PROJECT.md 里面追加一段模块说明你重构了数据库表结构那就要同步改掉旧的表关系描述。实际模板示例# 项目档案 ## 一句话定位 面向公司内部的订单履约中台负责从下单到出库的全链路状态流转。 ## 目录结构约定 - src/api/HTTP 接口层只放路由和请求/响应模型 - src/service/业务逻辑层所有核心流程都在这里 - src/model/SQLAlchemy ORM 模型 - src/repository/数据库查询封装 - tests/pytest 测试 - docs/除了本文件之外的架构文档 注意src/model/ 里的类只做数据映射不允许写业务逻辑。 ## 核心领域模型 ### Order订单 - 状态机PENDING - PAID - FULFILLING - SHIPPED - COMPLETED - 取消路径PENDING/PAID - CANCELLED - 关键字段order_no(唯一订单号), user_id, total_amount, status ### Payment支付单 - 一个 Order 对应一到多个 Payment支持部分支付/多次退款 - 关键字段payment_no, order_id, amount, paid_at ## 外部依赖 - PostgreSQL 15主库库名 order_center - Redis 7缓存 分布式锁默认 DB 0 - RabbitMQ事件总线exchange 类型为 topic ## 当前迭代状态 - 正在做订单超时自动取消的定时任务 - 最近完成支付回调接口幂等性改造 - 待办对账文件生成逻辑3.4 LOG.md把每次会话的“前因后果”固化下来第三个文件是最容易被忽视、但实际价值最高的——变更日志。你可能会想项目里不是有 Git 吗Git 提交记录不就是最完整的操作日志吗为什么还要单独维护一个 LOG.md原因很直接Git 记录的是代码维度的变更但 Claude Code 需要的是“意图维度的变更”。比如这次重构背后的原因是什么、之前设计某个接口时想到了哪几个替代方案、为什么最终选了这个方案、有哪些隐含约定是代码里看不出来的这些信息都不会出现在 Git 提交里但它们恰恰是避免 Claude Code 下次“想当然”做出错误决策的良药。LOG.md 的更新时机是每次和 Claude Code 干完一通活之后把这次会话中产生的重要决策、踩过的坑、遗留的 TODO 都追加进去。写法上推荐用倒序追加最新的记录排在最上面方便下次会话能一眼看到最近发生了什么# 变更日志 ## 2025.06.22 - 重构支付回调处理流程 - 背景支付回调存在重复通知当前逻辑对重复通知支持不完善 - 改动在 PaymentService 中增加 process_notification()依赖 payment_no event_id 做幂等 - 决策使用 Redis Setnx 实现分布式锁TTL 设为 30s - 原因数据库唯一索引虽然也能做幂等但会把“回调处理中”的状态暴露给查询方 - 待办处理手工补单后台页面功能接口已完成但前端未对接 - 注意process_notification() 里调用了 refund_overpaid()如果未来改退款逻辑记得同步这里这种以“人和 AI 协作”为视角写的日志比 Git 提交信息要丰富得多。它记录了“为什么这么做”而这恰恰是所有 AI 编码工具最欠缺也最需要的信息。3.5 三文件的分工逻辑拆得越开维护成本越低三个文件各司其职整个记忆系统才不会退化。如果所有东西都堆到一个文档里会出现什么情况每次会话开始都要读一个超长的文档token 成本先不说关键是 Claude Code 对文档重点的把握会漂移。可能它今天把你的代码风格规则记住了明天却被你夹在文档中间的待办列表干扰了注意力。分开之后就能在每次开工之前按需加载AGENTS.md 每次会话都加载因为全局规则是每个人任何时候都必须知道的。PROJECT.md 每次会话都加载因为项目当前状态是所有任务的基础。LOG.md 不是每次都要全量加载往往只需要读最近 20 到 30 行就能了解到最新的变更历史部分只有在处理具体问题时才回去翻。这个按需读取的特点正是三个文件方案最有价值的地方。存储硬盘是无限的上下文窗口是有限的。把无限的信息放在可无限扩展的文件里把有限的窗口用来加载最必要的那一部分这就是外置大脑的本质。4. 实战配置目录怎么搭、文件怎么建、加载策略怎么设方法论讲得再漂亮最终还是要落地。这一步我直接给出具体做法包括目录位置、初始化流程和 Claude Code 的加载配置。4.1 目录结构所有记忆文件集中在brain/文件夹关于文件放哪里我试过放在项目根目录也试过放在docs/下面最终采用的是在项目根目录创建独立brain/文件夹的做法。好处有两个第一一目了然。brain/文件夹一看就知道是给 AI 用的记忆仓库不同于面向人类阅读的docs/。团队成员看到也不会混淆。第二便于按需加载和备份。我可以把整个brain/看作一个整体需要迁移项目时直接把这个文件夹拷走三文件的结构不会散落各处。结构如下your-project/ ├── brain/ │ ├── AGENTS.md # 员工手册全局规则 │ ├── PROJECT.md # 项目档案结构、模型、依赖 │ └── LOG.md # 变更日志按时间倒序追加 ├── src/ ├── tests/ └── ...其他项目文件每个文件开头我还要加一段约 500 字节的“自描述头”告诉 Claude Code 这个文件是什么、什么时候该读、什么时候该更新。这听起来有点像给文件写说明书但实测下来非常有效它能让 Claude Code 在没有额外指令的情况下自己判断“该不该更新这个文件”。比如AGENTS.md的开头# AGENTS.md 本文件是项目的全局员工手册。你在开始任何任务前必须阅读本文件。 当你发现项目技术栈、代码风格、测试要求等全局规则发生变化时必须更新本文件。 本文件不记录具体模块的细节那些内容属于 PROJECT.md。PROJECT.md的开头类似# PROJECT.md 本文件是项目档案。每次任务开始前必须阅读本文件。 当新增、删除、重构了核心模块或领域模型时必须同步更新本文件。 本文件记录“项目当前是什么状态”不记录“做过的操作历史”那些内容属于 LOG.md。LOG.md的开头# LOG.md 本文件是变更日志。每次与 AI 协作完成一批改动后必须在本文件最上方追加一条记录。 记录内容包括本次改了什么、为什么这样改、留下了哪些待办、有什么坑需要下次注意。 本文件按时间倒序排列最新的记录在最上方。加上这段“文件用途说明”Claude Code 即使在上下文窗口已经滚动了很多轮之后看到这个文件也能立刻明白它的角色。4.2 初始化的 30 分钟一次性写好种子内容初始化这套外置大脑我的建议是不要偷懒第一次的种子内容尽量人工写质量直接决定后面用起来顺不顺手。这 30 分钟花得非常值。步骤大致如下先想清楚项目的技术栈和编码习惯。不要急着写先把团队实际开发中最常被触犯的几条规则列出来。找一下你的历史代码看看是否存在反复出现的风格偏差那些就是最该写进 AGENTS.md 的红线。把项目的目录结构和核心模型过一遍。这一步不需要写得非常详细先搭骨架后面每次遇到新增模块再补。写一篇 LOG.md 的“第 0 条记录”。记录一下这个项目当前的起点状态比如“完成了脚手架搭建登录/注册功能可用支付流程还未联调”。这就给 Claude Code 建立了“项目时间线”的起点。种子的目的在于让 Claude Code 第一次打开项目时就有东西可读而不是面对一个空文件夹。4.3 Claude Code 的加载配置不用做太多额外的事Claude Code 本身有自动读取约定文件的能力如果你的文件名直接用AGENTS.md放到项目根目录或brain/目录下它一般能自己发现并加载。但为了稳妥我通常会明确告诉它在每个会话里先去读这三个文件。有两种做法方法一在每次会话开头说一句Read brain/AGENTS.md, brain/PROJECT.md, brain/LOG.md first, and comply with all the rules in them.方法二利用 Claude Code 的预置指令功能把这句话写进全局配置里这样每次启动新会话时它会自动执行这个“预读动作”。具体配置方式不展开不同版本的入口可能略有差异但核心思路是在全局指令里加入类似“开工前先读 brain 目录下三个文件”的句子。这里我想强调一个技巧让 Claude Code 自己“上报”它读了什么、准备怎么做比让它“默默读”效果更好。比如你可以要求它After reading the brain files, list the top 5 constraints you are going to follow in this session, based on those files.这会促使它真的去读而不是假装读了。而且它列出的约束方便你在会话开头快速校验它有没有理解偏差。如果它列的东西和你的关键项目事实有出入你可以马上纠正而不是等到它写了一段不符合预期的代码之后才发现问题。5. 三个文件在手具体工作流怎么跑起来机制搭好了接下来是这件事情最迷人的部分——状态机的设计。我把一次“人机协作开发”分成四个阶段预读、执行、沉淀、收尾。这四个阶段在每个会话中循环外置大脑就是整个循环里的“常量存储”。5.1 预读阶段让 Claude Code 带着“记忆”进入工作状态每次新开一个会话我不会直接甩给它一个任务而是先用一段 Prompt 让它完成“预读”动作。这段 Prompt 我现在的写法已经基本固定你是一个经验丰富的开发者现在要进入项目工作。开始之前请先完成以下步骤 1. 阅读 brain/AGENTS.md总结本项目最核心的 5 条全局规则并复述一遍。 2. 阅读 brain/PROJECT.md说明当前项目的架构和核心领域模型特别指出你这轮任务可能涉及的部分。 3. 阅读 brain/LOG.md 的最新 3 条记录简要概括最近发生了什么。 4. 基于以上信息列出你本次会话打算如何执行我给你的任务。 现在我给你的任务是[具体的任务描述]这一套步骤下来不夸张地说Collude Code 的回答质量会有一个肉眼可见的提升。它脑子里在回答你任务之前先灌入了一套项目语境我是谁、我在哪、周围发生了什么。就像你叫一个同事干活他会问“这个项目现在处在什么阶段”“有什么我需要注意的吗”这种背景信息直接影响他干活的质量。5.2 执行阶段边界声明与“禁止修改”清单执行阶段的核心是利用外置大脑来划边界。在任务描述中可以要求 Claude Code 在动手之前先检查它的改动范围是否触碰了 AGENTS.md 和 PROJECT.md 中定义的“不可变区域”。比如我的一些项目里会有很多自动生成的代码Claude Code 经常会在重构时把生成文件也改了然后用看似合理的方式告诉你“顺手优化了一下”。这是我最不能忍的行为。所以我在 AGENTS.md 里专门加了这么一段## 修改边界 - src/generated/ 下的所有文件均由代码生成器产出禁止手动修改。 - 如需变更生成逻辑请修改 scripts/generate.py 后重新生成。 - 对上述文件的任何非生成操作都会被视作严重错误。有了这种硬性声明Claude Code 在越界时会更容易“刹车”。当然它不是每次都能 100% 遵守但至少违反的概率从“经常”降到了“偶发”。另一个有用的小技巧是在执行完一段时间后主动让它报告“本次改动了哪些文件”你只需要把这份报告和实际 git diff 对照一眼就能把风险扼杀在摇篮里。5.3 沉淀阶段一次成功的对话必须转化为可复用的资产这是整套方案里最关键的一步也是大多数教程不会强调的一步每次会话结束强制 Claude Code 更新 LOG.md。我每次让 Claude Code 完成一批改动之后会追加这样一段要求现在请将这次会话的完整结果更新到 brain/LOG.md 中。记录以下内容 - 本次改动涉及的功能/模块 - 做出的关键设计决策以及原因 - 遗留的 TODO 或已知问题 - 下次会话需要特别注意的点 格式参考已有历史记录。这段要求看起来简单但坚持做下来价值非常大。只要 LOG.md 更新及时哪怕你隔了一个月再回到一个项目让 Claude Code 读一遍 LOG.md它就相当于和“一个月前的自己”无缝接上了。它清楚记得上次做到哪儿、有什么坑、下一步怎么走。我把这个过程形容为每次会话都在“落地成文”而不是聊完即焚。工作不是从聊天记录里传承的而是从 LOG.md 里传承的。5.4 收尾阶段用“三查”确认这次协作没有留下暗坑我是个比较谨慎的人每次和 Claude Code 协作完在结束会话之前我习惯做三个检查查运行跑一遍测试和静态检查。这是最基本的相当于面试时的笔试环节。查边界对照 AGENTS.md 里的修改边界确认没有动到不该动的区域。我一般用git status看一遍变更文件列表看到有不该出现的文件就立即处理。查沉淀确认 LOG.md 已经更新关键决策有没有遗漏待办事项清不清楚。如果这三个检查都通过了我才会踏实结束这次会话不管是关掉终端还是切换去干别的。这套流程内化之后成了一种肌肉记忆也让我对 Claude Code 的信任度提升了好几个档次。6. 实测记录一个小项目从“野生生长”到“按图施工”光说不练假把式。上周末我拿一个之前练手用的项目做了一次完整测试记录一下实测中的前后差异供大家参考。6.1 测试项目背景项目是一个简单的个人博客后端FastAPI SQLite JWT 认证大概两千行代码七八个业务模块。之前是我手动写的一直没敢拿给 Claude Code 折腾就是担心它把已有功能弄坏。这次测试的任务是新增文章标签功能允许一篇文章挂多个标签并支持按标签筛选文章列表。6.2 没有外置大脑之前的表现先回顾一下没配外置大脑时这类任务的表现这也可以说是大部分人现有的体验第一它会自己决定 Article 和 Tag 的关系表怎么建。它可能会创建一个article_tags表也可能直接在articles表里加一个tag_ids字段存逗号分隔的 ID。这两种方案它都可能出完全取决于它在当前窗口里“灵光一现”时的想法。第二它的命名不统一。比如已有的接口路径是/api/v1/posts/{id}但历史项目里根本没有这个路径而是/api/articles/{id}。它会按照新上下文重新发明一套接口路径和现有路由风格割裂。第三它不会自动补测试。如果我不明确要求它基本不会主动写测试文件因为它不知道这个项目的质量红线。这三点叠加导致用 Claude Code 维护一个“野生项目”时每次改动都像在玩地雷阵。6.3 有了外置大脑之后的表现这次我提前把三个文件写好放在了brain/目录。AGENTS.md 里面写了 API 路由格式需要用复数名词、所有新增功能必须补测试、ORM 模型必须放在src/model/下。PROJECT.md 里写清楚了现有的文章模型字段、接口列表、认证方式。LOG.md 里记录了上次会话停在哪里以及之前定下的技术选型。同一句话“新增文章标签功能允许一篇文章挂多个标签并支持按标签筛选文章列表。” 它这次的表现完全不一样它主动说根据项目管理规范新建 Tag 模型并放在src/model/tag.py同时创建article_tag关联表放在同一个文件里。它在 API 层新增了/api/v1/articles/{article_id}/tags,/api/v1/tags/{tag_id}/articles这两个路由完全贴合已有路由风格。它在领域模型中加了Article.tags关系字段格式和已有Category关系字段保持一致。它自动为这次新增功能写了三个 pytest 测试文件分别测试标签创建、文章挂标签、按标签筛选文章。整个过程中它没有动任何一个已有模型字段没有改接口返回值结构。做完任务后我让它自己总结变更并追加到 LOG.md它的记录措辞合理大型决策备注清晰## 2025.06.23 - 新增文章标签功能 - 背景博客系统需要支持一篇文章多个标签并支持按标签筛选 - 改动新增 Tag 模型及 article_tag 关联表新增标签相关的 3 个 API - 决策使用关联表方案而非 JSON 字段理由标签需要独立维护和统计 - 待办标签热度统计接口尚未实现计划下个迭代完成 - 注意Article.tags 关系加载使用了 lazyselectin避免后续查询 N1这次的输出质量已经接近一个熟练工程师写出的水准了。当然这不是因为 Claude Code 变聪明了而是因为它在动手之前看到了“这个项目是怎么运转的”。6.4 实验结果小结行为维度无外置大脑有外置大脑表结构设计不确定随上下文飘移稳定参照已有模型API 风格经常自创对齐已有路由约定测试覆盖率基本不写自动补齐改动边界可能误伤已有代码基本不越界结果可追溯性事后难复原决策原因LOG.md 有完整记录数据不说谎一次实测试下来无须多言。7. 进阶玩法外置大脑的扩展与微调基础三件套稳定后还可以继续加料。这部分属于锦上添花但如果你经常用 Claude Code也值得尝试。7.1 增加“决策记录库”专记已经拍板过的方案团队里常有一种文件叫 ADRArchitecture Decision Records记录每个技术决策的背景、选择和代价。类似的思路也可以应用到外置大脑中。我有时候会额外加一个brain/DECISIONS.md专门记那些“已经和 Claude Code 讨论过并最终拍板”的决策。比如之前有一次我纠结某个模块是用状态机实现还是手动 if-else。当时和 Claude Code 聊了很多轮最终决定用状态机。如果这个结论不记录下来下次遇到类似模块它可能又会推荐 if-else白白浪费一轮讨论。DECISIONS.md 就是为了避免这种重复决策。模板可以是这样# 决策记录 ## 2025.06.20 - 订单状态流转用状态机 - 背景订单模块状态逻辑较复杂涉及取消、退款、超时 - 备选方案A. 手动 if-elseB. 使用 transitions 库的状态机 - 决策方案 B使用 transitions 库 - 原因状态转移路径清晰、扩展新状态成本低、避免隐藏分支 - 代价引入一个第三方库依赖需要额外维护状态图描述7.2 给 Claude Code 定制“任务前检查清单”另一个有效的扩展是在 AGENTS.md 里面加一个“任务前检查清单”让 Claude Code 在每次执行任务前都默认走一遍。典型清单如下## 任务前检查清单 在开始具体编码之前你要确认以下几项 1. 我已经阅读了 brain/ 下所有相关文件 2. 我了解本次改动影响到的模块和接口 3. 我检查了 PROJECT.md 中的领域模型确认新改动的字段/方法不会与现有结构冲突 4. 我了解项目的测试要求并会在完成后补上对应测试 5. 若有修改公共接口或数据库结构我会在完成后更新 PROJECT.md有了这个清单即使是新手用户第一次用 Claude Code也不会在项目里乱打乱撞。7.3 接入自动化流程让更新外置大脑成为提交前的一环我目前还没有做到完全自动化但我见过一个很合理的做法用 git pre-commit 钩子检查AGENTS.md和PROJECT.md是否有未提交的改动若有改动则提示用户“是否确认这些记忆文件已更新”。这能在协作层面堵住“脑子里改了但没记到文件里”的漏洞。如果项目已经接了 CI还可以加一步文档一致性检查比如用脚本对比代码里新增的模块和 PROJECT.md 中的模块列表不一致就报警告。这些属于工程化做法视项目复杂度取舍即可。8. 最后碎碎念为什么这套方案能治“失忆”却不麻烦可能有人会担心三个文件听起来不错但维护成本是不是太高了每次都要更新这些文件不烦吗我的真实感受是在一开始的一两天会比较烦但过了“建立初始档案”的阵痛期后面几乎是无感的。理由有两个。第一大部分更新是让 Claude Code 自己干的。它改完代码后你只需要说一句“把本次变更记进 LOG.md”剩下的活它会自己完成。你检查一下措辞和关键信息就好基本不用从头开始写。第二这套机制解决的不只是 Claude Code 的记忆问题它其实在逼你把项目的隐性知识显性化。过去很多信息只存在于你自己的脑子里比如“为什么支付回调要加事务”“为什么这个接口返回结构不能乱改”这些逻辑在人员流动、项目交接时全部面临丢失风险。现在它们都成了文件里的白纸黑字。即使某天你自己忘了翻一翻这些档案也能重新找到上下文。再说回同事那句“不怕它把项目搞炸”。怕但怕没用得解决问题。项目搞炸往往不是因为 Claude Code 能力不够而是因为你没有给它一个可靠的项目认知框架。当我把它从一个“靠会话记忆干活的新人”变成“每次开工前先查员工手册和老同事留下的工作日志”的成熟协作伙伴之后它的输出稳定性和可靠性提升非常明显。这套方案不依赖任何特定模型也不绑定特定工具Markdown 文件是所有文本工具都能读懂的通用格式。哪怕未来某天我换了工具这些记忆资产依然能原封不动地迁移到新的 AI 开发环境里去。从这个角度讲这三份文件可能才是项目里最保值的那部分资产。
返回列表