[Bug]: Memory extraction stores an empty valid_at for semantic items, and an unparseable timestamp is written through unchanged

该问题出现在 RAGFlow 记忆提取(Memory extraction)流程中,当模型返回的 valid_at 为空或不是合法 ISO 8601 字符串时,会被原样写入数据库;semantic 类目约有 6.5% 的条目出现空 valid_at ,并伴随日志中的 [Bug]: Memory ex

快速结论:该问题出现在 RAGFlow 记忆提取(Memory extraction)流程中,当模型返回的 valid_at 为空或不是合法 ISO 8601 字符串时,会被原样写入数据库;semantic 类目约有 6.5% 的条目出现空 valid_at,并伴随日志中的 [Bug]: Memory extraction stores an empty valid_at for semantic items, and an unparseable timestamp is written through unchanged 相关报错。

适用环境:RAGFlow v0.26.4,问题发生在 memory 提取/写入服务链路(memory/utils/prompt_util.pycommon/time_utils.pyapi/db/joint_services/memory_message_service.py)。Issue 未提供操作系统、Python、CUDA 或显卡信息。

最快修复方案:暂无确认的一步修复方案。Issue 中确认了缺陷位置与两处修改建议(改 semantic 模板必填 timestamp、format_iso_8601_to_ymd_hms 记录被拒绝的值并返回默认值或空串),但未给出已合并的补丁版本。

注意事项:建议中的修改属于 Issue 作者与评论者确认的“正确方向”,并非官方已验证的发布修复,落地前需自行测试;同时需考虑历史数据中已写入的异常 valid_at 是否需要回补,否则排序逻辑(order_by.desc("valid_at"))仍会受影响。

问题场景

用户在 RAGFlow v0.26.4 上开启记忆(memory)功能,调用 memory 提取流程对对话内容做 semantic / episodic / procedural 多类型抽取时触发。具体触发点是 PromptAssembler.assemble_system_prompt({"memory_type": ["semantic", "episodic"]}) 生成的系统提示词,以及后续把抽取结果写入消息表的 memory_message_service.py 调用链。表现为 semantic 条目 valid_at 为空、或模型给出的时间字符串无法被解析却仍被写库;在一个约 4,132 条记录的记忆库中,144 条(占 semantic 条目的 6.5%,episodic 与 raw 为 0%)出现空 valid_at,每天可见约 20 次相关错误日志。

报错原文

[Bug]: Memory extraction stores an empty valid_at for semantic items, and an unparseable timestamp is written through unchanged

ERROR ISO string too short

日志仅包含异常消息(例如 ISO string too short),不包含字段名、被拒绝的值、所属 memory 或 message 信息。

原因分析

两个缺陷叠加导致该现象:

原因一:输出模板不对称。memory/utils/prompt_util.pyOUTPUT_TEMPLATES 中,不同类型对 valid_at 的声明不一致:semantic 写作 "timestamp or empty"(模型读作可选),而 episodic"event start timestamp"procedural"procedure effective timestamp"(明确必填)。这与 SYSTEM_BASE_TEMPLATE 中的 Each extracted item MUST have: content, valid_at, invalid_at 以及 semantic 的 Default: valid_at = conversation time 相矛盾。模型倾向于遵循格式块,于是 semantic 条目出现空 valid_at,分布与模板不对称完全吻合。

原因二:解析失败后静默写穿。common/time_utils.pyformat_iso_8601_to_ymd_hms 在解析异常时只记录 str(e),然后把原始字符串原样返回。调用点 api/db/joint_services/memory_message_service.py 中,valid_at 直接透传、没有像 invalid_at 那样做空值保护(if extracted_content.get("invalid_at")),因此空值或脏时间戳被直接持久化进时间列。

可能影响:valid_at 参与 MessageService.list_messageorder_by.desc("valid_at") 排序,也是事实的时间有效性字段;无时间戳的条目会排在最后,无法参与任何时效性/最近性逻辑。

环境排查

  • 确认 RAGFlow 版本是否为 v0.26.4(Issue 观察版本)。
  • 确认 memory 提取是否同时启用了 semantic 与其他类型,便于对比 6.5% 与 0% 的分布。
  • 检查 memory/utils/prompt_util.pyOUTPUT_TEMPLATES 的 semantic / episodic / procedural 三处 valid_at 声明是否一致。
  • 检查 common/time_utils.pyformat_iso_8601_to_ymd_hms 异常分支是否仍返回 time_str
  • 检查 api/db/joint_services/memory_message_service.py 调用点对 valid_at 是否有空值守卫。
  • Issue 未提供 Python、CUDA、PyTorch、显卡或依赖版本,相关项无需核对。

解决步骤

  1. 统计当前记忆库中 valid_at 为空的记录数与类型分布,确认是否集中在 semantic,并核对是否接近 6.5% 量级。
  2. 检索日志中的 ERROR ISO string too short 类异常条目,评估每天出现频率(Issue 中约 20 次/天),确认存在静默写穿。
  3. 按 Issue 建议修改 semantic 的输出模板,使其要求时间戳,例如改成 "valid_at": "timestamp — use the conversation time when the fact has no date of its own",与上下文的 MUST have 及 Default 规则对齐。
  4. 按 Issue 建议修改 format_iso_8601_to_ymd_hms:在异常分支中连同被拒绝的值一起记录,并改为抛出异常或替换为显式默认值(含空字符串),而不再把未解析字符串写入时间列。
  5. memory_message_service.py 调用点的 valid_at 增加与 invalid_at 一致的空值/格式防护。
  6. 对已落库的异常 valid_at 数据做清理或回补,避免影响 order_by.desc("valid_at") 排序与时效逻辑。

验证方法

改动后重新跑一轮 memory 提取,检查 semantic 条目是否仍出现空 valid_at;确认日志中不再出现只含 ISO string too short 这类无上下文的错误,且解析失败时能看到被拒绝的值或得到预期的默认值/异常;同时复核 list_messagevalid_at 降序返回的顺序是否符合预期。

参考来源

infiniflow/ragflow #18415

GamsGo AI

AI 工具推荐

想把多个 AI 模型放在一个入口?

GamsGo AI 集成 ChatGPT、DeepSeek、Gemini、Claude、Midjourney、Veo 等常用模型,适合写作、绘图、视频和日常 AI 工作流。

了解 GamsGo AI

推广链接:通过此链接购买,我可能获得佣金,不影响你的价格。

这个方案解决了吗?

celebrityanime
celebrityanime
文章: 25256

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注