Files
deepagents----/开发文档_V1.md
2025-11-02 18:06:38 +08:00

18 KiB
Raw Permalink Blame History

Deep Research System - 开发文档

框架: DeepAgents (LangChain) | 最后更新: 2025-10-31


📖 文档说明

本文档专注于技术实现细节

相关文档


系统架构

Agent 结构1主 + 6子

ResearchCoordinator (主Agent)
├── intent-analyzer (意图分析→search_queries.json)
├── search-orchestrator (并行搜索→search_results.json)
├── source-validator (来源验证→sources.json)
├── content-analyzer (内容分析→findings.json)
├── confidence-evaluator (置信度评估→confidence.json + iteration_decision.json)
└── report-generator (报告生成→final_report.md)

执行流程

用户输入 → ResearchCoordinator

【第1步】调用 intent-analyzer → /search_queries.json

【迭代循环】(第N轮)
  【第2步】调用 search-orchestrator → /iteration_N/search_results.json
  【第3步】调用 source-validator → /iteration_N/sources.json
  【第4步】调用 content-analyzer → /iteration_N/findings.json
  【第5步】调用 confidence-evaluator → /iteration_N/confidence.json
                                        /iteration_decision.json
  【第6步】主Agent读取 iteration_decision.json
    ├─ CONTINUE → 生成补充查询 → 回到第2步
    └─ FINISH → 进入第7步

【第7步】调用 report-generator → /final_report.md

关键要点:

  • 主Agent通过系统提示词引导不是Python while循环
  • 通过读取文件判断状态,不是函数返回值
  • SubAgent通过虚拟文件系统共享数据

技术栈

环境配置

虚拟环境: deep_research_env (Python 3.11.x, Anaconda)

创建虚拟环境(如果还未创建)

# 创建虚拟环境
conda create -n deep_research_env python=3.11 -y

# 激活虚拟环境
conda activate deep_research_env

安装依赖包

requirements.txt

# 核心框架
deepagents>=0.1.0
langchain>=0.3.0
langchain-openai>=0.2.0
langchain-community>=0.3.0
langgraph>=0.2.0

# 搜索工具
tavily-python>=0.5.0

# 环境变量管理
python-dotenv>=1.0.0

# CLI和进度显示
rich>=13.0.0
click>=8.1.0

# 工具和实用库
typing-extensions>=4.12.0
pydantic>=2.0.0

安装命令:

# 确保已激活虚拟环境
conda activate deep_research_env

# 安装依赖
pip install -r requirements.txt

# 验证安装
python -c "import deepagents; print('DeepAgents installed successfully')"

核心框架

from deepagents import create_deep_agent
from langchain_openai import ChatOpenAI

# DeepAgents 自动附加三个核心中间件:
# - TodoListMiddleware → write_todos 工具
# - FilesystemMiddleware → ls, read_file, write_file, edit_file, glob, grep
# - SubAgentMiddleware → task 工具

API配置

.env 文件:

DASHSCOPE_API_KEY=your_dashscope_key_here
TAVILY_API_KEY=your_tavily_key_here

src/config.py

import os
from dotenv import load_dotenv
from langchain_openai import ChatOpenAI

load_dotenv()

llm = ChatOpenAI(
    model="qwen-max",
    openai_api_key=os.environ.get("DASHSCOPE_API_KEY"),
    openai_api_base="https://dashscope.aliyunapis.com/compatible-mode/v1",
    timeout=60,
    max_retries=2
)

TAVILY_API_KEY = os.environ.get("TAVILY_API_KEY")

ERROR_HANDLING_CONFIG = {
    "max_retries": 3,
    "retry_delay": 1.0,
    "backoff_factor": 2.0,
    "timeout": {"search": 30, "subagent": 120, "total": 600}
}

安全:

  • ⚠️ 不要提交 .env 到版本控制
  • .gitignore 中添加 .env
  • 提供 .env.example 模板

虚拟文件系统

/
├── question.txt                 # 原始问题
├── config.json                  # 研究配置
├── search_queries.json          # 搜索查询列表
├── iteration_1/
│   ├── search_results.json     # 搜索结果
│   ├── sources.json            # 验证的来源Tier分级
│   ├── findings.json           # 分析发现
│   └── confidence.json         # 置信度评估
├── iteration_2/
│   └── ...
├── iteration_decision.json     # {"decision": "CONTINUE/FINISH", "reason": "..."}
└── final_report.md             # 最终报告

config.json 格式:

