1. 新开对话就“失忆”,问题到底出在哪
如果你每天都在用 AI 编程助手写代码,大概率经历过这个场景:昨天花了半小时跟它讲清楚项目结构、命名规范、接口约定,今天新开一个对话窗口,它又变回一张白纸,连你用的是哪个框架都要重新问一遍。这种“每次都要重新解释项目”的重复劳动,消耗的不只是时间,更是耐心。
这个问题的根源在于,绝大多数对话式 AI 工具的记忆是会话级的,而不是项目级的。一个对话窗口关闭或新建,上下文就清零了。你之前喂给它的所有背景信息——技术栈、目录结构、代码风格、业务规则——全部丢失。对于一次性问答这没什么,但对于需要持续迭代的项目开发来说,这就是灾难。
WES Code 的跨会话记忆功能,针对的正是这个痛点。它做的事情说白了就一句话:把项目的关键上下文从“对话里”抽出来,存到“项目里”,让每一次新对话都能自动加载。这样一来,你不需要每次重新解释,AI 助手一上来就知道你的项目长什么样、该怎么写。
这篇文章适合两类人看:一类是已经被“重复解释项目”折磨很久、想找个系统解法的人;另一类是刚开始接触 WES Code、还没搞明白记忆机制怎么配置的人。我会从原理讲到实操,把配置步骤、目录结构、常见坑都拆开说清楚,让你看完就能直接上手。
需要先说明一点:WES Code 的跨会话记忆不是“AI 自动记住一切”那种黑盒魔法,它依赖你主动维护一份项目级的记忆文件。理解这一点很关键,后面所有的操作都围绕它展开。
2. WES Code 记忆机制的核心:项目级记忆文件是怎么工作的
2.1 会话记忆与项目记忆的本质区别
要理解跨会话记忆,先要分清两个概念。
会话记忆是临时的。你在一个对话窗口里说的话,只在这个窗口的生命周期内有效。窗口一关,记忆就没了。这就像你和一个人当面聊天,聊完各自走开,下次见面他完全不记得你。
项目记忆是持久的。它把关键信息写进项目目录下的特定文件里,只要项目还在,这些信息就在。每次新开对话,WES Code 会先读取这些文件,把内容作为初始上下文注入。这就像你给新来的同事留了一份项目交接文档,他一看就懂。
两者的对比如下:
| 维度 | 会话记忆 | 项目记忆 |
|---|---|---|
| 生命周期 | 单个对话窗口 | 项目存续期间 |
| 存储位置 | 内存/临时上下文 | 项目目录下的文件 |
| 是否自动加载 | 否 | 是(配置后) |
| 适用场景 | 一次性问答 | 持续迭代的项目开发 |
| 维护成本 | 无 | 需要主动更新 |
关键结论:跨会话记忆的本质,是用文件持久化替代内存临时存储。你维护的文件质量,直接决定 AI 助手“记得”多少、记得多准。
2.2 记忆文件的加载顺序与优先级
WES Code 在启动一个新对话时,会按特定顺序加载记忆文件。这个顺序很重要,因为它决定了当多个文件内容冲突时,谁说了算。
通常的加载逻辑是这样的:
- 全局记忆文件:放在用户主目录下,对所有项目生效。适合放个人偏好,比如“我习惯用 4 空格缩进”“注释用中文”。
- 项目根目录记忆文件:放在项目根目录,只对当前项目生效。适合放项目级约定,比如技术栈、目录结构、接口规范。
- 子目录记忆文件:放在特定子目录下,只对该目录及其子目录生效。适合放模块级规则,比如“这个目录下的代码必须用 TypeScript 严格模式”。
优先级从低到高:全局 < 项目根 < 子目录。也就是说,越靠近具体代码的记忆文件,优先级越高,会覆盖上层同名配置。
注意:不同版本的 WES Code 对记忆文件的命名和加载顺序可能有细微差异,建议先查看你所用版本的官方文档确认文件名。常见命名包括
WES.md、.wescode/memory.md等。
2.3 为什么是 Markdown 而不是数据库
你可能会问:为什么不用数据库或者 JSON 来存记忆,而要用 Markdown 文件?
原因有三点。第一,可读性。Markdown 是人能直接看懂的,你随时可以打开检查 AI 到底“记住”了什么,发现不对直接改。第二,可版本控制。Markdown 文件可以跟着项目一起提交到 Git,团队成员共享同一份记忆,新人拉下代码就自带上下文。第三,低门槛。不需要学任何查询语言或 schema,会写字就能维护。
这三点决定了 Markdown 是项目记忆最务实的载体。数据库适合结构化查询,但项目记忆更多是自然语言的约定和说明,Markdown 刚好匹配。
3. 从零配置一套可用的跨会话记忆
3.1 第一步:确定记忆文件的存放位置
配置跨会话记忆的第一步,是决定记忆文件放哪里。我的建议是分两层:
- 项目根目录放一份主记忆文件,命名建议用
WES.md或项目约定的名字。这份文件承载项目的核心上下文,是所有对话都会加载的。 - 在
.wescode/目录下放扩展记忆,比如memory.md、conventions.md。这些文件用于存放更细的规则,按需加载。
为什么分两层?因为主记忆文件会被频繁读取,内容要精炼;扩展记忆可以写得更详细,但只在需要时引用。这样既保证加载速度,又保证信息完整。
目录结构大概长这样:
my-project/ ├── WES.md # 主记忆文件 ├── .wescode/ │ ├── memory.md # 扩展记忆 │ └── conventions.md # 编码规范 ├── src/ │ └── ... └── package.json3.2 第二步:写一份 AI 能读懂的项目记忆
记忆文件不是写给人看的文档,是写给 AI 看的上下文。所以写法上有讲究。我总结了一个模板,你可以直接抄:
# 项目记忆 ## 项目概述 - 项目名称:某内部管理系统 - 一句话描述:面向内部员工的工单流转与审批平台 - 当前阶段:迭代开发中,主分支为 develop ## 技术栈 - 前端:React 18 + TypeScript 5 + Vite - 后端:Node.js 20 + Fastify - 数据库:PostgreSQL 15 - 状态管理:Zustand - 样式:Tailwind CSS ## 目录结构约定 - src/components:通用组件,每个组件一个目录 - src/features:按业务模块划分的功能代码 - src/api:接口封装,统一走 request.ts - src/utils:纯函数工具 ## 编码规范 - 缩进用 2 空格 - 组件用函数式,禁止 class 组件 - 接口类型定义放在 types.ts,不内联 - 注释用中文,函数必须有 JSDoc ## 接口约定 - 所有请求走 src/api/request.ts 封装 - 错误统一用 toast 提示,不弹 alert - 分页参数:page、pageSize ## 禁止事项 - 不要引入新的 UI 库 - 不要用 any 类型 - 不要直接操作 DOM这份模板的关键在于:信息密度高、结构清晰、没有废话。AI 读一遍就能抓住重点。你要避免的是写成散文,比如“我们这个项目呢,前端用的是 React,然后呢……”这种,AI 也能读,但效率低。
3.3 第三步:让 WES Code 自动加载记忆
写完记忆文件,还要确保 WES Code 每次新对话都会加载它。这一步通常有两种方式:
方式一:配置文件声明。在 WES Code 的配置文件里指定记忆文件路径。比如在.wescode/config.json里写:
{ "memory": { "files": ["WES.md", ".wescode/memory.md"], "autoLoad": true } }方式二:约定命名自动识别。有些版本会约定特定文件名,只要文件存在就自动加载,不需要额外配置。这种情况下你只要把文件放对位置、起对名字就行。
具体用哪种,取决于你的 WES Code 版本。建议先试方式二,不行再上方式一。配置完成后,新开一个对话,问它“这个项目用什么框架”,如果它能准确回答,说明加载成功。
3.4 第四步:验证记忆是否真的生效
配置完不要想当然,一定要验证。验证方法很简单:
- 新开一个对话窗口。
- 问一个只有记忆文件里才有的信息,比如“这个项目的分页参数叫什么”。
- 如果它回答
page和pageSize,说明记忆生效。 - 如果它说“不知道”或者瞎猜,说明没加载成功。
没生效的话,排查顺序是:文件路径对不对 → 文件名对不对 → 配置有没有写错 → 版本是否支持。这四步走完,基本能定位问题。
4. 记忆文件写什么、不写什么:一份实战清单
4.1 必须写进去的四类信息
不是所有信息都值得放进记忆文件。写多了浪费上下文,写少了不够用。根据我的经验,以下四类信息必须写:
第一类:技术栈与版本。这是最基础的。AI 不知道你用什么框架,就可能给出不兼容的代码。比如你用 React 18,它给你写 React 17 的写法,跑不起来。版本号也要写,因为不同版本 API 差异很大。
第二类:目录结构与文件职责。AI 需要知道代码放哪里。你告诉它“组件放 src/components”,它就不会把组件写到 src/utils 里。这一条能省掉大量“你放错地方了”的返工。
第三类:编码规范与风格。缩进、命名、注释语言、类型定义位置,这些都要写。否则 AI 按自己的默认风格写,和你项目格格不入,你还得手动改。
第四类:禁止事项。这一条最容易被忽略,但最重要。明确告诉 AI“不要做什么”,比告诉它“要做什么”更能避免翻车。比如“不要引入新依赖”“不要用 any”“不要改配置文件”,写清楚这些,能挡掉很多意外。
4.2 不该写进去的三类信息
反过来,有些信息不该写进记忆文件:
第一类:频繁变动的信息。比如“当前正在开发的功能是 XX”。这种信息一周就变了,写进去反而误导 AI。这类信息应该放在对话里临时说明,不放进持久记忆。
第二类:敏感信息。密钥、密码、内部地址,绝对不能写进记忆文件,尤其是要提交到 Git 的话。记忆文件是明文存储的,写进去等于泄露。
第三类:大段代码。记忆文件不是代码仓库。不要把整个组件的代码贴进去,AI 不需要。它需要的是约定和规则,不是具体实现。
4.3 记忆文件的更新时机
记忆文件不是写完就不管了。以下时机需要更新:
- 技术栈升级时,比如从 React 17 升到 18。
- 目录结构调整时,比如新增了 src/hooks 目录。
- 编码规范变更时,比如从 2 空格改成 4 空格。
- 发现 AI 反复犯同一个错误时,把“禁止 XX”加进去。
更新频率不用太高,一个月检查一次就够。但每次更新后,记得验证一下是否生效。
提示:把记忆文件纳入 Git 版本控制,团队成员共享。新人入职拉下代码,AI 助手就自带项目上下文,省掉大量口头交接。
5. 多项目、多模块场景下的记忆隔离与复用
5.1 一个项目一份记忆,不要混用
如果你同时维护多个项目,切记一个项目一份记忆文件,不要图省事共用一份。原因很简单:不同项目的技术栈、规范、目录结构都不一样。共用一份记忆,AI 会混淆,给出张冠李戴的代码。
正确的做法是每个项目根目录下都有自己的WES.md。全局记忆文件只放个人通用偏好,比如“注释用中文”“回答简洁点”,不放项目级信息。
5.2 子目录记忆解决模块级差异
大项目里,不同模块可能有不同规则。比如前端模块用 2 空格缩进,后端模块用 4 空格;或者某个模块必须用严格模式,另一个模块不用。这时候用子目录记忆文件。
在src/frontend/下放一份WES.md,写前端专属规则;在src/backend/下放另一份,写后端规则。WES Code 加载时,会按目录层级合并,子目录规则覆盖根目录规则。
这样既保证了项目级约定统一,又允许模块级差异存在。
5.3 团队协作中的记忆同步
团队用 WES Code 时,记忆文件的同步是个现实问题。我的建议是:
- 记忆文件提交到 Git,和代码一起管理。
- 修改记忆文件走正常的代码评审流程,避免有人乱改。
- 在 README 里说明记忆文件的作用和维护方式,让新成员知道有这么个东西。
这样做的好处是,团队里每个人的 AI 助手都基于同一份上下文工作,输出风格和规范一致,减少“你写的代码和我写的不一样”这种摩擦。
6. 实测中容易踩的坑与排查思路
6.1 记忆文件写了但没生效
这是最常见的坑。表现是:文件明明写了,新对话里 AI 还是不知道。排查思路按顺序来:
- 确认文件路径。是不是放在了项目根目录?有些工具只认根目录,放子目录不加载。
- 确认文件名。是不是拼错了?大小写敏感吗?
WES.md和wes.md可能是两回事。 - 确认配置。如果需要在配置文件里声明,是不是漏了?
- 确认版本。你用的版本支持跨会话记忆吗?老版本可能没这功能。
这四步走完,九成问题能解决。
6.2 记忆内容冲突导致行为异常
有时候 AI 的行为很奇怪,比如一会儿用 2 空格一会儿用 4 空格。这通常是记忆文件内容冲突了。比如全局记忆写“4 空格”,项目记忆写“2 空格”,AI 不知道该听谁的。
解决办法是明确优先级。在项目记忆里显式写“本项目覆盖全局缩进设置,用 2 空格”。或者干脆把全局记忆里的冲突项删掉,只保留项目级设置。
6.3 记忆文件太长导致加载慢或截断
记忆文件不是越长越好。太长了,一是加载慢,二是可能超出上下文窗口被截断,导致后面的内容根本没加载。
我的经验是:主记忆文件控制在 200 行以内,扩展记忆按需拆分。如果某个模块的规则特别多,单独放一个文件,用的时候再引用,不要全塞进主文件。
6.4 AI 记住了旧信息,没跟上项目变化
项目改了,记忆文件没更新,AI 就会按旧信息干活。比如目录结构变了,AI 还往老路径写代码。
解决办法是把记忆文件更新纳入开发流程。每次做结构性变更时,顺手更新记忆文件。可以在 PR 模板里加一条检查项:“记忆文件是否需要更新?”这样就不会忘。
6.5 排查链路复盘:一次真实的“记忆失效”经历
说一个我实际遇到的案例。有段时间我发现新对话里 AI 总是忽略我定义的接口封装规则,直接写裸请求。我按排查链路走了一遍:
先看文件路径,WES.md确实在根目录。再看文件名,没拼错。再看配置,autoLoad是 true。最后看版本,支持记忆功能。四步都没问题,但就是不生效。
后来我把记忆文件打开仔细看,发现接口约定那一段被我写在了一个二级标题下面,而那个标题前面有个特殊字符,导致解析时整段被跳过了。把特殊字符删掉,重新测试,生效了。
这个坑告诉我:记忆文件的格式比内容更容易出问题。写完最好用纯文本编辑器检查一遍,确保没有奇怪的符号或格式。
7. 把记忆用活:进阶技巧与长期维护建议
7.1 用记忆文件“训练”AI 的项目直觉
记忆文件用久了,你会发现它不只是“告诉 AI 项目信息”,更是在“训练 AI 的项目直觉”。比如你反复在记忆里强调“错误统一用 toast”,几次之后,AI 写代码时会主动加 toast,不用你每次提醒。
这背后的逻辑是:记忆文件提供了稳定的上下文,AI 在这个上下文里反复工作,行为模式会逐渐贴合你的预期。所以记忆文件写得越准,AI 越“懂”你的项目。
7.2 按场景拆分记忆,而不是堆在一起
当项目变大,记忆文件内容变多时,建议按场景拆分。比如:
WES.md:核心上下文,所有对话都加载。.wescode/api.md:接口相关约定,写接口时引用。.wescode/testing.md:测试规范,写测试时引用。
这样拆分的好处是,每次对话只加载相关部分,不浪费上下文。引用方式可以在主文件里写“接口约定详见 .wescode/api.md”,AI 需要时会自己去读。
7.3 定期回顾记忆文件,删掉过时内容
记忆文件要定期清理。过时的技术栈、废弃的目录、不再适用的规范,都要删掉。留着不仅没用,还可能误导 AI。
我的习惯是每个月花十分钟过一遍记忆文件,把明显过时的内容删掉,把新出现的约定加进去。这十分钟的投入,能省掉后面无数次的返工。
7.4 记忆文件与提示词的配合
记忆文件解决的是“长期上下文”,提示词解决的是“当前任务”。两者配合使用效果最好。比如记忆文件里写了项目规范,你在对话里只需要说“帮我写一个用户列表组件”,AI 就会按规范写,不用你再重复规范。
反过来说,如果记忆文件没写好,你就得在每次提示词里重复项目信息,这正是跨会话记忆要解决的问题。所以,花时间把记忆文件写好,是一劳永逸的事。
7.5 一个长期维护的小技巧
最后分享一个我一直在用的小技巧:在记忆文件顶部放一个“最后更新时间”和“更新人”的注释。这样团队成员一看就知道这份记忆是不是最新的,谁负责维护。格式大概这样:
<!-- 最后更新:2024-06-15 by 某开发者 --> <!-- 下次检查:2024-07-15 -->别小看这两行注释,它能提醒你定期维护,也能让团队知道该找谁问。记忆文件是活的,不是写完就扔的,保持它新鲜,它才能持续帮你省时间。