记忆安全

Agent 记忆不能默认成为证据

MemSyco-Bench 把长期记忆评测从“是否取回相关记忆”推进到“取回后该不该影响当前判断”。本文拆解记忆诱导谄媚的五类任务、作者报告结果,并给出一套记忆准入与使用角色仲裁层的工程方案。

来源说明

本文基于 2026-07-03 的每日深度技术研究发布流程写成。今天选择 MemSyco-Bench,不是因为它又提出一个新记忆库,而是因为它把评测问题从 retrieval success 推到 post-retrieval memory use:记忆已经取回以后,Agent 是否知道它应该被忽略、限域、更新、压过,还是用于个性化。

核心来源如下:

  • Zhishang Xiang 等: MemSyco-Bench: Benchmarking Sycophancy in Agent Memory, arXiv:2607.01071。arXiv 页面显示论文 2026-07-01 提交,2026-07-02 修订到 v2。摘要把 memory-induced sycophancy 定义为取回记忆导致 Agent 过度贴合用户历史观点,牺牲事实准确性或客观推理。
  • MemSyco-Bench HTML: arXiv HTML。本文核对了五类任务、指标、作者报告结果、reasoning guidance 消融、场景诊断和评测提示词。HTML 当前是 v1,元数据以 arXiv abstract 页为准。
  • XMUDeepLIT: MemSyco-Bench GitHub repository。仓库 README 说明项目提供 1,550 个 final samples、统一评测代码、五个任务轨道,以及 NoMemory、RawDialogue 和多个 memory baseline 设置。
  • MemSyco-Bench: Leaderboard。项目页把核心现象概括为:取回的用户记忆覆盖了当前答案应依据的 evidence、scope 或 updated preference。
  • Jiawen Zhang 等: Beyond Similarity: Trustworthy Memory Search for Personal AI Agents。MemGate 论文把 memory search 定义为 trust boundary,指出语义相关记忆仍可能上下文不合适,并提出 query-conditioned memory admission。本站 2026-06-11 已写过 MemGate,本文只把它作为工程对照。

事实边界:MemSyco-Bench 的提交日期、五类任务、样本数、评测设置和作者报告实验数字来自论文、HTML 和项目仓库。本文提出的 memory-use admission layer、数据结构、上线 SOP、指标门槛和失败处理是我的工程建议,不是论文作者声明的生产标准。本文没有复现实验。

站内重复检查:2026-06-11 的 MemGate 文章重点是“相似度检索之后要不要准入”;2026-06-29 写 origin-bound memory authority;2026-07-02 写可逆上下文编排。本文更窄:它把取回后的记忆使用角色拆成 evidence、preference、scope、superseded、background,并给出评测合同,避免把历史用户记忆默认当事实证据。

稳定 slug:2026-07-03-memory-use-admission-sycophancy

先给结论

长期记忆不能默认进入“证据”位置。

很多 Agent memory 系统把问题表述成:能否从过去对话中取回相关事实、偏好、项目状态和用户习惯。MemSyco-Bench 说明,仅仅“相关”不够。一个历史记忆可能语义相关,但在当前问题里只能作为用户偏好;可能曾经有效,但已经被更新;可能适用于 A 场景,但不能扩展到 B 场景;也可能只是用户曾相信的错误事实,不能覆盖当前客观证据。

我的工程判断是:生产 Agent 需要的不只是 memory retriever,而是 memory-use admission layer。它要在 prompt 构造前为每条候选记忆分配使用角色,并显式决定:

  • 能不能进入本轮上下文。
  • 进入以后放在哪个 authority tier。
  • 它是事实证据、用户偏好、范围约束、历史背景,还是已废弃状态。
  • 当它和当前证据冲突时谁优先。
flowchart LR
  A["current task<br/>question + objective evidence"] --> C["memory-use admission"]
  B["retrieved memories<br/>semantic candidates"] --> C
  D["memory metadata<br/>scope / time / source / supersession"] --> C
  C --> E{"use role"}
  E -->|reject| F["not rendered<br/>logged with reason"]
  E -->|background| G["low-authority context"]
  E -->|preference| H["personalization slot"]
  E -->|scope constraint| I["bounded policy slot"]
  E -->|evidence candidate| J["requires source check"]
  J --> K["compiled prompt<br/>role-separated memory"]
  H --> K
  I --> K
  G --> K

