前端进阶之旅前端进阶之旅
基础篇
进阶篇
高频篇
精选篇
手写篇
面经篇
AI 篇
原理篇
每日一题
小程序题库
知识卡片
  • 场景篇按分类整理的大前端场景考点
  • 历年面经按年份追踪真实考点
  • 算法题库NEW在线编码即时判题
  • 专项自测100 题快速查漏
  • 前端基础
    • HTTP从报文一路讲到 HTTPS
    • 浏览器渲染、事件循环、进程
    • 计算机基础Linux、网络、操作系统
  • 进阶专项
    • 设计模式23 种模式怎么用
    • 前端系统进阶学习大型项目工程化
    • 前端综合文章长期沉淀的实践文
  • 工程与工具
    • Node学习指南从环境搭建到服务端
    • NPM工作流script、依赖与发布
    • Docker容器化部署上手
    • Canvas图形与动画实战
  • 路线与导图
    • 思维导图知识点全景图
    • 学习路线按图索骥不跑偏
  • 动态
    • 公众号动态公众号历史文章
    • 博客动态站长的技术博客
    • 开发者导航常用工具与文档站
  • AI 助手随时提问,即时解析
  • AI 模拟面试模拟真实面试 + 报告
  • AI 知识地图串起全站知识点
  • AI 定制路线按你的简历现排
AI 热点
旧版
基础篇
进阶篇
高频篇
精选篇
手写篇
面经篇
AI 篇
原理篇
每日一题
小程序题库
知识卡片
  • 场景篇按分类整理的大前端场景考点
  • 历年面经按年份追踪真实考点
  • 算法题库NEW在线编码即时判题
  • 专项自测100 题快速查漏
  • 前端基础
    • HTTP从报文一路讲到 HTTPS
    • 浏览器渲染、事件循环、进程
    • 计算机基础Linux、网络、操作系统
  • 进阶专项
    • 设计模式23 种模式怎么用
    • 前端系统进阶学习大型项目工程化
    • 前端综合文章长期沉淀的实践文
  • 工程与工具
    • Node学习指南从环境搭建到服务端
    • NPM工作流script、依赖与发布
    • Docker容器化部署上手
    • Canvas图形与动画实战
  • 路线与导图
    • 思维导图知识点全景图
    • 学习路线按图索骥不跑偏
  • 动态
    • 公众号动态公众号历史文章
    • 博客动态站长的技术博客
    • 开发者导航常用工具与文档站
  • AI 助手随时提问,即时解析
  • AI 模拟面试模拟真实面试 + 报告
  • AI 知识地图串起全站知识点
  • AI 定制路线按你的简历现排
