Skip to content
预计 1 分钟右侧目录可快速定位

一条 Memory 还能不能信:Provenance、Freshness、Conflict 与 Isolation ​

前置:什么值得长期记住:Long-Term Memory 的写入与检索
核心问题:两条 Memory 相互冲突或已经过期时,系统凭什么判断哪条还能信,并保证不同用户/项目的记忆不会串线?

旧 Memory 记录“服务端口是 8080”,新文档显示已经改成 9000;同时另一个 tenant 也有同名服务。系统不仅要检索到记忆,还必须判断 freshness、source、scope 和冲突处理。

Mental Model ​

text
Evidence / Observation
       ↓
MemoryRecord
├─ content
├─ provenance
├─ namespace / tenant scope
├─ valid_from / valid_until
├─ confidence
└─ status / supersedes
       ↓
Conflict Resolution
       ↓
Authorized Active View
       ↓
Retrieval → Context

一条 Memory 不能只有 text + embedding。生产系统还必须记录它的可信边界。这里有三个相互独立的问题:Provenance 回答它从哪里来;Freshness/Conflict 回答现在是否仍成立;Isolation 回答谁有权看见它。 任何一个维度缺失,retrieval 命中都不能直接等价为“可以相信并注入模型”。

Memory Provenance ​

一条 Memory 至少要能追到:

text
source type      用户 / tool / repo / run outcome / imported knowledge
source id        message_id / tool_call_id / commit / document
observed at      什么时候观察到
written by       哪个 policy/agent 生成
scope            user/project/workspace/agent
confidence       系统对它的信任等级

Freshness 与 Conflict ​

同一个 canonical fact 可能先后出现两个值;旧值曾经正确,但已经过时:

text
2026-01: deployment region = us-east-1
2026-08: deployment region = us-west-2

Memory Isolation ​

常见 scope:

text
user
organization
project
workspace
agent-role
conversation

检索查询必须在 storage/query 边界显式携带授权 scope,而不是先做全局向量搜索,再在应用层“希望过滤正确”。

最小实现 / 数据结构 ​

最小记录结构可以是:

python
@dataclass
class MemoryRecord:
    memory_id: str
    namespace: tuple[str, ...]
    canonical_key: str | None
    content: str
    provenance: MemoryProvenance
    valid_from: datetime
    valid_until: datetime | None
    last_verified_at: datetime | None
    supersedes: str | None
    status: Literal["active", "superseded", "deleted"]

默认 retrieval view 只暴露满足这些条件的记录:

text
status = active
scope authorized
not expired

在 Shadow Harness 中怎么落地 ​

MemoryStore.search() 的输入要显式携带授权 scope,不能只传一段 query string。Conflict resolution 可以先实现简单 deterministic policy:同 canonical key 下,明确的新权威 evidence supersede 旧记录;跨 scope 的事实不视为冲突。

Failure Modes ​

Memory 没有 source_ref ​

症状: MemoryRecord 只有 text/embedding,没有来源、run、观察时间或 producer。

为什么危险: 错误记忆出现后无法回证据验证,也无法撤销某个失效 source 派生的记录。

处理: 保存 provenance:source_type/source_ref/run_id/observed_at/producer/confidence。

新旧事实同时 active ​

症状: 同一 canonical fact 的旧值和新值同时参与 retrieval。

为什么危险: stale 事实可能仍高相似,导致相同问题在不同运行中命中不同版本。

处理: 建模 valid_from/valid_until/last_verified/supersedes/status,用规则先解决版本冲突。

namespace 只存在 prompt 中 ​

症状: Prompt 说“不要读取其他租户”,但底层 search 实际查询全局索引。

为什么危险: 模型遵守文字不是访问控制;prompt injection 或 tool bug 会泄漏跨 tenant 数据。

处理: identity 进入 storage namespace、query filter、cache key 和 authorization policy,由程序强制。

把 confidence 当 freshness ​

症状: 历史上来源可靠的旧记录因 confidence 高而永远排在新事实前。

为什么危险: 可信度和时效性正交;旧事实可能曾经完全正确但今天已失效。

处理: 分别建模 confidence 与 freshness/validity,current authoritative evidence 优先于旧 Memory。

如何验证 ​

Case断言
Memory 没有 source_ref撤销 source 后能精确定位并失效其派生 Memory。
新旧事实同时 active写入新版本后反复检索,旧记录不得以 active 状态注入。
namespace 只存在 prompt 中两个 tenant 写入高相似数据,模型调用前 candidate set 已严格隔离。
把 confidence 当 freshness高 confidence 旧值与新权威 Tool evidence 同时存在时,新事实胜出并触发更新。

源码对照(B 类) ​

turn-memory.ts / sand-memory.ts 可用于观察 memory evidence、episode 和 extraction 的不同路径;provenance/conflict policy 仍由本文定义。 - 源码导航:Grok Bot Source Map

自测 ​

  1. 两条 Memory 对同一事实冲突,一条来自用户明确输入,一条来自模型推断。Provenance 应怎样影响可信度?
  2. 多租户系统如果 Memory key 没包含 tenant/user boundary,最严重的错误是什么?

Sources ​

AI Engineering · Agent · Harness · Backend Systems