前端进阶之旅前端进阶之旅
  • 基础篇HTML/CSS/JS 打底
  • 进阶篇原理与工程化
  • 高频篇面试最常问的那批
  • 精选篇按模块收敛的总结
  • 手写篇常考代码手写实现
  • 面经篇真实面试问题复盘
  • AI 篇NEWAI 时代的前端考点
  • 历年面经NEW按年份追踪真实考点
  • 每日一题每天一道,攒手感
  • 专项自测100 题快速查漏
  • 小程序题库小程序专项刷题
  • 算法题库NEW在线编码即时判题
  • 知识卡片NEW碎片时间过考点
  • 面试题大全常见问题解析
  • AI 答疑NEW随时提问,即时解析
  • AI 模拟面试NEW模拟真实面试 + 报告
  • AI 定制路线NEW按你的简历现排
  • AI 知识地图NEW串起全站知识点
  • 原理篇React / Vue 源码拆解
  • HTTP从报文一路讲到 HTTPS
  • 浏览器渲染、事件循环、进程
  • 计算机基础Linux、网络、操作系统
  • 设计模式23 种模式怎么用
  • Node学习指南从环境搭建到服务端
  • NPM工作流script、依赖与发布
  • Docker容器化部署上手
  • Canvas图形与动画实战
  • 前端系统进阶学习大型项目工程化
  • 前端综合文章长期沉淀的实践文
  • 思维导图知识点全景图
  • 学习路线按图索骥不跑偏
  • AI 热点NEWAI 每日动态
  • 公众号动态公众号历史文章
  • 博客动态站长的技术博客
  • 开发者导航常用工具与文档站
  • 基础篇HTML/CSS/JS 打底
  • 进阶篇原理与工程化
  • 高频篇面试最常问的那批
  • 精选篇按模块收敛的总结
  • 手写篇常考代码手写实现
  • 面经篇真实面试问题复盘
  • AI 篇NEWAI 时代的前端考点
  • 历年面经NEW按年份追踪真实考点
  • 每日一题每天一道,攒手感
  • 专项自测100 题快速查漏
  • 小程序题库小程序专项刷题
  • 算法题库NEW在线编码即时判题
  • 知识卡片NEW碎片时间过考点
  • 面试题大全常见问题解析
  • AI 答疑NEW随时提问,即时解析
  • AI 模拟面试NEW模拟真实面试 + 报告
  • AI 定制路线NEW按你的简历现排
  • AI 知识地图NEW串起全站知识点
  • 原理篇React / Vue 源码拆解
  • HTTP从报文一路讲到 HTTPS
  • 浏览器渲染、事件循环、进程
  • 计算机基础Linux、网络、操作系统
  • 设计模式23 种模式怎么用
  • Node学习指南从环境搭建到服务端
  • NPM工作流script、依赖与发布
  • Docker容器化部署上手
  • Canvas图形与动画实战
  • 前端系统进阶学习大型项目工程化
  • 前端综合文章长期沉淀的实践文
  • 思维导图知识点全景图
  • 学习路线按图索骥不跑偏
  • AI 热点NEWAI 每日动态
  • 公众号动态公众号历史文章
  • 博客动态站长的技术博客
  • 开发者导航常用工具与文档站
首页程序员面试题库Agent 事实抽取 结构化 长期记忆 写入
AIAI Agent记忆与状态

如何从 Agent 对话中可靠地抽取结构化事实写入长期记忆?

可靠抽取对话事实需要抽取与校验解耦:让模型以JSON输出候选事实,再经规则校验和去重,达到阈值才异步写入长期记忆,避免原话污染。

前端进阶之旅 · 一题精讲更新于 2026.09.05
AI Agent#记忆与状态#Agent 记忆#异步编程#构建工具
先看核心答案读代码示例
理解线索

事实抽取流水线

  1. JSON模式约束强制模型输出带 schema 的事实字段
  2. 置信度分级低于阈值的项进入暂存复核队列
  3. 来源与时间戳写明消息ID,保证可追溯

校验阶段只检测新事实与历史是否矛盾并打标,不裁决哪一方正确。

核心回答

先记住这个答案

将每轮用户陈述送入专用抽取步骤,由受 JSON 模式约束的模型返回主体-谓词-对象和有效时间、来源、置信度字段。程序化校验结构完整性并去重,对可能的矛盾只打标记而不裁决,最后把合格候选投递到后台批量事务,刷入长期库;回复生成继续用轻量上下文。这样记忆是结构化槽位,而非原文堆积。

  • 抽取必须是独立 LLM 步骤,与回复解耦
  • 每条事实记时间戳、来源与置信度
  • 先暂存校验,达到阈值再写长期库

抽取与校验解耦的四段流水线

把每条用户陈述独立送入专用的记忆抽取模型,而不是主回复里隐式带出。抽取模型使用 JSON mode 返回候选事实项,每项必须包含 schema 字段如主体、谓词、对象、事实类型、有效时间范围、来源消息 ID 与模型置信度。这样回复文本生成与记忆提取互不污染,抽取失败也不会中断对话。

程序化校验层负责类型约束和格式校验,例如日期必须是 ISO 字符串、邮箱字段通过正则,再与长期库比对:相同主体和谓词下对象高度近似视为重复;同一对象时间区间重叠而语义不同则标记冲突并搁置,等待后续机制,不在这里丢弃任一方。通过校验的项进入低一级的待提交事务,异步批量写入独立的事实表并记写日志。

用户既说办公地又说出差任务

