程云来 / 杭州
返回文章·Agent 与 Harness
·约 6 分钟

思想|Memory,新会话为什么还记得你的习惯?

把稳定偏好从对话中单独保存,新会话只带回相关记忆;区分记忆、历史、当前要求与执行证据。


程序还是那个程序,为什么又要教一次怎么报告?

上次检查 main.py 时,用户补充了一句:“记住,以后这个项目用中文报告,先给核对结论,再列是否执行、退出码和证据。”Agent 当场照做了。今天新开一个会话,再让它检查同一份程序,这个习惯还在吗?

第八课的快照能查到当时说过什么,但新会话不会自动把所有旧快照重新发送。摘要也围绕当时的任务组织,未必保住一句看似次要的格式偏好。即使找回“之前核对一致”,也不能证明今天这份程序还是那个结果。

我们需要留下的,是以后仍适用的偏好,以及它的来源。Memory(记忆)把这类内容从一次对话里单独保存;新任务到来时,再由 Harness 判断哪些内容与当前问题有关,放进这次模型请求。

先挑出来:什么值得留到下一次?

同一次检查会出现几种很像“应该保存”的内容,作用却不同:

内容应放在哪里
本项目报告先给结论,再列执行证据经确认的项目记忆
先读预期,再取得运行许可可复用操作规范,仍由 Skills 提供
这次已经读了文件,还没有运行当前计划与会话记录
这次输出42,退出码0本次工具结果和执行记录
用户上次允许运行那一次许可的记录,不能批准今天的运行

Skills 已规定核对步骤和报告应有的字段;记忆留下的是这个用户喜欢“先结论、后证据”的呈现习惯。新会话仍可重新加载同一份操作规范,同时带回相关偏好。

记忆不是另一个“所有东西都放进去”的 messages。报告偏好可以跨会话使用,实际输出却要重新取得;许可更要由本次执行入口判断。把后两者保存成一句“以后都按成功处理”,会让旧信息越过它原来的适用范围。

本课从用户明确要求记住的偏好开始,宿主审核后再保存。结构校验能检查名称、正文长度和来源字段,不能判断一句话是否准确、是否过时、是否值得长期保存。这个选择不能只靠“写文件没有报错”来证明。

文件留下了,为什么不全部交给模型?

设想项目记忆里有两条:一条讲检查程序后的报告格式,一条讲 SQL 的书写习惯。今天只核对 Python 输出,把 SQL 偏好也发送过去,只会让这次请求多出一项无关要求。

所以需要两层内容:目录让宿主知道存了什么,正文只在相关时进入请求。本课的目录包含名称、描述和关键词;Harness 用当前问题匹配关键词,得到少量名称,再附带这些名称对应的正文。没有匹配就返回空列表,不为展示“记得很多”而硬选一条。

PREFERENCE / SOURCEPREFERENCE / SOURCEMEMORY.JSONCURRENT SESSIONCURRENT QUESTIONFRESH HISTORYHOST PERMISSIONREQUEST COPYCURRENT QUESTIONRELATED MEMORYTOOL HISTORY用户的稳定偏好项目记忆文件新会话与当前问题本次模型请求
这句话值得带到以后

用户要求记住项目报告格式:先给核对结论,再列是否执行、退出码与证据。它是稳定偏好,没有保存本次程序的运行结果。

候选:中文报告,先结论、后证据。
  1. 这句话值得带到以后:用户要求记住项目报告格式:先给核对结论,再列是否执行、退出码与证据。它是稳定偏好,没有保存本次程序的运行结果。
  2. 确认后写入项目记忆文件:宿主审核候选和来源,临时写完后替换正式JSON。保存成功只代表下次还能读到,运行许可仍须单独判断。
  3. 新会话从文件重新建立目录:旧对话和计划已经不在内存。宿主重新读项目JSON,派生名称、描述和关键词目录;正文此时还没有全部放进模型请求。
  4. 按这次问题选择相关名称:新问题要求核对程序并按项目习惯报告。关键词命中report-format;SQL偏好没有命中,不附带。
  5. 相关正文附到本次请求副本:当前问题放在最前,选中记忆带来源并标为参考;完整工具交接仍保留。下次请求重新生成副本,不在旧附件后面继续追加。
  6. 报告偏好回来了,证据仍要新取得:父模型仍须读取当前预期、提出运行请求、经过宿主许可,再依据本次结果报告。旧记忆没有替它完成这些动作。