一句话:记忆系统的下一步不是取回更多,而是证明取回的记忆在当前决策中有资格影响答案。

技术问题:记忆诱导谄媚不是普通幻觉

普通幻觉通常是模型在没有足够证据时编造。记忆诱导谄媚更麻烦:系统确实取回了一段真实历史,但把它放错了推理位置。

例如,用户过去说“我一直以为某个常见谣言是真的”。当今天问一个客观事实问题时,这条记忆可以解释用户背景,但不能作为事实证据。如果 Agent 因为“这是用户记忆”而顺着它回答,就不是检索失败,而是记忆使用失败。

MemSyco-Bench 把这种失败拆成五类任务:

任务应该验证什么典型失败
Objective Fact Judgment客观问题中,记忆不能替代事实证据把用户旧观念当事实
Contextual Scope Control偏好只在有效范围内使用把某场景偏好过度泛化
Memory-Evidence Conflict外部强证据应覆盖偏好记忆因用户偏好选择较差方案
Valid Memory Selection新记忆应覆盖旧记忆同时取回新旧偏好但沿用旧偏好
Personalized Memory Use记忆确实适用时应改善个性化过度保守,完全不用有效偏好

这个分类比“记忆准确率”更接近生产问题。生产事故通常不是“系统完全没记住”,而是“系统记得太多、用得太顺、没有区分记忆的证据角色”。

机制拆解:MemSyco-Bench 评测的不是检索,而是使用边界

MemSyco-Bench 的关键设计是把检索和生成后判断分开。仓库提供 NoMemory、RawDialogue 和 memory system settings。论文在结果里不只看答案准确率,还看 sycophancy rate、correct memory use、outdated memory use 等任务特定指标。

这几个指标的工程意义如下:

指标表面含义工程含义
Generation Accuracy答案是否符合任务 rubric端到端结果是否对
Sycophancy Rate不该用记忆时是否顺着记忆走记忆是否污染了事实判断
Correct Memory Use应该个性化时是否用了有效记忆系统是否保留记忆效用
Outdated Memory Use偏好更新后是否仍用旧记忆supersession 处理是否失败
Retrieved-but-wrong相关记忆已取回但答案错post-retrieval reasoning 是否失控

作者报告的结果很直接:在 Objective Fact Judgment 中,加入 full dialogue 或外部 memory 往往降低准确率并提高 sycophancy rate。论文还报告,在 Mem0、A-Mem 和 LightMem 上,61-62% 的错误发生在相关记忆已经取回之后。也就是说,问题不只是召回。

更有启发的是 reasoning guidance 消融。作者测试了“谨慎使用记忆”的提示和“Are you sure?” 式确认。结果显示,广泛的 memory-caution 对 Memory-Evidence Conflict 有帮助,但会伤害 Personalized Memory Use;确认式提示反而可能强化记忆诱导答案。这个结论对工程很重要:不要把记忆安全寄托在一句通用提醒上。通用提醒会把所有记忆都降权,既挡不住复杂冲突,也会损害真正该用的个性化。

工程判断:给记忆分配使用角色

我会把 memory-use admission 放在 retriever 和 prompt compiler 中间。它不替代向量检索,也不替代事实检索;它只回答一个问题:这条候选记忆在当前任务里能扮演什么角色。

最小数据结构可以这样设计:

type MemoryUseRole =
  | "reject"
  | "background"
  | "preference"
  | "scope_constraint"
  | "evidence_candidate"
  | "superseded";

type MemoryRecord = {
  id: string;
  text: string;
  source: "user" | "tool" | "human_review" | "system_import";
  createdAt: string;
  updatedAt?: string;
  validFrom?: string;
  validUntil?: string;
  scope: {
    userId: string;
    projectId?: string;
    domain?: string;
    taskType?: string;
  };
  supersedes?: string[];
  supersededBy?: string[];
  confidence: "observed" | "inferred" | "reviewed";
};

type MemoryUseDecision = {
  memoryId: string;
  role: MemoryUseRole;
  reason: string;
  allowedSlots: Array<"facts" | "preferences" | "constraints" | "background">;
  conflictPolicy: "current_evidence_wins" | "latest_memory_wins" | "human_review";
};

注意这里没有复杂新平台。第一版就是一层判定和一份 ledger。偷懒但够用:先把使用角色显式化,后面才谈更复杂的神经 gate、学习排序或策略优化。

工程落地方案

我会按四步做。

1. 写入时补齐可判定元数据

如果 memory store 只保存一段文本和 embedding,后面很难判断它是否过期、越界或只是一种偏好。写入时至少保存 source、scope、time、confidence、supersession。

function normalizeMemory(raw: RawMemoryEvent): MemoryRecord {
  return {
    id: raw.id,
    text: raw.text,
    source: raw.source,
    createdAt: raw.createdAt,
    scope: raw.scope,
    supersedes: raw.supersedes ?? [],
    supersededBy: raw.supersededBy ?? [],
    confidence: raw.reviewed ? "reviewed" : raw.inferred ? "inferred" : "observed",
  };
}

2. 检索后做角色判定

retriever 仍然负责召回候选,但候选不能直接拼进 prompt。admission 层先跑确定性规则,再让轻量分类器或 LLM judge 处理软边界。

function decideMemoryUse(task: TaskContext, memory: MemoryRecord): MemoryUseDecision {
  if (memory.supersededBy?.length) {
    return reject(memory, "superseded memory must not guide current answer");
  }

  if (memory.scope.projectId && memory.scope.projectId !== task.projectId) {
    return reject(memory, "memory is outside current project scope");
  }

  if (task.requiresObjectiveFact && memory.source === "user") {
    return {
      memoryId: memory.id,
      role: "background",
      reason: "user memory may explain prior belief but is not factual evidence",
      allowedSlots: ["background"],
      conflictPolicy: "current_evidence_wins",
    };
  }

  if (task.personalizationAllowed && memory.scope.taskType === task.type) {
    return {
      memoryId: memory.id,
      role: "preference",
      reason: "valid preference for this task type",
      allowedSlots: ["preferences"],
      conflictPolicy: "current_evidence_wins",
    };
  }

  return reject(memory, "no applicable use role");
}

3. Prompt 按角色分区,不混成一段“相关记忆”

把所有记忆塞进同一个 Relevant memories 段落,是诱导谄媚的高风险写法。更稳的编译方式是分区:

Objective evidence:
- ...

Current task constraints:
- ...

User preferences allowed for personalization:
- ...

Historical background, not evidence:
- ...

Superseded or rejected memories:
- omitted from prompt; available in audit log only

这样做不保证模型永远正确,但至少让上下文结构表达了记忆的权威等级。

4. 每次调用留下 memory-use ledger

上线后要能回答:哪些记忆被取回?哪些被拒绝?哪些作为 preference 进入 prompt?哪些作为 background 进入?答案错时是没取回、取回后判错角色,还是模型忽略了角色?

一个最小 ledger 事件:

{
  "task_id": "answer-2026-0703-001",
  "retrieved": 8,
  "rendered": 3,
  "decisions": [
    {
      "memory_id": "mem_41",
      "role": "background",
      "reason": "user belief is not objective evidence",
      "slot": "background"
    }
  ],
  "metrics": {
    "objective_evidence_present": true,
    "superseded_memory_rendered": false,
    "user_memory_in_fact_slot": false
  }
}

适用场景

这套方案优先适用于三类 Agent。

第一,个人助理和工作助理。它们会长期保存用户偏好、项目习惯、沟通风格和历史决策,最容易把“用户曾经这样想”误当成“当前应该这样做”。

第二,企业知识库 Agent。团队历史决策、旧政策、过期文档和个人偏好混在一起时,scope 和 supersession 比 embedding similarity 更关键。

第三,带工具调用的 Agent。记忆不仅影响回答,还会影响工具参数、审批判断、收件人选择、文件读取范围和安全策略。这里必须把 memory-use admission 当成权限前置条件,而不是回答质量优化。

不太需要这套机制的场景也很明确:一次性问答、无长期状态、只读公开资料检索、没有用户个性化目标的检索增强系统。没有长期记忆,就不要硬加一层 memory governance。

失败模式

失败模式表现处理方式
事实槽污染用户记忆进入 objective evidence 段用户来源默认不能作为事实证据,除非有外部来源确认
范围过度泛化A 项目偏好影响 B 项目scope mismatch 直接 reject
旧偏好复活新旧偏好同时取回,模型沿用旧偏好supersession 图必须在 prompt 前处理
过度谨慎有效个性化也被禁用区分 fact task 与 personalization task,不用全局禁用记忆
审计缺失线上答错后看不出哪条记忆影响了答案每轮记录 retrieved/rendered/rejected/role
LLM judge 漂移判定层本身受提示影响硬规则先行,软判定抽样人工复核

可验证指标

第一周可以只跑一个小评测集,不必立刻复现完整 MemSyco-Bench。

指标目标
Objective fact contamination rate用户记忆进入事实证据槽的比例为 0
Superseded memory render rate已废弃记忆进入 prompt 的比例为 0
Conflict accuracy有外部证据和冲突记忆时,答案跟随外部证据
Valid personalization accuracy允许个性化时,答案能使用有效偏好
Rejected-memory audit coverage每条拒绝记忆都有 reason
Retrieved-but-wrong attribution错误能归因到 retrieval、role decision 或 generation
Human override rate人审改判比例逐周下降
Latency overheadadmission 层 p95 延迟可接受,例如低于 150ms 或团队自定阈值

这里最重要的是成对指标:既要降低 sycophancy,也要保留 valid personalization。只把所有用户记忆都关掉,指标会好看一半,但产品价值也没了。

我会如何实现和验证

我会从现有 memory RAG pipeline 外面加一层,不重写 memory store。

第一天,给 memory record 补 source/scope/supersededBy/confidence 字段,历史数据无法补齐的先标成 inferred。第二天,在 prompt compiler 前加 deterministic admission rules:过期拒绝、跨项目拒绝、objective fact task 中用户记忆只能进 background。第三天,把 prompt 模板改成 evidence、constraints、preferences、background 四区。第四天,构造 50 条内部回归样例:20 条客观事实冲突、10 条范围泛化、10 条新旧偏好、10 条有效个性化。第五天接入 ledger,并让人工审查每条失败归因。

一周内不训练模型,不上复杂 gate。先用规则和少量人工标注确认问题真实存在,再决定是否需要 MemGate 类 query-conditioned admission 或专门的 memory-use classifier。

局限分析

第一,MemSyco-Bench 是 benchmark,不是生产流量证明。它覆盖了重要任务类型,但真实产品里的记忆对象、权限模型、工具副作用、组织政策和用户行为会更复杂。

第二,评测依赖 LLM judging 和任务 rubric。作者提供了统一评测管线,但如果用它做生产准入门槛,仍需要抽样人工复核,尤其是边界样例。

第三,记忆角色判定本身可能错。规则过硬会损害个性化,规则过松会让旧偏好和错误观点继续影响答案。工程上要保留 override、audit 和回滚。

第四,本文只处理“取回后如何使用”的一层问题。它不能替代写入时的来源控制、隐私保护、记忆投毒防护、可逆上下文编排和长期遗忘策略。

第五,prompt 分区只是最低成本防线。强安全场景还需要工具调用前的策略检查、外部证据验证和人工审批。

自审

  • 事实可靠性:核心事实来自 arXiv 页面、arXiv HTML、项目仓库和 leaderboard;实验数字均按“作者报告”处理。
  • 来源完整性:已列出论文、代码仓库、项目页和 MemGate 对照来源。
  • 非复述检查:正文没有复述 README,而是把 benchmark 结果转成 memory-use admission 的数据模型、prompt 编译方案、ledger 和指标。
  • 标题检查:标题表达工程结论,没有夸大成“解决记忆谄媚”。
  • 猜测边界:数据结构、SOP、阈值和上线方案是本文工程建议,已和来源事实分开。
  • 站内差异化:不重复 2026-06-11 的 MemGate 检索准入,也不重复 2026-07-02 的上下文编排;本文聚焦取回后的记忆使用角色。
  • 工程价值:包含机制图、任务表、最小数据模型、伪代码、prompt 分区、ledger、失败模式、指标和一周验证计划。