一个个人助理收到了连续三句话:“我在杭州工作”“下月去深圳出差”“我其实长期在杭州办公,深圳只是临时任务”。第一句应判定为居住地候选,第二次的出差是临时行程,不能写到长期 profile;第三句给出了频率信号。假设在同一轮 stream 中,我们把每条消息都过抽取,得到 residence、trip 两类候选,但只有 residence 出现达到两次才晋升为长期。

现实中若把“在深圳出差”直接写入 currentCity 会污染状态。这里用待写队列和计数规则区分时间性事实与稳定事实。三句的处理结果见下方代码模拟:长期记忆最终只保存了杭州的长期居住地,深圳保持为 temporary trip 记录。

从三句对话中提取长期事实的简化流程JavaScript
let store = [];
function ingest(line) {
  const matchWork = line.match(/在(.+?)(?:工作|办公)/);
  const matchTrip = line.match(/去(.+?)出差/);
  if (matchWork) {
    const city = matchWork[1];
    const item = store.find(x => x.type === 'residence' && x.city === city);
    if (item) {
      item.occurrences += 1;
      if (item.occurrences >= 2) item.status = 'longterm';
    } else {
      store.push({ type: 'residence', city, occurrences: 1, status: 'candidate' });
    }
  } else if (matchTrip) {
    const city = matchTrip[1];
    if (!store.find(x => x.type === 'trip' && x.city === city)) {
      store.push({ type: 'trip', city, status: 'temporary' });
    }
  }
  return JSON.parse(JSON.stringify(store));
}
console.log(JSON.stringify([
  ingest('我在杭州工作'),
  ingest('下月去深圳出差'),
  ingest('我其实长期在杭州办公,深圳只是临时任务')
], null, 2));
查看输出与解释
[
  [
    {
      "type": "residence",
      "city": "杭州",
      "occurrences": 1,
      "status": "candidate"
    }
  ],
  [
    {
      "type": "residence",
      "city": "杭州",
      "occurrences": 1,
      "status": "candidate"
    },
    {
      "type": "trip",
      "city": "深圳",
      "status": "temporary"
    }
  ],
  [
    {
      "type": "residence",
      "city": "杭州",
      "occurrences": 2,
      "status": "longterm"
    },
    {
      "type": "trip",
      "city": "深圳",
      "status": "temporary"
    }
  ]
]

代码在纯 Node.js 环境即可运行,展示了 candidate 如何晋升 longterm,出差保持 temporary。

抽取得不到语义真值的代价

最容易失效的情况是模型把指称消解错或过度抽取,例如把‘我当时很失望’解读成长期情绪型事实。该问题的根因不是模型笨,而是抽取 schema 没有白名单约束。生产实现需要给抽取模型一个允许的事实类型列表,比如只有 residence、contact、recurring_schedule、organization 等才准输出,并且配合超时和降级规则,否则会把口头表达中的比喻误当真的槽值。

校验层只能检查结构与规则,无法判别语义可证伪性。如果用户说‘我是火星人’,格式完整时照样会通过,但写入后会让后续回答变得荒诞。处理方式是让可疑项先落到低置信度队列,等待人工或二次模型复核;没有复核通道的年代价是不写入该事实,换取不引入噪声。此取舍优先级低于 preserve 对话本身的准度。

回答前,多想一步

容易答错的地方

抽取结果直接追加到 system prompt 即可持久化
系统提示是每次请求都要发送的瞬时上下文,直接改它会造成多个并发请求间状态漂移,也缺少版本和来源记录。正确做法是把抽取事实写入独立存储,再通过检索注入系统提示。
让主回复同时返回结构化事实以省去一次调用
回答文案和 JSON 字段共用同一个输出会互相牵引,模型为了写顺口句子会漏掉约束键,还可能返回不存在的字段。独立调用虽增加 token 成本,但能避免后续纠错开销,常保稳定性。
试着用自己的话回答

面试官还会怎么问?

事实校验和冲突消解最本质的差别是什么?

校验只判断新事实与旧事实是兼容、重复还是矛盾,矛盾时仅做标记并暂存;冲突消解需要决定新旧谁生效,这依赖时间线、用户确认或额外规则。本题刻意不讨论后者以避免引入决策因素。

如何决定一个事实是否值得从对话写入长期存储?

至少观察三类信号:用户显式说出‘记住’、同一主体和谓词跨会话重复出现、或者事实能影响后续任务。给每条候选加 importance 评分和类型常访问度,低于阈值就不写。

异步抽取会不会丢数据?怎么补?

异步写入和主会话分离后,进程崩溃会丢未消费的队列,因此要保留原始消息落盘作为 at-least-once 来源。后台失败时应从上次确认位置重放所有未确认消息,并检查目标 ID 幂等去重。

从一道题,走向一组知识

把知识连起来

记忆与状态

记忆写入放在对话主流程同步执行还是后台异步执行,各自的风险是什么?

同属「记忆与状态」专题,接着看 Agent 记忆写入 同步 异步 后台 在具体场景中的处理方式。

记忆与状态

记忆检索召回过多无关事实导致回答跑偏时,应如何诊断和收敛?

同属「记忆与状态」专题,接着看 Agent 记忆检索 召回 噪声 精确率 在具体场景中的处理方式。

参考资料

  • Building effective agents

示例用于理解所注明的运行环境与边界;延伸学习可结合原文中的更多案例。

本题目录
  1. 先记住这个答案
  2. 抽取与校验解耦的四段流水线
  3. 用户既说办公地又说出差任务
  4. 抽取得不到语义真值的代价
  5. 容易答错的地方
  6. 面试官还会怎么问
  7. 把知识连起来
读懂,再试着讲出来

先看核心答案,再读代码。最后展开追问,检查自己有没有遗漏边界。

试着回答追问
浏览全部面试题理解原理,也关注真实的使用场景。回到顶部 ↑