本页还没有译文
本页 139 段还没译成日本語,下面显示的是英文原文。Customize Deep Agents
还没翻译译自英文(docs.langchain.com)本页 139 段都还没译
Build the harness around your goal. create_deep_agent gives you a production-ready foundation: connect it to your data, shape its behavior, and add the capabilities your use case needs.
createDeepAgent ships with a pre-assembled harness: filesystem, summarization, subagents, and prompt caching by default. The parameters below let you define the agent's persona, connect it to your data and tools, and extend the Deep Agents stack with additional middleware.
import { createDeepAgent } from "deepagents";
const agent = await createDeepAgent({
model: "google:gemini-3.6-flash",
systemPrompt: "You are a helpful assistant.",
tools: [search, fetchUrl],
memory: ["./AGENTS.md"],
skills: ["./skills/"],
});import { createDeepAgent } from "deepagents";
const agent = await createDeepAgent({
model: "openai:gpt-5.5",
systemPrompt: "You are a helpful assistant.",
tools: [search, fetchUrl],
memory: ["./AGENTS.md"],
skills: ["./skills/"],
});import { createDeepAgent } from "deepagents";
const agent = await createDeepAgent({
model: "anthropic:claude-sonnet-5",
systemPrompt: "You are a helpful assistant.",
tools: [search, fetchUrl],
memory: ["./AGENTS.md"],
skills: ["./skills/"],
});import { createDeepAgent } from "deepagents";
const agent = await createDeepAgent({
model: "openrouter:z-ai/glm-5.2",
systemPrompt: "You are a helpful assistant.",
tools: [search, fetchUrl],
memory: ["./AGENTS.md"],
skills: ["./skills/"],
});import { createDeepAgent } from "deepagents";
const agent = await createDeepAgent({
model: "fireworks:accounts/fireworks/models/glm-5p2",
systemPrompt: "You are a helpful assistant.",
tools: [search, fetchUrl],
memory: ["./AGENTS.md"],
skills: ["./skills/"],
});import { createDeepAgent } from "deepagents";
const agent = await createDeepAgent({
model: "baseten:zai-org/GLM-5.2",
systemPrompt: "You are a helpful assistant.",
tools: [search, fetchUrl],
memory: ["./AGENTS.md"],
skills: ["./skills/"],
});import { createDeepAgent } from "deepagents";
const agent = await createDeepAgent({
model: "ollama:north-mini-code-1.0",
systemPrompt: "You are a helpful assistant.",
tools: [search, fetchUrl],
memory: ["./AGENTS.md"],
skills: ["./skills/"],
});| Parameter | What it does |
|---|---|
model | Which model to use |
systemPrompt | Custom instructions for the agent |
tools | Domain tools the agent can call |
memory | AGENTS.md files loaded at startup |
skills | Skills directory for on-demand knowledge |
backend | Filesystem backend (StateBackend by default) |
permissions | Path-level access control for the filesystem |
subagents | Custom subagents for delegated tasks |
middleware | Extra middleware appended to the Deep Agents stack |
interruptOn | Pause before tool calls for human approval |
responseFormat | Structured output schema |
contextSchema | Per-run runtime context schema (user IDs, API keys, feature flags) |
For the full parameter list, see the createDeepAgent API reference. To compose a fully custom harness from scratch, see Configure the harness.
Tip
As you add tools, subagents, and backends, use LangSmith to trace how each piece behaves together. Follow the observability quickstart to get set up, and see Going to production for deployment on LangSmith.
We recommend you also set up LangSmith Engine, which monitors your traces, detects issues, and proposes fixes.
Model
Pass a model string in provider:model format, or an initialized model instance. See supported models for all providers and suggested models for tested recommendations.
Tip
Use the provider:model format (for example openai:gpt-5.5) to quickly switch between models.
👉 Read the OpenAI chat model integration docs
npm install @langchain/openai deepagentspnpm install @langchain/openai deepagentsyarn add @langchain/openai deepagentsbun add @langchain/openai deepagentsimport { createDeepAgent } from "deepagents";
process.env.OPENAI_API_KEY = "your-api-key";
const agent = createDeepAgent({ model: "gpt-5.5" });
// this calls initChatModel for the specified model with default parameters
// to use specific model parameters, use initChatModel directlyimport { initChatModel } from "langchain";
import { createDeepAgent } from "deepagents";
process.env.OPENAI_API_KEY = "your-api-key";
const model = await initChatModel("gpt-5.5");
const agent = createDeepAgent({
model,
temperature: 0,
});import { ChatOpenAI } from "@langchain/openai";
import { createDeepAgent } from "deepagents";
const agent = createDeepAgent({
model: new ChatOpenAI({
model: "gpt-5.5",
apiKey: "your-api-key",
temperature: 0,
}),
});👉 Read the Anthropic chat model integration docs
npm install @langchain/anthropic deepagentspnpm install @langchain/anthropic deepagentsyarn add @langchain/anthropic deepagentsbun add @langchain/anthropic deepagentsimport { createDeepAgent } from "deepagents";
process.env.ANTHROPIC_API_KEY = "your-api-key";
const agent = createDeepAgent({ model: "anthropic:claude-sonnet-4-6" });
// this calls initChatModel for the specified model with default parameters
// to use specific model parameters, use initChatModel directlyimport { initChatModel } from "langchain";
import { createDeepAgent } from "deepagents";
process.env.ANTHROPIC_API_KEY = "your-api-key";
const model = await initChatModel("claude-sonnet-4-6");
const agent = createDeepAgent({
model,
temperature: 0,
});import { ChatAnthropic } from "@langchain/anthropic";
import { createDeepAgent } from "deepagents";
const agent = createDeepAgent({
model: new ChatAnthropic({
model: "claude-sonnet-4-6",
apiKey: "your-api-key",
temperature: 0,
}),
});👉 Read the Azure chat model integration docs
npm install @langchain/azure deepagentspnpm install @langchain/azure deepagentsyarn add @langchain/azure deepagentsbun add @langchain/azure deepagentsimport { createDeepAgent } from "deepagents";
process.env.AZURE_OPENAI_API_KEY = "your-api-key";
process.env.AZURE_OPENAI_ENDPOINT = "your-endpoint";
process.env.OPENAI_API_VERSION = "your-api-version";
const agent = createDeepAgent({ model: "azure_openai:gpt-5.5" });
// this calls initChatModel for the specified model with default parameters
// to use specific model parameters, use initChatModel directlyimport { initChatModel } from "langchain";
import { createDeepAgent } from "deepagents";
process.env.AZURE_OPENAI_API_KEY = "your-api-key";
process.env.AZURE_OPENAI_ENDPOINT = "your-endpoint";
process.env.OPENAI_API_VERSION = "your-api-version";
const model = await initChatModel("azure_openai:gpt-5.5");
const agent = createDeepAgent({
model,
temperature: 0,
});import { AzureChatOpenAI } from "@langchain/openai";
import { createDeepAgent } from "deepagents";
const agent = createDeepAgent({
model: new AzureChatOpenAI({
model: "gpt-5.5",
azureOpenAIApiKey: "your-api-key",
azureOpenAIApiEndpoint: "your-endpoint",
azureOpenAIApiVersion: "your-api-version",
temperature: 0,
}),
});👉 Read the ChatGoogle chat model integration docs
npm install @langchain/google deepagentspnpm install @langchain/google deepagentsyarn add @langchain/google deepagentsbun add @langchain/google deepagentsimport { createDeepAgent } from "deepagents";
process.env.GOOGLE_API_KEY = "your-api-key";
const agent = createDeepAgent({ model: "google:gemini-3.1-pro-preview" });
// this calls initChatModel for the specified model with default parameters
// to use specific model parameters, use initChatModel directlyimport { initChatModel } from "langchain";
import { createDeepAgent } from "deepagents";
process.env.GOOGLE_API_KEY = "your-api-key";
const model = await initChatModel("google:gemini-3.1-pro-preview");
const agent = createDeepAgent({
model,
temperature: 0,
});import { ChatGoogle } from "@langchain/google/node";
import { createDeepAgent } from "deepagents";
const agent = createDeepAgent({
model: new ChatGoogle({
model: "gemini-3.1-pro-preview",
apiKey: "your-api-key",
temperature: 0,
}),
});👉 Read the AWS Bedrock chat model integration docs
npm install @langchain/aws deepagentspnpm install @langchain/aws deepagentsyarn add @langchain/aws deepagentsbun add @langchain/aws deepagentsimport { createDeepAgent } from "deepagents";
// Follow the steps here to configure your credentials:
// https://docs.aws.amazon.com/bedrock/latest/userguide/getting-started.html
const agent = createDeepAgent({ model: "bedrock:anthropic.claude-sonnet-4-6" });
// this calls initChatModel for the specified model with default parameters
// to use specific model parameters, use initChatModel directlyimport { initChatModel } from "langchain";
import { createDeepAgent } from "deepagents";
// Follow the steps here to configure your credentials:
// https://docs.aws.amazon.com/bedrock/latest/userguide/getting-started.html
const model = await initChatModel("bedrock:anthropic.claude-sonnet-4-6");
const agent = createDeepAgent({
model,
temperature: 0,
});import { ChatBedrockConverse } from "@langchain/aws";
import { createDeepAgent } from "deepagents";
// Follow the steps here to configure your credentials:
// https://docs.aws.amazon.com/bedrock/latest/userguide/getting-started.html
const agent = createDeepAgent({
model: new ChatBedrockConverse({
model: "anthropic.claude-sonnet-4-6",
region: "us-east-2",
temperature: 0,
}),
});Pass any supported model string, or an initialized model instance:
import { initChatModel } from "langchain";
import { createDeepAgent } from "deepagents";
const model = await initChatModel("provider:model-name");
const agent = createDeepAgent({ model });Tip
Chat models automatically retry transient API failures (with exponential backoff). For defaults, limits, and code samples for tuning max_retries / timeout live on the LangChain Models page.
Tools
In addition to built-in tools for file management and subagent spawning, you can provide custom tools:
import { tool } from "langchain";
import { TavilySearch } from "@langchain/tavily";
import { createDeepAgent } from "deepagents";
import { z } from "zod";
const internetSearch = tool(
async ({
query,
maxResults = 5,
topic = "general",
includeRawContent = false,
}: {
query: string;
maxResults?: number;
topic?: "general" | "news" | "finance";
includeRawContent?: boolean;
}) => {
const tavilySearch = new TavilySearch({
maxResults,
tavilyApiKey: process.env.TAVILY_API_KEY,
includeRawContent,
topic,
});
return await tavilySearch._call({ query });
},
{
name: "internet_search",
description: "Run a web search",
schema: z.object({
query: z.string().describe("The search query"),
maxResults: z.number().optional().default(5),
topic: z
.enum(["general", "news", "finance"])
.optional()
.default("general"),
includeRawContent: z.boolean().optional().default(false),
}),
},
);
const agent = createDeepAgent({
model: "google:gemini-3.6-flash",
tools: [internetSearch],
});import { tool } from "langchain";
import { TavilySearch } from "@langchain/tavily";
import { createDeepAgent } from "deepagents";
import { z } from "zod";
const internetSearch = tool(
async ({
query,
maxResults = 5,
topic = "general",
includeRawContent = false,
}: {
query: string;
maxResults?: number;
topic?: "general" | "news" | "finance";
includeRawContent?: boolean;
}) => {
const tavilySearch = new TavilySearch({
maxResults,
tavilyApiKey: process.env.TAVILY_API_KEY,
includeRawContent,
topic,
});
return await tavilySearch._call({ query });
},
{
name: "internet_search",
description: "Run a web search",
schema: z.object({
query: z.string().describe("The search query"),
maxResults: z.number().optional().default(5),
topic: z
.enum(["general", "news", "finance"])
.optional()
.default("general"),
includeRawContent: z.boolean().optional().default(false),
}),
},
);
const agent = createDeepAgent({
model: "openai:gpt-5.5",
tools: [internetSearch],
});import { tool } from "langchain";
import { TavilySearch } from "@langchain/tavily";
import { createDeepAgent } from "deepagents";
import { z } from "zod";
const internetSearch = tool(
async ({
query,
maxResults = 5,
topic = "general",
includeRawContent = false,
}: {
query: string;
maxResults?: number;
topic?: "general" | "news" | "finance";
includeRawContent?: boolean;
}) => {
const tavilySearch = new TavilySearch({
maxResults,
tavilyApiKey: process.env.TAVILY_API_KEY,
includeRawContent,
topic,
});
return await tavilySearch._call({ query });
},
{
name: "internet_search",
description: "Run a web search",
schema: z.object({
query: z.string().describe("The search query"),
maxResults: z.number().optional().default(5),
topic: z
.enum(["general", "news", "finance"])
.optional()
.default("general"),
includeRawContent: z.boolean().optional().default(false),
}),
},
);
const agent = createDeepAgent({
model: "anthropic:claude-sonnet-5",
tools: [internetSearch],
});
import { tool } from "langchain";
import { TavilySearch } from "@langchain/tavily";
import { createDeepAgent } from "deepagents";
import { z } from "zod";
const internetSearch = tool(
async ({
query,
maxResults = 5,
topic = "general",
includeRawContent = false,
}: {
query: string;
maxResults?: number;
topic?: "general" | "news" | "finance";
includeRawContent?: boolean;
}) => {
const tavilySearch = new TavilySearch({
maxResults,
tavilyApiKey: process.env.TAVILY_API_KEY,
includeRawContent,
topic,
});
return await tavilySearch._call({ query });
},
{
name: "internet_search",
description: "Run a web search",
schema: z.object({
query: z.string().describe("The search query"),
maxResults: z.number().optional().default(5),
topic: z
.enum(["general", "news", "finance"])
.optional()
.default("general"),
includeRawContent: z.boolean().optional().default(false),
}),
},
);
const agent = createDeepAgent({
model: "openrouter:z-ai/glm-5.2",
tools: [internetSearch],
});
import { tool } from "langchain";
import { TavilySearch } from "@langchain/tavily";
import { createDeepAgent } from "deepagents";
import { z } from "zod";
const internetSearch = tool(
async ({
query,
maxResults = 5,
topic = "general",
includeRawContent = false,
}: {
query: string;
maxResults?: number;
topic?: "general" | "news" | "finance";
includeRawContent?: boolean;
}) => {
const tavilySearch = new TavilySearch({
maxResults,
tavilyApiKey: process.env.TAVILY_API_KEY,
includeRawContent,
topic,
});
return await tavilySearch._call({ query });
},
{
name: "internet_search",
description: "Run a web search",
schema: z.object({
query: z.string().describe("The search query"),
maxResults: z.number().optional().default(5),
topic: z
.enum(["general", "news", "finance"])
.optional()
.default("general"),
includeRawContent: z.boolean().optional().default(false),
}),
},
);
const agent = createDeepAgent({
model: "fireworks:accounts/fireworks/models/glm-5p2",
tools: [internetSearch],
});
import { tool } from "langchain";
import { TavilySearch } from "@langchain/tavily";
import { createDeepAgent } from "deepagents";
import { z } from "zod";
const internetSearch = tool(
async ({
query,
maxResults = 5,
topic = "general",
includeRawContent = false,
}: {
query: string;
maxResults?: number;
topic?: "general" | "news" | "finance";
includeRawContent?: boolean;
}) => {
const tavilySearch = new TavilySearch({
maxResults,
tavilyApiKey: process.env.TAVILY_API_KEY,
includeRawContent,
topic,
});
return await tavilySearch._call({ query });
},
{
name: "internet_search",
description: "Run a web search",
schema: z.object({
query: z.string().describe("The search query"),
maxResults: z.number().optional().default(5),
topic: z
.enum(["general", "news", "finance"])
.optional()
.default("general"),
includeRawContent: z.boolean().optional().default(false),
}),
},
);
const agent = createDeepAgent({
model: "baseten:zai-org/GLM-5.2",
tools: [internetSearch],
});
import { tool } from "langchain";
import { TavilySearch } from "@langchain/tavily";
import { createDeepAgent } from "deepagents";
import { z } from "zod";
const internetSearch = tool(
async ({
query,
maxResults = 5,
topic = "general",
includeRawContent = false,
}: {
query: string;
maxResults?: number;
topic?: "general" | "news" | "finance";
includeRawContent?: boolean;
}) => {
const tavilySearch = new TavilySearch({
maxResults,
tavilyApiKey: process.env.TAVILY_API_KEY,
includeRawContent,
topic,
});
return await tavilySearch._call({ query });
},
{
name: "internet_search",
description: "Run a web search",
schema: z.object({
query: z.string().describe("The search query"),
maxResults: z.number().optional().default(5),
topic: z
.enum(["general", "news", "finance"])
.optional()
.default("general"),
includeRawContent: z.boolean().optional().default(false),
}),
},
);
const agent = createDeepAgent({
model: "ollama:north-mini-code-1.0",
tools: [internetSearch],
});
MCP tools
Tip
Deep Agents fully support Model Context Protocol (MCP) tools. You can load tools from any MCP server—databases, APIs, file systems, and more—and pass them directly to create_deep_agent.
Install @langchain/mcp-adapters to connect to MCP servers:
npm install @langchain/mcp-adaptersimport { createDeepAgent } from "deepagents";
const { MultiServerMCPClient } = await import("@langchain/mcp-adapters");
const client = new MultiServerMCPClient({
my_server: {
transport: "http",
url: "http://localhost:8000/mcp",
},
});
const tools = await client.getTools();
const agent = await createDeepAgent({
model: "google:gemini-3.6-flash",
tools,
});
const result = await agent.invoke({
messages: [{ role: "user", content: "Use the MCP server to help me." }],
});
import { createDeepAgent } from "deepagents";
const { MultiServerMCPClient } = await import("@langchain/mcp-adapters");
const client = new MultiServerMCPClient({
my_server: {
transport: "http",
url: "http://localhost:8000/mcp",
},
});
const tools = await client.getTools();
const agent = await createDeepAgent({
model: "openai:gpt-5.5",
tools,
});
const result = await agent.invoke({
messages: [{ role: "user", content: "Use the MCP server to help me." }],
});
import { createDeepAgent } from "deepagents";
const { MultiServerMCPClient } = await import("@langchain/mcp-adapters");
const client = new MultiServerMCPClient({
my_server: {
transport: "http",
url: "http://localhost:8000/mcp",
},
});
const tools = await client.getTools();
const agent = await createDeepAgent({
model: "anthropic:claude-sonnet-5",
tools,
});
const result = await agent.invoke({
messages: [{ role: "user", content: "Use the MCP server to help me." }],
});
import { createDeepAgent } from "deepagents";
const { MultiServerMCPClient } = await import("@langchain/mcp-adapters");
const client = new MultiServerMCPClient({
my_server: {
transport: "http",
url: "http://localhost:8000/mcp",
},
});
const tools = await client.getTools();
const agent = await createDeepAgent({
model: "openrouter:z-ai/glm-5.2",
tools,
});
const result = await agent.invoke({
messages: [{ role: "user", content: "Use the MCP server to help me." }],
});
import { createDeepAgent } from "deepagents";
const { MultiServerMCPClient } = await import("@langchain/mcp-adapters");
const client = new MultiServerMCPClient({
my_server: {
transport: "http",
url: "http://localhost:8000/mcp",
},
});
const tools = await client.getTools();
const agent = await createDeepAgent({
model: "fireworks:accounts/fireworks/models/glm-5p2",
tools,
});
const result = await agent.invoke({
messages: [{ role: "user", content: "Use the MCP server to help me." }],
});
import { createDeepAgent } from "deepagents";
const { MultiServerMCPClient } = await import("@langchain/mcp-adapters");
const client = new MultiServerMCPClient({
my_server: {
transport: "http",
url: "http://localhost:8000/mcp",
},
});
const tools = await client.getTools();
const agent = await createDeepAgent({
model: "baseten:zai-org/GLM-5.2",
tools,
});
const result = await agent.invoke({
messages: [{ role: "user", content: "Use the MCP server to help me." }],
});
import { createDeepAgent } from "deepagents";
const { MultiServerMCPClient } = await import("@langchain/mcp-adapters");
const client = new MultiServerMCPClient({
my_server: {
transport: "http",
url: "http://localhost:8000/mcp",
},
});
const tools = await client.getTools();
const agent = await createDeepAgent({
model: "ollama:north-mini-code-1.0",
tools,
});
const result = await agent.invoke({
messages: [{ role: "user", content: "Use the MCP server to help me." }],
});
For detailed configuration options including stdio servers, OAuth authentication, tool filtering, and stateful sessions, see the full MCP guide.
System prompt
Pass system_prompt= to give the agent your own instructions:
import { createDeepAgent } from "deepagents";
const researchInstructions =
`You are an expert researcher. ` +
`Your job is to conduct thorough research, and then ` +
`write a polished report.`;
const agent = createDeepAgent({
model: "google:gemini-3.6-flash",
systemPrompt: researchInstructions,
});
import { createDeepAgent } from "deepagents";
const researchInstructions =
`You are an expert researcher. ` +
`Your job is to conduct thorough research, and then ` +
`write a polished report.`;
const agent = createDeepAgent({
model: "openai:gpt-5.5",
systemPrompt: researchInstructions,
});
import { createDeepAgent } from "deepagents";
const researchInstructions =
`You are an expert researcher. ` +
`Your job is to conduct thorough research, and then ` +
`write a polished report.`;
const agent = createDeepAgent({
model: "anthropic:claude-sonnet-5",
systemPrompt: researchInstructions,
});
import { createDeepAgent } from "deepagents";
const researchInstructions =
`You are an expert researcher. ` +
`Your job is to conduct thorough research, and then ` +
`write a polished report.`;
const agent = createDeepAgent({
model: "openrouter:z-ai/glm-5.2",
systemPrompt: researchInstructions,
});
import { createDeepAgent } from "deepagents";
const researchInstructions =
`You are an expert researcher. ` +
`Your job is to conduct thorough research, and then ` +
`write a polished report.`;
const agent = createDeepAgent({
model: "fireworks:accounts/fireworks/models/glm-5p2",
systemPrompt: researchInstructions,
});
import { createDeepAgent } from "deepagents";
const researchInstructions =
`You are an expert researcher. ` +
`Your job is to conduct thorough research, and then ` +
`write a polished report.`;
const agent = createDeepAgent({
model: "baseten:zai-org/GLM-5.2",
systemPrompt: researchInstructions,
});
import { createDeepAgent } from "deepagents";
const researchInstructions =
`You are an expert researcher. ` +
`Your job is to conduct thorough research, and then ` +
`write a polished report.`;
const agent = createDeepAgent({
model: "ollama:north-mini-code-1.0",
systemPrompt: researchInstructions,
});
Note
Besides a string, the main agent also accepts a SystemMessage with structured content blocks; Deep Agents preserve those blocks (subagent dictionary specs remain strings).
Middleware
Deep Agents support any middleware, including the built-in middleware listed below, prebuilt middleware from LangChain, provider-specific middleware, and custom middleware you write yourself.
Pass middleware to the middleware argument of createDeepAgent. Each instance is merged into the Deep Agents stack by its .name. An instance whose name matches a built-in entry replaces that entry in place. Anything else is inserted after PatchToolCallsMiddleware.
Deep Agents stack
createDeepAgent builds middleware in a fixed order. The bare stack is what you get with only a model. The full stack is the complete assembly order, including slots that appear only when you pass optional arguments or when the resolved harness profile contributes them.
Bare stack
With only a model (no other optional arguments), the main agent typically includes:
FilesystemMiddlewareSubAgentMiddleware(because the general-purpose subagent is auto-added unless a harness profile disables it)SummarizationMiddlewarePatchToolCallsMiddleware- Prompt caching middleware (added for supported providers; no-ops elsewhere)
- Harness profile extras and excluded-tool filtering, if the resolved model profile defines them
UnsupportedContentMiddleware
Full stack
From first to last:
-
FilesystemMiddleware: Handles file system operations such as reading, writing, and navigating directories. When you passpermissions, filesystem permissions enforcement is included here so it can evaluate every tool the agent might call. -
SubAgentMiddleware: Only when at least one synchronous subagent is available. Spawns and coordinates subagents for delegating tasks. Included in the bare stack because the general-purpose subagent is auto-added by default; omit it by disabling that subagent and passing no synchronoussubagents. See Running without subagents. -
SummarizationMiddleware: Condenses message history to stay within context limits when conversations grow long (via createSummarizationMiddleware). -
PatchToolCallsMiddleware: Repairs dangling tool calls in message history when a run resumes after an interruption or receives malformed tool-call arguments. Runs before Anthropic prompt caching and the tail stack below. -
AsyncSubAgentMiddleware: Only when you configure async subagents. -
Your middleware argument: Optional middleware you pass as the
middlewareargument is merged after Patch but before the rest of the stack. An instance whose.namematches a built-in entry replaces that entry in place instead of duplicating it. Anything else lands here. -
Harness profile extras: Provider-specific middleware from the resolved model profile, if any.
-
SkillsMiddleware: Only when you passskills, or pass acreateSkillsMiddlewareinstance inmiddleware. Either way, it runs after your middleware and directly before prompt caching, so it sees the summarized conversation and the model that is actually called. -
Prompt caching (
AnthropicPromptCachingMiddlewareandBedrockPromptCachingMiddleware): Added automatically for Anthropic models and Amazon Bedrock Converse models, respectively. Both run after Patch and after your middleware so the cached prefix matches what is actually sent to the model. -
MemoryMiddleware: Only when you passmemory.Note
MemoryMiddlewareis placed after profile extras and the prompt caching middleware so updates to injected memory are less likely to invalidate the cache prefix. The same ordering concern is called out in thecreateDeepAgentimplementation comments. -
HumanInTheLoopMiddleware: Only when you passinterruptOn. Pauses for human approval or input at configured tool calls. -
Excluded-tool filtering: When the harness profile lists excluded tools, middleware removes those tools from the agent.
-
UnsupportedContentMiddleware: Rewrites unsupported multimodal content in requests with a text placeholder.
Synchronous subagent stack
The built-in general-purpose subagent and each declarative synchronous SubAgent graph use a stack that createDeepAgent builds in code. It matches the main agent in broad shape (filesystem, summarization, Patch, profile extras, skills, Anthropic and Bedrock caching, optional permissions), except that there is no SubAgentMiddleware inside a subagent graph (only the parent agent exposes the task tool).
When a declarative subagent sets interruptOn, that value is forwarded to createAgent for the subagent, which wires up human-in-the-loop handling for the configured tool calls.
Prebuilt middleware
LangChain exposes additional prebuilt middleware that let you add-on various features, such as retries, fallbacks, or PII detection. See Prebuilt middleware for more.
The deepagents package also exposes createSummarizationMiddleware for the same workflow. For more detail, see Summarization.
Provider-specific middleware
For provider-specific middleware that is optimized for specific LLM providers, see Middleware integrations.
Custom middleware
You can provide additional middleware to extend functionality, add tools, or implement custom hooks:
import { tool, createMiddleware } from "langchain";
import { createDeepAgent } from "deepagents";
import * as z from "zod";
const getWeather = tool(
({ city }: { city: string }) => {
return `The weather in ${city} is sunny.`;
},
{
name: "get_weather",
description: "Get the weather in a city.",
schema: z.object({
city: z.string(),
}),
},
);
let callCount = 0;
const logToolCallsMiddleware = createMiddleware({
name: "LogToolCallsMiddleware",
wrapToolCall: async (request, handler) => {
// Intercept and log every tool call - demonstrates cross-cutting concern
callCount += 1;
const toolName = request.toolCall.name;
console.log(`[Middleware] Tool call #${callCount}: ${toolName}`);
console.log(
`[Middleware] Arguments: ${JSON.stringify(request.toolCall.args)}`,
);
// Execute the tool call
const result = await handler(request);
// Log the result
console.log(`[Middleware] Tool call #${callCount} completed`);
return result;
},
});
const agent = await createDeepAgent({
model: "google:gemini-3.6-flash",
tools: [getWeather] as any,
middleware: [logToolCallsMiddleware] as any,
});
import { tool, createMiddleware } from "langchain";
import { createDeepAgent } from "deepagents";
import * as z from "zod";
const getWeather = tool(
({ city }: { city: string }) => {
return `The weather in ${city} is sunny.`;
},
{
name: "get_weather",
description: "Get the weather in a city.",
schema: z.object({
city: z.string(),
}),
},
);
let callCount = 0;
const logToolCallsMiddleware = createMiddleware({
name: "LogToolCallsMiddleware",
wrapToolCall: async (request, handler) => {
// Intercept and log every tool call - demonstrates cross-cutting concern
callCount += 1;
const toolName = request.toolCall.name;
console.log(`[Middleware] Tool call #${callCount}: ${toolName}`);
console.log(
`[Middleware] Arguments: ${JSON.stringify(request.toolCall.args)}`,
);
// Execute the tool call
const result = await handler(request);
// Log the result
console.log(`[Middleware] Tool call #${callCount} completed`);
return result;
},
});
const agent = await createDeepAgent({
model: "openai:gpt-5.5",
tools: [getWeather] as any,
middleware: [logToolCallsMiddleware] as any,
});
import { tool, createMiddleware } from "langchain";
import { createDeepAgent } from "deepagents";
import * as z from "zod";
const getWeather = tool(
({ city }: { city: string }) => {
return `The weather in ${city} is sunny.`;
},
{
name: "get_weather",
description: "Get the weather in a city.",
schema: z.object({
city: z.string(),
}),
},
);
let callCount = 0;
const logToolCallsMiddleware = createMiddleware({
name: "LogToolCallsMiddleware",
wrapToolCall: async (request, handler) => {
// Intercept and log every tool call - demonstrates cross-cutting concern
callCount += 1;
const toolName = request.toolCall.name;
console.log(`[Middleware] Tool call #${callCount}: ${toolName}`);
console.log(
`[Middleware] Arguments: ${JSON.stringify(request.toolCall.args)}`,
);
// Execute the tool call
const result = await handler(request);
// Log the result
console.log(`[Middleware] Tool call #${callCount} completed`);
return result;
},
});
const agent = await createDeepAgent({
model: "anthropic:claude-sonnet-5",
tools: [getWeather] as any,
middleware: [logToolCallsMiddleware] as any,
});
import { tool, createMiddleware } from "langchain";
import { createDeepAgent } from "deepagents";
import * as z from "zod";
const getWeather = tool(
({ city }: { city: string }) => {
return `The weather in ${city} is sunny.`;
},
{
name: "get_weather",
description: "Get the weather in a city.",
schema: z.object({
city: z.string(),
}),
},
);
let callCount = 0;
const logToolCallsMiddleware = createMiddleware({
name: "LogToolCallsMiddleware",
wrapToolCall: async (request, handler) => {
// Intercept and log every tool call - demonstrates cross-cutting concern
callCount += 1;
const toolName = request.toolCall.name;
console.log(`[Middleware] Tool call #${callCount}: ${toolName}`);
console.log(
`[Middleware] Arguments: ${JSON.stringify(request.toolCall.args)}`,
);
// Execute the tool call
const result = await handler(request);
// Log the result
console.log(`[Middleware] Tool call #${callCount} completed`);
return result;
},
});
const agent = await createDeepAgent({
model: "openrouter:z-ai/glm-5.2",
tools: [getWeather] as any,
middleware: [logToolCallsMiddleware] as any,
});
import { tool, createMiddleware } from "langchain";
import { createDeepAgent } from "deepagents";
import * as z from "zod";
const getWeather = tool(
({ city }: { city: string }) => {
return `The weather in ${city} is sunny.`;
},
{
name: "get_weather",
description: "Get the weather in a city.",
schema: z.object({
city: z.string(),
}),
},
);
let callCount = 0;
const logToolCallsMiddleware = createMiddleware({
name: "LogToolCallsMiddleware",
wrapToolCall: async (request, handler) => {
// Intercept and log every tool call - demonstrates cross-cutting concern
callCount += 1;
const toolName = request.toolCall.name;
console.log(`[Middleware] Tool call #${callCount}: ${toolName}`);
console.log(
`[Middleware] Arguments: ${JSON.stringify(request.toolCall.args)}`,
);
// Execute the tool call
const result = await handler(request);
// Log the result
console.log(`[Middleware] Tool call #${callCount} completed`);
return result;
},
});
const agent = await createDeepAgent({
model: "fireworks:accounts/fireworks/models/glm-5p2",
tools: [getWeather] as any,
middleware: [logToolCallsMiddleware] as any,
});
import { tool, createMiddleware } from "langchain";
import { createDeepAgent } from "deepagents";
import * as z from "zod";
const getWeather = tool(
({ city }: { city: string }) => {
return `The weather in ${city} is sunny.`;
},
{
name: "get_weather",
description: "Get the weather in a city.",
schema: z.object({
city: z.string(),
}),
},
);
let callCount = 0;
const logToolCallsMiddleware = createMiddleware({
name: "LogToolCallsMiddleware",
wrapToolCall: async (request, handler) => {
// Intercept and log every tool call - demonstrates cross-cutting concern
callCount += 1;
const toolName = request.toolCall.name;
console.log(`[Middleware] Tool call #${callCount}: ${toolName}`);
console.log(
`[Middleware] Arguments: ${JSON.stringify(request.toolCall.args)}`,
);
// Execute the tool call
const result = await handler(request);
// Log the result
console.log(`[Middleware] Tool call #${callCount} completed`);
return result;
},
});
const agent = await createDeepAgent({
model: "baseten:zai-org/GLM-5.2",
tools: [getWeather] as any,
middleware: [logToolCallsMiddleware] as any,
});
import { tool, createMiddleware } from "langchain";
import { createDeepAgent } from "deepagents";
import * as z from "zod";
const getWeather = tool(
({ city }: { city: string }) => {
return `The weather in ${city} is sunny.`;
},
{
name: "get_weather",
description: "Get the weather in a city.",
schema: z.object({
city: z.string(),
}),
},
);
let callCount = 0;
const logToolCallsMiddleware = createMiddleware({
name: "LogToolCallsMiddleware",
wrapToolCall: async (request, handler) => {
// Intercept and log every tool call - demonstrates cross-cutting concern
callCount += 1;
const toolName = request.toolCall.name;
console.log(`[Middleware] Tool call #${callCount}: ${toolName}`);
console.log(
`[Middleware] Arguments: ${JSON.stringify(request.toolCall.args)}`,
);
// Execute the tool call
const result = await handler(request);
// Log the result
console.log(`[Middleware] Tool call #${callCount} completed`);
return result;
},
});
const agent = await createDeepAgent({
model: "ollama:north-mini-code-1.0",
tools: [getWeather] as any,
middleware: [logToolCallsMiddleware] as any,
});
Warning
Do not mutate attributes after initialization
If you need to track values across hook invocations (for example, counters or accumulated data), use graph state. Graph state is scoped to a thread by design, so updates are safe under concurrency.
Do this:
const customMiddleware = createMiddleware({
name: "CustomMiddleware",
beforeAgent: async (state) => {
return { x: (state.x ?? 0) + 1 }; // Update graph state instead
},
});Do not do this:
let x = 1;
const customMiddlewareBad = createMiddleware({
name: "CustomMiddleware",
beforeAgent: async () => {
x += 1; // Mutation causes race conditions
},
});
Mutation in place, such as modifying state.x in beforeAgent, mutating a shared variable in beforeAgent, or changing other shared values in hooks, can lead to subtle bugs and race conditions because many operations run concurrently (subagents, parallel tools, and parallel invocations on different threads).
If you must use mutation in custom middleware, consider what happens when subagents, parallel tools, or concurrent agent invocations run at the same time.
Override a default middleware instance
Pass a middleware instance whose .name matches an entry in the Deep Agents stack, such as SummarizationMiddleware, to replace that built-in instance in place instead of appending a duplicate. Any middleware you pass whose .name does not match a built-in entry is not replaced, it lands after the last core middleware entry and before the profile, prompt-caching, and memory. See Full stack for the complete ordering.
import {
createDeepAgent,
createSummarizationMiddleware,
StateBackend,
} from "deepagents";
const backend = new StateBackend();
const model = "openai:gpt-5.5";
const customSummarization = createSummarizationMiddleware({
model,
backend,
summaryPrompt: "Your custom summary prompt here.",
});
const agent = createDeepAgent({
model,
middleware: [customSummarization], // replaces the default SummarizationMiddleware
});
Note
An override replaces the default middleware instance, it is not merged with it. That means your replacement must be fully configured with any settings it needs. This is especially important for FilesystemMiddleware: if you override it, you must pass the backend (and permissions, if applicable) directly to createFilesystemMiddleware, since it will not inherit the backend and permissions passed to createDeepAgent. To restrict the available filesystem tools, pass a tools allowlist to your custom FilesystemMiddleware instance; see Virtual filesystem access.
The general-purpose subagent, which Deep Agents adds automatically, inherits overrides for its default middleware from the main agent, without carrying over middleware that is specific to the main agent.
Declarative subagents defined via subagents do not inherit the main agent's middleware customization. Pass the override directly in that subagent's own middleware field to apply it there; that field is matched against the synchronous subagent stack, the same way middleware is matched against the main agent's.
Examples
Interpreters
Use interpreters to add an eval tool that runs JavaScript in a scoped QuickJS runtime. Interpreters are useful when the agent needs to compose tools programmatically, batch work, handle errors in code, or transform structured data without a full shell environment.
import { createDeepAgent } from "deepagents";
import { createCodeInterpreterMiddleware } from "@langchain/quickjs";
const agent = createDeepAgent({
model: "google:gemini-3.6-flash",
middleware: [createCodeInterpreterMiddleware()],
});
import { createDeepAgent } from "deepagents";
import { createCodeInterpreterMiddleware } from "@langchain/quickjs";
const agent = createDeepAgent({
model: "openai:gpt-5.5",
middleware: [createCodeInterpreterMiddleware()],
});
import { createDeepAgent } from "deepagents";
import { createCodeInterpreterMiddleware } from "@langchain/quickjs";
const agent = createDeepAgent({
model: "anthropic:claude-sonnet-5",
middleware: [createCodeInterpreterMiddleware()],
});
import { createDeepAgent } from "deepagents";
import { createCodeInterpreterMiddleware } from "@langchain/quickjs";
const agent = createDeepAgent({
model: "openrouter:z-ai/glm-5.2",
middleware: [createCodeInterpreterMiddleware()],
});
import { createDeepAgent } from "deepagents";
import { createCodeInterpreterMiddleware } from "@langchain/quickjs";
const agent = createDeepAgent({
model: "fireworks:accounts/fireworks/models/glm-5p2",
middleware: [createCodeInterpreterMiddleware()],
});
import { createDeepAgent } from "deepagents";
import { createCodeInterpreterMiddleware } from "@langchain/quickjs";
const agent = createDeepAgent({
model: "baseten:zai-org/GLM-5.2",
middleware: [createCodeInterpreterMiddleware()],
});
import { createDeepAgent } from "deepagents";
import { createCodeInterpreterMiddleware } from "@langchain/quickjs";
const agent = createDeepAgent({
model: "ollama:north-mini-code-1.0",
middleware: [createCodeInterpreterMiddleware()],
});
For setup, programmatic tool calling, subagent orchestration, and limits, see Interpreters.
Subagents
To isolate detailed work and avoid context bloat, use subagents:
import { tool } from "langchain";
import { TavilySearch } from "@langchain/tavily";
import { createDeepAgent, type SubAgent } from "deepagents";
import { z } from "zod";
const internetSearch = tool(
async ({
query,
maxResults = 5,
topic = "general",
includeRawContent = false,
}: {
query: string;
maxResults?: number;
topic?: "general" | "news" | "finance";
includeRawContent?: boolean;
}) => {
const tavilySearch = new TavilySearch({
maxResults,
tavilyApiKey: process.env.TAVILY_API_KEY,
includeRawContent,
topic,
});
return await tavilySearch._call({ query });
},
{
name: "internet_search",
description: "Run a web search",
schema: z.object({
query: z.string().describe("The search query"),
maxResults: z.number().optional().default(5),
topic: z
.enum(["general", "news", "finance"])
.optional()
.default("general"),
includeRawContent: z.boolean().optional().default(false),
}),
},
);
const researchSubagent: SubAgent = {
name: "research-agent",
description: "Used to research more in depth questions",
systemPrompt: "You are a great researcher",
tools: [internetSearch],
model: "google:gemini-3.6-flash", // Optional override, defaults to main agent model
};
const subagents = [researchSubagent];
const agent = createDeepAgent({
model: "google:gemini-3.6-flash",
subagents,
});
import { tool } from "langchain";
import { TavilySearch } from "@langchain/tavily";
import { createDeepAgent, type SubAgent } from "deepagents";
import { z } from "zod";
const internetSearch = tool(
async ({
query,
maxResults = 5,
topic = "general",
includeRawContent = false,
}: {
query: string;
maxResults?: number;
topic?: "general" | "news" | "finance";
includeRawContent?: boolean;
}) => {
const tavilySearch = new TavilySearch({
maxResults,
tavilyApiKey: process.env.TAVILY_API_KEY,
includeRawContent,
topic,
});
return await tavilySearch._call({ query });
},
{
name: "internet_search",
description: "Run a web search",
schema: z.object({
query: z.string().describe("The search query"),
maxResults: z.number().optional().default(5),
topic: z
.enum(["general", "news", "finance"])
.optional()
.default("general"),
includeRawContent: z.boolean().optional().default(false),
}),
},
);
const researchSubagent: SubAgent = {
name: "research-agent",
description: "Used to research more in depth questions",
systemPrompt: "You are a great researcher",
tools: [internetSearch],
model: "openai:gpt-5.5", // Optional override, defaults to main agent model
};
const subagents = [researchSubagent];
const agent = createDeepAgent({
model: "google:gemini-3.6-flash",
subagents,
});
import { tool } from "langchain";
import { TavilySearch } from "@langchain/tavily";
import { createDeepAgent, type SubAgent } from "deepagents";
import { z } from "zod";
const internetSearch = tool(
async ({
query,
maxResults = 5,
topic = "general",
includeRawContent = false,
}: {
query: string;
maxResults?: number;
topic?: "general" | "news" | "finance";
includeRawContent?: boolean;
}) => {
const tavilySearch = new TavilySearch({
maxResults,
tavilyApiKey: process.env.TAVILY_API_KEY,
includeRawContent,
topic,
});
return await tavilySearch._call({ query });
},
{
name: "internet_search",
description: "Run a web search",
schema: z.object({
query: z.string().describe("The search query"),
maxResults: z.number().optional().default(5),
topic: z
.enum(["general", "news", "finance"])
.optional()
.default("general"),
includeRawContent: z.boolean().optional().default(false),
}),
},
);
const researchSubagent: SubAgent = {
name: "research-agent",
description: "Used to research more in depth questions",
systemPrompt: "You are a great researcher",
tools: [internetSearch],
model: "anthropic:claude-sonnet-5", // Optional override, defaults to main agent model
};
const subagents = [researchSubagent];
const agent = createDeepAgent({
model: "google:gemini-3.6-flash",
subagents,
});
import { tool } from "langchain";
import { TavilySearch } from "@langchain/tavily";
import { createDeepAgent, type SubAgent } from "deepagents";
import { z } from "zod";
const internetSearch = tool(
async ({
query,
maxResults = 5,
topic = "general",
includeRawContent = false,
}: {
query: string;
maxResults?: number;
topic?: "general" | "news" | "finance";
includeRawContent?: boolean;
}) => {
const tavilySearch = new TavilySearch({
maxResults,
tavilyApiKey: process.env.TAVILY_API_KEY,
includeRawContent,
topic,
});
return await tavilySearch._call({ query });
},
{
name: "internet_search",
description: "Run a web search",
schema: z.object({
query: z.string().describe("The search query"),
maxResults: z.number().optional().default(5),
topic: z
.enum(["general", "news", "finance"])
.optional()
.default("general"),
includeRawContent: z.boolean().optional().default(false),
}),
},
);
const researchSubagent: SubAgent = {
name: "research-agent",
description: "Used to research more in depth questions",
systemPrompt: "You are a great researcher",
tools: [internetSearch],
model: "openrouter:z-ai/glm-5.2", // Optional override, defaults to main agent model
};
const subagents = [researchSubagent];
const agent = createDeepAgent({
model: "google:gemini-3.6-flash",
subagents,
});
import { tool } from "langchain";
import { TavilySearch } from "@langchain/tavily";
import { createDeepAgent, type SubAgent } from "deepagents";
import { z } from "zod";
const internetSearch = tool(
async ({
query,
maxResults = 5,
topic = "general",
includeRawContent = false,
}: {
query: string;
maxResults?: number;
topic?: "general" | "news" | "finance";
includeRawContent?: boolean;
}) => {
const tavilySearch = new TavilySearch({
maxResults,
tavilyApiKey: process.env.TAVILY_API_KEY,
includeRawContent,
topic,
});
return await tavilySearch._call({ query });
},
{
name: "internet_search",
description: "Run a web search",
schema: z.object({
query: z.string().describe("The search query"),
maxResults: z.number().optional().default(5),
topic: z
.enum(["general", "news", "finance"])
.optional()
.default("general"),
includeRawContent: z.boolean().optional().default(false),
}),
},
);
const researchSubagent: SubAgent = {
name: "research-agent",
description: "Used to research more in depth questions",
systemPrompt: "You are a great researcher",
tools: [internetSearch],
model: "fireworks:accounts/fireworks/models/glm-5p2", // Optional override, defaults to main agent model
};
const subagents = [researchSubagent];
const agent = createDeepAgent({
model: "google:gemini-3.6-flash",
subagents,
});
import { tool } from "langchain";
import { TavilySearch } from "@langchain/tavily";
import { createDeepAgent, type SubAgent } from "deepagents";
import { z } from "zod";
const internetSearch = tool(
async ({
query,
maxResults = 5,
topic = "general",
includeRawContent = false,
}: {
query: string;
maxResults?: number;
topic?: "general" | "news" | "finance";
includeRawContent?: boolean;
}) => {
const tavilySearch = new TavilySearch({
maxResults,
tavilyApiKey: process.env.TAVILY_API_KEY,
includeRawContent,
topic,
});
return await tavilySearch._call({ query });
},
{
name: "internet_search",
description: "Run a web search",
schema: z.object({
query: z.string().describe("The search query"),
maxResults: z.number().optional().default(5),
topic: z
.enum(["general", "news", "finance"])
.optional()
.default("general"),
includeRawContent: z.boolean().optional().default(false),
}),
},
);
const researchSubagent: SubAgent = {
name: "research-agent",
description: "Used to research more in depth questions",
systemPrompt: "You are a great researcher",
tools: [internetSearch],
model: "baseten:zai-org/GLM-5.2", // Optional override, defaults to main agent model
};
const subagents = [researchSubagent];
const agent = createDeepAgent({
model: "google:gemini-3.6-flash",
subagents,
});
import { tool } from "langchain";
import { TavilySearch } from "@langchain/tavily";
import { createDeepAgent, type SubAgent } from "deepagents";
import { z } from "zod";
const internetSearch = tool(
async ({
query,
maxResults = 5,
topic = "general",
includeRawContent = false,
}: {
query: string;
maxResults?: number;
topic?: "general" | "news" | "finance";
includeRawContent?: boolean;
}) => {
const tavilySearch = new TavilySearch({
maxResults,
tavilyApiKey: process.env.TAVILY_API_KEY,
includeRawContent,
topic,
});
return await tavilySearch._call({ query });
},
{
name: "internet_search",
description: "Run a web search",
schema: z.object({
query: z.string().describe("The search query"),
maxResults: z.number().optional().default(5),
topic: z
.enum(["general", "news", "finance"])
.optional()
.default("general"),
includeRawContent: z.boolean().optional().default(false),
}),
},
);
const researchSubagent: SubAgent = {
name: "research-agent",
description: "Used to research more in depth questions",
systemPrompt: "You are a great researcher",
tools: [internetSearch],
model: "ollama:north-mini-code-1.0", // Optional override, defaults to main agent model
};
const subagents = [researchSubagent];
const agent = createDeepAgent({
model: "google:gemini-3.6-flash",
subagents,
});
For more information, see Subagents.
Backends
Tools for a deep agent can make use of virtual file systems to store, access, and edit files. By default, deep agents use a StateBackend.
If you are using skills or memory, you must add the expected skill or memory files to the backend before creating the agent.
A thread-scoped filesystem backend stored in langgraph state.
Files persist across turns within a thread (via your checkpointer) and are not shared across threads.
import { createDeepAgent, StateBackend } from "deepagents";
// By default we provide a StateBackend
const agent = createDeepAgent();
// Under the hood, it looks like
const agent2 = createDeepAgent({
backend: new StateBackend(),
});
The local machine's filesystem.
Warning
This backend grants agents direct filesystem read/write access.
Use with caution and only in appropriate environments.
For more information, see FilesystemBackend.
import { createDeepAgent, FilesystemBackend } from "deepagents";
const agent = createDeepAgent({
model: "google:gemini-3.6-flash",
backend: new FilesystemBackend({ rootDir: ".", virtualMode: true }),
});
import { createDeepAgent, FilesystemBackend } from "deepagents";
const agent = createDeepAgent({
model: "openai:gpt-5.5",
backend: new FilesystemBackend({ rootDir: ".", virtualMode: true }),
});
import { createDeepAgent, FilesystemBackend } from "deepagents";
const agent = createDeepAgent({
model: "anthropic:claude-sonnet-5",
backend: new FilesystemBackend({ rootDir: ".", virtualMode: true }),
});
import { createDeepAgent, FilesystemBackend } from "deepagents";
const agent = createDeepAgent({
model: "openrouter:z-ai/glm-5.2",
backend: new FilesystemBackend({ rootDir: ".", virtualMode: true }),
});
import { createDeepAgent, FilesystemBackend } from "deepagents";
const agent = createDeepAgent({
model: "fireworks:accounts/fireworks/models/glm-5p2",
backend: new FilesystemBackend({ rootDir: ".", virtualMode: true }),
});
import { createDeepAgent, FilesystemBackend } from "deepagents";
const agent = createDeepAgent({
model: "baseten:zai-org/GLM-5.2",
backend: new FilesystemBackend({ rootDir: ".", virtualMode: true }),
});
import { createDeepAgent, FilesystemBackend } from "deepagents";
const agent = createDeepAgent({
model: "ollama:north-mini-code-1.0",
backend: new FilesystemBackend({ rootDir: ".", virtualMode: true }),
});
Tip
Wrap FilesystemBackend in a CompositeBackend to prevent internal agent data (offloaded tool results, conversation history) from being written to disk alongside your project files. See the recommended pattern.
A filesystem with shell execution directly on the host. Provides filesystem tools plus the execute tool for running commands.
Warning
This backend grants agents direct filesystem read/write access and unrestricted shell execution on your host.
Use with extreme caution and only in appropriate environments.
For more information, see LocalShellBackend.
import { createDeepAgent, LocalShellBackend } from "deepagents";
const backend = new LocalShellBackend({ workingDirectory: "." });
const agent = createDeepAgent({
model: "google:gemini-3.6-flash",
backend,
});
import { createDeepAgent, LocalShellBackend } from "deepagents";
const backend = new LocalShellBackend({ workingDirectory: "." });
const agent = createDeepAgent({
model: "openai:gpt-5.5",
backend,
});
import { createDeepAgent, LocalShellBackend } from "deepagents";
const backend = new LocalShellBackend({ workingDirectory: "." });
const agent = createDeepAgent({
model: "anthropic:claude-sonnet-5",
backend,
});
import { createDeepAgent, LocalShellBackend } from "deepagents";
const backend = new LocalShellBackend({ workingDirectory: "." });
const agent = createDeepAgent({
model: "openrouter:z-ai/glm-5.2",
backend,
});
import { createDeepAgent, LocalShellBackend } from "deepagents";
const backend = new LocalShellBackend({ workingDirectory: "." });
const agent = createDeepAgent({
model: "fireworks:accounts/fireworks/models/glm-5p2",
backend,
});
import { createDeepAgent, LocalShellBackend } from "deepagents";
const backend = new LocalShellBackend({ workingDirectory: "." });
const agent = createDeepAgent({
model: "baseten:zai-org/GLM-5.2",
backend,
});
import { createDeepAgent, LocalShellBackend } from "deepagents";
const backend = new LocalShellBackend({ workingDirectory: "." });
const agent = createDeepAgent({
model: "ollama:north-mini-code-1.0",
backend,
});
A filesystem that provides long-term storage that is persisted across threads.
import { createDeepAgent, StoreBackend } from "deepagents";
import { InMemoryStore } from "@langchain/langgraph";
const store = new InMemoryStore(); // Good for local dev; omit for LangSmith Deployment
const agent = createDeepAgent({
model: "google:gemini-3.6-flash",
backend: new StoreBackend({
namespace: (rt) => [rt.serverInfo.user.identity],
}),
store,
});
import { createDeepAgent, StoreBackend } from "deepagents";
import { InMemoryStore } from "@langchain/langgraph";
const store = new InMemoryStore(); // Good for local dev; omit for LangSmith Deployment
const agent = createDeepAgent({
model: "openai:gpt-5.5",
backend: new StoreBackend({
namespace: (rt) => [rt.serverInfo.user.identity],
}),
store,
});
import { createDeepAgent, StoreBackend } from "deepagents";
import { InMemoryStore } from "@langchain/langgraph";
const store = new InMemoryStore(); // Good for local dev; omit for LangSmith Deployment
const agent = createDeepAgent({
model: "anthropic:claude-sonnet-5",
backend: new StoreBackend({
namespace: (rt) => [rt.serverInfo.user.identity],
}),
store,
});
import { createDeepAgent, StoreBackend } from "deepagents";
import { InMemoryStore } from "@langchain/langgraph";
const store = new InMemoryStore(); // Good for local dev; omit for LangSmith Deployment
const agent = createDeepAgent({
model: "openrouter:z-ai/glm-5.2",
backend: new StoreBackend({
namespace: (rt) => [rt.serverInfo.user.identity],
}),
store,
});
import { createDeepAgent, StoreBackend } from "deepagents";
import { InMemoryStore } from "@langchain/langgraph";
const store = new InMemoryStore(); // Good for local dev; omit for LangSmith Deployment
const agent = createDeepAgent({
model: "fireworks:accounts/fireworks/models/glm-5p2",
backend: new StoreBackend({
namespace: (rt) => [rt.serverInfo.user.identity],
}),
store,
});
import { createDeepAgent, StoreBackend } from "deepagents";
import { InMemoryStore } from "@langchain/langgraph";
const store = new InMemoryStore(); // Good for local dev; omit for LangSmith Deployment
const agent = createDeepAgent({
model: "baseten:zai-org/GLM-5.2",
backend: new StoreBackend({
namespace: (rt) => [rt.serverInfo.user.identity],
}),
store,
});
import { createDeepAgent, StoreBackend } from "deepagents";
import { InMemoryStore } from "@langchain/langgraph";
const store = new InMemoryStore(); // Good for local dev; omit for LangSmith Deployment
const agent = createDeepAgent({
model: "ollama:north-mini-code-1.0",
backend: new StoreBackend({
namespace: (rt) => [rt.serverInfo.user.identity],
}),
store,
});
Note
When deploying to LangSmith Deployment, omit the store parameter. The platform automatically provisions a store for your agent.
Tip
The namespace parameter controls data isolation. For multi-user deployments, always set a namespace factory to isolate data per user or tenant.
Durable filesystem storage in a LangSmith Hub repo.
For more details, see ContextHubBackend.
A flexible backend where you can specify different routes in the filesystem to point towards different backends.
import {
createDeepAgent,
CompositeBackend,
StateBackend,
StoreBackend,
} from "deepagents";
import { InMemoryStore } from "@langchain/langgraph";
const store = new InMemoryStore();
const agent = createDeepAgent({
model: "google:gemini-3.6-flash",
backend: new CompositeBackend(new StateBackend(), {
"/memories/": new StoreBackend({
namespace: () => ["memories"],
}),
}),
store,
});
import {
createDeepAgent,
CompositeBackend,
StateBackend,
StoreBackend,
} from "deepagents";
import { InMemoryStore } from "@langchain/langgraph";
const store = new InMemoryStore();
const agent = createDeepAgent({
model: "openai:gpt-5.5",
backend: new CompositeBackend(new StateBackend(), {
"/memories/": new StoreBackend({
namespace: () => ["memories"],
}),
}),
store,
});
import {
createDeepAgent,
CompositeBackend,
StateBackend,
StoreBackend,
} from "deepagents";
import { InMemoryStore } from "@langchain/langgraph";
const store = new InMemoryStore();
const agent = createDeepAgent({
model: "anthropic:claude-sonnet-5",
backend: new CompositeBackend(new StateBackend(), {
"/memories/": new StoreBackend({
namespace: () => ["memories"],
}),
}),
store,
});
import {
createDeepAgent,
CompositeBackend,
StateBackend,
StoreBackend,
} from "deepagents";
import { InMemoryStore } from "@langchain/langgraph";
const store = new InMemoryStore();
const agent = createDeepAgent({
model: "openrouter:z-ai/glm-5.2",
backend: new CompositeBackend(new StateBackend(), {
"/memories/": new StoreBackend({
namespace: () => ["memories"],
}),
}),
store,
});
import {
createDeepAgent,
CompositeBackend,
StateBackend,
StoreBackend,
} from "deepagents";
import { InMemoryStore } from "@langchain/langgraph";
const store = new InMemoryStore();
const agent = createDeepAgent({
model: "fireworks:accounts/fireworks/models/glm-5p2",
backend: new CompositeBackend(new StateBackend(), {
"/memories/": new StoreBackend({
namespace: () => ["memories"],
}),
}),
store,
});
import {
createDeepAgent,
CompositeBackend,
StateBackend,
StoreBackend,
} from "deepagents";
import { InMemoryStore } from "@langchain/langgraph";
const store = new InMemoryStore();
const agent = createDeepAgent({
model: "baseten:zai-org/GLM-5.2",
backend: new CompositeBackend(new StateBackend(), {
"/memories/": new StoreBackend({
namespace: () => ["memories"],
}),
}),
store,
});
import {
createDeepAgent,
CompositeBackend,
StateBackend,
StoreBackend,
} from "deepagents";
import { InMemoryStore } from "@langchain/langgraph";
const store = new InMemoryStore();
const agent = createDeepAgent({
model: "ollama:north-mini-code-1.0",
backend: new CompositeBackend(new StateBackend(), {
"/memories/": new StoreBackend({
namespace: () => ["memories"],
}),
}),
store,
});
For more information, see Backends.
Sandboxes
Sandboxes are specialized backends that run agent code in an isolated environment with their own filesystem and an execute tool for shell commands.
Use a sandbox backend when you want your deep agent to write files, install dependencies, and run commands without changing anything on your local machine.
You configure sandboxes by passing a sandbox backend to backend when creating your deep agent:
import { createDeepAgent, LangSmithSandbox } from "deepagents";
import { ChatAnthropic } from "@langchain/anthropic";
import { SandboxClient } from "langsmith/sandbox";
const client = new SandboxClient();
const lsSandbox = await client.createSandbox();
try {
const agent = createDeepAgent({
model: new ChatAnthropic({ model: "claude-opus-4-8" }),
systemPrompt: "You are a coding assistant with sandbox access.",
backend: new LangSmithSandbox({ sandbox: lsSandbox }),
});
const result = await agent.invoke({
messages: [
{
role: "user",
content: "Create a hello world Python script and run it",
},
],
});
} finally {
await client.deleteSandbox(lsSandbox.name);
}
For more information, see Sandboxes.
Human-in-the-loop
Some tool operations may be sensitive and require human approval before execution. You can configure the approval for each tool:
import { tool } from "langchain";
import { createDeepAgent } from "deepagents";
import { MemorySaver } from "@langchain/langgraph";
import { z } from "zod";
const removeFile = tool(
async ({ path }: { path: string }) => {
return `Deleted ${path}`;
},
{
name: "remove_file",
description: "Delete a file from the filesystem.",
schema: z.object({
path: z.string(),
}),
},
);
const fetchFile = tool(
async ({ path }: { path: string }) => {
return `Contents of ${path}`;
},
{
name: "fetch_file",
description: "Read a file from the filesystem.",
schema: z.object({
path: z.string(),
}),
},
);
const notifyEmail = tool(
async ({
to,
subject,
body,
}: {
to: string;
subject: string;
body: string;
}) => {
return `Sent email to ${to}`;
},
{
name: "notify_email",
description: "Send an email.",
schema: z.object({
to: z.string(),
subject: z.string(),
body: z.string(),
}),
},
);
// Checkpointer is REQUIRED for human-in-the-loop
const checkpointer = new MemorySaver();
const agent = createDeepAgent({
model: "google:gemini-3.6-flash",
tools: [removeFile, fetchFile, notifyEmail],
interruptOn: {
remove_file: true, // Default: approve, edit, reject, respond
fetch_file: false, // No interrupts needed
notify_email: { allowedDecisions: ["approve", "reject"] }, // No editing
},
checkpointer, // Required!
});
You can configure interrupt for agents and subagents on tool call as well as from within tool calls. For more information, see Human-in-the-loop.
Skills
You can use skills to provide your deep agent with new capabilities and expertise. While tools tend to cover lower level functionality like native file system actions, skills can contain detailed instructions on how to complete tasks, reference info, and other assets, such as templates. These files are only loaded by the agent when the agent has determined that the skill is useful for the current prompt. This progressive disclosure reduces the amount of tokens and context the agent has to consider upon startup.
For example skills, see Deep Agents example skills.
To add skills to your deep agent, pass them as an argument to create_deep_agent:
import { createDeepAgent, StateBackend, type FileData } from "deepagents";
import { MemorySaver } from "@langchain/langgraph";
const checkpointer = new MemorySaver();
const backend = new StateBackend();
function createFileData(content: string): FileData {
const now = new Date().toISOString();
return {
content: content.split("\n"),
created_at: now,
modified_at: now,
};
}
const skillsFiles: Record<string, FileData> = {};
const skillUrl =
"https://raw.githubusercontent.com/langchain-ai/deepagentsjs/refs/heads/main/examples/skills/langgraph-docs/SKILL.md";
const response = await fetch(skillUrl);
const skillContent = await response.text();
skillsFiles["/skills/langgraph-docs/SKILL.md"] = createFileData(skillContent);
const agent = await createDeepAgent({
model: "anthropic:claude-sonnet-4-6",
backend,
checkpointer, // Required !
// IMPORTANT: deepagents skill source paths are virtual (POSIX) paths relative to the backend root.
skills: ["/skills/"],
});
const config = { configurable: { thread_id: `thread-${Date.now()}` } };
const result = await agent.invoke(
{
messages: [{ role: "user", content: "what is langraph?" }],
files: skillsFiles,
},
config,
);
Open a public LangSmith run for this example.
import { createDeepAgent, StoreBackend } from "deepagents";
import { InMemoryStore, MemorySaver } from "@langchain/langgraph";
const checkpointer = new MemorySaver();
const store = new InMemoryStore();
const backend = new StoreBackend({
namespace: () => ["filesystem"],
store,
});
const skillUrl =
"https://raw.githubusercontent.com/langchain-ai/deepagentsjs/refs/heads/main/examples/skills/langgraph-docs/SKILL.md";
const response = await fetch(skillUrl);
const skillContent = await response.text();
await backend.uploadFiles([
["/skills/langgraph-docs/SKILL.md", new TextEncoder().encode(skillContent)],
]);
const agent = await createDeepAgent({
model: "anthropic:claude-sonnet-4-6",
backend,
store,
checkpointer,
// IMPORTANT: deepagents skill source paths are virtual (POSIX) paths relative to the backend root.
skills: ["/skills/"],
});
const config = {
recursionLimit: 50,
configurable: { thread_id: `thread-${Date.now()}` },
};
const result = await agent.invoke(
{ messages: [{ role: "user", content: "what is langraph?" }] },
config,
);
Open a public LangSmith run for this example.
import { createDeepAgent, FilesystemBackend } from "deepagents";
import { MemorySaver } from "@langchain/langgraph";
const checkpointer = new MemorySaver();
const skillUrl =
"https://raw.githubusercontent.com/langchain-ai/deepagentsjs/refs/heads/main/examples/skills/langgraph-docs/SKILL.md";
const response = await fetch(skillUrl);
const skillContent = await response.text();
let backend = new FilesystemBackend({
rootDir: process.cwd(),
virtualMode: true,
});
await backend.uploadFiles([
["/skills/langgraph-docs/SKILL.md", new TextEncoder().encode(skillContent)],
]);
const agent = await createDeepAgent({
model: "anthropic:claude-sonnet-4-6",
backend,
// IMPORTANT: deepagents skill source paths are virtual (POSIX) paths relative to the backend root.
skills: ["/skills/"],
interruptOn: {
read_file: true,
write_file: true,
delete_file: true,
},
checkpointer, // Required for filesystem operations!
});
const config = { configurable: { thread_id: `thread-${Date.now()}` } };
const result = await agent.invoke(
{ messages: [{ role: "user", content: "what is langraph?" }] },
config,
);
Open a public LangSmith run for this example.
Memory
Use AGENTS.md files to provide extra context to your deep agent.
Tip
To generate a repository wiki that coding agents discover through AGENTS.md, see OpenWiki.
You can pass one or more file paths to the memory parameter when creating your deep agent:
import { createDeepAgent, type FileData } from "deepagents";
import { MemorySaver } from "@langchain/langgraph";
const AGENTS_MD_URL =
"https://raw.githubusercontent.com/langchain-ai/deepagents/refs/heads/main/examples/text-to-sql-agent/AGENTS.md";
async function fetchText(url: string): Promise<string> {
const res = await fetch(url);
if (!res.ok) {
throw new Error(`Failed to fetch ${url}: ${res.status} ${res.statusText}`);
}
return await res.text();
}
const agentsMd = await fetchText(AGENTS_MD_URL);
const checkpointer = new MemorySaver();
function createFileData(content: string): FileData {
const now = new Date().toISOString();
return {
content,
mimeType: "text/plain",
created_at: now,
modified_at: now,
};
}
const agent = await createDeepAgent({
model: "google:gemini-3.6-flash",
memory: ["/AGENTS.md"],
checkpointer: checkpointer,
});
const result = await 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": createFileData(agentsMd) },
},
{ configurable: { thread_id: "12345" } },
);
import { createDeepAgent, type FileData } from "deepagents";
import { MemorySaver } from "@langchain/langgraph";
const AGENTS_MD_URL =
"https://raw.githubusercontent.com/langchain-ai/deepagents/refs/heads/main/examples/text-to-sql-agent/AGENTS.md";
async function fetchText(url: string): Promise<string> {
const res = await fetch(url);
if (!res.ok) {
throw new Error(`Failed to fetch ${url}: ${res.status} ${res.statusText}`);
}
return await res.text();
}
const agentsMd = await fetchText(AGENTS_MD_URL);
const checkpointer = new MemorySaver();
function createFileData(content: string): FileData {
const now = new Date().toISOString();
return {
content,
mimeType: "text/plain",
created_at: now,
modified_at: now,
};
}
const agent = await createDeepAgent({
model: "openai:gpt-5.5",
memory: ["/AGENTS.md"],
checkpointer: checkpointer,
});
const result = await 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": createFileData(agentsMd) },
},
{ configurable: { thread_id: "12345" } },
);
import { createDeepAgent, type FileData } from "deepagents";
import { MemorySaver } from "@langchain/langgraph";
const AGENTS_MD_URL =
"https://raw.githubusercontent.com/langchain-ai/deepagents/refs/heads/main/examples/text-to-sql-agent/AGENTS.md";
async function fetchText(url: string): Promise<string> {
const res = await fetch(url);
if (!res.ok) {
throw new Error(`Failed to fetch ${url}: ${res.status} ${res.statusText}`);
}
return await res.text();
}
const agentsMd = await fetchText(AGENTS_MD_URL);
const checkpointer = new MemorySaver();
function createFileData(content: string): FileData {
const now = new Date().toISOString();
return {
content,
mimeType: "text/plain",
created_at: now,
modified_at: now,
};
}
const agent = await createDeepAgent({
model: "anthropic:claude-sonnet-5",
memory: ["/AGENTS.md"],
checkpointer: checkpointer,
});
const result = await 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": createFileData(agentsMd) },
},
{ configurable: { thread_id: "12345" } },
);
import { createDeepAgent, type FileData } from "deepagents";
import { MemorySaver } from "@langchain/langgraph";
const AGENTS_MD_URL =
"https://raw.githubusercontent.com/langchain-ai/deepagents/refs/heads/main/examples/text-to-sql-agent/AGENTS.md";
async function fetchText(url: string): Promise<string> {
const res = await fetch(url);
if (!res.ok) {
throw new Error(`Failed to fetch ${url}: ${res.status} ${res.statusText}`);
}
return await res.text();
}
const agentsMd = await fetchText(AGENTS_MD_URL);
const checkpointer = new MemorySaver();
function createFileData(content: string): FileData {
const now = new Date().toISOString();
return {
content,
mimeType: "text/plain",
created_at: now,
modified_at: now,
};
}
const agent = await createDeepAgent({
model: "openrouter:z-ai/glm-5.2",
memory: ["/AGENTS.md"],
checkpointer: checkpointer,
});
const result = await 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": createFileData(agentsMd) },
},
{ configurable: { thread_id: "12345" } },
);
import { createDeepAgent, type FileData } from "deepagents";
import { MemorySaver } from "@langchain/langgraph";
const AGENTS_MD_URL =
"https://raw.githubusercontent.com/langchain-ai/deepagents/refs/heads/main/examples/text-to-sql-agent/AGENTS.md";
async function fetchText(url: string): Promise<string> {
const res = await fetch(url);
if (!res.ok) {
throw new Error(`Failed to fetch ${url}: ${res.status} ${res.statusText}`);
}
return await res.text();
}
const agentsMd = await fetchText(AGENTS_MD_URL);
const checkpointer = new MemorySaver();
function createFileData(content: string): FileData {
const now = new Date().toISOString();
return {
content,
mimeType: "text/plain",
created_at: now,
modified_at: now,
};
}
const agent = await createDeepAgent({
model: "fireworks:accounts/fireworks/models/glm-5p2",
memory: ["/AGENTS.md"],
checkpointer: checkpointer,
});
const result = await 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": createFileData(agentsMd) },
},
{ configurable: { thread_id: "12345" } },
);
import { createDeepAgent, type FileData } from "deepagents";
import { MemorySaver } from "@langchain/langgraph";
const AGENTS_MD_URL =
"https://raw.githubusercontent.com/langchain-ai/deepagents/refs/heads/main/examples/text-to-sql-agent/AGENTS.md";
async function fetchText(url: string): Promise<string> {
const res = await fetch(url);
if (!res.ok) {
throw new Error(`Failed to fetch ${url}: ${res.status} ${res.statusText}`);
}
return await res.text();
}
const agentsMd = await fetchText(AGENTS_MD_URL);
const checkpointer = new MemorySaver();
function createFileData(content: string): FileData {
const now = new Date().toISOString();
return {
content,
mimeType: "text/plain",
created_at: now,
modified_at: now,
};
}
const agent = await createDeepAgent({
model: "baseten:zai-org/GLM-5.2",
memory: ["/AGENTS.md"],
checkpointer: checkpointer,
});
const result = await 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": createFileData(agentsMd) },
},
{ configurable: { thread_id: "12345" } },
);
import { createDeepAgent, type FileData } from "deepagents";
import { MemorySaver } from "@langchain/langgraph";
const AGENTS_MD_URL =
"https://raw.githubusercontent.com/langchain-ai/deepagents/refs/heads/main/examples/text-to-sql-agent/AGENTS.md";
async function fetchText(url: string): Promise<string> {
const res = await fetch(url);
if (!res.ok) {
throw new Error(`Failed to fetch ${url}: ${res.status} ${res.statusText}`);
}
return await res.text();
}
const agentsMd = await fetchText(AGENTS_MD_URL);
const checkpointer = new MemorySaver();
function createFileData(content: string): FileData {
const now = new Date().toISOString();
return {
content,
mimeType: "text/plain",
created_at: now,
modified_at: now,
};
}
const agent = await createDeepAgent({
model: "ollama:north-mini-code-1.0",
memory: ["/AGENTS.md"],
checkpointer: checkpointer,
});
const result = await 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": createFileData(agentsMd) },
},
{ configurable: { thread_id: "12345" } },
);
Open a public LangSmith run for this example.
import { createDeepAgent, StoreBackend, type FileData } from "deepagents";
import { InMemoryStore, MemorySaver } from "@langchain/langgraph";
const AGENTS_MD_URL =
"https://raw.githubusercontent.com/langchain-ai/deepagents/refs/heads/main/examples/text-to-sql-agent/AGENTS.md";
async function fetchText(url: string): Promise<string> {
const res = await fetch(url);
if (!res.ok) {
throw new Error(`Failed to fetch ${url}: ${res.status} ${res.statusText}`);
}
return await res.text();
}
const agentsMd = await fetchText(AGENTS_MD_URL);
function createFileData(content: string): FileData {
const now = new Date().toISOString();
return {
content,
mimeType: "text/plain",
created_at: now,
modified_at: now,
};
}
const store = new InMemoryStore();
const fileData = createFileData(agentsMd);
await store.put(["filesystem"], "/AGENTS.md", fileData);
const checkpointer = new MemorySaver();
const agent = await createDeepAgent({
model: "google:gemini-3.6-flash",
backend: new StoreBackend({
namespace: () => ["filesystem"],
}),
store: store,
checkpointer: checkpointer,
memory: ["/AGENTS.md"],
});
const result = await agent.invoke(
{
messages: [
{
role: "user",
content: "Please tell me what's in your memory files.",
},
],
},
{ configurable: { thread_id: "12345" } },
);
import { createDeepAgent, StoreBackend, type FileData } from "deepagents";
import { InMemoryStore, MemorySaver } from "@langchain/langgraph";
const AGENTS_MD_URL =
"https://raw.githubusercontent.com/langchain-ai/deepagents/refs/heads/main/examples/text-to-sql-agent/AGENTS.md";
async function fetchText(url: string): Promise<string> {
const res = await fetch(url);
if (!res.ok) {
throw new Error(`Failed to fetch ${url}: ${res.status} ${res.statusText}`);
}
return await res.text();
}
const agentsMd = await fetchText(AGENTS_MD_URL);
function createFileData(content: string): FileData {
const now = new Date().toISOString();
return {
content,
mimeType: "text/plain",
created_at: now,
modified_at: now,
};
}
const store = new InMemoryStore();
const fileData = createFileData(agentsMd);
await store.put(["filesystem"], "/AGENTS.md", fileData);
const checkpointer = new MemorySaver();
const agent = await createDeepAgent({
model: "openai:gpt-5.5",
backend: new StoreBackend({
namespace: () => ["filesystem"],
}),
store: store,
checkpointer: checkpointer,
memory: ["/AGENTS.md"],
});
const result = await agent.invoke(
{
messages: [
{
role: "user",
content: "Please tell me what's in your memory files.",
},
],
},
{ configurable: { thread_id: "12345" } },
);
import { createDeepAgent, StoreBackend, type FileData } from "deepagents";
import { InMemoryStore, MemorySaver } from "@langchain/langgraph";
const AGENTS_MD_URL =
"https://raw.githubusercontent.com/langchain-ai/deepagents/refs/heads/main/examples/text-to-sql-agent/AGENTS.md";
async function fetchText(url: string): Promise<string> {
const res = await fetch(url);
if (!res.ok) {
throw new Error(`Failed to fetch ${url}: ${res.status} ${res.statusText}`);
}
return await res.text();
}
const agentsMd = await fetchText(AGENTS_MD_URL);
function createFileData(content: string): FileData {
const now = new Date().toISOString();
return {
content,
mimeType: "text/plain",
created_at: now,
modified_at: now,
};
}
const store = new InMemoryStore();
const fileData = createFileData(agentsMd);
await store.put(["filesystem"], "/AGENTS.md", fileData);
const checkpointer = new MemorySaver();
const agent = await createDeepAgent({
model: "anthropic:claude-sonnet-5",
backend: new StoreBackend({
namespace: () => ["filesystem"],
}),
store: store,
checkpointer: checkpointer,
memory: ["/AGENTS.md"],
});
const result = await agent.invoke(
{
messages: [
{
role: "user",
content: "Please tell me what's in your memory files.",
},
],
},
{ configurable: { thread_id: "12345" } },
);
import { createDeepAgent, StoreBackend, type FileData } from "deepagents";
import { InMemoryStore, MemorySaver } from "@langchain/langgraph";
const AGENTS_MD_URL =
"https://raw.githubusercontent.com/langchain-ai/deepagents/refs/heads/main/examples/text-to-sql-agent/AGENTS.md";
async function fetchText(url: string): Promise<string> {
const res = await fetch(url);
if (!res.ok) {
throw new Error(`Failed to fetch ${url}: ${res.status} ${res.statusText}`);
}
return await res.text();
}
const agentsMd = await fetchText(AGENTS_MD_URL);
function createFileData(content: string): FileData {
const now = new Date().toISOString();
return {
content,
mimeType: "text/plain",
created_at: now,
modified_at: now,
};
}
const store = new InMemoryStore();
const fileData = createFileData(agentsMd);
await store.put(["filesystem"], "/AGENTS.md", fileData);
const checkpointer = new MemorySaver();
const agent = await createDeepAgent({
model: "openrouter:z-ai/glm-5.2",
backend: new StoreBackend({
namespace: () => ["filesystem"],
}),
store: store,
checkpointer: checkpointer,
memory: ["/AGENTS.md"],
});
const result = await agent.invoke(
{
messages: [
{
role: "user",
content: "Please tell me what's in your memory files.",
},
],
},
{ configurable: { thread_id: "12345" } },
);
import { createDeepAgent, StoreBackend, type FileData } from "deepagents";
import { InMemoryStore, MemorySaver } from "@langchain/langgraph";
const AGENTS_MD_URL =
"https://raw.githubusercontent.com/langchain-ai/deepagents/refs/heads/main/examples/text-to-sql-agent/AGENTS.md";
async function fetchText(url: string): Promise<string> {
const res = await fetch(url);
if (!res.ok) {
throw new Error(`Failed to fetch ${url}: ${res.status} ${res.statusText}`);
}
return await res.text();
}
const agentsMd = await fetchText(AGENTS_MD_URL);
function createFileData(content: string): FileData {
const now = new Date().toISOString();
return {
content,
mimeType: "text/plain",
created_at: now,
modified_at: now,
};
}
const store = new InMemoryStore();
const fileData = createFileData(agentsMd);
await store.put(["filesystem"], "/AGENTS.md", fileData);
const checkpointer = new MemorySaver();
const agent = await createDeepAgent({
model: "fireworks:accounts/fireworks/models/glm-5p2",
backend: new StoreBackend({
namespace: () => ["filesystem"],
}),
store: store,
checkpointer: checkpointer,
memory: ["/AGENTS.md"],
});
const result = await agent.invoke(
{
messages: [
{
role: "user",
content: "Please tell me what's in your memory files.",
},
],
},
{ configurable: { thread_id: "12345" } },
);
import { createDeepAgent, StoreBackend, type FileData } from "deepagents";
import { InMemoryStore, MemorySaver } from "@langchain/langgraph";
const AGENTS_MD_URL =
"https://raw.githubusercontent.com/langchain-ai/deepagents/refs/heads/main/examples/text-to-sql-agent/AGENTS.md";
async function fetchText(url: string): Promise<string> {
const res = await fetch(url);
if (!res.ok) {
throw new Error(`Failed to fetch ${url}: ${res.status} ${res.statusText}`);
}
return await res.text();
}
const agentsMd = await fetchText(AGENTS_MD_URL);
function createFileData(content: string): FileData {
const now = new Date().toISOString();
return {
content,
mimeType: "text/plain",
created_at: now,
modified_at: now,
};
}
const store = new InMemoryStore();
const fileData = createFileData(agentsMd);
await store.put(["filesystem"], "/AGENTS.md", fileData);
const checkpointer = new MemorySaver();
const agent = await createDeepAgent({
model: "baseten:zai-org/GLM-5.2",
backend: new StoreBackend({
namespace: () => ["filesystem"],
}),
store: store,
checkpointer: checkpointer,
memory: ["/AGENTS.md"],
});
const result = await agent.invoke(
{
messages: [
{
role: "user",
content: "Please tell me what's in your memory files.",
},
],
},
{ configurable: { thread_id: "12345" } },
);
import { createDeepAgent, StoreBackend, type FileData } from "deepagents";
import { InMemoryStore, MemorySaver } from "@langchain/langgraph";
const AGENTS_MD_URL =
"https://raw.githubusercontent.com/langchain-ai/deepagents/refs/heads/main/examples/text-to-sql-agent/AGENTS.md";
async function fetchText(url: string): Promise<string> {
const res = await fetch(url);
if (!res.ok) {
throw new Error(`Failed to fetch ${url}: ${res.status} ${res.statusText}`);
}
return await res.text();
}
const agentsMd = await fetchText(AGENTS_MD_URL);
function createFileData(content: string): FileData {
const now = new Date().toISOString();
return {
content,
mimeType: "text/plain",
created_at: now,
modified_at: now,
};
}
const store = new InMemoryStore();
const fileData = createFileData(agentsMd);
await store.put(["filesystem"], "/AGENTS.md", fileData);
const checkpointer = new MemorySaver();
const agent = await createDeepAgent({
model: "ollama:north-mini-code-1.0",
backend: new StoreBackend({
namespace: () => ["filesystem"],
}),
store: store,
checkpointer: checkpointer,
memory: ["/AGENTS.md"],
});
const result = await agent.invoke(
{
messages: [
{
role: "user",
content: "Please tell me what's in your memory files.",
},
],
},
{ configurable: { thread_id: "12345" } },
);
Open a public LangSmith run for this example.
import { createDeepAgent, FilesystemBackend } from "deepagents";
import { MemorySaver } from "@langchain/langgraph";
// Checkpointer is REQUIRED for human-in-the-loop
const checkpointer = new MemorySaver();
const agent = await createDeepAgent({
model: "google:gemini-3.6-flash",
backend: new FilesystemBackend({ rootDir: "/Users/user/{project}" }),
memory: ["./AGENTS.md", "./.deepagents/AGENTS.md"],
interruptOn: {
read_file: true,
write_file: true,
delete_file: true,
},
checkpointer, // Required!
});
import { createDeepAgent, FilesystemBackend } from "deepagents";
import { MemorySaver } from "@langchain/langgraph";
// Checkpointer is REQUIRED for human-in-the-loop
const checkpointer = new MemorySaver();
const agent = await createDeepAgent({
model: "openai:gpt-5.5",
backend: new FilesystemBackend({ rootDir: "/Users/user/{project}" }),
memory: ["./AGENTS.md", "./.deepagents/AGENTS.md"],
interruptOn: {
read_file: true,
write_file: true,
delete_file: true,
},
checkpointer, // Required!
});
import { createDeepAgent, FilesystemBackend } from "deepagents";
import { MemorySaver } from "@langchain/langgraph";
// Checkpointer is REQUIRED for human-in-the-loop
const checkpointer = new MemorySaver();
const agent = await createDeepAgent({
model: "anthropic:claude-sonnet-5",
backend: new FilesystemBackend({ rootDir: "/Users/user/{project}" }),
memory: ["./AGENTS.md", "./.deepagents/AGENTS.md"],
interruptOn: {
read_file: true,
write_file: true,
delete_file: true,
},
checkpointer, // Required!
});
import { createDeepAgent, FilesystemBackend } from "deepagents";
import { MemorySaver } from "@langchain/langgraph";
// Checkpointer is REQUIRED for human-in-the-loop
const checkpointer = new MemorySaver();
const agent = await createDeepAgent({
model: "openrouter:z-ai/glm-5.2",
backend: new FilesystemBackend({ rootDir: "/Users/user/{project}" }),
memory: ["./AGENTS.md", "./.deepagents/AGENTS.md"],
interruptOn: {
read_file: true,
write_file: true,
delete_file: true,
},
checkpointer, // Required!
});
import { createDeepAgent, FilesystemBackend } from "deepagents";
import { MemorySaver } from "@langchain/langgraph";
// Checkpointer is REQUIRED for human-in-the-loop
const checkpointer = new MemorySaver();
const agent = await createDeepAgent({
model: "fireworks:accounts/fireworks/models/glm-5p2",
backend: new FilesystemBackend({ rootDir: "/Users/user/{project}" }),
memory: ["./AGENTS.md", "./.deepagents/AGENTS.md"],
interruptOn: {
read_file: true,
write_file: true,
delete_file: true,
},
checkpointer, // Required!
});
import { createDeepAgent, FilesystemBackend } from "deepagents";
import { MemorySaver } from "@langchain/langgraph";
// Checkpointer is REQUIRED for human-in-the-loop
const checkpointer = new MemorySaver();
const agent = await createDeepAgent({
model: "baseten:zai-org/GLM-5.2",
backend: new FilesystemBackend({ rootDir: "/Users/user/{project}" }),
memory: ["./AGENTS.md", "./.deepagents/AGENTS.md"],
interruptOn: {
read_file: true,
write_file: true,
delete_file: true,
},
checkpointer, // Required!
});
import { createDeepAgent, FilesystemBackend } from "deepagents";
import { MemorySaver } from "@langchain/langgraph";
// Checkpointer is REQUIRED for human-in-the-loop
const checkpointer = new MemorySaver();
const agent = await createDeepAgent({
model: "ollama:north-mini-code-1.0",
backend: new FilesystemBackend({ rootDir: "/Users/user/{project}" }),
memory: ["./AGENTS.md", "./.deepagents/AGENTS.md"],
interruptOn: {
read_file: true,
write_file: true,
delete_file: true,
},
checkpointer, // Required!
});
Structured output
Deep Agents support structured output.
You can set a desired structured output schema by passing it as the responseFormat argument to the call to createDeepAgent().
Wrap the schema in a strategy such as toolStrategy() or providerStrategy() from langchain.
When the model generates the structured data, it's captured, validated, and returned in the 'structuredResponse' key of the agent's state.
import { tool, toolStrategy } from "langchain";
import { TavilySearch } from "@langchain/tavily";
import { createDeepAgent } from "deepagents";
import { z } from "zod";
const internetSearch = tool(
async ({
query,
maxResults = 5,
topic = "general",
includeRawContent = false,
}: {
query: string;
maxResults?: number;
topic?: "general" | "news" | "finance";
includeRawContent?: boolean;
}) => {
const tavilySearch = new TavilySearch({
maxResults,
tavilyApiKey: process.env.TAVILY_API_KEY,
includeRawContent,
topic,
});
return await tavilySearch._call({ query });
},
{
name: "internet_search",
description: "Run a web search",
schema: z.object({
query: z.string().describe("The search query"),
maxResults: z.number().optional().default(5),
topic: z
.enum(["general", "news", "finance"])
.optional()
.default("general"),
includeRawContent: z.boolean().optional().default(false),
}),
},
);
const weatherReportSchema = z.object({
location: z.string().describe("The location for this weather report"),
temperature: z.number().describe("Current temperature in Celsius"),
condition: z
.string()
.describe("Current weather condition (e.g., sunny, cloudy, rainy)"),
humidity: z.number().describe("Humidity percentage"),
windSpeed: z.number().describe("Wind speed in km/h"),
forecast: z.string().describe("Brief forecast for the next 24 hours"),
});
const agent = await createDeepAgent({
responseFormat: toolStrategy(weatherReportSchema),
tools: [internetSearch],
});
const result = await agent.invoke({
messages: [
{
role: "user",
content: "What's the weather like in San Francisco?",
},
],
});
console.log(result.structuredResponse);
// {
// location: 'San Francisco, California',
// temperature: 18.3,
// condition: 'Sunny',
// humidity: 48,
// windSpeed: 7.6,
// forecast: 'Clear skies with temperatures remaining mild. High of 18°C (64°F) during the day, dropping to around 11°C (52°F) at night.'
// }
Open a public LangSmith run for this example.
For more information and examples, see response format.
Advanced
createDeepAgent pre-assembles a middleware stack on top of createAgent. To build a fully custom agent—choosing exactly which capabilities to include—see Configure the harness.