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