{
  "depth_mode": "standard",
  "target_confidence": 0.7,
  "min_tier": 2,
  "max_iterations": 3,
  "parallel_searches": 5,
  "report_format": "technical"
}

SubAgent 配置

配置格式规范

subagents = [
    {
        "name": "subagent-name",          # 必须kebab-case格式
        "description": "简短描述",         # 必须
        "system_prompt": "详细提示词",     # 必须不是prompt
        "tools": [tool1, tool2],          # 可选:工具实例列表
        "model": "openai:gpt-4o"          # 可选
    }
]

6个SubAgent配置示例

from deepagents import create_deep_agent
from src.tools.search_tools import create_batch_search_tool

batch_internet_search = create_batch_search_tool()

subagents = [
    {
        "name": "intent-analyzer",
        "description": "分析用户意图并生成搜索查询",
        "system_prompt": """你是意图分析专家。

【任务】
1. 读取 /question.txt 和 /config.json
2. 识别领域类型technical/academic/general
3. 提取3-8个核心关键词
4. 根据 parallel_searches 数量生成查询

【输出】写入 /search_queries.json
{
  "domain": "technical",
  "keywords": ["关键词1", "关键词2"],
  "queries": ["查询1", "查询2", "查询3"]
}""",
        "tools": []
    },

    {
        "name": "search-orchestrator",
        "description": "执行并行搜索并聚合去重结果",
        "system_prompt": """你是搜索协调专家。

【任务】
1. 读取 /search_queries.json
2. 使用 batch_internet_search 工具执行批量搜索
3. 聚合结果按URL去重
4. 标准化格式

【输出】写入 /iteration_N/search_results.json
[
  {
    "url": "https://...",
    "title": "...",
    "snippet": "...",
    "published_date": "YYYY-MM-DD",
    "source_type": "official_doc|blog|forum|paper"
  }
]""",
        "tools": [batch_internet_search]
    },

    {
        "name": "source-validator",
        "description": "验证来源可信度并进行Tier分级",
        "system_prompt": """你是来源验证专家。

【Tier分级标准】
- Tier 1 (0.9-1.0): 官方文档、权威期刊、标准组织
- Tier 2 (0.7-0.9): MDN、Stack Overflow高分、大厂博客
- Tier 3 (0.5-0.7): 高质量教程、维基百科
- Tier 4 (0.3-0.5): 论坛、个人博客

【任务】
1. 读取 /iteration_N/search_results.json
2. 为每个来源分配Tier级别和分数
3. 统计质量指标
4. 判断是否满足要求总数≥5, Tier1-2≥3

【输出】写入 /iteration_N/sources.json
{
  "sources": [{"url": "...", "tier": 1, "tier_score": 0.95, ...}],
  "quality_check": {
    "total_count": 18,
    "tier1_count": 5,
    "tier2_count": 8,
    "meets_requirement": true
  }
}""",
        "tools": []
    },

    {
        "name": "content-analyzer",
        "description": "提取内容、交叉验证并检测矛盾",
        "system_prompt": """你是内容分析专家。

【任务】
1. 读取 /iteration_N/sources.json
2. 对每个来源提取关键信息
3. 按主题分组
4. 交叉验证:多个来源支持同一结论
5. 检测矛盾:不同来源对同一事实的冲突
6. 识别知识缺口

【输出】写入 /iteration_N/findings.json
{
  "findings": [
    {
      "topic": "主题1",
      "statement": "关键发现",
      "supporting_sources": ["url1", "url2"],
      "contradicting_sources": [],
      "evidence": ["证据1", "证据2"]
    }
  ],
  "contradictions": [...],
  "knowledge_gaps": ["缺失信息1", "缺失信息2"]
}""",
        "tools": [batch_internet_search]
    },

    {
        "name": "confidence-evaluator",
        "description": "计算置信度并决定是否继续迭代",
        "system_prompt": """你是置信度评估专家。

【置信度公式】
置信度 = (来源可信度 × 50%) + (交叉验证 × 30%) + (时效性 × 20%)

【评分细则】
- 来源可信度: Tier1=0.95, Tier2=0.80, Tier3=0.65, Tier4=0.45 (平均值)
- 交叉验证: 1源=0.4, 2-3源=0.7, 4+源=1.0, 有矛盾-0.3
- 时效性: <6月=1.0, 6-12月=0.9, 1-2年=0.7, 2-3年=0.5, >3年=0.3

【任务】
1. 读取 /iteration_N/sources.json 和 /iteration_N/findings.json
2. 为每个finding计算置信度
3. 计算整体平均置信度
4. 读取 /config.json 获取 target_confidence 和 max_iterations
5. 决策是否继续迭代

【决策逻辑】
- overall_confidence ≥ target → FINISH
- 未达标 且 current_iteration < max → CONTINUE
- 达到 max → FINISH标记未达标

【输出】
1. 写入 /iteration_N/confidence.json
   {"findings_confidence": [...], "overall_confidence": 0.78}
2. 写入 /iteration_decision.json
   {"decision": "CONTINUE", "current_iteration": 1, "reason": "..."}""",
        "tools": []
    },

    {
        "name": "report-generator",
        "description": "生成技术或学术研究报告",
        "system_prompt": """你是报告生成专家。

【任务】
1. 读取所有迭代的数据:
   - /question.txt
   - /config.json
   - /iteration_*/findings.json
   - /iteration_*/sources.json
   - /iteration_*/confidence.json
2. 根据 report_format 选择报告结构technical/academic
3. 生成完整报告

【技术报告结构】
# 技术研究报告:{主题}
## 📊 研究元信息
## 🎯 执行摘要
## 🔍 关键发现
## 📊 来源可信度矩阵
## ⚠️ 矛盾和不确定性
## 📚 参考文献

【输出】写入 /final_report.md""",
        "tools": []
    }
]

