从 Claude Code 到小暖:两类 AI 的记忆哲学之辨
From Claude Code to Xiaonuan — Two Memory Philosophies for Two Kinds of AI
关于”为什么 Claude Code 不用 RAG”,以及陪伴型 AI 该怎么”记住”一个人
引子:一个被忽略的反常识
2026 年 1 月,Anthropic 的 Claude Code 团队负责人 Boris Cherny 在 Hacker News 上写下一段话,被转发了上百万次:
“Claude Code 早期版本用过 RAG + 本地向量数据库,但我们很快发现 agentic search 在大多数情况下都更好。”
在一个”言必称 RAG”的时代,这句话像是从行业主流路线上划下了一道斜线。要知道,在过去三年里,几乎所有”让大模型记住你的代码库”的方案,都建立在同一套技术栈之上:分块(chunking)、向量化(embedding)、向量数据库(vector DB)、语义检索(semantic search)。这是教科书式的标准答案。
而 Claude Code——这个被认为是 2026 年最强的 AI 编程助手——选择了一条更”原始”的路:它不建索引,不做向量化,靠 grep、glob、find、Read 这些 Unix 老兵般的命令行工具,像一个真正的程序员那样,一行一行地探索代码库。
这不是技术上的”退步”,恰恰是 Anthropic 在大量内部 benchmark 之后做出的工程决策。一位 Anthropic 工程师在那条帖子下补充道:“In our testing we found that agentic search outperformed [RAG] by a lot, and this was surprising.”(“在我们的测试中,agentic search 大幅超过了 RAG,这令我们自己也很意外。”)
这件事值得深思的原因,不在于”RAG 是否过时”——那是一个被反复炒作的伪命题——而在于:它逼着我们去重新审视 “AI 记忆”这件事究竟该怎么做。Claude Code 处理的是代码库,那是一个高度结构化、有精确语义、有明确边界的世界。而我们正在构建的小暖,是一个面对老人的语音陪伴系统——它要记住的不是函数签名,而是张阿姨上周提过的孙子叫什么、李大爷昨天血压高了三天没说话、王奶奶最近开始反复讲同一个故事。
两类 AI,两种记忆哲学。Claude Code 的方案能否被小暖借用?还是说,小暖必须走一条完全不同的路?
这篇文章试图把这个问题讲清楚。我们会从 Claude Code 不用 RAG 的真正原因谈起,剖析它的四层记忆架构,然后转向小暖这类陪伴 AI 的记忆管理范式(mem0、Letta、知识图谱、自管理记忆),最后回答一个核心问题:对于”治未病 + 老人陪伴”这样一个高情感密度、低数据规模、长时间跨度的场景,最合理的记忆架构应该长什么样?
第一部分:Claude Code 为什么不用 RAG
1.1 先把”RAG”这个词说清楚
讨论这个问题之前,必须先消除歧义。“RAG”在不同语境下含义不同:
- 广义 RAG:任何”检索外部信息 + 基于检索结果生成”的机制。按这个定义,Claude Code 调用
grep然后基于结果生成回答,也是 RAG。 - 狭义 RAG:业界通常默认的那个标配——“文本分块 + Embedding + 向量数据库 + 相似度检索”。
Claude Code 抛弃的是狭义 RAG,而不是”检索增强”这个理念本身。Boris 的原话也只是说不用 vector DB,并不是说不检索。换句话说,他们抛弃的是特定的实现方式,保留了信息检索的核心思想。
这个区分很重要,因为接下来我们会看到:小暖也需要某种形式的”检索增强”,但它具体应该长什么样,恰恰是这篇文章要讨论的核心。
1.2 Claude Code 的实际工作方式:agentic search
Claude Code 在面对一个陌生代码库时,做的事情和一个有经验的工程师几乎一样:
Turn 1: glob "**/*auth*" → 找到 5 个相关文件
Turn 2: grep "login" auth/ → 找到 12 处匹配
Turn 3: Read auth/login.ts → 读取完整内容
Turn 4: grep "validateToken" --next → 顺着 import 链追踪
Turn 5: Read auth/token.ts → 读取依赖文件
...
每一步都是 LLM 自己主动发起的工具调用:它先看目录结构,再用关键字搜索,读相关文件,跟踪引用关系,必要时回溯重搜。整个过程是可观察的、可解释的、可追溯的。
这套机制有四个关键特征:
- 零预处理:不需要事先建索引、训练 embedding、维护向量库。
- 始终新鲜:直接读文件系统,永远不会出现”索引和代码不一致”的问题。
- 精确匹配:
createD1HttpClient这个函数名要么在文件里,要么不在——没有”语义模糊正例”。 - 本地隔离:代码不会被发送到外部 embedding 服务,对企业用户是巨大的合规优势。
1.3 为什么 RAG 在代码场景下输了
要理解 Claude Code 的选择,需要理解 RAG 在代码场景下的”四个软肋”:
软肋一:精度问题
Embedding 的本质是把文本压缩成几百维的稠密向量,然后用余弦相似度找”语义相近”的内容。这在写散文、找文档、聊天记录场景下是优势,但在代码场景下是灾难。代码里的 userAuth 和 authUser 在 embedding 空间里可能非常接近,但它们是完全不同的两个东西。一个搞错就是 bug。
软肋二:陈旧性问题(staleness)
代码每天都在变。如果你建了索引,那索引就要不断重建;如果不重建,索引就会和实际代码漂移。在一个团队同时修改的活跃代码库里,“昨晚的 embedding 索引”很可能已经过时几百次了。这是一个工程上的无底洞。
软肋三:基础设施复杂度
要做好 RAG,你需要:embedding 服务、向量数据库、索引重建守护进程、查询接口、监控系统、权限隔离。每一层都是新的故障点。而 agentic search 用的是操作系统自带的 grep 和文件系统——稳定、零依赖、零运维。
软肋四:隐私和安全
把代码发到云端 embedding 服务做向量化,这件事对很多企业(尤其是金融、医疗、国防)是不可接受的。本地跑 embedding 模型可以解决一部分问题,但又会带来 GPU 资源、模型管理、性能瓶颈等新问题。agentic search 天然 local-first,数据从不离开机器。
1.4 还有一个更深的原因:“苦涩的教训”对齐
Rich Sutton 那篇著名的 The Bitter Lesson 说过:长期来看,依赖算力和搜索的通用方法,总会击败依赖人类先验知识构建的精巧方法。
RAG 的本质,是用”人类设计的检索流程”去弥补”模型能力不足”。它假设模型搞不定大上下文,所以提前帮它”挑好”该看什么。但 2026 年的现实是:模型的上下文窗口已经做到 200K+ token,模型自己的工具调用能力越来越强,模型自己决定”该 grep 什么”的判断力越来越好。
当你让模型自己决定该读什么的时候,模型变强,方案就自动变强。当你用 RAG 帮模型预先决定的时候,模型变强,你的 RAG pipeline 没有跟着变强——除非你重新做工程。
这就是 Anthropic 内部测试发现 agentic search “大幅超过 RAG”的根本原因。它不是某个具体技术的胜利,而是架构哲学的胜利:把判断权交给模型,让模型成为可组合的智能单元。
1.5 那 Claude Code 用什么”记住”东西?
现在我们可以正面回答标题的第一个问题了:Claude Code 不用 RAG,那它用什么完成记忆?
答案是一个四层文件系统记忆架构:
┌─────────────────────────────────────────┐
│ Layer 1: Session Memory (200K context) │ ← 当前对话上下文窗口
├─────────────────────────────────────────┤
│ Layer 2: CLAUDE.md (project memory) │ ← 项目根目录,开发者手写
├─────────────────────────────────────────┤
│ Layer 3: MEMORY.md (auto memory) │ ← Claude 自己写的学习笔记
├─────────────────────────────────────────┤
│ Layer 4: Filesystem (agentic search) │ ← grep/glob/find on demand
└─────────────────────────────────────────┘
Layer 1:Session Memory(会话内记忆)
200K token 的当前会话上下文。所有当前任务的代码、对话、工具输出都在这里。会话结束就消失(除非用 claude -c 续接)。
Layer 2:CLAUDE.md(项目记忆)
每个项目根目录下的一个 Markdown 文件,由开发者手写。内容是项目的”宪法”——架构约定、命名规则、构建命令、技术栈选型、那些”踩过的坑”。每次启动 Claude Code,它都会自动读取。可以理解成”团队的入职手册”。
# CLAUDE.md
## 技术栈
- 包管理器:始终用 bun,不要用 npm
- 测试:vitest,不要 jest
- 日志:必须用 pino,不要 console.log
## 架构约定
- API 路由统一在 /src/api/,按资源命名(users.ts, orders.ts)
- 数据库 schema 在 /db/schema/,禁止直接写 SQL
## 容易踩的坑
- payment.ts 里的 chargeUser() 有重试逻辑,不要再加 try/catch
- legacy/ 目录的代码不要碰,会触发线上 cron 任务
Layer 3:MEMORY.md(自动记忆)
这是 2025 年下半年新加入的能力。Claude 在工作过程中,自己判断哪些信息值得长期保留:用户的纠正、反复出现的偏好、调试出来的解决方案、那些”我下次还会忘”的细节。它会自动写入 ~/.claude/projects/<项目>/memory/MEMORY.md。
用户也可以主动指令:
> 以后这个项目都用 tab 缩进,不要空格
[Claude 把这条规则写入 MEMORY.md]
> 忘掉关于代码风格的偏好
[Claude 删除相关条目]
这里有一个非常关键的设计细节:MEMORY.md 有一个 200 行的硬上限。这不是技术限制,而是设计约束——它强迫系统保持精简,强迫”低价值记忆”被自然淘汰,强迫高频出现的模式被提炼为永久规则。这是一种”通过限制实现质量”的工程智慧。
Layer 4:Filesystem(按需检索的”长期记忆”)
整个代码库本身就是 Claude Code 的”长期记忆”。需要时通过 grep/glob/Read 现场拉取。这种”懒加载”模式避免了向量索引的所有问题,代价是每次都要花 token 去搜索。
1.6 Claude Code 记忆架构的设计哲学
把这四层放在一起看,能提炼出三条核心哲学:
哲学一:分层 + 显式 + 可编辑
不同时效、不同稳定性的信息放在不同层。开发者写的规则(CLAUDE.md)和 Claude 自己学的经验(MEMORY.md)是分开的,方便审计、修改、版本控制。用户随时可以 /memory 看到 Claude 加载了哪些记忆文件——记忆是透明的,不是黑盒。
哲学二:让模型自己管理记忆
不是开发者写规则告诉模型”这种情况下保存这个东西”,而是模型自己判断什么值得记。Boris 团队在博客里反复强调这一点:模型的判断力是会越来越强的,把记忆管理权交给模型,本身就是在押注模型能力增长。
哲学三:文件系统是世界上最好的数据库
Markdown 文件是人类可读的、文本编辑器友好的、Git 可追踪的、永远不会”格式过时”的。比起 PostgreSQL + pgvector,纯文本文件在可移植性、可调试性、可审计性上全面占优。这是 Unix 哲学的延续——“一切皆文件”。

