Agents
An agent is a model calling tools in a loop until a given task is complete.
A harness is everything around that loop: the prompt, the tools, and any middleware that shapes the model’s behavior.
Note
Agent = Model + Harness
The job of a harness: get the model the right context at the right time for the given task.
create_agent is a highly configurable harness. At its simplest, you can create one with:
from langchain.agents import create_agent
agent = create_agent(model="google_genai:gemini-3.6-flash", tools=tools)OpenAI
from langchain.agents import create_agent
agent = create_agent(model="openai:gpt-5.5", tools=tools)Anthropic
from langchain.agents import create_agent
agent = create_agent(model="anthropic:claude-sonnet-5", tools=tools)OpenRouter
from langchain.agents import create_agent
agent = create_agent(model="openrouter:z-ai/glm-5.2", tools=tools)Fireworks
from langchain.agents import create_agent
agent = create_agent(model="fireworks:accounts/fireworks/models/glm-5p2", tools=tools)Baseten
from langchain.agents import create_agent
agent = create_agent(model="baseten:zai-org/GLM-5.2", tools=tools)Ollama
from langchain.agents import create_agent
agent = create_agent(model="ollama:north-mini-code-1.0", tools=tools)Building on that, you can configure the basics directly with the model=, tools=, and system_prompt= parameters. For more advanced capabilities, extend the harness with middleware.
Tip
Deep Agents builds on
create_agentand comes with commonly useful capabilities already assembled, such as planning, file system tools, subagents, and memory. Usecreate_agentwhen you need to configure the harness yourself.
Core components
Model
Pass a model identifier string ("provider:model") or an initialized model instance to select the model for your agent. See Models for parameters, provider setup, and dynamic model selection.
from langchain.agents import create_agent
agent = create_agent(model="google_genai:gemini-3.6-flash", tools=tools)OpenAI
from langchain.agents import create_agent
agent = create_agent(model="openai:gpt-5.5", tools=tools)Anthropic
from langchain.agents import create_agent
agent = create_agent(model="anthropic:claude-sonnet-5", tools=tools)OpenRouter
from langchain.agents import create_agent
agent = create_agent(model="openrouter:z-ai/glm-5.2", tools=tools)Fireworks
from langchain.agents import create_agent
agent = create_agent(model="fireworks:accounts/fireworks/models/glm-5p2", tools=tools)Baseten
from langchain.agents import create_agent
agent = create_agent(model="baseten:zai-org/GLM-5.2", tools=tools)Ollama
from langchain.agents import create_agent
agent = create_agent(model="ollama:north-mini-code-1.0", tools=tools)Tools
To provide the agent with tools, pass any Python callable, LangChain tool, or tool dict. See Tools for tool definition, context access, and dynamic tool selection.
from langchain.agents import create_agent
from langchain.tools import tool
@tool
def search(query: str) -> str:
"""Search for information."""
return f"Results for: {query}"
agent = create_agent(model="google_genai:gemini-3.6-flash", tools=[search])OpenAI
from langchain.agents import create_agent
from langchain.tools import tool
@tool
def search(query: str) -> str:
"""Search for information."""
return f"Results for: {query}"
agent = create_agent(model="openai:gpt-5.5", tools=[search])Anthropic
from langchain.agents import create_agent
from langchain.tools import tool
@tool
def search(query: str) -> str:
"""Search for information."""
return f"Results for: {query}"
agent = create_agent(model="anthropic:claude-sonnet-5", tools=[search])OpenRouter
from langchain.agents import create_agent
from langchain.tools import tool
@tool
def search(query: str) -> str:
"""Search for information."""
return f"Results for: {query}"
agent = create_agent(model="openrouter:z-ai/glm-5.2", tools=[search])Fireworks
from langchain.agents import create_agent
from langchain.tools import tool
@tool
def search(query: str) -> str:
"""Search for information."""
return f"Results for: {query}"
agent = create_agent(model="fireworks:accounts/fireworks/models/glm-5p2", tools=[search])Baseten
from langchain.agents import create_agent
from langchain.tools import tool
@tool
def search(query: str) -> str:
"""Search for information."""
return f"Results for: {query}"
agent = create_agent(model="baseten:zai-org/GLM-5.2", tools=[search])Ollama
from langchain.agents import create_agent
from langchain.tools import tool
@tool
def search(query: str) -> str:
"""Search for information."""
return f"Results for: {query}"
agent = create_agent(model="ollama:north-mini-code-1.0", tools=[search])System prompt
Shape how the agent approaches tasks. The system prompt parameter accepts a string or SystemMessage. For dynamic prompts at runtime, use middleware.
agent = create_agent(
model="google_genai:gemini-3.6-flash",
tools=tools,
system_prompt="You are a helpful assistant. Be concise and accurate.",
)OpenAI
agent = create_agent(
model="openai:gpt-5.5",
tools=tools,
system_prompt="You are a helpful assistant. Be concise and accurate.",
)Anthropic
agent = create_agent(
model="anthropic:claude-sonnet-5",
tools=tools,
system_prompt="You are a helpful assistant. Be concise and accurate.",
)OpenRouter
agent = create_agent(
model="openrouter:z-ai/glm-5.2",
tools=tools,
system_prompt="You are a helpful assistant. Be concise and accurate.",
)Fireworks
agent = create_agent(
model="fireworks:accounts/fireworks/models/glm-5p2",
tools=tools,
system_prompt="You are a helpful assistant. Be concise and accurate.",
)Baseten
agent = create_agent(
model="baseten:zai-org/GLM-5.2",
tools=tools,
system_prompt="You are a helpful assistant. Be concise and accurate.",
)Ollama
agent = create_agent(
model="ollama:north-mini-code-1.0",
tools=tools,
system_prompt="You are a helpful assistant. Be concise and accurate.",
)Structured output
Return a validated schema from the agent using response_format=. See Structured output for strategies and examples.
from pydantic import BaseModel
from langchain.agents import create_agent
class Answer(BaseModel):
summary: str
confidence: float
agent = create_agent(model="google_genai:gemini-3.6-flash", tools=tools, response_format=Answer)
result = agent.invoke({"messages": [{"role": "user", "content": "Summarize AI trends"}]})
result["structured_response"] # Answer(summary=..., confidence=...)OpenAI
from pydantic import BaseModel
from langchain.agents import create_agent
class Answer(BaseModel):
summary: str
confidence: float
agent = create_agent(model="openai:gpt-5.5", tools=tools, response_format=Answer)
result = agent.invoke({"messages": [{"role": "user", "content": "Summarize AI trends"}]})
result["structured_response"] # Answer(summary=..., confidence=...)Anthropic
from pydantic import BaseModel
from langchain.agents import create_agent
class Answer(BaseModel):
summary: str
confidence: float
agent = create_agent(model="anthropic:claude-sonnet-5", tools=tools, response_format=Answer)
result = agent.invoke({"messages": [{"role": "user", "content": "Summarize AI trends"}]})
result["structured_response"] # Answer(summary=..., confidence=...)OpenRouter
from pydantic import BaseModel
from langchain.agents import create_agent
class Answer(BaseModel):
summary: str
confidence: float
agent = create_agent(model="openrouter:z-ai/glm-5.2", tools=tools, response_format=Answer)
result = agent.invoke({"messages": [{"role": "user", "content": "Summarize AI trends"}]})
result["structured_response"] # Answer(summary=..., confidence=...)Fireworks
from pydantic import BaseModel
from langchain.agents import create_agent
class Answer(BaseModel):
summary: str
confidence: float
agent = create_agent(model="fireworks:accounts/fireworks/models/glm-5p2", tools=tools, response_format=Answer)
result = agent.invoke({"messages": [{"role": "user", "content": "Summarize AI trends"}]})
result["structured_response"] # Answer(summary=..., confidence=...)Baseten
from pydantic import BaseModel
from langchain.agents import create_agent
class Answer(BaseModel):
summary: str
confidence: float
agent = create_agent(model="baseten:zai-org/GLM-5.2", tools=tools, response_format=Answer)
result = agent.invoke({"messages": [{"role": "user", "content": "Summarize AI trends"}]})
result["structured_response"] # Answer(summary=..., confidence=...)Ollama
from pydantic import BaseModel
from langchain.agents import create_agent
class Answer(BaseModel):
summary: str
confidence: float
agent = create_agent(model="ollama:north-mini-code-1.0", tools=tools, response_format=Answer)
result = agent.invoke({"messages": [{"role": "user", "content": "Summarize AI trends"}]})
result["structured_response"] # Answer(summary=..., confidence=...)Agent state
Every agent manages its execution context through AgentState, a typed dictionary that holds the current conversation history and any custom fields your tools and middleware need.
The built-in field is:
| Field | Type | Description |
|---|---|---|
messages | list[BaseMessage] | The full conversation history for the current thread. Append-only: new messages are added, never replaced. |
AgentState is also the type signature for every node-style middleware hook (before_model, after_model, and similar). Hooks receive the current state and can return a dict of updates to merge back into it.
To add custom fields (for example, a user_id or a counter), subclass AgentState and pass the subclass to create_agent via state_schema=:
from langchain.agents import AgentState, create_agent
class MyState(AgentState):
user_id: str
call_count: int
agent = create_agent(
model="google_genai:gemini-3.6-flash",
tools=[],
state_schema=MyState, # [!code highlight]
)OpenAI
from langchain.agents import AgentState, create_agent
class MyState(AgentState):
user_id: str
call_count: int
agent = create_agent(
model="openai:gpt-5.5",
tools=[],
state_schema=MyState, # [!code highlight]
)Anthropic
from langchain.agents import AgentState, create_agent
class MyState(AgentState):
user_id: str
call_count: int
agent = create_agent(
model="anthropic:claude-sonnet-5",
tools=[],
state_schema=MyState, # [!code highlight]
)OpenRouter
from langchain.agents import AgentState, create_agent
class MyState(AgentState):
user_id: str
call_count: int
agent = create_agent(
model="openrouter:z-ai/glm-5.2",
tools=[],
state_schema=MyState, # [!code highlight]
)Fireworks
from langchain.agents import AgentState, create_agent
class MyState(AgentState):
user_id: str
call_count: int
agent = create_agent(
model="fireworks:accounts/fireworks/models/glm-5p2",
tools=[],
state_schema=MyState, # [!code highlight]
)Baseten
from langchain.agents import AgentState, create_agent
class MyState(AgentState):
user_id: str
call_count: int
agent = create_agent(
model="baseten:zai-org/GLM-5.2",
tools=[],
state_schema=MyState, # [!code highlight]
)Ollama
from langchain.agents import AgentState, create_agent
class MyState(AgentState):
user_id: str
call_count: int
agent = create_agent(
model="ollama:north-mini-code-1.0",
tools=[],
state_schema=MyState, # [!code highlight]
)For full details, examples, and middleware-level state schemas, see Short-term memory and Custom middleware.
Invocation
Tip
Trace each step of this loop, debug tool calls, and evaluate agent outputs with LangSmith. Follow the tracing quickstart to get set up. We recommend you also set up LangSmith Engine which monitors your traces, detects issues, and proposes fixes.
You can invoke an agent with a message. Behind the scenes that passes an update to the agent’s State. All agents include a sequence of messages in their state; to invoke the agent, pass a new message along with a thread_id so the agent can persist and resume conversation history:
from langchain.agents import create_agent
from langchain_core.utils.uuid import uuid7
from langgraph.checkpoint.memory import InMemorySaver
agent = create_agent(
model="google_genai:gemini-3.6-flash",
tools=[],
checkpointer=InMemorySaver(),
)
config = {"configurable": {"thread_id": str(uuid7())}}
result = agent.invoke(
{"messages": [{"role": "user", "content": "What's the weather in San Francisco?"}]},
config=config,
)
# A follow-up turn on the same conversation: reuse the same thread_id to keep history
result = agent.invoke(
{"messages": [{"role": "user", "content": "What about tomorrow?"}]},
config=config,
)OpenAI
from langchain.agents import create_agent
from langchain_core.utils.uuid import uuid7
from langgraph.checkpoint.memory import InMemorySaver
agent = create_agent(
model="openai:gpt-5.5",
tools=[],
checkpointer=InMemorySaver(),
)
config = {"configurable": {"thread_id": str(uuid7())}}
result = agent.invoke(
{"messages": [{"role": "user", "content": "What's the weather in San Francisco?"}]},
config=config,
)
# A follow-up turn on the same conversation: reuse the same thread_id to keep history
result = agent.invoke(
{"messages": [{"role": "user", "content": "What about tomorrow?"}]},
config=config,
)Anthropic
from langchain.agents import create_agent
from langchain_core.utils.uuid import uuid7
from langgraph.checkpoint.memory import InMemorySaver
agent = create_agent(
model="anthropic:claude-sonnet-5",
tools=[],
checkpointer=InMemorySaver(),
)
config = {"configurable": {"thread_id": str(uuid7())}}
result = agent.invoke(
{"messages": [{"role": "user", "content": "What's the weather in San Francisco?"}]},
config=config,
)
# A follow-up turn on the same conversation: reuse the same thread_id to keep history
result = agent.invoke(
{"messages": [{"role": "user", "content": "What about tomorrow?"}]},
config=config,
)OpenRouter
from langchain.agents import create_agent
from langchain_core.utils.uuid import uuid7
from langgraph.checkpoint.memory import InMemorySaver
agent = create_agent(
model="openrouter:z-ai/glm-5.2",
tools=[],
checkpointer=InMemorySaver(),
)
config = {"configurable": {"thread_id": str(uuid7())}}
result = agent.invoke(
{"messages": [{"role": "user", "content": "What's the weather in San Francisco?"}]},
config=config,
)
# A follow-up turn on the same conversation: reuse the same thread_id to keep history
result = agent.invoke(
{"messages": [{"role": "user", "content": "What about tomorrow?"}]},
config=config,
)Fireworks
from langchain.agents import create_agent
from langchain_core.utils.uuid import uuid7
from langgraph.checkpoint.memory import InMemorySaver
agent = create_agent(
model="fireworks:accounts/fireworks/models/glm-5p2",
tools=[],
checkpointer=InMemorySaver(),
)
config = {"configurable": {"thread_id": str(uuid7())}}
result = agent.invoke(
{"messages": [{"role": "user", "content": "What's the weather in San Francisco?"}]},
config=config,
)
# A follow-up turn on the same conversation: reuse the same thread_id to keep history
result = agent.invoke(
{"messages": [{"role": "user", "content": "What about tomorrow?"}]},
config=config,
)Baseten
from langchain.agents import create_agent
from langchain_core.utils.uuid import uuid7
from langgraph.checkpoint.memory import InMemorySaver
agent = create_agent(
model="baseten:zai-org/GLM-5.2",
tools=[],
checkpointer=InMemorySaver(),
)
config = {"configurable": {"thread_id": str(uuid7())}}
result = agent.invoke(
{"messages": [{"role": "user", "content": "What's the weather in San Francisco?"}]},
config=config,
)
# A follow-up turn on the same conversation: reuse the same thread_id to keep history
result = agent.invoke(
{"messages": [{"role": "user", "content": "What about tomorrow?"}]},
config=config,
)Ollama
from langchain.agents import create_agent
from langchain_core.utils.uuid import uuid7
from langgraph.checkpoint.memory import InMemorySaver
agent = create_agent(
model="ollama:north-mini-code-1.0",
tools=[],
checkpointer=InMemorySaver(),
)
config = {"configurable": {"thread_id": str(uuid7())}}
result = agent.invoke(
{"messages": [{"role": "user", "content": "What's the weather in San Francisco?"}]},
config=config,
)
# A follow-up turn on the same conversation: reuse the same thread_id to keep history
result = agent.invoke(
{"messages": [{"role": "user", "content": "What about tomorrow?"}]},
config=config,
)- View example trace: Open a public LangSmith run for this example.
Note
Persisting conversation history with
thread_idrequires the agent to be configured with a checkpointer. When deployed on LangSmith, a checkpointer is provisioned automatically. Locally, pass one explicitly, for examplecreate_agent(..., checkpointer=InMemorySaver()).
If you also need to pass per-run configuration (such as a user ID, API keys, or feature flags) to tools and middleware, pass it as context alongside config. Define the shape of that data with context_schema and access it through runtime.context:
from dataclasses import dataclass
from langchain.agents import create_agent
from langchain_core.utils.uuid import uuid7
from langgraph.checkpoint.memory import InMemorySaver
@dataclass
class Context:
user_id: str
agent = create_agent(
model="google_genai:gemini-3.6-flash",
tools=[],
context_schema=Context,
checkpointer=InMemorySaver(),
)
result = agent.invoke(
{"messages": [{"role": "user", "content": "What's the weather in San Francisco?"}]},
config={"configurable": {"thread_id": str(uuid7())}},
context=Context(user_id="user-123"),
)OpenAI
from dataclasses import dataclass
from langchain.agents import create_agent
from langchain_core.utils.uuid import uuid7
from langgraph.checkpoint.memory import InMemorySaver
@dataclass
class Context:
user_id: str
agent = create_agent(
model="openai:gpt-5.5",
tools=[],
context_schema=Context,
checkpointer=InMemorySaver(),
)
result = agent.invoke(
{"messages": [{"role": "user", "content": "What's the weather in San Francisco?"}]},
config={"configurable": {"thread_id": str(uuid7())}},
context=Context(user_id="user-123"),
)Anthropic
from dataclasses import dataclass
from langchain.agents import create_agent
from langchain_core.utils.uuid import uuid7
from langgraph.checkpoint.memory import InMemorySaver
@dataclass
class Context:
user_id: str
agent = create_agent(
model="anthropic:claude-sonnet-5",
tools=[],
context_schema=Context,
checkpointer=InMemorySaver(),
)
result = agent.invoke(
{"messages": [{"role": "user", "content": "What's the weather in San Francisco?"}]},
config={"configurable": {"thread_id": str(uuid7())}},
context=Context(user_id="user-123"),
)OpenRouter
from dataclasses import dataclass
from langchain.agents import create_agent
from langchain_core.utils.uuid import uuid7
from langgraph.checkpoint.memory import InMemorySaver
@dataclass
class Context:
user_id: str
agent = create_agent(
model="openrouter:z-ai/glm-5.2",
tools=[],
context_schema=Context,
checkpointer=InMemorySaver(),
)
result = agent.invoke(
{"messages": [{"role": "user", "content": "What's the weather in San Francisco?"}]},
config={"configurable": {"thread_id": str(uuid7())}},
context=Context(user_id="user-123"),
)Fireworks
from dataclasses import dataclass
from langchain.agents import create_agent
from langchain_core.utils.uuid import uuid7
from langgraph.checkpoint.memory import InMemorySaver
@dataclass
class Context:
user_id: str
agent = create_agent(
model="fireworks:accounts/fireworks/models/glm-5p2",
tools=[],
context_schema=Context,
checkpointer=InMemorySaver(),
)
result = agent.invoke(
{"messages": [{"role": "user", "content": "What's the weather in San Francisco?"}]},
config={"configurable": {"thread_id": str(uuid7())}},
context=Context(user_id="user-123"),
)Baseten
from dataclasses import dataclass
from langchain.agents import create_agent
from langchain_core.utils.uuid import uuid7
from langgraph.checkpoint.memory import InMemorySaver
@dataclass
class Context:
user_id: str
agent = create_agent(
model="baseten:zai-org/GLM-5.2",
tools=[],
context_schema=Context,
checkpointer=InMemorySaver(),
)
result = agent.invoke(
{"messages": [{"role": "user", "content": "What's the weather in San Francisco?"}]},
config={"configurable": {"thread_id": str(uuid7())}},
context=Context(user_id="user-123"),
)Ollama
from dataclasses import dataclass
from langchain.agents import create_agent
from langchain_core.utils.uuid import uuid7
from langgraph.checkpoint.memory import InMemorySaver
@dataclass
class Context:
user_id: str
agent = create_agent(
model="ollama:north-mini-code-1.0",
tools=[],
context_schema=Context,
checkpointer=InMemorySaver(),
)
result = agent.invoke(
{"messages": [{"role": "user", "content": "What's the weather in San Francisco?"}]},
config={"configurable": {"thread_id": str(uuid7())}},
context=Context(user_id="user-123"),
)- View example trace: Open a public LangSmith run for this example.
thread_id scopes the conversation (message history, checkpoints), while context carries per-run data your tools and middleware read at invocation time. Both are commonly passed together. See tool context and Runtime for more.
Streaming
invoke returns the final response at the end of a run. If an agent executes multiple tool calls, users often need progress updates before completion. Use streaming to surface intermediate messages and tool activity as they happen.
from langchain.messages import AIMessage, HumanMessage
stream = agent.stream_events(
{"messages": [{"role": "user", "content": "Search for AI news and summarize the findings"}]},
version="v3",
)
for snapshot in stream.values:
# Each snapshot contains the full state at that point
latest_message = snapshot["messages"][-1]
if latest_message.content:
if isinstance(latest_message, HumanMessage):
print(f"User: {latest_message.content}")
elif isinstance(latest_message, AIMessage):
print(f"Agent: {latest_message.content}")
elif latest_message.tool_calls:
print(f"Calling tools: {[tc['name'] for tc in latest_message.tool_calls]}")- View example trace: Open a public LangSmith run for this example.
Tip
For streaming modes, event types, and UI patterns, see Streaming.
Configure the harness
create_agent is highly extensible. Middleware is the primitive for customization: each piece handles one concern, hooks into the agent loop at the right moment, and composes freely with any other. Take exactly what your use case needs and skip the rest.
Common patterns are prebuilt as first-class middleware. You can build anything else as custom middleware.
As agents take on complex work, they need support across a few key areas. The middleware ecosystem provides:
- Execution environment: Tools, filesystem, sandboxes, and code execution
- Context management: Summarization, memory, skills, and prompt caching
- Planning and delegation: Todo lists and subagents for parallel, isolated work
- Fault tolerance: Retries, fallbacks, and call limits
- Guardrails: PII detection and content controls
- Steering: Human-in-the-loop approval before high-impact actions
Tip
create_deep_agentpre-assembles this stack for long-running coding and research tasks (filesystem, summarization, subagents, and prompt caching included by default). See Deep Agents for the full prebuilt harness.
Execution environment
Agents are especially useful when they can take action rather than just generate text. The execution environment gives the agent a workspace: tools it can call, a filesystem for reading and writing files across turns, and code execution for running scripts or shell commands.
from langchain.agents import create_agent
from deepagents.backends import StateBackend
from deepagents.middleware import FilesystemMiddleware
agent = create_agent(
model="google_genai:gemini-3.6-flash",
tools=[search],
middleware=[FilesystemMiddleware(backend=StateBackend())],
)OpenAI
from langchain.agents import create_agent
from deepagents.backends import StateBackend
from deepagents.middleware import FilesystemMiddleware
agent = create_agent(
model="openai:gpt-5.5",
tools=[search],
middleware=[FilesystemMiddleware(backend=StateBackend())],
)Anthropic
from langchain.agents import create_agent
from deepagents.backends import StateBackend
from deepagents.middleware import FilesystemMiddleware
agent = create_agent(
model="anthropic:claude-sonnet-5",
tools=[search],
middleware=[FilesystemMiddleware(backend=StateBackend())],
)OpenRouter
from langchain.agents import create_agent
from deepagents.backends import StateBackend
from deepagents.middleware import FilesystemMiddleware
agent = create_agent(
model="openrouter:z-ai/glm-5.2",
tools=[search],
middleware=[FilesystemMiddleware(backend=StateBackend())],
)Fireworks
from langchain.agents import create_agent
from deepagents.backends import StateBackend
from deepagents.middleware import FilesystemMiddleware
agent = create_agent(
model="fireworks:accounts/fireworks/models/glm-5p2",
tools=[search],
middleware=[FilesystemMiddleware(backend=StateBackend())],
)Baseten
from langchain.agents import create_agent
from deepagents.backends import StateBackend
from deepagents.middleware import FilesystemMiddleware
agent = create_agent(
model="baseten:zai-org/GLM-5.2",
tools=[search],
middleware=[FilesystemMiddleware(backend=StateBackend())],
)Ollama
from langchain.agents import create_agent
from deepagents.backends import StateBackend
from deepagents.middleware import FilesystemMiddleware
agent = create_agent(
model="ollama:north-mini-code-1.0",
tools=[search],
middleware=[FilesystemMiddleware(backend=StateBackend())],
)See FilesystemMiddleware, Sandboxes, Interpreters.
Note
This example imports from the
deepagentspackage. Install it with:pip
pip install deepagentsuv
uv add deepagents
Context management
Every model call has a fixed context window. As an agent runs, that window fills with accumulating history, tool results, and intermediate steps. Summarization compresses history before overflow hits; memory loads persistent instructions at startup so knowledge carries across sessions; skills surface domain knowledge on demand rather than loading everything upfront.
from deepagents.backends import StateBackend
from deepagents.middleware import FilesystemMiddleware, MemoryMiddleware, SkillsMiddleware, SummarizationMiddleware
backend = StateBackend()
model = "google_genai:gemini-3.6-flash"
agent = create_agent(
model=model,
tools=[search],
middleware=[
FilesystemMiddleware(backend=backend),
SummarizationMiddleware(model=model, backend=backend),
MemoryMiddleware(backend=backend, sources=["./AGENTS.md"]),
SkillsMiddleware(backend=backend, sources=["./skills/"]),
],
)OpenAI
from deepagents.backends import StateBackend
from deepagents.middleware import FilesystemMiddleware, MemoryMiddleware, SkillsMiddleware, SummarizationMiddleware
backend = StateBackend()
model = "openai:gpt-5.5"
agent = create_agent(
model=model,
tools=[search],
middleware=[
FilesystemMiddleware(backend=backend),
SummarizationMiddleware(model=model, backend=backend),
MemoryMiddleware(backend=backend, sources=["./AGENTS.md"]),
SkillsMiddleware(backend=backend, sources=["./skills/"]),
],
)Anthropic
from deepagents.backends import StateBackend
from deepagents.middleware import FilesystemMiddleware, MemoryMiddleware, SkillsMiddleware, SummarizationMiddleware
backend = StateBackend()
model = "anthropic:claude-sonnet-5"
agent = create_agent(
model=model,
tools=[search],
middleware=[
FilesystemMiddleware(backend=backend),
SummarizationMiddleware(model=model, backend=backend),
MemoryMiddleware(backend=backend, sources=["./AGENTS.md"]),
SkillsMiddleware(backend=backend, sources=["./skills/"]),
],
)OpenRouter
from deepagents.backends import StateBackend
from deepagents.middleware import FilesystemMiddleware, MemoryMiddleware, SkillsMiddleware, SummarizationMiddleware
backend = StateBackend()
model = "openrouter:z-ai/glm-5.2"
agent = create_agent(
model=model,
tools=[search],
middleware=[
FilesystemMiddleware(backend=backend),
SummarizationMiddleware(model=model, backend=backend),
MemoryMiddleware(backend=backend, sources=["./AGENTS.md"]),
SkillsMiddleware(backend=backend, sources=["./skills/"]),
],
)Fireworks
from deepagents.backends import StateBackend
from deepagents.middleware import FilesystemMiddleware, MemoryMiddleware, SkillsMiddleware, SummarizationMiddleware
backend = StateBackend()
model = "fireworks:accounts/fireworks/models/glm-5p2"
agent = create_agent(
model=model,
tools=[search],
middleware=[
FilesystemMiddleware(backend=backend),
SummarizationMiddleware(model=model, backend=backend),
MemoryMiddleware(backend=backend, sources=["./AGENTS.md"]),
SkillsMiddleware(backend=backend, sources=["./skills/"]),
],
)Baseten
from deepagents.backends import StateBackend
from deepagents.middleware import FilesystemMiddleware, MemoryMiddleware, SkillsMiddleware, SummarizationMiddleware
backend = StateBackend()
model = "baseten:zai-org/GLM-5.2"
agent = create_agent(
model=model,
tools=[search],
middleware=[
FilesystemMiddleware(backend=backend),
SummarizationMiddleware(model=model, backend=backend),
MemoryMiddleware(backend=backend, sources=["./AGENTS.md"]),
SkillsMiddleware(backend=backend, sources=["./skills/"]),
],
)Ollama
from deepagents.backends import StateBackend
from deepagents.middleware import FilesystemMiddleware, MemoryMiddleware, SkillsMiddleware, SummarizationMiddleware
backend = StateBackend()
model = "ollama:north-mini-code-1.0"
agent = create_agent(
model=model,
tools=[search],
middleware=[
FilesystemMiddleware(backend=backend),
SummarizationMiddleware(model=model, backend=backend),
MemoryMiddleware(backend=backend, sources=["./AGENTS.md"]),
SkillsMiddleware(backend=backend, sources=["./skills/"]),
],
)See SummarizationMiddleware, MemoryMiddleware, Skills, Context engineering.
Note
This example imports from the
deepagentspackage. Install it with:pip
pip install deepagentsuv
uv add deepagents
Planning and delegation
Complex tasks often exceed what one context window can handle. Delegation lets the main agent break work into pieces, hand them to subagents that each run in their own isolated context, and stay focused on coordination rather than execution. Work can run in parallel; the main agent’s context stays clean.
from deepagents.backends import StateBackend
from deepagents.middleware import FilesystemMiddleware
from deepagents.middleware.subagents import SubAgentMiddleware
from langchain.agents import create_agent
from langchain.agents.middleware import TodoListMiddleware
from langchain.tools import tool
@tool
def search(query: str) -> str:
"""Search for a query and return a short summary."""
return f"Search results for: {query}"
backend = StateBackend()
agent = create_agent(
model="google_genai:gemini-3.6-flash",
tools=[search],
middleware=[
FilesystemMiddleware(backend=backend),
TodoListMiddleware(),
SubAgentMiddleware(
backend=backend,
subagents=[
{
"name": "researcher",
"description": "Searches and returns a structured summary.",
"system_prompt": "Use the search tool to research the question and summarize key points.",
"tools": [search],
"model": "anthropic:claude-sonnet-4-6",
"middleware": [],
}
],
),
],
)OpenAI
from deepagents.backends import StateBackend
from deepagents.middleware import FilesystemMiddleware
from deepagents.middleware.subagents import SubAgentMiddleware
from langchain.agents import create_agent
from langchain.agents.middleware import TodoListMiddleware
from langchain.tools import tool
@tool
def search(query: str) -> str:
"""Search for a query and return a short summary."""
return f"Search results for: {query}"
backend = StateBackend()
agent = create_agent(
model="openai:gpt-5.5",
tools=[search],
middleware=[
FilesystemMiddleware(backend=backend),
TodoListMiddleware(),
SubAgentMiddleware(
backend=backend,
subagents=[
{
"name": "researcher",
"description": "Searches and returns a structured summary.",
"system_prompt": "Use the search tool to research the question and summarize key points.",
"tools": [search],
"model": "anthropic:claude-sonnet-4-6",
"middleware": [],
}
],
),
],
)Anthropic
from deepagents.backends import StateBackend
from deepagents.middleware import FilesystemMiddleware
from deepagents.middleware.subagents import SubAgentMiddleware
from langchain.agents import create_agent
from langchain.agents.middleware import TodoListMiddleware
from langchain.tools import tool
@tool
def search(query: str) -> str:
"""Search for a query and return a short summary."""
return f"Search results for: {query}"
backend = StateBackend()
agent = create_agent(
model="anthropic:claude-sonnet-5",
tools=[search],
middleware=[
FilesystemMiddleware(backend=backend),
TodoListMiddleware(),
SubAgentMiddleware(
backend=backend,
subagents=[
{
"name": "researcher",
"description": "Searches and returns a structured summary.",
"system_prompt": "Use the search tool to research the question and summarize key points.",
"tools": [search],
"model": "anthropic:claude-sonnet-4-6",
"middleware": [],
}
],
),
],
)OpenRouter
from deepagents.backends import StateBackend
from deepagents.middleware import FilesystemMiddleware
from deepagents.middleware.subagents import SubAgentMiddleware
from langchain.agents import create_agent
from langchain.agents.middleware import TodoListMiddleware
from langchain.tools import tool
@tool
def search(query: str) -> str:
"""Search for a query and return a short summary."""
return f"Search results for: {query}"
backend = StateBackend()
agent = create_agent(
model="openrouter:z-ai/glm-5.2",
tools=[search],
middleware=[
FilesystemMiddleware(backend=backend),
TodoListMiddleware(),
SubAgentMiddleware(
backend=backend,
subagents=[
{
"name": "researcher",
"description": "Searches and returns a structured summary.",
"system_prompt": "Use the search tool to research the question and summarize key points.",
"tools": [search],
"model": "anthropic:claude-sonnet-4-6",
"middleware": [],
}
],
),
],
)Fireworks
from deepagents.backends import StateBackend
from deepagents.middleware import FilesystemMiddleware
from deepagents.middleware.subagents import SubAgentMiddleware
from langchain.agents import create_agent
from langchain.agents.middleware import TodoListMiddleware
from langchain.tools import tool
@tool
def search(query: str) -> str:
"""Search for a query and return a short summary."""
return f"Search results for: {query}"
backend = StateBackend()
agent = create_agent(
model="fireworks:accounts/fireworks/models/glm-5p2",
tools=[search],
middleware=[
FilesystemMiddleware(backend=backend),
TodoListMiddleware(),
SubAgentMiddleware(
backend=backend,
subagents=[
{
"name": "researcher",
"description": "Searches and returns a structured summary.",
"system_prompt": "Use the search tool to research the question and summarize key points.",
"tools": [search],
"model": "anthropic:claude-sonnet-4-6",
"middleware": [],
}
],
),
],
)Baseten
from deepagents.backends import StateBackend
from deepagents.middleware import FilesystemMiddleware
from deepagents.middleware.subagents import SubAgentMiddleware
from langchain.agents import create_agent
from langchain.agents.middleware import TodoListMiddleware
from langchain.tools import tool
@tool
def search(query: str) -> str:
"""Search for a query and return a short summary."""
return f"Search results for: {query}"
backend = StateBackend()
agent = create_agent(
model="baseten:zai-org/GLM-5.2",
tools=[search],
middleware=[
FilesystemMiddleware(backend=backend),
TodoListMiddleware(),
SubAgentMiddleware(
backend=backend,
subagents=[
{
"name": "researcher",
"description": "Searches and returns a structured summary.",
"system_prompt": "Use the search tool to research the question and summarize key points.",
"tools": [search],
"model": "anthropic:claude-sonnet-4-6",
"middleware": [],
}
],
),
],
)Ollama
from deepagents.backends import StateBackend
from deepagents.middleware import FilesystemMiddleware
from deepagents.middleware.subagents import SubAgentMiddleware
from langchain.agents import create_agent
from langchain.agents.middleware import TodoListMiddleware
from langchain.tools import tool
@tool
def search(query: str) -> str:
"""Search for a query and return a short summary."""
return f"Search results for: {query}"
backend = StateBackend()
agent = create_agent(
model="ollama:north-mini-code-1.0",
tools=[search],
middleware=[
FilesystemMiddleware(backend=backend),
TodoListMiddleware(),
SubAgentMiddleware(
backend=backend,
subagents=[
{
"name": "researcher",
"description": "Searches and returns a structured summary.",
"system_prompt": "Use the search tool to research the question and summarize key points.",
"tools": [search],
"model": "anthropic:claude-sonnet-4-6",
"middleware": [],
}
],
),
],
)See Subagents.
Note
This example imports from the
deepagentspackage. Install it with:pip
pip install deepagentsuv
uv add deepagents
Name your agent
Optionally use an identifier for the agent. This is especially useful when embedding the agent as a subgraph in multi-agent systems.
agent = create_agent(model="google_genai:gemini-3.6-flash", tools=tools, name="research_assistant")OpenAI
agent = create_agent(model="openai:gpt-5.5", tools=tools, name="research_assistant")Anthropic
agent = create_agent(model="anthropic:claude-sonnet-5", tools=tools, name="research_assistant")OpenRouter
agent = create_agent(model="openrouter:z-ai/glm-5.2", tools=tools, name="research_assistant")Fireworks
agent = create_agent(model="fireworks:accounts/fireworks/models/glm-5p2", tools=tools, name="research_assistant")Baseten
agent = create_agent(model="baseten:zai-org/GLM-5.2", tools=tools, name="research_assistant")Ollama
agent = create_agent(model="ollama:north-mini-code-1.0", tools=tools, name="research_assistant")Fault tolerance
Agents in production encounter failures that rarely appear in development: rate limits, model timeouts, transient API errors. Fault tolerance middleware handles these at the infrastructure level so your tools and business logic don’t need try/catch around every call.
from langchain.agents import create_agent
from langchain.agents.middleware import ModelRetryMiddleware, ToolRetryMiddleware
from langchain.tools import tool
@tool
def search(query: str) -> str:
"""Search for a query and return a short summary."""
return f"Search results for: {query}"
agent = create_agent(
model="google_genai:gemini-3.6-flash",
tools=[search],
middleware=[
ModelRetryMiddleware(max_retries=3),
ToolRetryMiddleware(max_retries=2),
],
)OpenAI
from langchain.agents import create_agent
from langchain.agents.middleware import ModelRetryMiddleware, ToolRetryMiddleware
from langchain.tools import tool
@tool
def search(query: str) -> str:
"""Search for a query and return a short summary."""
return f"Search results for: {query}"
agent = create_agent(
model="openai:gpt-5.5",
tools=[search],
middleware=[
ModelRetryMiddleware(max_retries=3),
ToolRetryMiddleware(max_retries=2),
],
)Anthropic
from langchain.agents import create_agent
from langchain.agents.middleware import ModelRetryMiddleware, ToolRetryMiddleware
from langchain.tools import tool
@tool
def search(query: str) -> str:
"""Search for a query and return a short summary."""
return f"Search results for: {query}"
agent = create_agent(
model="anthropic:claude-sonnet-5",
tools=[search],
middleware=[
ModelRetryMiddleware(max_retries=3),
ToolRetryMiddleware(max_retries=2),
],
)OpenRouter
from langchain.agents import create_agent
from langchain.agents.middleware import ModelRetryMiddleware, ToolRetryMiddleware
from langchain.tools import tool
@tool
def search(query: str) -> str:
"""Search for a query and return a short summary."""
return f"Search results for: {query}"
agent = create_agent(
model="openrouter:z-ai/glm-5.2",
tools=[search],
middleware=[
ModelRetryMiddleware(max_retries=3),
ToolRetryMiddleware(max_retries=2),
],
)Fireworks
from langchain.agents import create_agent
from langchain.agents.middleware import ModelRetryMiddleware, ToolRetryMiddleware
from langchain.tools import tool
@tool
def search(query: str) -> str:
"""Search for a query and return a short summary."""
return f"Search results for: {query}"
agent = create_agent(
model="fireworks:accounts/fireworks/models/glm-5p2",
tools=[search],
middleware=[
ModelRetryMiddleware(max_retries=3),
ToolRetryMiddleware(max_retries=2),
],
)Baseten
from langchain.agents import create_agent
from langchain.agents.middleware import ModelRetryMiddleware, ToolRetryMiddleware
from langchain.tools import tool
@tool
def search(query: str) -> str:
"""Search for a query and return a short summary."""
return f"Search results for: {query}"
agent = create_agent(
model="baseten:zai-org/GLM-5.2",
tools=[search],
middleware=[
ModelRetryMiddleware(max_retries=3),
ToolRetryMiddleware(max_retries=2),
],
)Ollama
from langchain.agents import create_agent
from langchain.agents.middleware import ModelRetryMiddleware, ToolRetryMiddleware
from langchain.tools import tool
@tool
def search(query: str) -> str:
"""Search for a query and return a short summary."""
return f"Search results for: {query}"
agent = create_agent(
model="ollama:north-mini-code-1.0",
tools=[search],
middleware=[
ModelRetryMiddleware(max_retries=3),
ToolRetryMiddleware(max_retries=2),
],
)See ModelRetryMiddleware, ToolRetryMiddleware, Prebuilt middleware.
Guardrails
Some policies can’t live in a prompt—they need to be enforced deterministically regardless of what the model does. Guardrails intercept data as it flows through the agent loop, applying compliance rules or content policies before tool results reach the model’s context.
from langchain.agents import create_agent
from langchain.agents.middleware import PIIMiddleware
from langchain.tools import tool
@tool
def search(query: str) -> str:
"""Search for a query and return a short summary."""
return f"Search results for: {query}"
agent = create_agent(
model="google_genai:gemini-3.6-flash",
tools=[search],
middleware=[PIIMiddleware("email")],
)OpenAI
from langchain.agents import create_agent
from langchain.agents.middleware import PIIMiddleware
from langchain.tools import tool
@tool
def search(query: str) -> str:
"""Search for a query and return a short summary."""
return f"Search results for: {query}"
agent = create_agent(
model="openai:gpt-5.5",
tools=[search],
middleware=[PIIMiddleware("email")],
)Anthropic
from langchain.agents import create_agent
from langchain.agents.middleware import PIIMiddleware
from langchain.tools import tool
@tool
def search(query: str) -> str:
"""Search for a query and return a short summary."""
return f"Search results for: {query}"
agent = create_agent(
model="anthropic:claude-sonnet-5",
tools=[search],
middleware=[PIIMiddleware("email")],
)OpenRouter
from langchain.agents import create_agent
from langchain.agents.middleware import PIIMiddleware
from langchain.tools import tool
@tool
def search(query: str) -> str:
"""Search for a query and return a short summary."""
return f"Search results for: {query}"
agent = create_agent(
model="openrouter:z-ai/glm-5.2",
tools=[search],
middleware=[PIIMiddleware("email")],
)Fireworks
from langchain.agents import create_agent
from langchain.agents.middleware import PIIMiddleware
from langchain.tools import tool
@tool
def search(query: str) -> str:
"""Search for a query and return a short summary."""
return f"Search results for: {query}"
agent = create_agent(
model="fireworks:accounts/fireworks/models/glm-5p2",
tools=[search],
middleware=[PIIMiddleware("email")],
)Baseten
from langchain.agents import create_agent
from langchain.agents.middleware import PIIMiddleware
from langchain.tools import tool
@tool
def search(query: str) -> str:
"""Search for a query and return a short summary."""
return f"Search results for: {query}"
agent = create_agent(
model="baseten:zai-org/GLM-5.2",
tools=[search],
middleware=[PIIMiddleware("email")],
)Ollama
from langchain.agents import create_agent
from langchain.agents.middleware import PIIMiddleware
from langchain.tools import tool
@tool
def search(query: str) -> str:
"""Search for a query and return a short summary."""
return f"Search results for: {query}"
agent = create_agent(
model="ollama:north-mini-code-1.0",
tools=[search],
middleware=[PIIMiddleware("email")],
)See PIIMiddleware, Prebuilt middleware.
Steering
Full autonomy isn’t always appropriate. Steering lets you place humans at specific decision points—before destructive writes, expensive API calls, or anything requiring judgment—without restructuring your agent. The agent pauses and waits; a human approves, edits, or rejects; execution continues.
from langchain.agents import create_agent
from langchain.agents.middleware import HumanInTheLoopMiddleware
from langchain.tools import tool
@tool
def search(query: str) -> str:
"""Search for a query and return a short summary."""
return f"Search results for: {query}"
agent = create_agent(
model="google_genai:gemini-3.6-flash",
tools=[search],
middleware=[HumanInTheLoopMiddleware(interrupt_on={"write_file": True})],
)OpenAI
from langchain.agents import create_agent
from langchain.agents.middleware import HumanInTheLoopMiddleware
from langchain.tools import tool
@tool
def search(query: str) -> str:
"""Search for a query and return a short summary."""
return f"Search results for: {query}"
agent = create_agent(
model="openai:gpt-5.5",
tools=[search],
middleware=[HumanInTheLoopMiddleware(interrupt_on={"write_file": True})],
)Anthropic
from langchain.agents import create_agent
from langchain.agents.middleware import HumanInTheLoopMiddleware
from langchain.tools import tool
@tool
def search(query: str) -> str:
"""Search for a query and return a short summary."""
return f"Search results for: {query}"
agent = create_agent(
model="anthropic:claude-sonnet-5",
tools=[search],
middleware=[HumanInTheLoopMiddleware(interrupt_on={"write_file": True})],
)OpenRouter
from langchain.agents import create_agent
from langchain.agents.middleware import HumanInTheLoopMiddleware
from langchain.tools import tool
@tool
def search(query: str) -> str:
"""Search for a query and return a short summary."""
return f"Search results for: {query}"
agent = create_agent(
model="openrouter:z-ai/glm-5.2",
tools=[search],
middleware=[HumanInTheLoopMiddleware(interrupt_on={"write_file": True})],
)Fireworks
from langchain.agents import create_agent
from langchain.agents.middleware import HumanInTheLoopMiddleware
from langchain.tools import tool
@tool
def search(query: str) -> str:
"""Search for a query and return a short summary."""
return f"Search results for: {query}"
agent = create_agent(
model="fireworks:accounts/fireworks/models/glm-5p2",
tools=[search],
middleware=[HumanInTheLoopMiddleware(interrupt_on={"write_file": True})],
)Baseten
from langchain.agents import create_agent
from langchain.agents.middleware import HumanInTheLoopMiddleware
from langchain.tools import tool
@tool
def search(query: str) -> str:
"""Search for a query and return a short summary."""
return f"Search results for: {query}"
agent = create_agent(
model="baseten:zai-org/GLM-5.2",
tools=[search],
middleware=[HumanInTheLoopMiddleware(interrupt_on={"write_file": True})],
)Ollama
from langchain.agents import create_agent
from langchain.agents.middleware import HumanInTheLoopMiddleware
from langchain.tools import tool
@tool
def search(query: str) -> str:
"""Search for a query and return a short summary."""
return f"Search results for: {query}"
agent = create_agent(
model="ollama:north-mini-code-1.0",
tools=[search],
middleware=[HumanInTheLoopMiddleware(interrupt_on={"write_file": True})],
)See HumanInTheLoopMiddleware, Human-in-the-loop.
Middleware resources
- Middleware overview: How the middleware stack works and when hooks fire
- Prebuilt middleware: Full reference with configuration examples
- Custom middleware: Write your own hooks for business logic, PII scrubbing, and more