1843 字
9 分钟
- 次浏览
做长期记忆时,我把每条记录写成固定格式
读前导览

每条记忆先定好来源、能不能公开、可信度和出处,后面检索时才不会乱。

正文
1843 字
阅读
9 分钟
结构
10 节
来源线索

windows-bot-memory/record-schema

windows-bot-memory:memory-record.schema windows-bot-memory:memory-record-schema windows-bot-memory:architecture

给 AI 助手做长期记忆时,很容易先想检索:全文检索怎么做,向量库怎么选,召回结果怎么喂给模型。

但检索之前还有一件更基础的事:每条记忆到底该长什么样。

如果记录本身没有统一格式,后面的 FTS、向量检索、生命周期管理和安全过滤都会变得很脆。系统能搜到很多东西,却说不清它们来自哪里、是否可信、是否过期、能不能被公开复用。

所以本地记忆中心里我更愿意先写 memory-record 的 schema,再谈召回。

一段 text 不够长期用#

最简单的记忆格式是:

{ "text": "用户喜欢某类内容" }

这种格式适合 demo,不适合长期运行。

真实的本地助手会遇到很多来源:云端机器人、Windows 本地任务、项目索引、个人配置、整理后的每日笔记、维护摘要、公开仓库材料。它们的可信度、隐私级别和适用场景都不一样。

所以一条可用的记忆记录至少要能回答:

  • 来自哪个 source。
  • 属于哪个 namespace。
  • 是事实、偏好、规则、项目、任务,还是原始记录。
  • 适用 scope 是什么。
  • 隐私级别是什么。
  • 置信度是多少。
  • 证据在哪里。
  • 何时创建和更新。

这些字段不是为了表结构好看,主要是让召回时能先判断哪些内容该用、哪些内容该挡掉。

kind 决定怎么使用#

一条记忆的 kind 不能靠正文临时猜。

规则、偏好、项目、任务、人物和原始记录,应该在结构上区分开。因为它们被召回后使用方式完全不同。

例如:

  • rule 更像执行约束,应该稳定、谨慎、优先级高。
  • preference 是用户偏好,可以影响排序和表达,但不一定是硬规则。
  • project 适合做工作区路由。
  • task 需要关注状态和时效。
  • raw 只能作为弱证据,不该直接当长期结论。
  • boundary 用来提醒系统哪些事情不能跨域复用。

如果所有内容都只是 text,模型会在语义上看起来都能理解,但系统无法在执行层面区分“应该遵守”和“仅供参考”。

privacy 是召回前的第一道门#

长期记忆里必须有隐私字段。

我倾向于把隐私级别明确分成几类:public、routing、personal、private、sensitive。它们不是装饰字段,召回前就要用它们过滤。

公开写博客时,我只会使用 public 或已经抽象过的 routing 级信息。个人助手回答私聊问题时,可以使用 personal。private 和 sensitive 需要更强限制,甚至默认不进入普通召回。

隐私过滤最好发生在检索阶段;等文本已经进了上下文,再提醒模型小心,风险就高了。

trust 让系统知道该信谁#

同一句话来自不同来源,可信度不一样。

用户明确确认过的规则,和模型从一段聊天里推断出来的偏好,权重应该不同。外部导入的资料、本地推断的摘要、未经验证的候选,也不适合混成一个“事实池”。

所以记录里需要 trust:

user_confirmed
local_inferred
external_imported
model_inferred
untrusted

有了 trust,系统才能做更稳的召回排序。强信任记录优先,弱信任记录可以作为背景;冲突出现时,也能知道应该先看谁。

这对博客写作也有用。可公开草稿最好来自用户确认、公开仓库或整理摘要;未验证候选只适合当线索。

lifecycle 让记忆会老化#

长期记忆最怕“永远有效”。

项目路径会变,工具链会换,部署方式会过期,偏好也会变化。如果记录没有生命周期,系统就会越来越擅长召回旧答案。

所以记录格式里要有 lifecycle:

  • candidate:候选,还没稳定。
  • active:当前可用。
  • stale:可能过期。
  • archived:保留历史,不默认使用。
  • quarantined:有风险,需要隔离。
  • deleted:逻辑删除。

还可以记录 last_reviewed_at、expires_at、decay_score。这样维护脚本才能定期检查,而不是让旧记忆自然堆积。

记忆系统不能一直做加法,它也需要衰减、归档和隔离。

evidence 和 provenance 负责可解释#

模型召回时,我最想让系统回答的是:

你为什么想起这条?

如果记录只有 text,系统只能说“搜索命中了”。这不够。

记录里应该有 evidence 和 provenance。evidence 可以指向证据来源、路径、行号或 quote hash;provenance 则说明这条记录从哪个文件、快照或远端同步而来。

这让召回结果可解释,也让维护脚本能回头查证。发现某条记录错了,可以追到源头;发现某个来源不该进入索引,也可以重新构建。

没有出处的记忆,长期看会变成谣言。

relations 处理冲突和演进#

长期记忆不是静态表。

同一件事可能有别名,旧规则可能被新规则取代,两条记录可能互相冲突,一个项目可能和另一个项目共享部分流程。

所以记录格式里还需要 relations:

  • links:相关记录。
  • aliases:别名。
  • supersedes:取代了哪些旧记录。
  • conflicts:和哪些记录冲突。

这样检索结果不再是一堆散落记录,脚本也能知道它们之间谁替代了谁、谁和谁冲突。

尤其是 supersedes 和 conflicts,很适合处理工具链升级、配置迁移和项目范围变化。否则旧记录不会自动消失,只会和新记录一起挤在检索结果里。

schema 比口头提醒更可靠#

很多人会把这些规则写进给模型的说明里:

请注意隐私,不要混淆来源,不要使用过期记忆。

文字说明可以提醒模型,但字段过滤这类事更适合放在数据层和检索层处理。

schema -> index -> scoped retrieval -> model context

这个顺序比“先搜一堆文本,再提醒模型小心”可靠。

维护结果也要写回记录#

记录格式不是写完就结束。

维护脚本跑完以后,应该能更新状态、生成候选、发现冲突、标记 stale、补充 relation,甚至隔离风险记录。一次维护摘要里可以有索引数量、冲突候选、生命周期检查结果和测试结果,但这些结果最后要能反馈到记录层。

否则维护只是在写日志,系统本身没有变好。

我更喜欢把维护理解成一个回路:

records -> index -> search/use -> review -> lifecycle updates -> records

这个回路存在,记忆系统才不会只会越堆越大。

先把一条记忆写清楚#

长期记忆的第一步,我会先放在记录格式上。向量库和上下文组织都可以往后排。

记录里先写清来源、隐私、可信度、状态和出处,后面做检索、召回、写作过滤时才有东西可查。

模型助手不缺文本,缺的是每段文本能不能用、该怎么用、什么时候该停用。

先定记录格式,再做长期记忆。

做长期记忆时,我把每条记录写成固定格式
https://blog.sunmmyapi.xyz/posts/memory-record-contract-before-recall/
作者
Sun
发布于
2026-05-29
许可协议
CC BY-NC-SA 4.0

继续读

相关内容