AI 热点
旧版
返回 AI 情报前线
All News · 全部资讯9301
  • GPT-5.6明知必胜却主动认输:LLM推理的隐蔽缺陷
  • 多 Agent 系统架构:生产环境的陷阱与现实
  • 神经符号引擎实战:医疗理赔自动化方案
  • AI 的致命弱点:不知道自己何时出错
  • 企业 AI 瓶颈不是模型,而是遗留架构
  • 15 万次 CI 失败日志审计揭示的真相
  • 坏Prompt正在浪费你的免费模型调用:先做PromptLint
  • AI 生成配置变更的 Receipt-First 安全预检法
  • 如何检测恶意MCP服务器:对比烟雾测试实战
  • PixelRAG:让 Claude Code 直接理解和检索带表格/图表的文档
  • 微小视觉扰动可击溃多模态 Agent 的未来预测
  • AI 编程沙盒的双重计费陷阱
  • Qwen3.8-27B 本地运行指南:17GB 指的是总内存
  • 生产 RAG 中嵌入模型漂移的隐藏风险
  • 数据库开发者为什么需要了解 MCP
  • RAG 评估实战:如何摆脱「感觉还行」的主观判断
  • 79% 的企业员工绕过 AI 治理政策
  • AI 找 bug ≠ 证明 bug 存在
  • 混合搜索实战:关键词+语义+Rerank 提升文档问答精度
  • Agent 记忆问题的本质是检索问题
  • AI Agent 数据删除管道设计实战
  • 票务分类 API 设计:语音转写与多模型摘要的最优组合
  • AI 在独立项目中自主修复跨域 iframe DOM 查询缺陷
  • 基于实时美股深度数据构建订单簿失衡信号
  • Claude 系统提示词两年增长 9 倍:生产 AI 产品团队该学什么
  • 开源工具 whodunit:用 Git/DevLake 数据量化团队 AI 采用效果
  • AI Agent 开发常见反模式:业务逻辑不应委托给 LLM
  • 构建混合搜索实战:关键词+向量+重排序完整管道
  • 多 Agent 系统调试:为什么「跑通了」不等于「对了」
  • Agentic AI与RAG根本不是一回事
  • OpenAI Codex向ChatGPT用户开放百万Token上下文
  • 代码库本身就是提示词:给AI参照已有实现比空想更有效
  • DeepTutor:港大数据科学实验室3层记忆Agent-native学习工作区
  • 用CI自动化比对Prompt变更,避免模型输出悄然退化
  • DeepSeek Harness开源自进化Agent框架,4天获12.6万星
  • 用事件总线架构拆解长链路Agent,避免单点故障蔓延
  • LLM性别偏见藏在prompt写法而非提问者身份
  • 20分钟重塑AI工作流:五步框架释放LLM潜力
  • 184个AI API成本实测:企业与初创公司差异分析
  • ChatGPT macOS隐私检查清单:Computer History安全配置
  • 美团AI变革复盘:全员养虾翻车与CatPaw落地方法论
  • Unsloth桌面版发布:单GPU运行7440亿参数模型,支持本地编码Agent
  • 同一终端双信任级别:Claude Code对接廉价代理节省API成本
  • Cursor推出自有代码托管服务
  • 测试时训练:模型边推理边学习新权重
  • Cursor Origin 仓库现已支持 Vercel 自动化部署
  • GPT-5.6 Sol在AI Gateway五折优惠一个月
  • Replit企业版大规模管控:Admin API与50+事件审计日志上线
  • macOS 屏幕共享漏洞正遭活跃利用,可远程获取 Root 权限
  • Linux 7.2 稳定版发布:I/O 性能优化、AMD/Intel 显卡驱动改进
  • 2026年8月AI基础设施与推理平台定价对比:18款工具每日更新
  • 已加载 51 / 9301
8.0
热点
AI SCORE
技术实践2026-08-17 11:36

AI Agent 数据删除管道设计实战

dev.to · AI#AI安全#数据合规#Agent
Editor brief · 编辑速览

用户一次操作可能产生散落在 prompts、traces、向量库、工具日志等十余处数据,需设计完整的删除管道才能真正满足合规与信任要求。

文章思维导图
Knowledge map
拖拽缩放
Full translation

完整中文译文

删除按钮容易做,真正的删除难得多。

这个差距在 AI Agent 中比普通应用更重要,因为一次用户操作就能将数据分散到提示词、调用链路、记忆存储、向量索引、工具日志、临时文件、模型网关、重试队列和埋点事件中。如果你的产品只删除了可见的聊天记录,用户可能已从 UI 中消失,但他们的数据仍残留在五个后端系统中。

对于 AI 应用开发者来说,这不只是合规任务,而是信任功能。用户会更快原谅回答慢,但无法原谅一个声称"已删除"但保留了足够上下文可在之后重建对话的系统。

本指南展示如何设计一个 AI Agent 数据删除管道,真正移除用户数据、证明发生了什么,同时避免在执行过程中破坏生产工作流。

为什么 AI 删除与众不同

传统删除通常从已知记录开始:用户、项目、文件、消息或数据库中的一行。AI Agent 创造了一个更混乱的形态。

一次 Agent 执行可能包括:

  • 提示词和回复
  • 检索到的文档片段
  • 工具调用参数和结果
  • 向量嵌入
  • 记忆事实和摘要
  • Chain-of-thought 风格的内部注释(不应存储)
  • 工件和屏幕截图
  • 调用元数据(延迟、token 计数、模型名称)

其中一些记录对用户可见,许多则不是。

这就是为什么"删除聊天"不够。Agent 删除需要一张地图,列出用户数据可能落到的每个位置,加上一个工作流,根据每个位置的风险和法律保留规则删除、涂黑或立墓碑。

失败模式:UI 删除而未删除后端