创建主Agent

from src.config import llm

coordinator = create_deep_agent(
    model=llm,
    system_prompt=COORDINATOR_SYSTEM_PROMPT,  # 见下一章节
    tools=[],
    subagents=subagents
)

主Agent系统提示词核心

COORDINATOR_SYSTEM_PROMPT = """
你是深度研究协调专家通过调用SubAgent和管理虚拟文件系统完成复杂研究任务。

# 核心原则
- 通过 task 工具调用SubAgent
- 通过 read_file 读取SubAgent的输出
- 通过 write_todos 管理任务进度
- 根据文件内容自主决策下一步不是Python循环

# 执行流程

## 初始化
1. 读取 /question.txt 和 /config.json
2. 创建任务列表write_todos([{"task": "意图分析", "status": "pending"}, ...])

## 第1步意图分析
1. 更新进度write_todos([{"task": "意图分析", "status": "in_progress"}, ...])
2. 调用task(name="intent-analyzer")
3. 读取read_file("/search_queries.json")
4. 完成write_todos([{"task": "意图分析", "status": "completed"}, ...])

## 第2-6步研究迭代最多 max_iterations 轮)

**依次执行SubAgent**
1. search-orchestrator → /iteration_N/search_results.json
2. source-validator → /iteration_N/sources.json
3. content-analyzer → /iteration_N/findings.json
4. confidence-evaluator → /iteration_N/confidence.json + /iteration_decision.json

**迭代决策:**
读取 /iteration_decision.json
- decision="FINISH" → 跳转第7步
- decision="CONTINUE" 且 current_iteration < max → 生成补充查询回到步骤2.1
- 达到 max_iterations → 跳转第7步

## 第7步生成报告
1. 更新进度
2. 调用task(name="report-generator")
3. 读取:/final_report.md
4. 返回报告路径给用户

# 错误处理

## SubAgent调用失败
- 超时 → 降低并行度重试1次
- API限流 → 等待30秒重试1次
- 其他 → 记录错误,继续流程(降级运行)

## 搜索质量不足
- meets_requirement: false → 生成更广泛查询重新搜索最多扩展2次

## 置信度无法达标
- 达到最大迭代轮次仍未达标 → 强制结束,在报告中标注未达标

## 部分失败容错
- 5个查询中2个失败 → 使用3个成功的继续
- 在报告元信息中记录失败统计

# 进度监控
同时维护 /progress.json
{
  "current_step": "search-orchestrator",
  "iteration": 2,
  "total_iterations": 3,
  "estimated_completion": "60%",
  "eta_seconds": 180
}

# 重要提醒
1. **不要使用Python while循环** - LangGraph会持续调用你
2. **通过文件判断状态** - 不是返回值
3. **自主决策每一步** - 你自己判断
4. **失败不致命** - 降级运行,保证能产出报告
"""

自定义工具:批量并行搜索

# src/tools/search_tools.py

import os
from concurrent.futures import ThreadPoolExecutor, as_completed
from langchain_community.tools.tavily_search import TavilySearchResults
from langchain.tools import tool
from typing import List, Dict

