跳转至

AI Coding Agent 记忆系统

Ch04.288 AI Coding Agent 记忆系统

📊 Level ⭐⭐ | 8.5KB | entities/ai-coding-agent-memory-system.md

相关实体

深度分析

1. 记忆的本质是分层成本管理

AI Coding Agent 记忆系统的核心问题不是"记什么",而是"以什么成本、在哪一层被召回"。这个思路把记忆从存储容量问题转化为召回路径设计问题。 四层机制各有不同的延迟和成本特征:热记忆(MEMORY.md/USER.md)在每次会话开始时作为 frozen snapshot 注入系统提示词,延迟为零但持续占用 prompt token 预算;session_search 通过 FTS5 全文搜索走数据库查询,成本可控但依赖摘要质量;skills 是按需加载的索引,真正执行时才展开;外部用户模型走异步预取,不阻塞当前轮次。 这种分层和 Agent Harness 的工作集思路完全一致:窗口内只放当前轮次真正需要的工作集,窗口外的资产通过明确的召回路径接入。记忆分层是上下文治理的自然延伸,而不是一个独立的能力堆砌。

2. 热记忆设计优先于向量检索

热记忆是每次会话开始时注入系统提示词的短卡片。设计好这层的边界,比直接上向量库更关键。热记忆必须足够小(MEMORY.md 默认 2,200 字符,USER.md 默认 1,375 字符),只存放每轮都必须知道的高价值事实:用户偏好、稳定环境约定、反复踩过的坑和修正。 字符限制而非 token 限制是朴素但正确的工程选择:它让热记忆大小控制完全不依赖特定模型的 tokenizer,跨模型迁移时热记忆容量仍然有效。 写入边界同样重要。热记忆鼓励保存用户偏好、环境事实、稳定约定;明确不鼓励保存当前任务进度、本次会话结果、临时 TODO 和一次性排查路径。一旦记忆内容会进入 system prompt,它就属于提示词供应链的一部分,必须按这个级别做输入校验和权限管理。

3. 压缩前的状态迁移是记忆可靠性的关键

长会话压缩是所有长期 Agent 都会遇到的挑战。压缩本身不稀奇,真正难的是:压缩后 Agent 还能不能继续干活。如果压缩前不主动把关键状态迁移到 durable memory,压缩后这些状态就永久丢失了。 memory flush 机制在压缩前嵌入了状态迁移逻辑:在历史被磨薄之前,Agent 被给予一次专门机会,把值得长期保留的事实(用户偏好、反复修正、稳定约定)写到热记忆层,然后才让压缩执行。这相当于在历史被磨薄之前做一次 checkpoint。 这条原则可以推广到任何有压缩机制的 Agent 系统:压缩前必须有一次明确的状态迁移机会,否则"记住"这个词在工程上就是空谈。

4. Skills 是程序性记忆,不是日志

Skills 被称为 procedural memory(程序性记忆),这个命名揭示了它真正的设计意图:它不是记录"这次发生了什么"的日志,而是编码"这类任务下次怎么做"的 SOP。 事实记忆回答"环境是什么",会话检索回答"以前发生过什么",Skills 回答"遇到 X 类问题,应该按什么步骤处理"。如果团队反复遇到同一类问题,把解决方案编码成 skill 而不是留在聊天记录里,才是真正的知识沉淀。 Skills 也引入了独特的风险:错误经验一旦固化会比普通错误更难纠正,因为 skill 会在未来反复触发。所以 skill 必须有明确的生命周期管理:能创建、能更新、能删除、能标注适用范围,最好还能附带验证步骤和失败模式。

实践启示

先定义热记忆边界,再上向量库

从零构建 Agent 记忆系统,不要先上向量库或深层用户画像。先把热记忆的边界定义清楚:哪些信息配得上每次进入 system prompt,哪些只应该通过搜索召回。热记忆一旦进来就属于提示词供应链的一部分,必须按这个级别做输入校验和权限管理。

会话历史必须有档案层

不要把所有历史都压进 memory。更好的架构是:完整保存事件/消息 → 提供 FTS5 搜索 → 按 session 聚合 → 局部截断和摘要召回。用户问"上次那个怎么处理的"时,系统应该能查到,而不是让模型凭印象猜。

压缩前必须有一次状态迁移

长任务压缩前要有明确的 durable state extraction 步骤。趁历史还没被压薄,先问:哪些偏好和修正要留到下一轮,哪些只是本轮任务细节?这一步不能靠模型自觉,必须是 runtime 层面的强制 checkpoint。

流程经验要变成可维护资产

反复出现的问题和可复用的方法,光写进总结不够。更好的位置是 skill、runbook、.cursorrules 或 CI 脚本。流程经验要能版本化、能修补、能删除,不能是一旦写进去就再也没人动的旧文本。

记忆必须可观测

至少要能回答:哪些条目进了 prompt,哪些内容来自历史检索,哪些 skill 被触发,压缩前写了什么,外部 provider 返回了什么。如果记忆系统不可观测,最后很容易变成一团没人敢删的旧状态——这比没有记忆更麻烦。