危险模式是这样的:

用户点击删除。

应用从侧边栏移除对话。

后端保留调用链路、嵌入、提示词和工具日志用于调试。

恢复指针、支持导出、分析查询或向量搜索仍能揭示旧内容。

从产品团队角度看,项目没了。从用户角度看,删除承诺已兑现。从系统角度看,只是隐藏了。

AI 使这更糟,因为删除的内容可能间接重现:

  • 记忆摘要保留了重要事实
  • 嵌入仍能检索到旧文档
  • 网关中缓存的提示词仍在
  • 支持工单包含工具参数
  • Agent 工件包含复制的文本
  • 微调数据集意外包含了这次执行

真正的删除意味着移除数据路径,而不只是 UI 路径。

从删除清单开始

在编写删除代码之前,列出每个存储层。将这个清单保存在代码库中,而不是某人的脑子里。

一个有用的清单表如下:

存储层 内容类型 数据示例 删除动作
主数据库 消息、文件、元数据 对话、用户、项目 硬删除或墓碑
向量存储 嵌入 conversation chunks 按 lineage_id 删除
对象存储 上传文件、工件 PDF、截图 删除对象
工具调用日志 结构化事件 API 调用、参数 移除内容,保留元数据
记忆存储 事实、摘要 用户偏好、总结 重新计算或删除
提示词缓存 渲染后的提示词 系统提示词 + context 使缓存失效
消息队列 待处理任务 计划任务、重试 取消并清除
分析事件 埋点数据 页面浏览、点击 匿名化或聚合

关键列是"删除动作"。不是每条记录都用相同方式处理。

例如,账单可能需要保留"发生了 12 次模型调用"这样的非内容记录。但不应保留原始提示词。可观测性可以保留延迟、token 计数、模型名称和错误码,同时丢弃消息文本和工具载荷。

为每个 Agent 执行使用数据血缘 ID

当系统找不到相关记录时,删除就会失败。修复方法简单但常被跳过:给每个用户拥有的数据对象一个血缘 ID。

血缘 ID 将根对象连接到所有派生对象。

type DataLineage = {
  tenantId: string;
  userId: string;
  subjectType: "conversation" | "file" | "agent_run" | "memory";
  subjectId: string;
  lineageId: string;
};

每个派生记录都应携带该血缘 ID:

type AgentTraceEvent = {
  traceId: string;
  lineageId: string;
  tenantId: string;
  runId: string;
  step: "retrieve" | "model_call" | "tool_call" | "approval";
  payloadRef?: string;
  redactionState: "raw" | "redacted" | "deleted";
  createdAt: string;
};

不要只依赖指向可见聊天的外键。AI 系统经常在主应用数据库外创建记录。向量存储、对象存储桶和模型网关可能不知道你的对话 schema。但它们可以知道血缘 ID。

将内容删除与审计保留分开

一个常见错误是把删除当作全有或全无。这会产生两种糟糕结果:

  • 团队保留太多,因为他们需要审计历史
  • 团队删除太多,失去了解释滥用、账单或事件的能力

相反,将记录拆分为内容和元数据。

内容包括提示词、回复、检索到的片段、上传的文本、截图、工具参数和记忆事实。

元数据包括时间戳、角色 ID、token 计数、模型名称、状态码、成本总计、审批状态、删除收据 ID 和策略决策。

当删除请求到达时,内容应被移除或不可逆地涂黑。如果需要安全、账单、法律或运营原因,最小化元数据可以保留。

删除安全的示例事件:

{
  "event_id": "evt_93",
  "lineage_id": "lin_abc",
  "tenant_id": "tenant_7",
  "run_id": "run_42",
  "event_type": "model_call",
  "content_state": "deleted",
  "model": "primary-chat-model",
  "input_tokens": 1840,
  "output_tokens": 420,
  "created_at": "2026-08-17T03:32:00Z",
  "deleted_at": "2026-08-17T03:41:00Z",
  "deletion_receipt_id": "del_771"
}

注意缺失的内容:没有提示词、没有回复、没有检索片段、没有工具结果。

将删除构建为工作流,而不是按钮处理器

删除请求应创建一个持久化的删除作业。不要试图在一个 HTTP 请求内删除所有内容。