def create_batch_search_tool():
    tavily = TavilySearchResults(
        api_key=os.environ.get("TAVILY_API_KEY"),
        max_results=10,
        search_depth="advanced",
        include_raw_content=False
    )

    @tool
    def batch_internet_search(queries: List[str]) -> List[Dict]:
        """
        并行执行多个搜索查询并聚合去重结果

        Args:
            queries: 搜索查询列表

        Returns:
            聚合的搜索结果列表(已去重、按相关性排序)
        """
        def search_single(query: str) -> List[Dict]:
            try:
                results = tavily.invoke(query)
                for r in results:
                    r['query'] = query
                return results
            except Exception as e:
                print(f"搜索失败 '{query}': {e}")
                return []

        all_results = []
        with ThreadPoolExecutor(max_workers=5) as executor:
            future_to_query = {executor.submit(search_single, q): q for q in queries}

            for future in as_completed(future_to_query):
                query = future_to_query[future]
                try:
                    results = future.result(timeout=30)
                    all_results.extend(results)
                except Exception as e:
                    print(f"查询超时/失败 '{query}': {e}")

        # URL去重保留相关性更高的
        seen_urls = {}
        for result in all_results:
            url = result.get('url')
            score = result.get('score', 0)
            if url not in seen_urls or seen_urls[url]['score'] < score:
                seen_urls[url] = result

        # 按相关性分数排序
        unique_results = sorted(
            seen_urls.values(),
            key=lambda x: x.get('score', 0),
            reverse=True
        )

        return unique_results

    return batch_internet_search

# 创建工具实例
batch_internet_search = create_batch_search_tool()

为什么不需要 calculate_tier 和 calculate_confidence 工具?

  • LLM具备强大推理能力在 system_prompt 中说明标准即可
  • Tier判断需要上下文理解域名+内容类型+时间LLM更适合
  • 避免过度工具化,提高灵活性

项目结构

deep_research/
├── .env                     # 环境变量(不提交)
├── .env.example             # 环境变量模板
├── .gitignore
├── requirements.txt
├── README.md
│
├── src/
│   ├── __init__.py
│   ├── config.py            # API配置
│   ├── main.py              # CLI入口
│   │
│   ├── agents/
│   │   ├── __init__.py
│   │   ├── coordinator.py   # ResearchCoordinator主Agent
│   │   └── subagents.py     # 6个SubAgent配置
│   │
│   ├── tools/
│   │   ├── __init__.py
│   │   └── search_tools.py  # batch_internet_search
│   │
│   └── cli/
│       ├── __init__.py
│       └── commands.py      # research, config, history, resume命令
│
├── tests/
│   ├── __init__.py
│   ├── test_subagents.py
│   ├── test_tools.py
│   └── test_integration.py
│
└── outputs/
    └── .gitkeep

错误处理配置

已在 config.py 中定义:

ERROR_HANDLING_CONFIG = {
    "max_retries": 3,
    "retry_delay": 1.0,
    "backoff_factor": 2.0,
    "timeout": {
        "search": 30,
        "subagent": 120,
        "total": 600
    }
}

降级策略

场景 降级措施 影响
搜索API超时 减少并行查询数 速度变慢
高质量来源不足 降低min_tier要求 置信度降低
迭代超时 提前结束,生成报告 覆盖度降低
LLM限流 指数退避重试 延迟增加

进度跟踪

TodoListMiddleware使用

# 研究开始时
write_todos([
    {"task": "意图分析", "status": "pending"},
    {"task": "第1轮搜索", "status": "pending"},
    {"task": "第1轮来源验证", "status": "pending"},
    {"task": "第1轮内容分析", "status": "pending"},
    {"task": "第1轮置信度评估", "status": "pending"},
    {"task": "生成报告", "status": "pending"}
])

# 每完成一步更新
write_todos([
    {"task": "意图分析", "status": "completed"},
    {"task": "第1轮搜索", "status": "in_progress"},
    ...
])

CLI进度显示

使用Rich库实现实时进度

# src/cli/commands.py
from rich.console import Console
from rich.progress import Progress, SpinnerColumn, TextColumn, BarColumn

def research_command(topic: str, **options):
    console = Console()

    with Progress(
        SpinnerColumn(),
        TextColumn("[bold blue]{task.description}"),
        BarColumn(),
        TextColumn("[progress.percentage]{task.percentage:>3.0f}%"),
    ) as progress:
        research_task = progress.add_task("[cyan]深度研究中...", total=100)

        # 定期读取 /progress.json 更新进度条
        while not completed:
            progress_data = read_progress()
            progress.update(
                research_task,
                completed=progress_data['estimated_completion'],
                description=f"[cyan]{progress_data['current_step']}"
            )

🎓 参考资源


文档版本: 1.0 | 最后更新: 2025-10-31