第二部分:陪伴型 AI 的记忆管理范式
现在我们转到第二个问题:像小暖这样的陪伴型 AI,业界主流是怎么做记忆管理的?
这是一个完全不同的场景。我们先把场景特征列清楚:
| 维度 | Claude Code | 小暖(陪伴型 AI) |
|---|---|---|
| 数据形态 | 高度结构化(代码) | 非结构化(口语对话) |
| 数据规模 | 大(千万行级别) | 小(单用户对话累积) |
| 查询模式 | 精确匹配(找函数名) | 模糊召回(找”前几天聊过的事”) |
| 时效性 | 强(代码每天在变) | 弱(一个老人的生活很慢) |
| 用户主动检索 | 强(开发者会主动指引) | 弱(老人不会说”请查询昨天的对话”) |
| 错误成本 | 高(搞错就是 bug) | 中(搞错就是不自然) |
| 情感维度 | 几乎为零 | 核心维度 |
| 关系演化 | 无 | 有(关系会随时间深化) |
这八条差异里,每一条都在告诉我们:Claude Code 的方案,至少不能照搬。
2.1 业界主流的四种记忆架构
在 2025 到 2026 这一年间,陪伴型 AI 和 agent 领域逐渐沉淀出四种主流的记忆架构。下面逐一分析。
架构一:向量记忆层(Mem0、Zep 为代表)
这是最接近”标准 RAG”的方案,但做了大量针对对话场景的优化。Mem0 的核心思路是:不要把整个对话历史塞进向量库,而是先用 LLM 提炼”事实”,再向量化存储。
工作流程:
用户:今天我和孙子去公园了,他给我带了一束花。
↓
LLM 事实提炼:
- 用户有一个孙子
- 用户和孙子今天去了公园
- 孙子给用户送了花
↓
比对已有记忆,决定 ADD / UPDATE / DELETE / NOOP
↓
存入向量数据库
↓
下次对话时,根据当前语境检索 top-k 相关事实
Mem0 在 LOCOMO 长对话基准上的表现:78% 事实提取准确率,94% 检索相关性。在标准 RAG 60% 左右的基础上有明显提升,主要原因是它不再依赖向量相似度作为唯一信号,而是引入了 LLM-as-judge 的事实抽取层。
优点:成熟、好用、社区资源丰富、可以”贴”在任何 agent 框架上。
缺点:本质上还是向量召回。对于”上周三聊到的那件事”这种时间精确的查询,向量召回基本无能为力;对于”奶奶提到的人物关系网”,向量召回也很难做多跳推理。
架构二:操作系统式记忆(Letta / MemGPT 为代表)
这是 UC Berkeley 那篇 MemGPT 论文衍生出的方案。核心想法:把 LLM 的上下文窗口当作虚拟内存来管。
它把记忆分成三层:
┌──────────────────────────────────┐
│ Core Memory (RAM) │ ← 始终在上下文里的核心信息
│ 如:用户名字、当前任务、关键偏好 │
├──────────────────────────────────┤
│ Recall Memory (Disk Cache) │ ← 最近的对话历史
│ 按需 page-in 到上下文 │
├──────────────────────────────────┤
│ Archival Memory (Cold Storage) │ ← 长期归档,向量检索
└──────────────────────────────────┘
最关键的设计是:模型自己用函数调用决定什么时候 page-in、page-out。当模型觉得”我需要回忆一下三周前我们聊过什么”,它会主动调用 recall_memory_search();当它觉得”这个事实值得永久保留”,它会主动调用 core_memory_append()。
这其实和 Claude Code 的设计哲学高度一致——把记忆管理权交给模型本身。
优点:在长时程任务、连续多轮对话上表现极好。Letta 在 30 天连续运行测试中能在 500+ 次交互后仍保持任务连贯性,而标准 RAG 在 50 次后就开始崩溃。
缺点:每次记忆操作都要消耗 token(要 LLM 判断),延迟高、成本高。对老人陪伴这种单次交互价值不高、但累积价值很高的场景,单位成本可能扛不住。
架构三:知识图谱记忆(Graph-RAG、Cognee、Zep 部分能力)
把记忆建模成实体和关系的图:
[用户] —有孙子→ [小明]
[小明] —职业→ [程序员]
[小明] —居住地→ [北京]
[用户] —关心→ [小明的工作]
[用户] —近期情绪→ [想念]
查询时不再是向量相似度,而是图遍历——“用户最关心的人是谁?” → 顺着 关心 这条边走。“和孙子有关的话题有哪些?” → 找到 [小明] 节点的所有邻居。
优点:在涉及人物关系、跨实体推理、时序推理的查询上无可替代。对老人陪伴尤其重要——老人的世界本质上是”人和人的关系网”。
缺点:图谱构建成本高(需要专门的关系抽取流程)、维护复杂、查询语言(Cypher 等)对 LLM 不够友好。生产环境很少单独用,通常和向量记忆混合。
架构四:提供商管理的记忆(ChatGPT Memory、Claude Projects)
不用自己实现,让平台帮你管。ChatGPT 在每条消息后自动决定”要不要存”,Claude.ai 有 Projects 和跨会话 memory。
优点:零工程成本。
缺点:完全不可控、不可审计、不能定制、有数据出境风险。对小暖这种 To C 自研产品,这条路完全行不通。
2.2 2026 年的现实:没有银弹
把这四种架构放在一起看,2026 年业界的共识是:没有一种架构能单独通吃所有场景。生产环境的成熟方案,几乎都是混合架构:
┌─────────────────────────────────────────────┐
│ 对话短期窗口(最近 N 轮) │ ← 直接在上下文里
├─────────────────────────────────────────────┤
│ 事实层(Mem0 风格) │ ← LLM 提炼 + 向量召回
│ - 用户偏好、个人信息、习惯 │
├─────────────────────────────────────────────┤
│ 关系层(知识图谱) │ ← 实体 + 关系
│ - 家人朋友、人际网络 │
├─────────────────────────────────────────────┤
│ 时序层(按时间索引的事件日志) │ ← 时间精确查询
│ - "上周三说的""上个月开始的" │
├─────────────────────────────────────────────┤
│ 原始对话归档(必要时回查) │ ← 审计 + 调试
└─────────────────────────────────────────────┘
每一层用最适合它的技术,每一层服务一类查询模式。这才是工业界正在收敛的形态。
第三部分:聊天时如何应用这些记忆
讲完”存”,必须讲”用”——记忆系统的成败,一半在存,一半在用。
3.1 应用记忆的三个时机
陪伴型 AI 在一次对话中调用记忆,主要有三个时机:
时机一:会话启动时(预加载)
老人刚发起一次对话(或者说”小暖”被唤醒),系统应该把核心身份信息预先注入到 system prompt 里:
你正在和张桂兰阿姨对话。
- 76 岁,独居,住在北京海淀
- 有高血压和轻度糖尿病,按时吃药
- 有一个女儿(在上海)和一个孙子(小明,12 岁)
- 最近三周情绪稳定,但提到"想孙子"的频率上升
- 喜欢京剧,特别是程派;不喜欢被催促节奏
- 最近一次对话:昨晚 8 点,聊了天气和睡眠
这部分应该是精炼的、结构化的、不超过几百 token 的。它对应 Claude Code 里的 CLAUDE.md——“这个项目(这个老人)的基本宪法”。
时机二:识别到检索意图时(按需召回)
当老人说”上次我跟你讲过的那个事”、“我孙子叫什么来着”、“上礼拜你给我推荐的那个戏”,模型应该识别出这是显式的记忆查询,主动去事实层、时序层、关系层做检索。这里需要的不是模型自己有记忆,而是模型有能力调用记忆工具。
工具大致长这样:
recall_facts(query: str, top_k: int = 5) -> List[Fact]
recall_events(time_range: TimeRange, topic: str = None) -> List[Event]
recall_relations(entity: str) -> Graph
时机三:模型自己判断需要时(隐式检索)
这是最考验设计的部分。比如老人说”我今天有点累”,模型不应该只回应字面意思,而应该自动去查:
- 最近几天她身体状况的事件记录
- 是否提过类似的话(如果是反复出现,可能是抑郁信号)
- 最近一次提到”累”是什么场景
这个能力本质上要求模型在每一轮对话中,自动判断”我现在需要哪些上下文之外的信息”。这是 agentic search 思想在陪伴场景的延伸。
3.2 一个关键的反模式:不要过度检索
这是很多陪伴型 AI 项目踩过的坑。如果每一轮对话都召回十几条历史事实塞进 prompt:
- 模型会被噪音淹没,回答变得啰嗦、刻意、“太想表现自己记得”
- token 成本爆炸
- 老人会觉得”它在监视我”——隐私感和情感安全感被破坏
好的记忆调用应该是隐形的、克制的、自然的。 一次对话里,可能只有 20% 的轮次需要主动检索;剩下 80% 的时候,预加载的核心身份信息已经足够。
这对应到 Anthropic 自己的 Claude 内部记忆规范里有一段话,我觉得讲得很好:“Claude responds as if it inherently knows information from past conversations - like how a human colleague might recall shared history without narrating their thought process or memory retrieval.”——像一个老朋友自然地想起一件事,而不是像一个数据库在做查询。
3.3 记忆的写入:异步、增量、可回滚
应用记忆的另一面是更新记忆。这里有三个工程原则:
原则一:异步写入
对话过程中不要打断生成去更新记忆。老人说话停顿很短,反应慢一点都会破坏体验。记忆更新应该在响应发出后异步进行(用消息队列、后台 worker、或者干脆在对话结束后批量做)。
原则二:增量提炼
不要每次都全量重新提炼记忆——成本爆炸。而是基于当前对话片段 + 已有记忆做增量决策:这条新信息是 ADD(新事实)、UPDATE(修正已有事实)、DELETE(明显矛盾)、还是 NOOP(不重要)?
Mem0 论文里有一个有意思的发现:在 LOCOMO 基准上,加上 ADD/UPDATE/DELETE/NOOP 这套增量决策,比单纯往向量库里塞信息,准确率提升 10% 以上。
原则三:可回滚 + 可审计
老人说错的话、模型理解错的话,必须能被纠正。“我女儿不在上海,她搬到深圳了。” 模型应该能立刻 UPDATE 这条事实,且这次更新要有记录、可追溯。Claude Code 的 MEMORY.md 是纯文本可编辑的,这个设计在小暖的场景里同样适用——管理后台应该能让运营人员直接看到、直接修改老人的记忆档案。

