围绕目标构建 harness。create_deep_agent 提供 production-ready foundation:将它连接到你的 data、塑造其 behavior,并添加 use case 所需 capabilities。
from deepagents import create_deep_agent

agent = create_deep_agent(
    model="anthropic:claude-sonnet-4-6",
    system_prompt="You are a helpful assistant.",
    tools=[search, fetch_url],
    memory=["./AGENTS.md"],
    skills=["./skills/"],
)
Parameter作用
model=要使用的 model
system_prompt=Agent 的 custom instructions
tools=Agent 可调用的 domain tools
memory=Startup 时加载的 AGENTS.md files
skills=用于 on-demand knowledge 的 skills directory
backend=Filesystem backend(默认 StateBackend)
permissions=Filesystem 的 path-level access control
subagents=用于 delegated tasks 的 custom subagents
middleware=要添加到 stack 的 extra middleware
interrupt_on=在 tool calls 前暂停以等待 human approval
response_format=Structured output schema
state_schema=Custom graph state schema
profiles作为 reusable bundle 的 per-model defaults
create_deep_agent(
    model: str | BaseChatModel | None = None,
    tools: Sequence[BaseTool | Callable | dict[str, Any]] | None = None,
    *,
    system_prompt: str | SystemMessage | None = None,
    middleware: Sequence[AgentMiddleware] = (),
    subagents: Sequence[SubAgent | CompiledSubAgent | AsyncSubAgent] | None = None,
    skills: list[str] | None = None,
    memory: list[str] | None = None,
    permissions: list[FilesystemPermission] | None = None,
    backend: BackendProtocol | BackendFactory | None = None,
    interrupt_on: dict[str, bool | InterruptOnConfig] | None = None,
    response_format: ResponseFormat[ResponseT] | type[ResponseT] | dict[str, Any] | None = None,
    state_schema: type[DeepAgentState] | None = None,
    context_schema: type[ContextT] | None = None,
    checkpointer: Checkpointer | None = None,
    store: BaseStore | None = None,
    debug: bool = False,
    name: str | None = None,
    cache: BaseCache | None = None
) -> CompiledStateGraph[AgentState[ResponseT], ContextT, _InputAgentState, _OutputAgentState[ResponseT]]
完整 parameter list 请参阅 create_deep_agent API reference。若要从头组合 fully custom harness,请参阅 Configure the harness,或按照 Build a deep agent from scratch step-by-step guide 操作。
添加 tools、subagents 和 backends 时,请使用 LangSmith trace 各部分如何协同工作。按照 observability quickstart 完成设置,并参阅 Going to production 了解如何部署到 LangSmith。建议你同时设置 LangSmith Engine,它会监控 traces、检测 issues,并提出 fixes。

Model

传入 provider:model 格式的 model string,或 initialized model instance。所有 providers 请参阅 supported models,经过测试的 recommendations 请参阅 suggested models
使用 provider:model 格式(例如 openai:gpt-5.4)可在 models 之间快速切换。
👉 Read the OpenAI chat model integration docs
pip install -U "langchain[openai]"
import os
from deepagents import create_deep_agent

os.environ["OPENAI_API_KEY"] = "sk-..."

agent = create_deep_agent(model="openai:gpt-5.4")
# this calls init_chat_model for the specified model with default parameters
# to use specific model parameters, use init_chat_model directly
Chat models 会自动 retry transient API failures(使用 exponential backoff)。关于调优 max_retries / timeout 的 defaults、limits 和 code samples,请参阅 LangChain Models 页面。

Tools

除用于 planning、file management 和 subagent spawning 的 built-in tools 外,你还可以提供 custom tools:
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,
):
    """Run a web search"""
    return tavily_client.search(
        query,
        max_results=max_results,
        include_raw_content=include_raw_content,
        topic=topic,
    )


agent = create_deep_agent(
    model="google_genai:gemini-3.5-flash",
    tools=[internet_search],
)

MCP tools

Deep Agents 完全支持 Model Context Protocol (MCP) tools。你可以从任何 MCP server 加载 tools,例如 databases、APIs、file systems 等,并将它们直接传给 create_deep_agent
安装 langchain-mcp-adapters 以连接 MCP servers:
pip install langchain-mcp-adapters
import asyncio
from langchain_mcp_adapters.client import MultiServerMCPClient
from deepagents import create_deep_agent