这张图推演一次保存和一次新会话。切换“本次换格式”,旧报告偏好仍在文件里,但用户这次明确说只用一句话,临时要求不应被旧偏好覆盖,也不会因此自动改写长期记忆。

新会话带回的,究竟是哪一部分?

旧对话不必重新出现。新会话可以重新读记忆文件,拿到“报告先给结论,再列执行证据”这段正文,再从当前问题开始工作。下面只用序列化文本观察两份状态的独立性;正式实践会用文件和另一次 Python 进程验证:

PyPython · 浏览器本地运行
未运行
import json

old_history = ["检查main.py", "用户补充报告习惯"]
saved_text = json.dumps({
    "report-format": "先给核对结论,再列执行证据。"
}, ensure_ascii=False)
del old_history

new_history = []
memories = json.loads(saved_text)
print("新会话有旧历史:", bool(new_history))
print("重新带回的偏好:", memories["report-format"])
输出

点击行号设置断点,再点“调试”;也可以直接运行。

代码只读;执行发生在浏览器中,不会发送到博客服务器。

输出是“新会话有旧历史:False”,但仍能读到报告偏好。它说明历史和单独保存的记录可以各自存在;这段短代码没有恢复旧调用位置,也没有运行 main.py。

真正发送请求时,Harness 把相关记忆附到本次请求副本,原始活跃历史继续保存当前问题与工具交接。下次请求再从活跃历史生成副本,避免同一段记忆越附越多。即使第八课刚整理过历史,宿主仍能从独立持有的记忆重新附带正文。

本课用一个很小的 JSON 文件同时保存元数据和正文,启动时在宿主里整份读取,再生成目录。这里按需控制的是哪些正文进入模型请求,没有声称磁盘上只读了目录。规模变大以后,才需要考虑把正文分文件、检索和读取分别安排。

偏好回来了,本次检查仍然要从证据开始

新请求带上了报告习惯,父流程仍要读取当前 expected.txt、调查 main.py、请求运行并经过宿主许可。只有本次进程返回以后,才能核对完整输出。记忆里的“上次输出42”不能替它补齐这一步。

同样,记忆正文即使写着“以后不用再问”,也只是请求里的文字;本册第三课的许可入口依然独立判断。宿主拒绝时,程序就不启动。图里的记忆箭头只通向本次请求,没有绕过执行入口。

正文还可能与当前要求冲突。报告偏好提供默认做法,用户这次的明确要求优先;这是一条需要模型理解的请求约定,不是结构校验器能保证的行为。实践用固定响应展示格式变化,另用真实进程标记证明运行许可没有被记忆绕过。

记错了,先改哪一份?

如果用户更正长期偏好,可以审核新候选,用相同名称替换旧记录。换一个名称追加,反而可能让两条互相冲突的偏好同时被选中。当前会话里的临时要求则不自动写回,避免把一次例外当成以后的规则。

保存本身也会失败。本课先写同目录临时文件,再替换正式文件;替换失败时,旧文件保留。加载发现文件损坏就报错,不把它当成“没有记忆”然后覆盖。文件写成功与内容正确,是两件必须分别验证的事。

实践篇展开保存、相关选择、请求附带三个函数。可以停在正式文件替换之前,也可以让一个选择名称不存在,观察为什么不能把半份记忆交给下一步。

资料核对于2026-10-19:课程 Memory提供持久记录、目录与相关加载的学习路线;Claude Code 官方记忆说明区分项目指令与自动记忆,并指出文字上下文不等于强制执行配置。本课的单一 JSON、人工确认和关键词匹配是独立教学设计,没有复现官方自动记忆或其内部实现。