|
|
@@ -14,20 +14,20 @@
|
|
|
|
|
|
### 14.1.1 为什么需要深度研究助手
|
|
|
|
|
|
-在信息爆炸的时代,我们每天都需要快速了解新的技术、概念或事件。传统的研究方式有几个痛点。首先是**信息过载**。搜索引擎返回成千上万的结果,你需要逐个点开链接,阅读大量内容,才能找到有用的信息。其次是**缺少结构**。即使找到了相关信息,这些信息往往是碎片化的,缺少系统性的组织。最后是**重复劳动**。每次研究新主题时,都需要重复"搜索→阅读→总结→整理"的过程。
|
|
|
+在信息爆炸的时代,我们每天都需要快速了解新的技术、概念或事件。传统的研究方式有几个痛点。首先是<strong>信息过载</strong>。搜索引擎返回成千上万的结果,你需要逐个点开链接,阅读大量内容,才能找到有用的信息。其次是<strong>缺少结构</strong>。即使找到了相关信息,这些信息往往是碎片化的,缺少系统性的组织。最后是<strong>重复劳动</strong>。每次研究新主题时,都需要重复"搜索→阅读→总结→整理"的过程。
|
|
|
|
|
|
这就是深度研究助手需要解决的问题。它不仅仅是一个搜索工具,而是一个能够自主规划、执行和总结的研究助手。
|
|
|
|
|
|
-**深度研究助手的核心价值:**
|
|
|
+<strong>深度研究助手的核心价值:</strong>
|
|
|
|
|
|
-1. **节省时间**:将1-2小时的研究工作压缩到5-10分钟
|
|
|
-2. **提高质量**:系统化的研究流程,避免遗漏重要信息
|
|
|
-3. **可追溯**:记录所有搜索结果和来源,方便验证和引用
|
|
|
-4. **可扩展**:可以轻松添加新的搜索引擎、数据源和分析工具
|
|
|
+1. <strong>节省时间</strong>:将1-2小时的研究工作压缩到5-10分钟
|
|
|
+2. <strong>提高质量</strong>:系统化的研究流程,避免遗漏重要信息
|
|
|
+3. <strong>可追溯</strong>:记录所有搜索结果和来源,方便验证和引用
|
|
|
+4. <strong>可扩展</strong>:可以轻松添加新的搜索引擎、数据源和分析工具
|
|
|
|
|
|
### 14.1.2 技术架构概览
|
|
|
|
|
|
-此次系统仍然采用经典的**前后端分离架构**,如图14.1所示。
|
|
|
+此次系统仍然采用经典的<strong>前后端分离架构</strong>,如图14.1所示。
|
|
|
|
|
|
<div align="center">
|
|
|
<img src="https://raw.githubusercontent.com/datawhalechina/Hello-Agents/main/docs/images/14-figures/14-1.png" alt="" width="85%"/>
|
|
|
@@ -36,13 +36,13 @@
|
|
|
|
|
|
系统分为四层架构设计:
|
|
|
|
|
|
-**前端层 (Vue3+TypeScript)**:全屏模态对话框UI、Markdown结果可视化
|
|
|
+<strong>前端层 (Vue3+TypeScript)</strong>:全屏模态对话框UI、Markdown结果可视化
|
|
|
|
|
|
-**后端层 (FastAPI)**:API路由(`/research/stream`)
|
|
|
+<strong>后端层 (FastAPI)</strong>:API路由(`/research/stream`)
|
|
|
|
|
|
-**智能体层 (HelloAgents)**:三个专门Agent(TODO Planner、Task Summarizer、Report Writer)+ 两个核心工具(SearchTool、NoteTool)
|
|
|
+<strong>智能体层 (HelloAgents)</strong>:三个专门Agent(TODO Planner、Task Summarizer、Report Writer)+ 两个核心工具(SearchTool、NoteTool)
|
|
|
|
|
|
-**外部服务层**:搜索引擎+ LLM提供商
|
|
|
+<strong>外部服务层</strong>:搜索引擎+ LLM提供商
|
|
|
|
|
|
让我们看看一个完整的研究请求是如何在系统中流转的,如图14.2所示:
|
|
|
|
|
|
@@ -51,17 +51,17 @@
|
|
|
<p>图 14.2 深度研究助手数据流转过程</p>
|
|
|
</div>
|
|
|
|
|
|
-1. **用户输入**:用户在前端输入研究主题
|
|
|
-2. **前端发送**:前端通过SSE连接到`/research/stream`
|
|
|
-3. **后端接收**:FastAPI接收请求,创建研究状态
|
|
|
-4. **规划阶段**:调用研究规划Agent,分解为3个子任务
|
|
|
-5. **执行阶段**:逐个执行每个子任务
|
|
|
+1. <strong>用户输入</strong>:用户在前端输入研究主题
|
|
|
+2. <strong>前端发送</strong>:前端通过SSE连接到`/research/stream`
|
|
|
+3. <strong>后端接收</strong>:FastAPI接收请求,创建研究状态
|
|
|
+4. <strong>规划阶段</strong>:调用研究规划Agent,分解为3个子任务
|
|
|
+5. <strong>执行阶段</strong>:逐个执行每个子任务
|
|
|
- 使用SearchTool搜索
|
|
|
- 调用任务总结Agent总结
|
|
|
- 使用NoteTool记录结果
|
|
|
-6. **报告阶段**:调用报告生成Agent,整合所有总结
|
|
|
-7. **流式返回**:通过SSE推送进度和结果到前端
|
|
|
-8. **前端展示**:前端实时更新任务状态、进度条、日志、报告
|
|
|
+6. <strong>报告阶段</strong>:调用报告生成Agent,整合所有总结
|
|
|
+7. <strong>流式返回</strong>:通过SSE推送进度和结果到前端
|
|
|
+8. <strong>前端展示</strong>:前端实时更新任务状态、进度条、日志、报告
|
|
|
|
|
|
项目的目录结构如下:
|
|
|
|
|
|
@@ -185,9 +185,9 @@ npm run dev
|
|
|
|
|
|
研究完成后,你会看到:
|
|
|
|
|
|
-- **任务列表**:显示所有子任务及其状态
|
|
|
-- **进度日志**:显示研究过程中的所有操作
|
|
|
-- **最终报告**:结构化的Markdown报告,包含所有子任务的总结和来源引用
|
|
|
+- <strong>任务列表</strong>:显示所有子任务及其状态
|
|
|
+- <strong>进度日志</strong>:显示研究过程中的所有操作
|
|
|
+- <strong>最终报告</strong>:结构化的Markdown报告,包含所有子任务的总结和来源引用
|
|
|
|
|
|
现在你已经成功运行了深度研究助手,对系统有了直观的认识。
|
|
|
|
|
|
@@ -197,7 +197,7 @@ npm run dev
|
|
|
|
|
|
传统的搜索引擎只能回答单个问题,而深度研究需要回答一系列相关的问题。TODO驱动的研究范式将复杂的研究主题分解为多个子任务(TODO),逐个执行并整合结果。
|
|
|
|
|
|
-这种范式的核心思想是:**将"研究"这个复杂任务转化为"规划→执行→整合"的流程**。
|
|
|
+这种范式的核心思想是:<strong>将"研究"这个复杂任务转化为"规划→执行→整合"的流程</strong>。
|
|
|
|
|
|
让我们通过一个例子来理解这个转变。假设你想研究"Datawhale是一个什么样的组织?",传统的搜索方式是:
|
|
|
|
|
|
@@ -210,7 +210,7 @@ npm run dev
|
|
|
|
|
|
这种方式的问题在于每个链接只涵盖主题的一个方面、缺少系统性结构,需要手动整理和总结。
|
|
|
|
|
|
-**TODO驱动方式:系统化研究**
|
|
|
+<strong>TODO驱动方式:系统化研究</strong>
|
|
|
|
|
|
```
|
|
|
用户输入:Datawhale是一个什么样的组织?
|
|
|
@@ -240,11 +240,11 @@ npm run dev
|
|
|
|
|
|
一个完整的TODO驱动研究系统包含三个核心要素:
|
|
|
|
|
|
-**(1)智能规划器(TODO Planner)**:负责将研究主题分解为子任务。一个好的规划器需要理解主题的关键方面和研究目标,将主题分解为3-5个子任务(太少覆盖不全,太多会冗余),并为每个子任务设计合适的搜索查询。
|
|
|
+<strong>(1)智能规划器(TODO Planner)</strong>:负责将研究主题分解为子任务。一个好的规划器需要理解主题的关键方面和研究目标,将主题分解为3-5个子任务(太少覆盖不全,太多会冗余),并为每个子任务设计合适的搜索查询。
|
|
|
|
|
|
-**(2)任务执行器(Task Executor)**:负责执行每个子任务。执行器需要使用搜索引擎获取相关资料,提取关键信息并去除冗余内容,同时保存所有来源引用以方便验证。
|
|
|
+<strong>(2)任务执行器(Task Executor)</strong>:负责执行每个子任务。执行器需要使用搜索引擎获取相关资料,提取关键信息并去除冗余内容,同时保存所有来源引用以方便验证。
|
|
|
|
|
|
-**(3)报告生成器(Report Writer)**:负责整合所有子任务的结果。生成器需要按照逻辑顺序组织内容,合并重复的信息,并为每个观点添加来源引用。
|
|
|
+<strong>(3)报告生成器(Report Writer)</strong>:负责整合所有子任务的结果。生成器需要按照逻辑顺序组织内容,合并重复的信息,并为每个观点添加来源引用。
|
|
|
|
|
|
在我们的案例里,TODO驱动的研究流程如图14.5所示:
|
|
|
|
|
|
@@ -260,7 +260,7 @@ npm run dev
|
|
|
|
|
|
TODO驱动的研究流程分为三个阶段:规划(Planning)、执行(Execution)、报告(Reporting)。每个阶段都有专门的Agent负责。
|
|
|
|
|
|
-**(1)阶段1:规划**
|
|
|
+<strong>(1)阶段1:规划</strong>
|
|
|
|
|
|
规划阶段的目标是将研究主题分解为3-5个子任务。系统接收研究主题和当前日期作为输入,输出JSON格式的子任务列表。每个子任务包含三个字段:title(任务标题)、intent(研究意图)和query(搜索查询)。
|
|
|
|
|
|
@@ -284,13 +284,13 @@ TODO驱动的研究流程分为三个阶段:规划(Planning)、执行(Exec
|
|
|
|
|
|
一个好的规划应该覆盖全面、逻辑清晰、查询精准、条目数量适中。
|
|
|
|
|
|
-**(2)阶段2:执行**
|
|
|
+<strong>(2)阶段2:执行</strong>
|
|
|
|
|
|
执行阶段逐个执行每个子任务,搜索并总结相关资料。系统接收子任务列表和搜索引擎配置作为输入,输出每个子任务的总结(Markdown格式)和来源引用列表。执行流程如下:
|
|
|
|
|
|
对于每个子任务,执行器会:
|
|
|
|
|
|
-1. **搜索资料**:使用配置的搜索引擎执行搜索
|
|
|
+1. <strong>搜索资料</strong>:使用配置的搜索引擎执行搜索
|
|
|
|
|
|
```python
|
|
|
search_results = search_tool.run({
|
|
|
@@ -301,7 +301,7 @@ TODO驱动的研究流程分为三个阶段:规划(Planning)、执行(Exec
|
|
|
})
|
|
|
```
|
|
|
|
|
|
-2. **获取搜索结果**:提取标题、URL、摘要
|
|
|
+2. <strong>获取搜索结果</strong>:提取标题、URL、摘要
|
|
|
|
|
|
```json
|
|
|
{
|
|
|
@@ -316,7 +316,7 @@ TODO驱动的研究流程分为三个阶段:规划(Planning)、执行(Exec
|
|
|
}
|
|
|
```
|
|
|
|
|
|
-3. **调用总结Agent**:总结搜索结果
|
|
|
+3. <strong>调用总结Agent</strong>:总结搜索结果
|
|
|
|
|
|
```python
|
|
|
summary = summarizer_agent.run(
|
|
|
@@ -325,7 +325,7 @@ TODO驱动的研究流程分为三个阶段:规划(Planning)、执行(Exec
|
|
|
)
|
|
|
```
|
|
|
|
|
|
-4. **记录总结和来源**:保存到NoteTool
|
|
|
+4. <strong>记录总结和来源</strong>:保存到NoteTool
|
|
|
|
|
|
```python
|
|
|
note_tool.run({
|
|
|
@@ -390,7 +390,7 @@ Datawhale是一个专注于数据科学与AI领域的开源组织,成立于201
|
|
|
}
|
|
|
```
|
|
|
|
|
|
-**(3)阶段3:报告**
|
|
|
+<strong>(3)阶段3:报告</strong>
|
|
|
|
|
|
报告阶段的目标是整合所有子任务的总结,生成最终报告。系统接收所有子任务的总结和研究主题作为输入,输出Markdown格式的最终报告。报告包含标题、概述、各个子任务的详细分析、总结和参考文献五个部分。例如,对于"Datawhale是一个什么样的组织?",最终报告可能是:
|
|
|
|
|
|
@@ -443,13 +443,13 @@ Datawhale发布了多个高质量的开源教程,包括Hello-Agents、Joyful-P
|
|
|
|
|
|
让我们详细介绍每个Agent的设计。
|
|
|
|
|
|
-**Agent 1:研究规划专家(TODO Planner)**
|
|
|
+<strong>Agent 1:研究规划专家(TODO Planner)</strong>
|
|
|
|
|
|
-**职责**:将研究主题分解为3-5个子任务
|
|
|
+<strong>职责</strong>:将研究主题分解为3-5个子任务
|
|
|
|
|
|
-**设计理念**:研究规划专家的核心任务是理解用户的研究主题,分析主题的关键方面,然后生成一系列子任务。这个过程类似于人类研究者在开始研究前的"头脑风暴"阶段。
|
|
|
+<strong>设计理念</strong>:研究规划专家的核心任务是理解用户的研究主题,分析主题的关键方面,然后生成一系列子任务。这个过程类似于人类研究者在开始研究前的"头脑风暴"阶段。
|
|
|
|
|
|
-**Prompt设计**:
|
|
|
+<strong>Prompt设计</strong>:
|
|
|
|
|
|
```python
|
|
|
todo_planner_instructions = """
|
|
|
@@ -487,9 +487,9 @@ todo_planner_instructions = """
|
|
|
"""
|
|
|
```
|
|
|
|
|
|
-**关键设计点**:提示词包含当前日期以获取最新信息,明确要求JSON格式输出便于解析,通过示例帮助Agent理解期望输出,并强调子任务数量、逻辑关系等约束。
|
|
|
+<strong>关键设计点</strong>:提示词包含当前日期以获取最新信息,明确要求JSON格式输出便于解析,通过示例帮助Agent理解期望输出,并强调子任务数量、逻辑关系等约束。
|
|
|
|
|
|
-**实现代码**:
|
|
|
+<strong>实现代码</strong>:
|
|
|
|
|
|
这里的ToolAwareSimpleAgent是根据SimpleAgent拓展实现,可以在14.3.2了解,这里不用深究。
|
|
|
|
|
|
@@ -535,13 +535,13 @@ class PlanningService:
|
|
|
raise ValueError("无法从响应中提取JSON")
|
|
|
```
|
|
|
|
|
|
-**Agent 2:任务总结专家(Task Summarizer)**
|
|
|
+<strong>Agent 2:任务总结专家(Task Summarizer)</strong>
|
|
|
|
|
|
-**职责**:总结搜索结果,提取关键信息
|
|
|
+<strong>职责</strong>:总结搜索结果,提取关键信息
|
|
|
|
|
|
-**设计理念**:任务总结专家的核心任务是阅读搜索结果,提取关键信息,并以结构化的方式呈现。这个过程类似于人类研究者在阅读文献后做笔记的过程。
|
|
|
+<strong>设计理念</strong>:任务总结专家的核心任务是阅读搜索结果,提取关键信息,并以结构化的方式呈现。这个过程类似于人类研究者在阅读文献后做笔记的过程。
|
|
|
|
|
|
-**Prompt设计**:
|
|
|
+<strong>Prompt设计</strong>:
|
|
|
|
|
|
```python
|
|
|
task_summarizer_instructions = """
|
|
|
@@ -585,9 +585,9 @@ task_summarizer_instructions = """
|
|
|
"""
|
|
|
```
|
|
|
|
|
|
-**关键设计点**:提示词包含任务标题、意图、查询等上下文帮助Agent理解任务,明确要求输出包含核心观点、关键数据、来源引用,强调为每个观点添加来源引用,并通过示例帮助Agent理解期望的输出格式。
|
|
|
+<strong>关键设计点</strong>:提示词包含任务标题、意图、查询等上下文帮助Agent理解任务,明确要求输出包含核心观点、关键数据、来源引用,强调为每个观点添加来源引用,并通过示例帮助Agent理解期望的输出格式。
|
|
|
|
|
|
-**实现代码**:
|
|
|
+<strong>实现代码</strong>:
|
|
|
|
|
|
```python
|
|
|
class SummarizationService:
|
|
|
@@ -629,13 +629,13 @@ class SummarizationService:
|
|
|
return "\n".join(formatted)
|
|
|
```
|
|
|
|
|
|
-**Agent 3:报告撰写专家(Report Writer)**
|
|
|
+<strong>Agent 3:报告撰写专家(Report Writer)</strong>
|
|
|
|
|
|
-**职责**:整合所有子任务的总结,生成最终报告
|
|
|
+<strong>职责</strong>:整合所有子任务的总结,生成最终报告
|
|
|
|
|
|
-**设计理念**:报告撰写专家的核心任务是将所有子任务的总结整合成一份结构化的报告。这个过程类似于人类研究者在完成所有调研后撰写研究报告的过程。
|
|
|
+<strong>设计理念</strong>:报告撰写专家的核心任务是将所有子任务的总结整合成一份结构化的报告。这个过程类似于人类研究者在完成所有调研后撰写研究报告的过程。
|
|
|
|
|
|
-**Prompt设计**:
|
|
|
+<strong>Prompt设计</strong>:
|
|
|
|
|
|
```python
|
|
|
report_writer_instructions = """
|
|
|
@@ -690,9 +690,9 @@ report_writer_instructions = """
|
|
|
"""
|
|
|
```
|
|
|
|
|
|
-**关键设计点**:提示词明确要求报告包含标题、概述、详细分析、总结、参考文献等结构,强调按逻辑顺序组织内容,要求合并重复信息消除冗余,并保留所有来源引用。
|
|
|
+<strong>关键设计点</strong>:提示词明确要求报告包含标题、概述、详细分析、总结、参考文献等结构,强调按逻辑顺序组织内容,要求合并重复信息消除冗余,并保留所有来源引用。
|
|
|
|
|
|
-**实现代码**:
|
|
|
+<strong>实现代码</strong>:
|
|
|
|
|
|
```python
|
|
|
class ReportingService:
|
|
|
@@ -737,20 +737,20 @@ class ReportingService:
|
|
|
|
|
|
### 14.3.2 ToolAwareSimpleAgent的设计
|
|
|
|
|
|
-在第七章中,我们实现了`SimpleAgent`,它是HelloAgents框架的基础Agent。但在深度研究助手中,我们需要一个能够**记录工具调用**的Agent。这就是`ToolAwareSimpleAgent`的由来。
|
|
|
+在第七章中,我们实现了`SimpleAgent`,它是HelloAgents框架的基础Agent。但在深度研究助手中,我们需要一个能够<strong>记录工具调用</strong>的Agent。这就是`ToolAwareSimpleAgent`的由来。
|
|
|
|
|
|
在深度研究助手中,我们需要记录每个Agent的工具调用情况,用于:
|
|
|
|
|
|
-1. **调试**:查看Agent调用了哪些工具,传入了什么参数
|
|
|
-2. **日志**:记录研究过程中的所有操作
|
|
|
-3. **分析**:分析Agent的行为模式
|
|
|
-4. **进度展示**:实时显示Agent正在做什么
|
|
|
+1. <strong>调试</strong>:查看Agent调用了哪些工具,传入了什么参数
|
|
|
+2. <strong>日志</strong>:记录研究过程中的所有操作
|
|
|
+3. <strong>分析</strong>:分析Agent的行为模式
|
|
|
+4. <strong>进度展示</strong>:实时显示Agent正在做什么
|
|
|
|
|
|
`SimpleAgent`本身不支持工具调用监听,因此我们需要扩展它。
|
|
|
|
|
|
`ToolAwareSimpleAgent`在`SimpleAgent`的基础上增加了一个`tool_call_listener`参数,这是一个回调函数,每次工具调用时都会被调用。
|
|
|
|
|
|
-**使用示例:**
|
|
|
+<strong>使用示例:</strong>
|
|
|
|
|
|
```python
|
|
|
from hello_agents import ToolAwareSimpleAgent
|
|
|
@@ -836,7 +836,7 @@ class DeepResearchAgent:
|
|
|
|
|
|
### 14.3.3 Agent协作模式
|
|
|
|
|
|
-三个Agent之间是**顺序协作**的关系,如图14.6所示。
|
|
|
+三个Agent之间是<strong>顺序协作</strong>的关系,如图14.6所示。
|
|
|
|
|
|
<div align="center">
|
|
|
<img src="https://raw.githubusercontent.com/datawhalechina/Hello-Agents/main/docs/images/14-figures/14-6.png" alt="" width="85%"/>
|
|
|
@@ -845,9 +845,9 @@ class DeepResearchAgent:
|
|
|
|
|
|
顺序协作模式的特点是:
|
|
|
|
|
|
-1. **线性流程**:Agent按照固定的顺序执行
|
|
|
-2. **明确的输入输出**:每个Agent的输入来自上一个Agent的输出
|
|
|
-3. **无并发**:同一时间只有一个Agent在工作
|
|
|
+1. <strong>线性流程</strong>:Agent按照固定的顺序执行
|
|
|
+2. <strong>明确的输入输出</strong>:每个Agent的输入来自上一个Agent的输出
|
|
|
+3. <strong>无并发</strong>:同一时间只有一个Agent在工作
|
|
|
|
|
|
`DeepResearchAgent`是整个系统的核心协调器,负责调度三个Agent:
|
|
|
|
|
|
@@ -1083,14 +1083,14 @@ agent = ToolAwareSimpleAgent(
|
|
|
<p>图 14.7 工具调用流程</p>
|
|
|
</div>
|
|
|
|
|
|
-**工具调用流程**:
|
|
|
+**工具调用流程<strong>:
|
|
|
|
|
|
-1. **Agent生成指令**:Agent生成工具调用指令,如`[TOOL_CALL:search_tool:{"input": "Datawhale组织", "backend": "tavily"}]`
|
|
|
-2. **解析指令**:`ToolRegistry`解析指令,提取工具名称和参数
|
|
|
-3. **查找工具**:`ToolRegistry`根据工具名称查找对应的工具
|
|
|
-4. **调用工具**:调用工具的`run`方法,传入参数
|
|
|
-5. **返回结果**:工具返回执行结果
|
|
|
-6. **格式化结果**:将结果格式化为字符串,返回给Agent
|
|
|
+1. </strong>Agent生成指令<strong>:Agent生成工具调用指令,如`[TOOL_CALL:search_tool:{"input": "Datawhale组织", "backend": "tavily"}]`
|
|
|
+2. </strong>解析指令<strong>:`ToolRegistry`解析指令,提取工具名称和参数
|
|
|
+3. </strong>查找工具<strong>:`ToolRegistry`根据工具名称查找对应的工具
|
|
|
+4. </strong>调用工具<strong>:调用工具的`run`方法,传入参数
|
|
|
+5. </strong>返回结果<strong>:工具返回执行结果
|
|
|
+6. </strong>格式化结果<strong>:将结果格式化为字符串,返回给Agent
|
|
|
|
|
|
## 14.5 服务层实现
|
|
|
|
|
|
@@ -1100,14 +1100,14 @@ agent = ToolAwareSimpleAgent(
|
|
|
|
|
|
`PlanningService`负责调用研究规划Agent,将研究主题分解为子任务。这是整个研究流程的第一步,也是最关键的一步。
|
|
|
|
|
|
-**(1)方案实现**
|
|
|
+</strong>(1)方案实现<strong>
|
|
|
|
|
|
它的核心职责是:
|
|
|
|
|
|
-1. **构建规划Prompt**:根据研究主题和当前日期构建Prompt
|
|
|
-2. **调用规划Agent**:调用TODO Planner Agent生成子任务列表
|
|
|
-3. **解析JSON响应**:从Agent的响应中提取JSON格式的子任务列表
|
|
|
-4. **验证子任务格式**:确保每个子任务包含必需的字段(title、intent、query)
|
|
|
+1. </strong>构建规划Prompt<strong>:根据研究主题和当前日期构建Prompt
|
|
|
+2. </strong>调用规划Agent<strong>:调用TODO Planner Agent生成子任务列表
|
|
|
+3. </strong>解析JSON响应<strong>:从Agent的响应中提取JSON格式的子任务列表
|
|
|
+4. </strong>验证子任务格式**:确保每个子任务包含必需的字段(title、intent、query)
|
|
|
|
|
|
```python
|
|
|
import re
|
|
|
@@ -1205,23 +1205,23 @@ class PlanningService:
|
|
|
raise ValueError("无法从响应中提取JSON")
|
|
|
```
|
|
|
|
|
|
-**(2)JSON解析与验证**
|
|
|
+<strong>(2)JSON解析与验证</strong>
|
|
|
|
|
|
Agent返回的JSON可能包含额外的文本或格式错误,我们需要robust的解析逻辑:
|
|
|
|
|
|
-**常见问题**:
|
|
|
+<strong>常见问题</strong>:
|
|
|
|
|
|
-1. **包含额外文本**:Agent可能在JSON前后添加说明文字
|
|
|
-2. **格式错误**:JSON可能缺少引号、逗号等
|
|
|
-3. **字段缺失**:某些子任务可能缺少必需字段
|
|
|
+1. <strong>包含额外文本</strong>:Agent可能在JSON前后添加说明文字
|
|
|
+2. <strong>格式错误</strong>:JSON可能缺少引号、逗号等
|
|
|
+3. <strong>字段缺失</strong>:某些子任务可能缺少必需字段
|
|
|
|
|
|
-**解决方案**:
|
|
|
+<strong>解决方案</strong>:
|
|
|
|
|
|
-1. **使用正则表达式**:提取JSON部分
|
|
|
-2. **多种解析策略**:先尝试提取JSON数组,再尝试直接解析
|
|
|
-3. **字段验证**:确保每个子任务包含必需字段
|
|
|
+1. <strong>使用正则表达式</strong>:提取JSON部分
|
|
|
+2. <strong>多种解析策略</strong>:先尝试提取JSON数组,再尝试直接解析
|
|
|
+3. <strong>字段验证</strong>:确保每个子任务包含必需字段
|
|
|
|
|
|
-**示例**:
|
|
|
+<strong>示例</strong>:
|
|
|
|
|
|
```python
|
|
|
# Agent响应示例1:包含额外文本
|
|
|
@@ -1261,14 +1261,14 @@ tasks2 = service._extract_tasks(response2)
|
|
|
# 结果:[{"title": "什么是多模态模型", ...}, ...]
|
|
|
```
|
|
|
|
|
|
-**(3)规划质量评估**
|
|
|
+<strong>(3)规划质量评估</strong>
|
|
|
|
|
|
一个好的规划应该满足以下标准:
|
|
|
|
|
|
-1. **覆盖全面**:涵盖主题的所有重要方面
|
|
|
-2. **逻辑清晰**:子任务之间有明确的逻辑关系
|
|
|
-3. **查询精准**:搜索查询能够准确找到相关资料
|
|
|
-4. **数量适中**:3-5个子任务
|
|
|
+1. <strong>覆盖全面</strong>:涵盖主题的所有重要方面
|
|
|
+2. <strong>逻辑清晰</strong>:子任务之间有明确的逻辑关系
|
|
|
+3. <strong>查询精准</strong>:搜索查询能够准确找到相关资料
|
|
|
+4. <strong>数量适中</strong>:3-5个子任务
|
|
|
|
|
|
我们可以添加一个评估方法:
|
|
|
|
|
|
@@ -1311,10 +1311,10 @@ def evaluate_plan(self, todo_items: List[TodoItem]) -> dict:
|
|
|
|
|
|
它的职责是:
|
|
|
|
|
|
-1. **格式化搜索结果**:将搜索结果格式化为易读的文本
|
|
|
-2. **构建总结Prompt**:根据任务信息和搜索结果构建Prompt
|
|
|
-3. **调用总结Agent**:调用Task Summarizer Agent生成总结
|
|
|
-4. **提取来源引用**:从总结中提取来源引用
|
|
|
+1. <strong>格式化搜索结果</strong>:将搜索结果格式化为易读的文本
|
|
|
+2. <strong>构建总结Prompt</strong>:根据任务信息和搜索结果构建Prompt
|
|
|
+3. <strong>调用总结Agent</strong>:调用Task Summarizer Agent生成总结
|
|
|
+4. <strong>提取来源引用</strong>:从总结中提取来源引用
|
|
|
|
|
|
核心代码:
|
|
|
|
|
|
@@ -1407,12 +1407,12 @@ class SummarizationService:
|
|
|
|
|
|
它的职责是:
|
|
|
|
|
|
-1. **格式化子任务总结**:将所有子任务的总结格式化为统一的格式
|
|
|
-2. **构建报告Prompt**:根据研究主题和子任务总结构建Prompt
|
|
|
-3. **调用报告Agent**:调用Report Writer Agent生成最终报告
|
|
|
-4. **整理引用**:将所有来源引用整理到参考文献部分
|
|
|
+1. <strong>格式化子任务总结</strong>:将所有子任务的总结格式化为统一的格式
|
|
|
+2. <strong>构建报告Prompt</strong>:根据研究主题和子任务总结构建Prompt
|
|
|
+3. <strong>调用报告Agent</strong>:调用Report Writer Agent生成最终报告
|
|
|
+4. <strong>整理引用</strong>:将所有来源引用整理到参考文献部分
|
|
|
|
|
|
-**核心代码实现**:
|
|
|
+<strong>核心代码实现</strong>:
|
|
|
|
|
|
```python
|
|
|
from typing import List, Callable, Optional, Tuple
|
|
|
@@ -1503,10 +1503,10 @@ class ReportingService:
|
|
|
|
|
|
它的职责是:
|
|
|
|
|
|
-1. **调度搜索引擎**:根据配置选择搜索引擎
|
|
|
-2. **执行搜索**:调用SearchTool执行搜索
|
|
|
-3. **处理结果**:去重、限制Token、格式化
|
|
|
-4. **错误处理**:处理搜索失败的情况
|
|
|
+1. <strong>调度搜索引擎</strong>:根据配置选择搜索引擎
|
|
|
+2. <strong>执行搜索</strong>:调用SearchTool执行搜索
|
|
|
+3. <strong>处理结果</strong>:去重、限制Token、格式化
|
|
|
+4. <strong>错误处理</strong>:处理搜索失败的情况
|
|
|
|
|
|
核心代码:
|
|
|
|
|
|
@@ -1611,13 +1611,13 @@ class SearchService:
|
|
|
<p>图 14.8 搜索引擎调度流程</p>
|
|
|
</div>
|
|
|
|
|
|
-**调度逻辑**:
|
|
|
+**调度逻辑<strong>:
|
|
|
|
|
|
-1. **读取配置**:从`.env`文件读取`SEARCH_API`配置
|
|
|
-2. **选择引擎**:根据配置选择搜索引擎(tavily、duckduckgo、perplexity等)
|
|
|
-3. **执行搜索**:调用SearchTool执行搜索
|
|
|
-4. **处理结果**:去重、限制Token、格式化
|
|
|
-5. **返回结果**:返回处理后的搜索结果
|
|
|
+1. </strong>读取配置<strong>:从`.env`文件读取`SEARCH_API`配置
|
|
|
+2. </strong>选择引擎<strong>:根据配置选择搜索引擎(tavily、duckduckgo、perplexity等)
|
|
|
+3. </strong>执行搜索<strong>:调用SearchTool执行搜索
|
|
|
+4. </strong>处理结果<strong>:去重、限制Token、格式化
|
|
|
+5. </strong>返回结果<strong>:返回处理后的搜索结果
|
|
|
|
|
|
为了提高效率和降低成本,我们可以添加搜索结果缓存:
|
|
|
|
|
|
@@ -1679,10 +1679,10 @@ class SearchService:
|
|
|
|
|
|
深度研究助手采用全屏模态对话框的UI设计,这种设计有以下优势:
|
|
|
|
|
|
-1. **沉浸式体验**:全屏显示,避免干扰,专注于研究
|
|
|
-2. **清晰的层次**:主页面和研究页面分离,层次清晰
|
|
|
-3. **易于关闭**:点击关闭按钮或按ESC键即可返回主页面
|
|
|
-4. **响应式设计**:适配不同屏幕尺寸
|
|
|
+1. </strong>沉浸式体验<strong>:全屏显示,避免干扰,专注于研究
|
|
|
+2. </strong>清晰的层次<strong>:主页面和研究页面分离,层次清晰
|
|
|
+3. </strong>易于关闭<strong>:点击关闭按钮或按ESC键即可返回主页面
|
|
|
+4. </strong>响应式设计<strong>:适配不同屏幕尺寸
|
|
|
|
|
|
如图14.9所示,全屏模态对话框包含以下部分:
|
|
|
|
|
|
@@ -1691,12 +1691,12 @@ class SearchService:
|
|
|
<p>图 14.9 全屏模态对话框UI</p>
|
|
|
</div>
|
|
|
|
|
|
-**UI组件**:
|
|
|
+</strong>UI组件<strong>:
|
|
|
|
|
|
-1. **顶部栏**:包含研究主题和关闭按钮
|
|
|
-2. **进度区域**:显示当前研究进度(规划、执行、报告)
|
|
|
-3. **内容区域**:显示研究结果(Markdown格式)
|
|
|
-4. **底部栏**:显示状态信息(如"研究中..."、"已完成")
|
|
|
+1. </strong>顶部栏<strong>:包含研究主题和关闭按钮
|
|
|
+2. </strong>进度区域<strong>:显示当前研究进度(规划、执行、报告)
|
|
|
+3. </strong>内容区域<strong>:显示研究结果(Markdown格式)
|
|
|
+4. </strong>底部栏**:显示状态信息(如"研究中..."、"已完成")
|
|
|
|
|
|
对应的Vue实现如下所示(ResearchModal.vue):
|
|
|
|
|
|
@@ -1849,17 +1849,17 @@ watch(() => props.isOpen, (isOpen) => {
|
|
|
<p>图 14.10 SSE流程</p>
|
|
|
</div>
|
|
|
|
|
|
-**流程说明**:
|
|
|
+<strong>流程说明</strong>:
|
|
|
|
|
|
-1. **客户端发起请求**:发送POST请求到`/api/research`,包含研究主题
|
|
|
-2. **服务器建立SSE连接**:返回`text/event-stream`响应
|
|
|
-3. **服务器推送进度**:定期推送研究进度(规划、执行、报告)
|
|
|
-4. **客户端接收进度**:监听SSE事件,更新UI
|
|
|
-5. **研究完成**:服务器推送最终报告,关闭连接
|
|
|
+1. <strong>客户端发起请求</strong>:发送POST请求到`/api/research`,包含研究主题
|
|
|
+2. <strong>服务器建立SSE连接</strong>:返回`text/event-stream`响应
|
|
|
+3. <strong>服务器推送进度</strong>:定期推送研究进度(规划、执行、报告)
|
|
|
+4. <strong>客户端接收进度</strong>:监听SSE事件,更新UI
|
|
|
+5. <strong>研究完成</strong>:服务器推送最终报告,关闭连接
|
|
|
|
|
|
如果想把SSE用于前后端的项目中还需要做如下配置。
|
|
|
|
|
|
-**后端FastAPI SSE端点**:
|
|
|
+<strong>后端FastAPI SSE端点</strong>:
|
|
|
|
|
|
```python
|
|
|
from fastapi import FastAPI
|
|
|
@@ -1933,7 +1933,7 @@ async def research(request: ResearchRequest):
|
|
|
)
|
|
|
```
|
|
|
|
|
|
-**前端使用EventSource接收SSE**:
|
|
|
+<strong>前端使用EventSource接收SSE</strong>:
|
|
|
|
|
|
```typescript
|
|
|
// composables/useResearch.ts
|
|
|
@@ -2011,7 +2011,7 @@ export function useResearch() {
|
|
|
}
|
|
|
```
|
|
|
|
|
|
-**在组件中使用**:
|
|
|
+<strong>在组件中使用</strong>:
|
|
|
|
|
|
```vue
|
|
|
<script setup lang="ts">
|
|
|
@@ -2036,7 +2036,7 @@ const handleStartResearch = (topic: string) => {
|
|
|
|
|
|
研究结果以Markdown格式展示,包含标题、段落、列表、引用等元素。我们使用`marked`库将Markdown转换为HTML,并添加自定义样式。
|
|
|
|
|
|
-**渲染Markdown**:
|
|
|
+<strong>渲染Markdown</strong>:
|
|
|
|
|
|
```typescript
|
|
|
import { marked } from 'marked'
|
|
|
@@ -2071,74 +2071,74 @@ const renderedHtml = marked(markdownContent.value)
|
|
|
|
|
|
在本章中,我们从零开始构建了一个完整的自动化深度研究智能体系统。让我们回顾一下核心要点:
|
|
|
|
|
|
-**(1)TODO驱动的研究范式**
|
|
|
+<strong>(1)TODO驱动的研究范式</strong>
|
|
|
|
|
|
我们提出了一种新的研究范式——TODO驱动的研究。这种范式将复杂的研究主题分解为可执行的子任务,通过三个阶段完成研究:
|
|
|
|
|
|
-- **规划阶段**:将研究主题分解为3-5个子任务,每个子任务包含标题、意图和搜索查询
|
|
|
-- **执行阶段**:对每个子任务执行搜索和总结,生成结构化的知识
|
|
|
-- **报告阶段**:整合所有子任务的总结,生成最终的研究报告
|
|
|
+- <strong>规划阶段</strong>:将研究主题分解为3-5个子任务,每个子任务包含标题、意图和搜索查询
|
|
|
+- <strong>执行阶段</strong>:对每个子任务执行搜索和总结,生成结构化的知识
|
|
|
+- <strong>报告阶段</strong>:整合所有子任务的总结,生成最终的研究报告
|
|
|
|
|
|
这种范式的优势在于:
|
|
|
|
|
|
-1. **可控性强**:每个子任务都有明确的目标和范围
|
|
|
-2. **质量可靠**:通过专门的Agent保证每个环节的质量
|
|
|
-3. **易于调试**:可以单独调试每个子任务
|
|
|
-4. **可扩展性好**:可以轻松添加新的子任务或修改现有子任务
|
|
|
+1. <strong>可控性强</strong>:每个子任务都有明确的目标和范围
|
|
|
+2. <strong>质量可靠</strong>:通过专门的Agent保证每个环节的质量
|
|
|
+3. <strong>易于调试</strong>:可以单独调试每个子任务
|
|
|
+4. <strong>可扩展性好</strong>:可以轻松添加新的子任务或修改现有子任务
|
|
|
|
|
|
-**(2)三Agent协作系统**
|
|
|
+<strong>(2)三Agent协作系统</strong>
|
|
|
|
|
|
我们设计了三个专门的Agent,各司其职:
|
|
|
|
|
|
-- **TODO Planner(研究规划专家)**:负责将研究主题分解为子任务
|
|
|
-- **Task Summarizer(任务总结专家)**:负责总结每个子任务的搜索结果
|
|
|
-- **Report Writer(报告撰写专家)**:负责整合所有子任务的总结,生成最终报告
|
|
|
+- <strong>TODO Planner(研究规划专家)</strong>:负责将研究主题分解为子任务
|
|
|
+- <strong>Task Summarizer(任务总结专家)</strong>:负责总结每个子任务的搜索结果
|
|
|
+- <strong>Report Writer(报告撰写专家)</strong>:负责整合所有子任务的总结,生成最终报告
|
|
|
|
|
|
这种设计的优势在于:
|
|
|
|
|
|
-1. **职责清晰**:每个Agent专注于一个特定的任务
|
|
|
-2. **Prompt优化**:可以为每个Agent定制专门的Prompt
|
|
|
-3. **易于维护**:修改一个Agent不会影响其他Agent
|
|
|
-4. **质量保证**:每个Agent都是该领域的"专家"
|
|
|
+1. <strong>职责清晰</strong>:每个Agent专注于一个特定的任务
|
|
|
+2. <strong>Prompt优化</strong>:可以为每个Agent定制专门的Prompt
|
|
|
+3. <strong>易于维护</strong>:修改一个Agent不会影响其他Agent
|
|
|
+4. <strong>质量保证</strong>:每个Agent都是该领域的"专家"
|
|
|
|
|
|
-**(3)ToolAwareSimpleAgent的设计**
|
|
|
+<strong>(3)ToolAwareSimpleAgent的设计</strong>
|
|
|
|
|
|
我们扩展了HelloAgents框架的`SimpleAgent`,实现了`ToolAwareSimpleAgent`。这个Agent具有工具调用监听能力,可以:
|
|
|
|
|
|
-- **监听工具调用**:通过回调函数监听每次工具调用
|
|
|
-- **实时反馈**:将工具调用信息实时推送给前端
|
|
|
-- **调试支持**:记录所有工具调用,便于调试
|
|
|
+- <strong>监听工具调用</strong>:通过回调函数监听每次工具调用
|
|
|
+- <strong>实时反馈</strong>:将工具调用信息实时推送给前端
|
|
|
+- <strong>调试支持</strong>:记录所有工具调用,便于调试
|
|
|
|
|
|
这个Agent已经集成到HelloAgents框架中,可以在其他项目中复用。
|
|
|
|
|
|
-**(4)工具系统集成**
|
|
|
+<strong>(4)工具系统集成</strong>
|
|
|
|
|
|
我们充分利用了HelloAgents框架的工具系统:
|
|
|
|
|
|
-- **SearchTool**:扩展支持更多种搜索引擎(Tavily、DuckDuckGo、Perplexity等)
|
|
|
-- **NoteTool**:持久化研究进度,支持恢复和审计
|
|
|
-- **ToolRegistry**:统一管理所有工具,支持自定义扩展
|
|
|
+- <strong>SearchTool</strong>:扩展支持更多种搜索引擎(Tavily、DuckDuckGo、Perplexity等)
|
|
|
+- <strong>NoteTool</strong>:持久化研究进度,支持恢复和审计
|
|
|
+- <strong>ToolRegistry</strong>:统一管理所有工具,支持自定义扩展
|
|
|
|
|
|
通过配置化的设计,用户可以轻松切换搜索引擎,无需修改代码。
|
|
|
|
|
|
-**(5)核心服务实现**
|
|
|
+<strong>(5)核心服务实现</strong>
|
|
|
|
|
|
我们实现了四个核心服务,连接Agent和工具:
|
|
|
|
|
|
-- **PlanningService**:调用规划Agent,解析JSON,验证格式
|
|
|
-- **SummarizationService**:调用总结Agent,处理搜索结果,提取来源
|
|
|
-- **ReportingService**:调用报告Agent,整合总结,生成报告
|
|
|
-- **SearchService**:调度搜索引擎,处理结果,错误降级,结果缓存
|
|
|
+- <strong>PlanningService</strong>:调用规划Agent,解析JSON,验证格式
|
|
|
+- <strong>SummarizationService</strong>:调用总结Agent,处理搜索结果,提取来源
|
|
|
+- <strong>ReportingService</strong>:调用报告Agent,整合总结,生成报告
|
|
|
+- <strong>SearchService</strong>:调度搜索引擎,处理结果,错误降级,结果缓存
|
|
|
|
|
|
这些服务各司其职,通过清晰的接口协作,实现了从研究主题到最终报告的自动化流程。
|
|
|
|
|
|
-**(6)前端交互设计**
|
|
|
+<strong>(6)前端交互设计</strong>
|
|
|
|
|
|
我们设计了用户友好的前端界面:
|
|
|
|
|
|
-- **全屏模态对话框**:沉浸式体验,清晰的层次
|
|
|
-- **SSE实时进度**:实时展示研究进度,用户体验良好
|
|
|
-- **Markdown可视化**:美观的格式,清晰的结构
|
|
|
+- <strong>全屏模态对话框</strong>:沉浸式体验,清晰的层次
|
|
|
+- <strong>SSE实时进度</strong>:实时展示研究进度,用户体验良好
|
|
|
+- <strong>Markdown可视化</strong>:美观的格式,清晰的结构
|
|
|
|
|
|
通过Vue 3 + TypeScript + SSE的技术栈,我们实现了一个现代化的Web应用。
|
|
|
|