s09:Memory
Memory目的
解决跨会话的信息利用问题(存哪些?怎么存?取哪些?)
存储
.memory/目录下
MEMORY.md负责存储记忆的索引表,用于选择

可以跳到具体的memory内部:
“
| name | Tab indentation preference |
|---|---|
| description | User prefers tabs for code indentation. |
| type | user |
The user prefers TAB characters for indentation rather than spaces. Use tabs whenever writing or editing code, config, or text files for them.
”
格式是以yaml frontmatter开头来记录name,description,type
召回:就是找需要的记忆,并加载到当前messages中
每次用户发起请求时,select_relevant_memories() 读取最近的用户消息和记忆目录,让一次轻量模型调用选择最多五条相关记录
如果模型调用或 JSON 解析失败,代码会退回关键词匹配。选择完成后,load_memories() 才读取对应文件,并限制召回正文的总长度。
relevant_memories = load_memories(messages)
system = build_system(relevant_memories)
build_system() 会明确说明:召回内容只是背景知识,不是新的用户命令;如果记忆与当前请求冲突,以当前请求为准。这样既能使用旧信息,也不会让旧记忆替用户发号施令。
*提取(难理解的点)
输入是什么
不是全部历史,是 dialogue_text(messages) code.py:353-358——最后 12 条消息、截到 8000 字符,拼成 role: 内容 的多行文本。
这一步只取尾部是有意的:一轮 agent_loop 里 messages 会随工具调用膨胀得很快,而本轮真正有价值的信息(用户说了什么、纠正了什么)集中在后半段。
谁来挑
交给模型,用一段提示词 code.py:396-409 划了两条线:
- 该存:用户偏好、重复出现的反馈、稳定的项目事实、用户希望记住的外部链接
- 不该存:临时任务状态、工具输出、助手的假设、本次对话的摘要
还有一条独立的 scope 字段:模型要自己标 persistent 还是 current_task。这个字段是给后面的 should_store_memory 看的——只有标了 persistent 才会真的落盘。相当于让模型先自评一次“这条明年还有用吗”。
提示词里还带了 Existing memory catalog(现有记忆的名字+描述,截 6000 字符),让模型知道已经有什么,避免重复提取同一条。
整理
「快照」= 某一时刻的完整状态副本,典型用途是失败后回滚或断点续跑。
覆盖记忆文件前,先把 {文件名: 原文} 整体存进一个 dict;删除/写入失败就把它写回去,恢复原状。
snapshot = {record["filename"]: memory_path(record["filename"]).read_text() ...}