DeepAgents 入门
本文基于一个最小示例,阐明 DeepAgents 的核心使用方式:
如何接入大模型、如何定义工具、如何创建主代理、如何配置子代理。
一、DeepAgents 是什么
DeepAgents 适合用来构建更复杂的 Agent 系统:它不只是让大模型调用工具,还可以把任务拆给子代理执行,并通过事件流观察整个运行过程。
DeepAgents 是基于 LangGraph 和 LangChain 构建的高级 Agent 框架。相比LangGraph 偏向底层的图结构编排,DeepAgents 直接将多步骤任务规划、多工具并行调用、子代理委派与隔离执行等封装为开箱即用的高层级能力;同时,DeepAgents构建的Agent也兼备一些额外的基础能力,诸如虚拟沙盒文件系统、动态任务管理(TODO)等极大降低了复杂自主 Agent 的开发门槛。
DeepAgents 创建时的核心组件
- 工具调用:让模型不只是生成文本,而是能执行具体动作。
- 子代理委派:把复杂任务拆成多个角色,各自使用不同提示词、工具和模型。
对于简单问答,一个普通 ChatModel 就够了;对于需要多步骤执行、可观测调试、任务拆解和多角色协作的场景,DeepAgents 更适合做系统骨架。
二、DeepAgents 使用示例
下面是一个基础的 DeepAgents 使用示例,展示了从导入依赖到运行 Agent 的完整流程:
2.1 示例代码
python
# pip install -qU deepagents langchain-google-genai
from deepagents import create_deep_agent
from langchain_core.tools import tool
@tool
def get_weather(city: str) -> str:
"""Get weather for a given city."""
return f"It's always sunny in {city}!"
agent = create_deep_agent(
model="google_genai:gemini-3.5-flash",
tools=[get_weather],
system_prompt="You are a helpful assistant",
)
# Run the agent
agent.invoke(
{"messages": [{"role": "user", "content": "what is the weather in sf"}]}
)
2.2 步骤详解
上面的示例展示了 DeepAgents 的核心能力:自动规划、工具调用和任务执行,开发者只需定义工具和系统提示,Agent就能智能地完成复杂任务。下面对示例中的每一步作详细介绍:
2.2.1 导入依赖
python
from deepagents import create_deep_agent
from langchain_core.tools import tool
- 从
deepagents库导入创建 Agent 的核心函数 - 从
langchain_core导入工具装饰器
2.2.2 自定义工具(可选)
python
@tool
def get_weather(city: str) -> str:
"""Get weather for a given city."""
return f"It's always sunny in {city}!"
- 使用
@tool装饰器创建一个名为get_weather的工具函数 - 该工具接收城市名称作为参数,返回天气信息(这里是一个简化的示例,总是返回晴天)
- 工具函数的 docstring 会被用作工具的 description,帮助模型理解何时调用该工具
2.2.3 创建 Agent
python
agent = create_deep_agent(
model="google_genai:gemini-3.5-flash",
tools=[get_weather],
system_prompt="You are a helpful assistant",
)
- 使用
create_deep_agent函数创建一个 Agent 实例 - model: 指定使用的语言模型为 Google Gemini 3.5 Flash
- tools : 传入之前定义的
get_weather工具列表 - system_prompt: 设置系统提示词,定义代理的角色和行为准则
2.2.4 运行 Agent
python
agent.invoke(
{"messages": [{"role": "user", "content": "what is the weather in sf"}]}
)
- 使用
invoke方法执行 Agent - 传入一个消息字典,包含用户的问题:"旧金山的天气如何?"
- 代理会自动判断是否需要调用
get_weather工具来获取答案
2.3 工作流程
当这段代码运行时:
- 代理接收到用户关于旧金山天气的询问
- 模型分析后决定调用
get_weather工具,传入参数city="sf" - 工具执行并返回 "It's always sunny in sf!"
- 代理将工具返回的结果整合成最终回答给用户
三、创建具有子Agent的 Deep Agent 使用示例
DeepAgents 可以创建具有子代理的 Agent 系统。通过 subagents 参数,主代理可以将任务委派给专门的子代理执行。
3.1 基本结构
DeepAgents 的入口函数是 create_deep_agent。其结构包括:
model: 主代理使用的大模型tools: 主代理可调用的工具system_prompt: 主代理的行为约束subagents: 可委派的子代理列表
3.2 示例代码
示例中的子代理叫 researcher,其中 make_model 是我们自定义的一个模型加载函数,lookup_topic 是我们自定义的工具。在接下来的步骤详解中会一一介绍。
python
from deepagents import create_deep_agent
def make_basic_agent():
model = make_model(temperature=0)
researcher_model = make_model(temperature=0)
return create_deep_agent(
model=model,
tools=[lookup_topic],
system_prompt=(
"你是协调器。不要检查文件。不要搜索文件系统。"
"对于用户的请求,使用 subagent_type='researcher' 精确调用一次任务工具。"
"在任何任务结果返回后,不要再调用任务工具;立即给出一个简洁的最终答案,"
"以 FINAL_ANSWER: 开头"
),
subagents=[
{
"name": "researcher",
"description": "使用本地工具研究一个主题并返回紧凑的答案。",
"system_prompt": (
"你是研究员。不要检查文件。不要搜索文件系统。"
"使用 lookup_topic 精确调用一次,参数 topic='event streaming'。"
"然后返回两句话的摘要,以 FINAL_RESEARCH: 开头"
),
"model": researcher_model,
"tools": [lookup_topic],
}
],
)
3.3 步骤详解
3.3.1 subagents 的关键点
-
name 参数很重要 :
subagents里的name很重要。主代理调用task工具时,会通过subagent_type='researcher'指定要启动哪个子代理。 -
description 帮助主代理理解子代理 :
description会帮助主代理理解这个子代理适合做什么。 -
子代理是独立的 Agent :子代理可以有自己的
system_prompt、自己的模型、自己的工具集合。它不是简单函数调用,而是一个独立的 Agent。
3.3.2 接入自己的大模型
DeepAgents 接收 LangChain 的 chat model,因此只要你的模型服务兼容 OpenAI API,就可以用 ChatOpenAI 接入。
这里以OpenAI API的接口范式举例,事实上还可以使用其他方式接入大模型。
3.3.2.1 LLMConfig模型配置类
示例中的模型配置被封装成 LLMConfig,便于LLM配置的维护管理:
python
import os
class LLMConfig:
model = os.getenv("LLM_MODEL", "qwen3.6_27b")
base_url = os.getenv("LLM_BASE_URL", "http://your-host/v1")
api_key = os.getenv("LLM_API_KEY", "sk-...")
temperature = float(os.getenv("LLM_TEMPERATURE", "0.7"))
max_tokens = int(os.getenv("LLM_MAX_TOKENS", "4096"))
3.3.2.2 make_model模型加载函数定义
为保持主干代码整洁,我们将模型加载单独定义成函数来维护,真正创建模型对象时:
python
from langchain_openai import ChatOpenAI
def make_model(temperature: float | None = None) -> ChatOpenAI:
return ChatOpenAI(
model=LLMConfig.model,
base_url=LLMConfig.base_url,
api_key=LLMConfig.api_key,
temperature=LLMConfig.temperature if temperature is None else temperature,
max_tokens=LLMConfig.max_tokens,
)
密钥、模型名、base_url 都可以放到环境变量中保存。
3.3.3 定义工具:让 Agent 能做具体动作
DeepAgents 使用 LangChain 工具机制。一个普通 Python 函数加上 @tool 装饰器,就可以被模型调用。
3.3.3.1 lookup_topic工具定义示例
上面示例里的 lookup_topic,其定义工具的代码如下所示:
python
from langchain_core.tools import tool
@tool
def lookup_topic(topic: str) -> str:
"""查询一个本地短笔记。"""
notes = {
"event streaming": "事件流式传输在代理运行仍在执行时暴露消息、工具调用、值、子代理和最终输出。",
"deepagents": "Deep Agents 是基于 LangGraph 的代理,具有内置规划、文件系统工具和基于任务的子代理。",
"qwen": "Qwen 模型可以通过 OpenAI 兼容端点提供服务,并由 ChatOpenAI 使用。",
}
return notes.get(topic.lower(), f"未找到 {topic!r} 的本地笔记;使用通用知识并保持答案简洁。")
工具的作用不是"让代码更复杂",而是给模型一个稳定、可控、可观测的外部能力。
模型调用工具时,可以通过事件流看到工具名、输入、输出和执行状态。
3.3.3.2 工具调用的执行流程
在示例中,一个典型结构是:
text
用户
-> 主代理
-> task 工具(通过这种方式调度子代理)
-> researcher 子代理
-> lookup_topic 工具
主代理不需要自己完成所有事情,主代理可以通过内置的 task 工具,把一个明确的小任务交给某个子代理处理,然后再根据子代理结果给用户最终回答。
四、创建嵌套子代理的DeepAgents 使用示例
DeepAgents 支持子代理内部再启动子代理,形成多层级的代理架构。这种嵌套结构适合处理更复杂的任务分解场景。
4.1 嵌套结构示例
例如:
text
用户
-> 主代理
-> planner 子代理
-> fact_checker 嵌套子代理
-> lookup_topic 工具
4.2 创建嵌套子代理的步骤
4.2.1 创建内层子代理
示例里的写法是先创建一个 planner agent,它内部有一个 fact_checker 子代理:
python
planner = create_deep_agent(
model=make_model(temperature=0),
tools=[lookup_topic],
system_prompt=(
"你是规划器。严格按照以下顺序执行:"
"步骤1:使用 subagent_type='fact_checker' 精确调用一次任务工具。"
"步骤2:在任何任务结果返回后,不要再调用任何工具;返回一个简短的计划。"
),
subagents=[
{
"name": "fact_checker",
"description": "使用本地工具验证一个事实性笔记。",
"system_prompt": "使用 lookup_topic 精确调用一次,然后报告该笔记是否可用。",
"model": make_model(temperature=0),
"tools": [lookup_topic],
}
],
)
4.2.2 在主代理中注册 planner
然后在主代理中注册 planner:
python
agent = create_deep_agent(
model=make_model(temperature=0),
tools=[lookup_topic],
system_prompt="你是协调器。调用 planner 一次,然后给出最终答案。",
subagents=[
{
"name": "planner",
"description": "规划答案并委托事实核查。",
"runnable": planner,
}
],
)
注意 :这里的 runnable 参数表示这个子代理不是简单配置出来的新 agent,而是一个已经编译好的 agent。