大多数团队在做 AI agent 前,删除会话这件事都还不算复杂。删一条聊天记录,或者把某个工单状态置为归档,差不多就结束了。问题是,一旦 session 成了长任务的骨架,它就不再只是几段对话,而是会牵出一整串东西:中间产物、工具结果、审计快照、缓存、嵌入向量、人工 review 意见、外发记录,甚至恢复任务时必须依赖的 checkpoint。
于是“用户要求删除一段会话”就会突然变成一个很尴尬的系统问题。删轻了,数据还在别处继续被召回;删重了,恢复能力和审计能力一起没了;只给用户一个 JSON 导出,又会发现真正决定行为的 evidence 和 policy 记录根本不在导出包里。
这类事情最容易在客户真正问起来时才暴露出来。因为在内部 demo 阶段,团队通常只会关心 agent 能不能跑,不会先追问“半年后客户要导出这次 run 的证据链怎么办”。可一旦进入企业交付,这个问题迟早会变成信任问题,而不是纯技术问题。
建议配合 AI agent Session Store 设计、AI agent 上下文预算分配、AI agent 数据脱敏实践 和 AI agent Run Ledger 审计模型 一起看。
先分清:删的是哪一层,不是哪一行
| 数据层 | 典型内容 | 删除目标 | 导出目标 |
|---|---|---|---|
| Session Transcript | 对话、指令、用户输入 | 满足用户删除请求 | 给用户还原会话过程 |
| Durable Memory | 提炼后的长期记忆、偏好、事实 | 防止未来继续被召回 | 让客户知道系统留了什么长期信息 |
| Artifact / Evidence | 草稿、截图、diff、引用证据 | 降低泄露面和存储成本 | 支持复盘与审计 |
| Audit / Ledger | 谁在什么规则下触发了什么动作 | 通常不能像聊天记录一样直接抹掉 | 向企业解释行为责任链 |
| Cache / Embedding | 检索缓存、向量索引、临时派生数据 | 防止“看似删除、实际还能被找回” | 一般不直接交付用户,但必须纳入删除范围 |
如果系统没有这张分层表,删除和导出最终只会变成两种粗糙动作:要么“删数据库行”,要么“把所有东西都打包给客户”。这两种做法都不够好。
Retention 不是时间参数,而是目的管理
更成熟的 retention 设计不会先问“留 30 天还是 90 天”,而是先问这份数据为什么存在。因为不同目的,允许的保留方式完全不同:
- 为恢复任务而保留的 checkpoint,重点是恢复窗口和一致性
- 为安全审计而保留的 ledger,重点是不可抵赖和最小暴露
- 为用户体验而保留的 memory,重点是召回价值与撤回能力
- 为成本和速度而保留的 cache,重点是过期和彻底清除
这意味着 session retention policy 至少要有两个维度:
- 保留理由:resume、audit、analytics、personalization、cache
- 删除语义:hard delete、soft tombstone、delayed purge、redacted retain
很多团队的问题恰恰在于,他们只有“存”与“删”两个动作。结果一旦同时遇到用户删除诉求和企业审计诉求,系统就不知道该听谁的。
Customer Export 不该只导出聊天文本
用户真正要的“导出”通常不是字面上的 transcript,而是一次可以理解的任务记录。尤其在 AI agent 场景下,客户往往更关心:
- agent 看了哪些输入
- 产生了哪些关键中间结果
- 哪个步骤触发了人工 review
- 最终依据哪些证据得出了结论或做出了动作
所以好的 export bundle 不是一个扁平文本,而更像一个“可解释运行包”。它至少应该把下面几部分区分开:
- 原始会话与用户输入
- 重要的 evidence 引用
- 关键决策点与状态转换
- 已确认输出与被拒绝输出
- 删除说明,例如哪些派生缓存不会直接出现在导出包里,但会跟随删除策略处理
导出做得好的系统,客户拿到包后会觉得自己真的看到了这次运行;做得差的系统,客户只会收到一份孤零零的 transcript,然后继续追问:“可它为什么会这样做?”
删除流程最怕的,不是慢,而是“表面删除”
删除流程真正该避免的是假象。表面上 UI 显示“已删除”,实际向量索引、缓存摘要和 session-derived memory 还在别处活着,几周后又被同租户另一次任务召回。这种事故一旦发生,用户不会在意你删的是哪张表,他们只会觉得系统说了谎。
所以 delete flow 至少要经过四步:
- 打 tombstone:明确该 session 已进入删除流程,阻止继续被调度和继续写入。
- 传播删除事件:通知 memory、embedding、cache、artifact、analytics pipeline 这些下游系统。
- 延迟 purge:给审计和失败恢复留一个短窗口,但窗口期间必须保证不可继续召回。
- 完成证明:留下最小必要的 deletion receipt,证明这次删除请求被哪个流程处理过。
这个 deletion receipt 很重要。因为企业客户最终要问的不是“你们有没有 delete API”,而是“谁能证明这次删除真的发生过”。
一个很常见的翻车点:Transcript 删了,Embedding 还在
某团队给客户做了“删除会话”按钮,前端体验很好,几秒内就提示成功。两周后,客户再次跑相近任务,agent 又引用了之前已经删除的项目背景。排查后发现:
- transcript 表已删除
- session artifact 目录已清空
- 向量索引中的 derived chunks 还在
- memory summarizer 早先写入的长期记忆没有回收
也就是说,系统删掉了最显眼的一层,却保留了最会继续影响行为的一层。
最后团队不是去补一条“再删 embedding”的脚本,而是重构了 delete semantics:所有 session-derived object 必须带 sourceSessionId 和 deletionPropagationState,任何不能证明来源的派生数据都不允许进入生产索引。这个改动看起来麻烦,但它让删除第一次从“表层动作”变成了“全链路约束”。
真正让客户安心的,不是“全删干净”,而是边界说清楚
删除与导出最难的部分,不在技术实现,而在边界表达。你需要坦白告诉客户:
- 哪些数据会用于恢复和审计,因此不会和聊天文本用同一种删除方式
- 哪些派生数据会被级联删除
- 哪些记录会以 redacted 方式留作系统责任证明
- 客户导出包能看到什么,不能看到什么,以及为什么
这类表达越清楚,系统越像一个可信的服务,而不是一个只会在 UI 上给出“已处理”的黑盒。
如果你现在要先补一层,最值得先做的不是导出下载按钮,而是把 session、memory、artifact、cache、audit 这五层的 retention reason 画清楚。只有先把“为什么留下”讲明白,后面的“删到什么程度”才不会永远摇摆。
延伸阅读:


