> ## Documentation Index
> Fetch the complete documentation index at: https://langchain-docs-zh.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# 构建深度研究代理

> 本指南展示了如何使用 Deep Agents 构建多步骤网页研究智能体。该智能体将研究问题分解为聚焦的任务，委托给专用子智能体处理，并将最终发现整合为综合报告。

## 概述

本指南展示了如何使用 [Deep Agents](https://langchain-docs-zh.mintlify.site/langchain/oss/deepagents.md) 构建多步骤网页研究智能体。该智能体将研究问题分解为聚焦的任务，委托给专用子智能体处理，并将最终发现整合为综合报告。

您构建的智能体将实现以下功能：

1. 使用可选待办事项中间件规划研究
2. 将聚焦型研究任务委托给具有独立上下文隔离的子智能体
3. 随着信息收集评估搜索结果并规划下一步行动
4. 将带有规范引用的发现整合为最终报告

生成的子智能体使用 Tavily 进行网页搜索，获取完整网页内容进行分析。

### 核心概念

本教程涵盖以下内容：

* [子智能体](https://langchain-docs-zh.mintlify.site/langchain/oss/deepagents/subagents.md) 实现并行、上下文隔离的研究
* 自定义 [工具](https://langchain-docs-zh.mintlify.site/langchain/oss/langchain/tools.md) 进行网页搜索
* 使用可选 [规划工具](https://langchain-docs-zh.mintlify.site/langchain/oss/deepagents/overview.md#任务规划) 实现多步骤规划

## 先决条件

需要以下 API 密钥：

* Anthropic（Claude）或 Google（Gemini）
* [Tavily](https://www.tavily.com/)（用于网页搜索，可选；免费套餐足够）
* [LangSmith](https://smith.langchain.com)（用于追踪，若使用 SDK 可选；使用 Managed Deep Agents 时必需）

## 选择路径

本指南展示了如何使用 [Managed Deep Agents](https://docs.langchain.com/langsmith/managed-deep-agents-overview) 和 Deep Agents SDK 构建该智能体。Managed Deep Agents 允许您无需管理基础设施即可部署智能体。Deep Agents SDK 提供最大灵活性，您既可使用相同的 Deep Agents harness 部署，也可通过自定义 [LangSmith 部署](https://docs.langchain.com/langsmith/deployment) 自行托管。

> [tab] Managed Deep Agents
>
> > [!NOTE]
> >
> > 托管深度智能体目前处于 **公开的 [beta](https://docs.langchain.com/langsmith/release-stages)** 版本，部署于 [LangSmith Cloud](https://docs.langchain.com/langsmith/cloud)。
>
> ### 配置
>
> 要开始，你需要：
>
> :::python
>
> * Python 和 `uv`。
>   :::
>
> :::js
>
> * Node.js 和 npm。
>   :::
>
> * 向你的模型服务提供商申请的 API 密钥。
>
> **1. Create the project**
>
> :::python
>
> ```bash theme={null}
> uvx --from managed-deepagents mda init deep-research
> cd deep-research
> ```
>
> :::
>
> :::js
>
> ```bash npm theme={null}
> npx managed-deepagents init deep-research
> cd deep-research
> ```
>
> ```bash pnpm theme={null}
> pnpm dlx managed-deepagents init deep-research
> cd deep-research
> ```
>
> ```bash bun theme={null}
> bunx managed-deepagents init deep-research
> cd deep-research
> ```
>
> :::
>
> **2. Add API keys**
>
> 将模型提供商密钥、Tavily 密钥和 LangSmith API 密钥添加到 `.env`：
>
> > [tab] Claude
> >
> > ```text .env theme={null}
> > ANTHROPIC_API_KEY=<ANTHROPIC_API_KEY>
> > TAVILY_API_KEY=<TAVILY_API_KEY>
> > LANGSMITH_API_KEY=<LANGSMITH_API_KEY>
> > ```
>
> > [tab] Gemini
> >
> > ```text .env theme={null}
> > GOOGLE_API_KEY=<GOOGLE_API_KEY>
> > TAVILY_API_KEY=<TAVILY_API_KEY>
> > LANGSMITH_API_KEY=<LANGSMITH_API_KEY>
> > ```
>
> > [!WARNING]
> >
> > 不要将 `.env` 文件提交到版本控制。该文件包含敏感信息。
>
> **3. Install search dependencies**
>
> :::python
>
> ```bash theme={null}
> uv add tavily-python httpx markdownify
> ```
>
> :::
>
> :::js
> 本教程中的搜索工具无需额外包依赖。它使用内置 `fetch` API 和 Tavily HTTP 端点。
> :::
>
> ### 构建智能体
>
> **1. Add tools**
>
> 创建自定义搜索工具。`tavily_search` 工具使用 Tavily 进行 URL 发现，然后获取完整网页内容，使智能体能够基于完整来源进行分析而非摘要。
>
> :::python
> 创建 `tools/search.py`：
>
> ```python tools/search.py theme={null}
> import os
> from typing import Annotated, Literal
>
> import httpx
> from langchain.tools import InjectedToolArg, tool
> from markdownify import markdownify
> from tavily import TavilyClient
>
> tavily_client = TavilyClient(api_key=os.environ["TAVILY_API_KEY"])
>
>
> def fetch_webpage_content(url: str, timeout: float = 10.0) -> str:
>     """Fetch webpage and convert HTML to markdown."""
>     headers = {
>         "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36"
>     }
>     try:
>         response = httpx.get(url, headers=headers, timeout=timeout)
>         response.raise_for_status()
>         return markdownify(response.text)
>     except Exception as e:
>         return f"Error fetching {url}: {e!s}"
>
>
> @tool(parse_docstring=True)
> def tavily_search(
>     query: str,
>     max_results: Annotated[int, InjectedToolArg] = 1,
>     topic: Annotated[
>         Literal["general", "news", "finance"], InjectedToolArg
>     ] = "general",
> ) -> str:
>     """Search the web for information on a given query.
>
>     Uses Tavily to discover relevant URLs, then fetches and returns full webpage content as markdown.
>
>     Args:
>         query: Search query to execute
>         max_results: Maximum number of results to return (default: 1)
>         topic: Topic filter - 'general', 'news', or 'finance' (default: 'general')
>
>     Returns:
>         Formatted search results with full webpage content
>     """
>     search_results = tavily_client.search(
>         query,
>         max_results=max_results,
>         topic=topic,
>     )
>     result_texts = []
>     for result in search_results.get("results", []):
>         url = result["url"]
>         title = result["title"]
>         content = fetch_webpage_content(url)
>         result_texts.append(f"## {title}\n**URL:** {url}\n\n{content}\n---")
>
>     return f"Found {len(result_texts)} result(s) for '{query}':\n\n" + "\n".join(
>         result_texts
>     )
> ```
>
> ※ 重要提示：在您之前的输出中占位符集不正确。缺少的 id：\['0']；意外的额外 id：\[]。请再次翻译全文，并保持每个占位符（六边形括号 + 数字）的原位置，且仅出现一次。
>
> :::
>
> :::js
> 创建 `tools/search.ts`：
>
> ```ts tools/search.ts theme={null}
> import { tool } from "langchain";
> import { z } from "zod";
>
> async function fetchWebpageContent(
>   url: string,
>   timeout = 10_000,
> ): Promise<string> {
>   try {
>     const controller = new AbortController();
>     const id = setTimeout(() => controller.abort(), timeout);
>     const response = await fetch(url, {
>       headers: {
>         "User-Agent":
>           "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36",
>       },
>       signal: controller.signal,
>     });
>     clearTimeout(id);
>     if (!response.ok) {
>       return `Error fetching ${url}: HTTP ${response.status}`;
>     }
>     return await response.text();
>   } catch (e) {
>     return `Error fetching ${url}: ${e}`;
>   }
> }
>
> export const tavilySearch = tool(
>   async ({
>     query,
>     maxResults = 1,
>     topic = "general",
>   }: {
>     query: string;
>     maxResults?: number;
>     topic?: "general" | "news" | "finance";
>   }) => {
>     const response = await fetch("https://api.tavily.com/search", {
>       method: "POST",
>       headers: {
>         "Content-Type": "application/json",
>         Authorization: `Bearer ${process.env.TAVILY_API_KEY}`,
>       },
>       body: JSON.stringify({ query, max_results: maxResults, topic }),
>     });
>     const data = (await response.json()) as {
>       results: Array<{ url: string; title: string }>;
>     };
>     const results = data.results ?? [];
>     const resultTexts: string[] = [];
>     for (const result of results) {
>       const content = await fetchWebpageContent(result.url);
>       resultTexts.push(
>         `## ${result.title}\n**URL:** ${result.url}\n\n${content}\n---`,
>       );
>     }
>     return (
>       `Found ${resultTexts.length} result(s) for '${query}':\n\n` +
>       resultTexts.join("\n")
>     );
>   },
>   {
>     name: "tavily_search",
>     description:
>       "Search the web for information on a given query. Uses Tavily to discover relevant URLs, then fetches and returns full webpage content.",
>     schema: z.object({
>       query: z.string().describe("Search query to execute"),
>       maxResults: z
>         .number()
>         .optional()
>         .default(1)
>         .describe("Maximum number of results to return (default: 1)"),
>       topic: z
>         .enum(["general", "news", "finance"])
>         .optional()
>         .default("general")
>         .describe(
>           "Topic filter - 'general', 'news', or 'finance' (default: 'general')",
>         ),
>     }),
>   },
> );
> ```
>
> ※ 重要提示：在您之前的输出中占位符集不正确。缺少的 id：\['0']；意外的额外 id：\['1', '2', '3', '4', '5']。请再次翻译全文，并保持每个占位符（六边形括号 + 数字）的原位置，且仅出现一次。
>
> :::
>
> **2. Add orchestrator instructions**
>
> 将研究工作流和子智能体协调指导写入 `instructions.md`。Managed Deep Agents 将此文件作为编排系统提示加载：
>
> ```markdown instructions.md expandable wrap theme={null}
> # Research Workflow
>
> Follow this workflow for all research requests:
>
> 1. **Plan**: Create a todo list with write_todos to break down the research into focused tasks
> 2. **Save the request**: Use write_file() to save the user's research question to `/research_request.md`
> 3. **Research**: Delegate research tasks to sub-agents using the task() tool - ALWAYS use sub-agents for research, never conduct research yourself
> 4. **Synthesize**: Review all sub-agent findings and consolidate citations (each unique URL gets one number across all findings)
> 5. **Write Report**: Write a comprehensive final report to `/final_report.md` (see Report Writing Guidelines below)
> 6. **Verify**: Read `/research_request.md` and confirm you've addressed all aspects with proper citations and structure
>
> ## Research Planning Guidelines
> - Batch similar research tasks into a single TODO to minimize overhead
> - For simple fact-finding questions, use 1 sub-agent
> - For comparisons or multi-faceted topics, delegate to multiple parallel sub-agents
> - Each sub-agent should research one specific aspect and return findings
>
> ## Report Writing Guidelines
>
> When writing the final report to `/final_report.md`, follow these structure patterns:
>
> **For comparisons:**
> 1. Introduction
> 2. Overview of topic A
> 3. Overview of topic B
> 4. Detailed comparison
> 5. Conclusion
>
> **For lists/rankings:**
> Simply list items with details - no introduction needed:
> 1. Item 1 with explanation
> 2. Item 2 with explanation
> 3. Item 3 with explanation
>
> **For summaries/overviews:**
> 1. Overview of topic
> 2. Key concept 1
> 3. Key concept 2
> 4. Key concept 3
> 5. Conclusion
>
> **General guidelines:**
> - Use clear section headings (## for sections, ### for subsections)
> - Write in paragraph form by default - be text-heavy, not just bullet points
> - Do NOT use self-referential language ("I found...", "I researched...")
> - Write as a professional report without meta-commentary
> - Each section should be comprehensive and detailed
> - Use bullet points only when listing is more appropriate than prose
>
> **Citation format:**
> - Cite sources inline using [1], [2], [3] format
> - Assign each unique URL a single citation number across ALL sub-agent findings
> - End report with ### Sources section listing each numbered source
> - Number sources sequentially without gaps (1,2,3,4...)
> - Format: [1] Source Title: URL (each on separate line for proper list rendering)
> - Example:
>
>  Some important finding [1]. Another key insight [2].
>
>  ### Sources
>  [1] AI Research Paper: https://example.com/paper
>  [2] Industry Analysis: https://example.com/analysis
>
> # Sub-Agent Research Coordination
>
> Your role is to coordinate research by delegating tasks from your TODO list to specialized research sub-agents.
>
> ## Delegation Strategy
>
> **DEFAULT: Start with 1 sub-agent** for most queries:
> - "What is quantum computing?" -> 1 sub-agent (general overview)
> - "List the top 10 coffee shops in San Francisco" -> 1 sub-agent
> - "Summarize the history of the internet" -> 1 sub-agent
> - "Research context engineering for AI agents" -> 1 sub-agent (covers all aspects)
>
> **ONLY parallelize when the query EXPLICITLY requires comparison or has clearly independent aspects:**
>
> **Explicit comparisons** -> 1 sub-agent per element:
> - "Compare OpenAI vs Anthropic vs DeepMind AI safety approaches" -> 3 parallel sub-agents
> - "Compare Python vs JavaScript for web development" -> 2 parallel sub-agents
>
> **Clearly separated aspects** -> 1 sub-agent per aspect (use sparingly):
> - "Research renewable energy adoption in Europe, Asia, and North America" -> 3 parallel sub-agents (geographic separation)
> - Only use this pattern when aspects cannot be covered efficiently by a single comprehensive search
>
> ## Key Principles
> - **Bias towards single sub-agent**: One comprehensive research task is more token-efficient than multiple narrow ones
> - **Avoid premature decomposition**: Don't break "research X" into "research X overview", "research X techniques", "research X applications" - just use 1 sub-agent for all of X
> - **Parallelize only for clear comparisons**: Use multiple sub-agents when comparing distinct entities or geographically separated data
>
> ## Parallel Execution Limits
> - Use at most 3 parallel sub-agents per iteration
> - Make multiple task() calls in a single response to enable parallel execution
> - Each sub-agent returns findings independently
>
> ## Research Limits
> - Stop after 3 delegation rounds if you haven't found adequate sources
> - Stop when you have sufficient information to answer comprehensively
> - Bias towards focused research over exhaustive exploration
> ```
>
> 部署时，Managed Deep Agents 会将上述指令同步至 [Context Hub](https://docs.langchain.com/langsmith/managed-deep-agents-context-hub)。
>
> **3. Create the agent**
>
> 您只需将主智能体的指令写入 `instructions.md`。替换脚手架中的智能体条目为下方完整文件。该文件设置模型、工具、研究子智能体（包括该子智能体的自身提示词），以及@\[`TodoListMiddleware`] 以支持 `write_todos` 调用 [任务规划](https://langchain-docs-zh.mintlify.site/langchain/oss/deepagents/overview.md#任务规划)。 `name` 是必需的：MDA 使用它作为 LangGraph 助理 ID 和默认部署名称。
>
> :::python
> 替换 `agent.py`。选择您的服务提供商：
>
> > [tab] Claude
> >
> > ```python agent.py theme={null}
> > from datetime import datetime
> >
> > from langchain.agents.middleware import TodoListMiddleware
> > from managed_deepagents import define_deep_agent
> >
> > from tools.search import tavily_search
> >
> > current_date = datetime.now().strftime("%Y-%m-%d")
> >
> > RESEARCHER_INSTRUCTIONS = """You are a research assistant conducting research on the user's input topic. For context, today's date is {date}.
> >
> > Your job is to use tools to gather information about the user's input topic.
> > You can use the tavily_search tool to find resources that can help answer the research question.
> > You can call it in series or in parallel, your research is conducted in a tool-calling loop.
> >
> > You have access to the tavily_search tool for conducting web searches.
> >
> > Think like a human researcher with limited time. Follow these steps:
> >
> > 1. **Read the question carefully** - What specific information does the user need?
> > 2. **Start with broader searches** - Use broad, comprehensive queries first
> > 3. **After each search, pause and assess** - Do I have enough to answer? What's still missing?
> > 4. **Execute narrower searches as you gather information** - Fill in the gaps
> > 5. **Stop when you can answer confidently** - Don't keep searching for perfection
> >
> > **Tool Call Budgets** (Prevent excessive searching):
> > - **Simple queries**: Use 2-3 search tool calls maximum
> > - **Complex queries**: Use up to 5 search tool calls maximum
> > - **Always stop**: After 5 search tool calls if you cannot find the right sources
> >
> > **Stop Immediately When**:
> > - You can answer the user's question comprehensively
> > - You have 3+ relevant examples/sources for the question
> > - Your last 2 searches returned similar information
> >
> > After each search, assess results before continuing: What key information did I find? What's missing? Do I have enough to answer? Should I search more or provide my answer?
> >
> > When providing your findings back to the orchestrator:
> >
> > 1. **Structure your response**: Organize findings with clear headings and detailed explanations
> > 2. **Cite sources inline**: Use [1], [2], [3] format when referencing information from your searches
> > 3. **Include Sources section**: End with ### Sources listing each numbered source with title and URL
> >
> > The orchestrator will consolidate citations from all sub-agents into the final report.
> > """
> >
> > research_sub_agent = {
> >     "name": "research-agent",
> >     "description": "Delegate research to the sub-agent. Give one topic at a time.",
> >     "system_prompt": RESEARCHER_INSTRUCTIONS.format(date=current_date),
> >     "tools": [tavily_search],
> > }
> >
> > agent = define_deep_agent(
> >     name="deep-research",
> >     model="anthropic:claude-sonnet-4-5-20250929",
> >     tools=[tavily_search],
> >     subagents=[research_sub_agent],
> >     middleware=[TodoListMiddleware()],
> > )
> > ```
>
> > [tab] Gemini
> >
> > ```python agent.py theme={null}
> > from datetime import datetime
> >
> > from langchain.agents.middleware import TodoListMiddleware
> > from managed_deepagents import define_deep_agent
> >
> > from tools.search import tavily_search
> >
> > current_date = datetime.now().strftime("%Y-%m-%d")
> >
> > RESEARCHER_INSTRUCTIONS = """You are a research assistant conducting research on the user's input topic. For context, today's date is {date}.
> >
> > Your job is to use tools to gather information about the user's input topic.
> > You can use the tavily_search tool to find resources that can help answer the research question.
> > You can call it in series or in parallel, your research is conducted in a tool-calling loop.
> >
> > You have access to the tavily_search tool for conducting web searches.
> >
> > Think like a human researcher with limited time. Follow these steps:
> >
> > 1. **Read the question carefully** - What specific information does the user need?
> > 2. **Start with broader searches** - Use broad, comprehensive queries first
> > 3. **After each search, pause and assess** - Do I have enough to answer? What's still missing?
> > 4. **Execute narrower searches as you gather information** - Fill in the gaps
> > 5. **Stop when you can answer confidently** - Don't keep searching for perfection
> >
> > **Tool Call Budgets** (Prevent excessive searching):
> > - **Simple queries**: Use 2-3 search tool calls maximum
> > - **Complex queries**: Use up to 5 search tool calls maximum
> > - **Always stop**: After 5 search tool calls if you cannot find the right sources
> >
> > **Stop Immediately When**:
> > - You can answer the user's question comprehensively
> > - You have 3+ relevant examples/sources for the question
> > - Your last 2 searches returned similar information
> >
> > After each search, assess results before continuing: What key information did I find? What's missing? Do I have enough to answer? Should I search more or provide my answer?
> >
> > When providing your findings back to the orchestrator:
> >
> > 1. **Structure your response**: Organize findings with clear headings and detailed explanations
> > 2. **Cite sources inline**: Use [1], [2], [3] format when referencing information from your searches
> > 3. **Include Sources section**: End with ### Sources listing each numbered source with title and URL
> >
> > The orchestrator will consolidate citations from all sub-agents into the final report.
> > """
> >
> > research_sub_agent = {
> >     "name": "research-agent",
> >     "description": "Delegate research to the sub-agent. Give one topic at a time.",
> >     "system_prompt": RESEARCHER_INSTRUCTIONS.format(date=current_date),
> >     "tools": [tavily_search],
> > }
> >
> > agent = define_deep_agent(
> >     name="deep-research",
> >     model="google_genai:gemini-3-pro-preview",
> >     tools=[tavily_search],
> >     subagents=[research_sub_agent],
> >     middleware=[TodoListMiddleware()],
> > )
> > ```
>
> :::
>
> :::js
> 替换 `agent.ts`。选择您的服务提供商：
>
> > [tab] Claude
> >
> > ```ts agent.ts theme={null}
> > import { defineDeepAgent } from "managed-deepagents";
> > import { todoListMiddleware } from "langchain";
> >
> > import { tavilySearch } from "./tools/search";
> >
> > const currentDate = new Date().toISOString().split("T")[0];
> >
> > const RESEARCHER_INSTRUCTIONS = `You are a research assistant conducting research on the user's input topic. For context, today's date is {date}.
> >
> > Your job is to use tools to gather information about the user's input topic.
> > You can use the tavily_search tool to find resources that can help answer the research question.
> > You can call it in series or in parallel, your research is conducted in a tool-calling loop.
> >
> > You have access to the tavily_search tool for conducting web searches.
> >
> > Think like a human researcher with limited time. Follow these steps:
> >
> > 1. **Read the question carefully** - What specific information does the user need?
> > 2. **Start with broader searches** - Use broad, comprehensive queries first
> > 3. **After each search, pause and assess** - Do I have enough to answer? What's still missing?
> > 4. **Execute narrower searches as you gather information** - Fill in the gaps
> > 5. **Stop when you can answer confidently** - Don't keep searching for perfection
> >
> > **Tool Call Budgets** (Prevent excessive searching):
> > - **Simple queries**: Use 2-3 search tool calls maximum
> > - **Complex queries**: Use up to 5 search tool calls maximum
> > - **Always stop**: After 5 search tool calls if you cannot find the right sources
> >
> > **Stop Immediately When**:
> > - You can answer the user's question comprehensively
> > - You have 3+ relevant examples/sources for the question
> > - Your last 2 searches returned similar information
> >
> > After each search, assess results before continuing: What key information did I find? What's missing? Do I have enough to answer? Should I search more or provide my answer?
> >
> > When providing your findings back to the orchestrator:
> >
> > 1. **Structure your response**: Organize findings with clear headings and detailed explanations
> > 2. **Cite sources inline**: Use [1], [2], [3] format when referencing information from your searches
> > 3. **Include Sources section**: End with ### Sources listing each numbered source with title and URL
> >
> > The orchestrator will consolidate citations from all sub-agents into the final report.
> > `;
> >
> > const researchSubAgent = {
> >   name: "research-agent",
> >   description: "Delegate research to the sub-agent. Give one topic at a time.",
> >   systemPrompt: RESEARCHER_INSTRUCTIONS.replace("{date}", currentDate),
> >   tools: [tavilySearch],
> > };
> >
> > export const agent = defineDeepAgent({
> >   name: "deep-research",
> >   model: "anthropic:claude-sonnet-4-5-20250929",
> >   tools: [tavilySearch],
> >   subagents: [researchSubAgent],
> >   middleware: [todoListMiddleware()],
> > });
> > ```
>
> > [tab] Gemini
> >
> > ```ts agent.ts theme={null}
> > import { defineDeepAgent } from "managed-deepagents";
> > import { todoListMiddleware } from "langchain";
> >
> > import { tavilySearch } from "./tools/search";
> >
> > const currentDate = new Date().toISOString().split("T")[0];
> >
> > const RESEARCHER_INSTRUCTIONS = `You are a research assistant conducting research on the user's input topic. For context, today's date is {date}.
> >
> > Your job is to use tools to gather information about the user's input topic.
> > You can use the tavily_search tool to find resources that can help answer the research question.
> > You can call it in series or in parallel, your research is conducted in a tool-calling loop.
> >
> > You have access to the tavily_search tool for conducting web searches.
> >
> > Think like a human researcher with limited time. Follow these steps:
> >
> > 1. **Read the question carefully** - What specific information does the user need?
> > 2. **Start with broader searches** - Use broad, comprehensive queries first
> > 3. **After each search, pause and assess** - Do I have enough to answer? What's still missing?
> > 4. **Execute narrower searches as you gather information** - Fill in the gaps
> > 5. **Stop when you can answer confidently** - Don't keep searching for perfection
> >
> > **Tool Call Budgets** (Prevent excessive searching):
> > - **Simple queries**: Use 2-3 search tool calls maximum
> > - **Complex queries**: Use up to 5 search tool calls maximum
> > - **Always stop**: After 5 search tool calls if you cannot find the right sources
> >
> > **Stop Immediately When**:
> > - You can answer the user's question comprehensively
> > - You have 3+ relevant examples/sources for the question
> > - Your last 2 searches returned similar information
> >
> > After each search, assess results before continuing: What key information did I find? What's missing? Do I have enough to answer? Should I search more or provide my answer?
> >
> > When providing your findings back to the orchestrator:
> >
> > 1. **Structure your response**: Organize findings with clear headings and detailed explanations
> > 2. **Cite sources inline**: Use [1], [2], [3] format when referencing information from your searches
> > 3. **Include Sources section**: End with ### Sources listing each numbered source with title and URL
> >
> > The orchestrator will consolidate citations from all sub-agents into the final report.
> > `;
> >
> > const researchSubAgent = {
> >   name: "research-agent",
> >   description: "Delegate research to the sub-agent. Give one topic at a time.",
> >   systemPrompt: RESEARCHER_INSTRUCTIONS.replace("{date}", currentDate),
> >   tools: [tavilySearch],
> > };
> >
> > export const agent = defineDeepAgent({
> >   name: "deep-research",
> >   model: "google:gemini-3-pro-preview",
> >   tools: [tavilySearch],
> >   subagents: [researchSubAgent],
> >   middleware: [todoListMiddleware()],
> > });
> > ```
> >
> > ※ 重要提示：在您之前的输出中占位符集不正确。缺少的 id：\['0']; 预期之外的额外 id：\[]。请再次翻译全文，并确保每个六边形括号加数字的占位符都保留在原始位置，且仅出现一次。
>
> :::
>
> ### 运行智能体
>
> **1. Run locally**
>
> 安装依赖项并启动智能体：
>
> :::python
>
> ```bash theme={null}
> uv sync
> uv run mda dev
> ```
>
> :::
>
> :::js
>
> ```bash npm theme={null}
> npm install
> npx mda dev
> ```
>
> ```bash pnpm theme={null}
> pnpm install
> pnpm exec mda dev
> ```
>
> ```bash bun theme={null}
> bun install
> bunx mda dev
> ```
>
> :::
>
> `mda dev` 从 `.env` 加载 API 密钥，启动本地智能体服务器，并在 LangSmith Studio 中打开智能体。
>
> 在 Studio 中发送研究问题，例如：
>
> ```txt wrap theme={null}
> Compare the main approaches to context engineering for AI agents in 2025.
> ```
>
> 您应该看到 orchestrator 计划包含 `write_todos`，将任务委托给研究子智能体，并生成报告。更多详情请见 [在 LangSmith Studio 本地开发](https://docs.langchain.com/langsmith/managed-deep-agents-local-development)。
>
> **2. Deploy (optional)**
>
> :::python
>
> ```bash theme={null}
> uv run mda deploy
> ```
>
> :::
>
> :::js
>
> ```bash npm theme={null}
> npx mda deploy
> ```
>
> ```bash pnpm theme={null}
> pnpm exec mda deploy
> ```
>
> ```bash bun theme={null}
> bunx mda deploy
> ```
>
> :::
>
> 成功时，CLI 会打印部署仪表板 URL。请参考 [部署](https://docs.langchain.com/langsmith/managed-deep-agents-deploy)。

> [tab] Deep Agents SDK
>
> ### 配置
>
> :::python
>
> **1. Create project directory**
>
> ```bash theme={null}
> mkdir deep-research-agent
> cd deep-research-agent
> ```
>
> **2. Install dependencies**
>
> > [tab] Claude
> >
> > ```bash pip wrap theme={null}
> > pip install deepagents tavily-python httpx markdownify langchain-anthropic langchain-core
> > ```
> >
> > ```bash uv wrap theme={null}
> > uv init
> > uv add deepagents tavily-python httpx markdownify langchain-anthropic langchain-core
> > uv sync
> > ```
>
> > [tab] Gemini
> >
> > ```bash pip wrap theme={null}
> > pip install deepagents tavily-python httpx markdownify langchain-google-genai langchain-core
> > ```
> >
> > ```bash uv wrap theme={null}
> > uv init
> > uv add deepagents tavily-python httpx markdownify langchain-google-genai langchain-core
> > uv sync
> > ```
>
> **3. Set API keys**
>
> > [tab] Claude
> >
> > ```bash theme={null}
> > export ANTHROPIC_API_KEY="your_anthropic_api_key"
> > export TAVILY_API_KEY="your_tavily_api_key"
> > export LANGSMITH_API_KEY="your_langsmith_api_key"   # Optional
> > ```
>
> > [tab] Gemini
> >
> > ```bash theme={null}
> > export GOOGLE_API_KEY="your_google_api_key"
> > export TAVILY_API_KEY="your_tavily_api_key"
> > export LANGSMITH_API_KEY="your_langsmith_api_key"   # Optional
> > ```
>
> :::
>
> :::js
>
> **1. Create project directory**
>
> ```bash theme={null}
> mkdir deep-research-agent
> cd deep-research-agent
> ```
>
> **2. Install dependencies**
>
> > [tab] Claude
> >
> > ```bash npm wrap theme={null}
> > npm install deepagents langchain @langchain/anthropic @langchain/core zod tsx
> > ```
>
> > [tab] Gemini
> >
> > ```bash npm wrap theme={null}
> > npm install deepagents langchain @langchain/google @langchain/core zod tsx
> > ```
>
> **3. Set API keys**
>
> > [tab] Claude
> >
> > ```bash theme={null}
> > export ANTHROPIC_API_KEY="your_anthropic_api_key"
> > export TAVILY_API_KEY="your_tavily_api_key"
> > export LANGSMITH_API_KEY="your_langsmith_api_key"   # Optional
> > ```
>
> > [tab] Gemini
> >
> > ```bash theme={null}
> > export GOOGLE_API_KEY="your_google_api_key"
> > export TAVILY_API_KEY="your_tavily_api_key"
> > export LANGSMITH_API_KEY="your_langsmith_api_key"   # Optional
> > ```
>
> :::
>
> ### 构建智能体
>
> :::python
> 在项目目录中创建 `agent.py`：
> :::
>
> :::js
> 在项目目录中创建 `agent.ts`：
> :::
>
> **1. Add tools**
>
> 添加自定义搜索工具。`tavily_search` 工具使用 Tavily 进行 URL 发现，然后获取完整网页内容，使智能体能够分析完整信息源而非摘要。
>
> :::python
>
> ```python theme={null}
> import os
> from typing import Annotated, Literal
>
> import httpx
> from langchain.tools import InjectedToolArg, tool
> from markdownify import markdownify
> from tavily import TavilyClient
>
> tavily_client = TavilyClient(api_key=os.environ["TAVILY_API_KEY"])
>
>
> def fetch_webpage_content(url: str, timeout: float = 10.0) -> str:
>     """Fetch webpage and convert HTML to markdown."""
>     headers = {
>         "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36"
>     }
>     try:
>         response = httpx.get(url, headers=headers, timeout=timeout)
>         response.raise_for_status()
>         return markdownify(response.text)
>     except Exception as e:
>         return f"Error fetching {url}: {e!s}"
>
>
> @tool(parse_docstring=True)
> def tavily_search(
>     query: str,
>     max_results: Annotated[int, InjectedToolArg] = 1,
>     topic: Annotated[
>         Literal["general", "news", "finance"], InjectedToolArg
>     ] = "general",
> ) -> str:
>     """Search the web for information on a given query.
>
>     Uses Tavily to discover relevant URLs, then fetches and returns full webpage content as markdown.
>
>     Args:
>         query: Search query to execute
>         max_results: Maximum number of results to return (default: 1)
>         topic: Topic filter - 'general', 'news', or 'finance' (default: 'general')
>
>     Returns:
>         Formatted search results with full webpage content
>     """
>     search_results = tavily_client.search(
>         query,
>         max_results=max_results,
>         topic=topic,
>     )
>     result_texts = []
>     for result in search_results.get("results", []):
>         url = result["url"]
>         title = result["title"]
>         content = fetch_webpage_content(url)
>         result_texts.append(f"## {title}\n**URL:** {url}\n\n{content}\n---")
>
>     return f"Found {len(result_texts)} result(s) for '{query}':\n\n" + "\n".join(
>         result_texts
>     )
> ```
>
> :::
>
> :::js
>
> ```ts theme={null}
> import { tool } from "langchain";
> import { z } from "zod";
>
> async function fetchWebpageContent(
>   url: string,
>   timeout = 10_000,
> ): Promise<string> {
>   try {
>     const controller = new AbortController();
>     const id = setTimeout(() => controller.abort(), timeout);
>     const response = await fetch(url, {
>       headers: {
>         "User-Agent":
>           "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36",
>       },
>       signal: controller.signal,
>     });
>     clearTimeout(id);
>     if (!response.ok) {
>       return `Error fetching ${url}: HTTP ${response.status}`;
>     }
>     return await response.text();
>   } catch (e) {
>     return `Error fetching ${url}: ${e}`;
>   }
> }
>
> const tavilySearch = tool(
>   async ({
>     query,
>     maxResults = 1,
>     topic = "general",
>   }: {
>     query: string;
>     maxResults?: number;
>     topic?: "general" | "news" | "finance";
>   }) => {
>     const response = await fetch("https://api.tavily.com/search", {
>       method: "POST",
>       headers: {
>         "Content-Type": "application/json",
>         Authorization: `Bearer ${process.env.TAVILY_API_KEY}`,
>       },
>       body: JSON.stringify({ query, max_results: maxResults, topic }),
>     });
>     const data = (await response.json()) as {
>       results: Array<{ url: string; title: string }>;
>     };
>     const results = data.results ?? [];
>     const resultTexts: string[] = [];
>     for (const result of results) {
>       const content = await fetchWebpageContent(result.url);
>       resultTexts.push(
>         `## ${result.title}\n**URL:** ${result.url}\n\n${content}\n---`,
>       );
>     }
>     return (
>       `Found ${resultTexts.length} result(s) for '${query}':\n\n` +
>       resultTexts.join("\n")
>     );
>   },
>   {
>     name: "tavily_search",
>     description:
>       "Search the web for information on a given query. Uses Tavily to discover relevant URLs, then fetches and returns full webpage content.",
>     schema: z.object({
>       query: z.string().describe("Search query to execute"),
>       maxResults: z
>         .number()
>         .optional()
>         .default(1)
>         .describe("Maximum number of results to return (default: 1)"),
>       topic: z
>         .enum(["general", "news", "finance"])
>         .optional()
>         .default("general")
>         .describe(
>           "Topic filter - 'general', 'news', or 'finance' (default: 'general')",
>         ),
>     }),
>   },
> );
> ```
>
> :::
>
> **2. Create the agent**
>
> 在工具下方添加提示词常量和创建智能体。三个常量（`RESEARCH_WORKFLOW_INSTRUCTIONS`、`RESEARCHER_INSTRUCTIONS` 和 `SUBAGENT_DELEGATION_INSTRUCTIONS`）必须与 `create_deep_agent` / `createDeepAgent` 调用位于同一文件。@\[`TodoListMiddleware`] 是可选的 [任务规划](https://langchain-docs-zh.mintlify.site/langchain/oss/deepagents/overview.md#任务规划)，使智能体能调用 `write_todos`。
>
> :::python
> 将提示词添加到 `agent.py`：
>
> ```python expandable wrap theme={null}
> RESEARCH_WORKFLOW_INSTRUCTIONS = """# Research Workflow
>
> Follow this workflow for all research requests:
>
> 1. **Plan**: Create a todo list with write_todos to break down the research into focused tasks
> 2. **Save the request**: Use write_file() to save the user's research question to `/research_request.md`
> 3. **Research**: Delegate research tasks to sub-agents using the task() tool - ALWAYS use sub-agents for research, never conduct research yourself
> 4. **Synthesize**: Review all sub-agent findings and consolidate citations (each unique URL gets one number across all findings)
> 5. **Write Report**: Write a comprehensive final report to `/final_report.md` (see Report Writing Guidelines below)
> 6. **Verify**: Read `/research_request.md` and confirm you've addressed all aspects with proper citations and structure
>
> ## Research Planning Guidelines
> - Batch similar research tasks into a single TODO to minimize overhead
> - For simple fact-finding questions, use 1 sub-agent
> - For comparisons or multi-faceted topics, delegate to multiple parallel sub-agents
> - Each sub-agent should research one specific aspect and return findings
>
> ## Report Writing Guidelines
>
> When writing the final report to `/final_report.md`, follow these structure patterns:
>
> **For comparisons:**
> 1. Introduction
> 2. Overview of topic A
> 3. Overview of topic B
> 4. Detailed comparison
> 5. Conclusion
>
> **For lists/rankings:**
> Simply list items with details - no introduction needed:
> 1. Item 1 with explanation
> 2. Item 2 with explanation
> 3. Item 3 with explanation
>
> **For summaries/overviews:**
> 1. Overview of topic
> 2. Key concept 1
> 3. Key concept 2
> 4. Key concept 3
> 5. Conclusion
>
> **General guidelines:**
> - Use clear section headings (## for sections, ### for subsections)
> - Write in paragraph form by default - be text-heavy, not just bullet points
> - Do NOT use self-referential language ("I found...", "I researched...")
> - Write as a professional report without meta-commentary
> - Each section should be comprehensive and detailed
> - Use bullet points only when listing is more appropriate than prose
>
> **Citation format:**
> - Cite sources inline using [1], [2], [3] format
> - Assign each unique URL a single citation number across ALL sub-agent findings
> - End report with ### Sources section listing each numbered source
> - Number sources sequentially without gaps (1,2,3,4...)
> - Format: [1] Source Title: URL (each on separate line for proper list rendering)
> - Example:
>
>  Some important finding [1]. Another key insight [2].
>
>  ### Sources
>  [1] AI Research Paper: https://example.com/paper
>  [2] Industry Analysis: https://example.com/analysis
> """
> ```
>
> ```python expandable wrap theme={null}
> RESEARCHER_INSTRUCTIONS = """You are a research assistant conducting research on the user's input topic. For context, today's date is {date}.
>
> Your job is to use tools to gather information about the user's input topic.
> You can use the tavily_search tool to find resources that can help answer the research question.
> You can call it in series or in parallel, your research is conducted in a tool-calling loop.
>
> You have access to the tavily_search tool for conducting web searches.
>
> Think like a human researcher with limited time. Follow these steps:
>
> 1. **Read the question carefully** - What specific information does the user need?
> 2. **Start with broader searches** - Use broad, comprehensive queries first
> 3. **After each search, pause and assess** - Do I have enough to answer? What's still missing?
> 4. **Execute narrower searches as you gather information** - Fill in the gaps
> 5. **Stop when you can answer confidently** - Don't keep searching for perfection
>
> **Tool Call Budgets** (Prevent excessive searching):
> - **Simple queries**: Use 2-3 search tool calls maximum
> - **Complex queries**: Use up to 5 search tool calls maximum
> - **Always stop**: After 5 search tool calls if you cannot find the right sources
>
> **Stop Immediately When**:
> - You can answer the user's question comprehensively
> - You have 3+ relevant examples/sources for the question
> - Your last 2 searches returned similar information
>
> After each search, assess results before continuing: What key information did I find? What's missing? Do I have enough to answer? Should I search more or provide my answer?
>
> When providing your findings back to the orchestrator:
>
> 1. **Structure your response**: Organize findings with clear headings and detailed explanations
> 2. **Cite sources inline**: Use [1], [2], [3] format when referencing information from your searches
> 3. **Include Sources section**: End with ### Sources listing each numbered source with title and URL
>
> Example:
> ## Key Findings
> Context engineering is a critical technique for AI agents [1]. Studies show that proper context management can improve performance by 40% [2].
>
> ### Sources
> [1] Context Engineering Guide: https://example.com/context-guide
> [2] AI Performance Study: https://example.com/study
>
> The orchestrator will consolidate citations from all sub-agents into the final report.
> """
> ```
>
> ```python expandable wrap theme={null}
> SUBAGENT_DELEGATION_INSTRUCTIONS = """# Sub-Agent Research Coordination
>
> Your role is to coordinate research by delegating tasks from your TODO list to specialized research sub-agents.
>
> ## Delegation Strategy
>
> **DEFAULT: Start with 1 sub-agent** for most queries:
> - "What is quantum computing?" -> 1 sub-agent (general overview)
> - "List the top 10 coffee shops in San Francisco" -> 1 sub-agent
> - "Summarize the history of the internet" -> 1 sub-agent
> - "Research context engineering for AI agents" -> 1 sub-agent (covers all aspects)
>
> **ONLY parallelize when the query EXPLICITLY requires comparison or has clearly independent aspects:**
>
> **Explicit comparisons** -> 1 sub-agent per element:
> - "Compare OpenAI vs Anthropic vs DeepMind AI safety approaches" -> 3 parallel sub-agents
> - "Compare Python vs JavaScript for web development" -> 2 parallel sub-agents
>
> **Clearly separated aspects** -> 1 sub-agent per aspect (use sparingly):
> - "Research renewable energy adoption in Europe, Asia, and North America" -> 3 parallel sub-agents (geographic separation)
> - Only use this pattern when aspects cannot be covered efficiently by a single comprehensive search
>
> ## Key Principles
> - **Bias towards single sub-agent**: One comprehensive research task is more token-efficient than multiple narrow ones
> - **Avoid premature decomposition**: Don't break "research X" into "research X overview", "research X techniques", "research X applications" - just use 1 sub-agent for all of X
> - **Parallelize only for clear comparisons**: Use multiple sub-agents when comparing distinct entities or geographically separated data
>
> ## Parallel Execution Limits
> - Use at most {max_concurrent_research_units} parallel sub-agents per iteration
> - Make multiple task() calls in a single response to enable parallel execution
> - Each sub-agent returns findings independently
>
> ## Research Limits
> - Stop after {max_researcher_iterations} delegation rounds if you haven't found adequate sources
> - Stop when you have sufficient information to answer comprehensively
> - Bias towards focused research over exhaustive exploration"""
> ```
>
> 然后添加模型和智能体。选择您的服务提供商：
>
> > [tab] Claude
> >
> > ```python theme={null}
> > from datetime import datetime
> >
> > from deepagents import create_deep_agent
> > from langchain.agents.middleware import TodoListMiddleware
> > from langchain.chat_models import init_chat_model
> >
> > max_concurrent_research_units = 3
> > max_researcher_iterations = 3
> >
> > current_date = datetime.now().strftime("%Y-%m-%d")
> >
> > INSTRUCTIONS = (
> >     RESEARCH_WORKFLOW_INSTRUCTIONS
> >     + "\n\n"
> >     + "=" * 80
> >     + "\n\n"
> >     + SUBAGENT_DELEGATION_INSTRUCTIONS.format(
> >         max_concurrent_research_units=max_concurrent_research_units,
> >         max_researcher_iterations=max_researcher_iterations,
> >     )
> > )
> >
> > research_sub_agent = {
> >     "name": "research-agent",
> >     "description": "Delegate research to the sub-agent. Give one topic at a time.",
> >     "system_prompt": RESEARCHER_INSTRUCTIONS.format(date=current_date),
> >     "tools": [tavily_search],
> > }
> >
> > model = init_chat_model(model="anthropic:claude-sonnet-4-5-20250929", temperature=0.0)
> >
> > agent = create_deep_agent(
> >     model=model,
> >     tools=[tavily_search],
> >     system_prompt=INSTRUCTIONS,
> >     subagents=[research_sub_agent],
> >     middleware=[TodoListMiddleware()],
> > )
> > ```
>
> > [tab] Gemini
> >
> > ```python theme={null}
> > from datetime import datetime
> >
> > from deepagents import create_deep_agent
> > from langchain.agents.middleware import TodoListMiddleware
> > from langchain_google_genai import ChatGoogleGenerativeAI
> >
> > max_concurrent_research_units = 3
> > max_researcher_iterations = 3
> >
> > current_date = datetime.now().strftime("%Y-%m-%d")
> >
> > INSTRUCTIONS = (
> >     RESEARCH_WORKFLOW_INSTRUCTIONS
> >     + "\n\n"
> >     + "=" * 80
> >     + "\n\n"
> >     + SUBAGENT_DELEGATION_INSTRUCTIONS.format(
> >         max_concurrent_research_units=max_concurrent_research_units,
> >         max_researcher_iterations=max_researcher_iterations,
> >     )
> > )
> >
> > research_sub_agent = {
> >     "name": "research-agent",
> >     "description": "Delegate research to the sub-agent. Give one topic at a time.",
> >     "system_prompt": RESEARCHER_INSTRUCTIONS.format(date=current_date),
> >     "tools": [tavily_search],
> > }
> >
> > model = ChatGoogleGenerativeAI(model="gemini-3-pro-preview", temperature=0.0)
> >
> > agent = create_deep_agent(
> >     model=model,
> >     tools=[tavily_search],
> >     system_prompt=INSTRUCTIONS,
> >     subagents=[research_sub_agent],
> >     middleware=[TodoListMiddleware()],
> > )
> > ```
>
> :::
>
> :::js
> 将提示词添加到 `agent.ts`：
>
> ```ts expandable wrap theme={null}
> const RESEARCH_WORKFLOW_INSTRUCTIONS = `# Research Workflow
>
> Follow this workflow for all research requests:
>
> 1. **Plan**: Create a todo list with write_todos to break down the research into focused tasks
> 2. **Save the request**: Use write_file() to save the user's research question to \`/research_request.md\`
> 3. **Research**: Delegate research tasks to sub-agents using the task() tool - ALWAYS use sub-agents for research, never conduct research yourself
> 4. **Synthesize**: Review all sub-agent findings and consolidate citations (each unique URL gets one number across all findings)
> 5. **Write Report**: Write a comprehensive final report to \`/final_report.md\` (see Report Writing Guidelines below)
> 6. **Verify**: Read \`/research_request.md\` and confirm you've addressed all aspects with proper citations and structure
>
> ## Research Planning Guidelines
> - Batch similar research tasks into a single TODO to minimize overhead
> - For simple fact-finding questions, use 1 sub-agent
> - For comparisons or multi-faceted topics, delegate to multiple parallel sub-agents
> - Each sub-agent should research one specific aspect and return findings
>
> ## Report Writing Guidelines
>
> When writing the final report to \`/final_report.md\`, follow these structure patterns:
>
> **For comparisons:**
> 1. Introduction
> 2. Overview of topic A
> 3. Overview of topic B
> 4. Detailed comparison
> 5. Conclusion
>
> **For lists/rankings:**
> Simply list items with details - no introduction needed:
> 1. Item 1 with explanation
> 2. Item 2 with explanation
> 3. Item 3 with explanation
>
> **For summaries/overviews:**
> 1. Overview of topic
> 2. Key concept 1
> 3. Key concept 2
> 4. Key concept 3
> 5. Conclusion
>
> **General guidelines:**
> - Use clear section headings (## for sections, ### for subsections)
> - Write in paragraph form by default - be text-heavy, not just bullet points
> - Do NOT use self-referential language ("I found...", "I researched...")
> - Write as a professional report without meta-commentary
> - Each section should be comprehensive and detailed
> - Use bullet points only when listing is more appropriate than prose
>
> **Citation format:**
> - Cite sources inline using [1], [2], [3] format
> - Assign each unique URL a single citation number across ALL sub-agent findings
> - End report with ### Sources section listing each numbered source
> - Number sources sequentially without gaps (1,2,3,4...)
> - Format: [1] Source Title: URL (each on separate line for proper list rendering)
> - Example:
>
>  Some important finding [1]. Another key insight [2].
>
>  ### Sources
>  [1] AI Research Paper: https://example.com/paper
>  [2] Industry Analysis: https://example.com/analysis
> `;
> ```
>
> ```ts expandable wrap theme={null}
> const RESEARCHER_INSTRUCTIONS = `You are a research assistant conducting research on the user's input topic. For context, today's date is {date}.
>
> Your job is to use tools to gather information about the user's input topic.
> You can use the tavily_search tool to find resources that can help answer the research question.
> You can call it in series or in parallel, your research is conducted in a tool-calling loop.
>
> You have access to the tavily_search tool for conducting web searches.
>
> Think like a human researcher with limited time. Follow these steps:
>
> 1. **Read the question carefully** - What specific information does the user need?
> 2. **Start with broader searches** - Use broad, comprehensive queries first
> 3. **After each search, pause and assess** - Do I have enough to answer? What's still missing?
> 4. **Execute narrower searches as you gather information** - Fill in the gaps
> 5. **Stop when you can answer confidently** - Don't keep searching for perfection
>
> **Tool Call Budgets** (Prevent excessive searching):
> - **Simple queries**: Use 2-3 search tool calls maximum
> - **Complex queries**: Use up to 5 search tool calls maximum
> - **Always stop**: After 5 search tool calls if you cannot find the right sources
>
> **Stop Immediately When**:
> - You can answer the user's question comprehensively
> - You have 3+ relevant examples/sources for the question
> - Your last 2 searches returned similar information
>
> After each search, assess results before continuing: What key information did I find? What's missing? Do I have enough to answer? Should I search more or provide my answer?
>
> When providing your findings back to the orchestrator:
>
> 1. **Structure your response**: Organize findings with clear headings and detailed explanations
> 2. **Cite sources inline**: Use [1], [2], [3] format when referencing information from your searches
> 3. **Include Sources section**: End with ### Sources listing each numbered source with title and URL
>
> Example:
> ## Key Findings
> Context engineering is a critical technique for AI agents [1]. Studies show that proper context management can improve performance by 40% [2].
>
> ### Sources
> [1] Context Engineering Guide: https://example.com/context-guide
> [2] AI Performance Study: https://example.com/study
>
> The orchestrator will consolidate citations from all sub-agents into the final report.
> `;
> ```
>
> ```ts expandable wrap theme={null}
> const SUBAGENT_DELEGATION_INSTRUCTIONS = `# Sub-Agent Research Coordination
>
> Your role is to coordinate research by delegating tasks from your TODO list to specialized research sub-agents.
>
> ## Delegation Strategy
>
> **DEFAULT: Start with 1 sub-agent** for most queries:
> - "What is quantum computing?" -> 1 sub-agent (general overview)
> - "List the top 10 coffee shops in San Francisco" -> 1 sub-agent
> - "Summarize the history of the internet" -> 1 sub-agent
> - "Research context engineering for AI agents" -> 1 sub-agent (covers all aspects)
>
> **ONLY parallelize when the query EXPLICITLY requires comparison or has clearly independent aspects:**
>
> **Explicit comparisons** -> 1 sub-agent per element:
> - "Compare OpenAI vs Anthropic vs DeepMind AI safety approaches" -> 3 parallel sub-agents
> - "Compare Python vs JavaScript for web development" -> 2 parallel sub-agents
>
> **Clearly separated aspects** -> 1 sub-agent per aspect (use sparingly):
> - "Research renewable energy adoption in Europe, Asia, and North America" -> 3 parallel sub-agents (geographic separation)
> - Only use this pattern when aspects cannot be covered efficiently by a single comprehensive search
>
> ## Key Principles
> - **Bias towards single sub-agent**: One comprehensive research task is more token-efficient than multiple narrow ones
> - **Avoid premature decomposition**: Don't break "research X" into "research X overview", "research X techniques", "research X applications" - just use 1 sub-agent for all of X
> - **Parallelize only for clear comparisons**: Use multiple sub-agents when comparing distinct entities or geographically separated data
>
> ## Parallel Execution Limits
> - Use at most {maxConcurrentResearchUnits} parallel sub-agents per iteration
> - Make multiple task() calls in a single response to enable parallel execution
> - Each sub-agent returns findings independently
>
> ## Research Limits
> - Stop after {maxResearcherIterations} delegation rounds if you haven't found adequate sources
> - Stop when you have sufficient information to answer comprehensively
> - Bias towards focused research over exhaustive exploration`;
> ```
>
> 然后添加模型和智能体。选择您的服务提供商：
>
> > [tab] Claude
> >
> > ```ts theme={null}
> > import { createDeepAgent } from "deepagents";
> > import { ChatAnthropic } from "@langchain/anthropic";
> > import { todoListMiddleware } from "langchain";
> >
> > const maxConcurrentResearchUnits = 3;
> > const maxResearcherIterations = 3;
> >
> > const currentDate = new Date().toISOString().split("T")[0];
> >
> > const INSTRUCTIONS =
> >   RESEARCH_WORKFLOW_INSTRUCTIONS +
> >   "\n\n" +
> >   "=".repeat(80) +
> >   "\n\n" +
> >   SUBAGENT_DELEGATION_INSTRUCTIONS.replace(
> >     "{maxConcurrentResearchUnits}",
> >     String(maxConcurrentResearchUnits),
> >   ).replace("{maxResearcherIterations}", String(maxResearcherIterations));
> >
> > const researchSubAgent = {
> >   name: "research-agent",
> >   description: "Delegate research to the sub-agent. Give one topic at a time.",
> >   systemPrompt: RESEARCHER_INSTRUCTIONS.replace("{date}", currentDate),
> >   tools: [tavilySearch],
> > };
> >
> > const model = new ChatAnthropic({
> >   model: "claude-sonnet-4-5-20250929",
> >   temperature: 0,
> > });
> >
> > const agent = await createDeepAgent({
> >   model,
> >   tools: [tavilySearch],
> >   systemPrompt: INSTRUCTIONS,
> >   subagents: [researchSubAgent],
> >   middleware: [todoListMiddleware()],
> > });
> > ```
>
> > [tab] Gemini
> >
> > ```ts theme={null}
> > import { createDeepAgent } from "deepagents";
> > import { ChatGoogle } from "@langchain/google/node";
> > import { todoListMiddleware } from "langchain";
> >
> > const maxConcurrentResearchUnits = 3;
> > const maxResearcherIterations = 3;
> >
> > const currentDate = new Date().toISOString().split("T")[0];
> >
> > const INSTRUCTIONS =
> >   RESEARCH_WORKFLOW_INSTRUCTIONS +
> >   "\n\n" +
> >   "=".repeat(80) +
> >   "\n\n" +
> >   SUBAGENT_DELEGATION_INSTRUCTIONS.replace(
> >     "{maxConcurrentResearchUnits}",
> >     String(maxConcurrentResearchUnits),
> >   ).replace("{maxResearcherIterations}", String(maxResearcherIterations));
> >
> > const researchSubAgent = {
> >   name: "research-agent",
> >   description: "Delegate research to the sub-agent. Give one topic at a time.",
> >   systemPrompt: RESEARCHER_INSTRUCTIONS.replace("{date}", currentDate),
> >   tools: [tavilySearch],
> > };
> >
> > const model = new ChatGoogle({
> >   model: "gemini-3-pro-preview",
> >   temperature: 0,
> > });
> >
> > const agent = createDeepAgent({
> >   model,
> >   tools: [tavilySearch],
> >   systemPrompt: INSTRUCTIONS,
> >   subagents: [researchSubAgent],
> >   middleware: [todoListMiddleware()],
> > });
> > ```
> >
> > ※ 重要提示：在您之前的输出中占位符集不正确。缺少的 ID：\['0']；意外的额外 ID：\[]。请再次翻译全文，并保持每个占位符（六边形括号 + 数字）的原位置，且仅出现一次。
>
> :::
>
> ### 运行智能体
>
> 您可以选择同步运行智能体（等待完整结果后输出）或流式接收更新。
>
> :::python
> 在 `agent.py` 底部添加对应标签的代码：
> :::
>
> :::js
> 在 `agent.ts` 底部添加对应标签的代码：
> :::
>
> > [tab] Run synchronously
> >
> > :::python
> >
> > ```python theme={null}
> > from langchain.messages import HumanMessage
> >
> > if __name__ == "__main__":
> >     result = agent.invoke(
> >         {
> >             "messages": [
> >                 HumanMessage(
> >                     content="What are the main differences between RAG and fine-tuning for LLM applications?"
> >                 )
> >             ]
> >         }
> >     )
> >
> >     for msg in result.get("messages", []):
> >         if hasattr(msg, "content") and msg.content:
> >             print(msg.content)
> > ```
> >
> > :::
> >
> > :::js
> >
> > ```ts theme={null}
> > {
> >   async function main() {
> >     const result = await agent.invoke({
> >       messages: [
> >         {
> >           role: "user",
> >           content:
> >             "What are the main differences between RAG and fine-tuning for LLM applications?",
> >         },
> >       ],
> >     });
> >
> >     for (const msg of result.messages ?? []) {
> >       if (msg.content) {
> >         console.log(msg.content);
> >       }
> >     }
> >   }
> >
> >   main().catch((err) => {
> >     console.error(err);
> >     process.exitCode = 1;
> >   });
> > }
> > ```
> >
> > :::
>
> > [tab] Stream updates
> >
> > :::python
> >
> > ```python theme={null}
> > from langchain.messages import HumanMessage
> >
> > if __name__ == "__main__":
> >     stream = agent.stream_events(
> >         {
> >             "messages": [
> >                 HumanMessage(content="Compare Python vs JavaScript for web development")
> >             ]
> >         },
> >         version="v3",
> >     )
> >     for message in stream.messages:
> >         for token in message.text:
> >             print(token, end="", flush=True)
> > ```
> >
> > :::
> >
> > :::js
> >
> > ```ts theme={null}
> > {
> >   async function main() {
> >     const stream = await agent.streamEvents(
> >       {
> >         messages: [
> >           {
> >             role: "user",
> >             content: "Compare Python vs JavaScript for web development",
> >           },
> >         ],
> >       },
> >       { version: "v3" },
> >     );
> >     for await (const message of stream.messages) {
> >       for await (const token of message.text) {
> >         process.stdout.write(token);
> >       }
> >     }
> >   }
> >
> >   main().catch((err) => {
> >     console.error(err);
> >     process.exitCode = 1;
> >   });
> > }
> > ```
> >
> > :::
>
> 在项目根目录运行智能体：
>
> :::python
>
> ```sh theme={null}
> python agent.py
> ```
>
> :::
>
> :::js
>
> ```sh theme={null}
> npx tsx agent.ts
> ```
>
> :::
>
> 如果设置 `LANGSMITH_API_KEY` 环境变量，您可以在 [LangSmith](https://docs.langchain.com/langsmith/observability) 中查看智能体轨迹以调试和监控多步骤行为。
>
> ### 完整代码
>
> 查看完整 [Deep Research 示例](https://github.com/langchain-ai/deepagents/tree/main/examples/deep_research) 在 GitHub。

## 下一步骤

现在已构建智能体，可通过编辑编排器指令（Managed Deep Agents: `instructions.md`；SDK: 在您的智能体文件中修改提示常量）来定制工作流。您还可以调整委派限制以允许更多并行子智能体或委派轮次。

关于本教程中涉及的概念，请参考：

* [子智能体](https://langchain-docs-zh.mintlify.site/langchain/oss/deepagents/subagents.md): 使用不同工具和提示词配置子智能体
* [自定义](https://langchain-docs-zh.mintlify.site/langchain/oss/deepagents/customization.md): 自定义模型、工具、系统提示词及可选[任务规划](https://langchain-docs-zh.mintlify.site/langchain/oss/deepagents/overview.md#任务规划)
* [Managed Deep Agents](https://docs.langchain.com/langsmith/managed-deep-agents-overview): 使用 managed 部署基础设施构建深度智能体
* [LangSmith](https://docs.langchain.com/langsmith/observability): 追踪研究运行并调试多步骤行为
* [Deep Research Course](https://academy.langchain.com/courses/deep-research-with-langgraph): 完整的深度研究课程（基于 LangGraph）]

***

> 官方原文：[src/oss/deepagents/deep-research.mdx](https://github.com/langchain-ai/docs/blob/main/src/oss/deepagents/deep-research.mdx) · 非官方翻译，译文由 AI 生成，以英文原文为准。


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.