OROpenRealtime
角色资源文档
对话记录

还没有对话记录

OROpenRealtime
角色资源文档
对话记录

还没有对话记录

知识库 Demo、Memory 与续聊

知识、工具与记忆 · 正文语言: 中文

文档目录
全部文档开发与扩展产品功能架构与可替换模块开发与扩展系统架构与消息流程开发与扩展文档与发布边界认识产品与开始使用认识 OpenRealtime知识、工具与记忆用产品资料配置语音助手认识产品与开始使用首页使用指南定制语音 Agent角色配置指南知识、工具与记忆知识库使用指南知识、工具与记忆记忆与会话历史知识、工具与记忆工具权限设置知识、工具与记忆知识与记忆管理指南定制语音 Agent成本与服务选型可选:添加数字人数字人驱动方案可选:添加数字人动作编排使用指南部署与维护本地启动与排错定制语音 Agent连接真实语音与模型服务部署与维护自行部署指南部署与维护前后端分离部署部署与维护可靠性与运维开发与扩展模块化话轮协调器开发与扩展判停与打断插件合约开发与扩展语音 Pipeline 与插件接口开发与扩展知识库选型与接入方案接入你的 Agent接入自己的 Chat Agent

截至 2026-09-30,项目已具备知识检索、规则提取的长期记忆、当前会话上下文投影和断线恢复基础。历史记录页支持继续带有运行时标识的新记录;缺少标识的旧记录仍只供查看。跨服务重启续聊需要持久化 Journal。下面先用一个售后助手例子验证使用方式,再说明实际实现和缺口。

在页面里体验售后助手

1. 创建并绑定知识

打开知识库资源页,先选择准备体验的角色,填写名称「星河商店售后说明 v1」,粘贴以下正文并创建资料:

星河商店的退货期限为签收后 7 天。
退货条件:商品未使用、包装完整,并提供订单号。
客服服务时间为工作日 09:00—18:00。
退货运费规则:商品质量问题由商店承担,其他情况由买家承担。

仓库也提供同样主题的 docs/demos/shop-knowledge.md 文件,可以直接选它导入。勾选资料,测试「退货期限」与「退货运费规则」,展开结果核对原文。

新资料会自动加入所选角色。进入角色列表,打开同一角色,在「知识库」中确认这份资料已选中。完整导入和更新方式见知识库使用指南。

2. 添加一条长期记忆

在角色配置中启用「长期记忆」,再到记忆管理选择同一角色。添加一条「偏好」记忆:「我喜欢简洁回答」。

先手动添加可以确认记忆读取链路。自动保存则可另行测试:从这个角色开始对话,说「我的目标是学会日语」,等待对话记录保存后,重新打开 Memory 页面检查是否出现「目标」记录。页面不会自动刷新其他页面刚写入的记忆。

若列表未出现记录,请先查看对话记录是否保存了这句话,确认该条用户消息是最终文本、角色记忆已开启,且使用同一账号与角色。自动提取失败不会让对话保存失败,也没有独立的页面失败提示。

3. 验证多轮上下文与记忆

从配置好的角色开始会话,依次问:

提问要验证的内容
「请查知识库,星河商店的退货期限是多少?」回答依据「签收后 7 天」
「我是因为商品质量问题退货。」接着问「那运费谁承担?」前文的质量问题与当前知识片段结合,回答商店承担
「退款多久到账?」资料缺少答案时明确说明,不猜时间
「我之前说过的学习目标是什么?」在新会话中验证保存的目标记忆是否可读

前两轮测试当前会话上下文;最后一问测试跨会话的长期记忆。模型回答会有变化,要结合原文、Memory 列表和实际工具调用判断,不能仅凭一次回答看起来正确就认定链路完整。

4. 测试关闭和删除记忆

关闭该角色的长期记忆后,后续提示词不再注入这些记录,自动提取也停止。关闭不会删除已保存记录,需要在 Memory 页面单独删除或清空。

验证关闭是否生效时,使用一个新会话,避免模型仍从当前会话的前文读到同样内容。删除或过期清理网页对话时,会清理对应来源自动记忆;手工编辑后已解除来源关联的记忆保留。删除弹窗另可选择擦除关联运行时对话,并安排录音清理;运行时不可用、归属验证失败或录音受保护时保留网页记录供重试。录音物理删除可能延迟,备份与外部供应商数据需独立处理。

按对话清理来源记忆会在移除内容前写入 Memory 删除回执和来源标记。使用最新删除快照重放时,仅恢复 Memory 模块也会排除这些已删记录,并拒绝从同一角色的旧来源重新提取;手工编辑后解除来源关联的记录保留。写回执失败时保留原 Memory 文件供重试。旧备份本体不因恢复而被修改,仍需执行独立的备份保留策略。

删除来源记忆后,同一条已保存的最终转写即使迟到修订,也不会通过普通历史保存重新提取该来源记忆。新的明确发言和手工添加仍可创建记忆;未删除事实的正常 ASR 更正仍会更新原条目。这个保护不撤回模型已接收的当前会话上下文。

