聊到给 AI 编程工具接外部记忆这件事,我算是把市面上的方案试了个遍。一开始用 Cursor 做重构,核心问题不是代码写得不对,而是它老"失忆"——上午刚定好的接口规范,下午换个会话窗口就忘得干干净净。后来我开始折腾 Claude Code,发现命令行环境下的上下文管理更苛刻。就在我快被这种"金鱼记忆"逼疯的时候,接触到了 MCP 这套协议,然后自己动手搭了一台叫 TiMemMCP Server 的轻量服务,专门解决"AI 记住项目里发生过的事"这个难题。这篇文章就把我接入 Cursor 和 Claude Code 的完整过程、五层时序记忆的设计思路、以及踩过的坑一次讲清楚,适合那些已经开始用 AI 编程、但被长期项目上下文折磨得不行的开发者。
1. 痛点复盘:AI 编程助手为什么总在"失忆"
1.1 我反复吐槽的几个场景
先说几个真实到让人血压升高的场景。
第一个场景是跨会话丢失。某天上午我在 Cursor 里和模型讨论清楚了某个订单模块的数据模型,定了用状态机来管理订单流转,字段名、枚举值都敲定了。下午我重新打开一个会话,让它实现一下这个状态机,结果它按自己的理解重新设计了一套,和上午的约定完全对不上。我只能在提示词里重新把上午的结论粘贴一遍,一次两次还好,项目一复杂,光维护这种"上下文搬运"就烦死人。
第二个场景是跨工具丢失。我用 Cursor 做代码补全和单文件修改,用 Claude Code 做批量重构和脚本任务。两边各有各的好,但因为它们的上下文是隔离的,我在 Claude Code 里让它看过的代码规范、命名约定,换到 Cursor 里它一概不知。同一个项目,两个助手像两个不认识的临时工。
第三个场景是跨时间丢失。有次我出差一周,回来继续一个进行到一半的模块。我打开之前的会话记录,发现模型完全不记得当时已经决定引入某个第三方库、以及决定放弃另一个库的原因。我不得不在代码里翻注释、看 commit 记录,才把这些决定拼出来。那一刻我就在想,如果 AI 能像人一样有自己的"工作笔记",这事应该早有解。
1.2 我试过的临时方案都不太顶用
很多人第一反应是写MEMORY.md,我也写过。最开始确实有效,把项目的架构决策、编码规范、常用命令都塞进去。但用久了问题很明显:
第一,它是静态文件。你要手动维护,忘了更新它就过时,过时的记忆比没有记忆更坑。第二,它没有时间维度。我改了一条规则之后,旧的决策就湮没了,我想追溯"为什么当时选了 A 而没选 B"根本做不到。第三,它没有分层。项目里既有团队层面的规范,也有某个功能模块的局部约定,还有我个人的编码偏好,这些全混在一个文件里,模型读取的时候很难知道哪条更重要。
我也试过每次对话开头粘贴一段"项目摘要",token 消耗大不说,摘要本身就得费劲维护。还试过用脚本把代码库里的注释抽出来喂给模型,但那只是零散信息,构不成结构化的记忆。
后来我意识到,核心问题不是没有记忆方案,而是缺少一个统一的、带时间概念的、能通过标准协议暴露给任意 AI 客户端的记忆服务。也就是这个时候,"MCP 服务"这个概念进入了我的视野。
2. MCP 协议和 TiMemMCP Server 的定位
2.1 MCP 到底帮了什么忙
在说 TiMemMCP 之前,得先把 MCP 这个东西讲清楚。MCP 的全称是 Model Context Protocol,可以把它理解成一条"外接设备总线"。以前 AI 模型只有对话窗口这一个大脑袋,你需要什么信息就得粘贴什么信息,模型想调外部工具还得靠各种本地脚本、API 接口,每个工具都得单独适配。MCP 出现之后,模型可以通过统一协议去调用外部工具、读取外部资源、挂载各种上下文。
我用大白话打个比方:没有 MCP 的 AI 助手像一个人只有一张嘴和一双眼睛,你喂一句它看一句;有了 MCP 之后,它像多了一本工作笔记和一个工具箱,需要的时候可以自己去翻笔记、拿工具。MCP Server 就是那个提供"笔记"和"工具"的服务端,它可以把记忆文件、代码索引、任务清单、外部知识库等都封装成标准接口给模型调用。
所以当我想给 Cursor 和 Claude Code 接入一套统一的记忆系统时,第一时间想到的就是写一个 MCP Server。TiMemMCP Server 就是我基于这个思路做出来的一个轻量级记忆服务。它不是某个大厂出的产品,而是一个可以本地跑、用 SQLite 做存储、通过 MCP 协议对外暴露记忆读写能力的服务。
2.2 它和普通记忆文件的核心区别
我把 TiMemMCP 的设计目标定得很具体:
- 支持分层的记忆结构,不同粒度的信息放在不同层。
- 所有记忆都有时间戳和来源标记,可以回溯。
- 通过标准化工具暴露给 AI 客户端,模型只需要学会几个工具名称。
- 本地存储,不依赖外部 API,安全性可控。
- 支持会话隔离、项目隔离,多个项目之间的记忆互不干扰。
这些目标每一个都对应着我前面踩过的坑。比如时间戳,就是为了解决"追溯决策原因"的问题;记忆分层,是为了解决"什么信息更重要、该优先读哪条"的问题;项目隔离,是为了解决"我在不同项目里用同一个 AI 客户端时,记忆不能串味"的问题。
接下来我会详细讲五层时序记忆的设计,这也是这个服务名字里"TiMem"的来源——Time-aware Memory,带时间感知的记忆。
3. 五层时序记忆:分层逻辑和每层职责
3.1 为什么一定要分五层
很多记忆方案就是一张大表,把所有信息往里面塞,模型读取时靠"相关性"去检索。但我在实际使用中发现,记忆不能只看相关性,还要看信息的稳定度和生命周期。有些信息是临时的,比如"这次重构的下一步任务是改 A 模块",过了几天就没用了;有些信息是稳定的,比如"项目的目录结构约定",它不会轻易变。如果把这两种信息混在一起,模型很容易被临时信息干扰,或者因为临时信息过期而做出错误判断。
所以我设计了五层,从低到高分别是:瞬态层、短期层、项目规范层、用户偏好层、元记忆层。每一层有自己的存储粒度、默认生命周期和读取优先级。
3.2 五层的具体定义和示例
| 层级 | 名称 | 生命周期 | 典型内容 | 存储粒度 |
|---|---|---|---|---|
| L1 | 瞬态层 | 分钟到小时 | 当前会话中用户刚说过的要求、临时决定的变量名写法 | 单条消息级别的碎片 |
| L2 | 短期层 | 数天到数周 | 正在进行的模块任务清单、某个接口当前的实现状态 | 对话摘要级别的段落 |
| L3 | 项目规范层 | 长期(一个项目周期) | 编码规范、架构决策、目录结构约定、技术选型原因 | 结构化条目 |
| L4 | 用户偏好层 | 超长期 | 开发者个人命名偏好、常用工具链、讨厌的编程风格 | 偏好条目 |
| L5 | 元记忆层 | 永久 | 记忆的索引、分类标签、重要事件的关联关系 | 元数据记录 |
我举一个具体例子来说明层的作用。假设我在做一个电商项目,午休前让 AI 写了购物车逻辑的开头,并在对话里说"结算模块用策略模式实现"。这句话很短,但它至少涉及三层记忆:
- "用策略模式实现结算"这个消息级别的结论,先进 L1。
- 同一会话里连续几条消息被汇总之后,形成"结算模块的当前实现计划",进 L2。
- 如果这个策略模式的选择是一个长期的架构决策,它会被提升到 L3,标记为"架构决策:结算模块使用策略模式,因为后续可能接入多种促销规则"。
- L4 可能记录的是我平时的编码习惯,比如"用户偏好:接口命名喜欢动词开头"。
- L5 则是所有这些条目之间的关联,比如"结算模块"相关联的词有"策略模式、订单、支付、促销"。
模型在实际调用时,会先按层级过滤,再按时间排序。比如它关心的是一个刚发生 10 分钟的事,L1 和 L2 的优先级就高;它关心的是跨周的架构决策,L3 的优先级就高。
3.3 "时序"两个字到底做了什么
我在每一层都加了"时序"属性,这也是 TiMemMCP 最花心思的地方。
先说为什么需要时序。假设项目里有一条记忆说"订单状态只保留未支付、已支付、已取消三种"。两周后又有一条新记忆说"订单状态新增了已退款"。如果没有时间机制,这两条记忆会同时存在,模型可能拿旧的当依据。有了时间戳之后,读取时会默认新记录覆盖旧记录。再进一步,如果记忆里保留了"新增已退款的原因",模型就能追溯这条规则是怎么演变的。
在实现上,我给每条记忆都打上了三个时间相关字段:created_at(创建时间)、updated_at(更新时间)、effective_at(生效时间)。前两个好理解,生效时间是专门为"计划性记忆"设计的,比如"从下周开始,所有接口都要走新版本协议"。平时读取时,只会读取 effective_at 早于当前时间的记忆,这样就不会出现模型把"未来的规则"用来处理"现在的代码"这种诡异情况。
这里顺带分享一个细节:我在读取逻辑里加了"时间权重"这个概念。也就是说,检索到多条相关记忆时,不是简单按时间去重,而是计算一个综合分数,时间越近权重越高,但同时参考层级权重。L3 的时间权重可以低一点,因为项目规范是稳定的;L1 的时间权重必须爆表,因为过了 10 分钟它可能就失效了。这个调参过程花了我不少时间,后面在"踩坑记录"里会展开讲。
4. 部署 TiMemMCP Server:从零到跑通
4.1 运行环境准备
我的部署环境是 Linux 机器,配置很简单:2 核 CPU、4G 内存,系统盘 40G。跑 SQLite 完全没有压力。如果你只有一台老笔记本电脑,或者一个低配云主机,也完全够用,因为服务本身很轻。
TiMemMCP Server 的运行时依赖不多,Node.js 18+ 和 SQLite3就够了。如果你的开发机上已经装了 Node.js,直接用它掉进去。没有的话,用系统的包管理器装一下就行。某些系统自带的 Node 版本比较老,建议装到 18 以上,否则一些 MCP 官方包会跑不起来。
安装依赖的步骤大概是这样:
# 我用的系统是 Debian 系,通常先确认 Node 版本 node -v # 如果版本太低,用 nvm 装一个较新的 LTS curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/xxx/install.sh | bash nvm install 20 nvm use 20 # 接着把项目仓库拉下来 git clone <你的TiMemMCP地址> cd timemmcp-server npm install这里有个容易踩坑的点:npm install 之前先看一下 package.json 里的 engines 字段,确保你的 Node 版本满足要求,不然装依赖的时候会看到一堆 node-gyp 报错,非常抓狂。
4.2 初始化配置
TiMemMCP 的配置设计很直白,就是一个 JSON 文件config.json。我的初始配置长这样:
{ "port": 54321, "host": "127.0.0.1", "database": { "type": "sqlite", "path": "/home/dev/data/timmem.sqlite3" }, "storage": { "enable_encryption": true, "encryption_key": "change-me-to-a-random-key" }, "memory": { "l1_ttl": 3600, "l2_ttl": 604800, "l3_ttl": 0, "max_items_per_search": 100 } }我来逐个解释这几个关键配置项的用途:
host我绑的是 127.0.0.1,也就是只允许本地访问。因为我的 Cursor 和 Claude Code 都跑在同一台机器上,不需要对外开放。如果你有多台设备要访问,再考虑绑成局域网地址,但务必加一层访问校验。database.path指定 SQLite 数据库文件的位置。这个路径要提前建好目录,否则服务启动时会报错。enable_encryption是控制是否对敏感字段做加密。我选择开启,因为记忆里难免会存到一些涉及内部信息的片段,比如数据库连接字符串、密钥、内部 API 地址等。l1_ttl和l2_ttl分别是 L1 和 L2 的过期时间,单位是秒。我这里设置 L1 是一小时过期,L2 是一周过期。L3 的 ttl 设成 0 表示永不过期。max_items_per_search是每次检索最多返回多少条记忆。限制这个数很重要,否则一次就把它能用的上下文撑爆了。
配置完以后,执行启动命令:
node server.js如果一切正常,控制台会输出类似TiMemMCP MCP server running at http://127.0.0.1:54321的提示。这时候服务就起来了,但还没连上任何客户端,下一步就是把 Cursor 和 Claude Code 引过来。
4.3 表结构和数据写入逻辑
数据库里我建了三张核心表,设计得比较克制:
memory_items:存储每一条记忆正文、层级、标签、时间字段。memory_sessions:记录来源会话的元信息,比如工具类型(Cursor 还是 Claude Code)、项目路径、会话 ID。memory_relations:存储记忆之间的关联边,比如"这条规范是从上一条决策延伸出来的"。
在实际写入时,服务接收 MCP 请求后,会先判断命中的是哪个工具函数,比如mcp__write_memory还是mcp__update_memory,然后按层级和时间字段写入。为了效率,我没有引入复杂的 ORM,直接用的 SQLite 原生语句加少量封装。写操作本身很快,实测在普通机械硬盘上单次插入耗时都能控制在几毫秒内。
5. 在 Cursor 中接入 TiMemMCP
5.1 Cursor 的 MCP 配置入口
Cursor 这个 AI 编程编辑器对 MCP 的支持还算成熟。我用的版本是较新的版本,它已经支持直接在界面里配置 MCP 服务。入口在设置菜单里,找到MCP相关选项,或者直接打开项目根目录下的.cursor/mcp.json文件进行配置。
用界面配置更直观一些,适合第一次操作的人。方法是点开设置 → 搜索 MCP → 添加新服务器,然后填写服务器名称和启动命令。用文件配置则适合团队同步,把 mcp.json 放进代码仓库,同事拉下来就自动生效。
5.2 配置示例和关键细节
我先给出我在.cursor/mcp.json里用的完整配置:
{ "mcpServers": { "timemmcp": { "command": "node", "args": ["/home/dev/timmemcp-server/server.js"], "env": { "TMMCP_CONFIG": "/home/dev/timmemcp-server/config.json" } } } }这里有几个坑我第一次配置的时候踩过,提醒一下。
首先,command 用了绝对路径还是相对路径,影响很大。Cursor 在启动 MCP 服务时,工作目录不一定是你项目的根目录。如果你写成"command": "node", "args": ["server.js"],它很可能找不到文件。所以 args 里的脚本路径一定要用绝对路径。再看env里的配置文件路径,同样用绝对路径。
其次,要在环境变量里指定 config 文件。我的服务支持从环境变量读取配置路径,这样做的好处是你不需要在代码里硬编码路径,换机器的时候只改配置即可。如果你没有配置 env,服务会去默认路径找配置文件,找不到就报错。
第三,端口冲突要注意。如果你的机器上同时跑了很多开发服务,检查一下 54321 端口有没有被占用。占用的话服务起不来,Cursor 界面里 MCP 工具一直是灰的。用lsof -i:54321就能查。
配置好之后,在 Cursor 里重新加载窗口,MCP 工具列表里应该能看到 timemmcp 下面出现一串工具。加载成功的话,工具前面会显示一个绿色的小圆点;如果显示灰色,说明连接失败,需要回去看命令和路径。
5.3 验证连接是否成功
我习惯先做一次最简单的联调:在 Cursor 的对话输入框里问它"当前记忆服务里有哪些项目条目",它会调用 TiMemMCP 的检索工具,返回结果。如果回答里带出了我之前写入的记忆条目,说明整条链路是通的。如果没带出来,就去 Cursor 的日志或控制台里看 MCP 请求有没有报错。这一步不要跳过,它帮你确认的是"配置正确 + 请求可达 + 模型能调用工具"三个环节,任何一环断了都能立刻暴露出来。
6. 接入 Claude Code:命令行方式的配置流程
6.1 Claude Code 的 MCP 配置方式
Claude Code 是跑在终端里的 AI 编程助手,它的配置方式和 Cursor 有区别。Cursor 主要靠图形界面和项目配置文件,而 Claude Code 偏向命令行操作。不过核心思路一致:告诉它有一个 MCP 服务在某个地址,并给它一批工具函数。
Claude Code 支持两种方式配置 MCP。一种是在项目根目录放.mcp.json,这种方式适合跟着代码库走,团队共享。另一种是全局配置,写入用户目录下的设置文件,这种方式适合跨项目复用同一个记忆服务。我的做法是两个都用:全局配置指到通用的用户偏好记忆,项目配置指到项目相关的记忆层。
6.2 配置命令实操
我用的命令像下面这样:
claude mcp add timemmcp -- cmd /c node C:/timmem/server.js因为我是类 Unix 环境,命令其实更简单:
claude mcp add timemmcp -- node /home/dev/timmemcp-server/server.js添加完以后,可以列出当前所有已添加的 MCP 服务:
claude mcp list输出里会显示 timemmcp 的状态是 connected,还是 failed。failed 的话,检查路径和 Node 版本。
和 Cursor 一样,Claude Code 也会把 MCP 服务里定义的工具加载进来。加载之后,你在对话里就能直接让模型"搜索记忆""保存记忆"了。
6.3 终端里的实际调用效果
我跑过一次完整的交互测试。在项目目录下启动 Claude Code,输入一行提示:
帮我看看这个项目里有没有关于订单模块的架构决策记录。
然后从日志里能看到,Claude Code 调用了 TiMemMCP 的检索工具,传入参数大概是"订单模块 架构决策"。服务端返回了几条记忆,其中一条标着 L3 层、时间戳是上周,内容写着"订单模块采用事件驱动架构,核心事件包括订单创建、支付完成、退款申请"。模型基于这条记忆继续回答。
还有一次我保存了即时印象。我跟 Claude Code 说"以后工具函数的命名最好统一用动词开头",这条信息通过写入工具进了 L4 用户偏好层。隔天我用 Cursor 进行开发时,Cursor 里也能读取到这条偏好,因为两个客户端共享同一个 TiMemMCP Server。这种"一个记忆源、多个客户端共用"的效果,正是我搭建这套服务的最主要动机。
7. 实际项目中的使用效果与检索机制
7.1 记忆是怎么被自动读出来的
TiMemMCP 不只是被动存储,它也会在模型收到用户请求时主动提供相关上下文。这个机制我在设计时叫"上下文预取"。
具体流程是:当模型检测到当前对话涉及项目代码、模块名称等实体时,会调用检索工具,把这些实体的相关内容从记忆库里取出。取出的内容按照层级过滤和时间权重排序后,作为额外上下文拼到模型的消息队列里。
举个例子。我在 Cursor 里打开一个文件,让模型"给这个支付服务补一个超时处理"。模型先解析出这个文件属于支付模块,然后调用检索工具,找出记忆库里关于支付模块的所有条目。发现三天前有一条 L2 记录说"支付回调需要加上幂等校验",还有一条 L1 记录是刚才对话里用户提到的"超时时间改为 30 秒"。两者都会被注入上下文,让模型在修改代码时不会忽略之前定的规则。
7.2 检索排序的分层和时间权重
我提到过"综合分数"这个计算逻辑,这里把公式大致说一下:
score = 关键词相关性得分 * (层级权重 * 时间衰减系数)
层级权重里,L1 和 L2 设得比较高,因为它们往往直接关联当前任务;L3 略低但稳定,不会因为时间衰减而大幅贬值;L4 更低一些;L5 是元信息层,一般不参与常规检索。时间衰减系数则是一个随updated_at距今时长指数下降的因子。L1 的衰减极快,几十分钟后就权重趋近于 0;L3 的衰减很慢,几个月前的规范依然有效。
实际调下来,这套排序逻辑能解决大部分"旧记忆干扰"的问题。但它不是万能的,我后面会讲一个差点让我想砍掉整个重写的 bug。
7.3 一次跨越工具和会话的完整演示
我完整演示一个我自己用得最多的场景。
周一下午,我在 Claude Code 里做批量重构,过程中告诉它:"这个工具库已经废弃,后续所有新代码不要引用它,改用新库。"这条信息写入了 L3 项目规范层。
周三上午,我换到 Cursor 里看一个新模块的需求文档。我向模型提需求时,模型发现相关代码里出现了废弃库的引用,于是检索记忆,读到了周一那条 L3 记录。它主动提醒我说:"这个文件里有用到已废弃的库,规范里说后续不再引用,建议改成新库方案。要自动处理吗?"这种跨会话、跨工具的一致响应,是我搭这套系统以来最爽的体验。
我实际统计过,接入五层记忆后的第二周,我在 Cursor 里回复新手问题的时间减少了,因为不用反复解释项目背景,模型自己就能从记忆库拿到上下文。但也正因如此,记忆膨胀的问题随之而来,这个话题放到下一章。
8. 我踩过的坑与优化经验
8.1 记忆膨胀导致检索变慢和上下文超载
最开始我把所有对话都无条件写入记忆,两周后数据库膨胀到了几十万条记录。表面上看 SQLite 也能扛,但检索效率明显下降,单次查询偶尔会超过 500ms。更头疼的是,检索出来的关联记忆太多,模型可用的上下文窗口被记忆内容占掉大半,真正有用的指令反而排不进去。
我的解决方法:
- 严控写入条件。只在对话里出现明确指令词(比如"记住""以后""规则")时才写 L3 和 L4;L1 和 L2 虽然每条对话都写,但设置 TTL 自动清理。
- 增加"记忆压缩"流程。定期把 L2 中同一主题的多条记录合并成一条摘要,更新
updated_at,原来的碎条删除。 - 给每条记忆加了
source_weight,从用户手动保存的指令权重最高,模型自动总结的权重较低。权重太低的记录在检索时会被忽略。
这样调整之后,检索耗时降回 50ms 左右,上下文也不再被记忆挤爆。
8.2 新旧记忆冲突时的"提示而非篡改"
记忆冲突是我最头疼的问题。有时旧规则是"接口返回 code=0 表示成功",新规则改成"HTTP 200 + body 里 success=true"。两条记忆都在,模型如果只按时间取最新,可能忽略了一部分接口还没有改成新协议的实际情况,导致生成的代码和旧接口不兼容。
后来我把读取策略改成"按时间加权,但冲突时必须同时展示新旧两条记忆,并标记冲突原因"。模型读到冲突信息时会主动询问我以哪个为准,而不是自作主张覆盖。这相当于把记忆服务的角色从"权威答案"变成了"决策辅助"。试下来比单纯更新记忆更靠谱,因为代码仓库里真实存在两种状态的接口。
8.3 敏感信息被写进记忆库的教训
我最担心的事情还是发生了:一次对话里我粘贴了带密钥的配置片段,模型把它当成普通信息写进了记忆库。虽然服务端做了加密存储,但密钥出现在记忆库里总归不是好事。而且如果后续模型在回答时又把这个密钥当成"需要照做的配置"输出,那更麻烦。
我现在采取了几条铁律:
- 在记忆写入前做内容过滤。检测到常见密钥格式(例如
sk-开头、私钥块、连接字符串里的密码字段),直接拒绝写入并提示。 - 对合法写入的敏感字段强制加密,读取时只在同一进程内解密。
- 更重要的是,在 Cursor 和 Claude Code 的提示词里明确加了一条:"涉及密钥和私有信息的内容不要写入记忆,除非用户明确要求。"
- 单独配置了一个"黑名单目录",比如
.env、vault等路径下的内容一概不进入记忆库。
8.4 多人协作时的并发冲突
我的 TiMemMCP Server 本来只在我本机跑,后来我让团队里两个人也接入了同一个服务实例,结果出现了并发写入和读取的冲突。A 写入一条规范,B 在 A 写入还没落盘的间隙发起读取,读到的还是旧版本,导致两个人配合时偶尔出现判断不一致。
解决方案是在写入路径上加了一个乐观锁版本号。每次写入时比对库内当前版本号,不匹配就重试一次;同时检索时增加"最终一致性"机制,在写入冲突时等 50ms 再读一次。也可以直接把 SQLite 数据库放到一个支持并发更好的位置上,但这个项目用 SQLite 就够,不必上更重的方案。
8.5 记忆服务的健康检查与日志
最后聊一个日常维护的细节。TiMemMCP 提供了健康检查接口,返回 JSON 格式的服务状态、数据库连接、记忆条目总数。我会用系统定时任务每分钟拉一次,如果返回异常就报警。日志方面,我保留了每个 MCP 请求的入参和耗时,排查问题的时候特别有用。之前有一次 Cursor 加载工具特别慢,就是靠日志发现某个请求锁了数据库 5 秒,后来定位到是压缩任务还没跑完,改成了凌晨自动跑。
这些日志文件要设置轮转,我用系统自带的 logrotate 按天切分,保留最近 30 天,超过时间自动清理。不然日志文件一样会有膨胀问题。
9. 最后聊点真实的使用感受
如果你正在被 AI 编程助手的记忆力折磨,TiMemMCP 这套思路可以给你一个非常实用的参考。我最终没有把记忆设计成"越大越好",而是强调了分层、时序、冲突提示这三个原则,因为它们才是真实开发中反复出现的问题。多层的意义不是把信息分类得好看,而是让模型在合适的场景只看到合适粒度的信息。
接入过程中我最大的体会是:配置 MCP 服务本身不难,难的是想清楚记忆的写入边界。不该记的东西如果全记录下来,效果反而比没有记忆更差。我现在常用的就三个动作——手动保存重要决策、定期清理过期任务、偶尔查询历史决定的原因。这三个动作覆盖了我 80% 的记忆需求。
还有一个维护建议,我会在每周五下班前花几分钟看一眼记忆库里 L3 层的条目,把过时的标记掉、把仍然有效的整理成一句话。这个过程相当于给 AI 助手做一次"记忆梳理",越来越顺手。别等到记忆库变成垃圾场再去整理,那种状态下连你自己都懒得翻。