使用如下工作流:

  1. 在 pending 状态下创建删除收据
  2. 冻结或取消该 lineage ID 的活跃 Agent 执行
  3. 跨系统发现相关记录
  4. 在每个系统中删除或涂黑内容
  5. 验证每个删除目标
  6. 将收据标记为 completed、partial 或 failed
  7. 向用户公开安全的删除状态

一个简单的收据 schema:

create table deletion_receipts (
  id text primary key,
  tenant_id text not null,
  requested_by text not null,
  subject_type text not null,
  subject_id text not null,
  lineage_id text not null,
  status text not null,
  targets jsonb not null,
  created_at timestamptz not null default now(),
  completed_at timestamptz
);

每个目标应跟踪自己的状态:

{
  "target": "vector_store",
  "action": "delete_by_lineage_id",
  "status": "completed",
  "records_matched": 18,
  "records_remaining": 0
}

这为开发者和支持团队提供了一种安全的方式来回答"用户删除时发生了什么?"而不再次暴露已删除的数据。

删除前取消活跃执行

AI Agent 通常是长时间运行的。删除请求可能在 Agent 仍在使用即将被删除的上下文时到达。

删除开始时:

  • 阻止该 subject 的新执行
  • 取消使用该 lineage ID 的排队作业
  • 撤销活跃工作器的租约
  • 停止计划的后续任务
  • 使审批链接失效
  • 清除待处理的工具调用
  • 阻止记忆写入完成

如果跳过这一步,工作器可能在删除作业完成后重新创建已删除的数据。

一个简单的运行时检查:

async function assertLineageIsActive(lineageId: string) {
  const deletion = await db.deletionReceipts.findActive(lineageId);
  if (deletion) {
    throw new Error(`Lineage ${lineageId} is under deletion`);
  }
}

在检索、模型调用、记忆写入和工具执行前调用此函数。

按源删除向量数据,而不是按相似性

不要通过运行相似性搜索用户文本来删除嵌入。那样做慢、不完整且有风险。

每个向量片段应包含元数据:

{
  "chunk_id": "chunk_22",
  "tenant_id": "tenant_7",
  "source_type": "conversation",
  "source_id": "conv_99",
  "lineage_id": "lin_abc",
  "created_by_run_id": "run_42"
}

然后删除是确定性的:

await vectorStore.delete({
  tenantId,
  filter: { lineage_id: lineageId }
});

删除后,对该 lineage ID 运行元数据查找。结果应该为零。不要问模型数据是否消失。问存储系统。

重新计算记忆而不是盲目修补

Agent 记忆很棘手,因为它通常存储摘要而不是精确的源文本。

如果记忆摘要来自十个对话,其中一个被删除,你可能不知道哪句话来自哪个源,除非你跟踪了溯源。

  • 存储带源 lineage ID 的记忆事实
  • 只删除来自已删除 lineage 的事实
  • 从剩余源重新计算混合摘要
  • 在重新计算期间将旧摘要标记为过时
type MemoryFact = {
  factId: string;
  tenantId: string;
  userId: string;
  text: string;
  sourceLineageIds: string[];
  state: "active" | "stale" | "deleted";
};

如果 sourceLineageIds 包含已删除数据和活跃数据,不要保持旧句子不变。从活跃源重建它或删除它。

这就是许多 AI 系统泄露已删除数据的地方:原始聊天没了,但"用户偏好季度营收图表"这条记忆还在,因为它被复制到了个人资料摘要中。

谨慎对待模型提供商的保留

你的删除管道可以控制你的系统,但可能无法删除模型提供商内部的每个临时副本。

这意味着需要在删除请求发生前建立清晰的数据路由规则:

  • 避免将敏感内容发送给训练输入的提供商
  • 尽可能使用零保留或企业控制
  • 如果提供商提供,保留请求 ID 用于提供商侧删除支持
  • 避免在网关日志中存储完整提示词
  • 记录保留了什么、在哪里、保留多久

不要承诺超出架构所能提供的。如果提供商为滥用监控日志保留了固定窗口,请在内部策略和用户条款中说明。

当删除承诺精确时,信任就会提升。

在 CI 中添加删除测试

删除应该像支付或认证一样被测试。

创建一个带有已知标记文本的合成用户:

DELETE_TEST_MARKER_7f3a9b

运行一个正常的 Agent 工作流:

  • 发送一条带有标记的提示词
  • 创建一个检索片段

然后触发删除,并断言标记从每个内容层消失。

  • 关系数据库内容列
  • 向量元数据和片段
  • 导出的调试包

一个粗糙但有效的测试:

const surfaces = await collectDebugSurfaces({ tenantId, marker });
for (const surface of surfaces) {
  if (surface.content?.includes(marker)) {
    throw new Error(`Deletion marker found in ${surface.name}`);
  }
}

这个测试会捕获以后会变成严重问题的无聊泄露。

给用户删除状态而不暴露内部信息

用户不需要看到你的向量存储目标列表。他们需要一个真实的状态。

  • 已从活跃系统中删除
  • 仅在安全或账单需要时保留
  • 删除失败;支持团队已收到通知
  • 后台作业完成前的"已删除"
  • 提供商保留仍适用的"永久删除"
  • 内部仍可搜索的"已从您的账户移除"

对于开发者工具,管理删除收据可以显示目标类别而不暴露已删除内容。

实用推广计划

从最高风险的存储层开始。

阶段 1:停止明显的假删除

  • 删除可见消息
  • 按源 ID 清除向量片段
  • 移除上传的文件
  • 涂黑调用链路载荷

阶段 2:到处添加 lineage

  • 在执行、工具调用、记忆、缓存键、工件和嵌入中添加 lineage_id
  • 尽可能回填近期记录
  • 阻止缺少 lineage 的新存储写入

阶段 3:添加收据和验证

  • 创建删除收据
  • 存储删除元数据
  • 添加支持安全的状态

阶段 4:添加自动化测试

  • 基于标记的删除测试
  • 记忆重新计算测试
  • 向量删除测试
  • 队列取消测试
  • 提供商保留检查

这个顺序在构建完整删除系统的同时提升信任。

FAQ

什么是 AI Agent 数据删除管道?

AI Agent 数据删除管道是一个后端工作流,跨提示词、调用链路、嵌入、记忆、缓存、文件、工具日志、队列和埋点删除或涂黑用户数据。它比删除可见的聊天记录更完整。

只删除对话够吗?

通常不够。对话可能创建了派生记录,如向量片段、记忆摘要、调用链路载荷、工具结果、提示词缓存和工件。这些需要单独的删除或涂黑步骤。

AI 日志应该硬删除吗?

内容重的日志通常应该快速删除、涂黑或过期。当需要账单、滥用预防、安全或法律原因时,可以保留最小的运营元数据。将内容与元数据分离,这样你不会意外保留原始提示词。

如何安全删除嵌入?

为每个向量片段存储源元数据,如 tenant_id、source_id 和 lineage_id。按元数据过滤器删除,然后验证该 lineage ID 没有剩余片段。不要依赖相似性搜索来删除。

删除期间 Agent 正在运行会发生什么?

删除工作流应该取消排队的工作、撤销活跃工作器租约、阻止新工具调用,并阻止该 lineage ID 的记忆写入。否则,Agent 可能在删除作业完成后重新创建数据。

如果使用第三方模型 API,能承诺永久删除吗?

只有当提供商合同和保留设置支持该承诺时。许多团队应该使用更精确的措辞:从活跃产品系统中删除,在适用的有限提供商或安全保留范围内。

应该添加的第一个删除测试是什么?

创建一个带有唯一标记的合成提示词,让 Agent 完成一个正常工作流,删除它,然后在每个内容层搜索该标记。如果标记出现在任何存储用户内容的地方,管道就不完整。

AI 删除不是设置页功能,而是数据架构功能。

如果 Agent 可以读取、转换、记忆、检索和操作用户数据,那么删除必须遵循相同的路径。目标很简单:当用户要求移除他们的数据时,你的系统应该知道它去了哪里,阻止它被重用,删除可以删除的,涂黑必须保留的,并产生一个你可以信任的收据。

Original source

本文由 AI 翻译整理自 dev.to · AI,原文版权归原作者所有。

阅读英文原文
上一篇
Agent 记忆问题的本质是检索问题
下一篇
票务分类 API 设计:语音转写与多模型摘要的最优组合