手工编辑有来源的记忆时,也会屏蔽该角色旧来源的历史重提取,避免补全旧对话后再次出现编辑前的版本。新明确发言的正常修订仍可更新对应记忆;生日、当前居住城市这些已有稳定字段的事实,不会被较旧最终转写覆盖较新发言或手工编辑。

无模型凭据也能运行的代码 Demo

在项目根目录执行:

.venv/bin/python -m demos.knowledge_memory_demo

Demo 使用临时目录和真实项目组件,运行结束自动清理,输出 JSON。它执行知识库工具检索、Memory 文件读取以及预算化上下文投影,展示传给模型的数据;无需启动网页、麦克风或调用付费模型。

验证结果包含:未绑定不命中、绑定后命中、用户隔离、新 Session 读取保存的 Memory、关闭后停止注入、同一 thread 读取前文,以及新 thread 不自动继承旧历史。

输出的模型输入类似:

system_prompt:
  你是商店助手,请依据资料回答。
  <memory_data>我喜欢简洁回答</memory_data>

user_text:
  最近对话上下文:
  用户:我刚签收了星河商店的商品,想退货。
  助手:资料规定签收后 7 天内可以退货……
  当前用户输入:那运费谁承担?

knowledge_tool_result:
  [资料来源: 星河商店售后说明 v1]
  <untrusted_knowledge>退货运费规则……</untrusted_knowledge>

上面为简化展示;实际输出带 JSON 元数据。Demo 中的助手前文和 Memory 是预置测试数据,未运行自动提取、模型答案生成、浏览器续聊或 WebSocket 断线恢复。应与页面体验及各链路测试配合使用。

Memory 实际怎么工作

长期记忆保存到 .openrealtime/memory/owners/<用户标识的 SHA-256>/memories.json,可通过 VOICEAGENT_MEMORY_DIR 指定根目录。首次管理访问会迁移旧版单个文件;Python 兼容读取旧格式与新格式。每条记录包含用户、角色、类型、内容、来源对话 ID、时间和 revision。

自动提取发生在网页调用 POST /api/conversations 保存记录时:服务端检查角色的 memory_enabled,对新增或修改后的最终用户消息做正则匹配。重复保存未变化的记录不会重放旧事实。生日使用同一个事实键,明确的新生日替换旧生日;手工编辑采用 revision 检查,并解除与原对话的关联。自动提取失败会返回状态并在对话页面提示用户核对记忆列表。

类型可触发的句式示例
偏好我喜欢简洁回答、我不喜欢太长的解释、我偏好中文交流
目标我的目标是学会日语、我打算长期学习编程
纠正请记住我更喜欢分步骤说明、纠正一下称呼方式
关系我和同事每周一起复盘

匹配针对整条消息,有长度限制,复杂句、多个事实、间接表达、否定或口语化改写可能不会保存。内容须满足敏感词与格式过滤;每条最多 300 字符,每个用户与角色最多 100 条,完全相同的内容会去重。

语音路径使用 SessionMemory.apply_async() 在线程中读取当前用户的记忆,检查角色开关,再选取该角色最近 20 条,作为 <memory_data> 注入系统提示词。同步 apply() 保留给离线调用。读取时冻结角色选择,角色切换不会改变已经开始的读取。当前按 updated_at(缺失时用 created_at)选择,不按相关性检索;最近编辑的旧记录也会进入优先读取范围。

没有自动处理「原来喜欢 A,现在喜欢 B」之类的冲突。冲突条目需在管理页面编辑或删除。资料目录、记忆目录与角色配置目录需要在 Next.js 与 Python 进程之间共享,身份格式也必须一致。

历史如何进入模型

项目中有两种历史存储,用途不同:

数据写入方与用途是否直接供当前模型读取
页面对话记录浏览器分段提交 transcript,通过 /api/conversations 写入每个会话独立的 conversation.jsonl,用于列表与详情展示可用来展示恢复前文;模型历史仍从经过授权的原 thread Journal 读取
服务端 Conversation Journal语音运行时记录用户输入、助手输出、工具结果等语义事件,按 tenant/user/thread 隔离当前会话上下文来自这里

当前会话处理下一轮时,Cascaded Engine 获取当前输入之前的已投影 Journal 条目,通过 BudgetedConversationContextProjector 渲染历史,将其填入 TurnContent.conversation_context。TurnContent.model_text 再将历史和本轮输入组合,交给 Brain 与模型客户端。长期 Memory 通过系统提示词加入,知识库则由工具检索加入。

长历史有上下文预算与摘要压缩:预留输出、工具 schema、指令、当前输入和安全余量,达到阈值时压缩历史。摘要带源序列与摘要校验,不能随意替代原文;摘要 checkpoint 当前存在内存中。语音投影还区分已播放与被打断的输出,默认被打断的内容只保留确认听到的前缀。

「继续会话」需要区分使用场景

场景当前实现当前限制
同一页暂停麦克风再恢复停止/恢复输入,原连接与 thread 保持,前文可继续使用依赖会话与连接仍有效
网络短暂断开后恢复使用 session ID、resume token、序列号和恢复屏障重连凭据在页面控制器内存中,刷新后不会直接复用
服务端要求创建 continuation控制器发送 previous_voice_session_id 和 requested_thread_id,服务端校验原 thread 权限属于协议恢复链路,还不是历史页面的入口
结束后的当前页「继续」本地复用当前 thread;公开准入续期发送原 session/thread 的 continuation服务端验证历史所属用户与原 session;历史不可用时拒绝,不静默降级成空会话
在历史详情页继续旧对话新记录保存 thread/session 标识,详情页提供「继续此对话」;进入后点击「继续」开始旧记录无标识不可恢复;已删除的角色不可恢复;运行时 Journal 必须仍存在
浏览器刷新或服务重启后继续Journal 可以配置 PostgreSQL 持久化默认 VOICEAGENT_STATE_BACKEND=memory 不持久;网页历史存在磁盘不等于模型历史可恢复

页面记录 ID 仍为独立 UUID,同时保存 thread_id 与 voice_session_id,不保存 resume token。历史页面先按当前账号读取记录,服务端按记录选择原角色;运行时再验证 thread 归属和原 session 是否确实出现在 Journal 中。不会把网页上传的 transcript 直接当成模型历史,也不会将页面 UUID 当成 thread ID。

新建对话会重置运行时身份;本地连接重新握手,公开模式在下次准入创建新 thread。「继续」保留原 thread,并沿用同一页面记录 ID。跨 session 的历史展示去除旧 generation/turn 编号,避免新 session 使用相同编号覆盖旧消息。

恢复失败时需要检查账号、角色是否存在、运行时是否重启,以及 Journal 是否启用 PostgreSQL。默认内存后端无法在进程重启后恢复;旧记录缺少映射时也不能推测原 thread。此时可以新建对话并自行提供必要背景,但不等同于恢复原会话。

记录保存失败显示错误与「重试保存」按钮。当前以固定 800 ms 节奏刷写,并在页面隐藏、离页和恢复联网时刷写;未发送快照合并为最新版本,提交按 UTF-8 字节限制分段,丢失响应时先重试同一个幂等操作。临时失败按 1–30 秒退避,不阻塞其他对话。单次段最多 100 条,总会话最多 100000 条,长对话不会因 500 条的单次限制停止保存。

已确认用户身份的页面使用 IndexedDB 保存最新待发送快照、已确认版本及未确认请求。提交前先完成本机写入,重开对话页面后按原账号重试;账号切换后的旧请求由服务端拒绝。版本冲突或无效请求停止自动覆盖,保留草稿导出与移除入口;服务端确认记录已删除或过期后清理相应待发送副本。多个页面写同一份本机草稿时使用版本检查,避免静默覆盖。

本机待发送内容是明文,仅按账号分区,不是加密存储。不要在共享设备上留下未保存草稿;清理浏览器站点数据会删除它们。存储权限/容量错误会显示单独提示,仍尝试服务器保存。浏览器在本机事务提交前被强杀、用户清理站点数据或设备故障时,仍不能保证末尾内容;多段 keepalive 超过浏览器总配额时会留待下一次打开对话页面补传。Journal 对账仍待完成。

完善程度与后续优先级

本次优化补齐了当前页结束后继续、新建 thread 隔离、运行时身份保存、历史详情续聊入口、旧消息编号隔离以及保存失败提示。

仍需继续完善:

  1. 可靠保存:页面隐藏时刷写、超过 500 条消息时分段保存、Memory 提取失败提示和浏览器待发送数据持久化已实现;仍需服务端 Journal 与页面记录对账。
  2. 旧记录迁移:缺少 thread 标识的旧记录目前只读,没有自动推测身份或直接注入模型的隐式恢复流程。
  3. 持久化验收:线上使用 PostgreSQL 后验证跨刷新、跨进程重启、已过期 thread 和删除历史的行为。
  4. Memory 质量:生日更正替换旧生日、手动编辑版本检查和删除对话时清理来源记忆已实现;多事实提取、其他事实冲突替换、相关性筛选和来源查看仍需完善。

回归测试覆盖客户端握手与编号隔离、网页历史用户隔离及身份一致性、服务端 Journal 与恢复权限。未连接真实语音模型进行完整端到端验收,不能将这些测试视为模型实际回答效果的证明。

管理操作补充(2026-10-01)

关闭记忆后仍可手动维护条目;页面支持刷新、数量提示和切换角色清除草稿。增删改、清空与会话归零的区别,以及 API、部署和备份说明,见数据管理指南。整体后续工作见项目完善清单。

知识库网页“测试检索”与Python Runtime采用一致的词法检索规则:标题和正文参与匹配、中文重叠双字词组、英文完整单词、最低查询词覆盖率,并优先覆盖不同来源。未命中可尝试资料标题或原文关键词;它不证明资料中没有答案。34条合成任务的评测及已知同义问法漏召回详见 docs/reports/2026-10-09-knowledge-quality-evaluation.md,当前实现不提供语义召回保证。