第四部分:小暖能借用 Claude Code 的哲学吗
终于到了核心问题。Claude Code 的设计哲学放在小暖身上,哪些可以借、哪些不能借?
4.1 可以借的三件事
借鉴一:分层记忆架构
Claude Code 的”会话 + 项目宪法 + 自学笔记 + 长期文件系统”四层架构,结构上完全适配小暖。映射过来就是:
┌───────────────────────────────────────────┐
│ Layer 1: 当前对话窗口 │
│ - 最近 N 轮口语对话 │
├───────────────────────────────────────────┤
│ Layer 2: 用户档案(XIAONUAN.md 风格) │
│ - 基本信息、健康状况、家庭关系 │
│ - 喜好、性格、忌讳 │
│ - 由产品团队 + 子女初始化,可被持续编辑│
├───────────────────────────────────────────┤
│ Layer 3: 自动记忆(AUTO_MEMORY.md) │
│ - 模型从日常对话中提炼的事实和模式 │
│ - 用户主动告知的偏好和纠正 │
│ - 200 行硬上限,自然淘汰低价值条目 │
├───────────────────────────────────────────┤
│ Layer 4: 长期事件日志 + 关系图谱 │
│ - 时序索引的对话事件 │
│ - 人物关系图 │
│ - 按需检索,agentic 拉取 │
└───────────────────────────────────────────┘
这个结构最大的优势是职责清晰:Layer 2 是”宪法层”,运营和家属可编辑;Layer 3 是”学习层”,模型自管;Layer 4 是”档案层”,需要时按需召回。
借鉴二:让模型自己管理记忆
不要写死规则告诉模型”在 X 情况下保存 Y 信息”。设计若干个记忆工具给模型:
update_user_profile(field: str, value: str)
add_to_auto_memory(content: str, category: str)
log_event(event_type: str, content: str, importance: int)
add_relation(entity_a: str, relation: str, entity_b: str)
mark_for_human_review(reason: str) # 重要的逃生舱
让模型自己在对话过程中判断什么时候用。这件事最大的好处是可扩展性——随着 Qwen3、DeepSeek、GLM 等基础模型能力提升,整个记忆系统的质量会自动提升,不需要重新做工程。
借鉴三:用 Markdown 作为记忆的”母语”
Claude Code 用 Markdown 文件存记忆有几个好处对小暖完全成立:
- 人类可读:运营、家属、医生都能直接看懂用户档案
- 可版本控制:Git 跟踪记忆变更,回滚一次错误的更新很简单
- 格式不会过时:十年后这些文件依然能打开、能被任何工具处理
- LLM 原生友好:Markdown 是当今所有 LLM 训练数据里占比最高的格式之一,模型对它的理解最好
具体到小暖的实现,每个用户的 XIAONUAN.md 可以长这样:
# 张桂兰阿姨
## 基本信息
- 76 岁,独居
- 住址:北京海淀区某小区
- 紧急联系人:女儿(138xxxx)
## 健康
- 高血压(缬沙坦,早 1 粒)
- 轻度糖尿病(二甲双胍,早晚各 1 粒)
- 膝盖不好,行走慢
- 听力:右耳偏弱,请提高音量
## 家庭
- 女儿:在上海工作,每两周通话一次
- 孙子:小明,12 岁,最近升初一
- 已故老伴:李建国,2019 年去世,提及时温和
## 偏好与性格
- 喜欢京剧(程派青衣)
- 不喜欢被催促
- 早睡早起(晚 9 点入睡)
- 信赖小暖,但忌讳"被监视"感
## 沟通风格
- 语速适中偏慢
- 多用京味儿词
- 不要太多"亲爱的""宝贝"这类称呼
- 遇到情绪低落时优先共情,不要急着给建议
## 治未病关注点
- 血压每周记录
- 睡眠质量
- 情绪波动(特别留意孤独感和回忆已故老伴的频率)
这个文件初始版本由家属和产品团队共同填写,之后模型可以在 Auto Memory 里补充。它是小暖在每次对话开始时加载的”宪法”。
4.2 不能直接借的两件事
差异一:agentic search 在小暖场景下不成立
Claude Code 能用 grep 是因为代码是结构化文本,函数名、变量名都是精确字符串。小暖的”代码库”是什么?是几个月、几年累积下来的口语对话日志。
grep "孙子" 能找到所有提到孙子的对话,但找不到:“上次她说不想见小明,是哪天?” 或 “她最近情绪是不是变差了?“——这些查询需要语义理解和情感推理,不是字符串匹配能解决的。
结论:底层的”长期记忆”必须用某种检索增强(向量召回 + 知识图谱 + 时序索引)。完全的 agentic search 在这个场景下不工作。
但是——agentic search 的精神可以保留:让模型在每一轮对话中自己决定是否需要去查、查什么、查多深,而不是固定每轮都做检索。
差异二:用户特征决定了”信息密度”完全不同
Claude Code 的用户是程序员。他们会主动维护 CLAUDE.md,会精确告诉模型”用 bun 不要用 npm”,会指出错误然后让模型记下来。这是一种高信息密度、高反馈精度的交互。
小暖的用户是 70 岁以上的老人。她不会说”请把这条加入你的记忆系统”。她说的是”哎呀我女儿前天给我打电话来着……是周二?还是周一?反正就那个,她说……”——你需要从模糊的、跳跃的、口语化的、有重复的、带方言的语流里提炼信息。
结论:小暖的事实提炼层必须更”重”。需要:
- 更强的语义理解(指代消解、时间推理)
- 更宽容的容错(不能要求老人说话精确)
- 更多的隐式信号采集(情绪、语速、停顿、犹豫)
- 更被动的纠正机制(不能指望老人主动纠正,必须靠多次重复确认 + 家属审核)
4.3 小暖独有的、Claude Code 不需要考虑的事
陪伴 AI 还有几件事是 Claude Code 完全不涉及的,必须专门设计:
独有点一:情感维度的记忆
代码不会”心情不好”。但老人会。一段对话不仅有事实信息,还有:
- 当时的情绪(高兴 / 孤独 / 焦虑 / 平静)
- 情绪的趋势(这周比上周更孤独吗?)
- 触发因子(一提到老伴就低落?一提到孙子就开心?)
这些信息对治未病和心理预警至关重要,是小暖区别于普通客服 bot 的核心价值。专门设计一个 EmotionTimeline 数据结构,每条对话事件附带情绪标签,按时间维度可视化,这是必须做的。
独有点二:关系网络的演化
老人的世界是关系网。家庭关系、邻里关系、过去的同事、已故的亲友。这些关系不仅要记录,还要追踪演化:
- 谁多久没联系了?
- 哪些关系最近频繁出现?
- 哪些关系出现频率突然下降?(可能意味着冲突或悲伤事件)
这要求一个真正的轻量级知识图谱——不需要 Neo4j 那种重型方案,可以用一个简单的 JSON 文件存储 [entity, relation, entity, last_mentioned_at] 四元组就够了。
独有点三:医疗安全护栏
这是和 RAG 设计相关但又超越 RAG 的一层。小暖的 RAG 必须有安全检索源,并且要确保医疗类查询只从经过认证的知识源召回(中医治未病知识库、官方健康指南、产品团队审核过的内容)。绝不能让模型用通用知识”自由发挥”医疗建议。
这一层是 Claude Code 完全不需要的,但对小暖是红线。
独有点四:长期叙事的一致性
陪伴关系需要”连贯的角色感”。如果小暖三个月前说自己”特别喜欢冬天”,三个月后又说”我最讨厌冷天”,老人会立刻产生不信任感。Claude Code 不在乎一致性,因为它不扮演角色。小暖必须维护一份自我角色档案(persona memory),里面写明小暖自己的性格、偏好、口头禅、对一些常见话题的稳定态度,每次响应都参照这份档案保持一致。
4.4 小暖记忆架构的综合建议
把所有的分析综合起来,小暖的记忆架构建议长这样:
┌──────────────────────────────────────────────────────────────┐
│ 会话层(Session) │
│ - 当前对话最近 N 轮 │
│ - 当前对话的情绪轨迹 │
│ - 当前对话的话题栈 │
├──────────────────────────────────────────────────────────────┤
│ 用户宪法层(XIAONUAN.md,借鉴 CLAUDE.md) │
│ - 基本信息 / 健康 / 家庭 / 偏好 / 沟通风格 │
│ - 由家属和运营共同维护,模型只读 │
├──────────────────────────────────────────────────────────────┤
│ 小暖角色层(PERSONA.md) │
│ - 小暖自己的角色档案,所有用户共享 │
│ - 性格、口头禅、稳定立场 │
├──────────────────────────────────────────────────────────────┤
│ 自动记忆层(AUTO_MEMORY.md,借鉴 Claude Code MEMORY.md) │
│ - 模型从日常对话中提炼,可读可写 │
│ - 严格的长度上限(如 300 行),强制淘汰 │
├──────────────────────────────────────────────────────────────┤
│ 事实知识库(FactStore,Mem0 风格) │
│ - 向量化存储用户事实 │
│ - 增量 ADD/UPDATE/DELETE/NOOP │
├──────────────────────────────────────────────────────────────┤
│ 关系图谱(RelationGraph,轻量级) │
│ - 实体 + 关系 + 时间戳 │
│ - JSON 存储,按需召回 │
├──────────────────────────────────────────────────────────────┤
│ 时序事件流(EventTimeline) │
│ - 所有对话事件按时间排序 │
│ - 附带情绪标签和重要性评分 │
│ - 支持时间窗口查询 │
├──────────────────────────────────────────────────────────────┤
│ 安全知识库(SafetyKB,专用 RAG) │
│ - 治未病、医疗、健康知识 │
│ - 经过严格审核,独立向量库 │
│ - 唯一被允许在医疗类问答中召回的知识源 │
├──────────────────────────────────────────────────────────────┤
│ 原始对话归档(RawArchive) │
│ - 完整对话日志,加密存储 │
│ - 仅用于审计、回放、家属授权查看 │
└──────────────────────────────────────────────────────────────┘
工具暴露给模型的层面:
# 写入工具(模型主动调用)
update_user_profile(field, value) # 慎用,需家属审核
add_to_auto_memory(content, category) # 自由使用
log_event(event_type, content, importance, emotion)
add_relation(entity_a, relation, entity_b)
mark_concern(category, urgency, reason) # 治未病预警
# 检索工具(模型按需调用)
recall_facts(query, top_k=5)
recall_events(time_range, topic=None)
recall_relations(entity)
query_safety_kb(question) # 唯一医疗源
# 元工具
review_recent_emotional_trend(days=7) # 情绪回顾
get_today_context() # 今日话题预热
这个架构同时具备:
- Claude Code 的分层 + 显式 + 模型自管哲学
- Mem0 的事实提炼 + 增量更新机制
- Letta 的模型驱动的按需召回思路
- 知识图谱的关系推理能力
- 时序索引的时间精确查询能力
- 陪伴场景独有的情感、关系、安全三个专属维度
第五部分:几个落地工程上的建议
最后,几条具体落地时的工程建议:
建议一:先做 Layer 2 + Layer 3 + Layer 7(时序事件流),其他往后排
不要一上来就上知识图谱、上 Mem0、上 Letta。MVP 阶段,三个 Markdown 文件 + 一张事件表,已经能覆盖 80% 的场景。优先把”用户宪法”和”自动记忆”两件事打磨到位,剩下的等真实用户反馈来驱动。
建议二:把记忆系统的”可解释性”做成 P0
每一条记忆条目都要能回答三个问题:什么时候记的?从哪条对话来的?为什么模型觉得值得记? 这对调试、审计、家属信任都是关键。可以参考 Claude Code 的 /memory 命令的设计——一个命令就能看到模型当前加载了哪些记忆文件。
建议三:异步处理一切非关键路径
记忆提炼、向量更新、图谱构建、情绪分析,全部异步。响应延迟必须保留给”听清楚 + 想明白 + 说自然”这三件事。NATS、Dify 的异步节点、独立的后台 worker 都可以承担。
建议四:把”忘记”和”记住”做得一样好
老人有隐私需求,家属有合规需求。“小暖,忘掉刚才那段。""把上个月的聊天记录全部删除。“——这些指令必须有干净的执行路径,包括从向量库、图谱、归档中级联删除。Claude Code 的 > Forget the preference about X 是个好范例。
建议五:警惕”过拟合”到个别老人
模型自动记忆的危险之处在于:如果老人有一次说错的、或情绪极端时说的话,被错误地长期保存下来,后面就会反复影响对话。设计上要给 Auto Memory 加时间衰减——长期未被复现的”事实”应该自然淡化,而不是永久占据档案。这一点 Claude Code 的 200 行硬上限就是一种朴素但有效的衰减机制。
建议六:Persona 一致性优先于”显示记忆能力”
不要为了”显得记得多”而频繁地说”对了,您上次说过……”。陪伴关系靠的是自然的连贯,不是炫耀式的回忆。如果一次回应中过度引用历史,会让老人产生”被监视”感,破坏情感安全。让记忆默默地塑造”语气、节奏、关切的方向”,而不是变成台词。
结语:两种 AI,两条记忆的路
回到最开始的问题。Claude Code 为什么不用 RAG?因为它面对的是一个精确、结构化、时刻变化、不需要”语义模糊匹配”的世界——代码。它选择了 agentic search + 分层文件系统记忆,因为这个组合最大化地利用了模型自身的能力,最少地依赖工程上的预处理。
小暖能不能照搬?结构上能,底层不能。
结构上,“分层 + 显式 + 模型自管 + Markdown 母语”这四个原则,是 Anthropic 在 2025 年用大量真实数据淬炼出来的工程智慧,跨场景成立。
底层上,老人的世界不是函数和变量,是回忆、情绪、关系、衰老、孤独。这意味着小暖必须额外引入:事实层的语义召回(向量记忆)、关系层的图谱推理、时序层的精确时间索引、情感层的轨迹追踪、安全层的医疗护栏、角色层的人格一致性。这六层是 Claude Code 完全不需要的,而对小暖每一层都是核心。
两类 AI 的根本差异,不在于工具的差异,而在于”被记住”对用户意味着什么。 对一个程序员,“被 Claude Code 记住”是工作效率的提升。对一个老人,“被小暖记住”是被看见、被在乎、被陪伴。
这不是同一件事。所以记忆系统也不该是同一件事。
但有一点,Claude Code 和小暖是完全相通的——好的记忆系统应该是隐形的。它不需要用户感知到它的存在,不需要用户学习如何”使用记忆”,不需要用户配合任何特定的输入格式。它只是默默地,让模型在每一次回应时,更像那个真正了解你的人。
这才是值得追求的方向。
💬展开评论 / Show comments