Dify平台中基于事件图谱的对话记忆技术方案
Dify 平台基于事件图谱的对话记忆技术方案
1. 项目背景与技术选型
1.1. 核心挑战:为“供应链助手Agent”构建长期记忆
在研发“供应链助手Agent”时,面临一个核心的技术瓶颈:如何为Agent构建一个有效、可靠的长期记忆系统。该Agent的目标是帮助供应链同事实时追踪、分析并应对复杂的供应链风险,尽量提前规避供应链风险助力全球的车辆交付销售,避免出现“以运定销”的尴尬与不利局面。但是在实场景中,我发现传统的 Agent记忆机制完全无法满足需求。
具体挑战如下:
无法理解事件的演变与关联:用户可能会连续输入一系列相关但离散的信息。例如:
- “报告:越南A港口因台风临时关闭。”
- “我们的B物料运输似乎有延误。”
- “查询客户C的订单状态。”
一个没有结构化记忆的Agent无法理解这三件事的内在联系:港口关闭(事件1)是物料延误(事件2)的根本原因,而物料延误可能会影响客户订单(事件3)。Agent无法回答“客户C的订单为什么可能延迟?”这类需要因果推理的问题。
上下文丢失与信息遗忘:随着对话的进行,早期的关键信息(如台风预警)很快就会被冲出LLM的上下文窗口。当用户在几小时或几天后回来询问“上次那个台风的后续影响是什么?”时,Agent已经“遗忘”了核心事件。
低效且不精确的检索:简单地将对话历史存入向量数据库进行检索(RAG),虽然能找回语义相似的片段,但无法区分“事件”本身和对事件的“讨论”。当用户问及“A港口关闭”时,可能会同时召回最初的报告、中间的讨论、以及最终的解决方案,充满了噪声和冗余。
为了构建一个真正智能的供应链助手,必须寻找一种能够结构化存储信息、显式表达事件间关系、并能进行精准、高效检索的记忆技术。
1.2. 技术方案调研与选型对比
针对以上挑战,我对业界主流的Agent记忆技术方案进行了深入调研和对比分析:
技术方案 | 上下文丰富度 | 关系推理能力 | 检索精度 | 长期一致性 | 实现复杂度 |
---|---|---|---|---|---|
滑动窗口 + 摘要 | 低 | 无 | 低 | 差 | 低 |
向量数据库 (RAG) | 中 | 弱 (隐式) | 中 | 中 | 中 |
事件图谱 (EKG) | 高 | 强 (显式) | 高 | 优 | 高 |
方案解读:
- 滑动窗口 + 摘要: 这是最基础的方法。它只保留最近的对话,并尝试将更早的信息压缩成摘要。这种方法丢失了大量细节,且完全无法进行逻辑推理,首先被排除。
- 向量数据库 (RAG): 这是目前最主流的方案。它通过向量嵌入实现了对语义信息的检索,解决了部分信息遗忘问题。但其核心缺陷在于,它将所有信息视为无差别的“文本块”,无法理解文本块之间的因果、时序等结构化关系。对于需要严谨逻辑推理的供应链分析场景,这种“模糊”的记忆是远远够的。
- 事件图谱 (EKG): 该方案将每一次交互都抽象为一个结构化的“事件”节点,并用明确的“关系”边(如
导致
、发生在...之后
)将它们连接起来。这创建了一个动态的、机器可读的知识网络。
1.3. 最终决策:选择事件图谱 (EKG)
经过审慎评估,我最终决定采用**事件图谱(EKG)**作为“供应链助手Agent”的长期记忆核心技术。
尽管其实现复杂度相对较高,但EKG是唯一能够从根本上解决我们核心挑战的方案。它强大的体系推理能力和高精度的检索能力,使得Agent能够真正理解复杂的事件演变过程,为用户提供精准、深刻、富有洞察力的供应链风险分析,从而构建起项目的核心技术壁垒。
本方案将详细阐述基于事件图谱的对话记忆系统的设计与实现。
2. 低代码智能体开发平台:Dify.AI
Dify 是一款开源的、领先的LLM应用开发平台,它将复杂的后端服务、模型调度、上下文管理等功能封装为一系列易于使用的模块,使开发者能通过可视化编排,专注于应用逻辑本身。我已经带领另一名研发同事对 Dify 平台进行了二次开发以及优化部署在了私有云环境作为我们的开发平台并且在持续迭代适配企内部员工使用。
选择Dify作为 AI Agent 开发平台的核心考虑点在于:
- 可视化工作流 (Workflow): Dify允许通过拖���方式,将LLM节点、代码节点、知识库、工具等组件连接起来,直观地构建出Agent逻辑,极大地提升了开发和调试效率,比较适合对于高代码智能体开发框架暂时不熟悉而且业务场景的逻辑相对固定的技术人员开发 AI Agent 的需求。
- 强大的会话变量 (Session Variables): Dify内置了会话级的变量管理机制。这正是实现事件图谱(EKG)动态存储与更新的关键。
session_event_graph
变量可以在工作流的每一步被读取和写回,完美支持了对话记忆的持久化。 - 灵活的代码节点 (Code Node): Dify允许在工作流中嵌入执行Python或Node.js代码的节点。这为实现自定义的、复杂的图谱操作(如事件解析、检索、合并)提供了无限的灵活性。
- 开箱即用的Agent能力: Dify集成了模型支持、工具调用、知识库等构建Agent所需的全套功能,使用户无需从零搭建后端服务,可以专注于实现事件图谱这一核心创新点。
- 企业级稳定性和可扩展性支撑能力:Dify 目前已经被许多行业的企业用户采纳使用作为低代码智能体研发平台,而且 Dify 在 V1.0 进行重构以后稳定性和可扩展性得到了极大提升。
3. 核心技术:事件图谱 (EKG)
3.1. EKG定义
事件图谱是一种以“事件”为核心节点来组织知识的图结构。在对话场景中,每个关键交互(如提问、回答、澄清、任务执行)都被抽象为一个结构化的事件节点。
3.2. 事件模型设计
每个“事件”节点应至少包含以下标准化字段:
字段名 | 数据类型 | 描述 | 示例 |
---|---|---|---|
event_id | String | 事件的唯一标识符 | evt_20250717103005_abc |
timestamp | Datetime | 事件发生的时间戳 (ISO 8601) | 2025-07-17T10:30:05Z |
actor | Enum | 事件的发起者 | user , assistant , system |
action_type | Enum | 事件的核心动作类型 | query , answer , clarify , execute_tool |
content_summary | String | 事件内容的简洁摘要 | “用户询问关于A公司的最新财报” |
entities | Array[Object] | 从内容中提取的关键实体 | [{"name": "A公司", "type": "ORG"}] |
status | Enum | 事件的当前状态 | pending , completed , failed |
related_event_ids | Array[String] | 与此事件相关的其他事件ID(如因果、指代) | ["evt_20250717102950_xyz"] |
4. Dify平台实现方
4.1. 系统架构与数据流
数据流转说明: 详见下一节的节点配置详解。
4.2. Dify 节点配置详解
要在Dify中实现上图的架构,需要对以下关键节点进行精确配置:
开始 (Start) 节点:
- 作用: 工作流的入口。
- 配置: 定义用户输入变量,通常为
userInput
。同时,在“变量”面板中,定义一个会话型 (Session) 变量session_event_graph
,类型设置为JSON
,并为其提供一个初始值{"events": []}
。
代码 (Code) 节点 -
EventRetriever
:- 作用: 对应架构图中的“Event Retrieval”环节,负责从完整的事件图谱中检索出与当前对话最相关的历史事件。
- 输入变量:
current_input
(引用userInput
),full_graph_json
(引用session_event_graph
)。 - 核心逻辑 (Python): 解析
full_graph_json
,根据current_input
的内容筛选出Top-K相关事件,并将其序列化为JSON字符串。 - 输出变量:
retrieved_events_json
。
大语言模型 (LLM) 节点 -
EventAwareResponder
:- 作用: 对应架构图中的“Event-Aware Responder”,负责生成回复并提取新事件。
- Prompt 设计: 这是整个系统的灵魂。Prompt需包含对角色的定义、注入
{{retrieved_events_json}}
和{{userInput}}
作为上下文,并严格规定其输出必须为包含user_reply
和new_events
两个键的JSON对象。 - 输出: LLM的输出是一个完整的JSON字符串,包含了给用户的回复和新提取的事件。
代码 (Code) 节点 -
GraphUpdater
:- 作用: 对应架构图中的“Graph Update”,负责解析LLM的输出,更新图谱,并分离出最终回复。
- 输入变量:
llm_output_json
(引用上一步LLM节点的输出),full_graph_json
(再次引用session_event_graph
)。 - 核心逻辑 (Python): 解析
llm_output_json
,得到user_reply
和new_events
。然后解析full_graph_json
,将新事件合并进去,最后将更新后的完整图谱序列化为JSON字符串。 - 输出变量:
final_reply
(包含user_reply
),updated_graph_json
(包含更新后的图谱)。
赋值 (Assign) / 更新变量:
- 作用: 将
GraphUpdater
输出的updated_graph_json
的值,重新赋给会话变量session_event_graph
,完成记忆的闭环更新。在Dify中,这通常通过在GraphUpdater
代码节点的末尾直接更新会话变量来实现。
- 作用: 将
回答 (Answer) 节点:
- 作用: 工作流的终点,向用户展示最终回复。
- 配置: 将其回复内容设置为引用
GraphUpdater
节点的final_reply
输出。
5. 其他优化点
5.1. 跨会话长期记忆
- 持久化存储: 在会话结束时,将
session_event_graph
存储到外部数据库(选择了neo4J图数据库)。 - 记忆加载: 用户再次开始会话时,从数据库加载其历史事件图谱,实现真正的个性化与长期记忆。
5.2. 高级分析与洞察
利用存储的事件图谱数据,进行离线分析,挖掘用户行为模式、识别高频问题、优化服务流程。
5.3. 工具化与自主化
将事件图谱的查询、更新等操作封装成Dify的原生工具,使Agent能够更智能、自主地管理和利用其记忆。