async def main():
    async with MultiServerMCPClient(
        {
            "my_server": {
                "transport": "http",
                "url": "http://localhost:8000/mcp",
            }
        }
    ) as client:
        tools = await client.get_tools()

        agent = create_deep_agent(
            model="openai:gpt-5.4",
            tools=tools,
        )

        result = await agent.ainvoke(
            {"messages": [{"role": "user", "content": "Use the MCP server to help me."}]},
            config={"configurable": {"thread_id": "1"}},
        )

asyncio.run(main())
有关 stdio servers、OAuth authentication、tool filtering 和 stateful sessions 的详细配置选项,请参阅完整 MCP guide

System prompt

Deep Agents 附带 built-in system prompt。Deep agent 的价值来自 SDK 在 model 之上提供的 orchestration layer,包括 planning、virtual-filesystem tools 和 subagents,而 model 需要知道这些能力存在以及何时使用它们。Built-in prompt 会教 agent 如何使用这套 scaffolding,因此你无需为每个 project 重新推导;请通过 profile 或你自己的 system_prompt= 调整它,而不是逐字复制。 当 middleware 添加 filesystem tools 等 special tools 时,它会将相关内容追加到 system prompt。 每个 deep agent 也应包含面向其 specific use case 的 custom system prompt:
from deepagents import create_deep_agent

research_instructions = """\
You are an expert researcher. Your job is to conduct \
thorough research, and then write a polished report. \
"""

agent = create_deep_agent(
    model="google_genai:gemini-3.5-flash",
    system_prompt=research_instructions,
)

Prompt assembly

Deep Agents 会从最多四个 named parts 构建 system prompt,让 caller-supplied instructions、SDK built-in agent guidance,以及任何 model-specific profile overrides 能以可预测 precedence 共存。如果没有这种 layering,针对 Claude 调优的 profile suffix 可能会根据 call order 覆盖你的 system_prompt= argument,或被它覆盖;named slots 让 ordering 明确且稳定。 实践中,大多数 callers 只会遇到两个 slots:USER(你的 system_prompt=)和 BASE(SDK default)。选择带 built-in profile 的 model(目前为 Anthropic 或 OpenAI)会添加 SUFFIX。完整四段式 assembly 主要在你编写 custom HarnessProfile,或 debug profile text 为什么出现在某个位置时相关。 四个 named parts 如下(每个都可能不存在):
NameSourceNotes
USERsystem_prompt= argument to create_deep_agentstr or SystemMessage; omitted when unset.
BASEThe SDK default (BASE_AGENT_PROMPT)Always present unless replaced by a profile’s CUSTOM.
CUSTOMHarnessProfile.base_system_promptReplaces BASE outright when a matching profile sets it.
SUFFIXHarnessProfile.system_prompt_suffixAppended last when a matching profile sets it.
顺序始终是 USER -> (BASE or CUSTOM) -> SUFFIX,并以空行(\n\n)连接。由此得到两个 invariants:
  1. USER 始终在最前面。 Caller text 位于任何 SDK 或 profile content 之前,因此无论选择哪个 model,persona/instructions 都优先。
  2. SUFFIX 始终在最后。 Profile suffixes 最接近 conversation history,model-tuning guidance 在这里最可靠。
Assembled shapes(✓ = field is set,- = field is unset):
system_prompt=profile base_system_prompt (CUSTOM)profile system_prompt_suffix (SUFFIX)Final assembled system prompt
None--BASE
None-BASE + SUFFIX
None-CUSTOM
NoneCUSTOM + SUFFIX
str--USER + BASE
str-USER + BASE + SUFFIX
str-USER + CUSTOM
strUSER + CUSTOM + SUFFIX
Worked example:built-in profiles(Anthropic、OpenAI)只附带 system_prompt_suffix,因此典型 call 会落在 str + - + 行:
agent = create_deep_agent(
    model="anthropic:claude-sonnet-4-6",
    system_prompt="You are a customer-support agent for ACME Corp.",
)
# Final = USER + BASE + SUFFIX
#       = "You are a customer-support agent for ACME Corp."
#         + "\n\n"
#         + BASE_AGENT_PROMPT
#         + "\n\n"
#         + <Claude-specific guidance>
传入 SystemMessage(而不是 string)会触发不同的 concatenation path:右侧 assembly(BASE-or-CUSTOM 加上任何 SUFFIX)会作为 additional text content block 追加到 message 现有的 content_blocks。相同 logical ordering 仍然适用(caller blocks 在前),并且 caller blocks 上的任何 cache_control markers 都会保留,这对于放置显式 Anthropic prompt-cache breakpoints 很有用。
Prompt assembly overlay rules 也适用于 declarative subagents:每个 subagent 会针对自己的 model重新运行 profile resolution,然后将 resolved profile 的 base_system_prompt / system_prompt_suffix 应用于其 authored system_prompt。Subagent 的 system_prompt 扮演 BASE 角色;CUSTOMSUFFIX 来自匹配 subagent model 的 profile(可能不同于 main agent profile)。
spec["system_prompt"]profile base_system_prompt (CUSTOM)profile system_prompt_suffix (SUFFIX)Final subagent system prompt
authored--authored
authored-authored + SUFFIX
authored-CUSTOM
authoredCUSTOM + SUFFIX
Subagents 没有 USER segment。Spec 中 authored system_prompt 是最接近的 analog,并保留在 BASE slot 中。只附带 system_prompt_suffix 的 profile(built-in Anthropic / OpenAI profiles 的常见情况)只会追加到 subagent author 写入的内容后。设置 base_system_prompt 的 profile 会直接替换 authored prompt。
Auto-added general-purpose subagent 遵循 prompt assembly overlay rules,但多一层:GP base prompt 会解析为 general_purpose_subagent.system_prompt(如果设置)-> HarnessProfile.base_system_prompt(如果设置)-> SDK general-purpose default。无论哪种情况,profile suffix 都会叠加其上。这两个 override fields 都可以携带 base-prompt replacement,但它们不可互换。general_purpose_subagent.system_prompt 是 general-purpose-specific configuration;base_system_prompt 是主要面向 main agent 的 global override。当二者都设置时,general-purpose-specific intent 会在 general-purpose subagent 上胜出,因此同时调优两个 fields 的 user 不会看到 GP override 被静默丢弃:
register_harness_profile(
    "anthropic",
    HarnessProfile(
        base_system_prompt="You are ACME's support orchestrator.",  # main agent
        general_purpose_subagent=GeneralPurposeSubagentProfile(
            system_prompt="You are a research subagent. Cite sources.",  # GP subagent
        ),
        system_prompt_suffix="Always think step by step.",
    ),
)
StackFinal system prompt
Main agent"You are ACME's support orchestrator." + SUFFIX
GP subagent"You are a research subagent. Cite sources." + SUFFIX
如果 general_purpose_subagent.system_prompt 未设置,GP subagent 会回退到 base_system_prompt(如果设置),最后回退到 SDK general-purpose default。

Middleware

Deep Agents 支持任何 middleware,包括下方列出的 built-in middleware、来自 LangChain 的 prebuilt middleware、provider-specific middleware,以及你自己编写的 custom middleware。 将 middleware 传给 create_deep_agentmiddleware argument。 默认情况下,Deep Agents 可以访问以下 middleware:

Default stack (main agent)

从前到后:
  1. TodoListMiddleware: Tracks and manages todo lists for organizing agent tasks and work.
  2. SkillsMiddleware: Only when you pass skills. Injected immediately after the todo middleware and before filesystem middleware so skill metadata is available before file tools run.
  3. FilesystemMiddleware: Handles file system operations such as reading, writing, and navigating directories. When you pass permissions, filesystem permissions enforcement is included here so it can evaluate every tool the agent might call.
  4. SubAgentMiddleware: Spawns and coordinates subagents for delegating tasks to specialized agents.
  5. SummarizationMiddleware: Condenses message history to stay within context limits when conversations grow long (via create_summarization_middleware).
  6. PatchToolCallsMiddleware: Automatic message history fixes when tool calls are interrupted or cancelled before receiving results. Runs before Anthropic prompt caching and the tail stack below.
  7. AsyncSubAgentMiddleware: Only when you configure async subagents.
  8. Your middleware argument: Optional middleware you pass as the middleware argument is appended here (after Patch, before the tail stack).
  9. Harness profile extras: Provider-specific middleware from the resolved model profile, if any.
  10. Excluded-tool filtering: When the harness profile lists excluded tools, middleware removes those tools from the agent.
  11. AnthropicPromptCachingMiddleware: Always registered; it no-ops on non-Anthropic models (unsupported_model_behavior="ignore"). Runs after Patch and after your middleware so the cached prefix matches what is actually sent to the model.
  12. MemoryMiddleware: Only when you pass memory.
    MemoryMiddleware is placed after profile extras and Anthropic prompt caching so updates to injected memory are less likely to invalidate the Anthropic cache prefix. The same ordering concern is called out in the create_deep_agent implementation comments.
  13. HumanInTheLoopMiddleware: Only when you pass interrupt_on. Pauses for human approval or input at configured tool calls.

Default stack (synchronous subagents)

The built-in general-purpose subagent and each declarative synchronous SubAgent graph use a stack that create_deep_agent builds in code. It matches the main agent in broad shape (todo list, filesystem, summarization, Patch, profile extras, Anthropic caching, optional permissions) but differs in two ways:
  • Skills run after PatchToolCallsMiddleware on these inner agents (on the main agent, skills run before filesystem middleware when skills is set).
  • There is no SubAgentMiddleware inside a subagent graph (only the parent agent exposes the task tool).
When a declarative subagent sets interrupt_on, that value is forwarded to create_agent for the subagent, which wires up human-in-the-loop handling for the configured tool calls.

Prebuilt middleware

LangChain 暴露 additional prebuilt middleware,可让你添加 retries、fallbacks 或 PII detection 等各种 features。更多信息请参阅 Prebuilt middleware deepagents library 还暴露 create_summarization_tool_middleware,让 agents 可以在合适时机触发 summarization,例如 tasks 之间,而不是在固定 token intervals 触发。更多 details 请参阅 Summarization

Provider-specific middleware

针对特定 LLM providers 优化的 provider-specific middleware,请参阅 Official integrationsCommunity integrations

Custom middleware

你可以提供 additional middleware 来扩展 functionality、添加 tools,或实现 custom hooks:
from langchain.agents.middleware import wrap_tool_call
from langchain.tools import tool
from deepagents import create_deep_agent


@tool
def get_weather(city: str) -> str:
    """Get the weather in a city."""
    return f"The weather in {city} is sunny."


call_count = [0]  # Use list to allow modification in nested function


@wrap_tool_call
def log_tool_calls(request, handler):
    """Intercept and log every tool call - demonstrates cross-cutting concern."""
    call_count[0] += 1
    tool_name = request.name if hasattr(request, "name") else str(request)

    print(f"[Middleware] Tool call #{call_count[0]}: {tool_name}")
    print(f"[Middleware] Arguments: {request.args if hasattr(request, 'args') else 'N/A'}")

    # Execute the tool call
    result = handler(request)

    # Log the result
    print(f"[Middleware] Tool call #{call_count[0]} completed")

    return result


agent = create_deep_agent(
    model="google_genai:gemini-3.5-flash",
    tools=[get_weather],
    middleware=[log_tool_calls],
)
初始化后不要 mutate attributes如果需要跨 hook invocations 跟踪 values(例如 counters 或 accumulated data),请使用 graph state。 Graph state 设计上作用域限定于 thread,因此并发下更新是安全的。推荐这样做:
from langchain.agents.middleware import AgentMiddleware


class CustomMiddleware(AgentMiddleware):
    def __init__(self):
        pass

    def before_agent(self, state, runtime):
        return {"x": state.get("x", 0) + 1}  # Update graph state instead
不要这样做:
class CustomMiddlewareBad(AgentMiddleware):
    def __init__(self):
        self.x = 1

    def before_agent(self, state, runtime):
        self.x += 1  # Mutation causes race conditions
In-place mutation,例如在 before_agent 中修改 self.x 或在 hooks 中更改其他 shared values,可能导致 subtle bugs 和 race conditions,因为许多 operations 会并发运行(subagents、parallel tools,以及不同 threads 上的 parallel invocations)。关于使用 custom properties 扩展 state 的完整 details,请参阅 Custom middleware - Custom state schema如果必须在 custom middleware 中使用 mutation,请考虑 subagents、parallel tools 或 concurrent agent invocations 同时运行时会发生什么。

Interpreters

使用 interpreters 添加在 scoped QuickJS runtime 中运行 JavaScript 的 eval tool。当 agent 需要以编程方式组合 tools、batch work、在 code 中处理 errors,或在没有完整 shell environment 的情况下 transform structured data 时,Interpreters 很有用。
from deepagents import create_deep_agent
from langchain_quickjs import CodeInterpreterMiddleware

agent = create_deep_agent(
    model="google_genai:gemini-3.5-flash",
    middleware=[CodeInterpreterMiddleware()],
)
有关 setup、programmatic tool calling、interpreter skills 和 limits,请参阅 Interpreters

Subagents

若要隔离 detailed work 并避免 context bloat,请使用 subagents:
import os
from typing import Literal

from deepagents import create_deep_agent
from tavily import TavilyClient

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,
):
    """Run a web search"""
    return tavily_client.search(
        query,
        max_results=max_results,
        include_raw_content=include_raw_content,
        topic=topic,
    )


research_subagent = {
    "name": "research-agent",
    "description": "Used to research more in depth questions",
    "system_prompt": "You are a great researcher",
    "tools": [internet_search],
    "model": "openai:gpt-5.4",  # Optional override, defaults to main agent model
}
subagents = [research_subagent]

agent = create_deep_agent(
    model="google_genai:gemini-3.5-flash",
    subagents=subagents,
)
更多信息请参阅 Subagents

Backends

Deep agent 的 tools 可以使用 virtual file systems 存储、访问和编辑 files。默认情况下,deep agents 使用 StateBackend 如果使用 skillsmemory,必须先将预期的 skill 或 memory files 添加到 backend,然后再创建 agent。
存储在 langgraph state 中的 thread-scoped filesystem backend。Files 会在 thread 内跨 turns 持久存在(通过 checkpointer),但不会跨 threads 共享。
from deepagents import create_deep_agent
from deepagents.backends import StateBackend

# By default we provide a StateBackend
agent = create_deep_agent(model="google_genai:gemini-3.5-flash")

# Under the hood, it looks like
agent2 = create_deep_agent(
    model="openai:gpt-5.4",
    backend=StateBackend(),
)
更多信息请参阅 Backends

Sandboxes

Sandboxes 是 specialized backends,会在带有独立 filesystem 和用于 shell commands 的 execute tool 的 isolated environment 中运行 agent code。 当你希望 deep agent 写 files、安装 dependencies 并运行 commands,同时不更改 local machine 上任何内容时,请使用 sandbox backend。 创建 deep agent 时,将 sandbox backend 传给 backend 即可配置 sandboxes: 更多信息请参阅 Sandboxes

Human-in-the-loop

某些 tool operations 可能比较敏感,需要在执行前获得 human approval。 你可以为每个 tool 配置 approval:
from langchain.tools import tool
from deepagents import create_deep_agent
from langgraph.checkpoint.memory import MemorySaver


@tool
def remove_file(path: str) -> str:
    """Delete a file from the filesystem."""
    return f"Deleted {path}"


@tool
def fetch_file(path: str) -> str:
    """Read a file from the filesystem."""
    return f"Contents of {path}"


@tool
def notify_email(to: str, subject: str, body: str) -> str:
    """Send an email."""
    return f"Sent email to {to}"


# Checkpointer is REQUIRED for human-in-the-loop
checkpointer = MemorySaver()

agent = create_deep_agent(
    model="google_genai:gemini-3.5-flash",
    tools=[remove_file, fetch_file, notify_email],
    interrupt_on={
        "remove_file": True,  # Default: approve, edit, reject, respond
        "fetch_file": False,  # No interrupts needed
        "notify_email": {"allowed_decisions": ["approve", "reject"]},  # No editing
    },
    checkpointer=checkpointer,  # Required!
)
你可以为 agents 和 subagents 配置在 tool call 时 interrupt,也可以从 tool calls 内部进行配置。 更多信息请参阅 Human-in-the-loop

Skills

你可以使用 skills 为 deep agent 提供 new capabilities 和 expertise。 Tools 通常覆盖 native file system actions 或 planning 等 lower level functionality,而 skills 可以包含如何完成 tasks 的详细 instructions、reference info,以及 templates 等其他 assets。 这些 files 只有在 agent 判断 skill 对当前 prompt 有用时才会加载。 这种 progressive disclosure 会减少 agent 在 startup 时必须考虑的 tokens 和 context 数量。 示例 skills 请参阅 Deep Agents example skills 若要向 deep agent 添加 skills,请将其作为 argument 传给 create_deep_agent
from urllib.request import urlopen
from deepagents import create_deep_agent
from deepagents.backends import StateBackend
from deepagents.backends.utils import create_file_data
from langchain_quickjs import CodeInterpreterMiddleware
from langgraph.checkpoint.memory import MemorySaver

checkpointer = MemorySaver()
backend = StateBackend()

skill_url = "https://raw.githubusercontent.com/langchain-ai/deepagents/refs/heads/main/libs/cli/examples/skills/langgraph-docs/SKILL.md"
with urlopen(skill_url) as response:
    skill_content = response.read().decode('utf-8')

skills_files = {
    "/skills/langgraph-docs/SKILL.md": create_file_data(skill_content),
}

agent = create_deep_agent(
    model="google_genai:gemini-3.5-flash",
    backend=backend,
    skills=["/skills/"],
    checkpointer=checkpointer,
    middleware=[CodeInterpreterMiddleware(skills_backend=backend)], # for interpreter skills
)

result = agent.invoke(
    {
        "messages": [{"role": "user", "content": "What is langgraph?"}],
        # Seed the default StateBackend's in-state filesystem (virtual paths must start with "/").
        "files": skills_files,
    },
    config={"configurable": {"thread_id": "12345"}},
)

Memory

使用 AGENTS.md files 为 deep agent 提供 extra context。 创建 deep agent 时,可以向 memory parameter 传入一个或多个 file paths:
from urllib.request import urlopen

from deepagents import create_deep_agent
from deepagents.backends.utils import create_file_data
from langgraph.checkpoint.memory import MemorySaver

with urlopen(
    "https://raw.githubusercontent.com/langchain-ai/deepagents/refs/heads/main/examples/text-to-sql-agent/AGENTS.md"
) as response:
    agents_md = response.read().decode("utf-8")
checkpointer = MemorySaver()

agent = create_deep_agent(
    model="google_genai:gemini-3.5-flash",
    memory=[
        "/AGENTS.md"
    ],
    checkpointer=checkpointer,
)

result = agent.invoke(
    {
        "messages": [
            {
                "role": "user",
                "content": "Please tell me what's in your memory files.",
            }
        ],
        # Seed the default StateBackend's in-state filesystem (virtual paths must start with "/").
        "files": {"/AGENTS.md": create_file_data(agents_md)},
    },
    config={"configurable": {"thread_id": "123456"}},
)

Profiles

Harness profile 是 per-model configuration 的 reusable bundle,当选择 matching model 时,create_deep_agent 会自动应用它。当你希望 behavior 跟随 model 而不是 call site 时,profiles 是合适工具,例如为 Claude instruction style 调优的 system prompt suffix、为 GPT 重写的 tool descriptions,或只对特定 provider 有意义的 extra middleware。 单个 profile 可以携带:custom base system prompt(base_system_prompt)、appended suffix(system_prompt_suffix)、tool description overrides、要 exclude 的 tools 或 middleware、要 inject 的 additional middleware,以及对 auto-added general-purpose subagent 的 edits。
from deepagents import HarnessProfile, register_harness_profile

# Append a system-prompt suffix whenever gpt-5.4 is selected.
register_harness_profile(
    "openai:gpt-5.4",
    HarnessProfile(system_prompt_suffix="Respond in under 100 words."),
)
Registration keys、merge semantics 和 plugin packaging 请参阅 Profiles。更窄的 companion API provider profiles 会为 provider 打包 model-construction arguments(API keys、timeouts、retry settings)。

Structured output

Deep Agents 支持 structured output。 可以在调用 create_deep_agent() 时通过 response_format argument 传入期望的 structured output schema。 当 model 生成 structured data 时,它会被 captured、validated,并在 deep agent state 的 structured_response key 中返回。
import os
from typing import Literal

from pydantic import BaseModel, Field
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,
):
    """Run a web search"""
    return tavily_client.search(
        query,
        max_results=max_results,
        include_raw_content=include_raw_content,
        topic=topic,
    )


class WeatherReport(BaseModel):
    """A structured weather report with current conditions and forecast."""
    location: str = Field(description="The location for this weather report")
    temperature: float = Field(description="Current temperature in Celsius")
    condition: str = Field(
        description="Current weather condition (e.g., sunny, cloudy, rainy)"
    )
    humidity: int = Field(description="Humidity percentage")
    wind_speed: float = Field(description="Wind speed in km/h")
    forecast: str = Field(description="Brief forecast for the next 24 hours")


agent = create_deep_agent(
    model=model,
    response_format=WeatherReport,
    tools=[internet_search],
)

result = agent.invoke(
    {
        "messages": [
            {
                "role": "user",
                "content": "What's the weather like in San Francisco?",
            }
        ]
    }
)

print(result["structured_response"])
# location='San Francisco, California' temperature=18.3 condition='Sunny' humidity=48 wind_speed=7.6 forecast='Pleasant sunny conditions expected to continue with temperatures around 64°F (18°C) during the day, dropping to around 52°F (11°C) at night. Clear skies with minimal precipitation expected.'
更多信息和示例请参阅 response format

Advanced

create_deep_agent 会在 create_agent 之上预组装 middleware stack。若要构建 fully custom agent,并精确选择要包含哪些 capabilities,请参阅 Configure the harness