《Deep Agents 实战笔记》第 2 篇 | 基于 deepagents (Python) 官方 Quickstart 原文:https://docs.langchain.com/oss/python/deepagents/quickstart
上一篇讲了 Deep Agents 为什么用文件系统和子代理这两个设计来解决问题。纸上得来终觉浅,这一篇我们直接跑通官方 Quickstart:一个能自主搜索、拆解任务、写出研究报告的深度研究 Agent。完整代码不到 40 行。
一、准备环境
pip install -U deepagents
然后配一个模型 API key(三选一即可):
# 任选其一
export GOOGLE_API_KEY="..." # Google
export OPENAI_API_KEY="..." # OpenAI
export ANTHROPIC_API_KEY="..." # Anthropic
Deep Agents 的模型接入沿用 LangChain 的 provider:model 字符串规范,理论上 100+ 提供商都能接。国内读者常用的 OpenRouter / Ollama 也直接支持,比如 openrouter:z-ai/glm-5.2 或 ollama:你的模型名,后面代码里替换即可。
二、给 Agent 一双"能上网的手"
Agent 本身没有任何联网能力,搜索要靠我们喂给它一个工具。如果你的模型自带搜索(Gemini / GPT / Claude 均有内置 web search),可以直接用内置搜索,零额外配置:
# Google 内置搜索(以 Gemini 为例)
internet_search = {"google_search": {}}
如果你的模型没有内置搜索(或你想统一控制),用 Tavily:
import os
from typing import Literal
from tavily import TavilyClient
from deepagents import create_deep_agent
tavily_client = TavilyClient(api_key=os.environ["TAVILY_API_KEY"])
def internet_search(
query: str,
max_results: int = 5,
topic: Literal["general", "news", "finance"] = "general",
include_raw_content: bool = False,
):
"""执行一次网络搜索"""
return tavily_client.search(
query,
max_results=max_results,
include_raw_content=include_raw_content,
topic=topic,
)
注意这个普通 Python 函数的三要素:类型标注的参数签名 + docstring。Deep Agents 会自动把它包装成模型可调用的工具,docstring 就是模型决定"什么时候调它、怎么调"的唯一依据。搜索类工具建议保留 include_raw_content 参数——后面你会看到它的妙用。
三、创建 Deep Agent:只需要三个参数
# 引导代理成为专家研究者的系统提示词
research_instructions = """You are an expert researcher. Your job is to conduct thorough research and then write a polished report.
You have access to an internet search tool as your primary means of gathering information.
## `internet_search`
Use this to run an internet search for a given query. You can specify the max number of results to return, the topic, and whether raw content should be included.
"""
agent = create_deep_agent(
model="google_genai:gemini-3.6-flash", # 换成你的 provider:model
tools=[internet_search],
system_prompt=research_instructions,
)
create_deep_agent 的必填参数只有三个:模型、工具、系统提示词。但真正的"深度"来自你没传的那些东西——你没配文件系统,它有;你没定义子代理,它有;你没写总结压缩逻辑,它也有。这些都是 harness 默认内置的。
四、跑起来
result = agent.invoke({"messages": [{"role": "user", "content": "What is langgraph?"}]})
# 打印最终报告
print(result["messages"][-1].content)
一个看起来平平无奇的问题 "What is langgraph?",背后会发生什么?用一张时序图还原 Agent 的真实执行过程:
sequenceDiagram
participant U as 用户
participant M as 主代理<br/>(监督者)
participant T as internet_search
participant FS as 虚拟文件系统
participant SA as 子代理
U->>M: What is langgraph?
M->>T: 搜索 "LangGraph"
T-->>M: 结果摘要
M->>T: 追问细节(架构 / 应用场景...)
T-->>M: 更多结果
Note over M,FS: 结果过大时<br/>write_file 落盘,上下文只留摘要
M->>SA: task: 深入研究某个子问题<br/>(独立上下文 + 同样的工具)
SA->>T: 自主多轮搜索
SA->>FS: 写入研究笔记
SA-->>M: 研究结果摘要
M->>U: 综合所有发现,输出完整报告
正在渲染图表…
官方对这段执行的概括是四步:
- 开展研究:调用
internet_search收集信息; - 管理上下文:用
write_file/read_file把大型搜索结果卸载到文件系统; - 按需生成子代理:把复杂的子问题委派给专门子代理;
- 综合成报告:汇总各项发现,输出连贯回答。
实际执行时它到底拆了几步、派了几个子代理,取决于问题的复杂度和模型自己的判断——这正是"deep"的含义:没有固定的 Agent 工作流,只有目标和工具,怎么拆解由它自己决定。
五、强烈建议:打开 LangSmith 追踪
裸看 result["messages"] 只能看到最终答案,看不到过程。强烈建议第一步就配好 LangSmith(免费额度够用):
export LANGSMITH_TRACING=true
export LANGSMITH_API_KEY="your-langsmith-api-key"
配好后再跑一次,在 smith.langchain.com 里你能看到完整的执行树:每一次 LLM 调用的输入输出、每一次工具调用的参数与结果、子代理委派的层级结构。调试 Deep Agent 的第一原则:先看 trace,再猜问题。
六、两个立刻可以试的增强
跑通之后,可以马上试两个官方提供的增强:
1. 任务规划(todo list):让复杂任务先列计划再执行,执行过程全程可追踪(v0.7 起为可选启用):
from langchain.agents.middleware import TodoListMiddleware
agent = create_deep_agent(
model="google_genai:gemini-3.6-flash",
tools=[internet_search],
system_prompt=research_instructions,
middleware=[TodoListMiddleware()],
)
2. 流式输出:invoke 换成 stream,实时看到每一步工具调用和 token 生成,长任务的体验会好非常多(第 9 篇细讲)。
七、本篇踩坑点
- docstring 不要省:搜索工具没有 docstring 或写得含糊,模型调用质量会断崖式下跌;
- 模型字符串写错不报错但很怪:
provider:model格式不对时有些 provider 会静默降级,遇到行为诡异先检查模型字符串; - 第一次运行会觉得"慢":深度研究本身就是多轮 LLM 调用 + 多轮搜索,这是特性不是 bug——但正因为慢,上下文管理才重要,这正是后面几篇的主题。
下一篇,我们拆开 harness 看内部构造:规划、文件系统、子代理、记忆、技能这五张牌各自怎么打。
参考资料与可运行代码: