|
|
@@ -1,8 +1,8 @@
|
|
|
# 第八章 记忆与检索增强生成
|
|
|
|
|
|
-在前面的章节中,我们构建了HelloAgents框架的基础架构,实现了多种智能体范式和工具系统。不过,我们的框架还缺少一个关键能力:**记忆**。如果智能体无法记住之前的交互内容,也无法从历史经验中学习,那么在连续对话或复杂任务中,其表现将受到极大限制。
|
|
|
+在前面的章节中,我们构建了HelloAgents框架的基础架构,实现了多种智能体范式和工具系统。不过,我们的框架还缺少一个关键能力:<strong>记忆</strong>。如果智能体无法记住之前的交互内容,也无法从历史经验中学习,那么在连续对话或复杂任务中,其表现将受到极大限制。
|
|
|
|
|
|
-本章将在第七章构建的框架基础上,为HelloAgents增加两个核心能力:**记忆系统(Memory System)**和**检索增强生成(Retrieval-Augmented Generation, RAG)**。我们将采用"框架扩展 + 知识科普"的方式,在构建过程中深入理解Memory和RAG的理论基础,最终实现一个具有完整记忆和知识检索能力的智能体系统。
|
|
|
+本章将在第七章构建的框架基础上,为HelloAgents增加两个核心能力:<strong>记忆系统(Memory System)</strong>和<strong>检索增强生成(Retrieval-Augmented Generation, RAG)</strong>。我们将采用"框架扩展 + 知识科普"的方式,在构建过程中深入理解Memory和RAG的理论基础,最终实现一个具有完整记忆和知识检索能力的智能体系统。
|
|
|
|
|
|
|
|
|
## 8.1 从认知科学到智能体记忆
|
|
|
@@ -18,26 +18,26 @@
|
|
|
|
|
|
根据认知心理学的研究,人类记忆可以分为以下几个层次:
|
|
|
|
|
|
-1. **感觉记忆(Sensory Memory)**:持续时间极短(0.5-3秒),容量巨大,负责暂时保存感官接收到的所有信息
|
|
|
-2. **工作记忆(Working Memory)**:持续时间短(15-30秒),容量有限(7±2个项目),负责当前任务的信息处理
|
|
|
-3. **长期记忆(Long-term Memory)**:持续时间长(可达终生),容量几乎无限,进一步分为:
|
|
|
- - **程序性记忆**:技能和习惯(如骑自行车)
|
|
|
- - **陈述性记忆**:可以用语言表达的知识,又分为:
|
|
|
- - **语义记忆**:一般知识和概念(如"巴黎是法国首都")
|
|
|
- - **情景记忆**:个人经历和事件(如"昨天的会议内容")
|
|
|
+1. <strong>感觉记忆(Sensory Memory)</strong>:持续时间极短(0.5-3秒),容量巨大,负责暂时保存感官接收到的所有信息
|
|
|
+2. <strong>工作记忆(Working Memory)</strong>:持续时间短(15-30秒),容量有限(7±2个项目),负责当前任务的信息处理
|
|
|
+3. <strong>长期记忆(Long-term Memory)</strong>:持续时间长(可达终生),容量几乎无限,进一步分为:
|
|
|
+ - <strong>程序性记忆</strong>:技能和习惯(如骑自行车)
|
|
|
+ - <strong>陈述性记忆</strong>:可以用语言表达的知识,又分为:
|
|
|
+ - <strong>语义记忆</strong>:一般知识和概念(如"巴黎是法国首都")
|
|
|
+ - <strong>情景记忆</strong>:个人经历和事件(如"昨天的会议内容")
|
|
|
|
|
|
### 8.1.2 为何智能体需要记忆与RAG
|
|
|
|
|
|
-借鉴人类记忆系统的设计,我们可以理解为什么智能体也需要类似的记忆能力。人类智能的一个重要特征就是能够记住过去的经历,从中学习,并将这些经验应用到新的情况中。同样,一个真正智能的智能体也需要具备记忆能力。对于基于LLM的智能体而言,通常面临两个根本性局限:**对话状态的遗忘**和**内置知识的局限**。
|
|
|
+借鉴人类记忆系统的设计,我们可以理解为什么智能体也需要类似的记忆能力。人类智能的一个重要特征就是能够记住过去的经历,从中学习,并将这些经验应用到新的情况中。同样,一个真正智能的智能体也需要具备记忆能力。对于基于LLM的智能体而言,通常面临两个根本性局限:<strong>对话状态的遗忘</strong>和<strong>内置知识的局限</strong>。
|
|
|
|
|
|
(1)局限一:无状态导致的对话遗忘
|
|
|
|
|
|
-当前的大语言模型虽然强大,但设计上是**无状态的**。这意味着,每一次用户请求(或API调用)都是一次独立的、无关联的计算。模型本身不会自动“记住”上一次对话的内容。这带来了几个问题:
|
|
|
+当前的大语言模型虽然强大,但设计上是<strong>无状态的</strong>。这意味着,每一次用户请求(或API调用)都是一次独立的、无关联的计算。模型本身不会自动“记住”上一次对话的内容。这带来了几个问题:
|
|
|
|
|
|
-1. **上下文丢失**:在长对话中,早期的重要信息可能会因为上下文窗口限制而丢失
|
|
|
-2. **个性化缺失**:Agent无法记住用户的偏好、习惯或特定需求
|
|
|
-3. **学习能力受限**:无法从过往的成功或失败经验中学习改进
|
|
|
-4. **一致性问题**:在多轮对话中可能出现前后矛盾的回答
|
|
|
+1. <strong>上下文丢失</strong>:在长对话中,早期的重要信息可能会因为上下文窗口限制而丢失
|
|
|
+2. <strong>个性化缺失</strong>:Agent无法记住用户的偏好、习惯或特定需求
|
|
|
+3. <strong>学习能力受限</strong>:无法从过往的成功或失败经验中学习改进
|
|
|
+4. <strong>一致性问题</strong>:在多轮对话中可能出现前后矛盾的回答
|
|
|
|
|
|
让我们通过一个具体例子来理解这个问题:
|
|
|
|
|
|
@@ -60,12 +60,12 @@ print(response2) # "抱歉,我不知道您的学习进度..."
|
|
|
|
|
|
(2)局限二:模型内置知识的局限性
|
|
|
|
|
|
-除了遗忘对话历史,LLM 的另一个核心局限在于其知识是**静态的、有限的**。这些知识完全来自于它的训练数据,并因此带来一系列问题:
|
|
|
+除了遗忘对话历史,LLM 的另一个核心局限在于其知识是<strong>静态的、有限的</strong>。这些知识完全来自于它的训练数据,并因此带来一系列问题:
|
|
|
|
|
|
-1. **知识时效性**:大模型的训练数据有时间截止点,无法获取最新信息
|
|
|
-2. **专业领域知识**:通用模型在特定领域的深度知识可能不足
|
|
|
-3. **事实准确性**:通过检索验证,减少模型的幻觉问题
|
|
|
-4. **可解释性**:提供信息来源,增强回答的可信度
|
|
|
+1. <strong>知识时效性</strong>:大模型的训练数据有时间截止点,无法获取最新信息
|
|
|
+2. <strong>专业领域知识</strong>:通用模型在特定领域的深度知识可能不足
|
|
|
+3. <strong>事实准确性</strong>:通过检索验证,减少模型的幻觉问题
|
|
|
+4. <strong>可解释性</strong>:提供信息来源,增强回答的可信度
|
|
|
|
|
|
为了克服这一局限,RAG技术应运而生。它的核心思想是在模型生成回答之前,先从一个外部知识库(如文档、数据库、API)中检索出最相关的信息,并将这些信息作为上下文一同提供给模型。
|
|
|
|
|
|
@@ -148,7 +148,7 @@ hello-agents/
|
|
|
└──
|
|
|
```
|
|
|
|
|
|
-**快速开始:安装HelloAgents框架**
|
|
|
+<strong>快速开始:安装HelloAgents框架</strong>
|
|
|
|
|
|
为了让读者能够快速体验本章的完整功能,我们提供了可直接安装的Python包。你可以通过以下命令安装本章对应的版本:
|
|
|
|
|
|
@@ -207,8 +207,8 @@ EMBED_BASE_URL=
|
|
|
|
|
|
本章的学习可以采用两种方式:
|
|
|
|
|
|
-1. **体验式学习**:直接使用`pip`安装框架,运行示例代码,快速体验各种功能
|
|
|
-2. **深度学习**:跟随本章内容,从零开始实现每个组件,深入理解框架的设计思想和实现细节
|
|
|
+1. <strong>体验式学习</strong>:直接使用`pip`安装框架,运行示例代码,快速体验各种功能
|
|
|
+2. <strong>深度学习</strong>:跟随本章内容,从零开始实现每个组件,深入理解框架的设计思想和实现细节
|
|
|
|
|
|
我们建议采用"先体验,后实现"的学习路径。在本章中,我们提供了完整的测试文件,你可以重写核心函数并运行测试,以检验你的实现是否正确。
|
|
|
|
|
|
@@ -290,11 +290,11 @@ INFO:hello_agents.memory.storage.qdrant_store:✅ 使用现有Qdrant集合: rag_
|
|
|
如图8.3所示,根据认知科学的研究,人类记忆的形成经历以下几个阶段:
|
|
|
|
|
|
|
|
|
-1. **编码(Encoding)**:将感知到的信息转换为可存储的形式
|
|
|
-2. **存储(Storage)**:将编码后的信息保存在记忆系统中
|
|
|
-3. **检索(Retrieval)**:根据需要从记忆中提取相关信息
|
|
|
-4. **整合(Consolidation)**:将短期记忆转化为长期记忆
|
|
|
-5. **遗忘(Forgetting)**:删除不重要或过时的信息
|
|
|
+1. <strong>编码(Encoding)</strong>:将感知到的信息转换为可存储的形式
|
|
|
+2. <strong>存储(Storage)</strong>:将编码后的信息保存在记忆系统中
|
|
|
+3. <strong>检索(Retrieval)</strong>:根据需要从记忆中提取相关信息
|
|
|
+4. <strong>整合(Consolidation)</strong>:将短期记忆转化为长期记忆
|
|
|
+5. <strong>遗忘(Forgetting)</strong>:删除不重要或过时的信息
|
|
|
|
|
|
基于该启发,我们为 HelloAgents 设计了一套完整的记忆系统。其核心思想是模仿人类大脑处理不同类型信息的方式,将记忆划分为多个专门的模块,并建立一套智能化的管理机制。图8.4详细展示了这套系统的工作流程,包括记忆的添加、检索、整合和遗忘等关键环节。
|
|
|
|
|
|
@@ -305,13 +305,13 @@ INFO:hello_agents.memory.storage.qdrant_store:✅ 使用现有Qdrant集合: rag_
|
|
|
|
|
|
我们的记忆系统由四种不同类型的记忆模块构成,每种模块都针对特定的应用场景和生命周期进行了优化:
|
|
|
|
|
|
-首先是**工作记忆 (Working Memory)**,它扮演着智能体“短期记忆”的角色,主要用于存储当前对话的上下文信息。为确保高速访问和响应,其容量被有意限制(例如,默认50条),并且生命周期与单个会话绑定,会话结束后便会自动清理。
|
|
|
+首先是<strong>工作记忆 (Working Memory)</strong>,它扮演着智能体“短期记忆”的角色,主要用于存储当前对话的上下文信息。为确保高速访问和响应,其容量被有意限制(例如,默认50条),并且生命周期与单个会话绑定,会话结束后便会自动清理。
|
|
|
|
|
|
-其次是**情景记忆 (Episodic Memory)**,它负责长期存储具体的交互事件和智能体的学习经历。与工作记忆不同,情景记忆包含了丰富的上下文信息,并支持按时间序列或主题进行回顾式检索,是智能体“复盘”和学习过往经验的基础。
|
|
|
+其次是<strong>情景记忆 (Episodic Memory)</strong>,它负责长期存储具体的交互事件和智能体的学习经历。与工作记忆不同,情景记忆包含了丰富的上下文信息,并支持按时间序列或主题进行回顾式检索,是智能体“复盘”和学习过往经验的基础。
|
|
|
|
|
|
-与具体事件相对应的是**语义记忆 (Semantic Memory)**,它存储的是更为抽象的知识、概念和规则。例如,通过对话了解到的用户偏好、需要长期遵守的指令或领域知识点,都适合存放在这里。这部分记忆具有高度的持久性和重要性,是智能体形成“知识体系”和进行关联推理的核心。
|
|
|
+与具体事件相对应的是<strong>语义记忆 (Semantic Memory)</strong>,它存储的是更为抽象的知识、概念和规则。例如,通过对话了解到的用户偏好、需要长期遵守的指令或领域知识点,都适合存放在这里。这部分记忆具有高度的持久性和重要性,是智能体形成“知识体系”和进行关联推理的核心。
|
|
|
|
|
|
-最后,为了与日益丰富的多媒体交互,我们引入了**感知记忆 (Perceptual Memory)**。该模块专门处理图像、音频等多模态信息,并支持跨模态检索。其生命周期会根据信息的重要性和可用存储空间进行动态管理。
|
|
|
+最后,为了与日益丰富的多媒体交互,我们引入了<strong>感知记忆 (Perceptual Memory)</strong>。该模块专门处理图像、音频等多模态信息,并支持跨模态检索。其生命周期会根据信息的重要性和可用存储空间进行动态管理。
|
|
|
|
|
|
### 8.2.2 快速体验:30秒上手记忆功能
|
|
|
|
|
|
@@ -386,7 +386,7 @@ def execute(self, action: str, **kwargs) -> str:
|
|
|
# ... 其他操作
|
|
|
````
|
|
|
|
|
|
-这种统一的`execute`接口设计简化了Agent的调用方式,通过`action`参数指定具体操作,使用`**kwargs`允许每个操作有不同的参数需求。在这里我们会将比较重要的几个操作罗列出来:
|
|
|
+这种统一的`execute`接口设计简化了Agent的调用方式,通过`action`参数指定具体操作,使用`<strong>kwargs`允许每个操作有不同的参数需求。在这里我们会将比较重要的几个操作罗列出来:
|
|
|
|
|
|
(1)操作1:add
|
|
|
|
|
|
@@ -400,7 +400,7 @@ def _add_memory(
|
|
|
importance: float = 0.5,
|
|
|
file_path: str = None,
|
|
|
modality: str = None,
|
|
|
- **metadata
|
|
|
+ </strong>metadata
|
|
|
) -> str:
|
|
|
"""添加记忆"""
|
|
|
try:
|
|
|
@@ -564,7 +564,7 @@ def _forget(self, strategy: str = "importance_based", threshold: float = 0.1, ma
|
|
|
return f"❌ 遗忘记忆失败: {str(e)}"
|
|
|
````
|
|
|
|
|
|
-**三种遗忘策略的使用:**
|
|
|
+<strong>三种遗忘策略的使用:</strong>
|
|
|
|
|
|
```python
|
|
|
# 1. 基于重要性的遗忘 - 删除重要性低于阈值的记忆
|
|
|
@@ -604,7 +604,7 @@ def _consolidate(self, from_type: str = "working", to_type: str = "episodic", im
|
|
|
|
|
|
consolidate操作借鉴了神经科学中的记忆固化概念,模拟人类大脑将短期记忆转化为长期记忆的过程。默认设置是将重要性超过0.7的工作记忆转换为情景记忆,这个阈值确保只有真正重要的信息才会被长期保存。整个过程是自动化的,用户无需手动选择具体的记忆,系统会智能地识别符合条件的记忆并执行类型转换。
|
|
|
|
|
|
-**记忆整合的使用示例:**
|
|
|
+<strong>记忆整合的使用示例:</strong>
|
|
|
|
|
|
```python
|
|
|
# 将重要的工作记忆转为情景记忆
|
|
|
@@ -969,9 +969,9 @@ def _combine_and_rank_results(self, vector_results, graph_results, query, limit)
|
|
|
|
|
|
语义记忆的评分公式为:`(向量相似度 × 0.7 + 图相似度 × 0.3) × (0.8 + 重要性 × 0.4)`。这种设计的核心思想是:
|
|
|
|
|
|
-- **向量检索权重(0.7)**:语义相似度是主要因素,确保检索结果与查询语义相关
|
|
|
-- **图检索权重(0.3)**:关系推理作为补充,发现概念间的隐含关联
|
|
|
-- **重要性权重范围[0.8, 1.2]**:避免重要性过度影响相似度排序,保持检索的准确性
|
|
|
+- <strong>向量检索权重(0.7)</strong>:语义相似度是主要因素,确保检索结果与查询语义相关
|
|
|
+- <strong>图检索权重(0.3)</strong>:关系推理作为补充,发现概念间的隐含关联
|
|
|
+- <strong>重要性权重范围[0.8, 1.2]</strong>:避免重要性过度影响相似度排序,保持检索的准确性
|
|
|
|
|
|
(4)感知记忆(PerceptualMemory)
|
|
|
|
|
|
@@ -1089,19 +1089,19 @@ def _calculate_recency_score(self, timestamp: str) -> float:
|
|
|
|
|
|
检索增强生成(Retrieval-Augmented Generation,RAG)是一种结合了信息检索和文本生成的技术。它的核心思想是:在生成回答之前,先从外部知识库中检索相关信息,然后将检索到的信息作为上下文提供给大语言模型,从而生成更准确、更可靠的回答。
|
|
|
|
|
|
-因此,检索增强生成可以拆分为三个词汇。**检索**是指从知识库中查询相关内容;**增强**是将检索结果融入提示词,辅助模型生成;**生成**则输出兼具准确性与透明度的答案。
|
|
|
+因此,检索增强生成可以拆分为三个词汇。<strong>检索</strong>是指从知识库中查询相关内容;<strong>增强</strong>是将检索结果融入提示词,辅助模型生成;<strong>生成</strong>则输出兼具准确性与透明度的答案。
|
|
|
|
|
|
(2)基本工作流程
|
|
|
|
|
|
-一个完整的RAG应用流程主要分为两大核心环节。在**数据准备阶段**,系统通过**数据提取**、**文本分割**和**向量化**,将外部知识构建成一个可检索的数据库。随后在**应用阶段**,系统会响应用户的**提问**,从数据库中**检索**相关信息,将其**注入Prompt**,并最终驱动大语言模型**生成答案**。
|
|
|
+一个完整的RAG应用流程主要分为两大核心环节。在<strong>数据准备阶段</strong>,系统通过<strong>数据提取</strong>、<strong>文本分割</strong>和<strong>向量化</strong>,将外部知识构建成一个可检索的数据库。随后在<strong>应用阶段</strong>,系统会响应用户的<strong>提问</strong>,从数据库中<strong>检索</strong>相关信息,将其<strong>注入Prompt</strong>,并最终驱动大语言模型<strong>生成答案</strong>。
|
|
|
|
|
|
(3)发展历程
|
|
|
|
|
|
-第一阶段:朴素RAG(Naive RAG, 2020-2021)。这是RAG技术的萌芽阶段,其流程直接而简单,通常被称为“检索-读取”(Retrieve-Read)模式。**检索方式**:主要依赖传统的关键词匹配算法,如`TF-IDF`或`BM25`。这些方法计算词频和文档频率来评估相关性,对字面匹配效果好,但难以理解语义上的相似性。**生成模式**:将检索到的文档内容不加处理地直接拼接到提示词的上下文中,然后送给生成模型。
|
|
|
+第一阶段:朴素RAG(Naive RAG, 2020-2021)。这是RAG技术的萌芽阶段,其流程直接而简单,通常被称为“检索-读取”(Retrieve-Read)模式。<strong>检索方式</strong>:主要依赖传统的关键词匹配算法,如`TF-IDF`或`BM25`。这些方法计算词频和文档频率来评估相关性,对字面匹配效果好,但难以理解语义上的相似性。<strong>生成模式</strong>:将检索到的文档内容不加处理地直接拼接到提示词的上下文中,然后送给生成模型。
|
|
|
|
|
|
-第二阶段:高级RAG(Advanced RAG, 2022-2023)。随着向量数据库和文本嵌入技术的成熟,RAG进入了快速发展阶段。研究者和开发者们在“检索”和“生成”的各个环节引入了大量优化技术。**检索方式**:转向基于**稠密嵌入(Dense Embedding)**的语义检索。通过将文本转换为高维向量,模型能够理解和匹配语义上的相似性,而不仅仅是关键词。**生成模式**:引入了很多优化技术,例如查询重写,文档分块,重排序等。
|
|
|
+第二阶段:高级RAG(Advanced RAG, 2022-2023)。随着向量数据库和文本嵌入技术的成熟,RAG进入了快速发展阶段。研究者和开发者们在“检索”和“生成”的各个环节引入了大量优化技术。<strong>检索方式</strong>:转向基于<strong>稠密嵌入(Dense Embedding)</strong>的语义检索。通过将文本转换为高维向量,模型能够理解和匹配语义上的相似性,而不仅仅是关键词。<strong>生成模式</strong>:引入了很多优化技术,例如查询重写,文档分块,重排序等。
|
|
|
|
|
|
-第三阶段:模块化RAG(Modular RAG, 2023-至今)。在高级RAG的基础上,现代RAG系统进一步向着模块化、自动化和智能化的方向发展。系统的各个部分被设计成可插拔、可组合的独立模块,以适应更多样化和复杂的应用场景。**检索方式**:如混合检索,多查询扩展,假设性文档嵌入等。**生成模式**:思维链推理,自我反思与修正等。
|
|
|
+第三阶段:模块化RAG(Modular RAG, 2023-至今)。在高级RAG的基础上,现代RAG系统进一步向着模块化、自动化和智能化的方向发展。系统的各个部分被设计成可插拔、可组合的独立模块,以适应更多样化和复杂的应用场景。<strong>检索方式</strong>:如混合检索,多查询扩展,假设性文档嵌入等。<strong>生成模式</strong>:思维链推理,自我反思与修正等。
|
|
|
|
|
|
|
|
|
|
|
|
@@ -1115,8 +1115,8 @@ def _calculate_recency_score(self, timestamp: str) -> float:
|
|
|
</div>
|
|
|
|
|
|
如图8.5所示,展示了RAG系统的两个主要工作模式:
|
|
|
-1. **数据处理流程**:处理和存储知识文档,在这里我们采取工具`Markitdown`,设计思路是将传入的一切外部知识源统一转化为Markdown格式进行处理。
|
|
|
-2. **查询与生成流程**:根据查询检索相关信息并生成回答。
|
|
|
+1. <strong>数据处理流程</strong>:处理和存储知识文档,在这里我们采取工具`Markitdown`,设计思路是将传入的一切外部知识源统一转化为Markdown格式进行处理。
|
|
|
+2. <strong>查询与生成流程</strong>:根据查询检索相关信息并生成回答。
|
|
|
|
|
|
### 8.3.3 快速体验:30秒上手RAG功能
|
|
|
|
|
|
@@ -1657,17 +1657,17 @@ def search_vectors_expanded(
|
|
|
|
|
|
在实际工作中,我们经常需要处理大量的技术文档、研究论文、产品手册等PDF文件。传统的文档阅读方式效率低下,难以快速定位关键信息,更无法建立知识间的关联。
|
|
|
|
|
|
-本案例将基于Datawhale另外一门动手学大模型教程Happy-LLM的公测PDF文档`Happy-LLM-0727.pdf`为例,构建一个**基于Gradio的Web应用**,展示如何使用RAGTool和MemoryTool构建完整的交互式学习助手。PDF可在这个[链接](https://github.com/datawhalechina/happy-llm/releases/download/v1.0.1/Happy-LLM-0727.pdf)获取。
|
|
|
+本案例将基于Datawhale另外一门动手学大模型教程Happy-LLM的公测PDF文档`Happy-LLM-0727.pdf`为例,构建一个<strong>基于Gradio的Web应用</strong>,展示如何使用RAGTool和MemoryTool构建完整的交互式学习助手。PDF可在这个[链接](https://github.com/datawhalechina/happy-llm/releases/download/v1.0.1/Happy-LLM-0727.pdf)获取。
|
|
|
|
|
|
我们希望实现以下功能:
|
|
|
|
|
|
-1. **智能文档处理**:使用MarkItDown实现PDF到Markdown的统一转换,基于Markdown结构的智能分块策略,高效的向量化和索引构建
|
|
|
+1. <strong>智能文档处理</strong>:使用MarkItDown实现PDF到Markdown的统一转换,基于Markdown结构的智能分块策略,高效的向量化和索引构建
|
|
|
|
|
|
-2. **高级检索问答**:多查询扩展(MQE)提升召回率,假设文档嵌入(HyDE)改善检索精度,上下文感知的智能问答
|
|
|
+2. <strong>高级检索问答</strong>:多查询扩展(MQE)提升召回率,假设文档嵌入(HyDE)改善检索精度,上下文感知的智能问答
|
|
|
|
|
|
-3. **多层次记忆管理**:工作记忆管理当前学习任务和上下文,情景记忆记录学习事件和查询历史,语义记忆存储概念知识和理解,感知记忆处理文档特征和多模态信息
|
|
|
+3. <strong>多层次记忆管理</strong>:工作记忆管理当前学习任务和上下文,情景记忆记录学习事件和查询历史,语义记忆存储概念知识和理解,感知记忆处理文档特征和多模态信息
|
|
|
|
|
|
-4. **个性化学习支持**:基于学习历史的个性化推荐,记忆整合和选择性遗忘,学习报告生成和进度追踪
|
|
|
+4. <strong>个性化学习支持</strong>:基于学习历史的个性化推荐,记忆整合和选择性遗忘,学习报告生成和进度追踪
|
|
|
|
|
|
为了更清晰地展示整个系统的工作流程,图8.6展示了五个步骤之间的关系和数据流动。五个步骤形成了一个完整的闭环:步骤1将PDF文档处理后的信息记录到记忆系统,步骤2的检索结果也会记录到记忆系统,步骤3展示记忆系统的完整功能(添加、检索、整合、遗忘),步骤4整合RAG和Memory提供智能路由,步骤5收集所有统计信息生成学习报告。
|
|
|
|
|
|
@@ -1678,9 +1678,9 @@ def search_vectors_expanded(
|
|
|
|
|
|
接下来,我们将展示如何实现这个Web应用。整个应用分为三个核心部分:
|
|
|
|
|
|
-1. **核心助手类(PDFLearningAssistant)**:封装RAGTool和MemoryTool的调用逻辑
|
|
|
-2. **Gradio Web界面**:提供友好的用户交互界面,这个部分可以参考示例代码学习
|
|
|
-3. **其他核心功能**:笔记记录、学习回顾、统计查看和报告生成
|
|
|
+1. <strong>核心助手类(PDFLearningAssistant)</strong>:封装RAGTool和MemoryTool的调用逻辑
|
|
|
+2. <strong>Gradio Web界面</strong>:提供友好的用户交互界面,这个部分可以参考示例代码学习
|
|
|
+3. <strong>其他核心功能</strong>:笔记记录、学习回顾、统计查看和报告生成
|
|
|
|
|
|
### 8.4.2 核心助手类的实现
|
|
|
|
|
|
@@ -1719,13 +1719,13 @@ class PDFLearningAssistant:
|
|
|
|
|
|
在这个初始化过程中,我们做了几个关键的设计决策:
|
|
|
|
|
|
-**MemoryTool的初始化**:通过`user_id`参数实现用户级别的记忆隔离。不同用户的学习记忆是完全独立的,每个用户都有自己的工作记忆、情景记忆、语义记忆和感知记忆空间。
|
|
|
+<strong>MemoryTool的初始化</strong>:通过`user_id`参数实现用户级别的记忆隔离。不同用户的学习记忆是完全独立的,每个用户都有自己的工作记忆、情景记忆、语义记忆和感知记忆空间。
|
|
|
|
|
|
-**RAGTool的初始化**:通过`rag_namespace`参数实现知识库的命名空间隔离。使用`f"pdf_{user_id}"`作为命名空间,每个用户都有自己独立的PDF知识库。
|
|
|
+<strong>RAGTool的初始化</strong>:通过`rag_namespace`参数实现知识库的命名空间隔离。使用`f"pdf_{user_id}"`作为命名空间,每个用户都有自己独立的PDF知识库。
|
|
|
|
|
|
-**会话管理**:`session_id`用于追踪单次学习会话的完整过程,便于后续的学习历程回顾和分析。
|
|
|
+<strong>会话管理</strong>:`session_id`用于追踪单次学习会话的完整过程,便于后续的学习历程回顾和分析。
|
|
|
|
|
|
-**统计信息**:`stats`字典记录关键的学习指标,用于生成学习报告。
|
|
|
+<strong>统计信息</strong>:`stats`字典记录关键的学习指标,用于生成学习报告。
|
|
|
|
|
|
(2)加载PDF文档
|
|
|
|
|
|
@@ -1793,10 +1793,10 @@ result = self.rag_tool.execute(
|
|
|
|
|
|
这个调用会触发RAGTool的完整处理流程(MarkItDown转换、增强处理、智能分块、向量化存储),这些内部细节在8.3节已经详细介绍过。我们只需要关注:
|
|
|
|
|
|
-- **操作类型**:`"add_document"` - 添加文档到知识库
|
|
|
-- **文件路径**:`file_path` - PDF文件的路径
|
|
|
-- **分块参数**:`chunk_size=1000, chunk_overlap=200` - 控制文本分块
|
|
|
-- **返回结果**:包含处理状态和统计信息的字典
|
|
|
+- <strong>操作类型</strong>:`"add_document"` - 添加文档到知识库
|
|
|
+- <strong>文件路径</strong>:`file_path` - PDF文件的路径
|
|
|
+- <strong>分块参数</strong>:`chunk_size=1000, chunk_overlap=200` - 控制文本分块
|
|
|
+- <strong>返回结果</strong>:包含处理状态和统计信息的字典
|
|
|
|
|
|
文档加载成功后,我们使用MemoryTool记录到情景记忆:
|
|
|
|
|
|
@@ -1811,7 +1811,7 @@ self.memory_tool.execute(
|
|
|
)
|
|
|
```
|
|
|
|
|
|
-**为什么用情景记忆?** 因为这是一个具体的、有时间戳的事件,适合用情景记忆记录。`session_id`参数将这个事件关联到当前学习会话,便于后续回顾学习历程。
|
|
|
+<strong>为什么用情景记忆?</strong> 因为这是一个具体的、有时间戳的事件,适合用情景记忆记录。`session_id`参数将这个事件关联到当前学习会话,便于后续回顾学习历程。
|
|
|
|
|
|
这个记忆记录为后续的个性化服务奠定了基础:
|
|
|
|
|
|
@@ -1872,7 +1872,7 @@ def ask(self, question: str, use_advanced_search: bool = True) -> str:
|
|
|
|
|
|
当我们调用`self.rag_tool.execute("ask", ...)`时,RAGTool内部执行了以下高级检索流程:
|
|
|
|
|
|
-1. **多查询扩展(MQE)**:
|
|
|
+1. <strong>多查询扩展(MQE)</strong>:
|
|
|
|
|
|
```python
|
|
|
# 生成多样化查询
|
|
|
@@ -1885,7 +1885,7 @@ def ask(self, question: str, use_advanced_search: bool = True) -> str:
|
|
|
|
|
|
MQE通过LLM生成语义等价但表述不同的查询,从多个角度理解用户意图,提升召回率30%-50%。
|
|
|
|
|
|
-2. **假设文档嵌入(HyDE)**:
|
|
|
+2. <strong>假设文档嵌入(HyDE)</strong>:
|
|
|
|
|
|
- 生成假设答案文档,桥接查询和文档的语义鸿沟
|
|
|
- 使用假设答案的向量进行检索
|
|
|
@@ -1962,10 +1962,10 @@ def generate_report(self, save_to_file: bool = True) -> Dict[str, Any]:
|
|
|
|
|
|
这些方法分别实现了:
|
|
|
|
|
|
-- **add_note**:将学习笔记保存到语义记忆
|
|
|
-- **recall**:从记忆系统中检索学习历程
|
|
|
-- **get_stats**:获取当前会话的统计信息
|
|
|
-- **generate_report**:生成详细的学习报告并保存为JSON文件
|
|
|
+- <strong>add_note</strong>:将学习笔记保存到语义记忆
|
|
|
+- <strong>recall</strong>:从记忆系统中检索学习历程
|
|
|
+- <strong>get_stats</strong>:获取当前会话的统计信息
|
|
|
+- <strong>generate_report</strong>:生成详细的学习报告并保存为JSON文件
|
|
|
|
|
|
### 8.4.5 运行效果展示
|
|
|
|
|
|
@@ -1997,7 +1997,7 @@ def generate_report(self, save_to_file: bool = True) -> Dict[str, Any]:
|
|
|
<p>图 8.10 问答助手主页面</p>
|
|
|
</div>
|
|
|
|
|
|
-通过这个问答助手的案例,我们展示了如何使用RAGTool和MemoryTool构建一个完整的**基于Web的智能文档问答系统**。完整的代码可以在`code/chapter8/11_Q&A_Assistant.py`中找到。启动后访问 `http://localhost:7860` 即可使用这个智能学习助手。
|
|
|
+通过这个问答助手的案例,我们展示了如何使用RAGTool和MemoryTool构建一个完整的<strong>基于Web的智能文档问答系统</strong>。完整的代码可以在`code/chapter8/11_Q&A_Assistant.py`中找到。启动后访问 `http://localhost:7860` 即可使用这个智能学习助手。
|
|
|
|
|
|
建议读者亲自运行这个案例,体验RAG和Memory的能力,并在此基础上进行扩展和定制,构建符合自己需求的智能应用!
|
|
|
|