Files
deepagents----/tests/EXECUTION_ANALYSIS.md
2025-11-02 18:06:38 +08:00

531 lines
16 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 智能深度研究系统 - 执行过程详细分析
**基于**: `llm_calls_20251031_150543.json`
**测试问题**: "Python asyncio最佳实践"
**深度模式**: quick
**总LLM调用次数**: 5次
**总耗时**: 49.49秒
---
## 整体架构回顾
```
┌─────────────────────────────────────────────────────────────┐
│ LangGraph 执行引擎 │
│ (持续调用Agent直到任务完成或无工具调用) │
└─────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────┐
│ ResearchCoordinator (主Agent) │
│ - 协调整个研究流程 │
│ - 通过虚拟文件系统管理状态 │
│ - 使用task工具调用SubAgent │
└─────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────┐
│ 虚拟文件系统 (State) │
│ - /question.txt │
│ - /config.json │
│ - /search_queries.json │
│ - /iteration_N/*.json │
└─────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────┐
│ 6个SubAgent (通过task调用) │
│ 1. intent-analyzer 4. content-analyzer │
│ 2. search-orchestrator 5. confidence-evaluator │
│ 3. source-validator 6. report-generator │
└─────────────────────────────────────────────────────────────┘
```
---
## 详细执行流程分析
### 🔵 LLM调用 #1 - 主Agent初始化 (步骤1)
**时间**: 15:04:53 → 15:05:01 (8秒)
**执行者**: ResearchCoordinator (主Agent)
**Token消耗**: 输入5,920 + 输出103 = 6,023 tokens
#### 输入
```
[SystemMessage] 完整的系统提示词
- 研究问题: "Python asyncio最佳实践"
- 7步执行流程说明
- 重要提示: write_file和task不能在同一个响应中调用
[HumanMessage] "请开始研究这个问题Python asyncio最佳实践"
```
#### 主Agent的思考过程
根据系统提示词主Agent理解到
1. 需要先执行步骤1初始化虚拟文件系统
2. 写入`/question.txt``/config.json`
3. **不能**在同一响应中调用task工具
#### 输出
```json
{
"tool_calls": [
{
"name": "write_file",
"file_path": "/question.txt",
"content": "Python asyncio最佳实践"
},
{
"name": "write_file",
"file_path": "/config.json",
"content": "{\"depth_mode\": \"quick\", \"report_format\": \"technical\", ...}"
}
]
}
```
#### 关键点
- ✅ 主Agent **只**调用了write_file没有调用task
- ✅ 两个文件被并行写入
- 🔄 LangGraph看到有工具调用会继续执行下一轮
#### State更新
```
虚拟文件系统:
├── /question.txt ✅ (新增)
└── /config.json ✅ (新增)
```
---
### 🔵 LLM调用 #2 - 主Agent启动SubAgent (步骤2)
**时间**: 15:05:01 → 15:05:06 (4.5秒)
**执行者**: ResearchCoordinator (主Agent)
**Token消耗**: 输入6,046 + 输出69 = 6,115 tokens
#### 输入
```
[SystemMessage] 完整的系统提示词 (相同)
[HumanMessage] "请开始研究这个问题Python asyncio最佳实践"
[AIMessage] 之前的响应 (write_file × 2)
[ToolMessage] "Updated file /question.txt" ✅
[ToolMessage] "Updated file /config.json" ✅
```
#### 主Agent的思考过程
主Agent看到
1. 两个文件已成功写入ToolMessage确认
2. 步骤1已完成应该进入步骤2
3. 现在可以调用task工具启动intent-analyzer
#### 输出
```json
{
"content": "已将研究问题和配置写入虚拟文件系统。现在,我将调用 `intent-analyzer` SubAgent 来分析研究问题并生成搜索查询。",
"tool_calls": [
{
"name": "task",
"args": {
"description": "分析研究问题并生成搜索查询",
"subagent_type": "intent-analyzer"
}
}
]
}
```
#### 关键点
- ✅ 主Agent在**独立的响应**中调用task
- ✅ 此时虚拟文件系统已包含两个文件
- 🚀 task工具触发SubAgent创建和执行
---
### 🔵 LLM调用 #3 - SubAgent读取文件
**时间**: 15:05:06 → 15:05:08 (2.7秒)
**执行者**: intent-analyzer (SubAgent)
**Token消耗**: 输入2,724 + 输出49 = 2,773 tokens
#### 输入
```
[SystemMessage] intent-analyzer的专用系统提示词
- 任务: 分析问题并生成搜索查询
- 需要读取: /question.txt, /config.json
- 需要输出: /search_queries.json
[HumanMessage] "分析研究问题并生成搜索查询"
```
#### SubAgent的思考过程
SubAgent按照提示词
1. 需要先读取输入文件
2. 使用ls查看文件系统结构
3. 使用read_file读取两个文件
#### 输出
```json
{
"tool_calls": [
{"name": "ls"},
{"name": "read_file", "file_path": "/question.txt"},
{"name": "read_file", "file_path": "/config.json"}
]
}
```
#### 关键机制解析
**🔑 核心问题SubAgent如何访问主Agent写入的文件**
根据DeepAgents源码 (`deepagents/middleware/subagents.py:332`):
```python
def _validate_and_prepare_state(subagent_type, description, runtime):
# 创建SubAgent的state从主Agent的state复制
subagent_state = {
k: v for k, v in runtime.state.items()
if k not in ("messages", "todos") # 排除这两个键
}
subagent_state["messages"] = [HumanMessage(content=description)]
return subagent, subagent_state
```
**执行时序**:
```
1. 主Agent调用 #1: write_file × 2
→ 返回 Command(update={"files": {...}})
2. LangGraph应用State更新
→ runtime.state["files"] = {
"/question.txt": {...},
"/config.json": {...}
}
3. 主Agent调用 #2: task(...)
→ task工具内部调用 _validate_and_prepare_state()
→ 复制 runtime.state (包括files) 给SubAgent
4. SubAgent启动时state中已包含这两个文件 ✅
```
这就是为什么**必须分两个响应**
- ❌ 如果在同一响应中调用write_file和task两个工具会**并行**执行
- ❌ 当task开始复制state时write_file的更新还没被应用
- ✅ 分两个响应后第二次调用时state已包含更新
---
### 🔵 LLM调用 #4 - SubAgent分析并生成查询
**时间**: 15:05:08 → 15:05:28 (19.4秒)
**执行者**: intent-analyzer (SubAgent)
**Token消耗**: 输入2,861 + 输出404 = 3,265 tokens
#### 输入
```
[SystemMessage] intent-analyzer的系统提示词
[HumanMessage] "分析研究问题并生成搜索查询"
[AIMessage] 之前的工具调用 (ls, read_file × 2)
[ToolMessage] "[\"/question.txt\", \"/config.json\"]" ✅
[ToolMessage] " 1\tPython asyncio最佳实践" ✅
[ToolMessage] " 1\t{\"depth_mode\": \"quick\", ...}" ✅
```
#### SubAgent的思考过程
SubAgent成功读取到文件内容
1. **问题**: "Python asyncio最佳实践"
2. **配置**: quick模式 → 生成3个查询
3. **领域分析**: 技术(编程)
4. **查询策略**: 基础概念 + 最佳实践 + 实现细节
#### 输出
```json
{
"content": "已经读取了原始研究问题和配置文件。研究问题是关于...",
"tool_calls": [
{
"name": "write_file",
"file_path": "/search_queries.json",
"content": "{\n \"original_question\": \"Python asyncio最佳实践\",\n \"queries\": [\n {\"query\": \"What is Python asyncio and how does it work?\", ...},\n {\"query\": \"Best practices for using Python asyncio\", ...},\n {\"query\": \"How to implement best practices with Python asyncio in real projects\", ...}\n ]\n}"
}
]
}
```
#### 生成的3个搜索查询
1. **基础概念**: "What is Python asyncio and how does it work?"
2. **最佳实践**: "Best practices for using Python asyncio"
3. **实现细节**: "How to implement best practices with Python asyncio in real projects"
#### State更新
```
虚拟文件系统:
├── /question.txt
├── /config.json
└── /search_queries.json ✅ (新增SubAgent写入)
```
---
### 🔵 LLM调用 #5 - SubAgent完成并返回
**时间**: 15:05:28 → 15:05:43 (14.6秒)
**执行者**: intent-analyzer (SubAgent)
**Token消耗**: 输入3,278 + 输出241 = 3,519 tokens
#### 输入
```
[SystemMessage] intent-analyzer的系统提示词
[HumanMessage] "分析研究问题并生成搜索查询"
[之前的所有消息和工具调用...]
[ToolMessage] "Updated file /search_queries.json" ✅
```
#### SubAgent的思考过程
SubAgent看到
1. 文件已成功写入
2. 任务已完成生成了3个查询
3. 可以总结并返回结果
#### 输出
```json
{
"content": "搜索查询已成功生成并写入`/search_queries.json`文件中。以下是生成的搜索查询:\n\n- **原始问题**: Python asyncio最佳实践\n- **领域**: 技术(编程)\n...",
"tool_calls": [] // ← 空数组,没有更多工具调用
}
```
#### 关键点
- ✅ SubAgent没有工具调用tool_calls为空
- 🔄 LangGraph检测到SubAgent完成返回结果给主Agent
- 📦 SubAgent的state更新包括/search_queries.json合并回主Agent
#### SubAgent返回机制
根据`deepagents/middleware/subagents.py:316-323`:
```python
def _return_command_with_state_update(result, tool_call_id):
# 排除messages和todos其他state都返回给主Agent
state_update = {
k: v for k, v in result.items()
if k not in ("messages", "todos")
}
return Command(update={
**state_update, # files会被合并
"messages": [ToolMessage(result["messages"][-1].text, tool_call_id)]
})
```
#### 最终State
```
虚拟文件系统 (主Agent):
├── /question.txt (主Agent写入)
├── /config.json (主Agent写入)
└── /search_queries.json (SubAgent写入已合并) ✅
```
---
## 执行流程图
```mermaid
sequenceDiagram
participant User
participant LangGraph
participant 主Agent
participant State as 虚拟文件系统
participant SubAgent as intent-analyzer
User->>LangGraph: "研究: Python asyncio最佳实践"
Note over LangGraph,主Agent: 🔵 LLM调用 #1 (8秒)
LangGraph->>主Agent: SystemMessage + HumanMessage
主Agent->>主Agent: 理解: 需执行步骤1 - 初始化
主Agent->>State: write_file(/question.txt)
主Agent->>State: write_file(/config.json)
State-->>主Agent: ToolMessage × 2
Note over LangGraph,State: State更新: files包含2个文件
Note over LangGraph,主Agent: 🔵 LLM调用 #2 (4.5秒)
LangGraph->>主Agent: 之前的消息 + ToolMessage
主Agent->>主Agent: 理解: 步骤1完成进入步骤2
主Agent->>LangGraph: task(intent-analyzer)
Note over LangGraph,SubAgent: task工具复制state给SubAgent
LangGraph->>SubAgent: 创建SubAgent (state包含2个文件)
Note over LangGraph,SubAgent: 🔵 LLM调用 #3 (2.7秒)
LangGraph->>SubAgent: SystemMessage + HumanMessage
SubAgent->>SubAgent: 理解: 需读取输入文件
SubAgent->>State: ls()
SubAgent->>State: read_file(/question.txt)
SubAgent->>State: read_file(/config.json)
State-->>SubAgent: ToolMessage × 3 ✅ 文件存在!
Note over LangGraph,SubAgent: 🔵 LLM调用 #4 (19.4秒)
LangGraph->>SubAgent: 之前的消息 + ToolMessage
SubAgent->>SubAgent: 分析问题生成3个查询
SubAgent->>State: write_file(/search_queries.json)
State-->>SubAgent: ToolMessage
Note over LangGraph,SubAgent: 🔵 LLM调用 #5 (14.6秒)
LangGraph->>SubAgent: 之前的消息 + ToolMessage
SubAgent->>SubAgent: 理解: 任务完成
SubAgent-->>LangGraph: 无工具调用 (完成)
Note over LangGraph,State: SubAgent state合并回主Agent
LangGraph->>主Agent: ToolMessage (SubAgent结果)
Note over 主Agent: 继续步骤3...
主Agent-->>User: (测试在此停止)
```
---
## Token消耗分析
| 调用 | 执行者 | 输入Token | 输出Token | 总计 | 占比 |
|------|--------|-----------|-----------|------|------|
| #1 | 主Agent | 5,920 | 103 | 6,023 | 31.2% |
| #2 | 主Agent | 6,046 | 69 | 6,115 | 31.7% |
| #3 | SubAgent | 2,724 | 49 | 2,773 | 14.4% |
| #4 | SubAgent | 2,861 | 404 | 3,265 | 16.9% |
| #5 | SubAgent | 3,278 | 241 | 3,519 | 18.2% |
| **总计** | | **20,829** | **866** | **19,295** | **100%** |
**关键观察**:
- 主Agent的Token消耗主要在系统提示词非常详细
- SubAgent的输入Token较少专用提示词更简洁
- 输出Token主要用于JSON生成调用#4
---
## 关键技术要点总结
### ✅ 成功解决的问题
1. **虚拟文件系统共享**
- SubAgent能成功读取主Agent写入的文件
- 通过state复制机制实现
2. **工具调用顺序**
- write_file在第一个响应
- task在第二个响应
- 确保state更新已应用
3. **SubAgent生命周期**
- 创建 → 接收任务描述
- 执行 → 读取文件、处理、写入结果
- 返回 → state合并回主Agent
### 🎯 设计亮点
1. **声明式流程控制**
- 通过系统提示词定义流程
- 不使用Python while循环
- LLM自主决策下一步
2. **文件驱动的状态管理**
- 所有状态通过虚拟文件系统
- 跨Agent通信通过文件
- 易于调试和追踪
3. **降级运行策略**
- 部分失败不影响整体
- 提示词中明确说明
---
## 后续步骤预测
如果测试继续运行,预期流程:
```
✅ 步骤1: 初始化 (已完成)
✅ 步骤2: 意图分析 (已完成)
⏭️ 步骤3.1: 并行搜索
- 主Agent调用search-orchestrator
- 使用Tavily API搜索3个查询
- 写入/iteration_1/search_results.json
⏭️ 步骤3.2: 来源验证
- 主Agent调用source-validator
- Tier 1-4分级
- 写入/iteration_1/sources.json
⏭️ 步骤3.3: 内容分析
- 主Agent调用content-analyzer
- 提取信息,交叉验证
- 写入/iteration_1/findings.json
⏭️ 步骤3.4: 置信度评估
- 主Agent调用confidence-evaluator
- 计算置信度 (50%+30%+20%)
- 写入/iteration_decision.json
- 决策: FINISH 或 CONTINUE
⏭️ 步骤7: 报告生成
- 主Agent调用report-generator
- 读取所有iteration数据
- 写入/final_report.md
```
---
## 性能优化建议
基于当前执行情况:
1. **系统提示词优化**
- 主Agent的提示词非常长5,920 tokens
- 可以精简部分重复说明
- 预期节省 ~20% Token
2. **并行SubAgent调用**
- 当前是串行步骤3.1 → 3.2 → 3.3
- 某些步骤可以并行(如果依赖允许)
- 预期减少 30-40% 时间
3. **缓存机制**
- 相同问题的搜索结果可缓存
- 减少API调用次数
---
## 总结
**测试成功证明**:
- 虚拟文件系统在主Agent和SubAgent之间正确共享
- 工具调用顺序控制有效
- 基于提示词的流程控制可行
🎯 **下一步工作**:
1. 完成剩余SubAgent的测试
2. 实现完整的端到端流程
3. 添加错误处理和降级策略
4. 性能优化
📊 **当前进度**: 2/7步 (28.6%)
- ✅ 步骤1: 初始化
- ✅ 步骤2: 意图分析
- ⏳ 步骤3-7: 待实现
---
**生成时间**: 2025-10-31
**测试数据**: `llm_calls_20251031_150543.json`