| # 开源盘古 Embedded-7B-DeepDiver |
| 中文 | [English](README_EN.md) |
| 📑[技术报告](https://ai.gitcode.com/ascend-tribe/openPangu-Embedded-7B-DeepDiver/blob/main/docs/openpangu-deepdiver-v2-tech-report.pdf) |
|
|
|
|
| ## 1. 简介 |
| DeepDiver是openPangu系列中定位深度信息获取与处理的Agent,支持原生 Multi-Agent System(MAS),用于复杂知识问答与长文调研报告写作。 |
|
|
| ### 特性 |
| - 🔍 支持QA模式:回答100步+复杂知识性问题 |
| - ✍️ 支持长文写作模式:撰写3w+字文章与报告 |
| - 🔄 支持自适应模式:根据用户问题自动选择知识问答模式或长文写作模式 |
|
|
| ## 2. 评测结果 |
|
|
| | 测评集 | 测评指标 | openPangu-7B-DeepDiver| |
| | :------------: | :-----------------: | :--------: | |
| | **BrowseComp-zh** | Acc | 18.3 | |
| | **BrowseComp-en** | Acc | 8.3 | |
| |**XBench-DeepSearch** | Acc | 39.0 | |
|
|
| 注:上表仅展示复杂问答的结果,长文调研的评测结果请参考[技术报告](https://ai.gitcode.com/ascend-tribe/openPangu-Embedded-7B-DeepDiver/blob/main/docs/openpangu-deepdiver-v2-tech-report.pdf) |
|
|
| ## 3. 快速部署 |
|
|
| ### 3.1 环境准备 |
|
|
| ```bash |
| # 克隆并安装 |
| git clone <repository-url> |
| cd deepdiver_v2 |
| pip install -r requirements.txt |
| ``` |
|
|
| ### 3.2 部署推理服务 |
|
|
| #### 拉取镜像 |
|
|
| ``` |
| docker pull quay.io/ascend/vllm-ascend:v0.9.2rc1 |
| ``` |
|
|
| 或按照[官方文档](https://vllm-ascend.readthedocs.io/en/stable/installation.html)手动构建 docker 容器。 |
|
|
| #### 运行容器 |
|
|
| ``` |
| docker run -itd --name vllm-deepdiver \ |
| --network host \ |
| --device /dev/davinci0 \ |
| --device /dev/davinci1 \ |
| --device /dev/davinci2 \ |
| --device /dev/davinci3 \ |
| --device /dev/davinci4 \ |
| --device /dev/davinci5 \ |
| --device /dev/davinci6 \ |
| --device /dev/davinci7 \ |
| -u root \ |
| --device /dev/davinci_manager \ |
| --device /dev/devmm_svm \ |
| --device /dev/hisi_hdc \ |
| -v /usr/local/dcmi:/usr/local/dcmi:ro \ |
| -v /usr/local/Ascend/driver/tools/hccn_tool:/usr/local/Ascend/driver/tools/hccn_tool:ro \ |
| -v /usr/local/bin/npu-smi:/usr/local/bin/npu-smi:ro \ |
| -v /usr/local/Ascend/driver/lib64/:/usr/local/Ascend/driver/lib64/:ro \ |
| -v /usr/local/Ascend/driver/version.info:/usr/local/Ascend/driver/version.info:ro \ |
| -v /etc/ascend_install.info:/etc/ascend_install.info:ro \ |
| -v /usr/local/Ascend/firmware:/usr/local/Ascend/firmware:ro \ |
| -v /data:/data:ro \ |
| -v /home/work:/home/work \ # 配置一个可读写的工作目录 |
| quay.io/ascend/vllm-ascend:v0.9.2rc1 |
| ``` |
|
|
| #### 进入容器 |
|
|
|
|
| ``` |
| docker exec -itu root vllm-deepdiver bash |
| ``` |
|
|
| 注意:必须使用 `-itu root`。 |
|
|
| #### 复制 Pangu 的 modeling 文件 |
|
|
| `open_pangu.py` 和 `__init__.py` 可以在[这里](https://ai.gitcode.com/ascend-tribe/openpangu-embedded-7b-model/tree/main/inference/vllm_ascend/models)找到。 |
|
|
| ``` |
| cp ./vllm_ascend/open_pangu.py /vllm-workspace/vllm-ascend/vllm_ascend/models/ |
| cp ./vllm_ascend/__init__.py /vllm-workspace/vllm-ascend/vllm_ascend/models/ |
| ``` |
|
|
| #### 启动部署 |
|
|
| ``` |
| PRECHECKPOINT_PATH="path/to/deepdiver_model" |
| |
| export VLLM_USE_V1=1 |
| |
| export VLLM_WORKER_MULTIPROC_METHOD=fork |
| # export ASCEND_RT_VISIBLE_DEVICES=0,1,2,3,4,5,6,7 |
| |
| vllm serve $PRECHECKPOINT_PATH \ |
| --served-model-name ${SERVED_MODEL_NAME:=pangu_auto} \ |
| --tensor-parallel-size ${tensor_parallel_size:=8} \ |
| --trust-remote-code \ |
| --host 127.0.0.1 \ |
| --port 8888 \ |
| --max-num-seqs 256 \ |
| --max-model-len ${MAX_MODEL_LEN:=131072} \ |
| --max-num-batched-tokens ${MAX_NUM_BATCHED_TOKENS:=4096} \ |
| --tokenizer-mode "slow" \ |
| --dtype bfloat16 \ |
| --distributed-executor-backend mp \ |
| --gpu-memory-utilization 0.93 \ |
| ``` |
|
|
| #### 测试部署 |
|
|
| ``` |
| curl -X POST http://127.0.0.1:8888/v1/completions -H "Content-Type: application/json" -d '{ |
| "model": "pangu_auto", |
| "prompt": ["Tell me who you are?"], |
| "max_tokens": 50 |
| }' |
| ``` |
|
|
| ### 3.3 实现所需工具 |
|
|
| 在启动服务器前,你需要为 web search 与 URL 抓取工具实现自定义逻辑。 |
|
|
| #### Web Search(`_generic_search`) |
|
|
| 位置:`src/tools/mcp_tools.py` - `_generic_search` 方法 |
|
|
| 将 `NotImplementedError` 替换为你的搜索工具实现: |
|
|
| ```python |
| def _generic_search(self, query: str, max_results: int, config: Dict[str, Any]) -> MCPToolResult: |
| """Your custom search implementation - based on the commented code example""" |
| try: |
| # Example implementation for search API: |
| url = config.get('base_url', 'https://api.search-provider.com/search') |
| payload = json.dumps({"q": query, "num": max_results}) |
| api_keys = config.get('api_keys', []) |
| headers = { |
| 'X-API-KEY': random.choice(api_keys), |
| 'Content-Type': 'application/json' |
| } |
| |
| response = requests.post(url, data=payload, headers=headers) |
| response.raise_for_status() |
| |
| # Transform your API response to required format |
| search_results = { |
| "organic": [ |
| { |
| "title": result["title"], |
| "link": result["link"], |
| "snippet": result["snippet"], |
| "date": result.get("date", "unknown") |
| } |
| for result in response.json().get("organic", []) |
| ] |
| } |
| |
| return MCPToolResult(success=True, data=search_results) |
| |
| except Exception as e: |
| return MCPToolResult(success=False, error=f"Generic search failed: {e}") |
| ``` |
|
|
| #### URL Crawler(`url_crawler` 与 `_content_extractor`) |
| |
| 位置:`src/tools/mcp_tools.py` - `_content_extractor` |
|
|
| 将 `NotImplementedError` 部分替换为你的网页抓取工具实现: |
|
|
| ```python |
| # Example implementation for content extractor: |
| crawler_url = f"{crawler_config.get('base_url', 'https://api.content-extractor.com')}/{url}" |
| response = requests.get(crawler_url, headers=headers, timeout=crawler_config.get('timeout', 30)) |
| response.raise_for_status() |
| |
| content = response.text |
| |
| # Truncate if needed |
| if max_tokens and len(content.split()) > max_tokens: |
| words = content.split()[:max_tokens] |
| content = ' '.join(words) + '...' |
| |
| return MCPToolResult(success=True, data=content) |
| ``` |
|
|
| #### ⚠️ 第三方服务提示 |
|
|
| 重要:搜索与抓取工具使用外部 API 由用户自行选择和实现。我们不对以下情况负责: |
| - 与第三方服务相关的隐私/安全问题 |
| - 搜索/抓取活动的合规性 |
| - 内容准确性或版权问题 |
| - API 停机或变更 |
|
|
| 使用这些服务需自担风险。请查看其条款与隐私政策。 |
|
|
| ### 3.4 必要配置 |
|
|
| #### 配置 .env 文件 |
| 复制 `env.template` 到 `config/.env` 并配置如下选项: |
|
|
| ```bash |
| # LLM Service |
| MODEL_REQUEST_URL=http://localhost:8888/v1/chat/completions # 你的 LLM endpoint |
| |
| # Agent 限制 |
| PLANNER_MODE=auto # 在 auto、writing 或 qa 模式间切换 |
| |
| # 外部 API(先实现函数) |
| SEARCH_ENGINE_BASE_URL= # 搜索 API endpoint |
| SEARCH_ENGINE_API_KEYS= # 搜索 API keys |
| URL_CRAWLER_BASE_URL= # URL Crawler API endpoint |
| URL_CRAWLER_API_KEYS= # URL Crawler API keys |
| ``` |
|
|
| ⚠️ 注意: |
| - 请将上一步部署的推理服务 URL 配置到 `MODEL_REQUEST_URL` |
| - 在 `PLANNER_MODE` 中指定模式。`auto` 会自动决策回答复杂问题或生成长文;若希望优先长文写作,可设置为 `writing`;若希望专注解决高难度问题,可设置为 `qa` |
|
|
| ### 3.5 启动工具服务 |
|
|
| ```bash |
| python src/tools/mcp_server_standard.py |
| ``` |
|
|
| ### 3.6 运行Demo |
|
|
| ```bash |
| # 交互模式 |
| python cli/demo.py |
| |
| # 单次查询 |
| python cli/demo.py -q "$your_query" |
| ``` |
|
|
| 基于上述步骤可以快速运行DeepDiver,如果需要二次开发,可以参考[章节4](#4-自定义工具开发指南)和[5](#5-个性化配置) |
|
|
| ## 4. 自定义工具开发指南 |
|
|
| 当前工具主要分为内置工具和外部MCP工具,内部工具主要包括分发任务,思考/反思等,外部MCP工具则是一些延伸LLM能力的工具,如搜索互联网,爬取链接,下载和读写文件等。 |
|
|
| ### 4.1 已实现的工具类别 |
|
|
| #### A. 外部MCP工具 |
| Web Search 与数据采集: |
| - `batch_web_search`:多查询 web 搜索 |
| - `url_crawler`:从 URL 抽取内容 |
| - `download_files`:从 URL 下载文件 |
|
|
| 文件操作: |
| - `file_read`、`file_write`:基础文件 I/O |
| - `list_workspace`:目录列表 |
|
|
| 文档处理与内容创作: |
| - `document_qa`:针对特定文档问答 |
| - `document_extract`:多格式文本抽取 |
| - `section_writer`:结构化内容生成 |
|
|
| #### B. 内置工具 |
| - `think`、`reflect`:推理与规划 |
| - `task_done`:任务完成汇报 |
| - `assign_task_xxx`: 分发任务并创建子智能体 |
|
|
| ### 4.2 开发并集成新的外部MCP工具 |
|
|
| #### A. 实现新的MCP工具 |
| 位置:`src/tools/mcp_tools.py` - 在 `MCPTools` 类中添加方法 |
|
|
| ```python |
| def your_new_tool(self, param1: str, param2: int) -> MCPToolResult: |
| """ |
| Description of what your tool does. |
| |
| Args: |
| param1: Description of parameter 1 |
| param2: Description of parameter 2 |
| |
| Returns: |
| MCPToolResult: Standardized result format |
| """ |
| try: |
| # Your tool implementation here |
| result_data = { |
| "output": "Tool result", |
| "processed_items": param2 |
| } |
| |
| return MCPToolResult( |
| success=True, |
| data=result_data, |
| metadata={"tool_name": "your_new_tool"} |
| ) |
| |
| except Exception as e: |
| logger.error(f"Tool execution failed: {e}") |
| return MCPToolResult( |
| success=False, |
| error=f"Tool failed: {str(e)}" |
| ) |
| ``` |
|
|
| #### B. 在服务器中注册工具 |
|
|
| ##### 添加工具 Schema |
| 位置:`src/tools/mcp_tools.py` - 添加到 `MCP_TOOL_SCHEMAS` 字典 |
|
|
| ```python |
| MCP_TOOL_SCHEMAS = { |
| # ... existing tools ... |
| |
| "your_new_tool": { |
| "name": "your_new_tool", |
| "description": "Brief description of what your tool does", |
| "inputSchema": { |
| "type": "object", |
| "properties": { |
| "param1": { |
| "type": "string", |
| "description": "Description of parameter 1" |
| }, |
| "param2": { |
| "type": "integer", |
| "default": 10, |
| "description": "Description of parameter 2" |
| } |
| }, |
| "required": ["param1"] |
| } |
| } |
| } |
| ``` |
|
|
| ##### 注册工具函数 |
| 位置:`src/tools/mcp_server_standard.py` - 添加到 `get_tool_function()` |
|
|
| ```python |
| def get_tool_function(tool_name: str): |
| """Get the actual function for a tool""" |
| tool_map = { |
| # ... existing tools ... |
| "your_new_tool": lambda tools, **kwargs: tools.your_new_tool(**kwargs), |
| } |
| return tool_map.get(tool_name) |
| ``` |
|
|
| #### C. 让特定智能体可使用工具 |
| 工具对各智能体的可见性由 MCP client 中的预定义工具集控制。 |
|
|
| 位置:`src/tools/mcp_client.py` - 修改各智能体的工具集 |
|
|
| ```python |
| # Define which MCP server tools each agent can access |
| PLANNER_AGENT_TOOLS = [ |
| "download_files", |
| "document_qa", |
| "file_read", |
| "file_write", |
| "str_replace_based_edit_tool", |
| "list_workspace", |
| "file_find_by_name", |
| "your_new_tool", # Add your new tool here |
| ] |
| |
| INFORMATION_SEEKER_TOOLS = [ |
| "batch_web_search", |
| "url_crawler", |
| "document_extract", |
| "document_qa", |
| "download_files", |
| "file_read", |
| "file_write", |
| "str_replace_based_edit_tool", |
| "list_workspace", |
| "file_find_by_name", |
| "your_new_tool", # Add your new tool here if needed |
| ] |
| |
| WRITER_AGENT_TOOLS = [ |
| "file_read", |
| "list_workspace", |
| "file_find_by_name", |
| "search_result_classifier", |
| "section_writer", |
| "concat_section_files", |
| # Add your tool if the writer agent needs it |
| ] |
| ``` |
|
|
| ### 4.3 添加内置智能体工具/函数 |
|
|
| #### A. 带有真实返回的工具/函数 |
| DeepDiver中的agent,如planner,集成了`assign_subjective_task_to_writer`, `assign_multi_objective_tasks_to_info_seeker` 等内置函数作为工具, 这类函数除了具体实现之外,还需要使用`_build_agent_specific_tool_schemas()` 添加专属的tool schema。 |
|
|
| 位置:`src/agents/your_agent.py` |
|
|
| ```python |
| def _build_agent_specific_tool_schemas(self) -> List[Dict[str, Any]]: |
| """Add built-in agent functions (not MCP server tools)""" |
| |
| # Get base schemas from MCP server via client |
| schemas = super()._build_agent_specific_tool_schemas() |
| |
| # Add agent-specific built-in functions like task assignment, completion reporting |
| builtin_functions = [ |
| { |
| "type": "function", |
| "function": { |
| "name": "agent_specific_task_done", |
| "description": "Report task completion for this agent", |
| "parameters": { |
| "type": "object", |
| "properties": { |
| "result": {"type": "string", "description": "Task result"}, |
| "status": {"type": "string", "description": "Completion status"} |
| }, |
| "required": ["result", "status"] |
| } |
| } |
| } |
| ] |
| |
| schemas.extend(builtin_functions) |
| return schemas |
| ``` |
|
|
| #### B. 带有伪返回的内置工具 |
| DeepDiver中的cognitive tools,比如think和reflect等,这些工具实际没有具体实现,agent在调用这些工具时通过生成工具入参,就已经完成了工具的调用。可以直接在模型生成完入参后,使用类似以下方法进行返回,继续让模型完成后续工作 (参考`planner_agent.py` 中`_execute_react_loop()`的实现): |
|
|
| ```python |
| if tool_call["name"] in ["think", "reflect"]: |
| tool_result = {"tool_results": "You can proceed to invoke other tools if needed. "} |
| ``` |
|
|
| 同理,这种内置工具也需要使用`_build_agent_specific_tool_schemas()` 添加专属的tool schema。 |
|
|
|
|
| ## 5. 个性化配置 |
|
|
| ### 5.1 Client 配置 |
|
|
| 复制 `env.template` 到 `config/.env` 并配置如下选项: |
|
|
| ```bash |
| # LLM Service |
| MODEL_REQUEST_URL=http://localhost:8000 # 你的 LLM endpoint |
| MODEL_REQUEST_TOKEN=your-token # LLM auth token |
| MODEL_NAME=pangu_auto # 模型名 |
| MODEL_TEMPERATURE=0.3 # 随机度(0.0-1.0) |
| MODEL_MAX_TOKENS=8192 # 最大回复长度 |
| MODEL_REQUEST_TIMEOUT=60 # 请求超时(秒) |
| |
| # Agent 限制 |
| PLANNER_MAX_ITERATION=40 # Planner 最大 ReAct 步数 |
| INFORMATION_SEEKER_MAX_ITERATION=30 # 信息搜集最大 ReAct 步数 |
| WRITER_MAX_ITERATION=40 # Writer 最大 ReAct 步数 |
| PLANNER_MODE=auto # auto / 长文优先 / qa 优先 |
| |
| # MCP Server |
| MCP_SERVER_URL=http://localhost:6274/mcp # MCP server endpoint |
| MCP_USE_STDIO=false # 使用 stdio 或 HTTP |
| |
| # 外部 API(先实现函数) |
| SEARCH_ENGINE_BASE_URL= # 搜索 API endpoint |
| SEARCH_ENGINE_API_KEYS= # 搜索 API keys |
| URL_CRAWLER_BASE_URL= # URL Crawler API endpoint |
| URL_CRAWLER_API_KEYS= # URL Crawler API keys |
| URL_CRAWLER_MAX_TOKENS=100000 # URL Crawler 内容最大长度 |
| |
| # 存储路径 |
| TRAJECTORY_STORAGE_PATH=./workspace # Agent工作目录 |
| REPORT_OUTPUT_PATH=./report # 报告输出目录 |
| DOCUMENT_ANALYSIS_PATH=./doc_analysis # 文档分析目录 |
| |
| # 系统 |
| DEBUG_MODE=false # 是否开启调试日志 |
| MAX_RETRIES=3 # API 重试次数 |
| TIMEOUT=30 # 通用超时(秒) |
| ``` |
|
|
| ### 5.2 Server 配置(server_config.yaml) |
| |
| `server_config.yaml` 控制服务器行为、工具限流与运行设置: |
|
|
| #### 核心服务器设置 |
|
|
| ```yaml |
| server: |
| host: "127.0.0.1" # 服务器绑定地址 |
| port: 6274 # 端口 |
| debug_mode: false # 调试日志 |
| session_ttl_seconds: 21600 # 会话过期(6小时) |
| max_sessions: 1000 # 并发会话上限 |
| ``` |
|
|
| #### 工具限流 |
|
|
| 对所有会话的外部 API 使用进行控制: |
|
|
| ```yaml |
| tool_rate_limits: |
| batch_web_search: |
| requests_per_minute: 9000 # 每分钟限制 |
| burst_limit: 35 # 短时突发 |
| |
| url_crawler: |
| requests_per_minute: 9000 |
| burst_limit: 60 |
| ``` |
|
|
| #### 会话管理 |
|
|
| ```yaml |
| server: |
| cleanup_interval_seconds: 600 # 清理过期会话(5分钟) |
| enable_session_keepalive: true # 长时操作期间保活 |
| keepalive_touch_interval: 300 # 保活触发间隔(秒) |
| ``` |
|
|
| #### 安全与性能 |
|
|
| ```yaml |
| server: |
| request_timeout_seconds: 1800 # 请求超时 |
| max_request_size_mb: 1000 # 最大请求体 |
| rate_limit_requests_per_minute: 300000 # 每 IP 限流 |
| ``` |
|
|
| 配置文件包含对每项设置的详细注释。请根据你的部署需求与外部 API 限额进行调整。 |
|
|
| ## 6. 模型许可证 |
|
|
| 除文件中对开源许可证另有约定外,openPangu-Embedded-7B-DeepDiver 模型根据 OPENPANGU MODEL LICENSE AGREEMENT VERSION 1.0 授权,旨在允许使用并促进人工智能技术的进一步发展。有关详细信息,请参阅模型存储库根目录中的 [LICENSE](LICENSE) 文件。 |
|
|
| ## 7. 安全提示与免责声明 |
| 由于 openPangu-Embedded-7B-DeepDiver 模型和框架所依赖的技术固有的技术限制,以及人工智能生成的内容是由盘古自动生成的,华为无法对以下事项做出任何保证: |
|
|
| - 尽管该模型的输出由 AI 算法生成,但不能排除某些信息可能存在缺陷、不合理或引起不适的可能性,生成的内容不代表华为的态度或立场; |
| - 无法保证该模型 100% 准确、可靠、功能齐全、及时、安全、无错误、不间断、持续稳定或无任何故障; |
| - 该模型的输出内容不构成任何建议或决策,也不保证生成的内容的真实性、完整性、准确性、及时性、合法性、功能性或实用性。生成的内容不能替代医疗、法律等领域的专业人士回答您的问题。生成的内容仅供参考,不代表华为的任何态度、立场或观点。您需要根据实际情况做出独立判断,华为不承担任何责任; |
| - DeepDiver MAS系统的组件间通信不包含内置的数据加密或认证(如 tokens、签名)。你需要自行评估安全需求并实施相应防护(例如运行在加密网络中、加入 SSL/TLS、强制组件身份校验); |
| - 由于缺乏加密/认证导致的任何安全事件(数据泄露、未授权访问、业务损失)由使用方自行承担。项目开发者不承担责任。 |
|
|
| ## 8. 反馈 |
|
|
| 如果有任何意见和建议,请提交issue或联系 openPangu@huawei.com。 |
|
|
| --- |