diff --git a/src/docs.json b/src/docs.json
index 3905df8dd8..f144d555b1 100644
--- a/src/docs.json
+++ b/src/docs.json
@@ -583,6 +583,30 @@
}
]
},
+ {
+ "tab": "Deep Agents",
+ "pages": [
+ "oss/javascript/deepagents/overview",
+ {
+ "group": "Get started",
+ "pages": [
+ "oss/javascript/deepagents/quickstart",
+ "oss/javascript/deepagents/customization"
+ ]
+ },
+ {
+ "group": "Core capabilities",
+ "pages": [
+ "oss/javascript/deepagents/harness",
+ "oss/javascript/deepagents/backends",
+ "oss/javascript/deepagents/subagents",
+ "oss/javascript/deepagents/human-in-the-loop",
+ "oss/javascript/deepagents/long-term-memory",
+ "oss/javascript/deepagents/middleware"
+ ]
+ }
+ ]
+ },
{
"tab": "Integrations",
"pages": [
@@ -709,7 +733,8 @@
"group": "Reference",
"pages": [
"oss/javascript/reference/langchain-javascript",
- "oss/javascript/reference/langgraph-javascript"
+ "oss/javascript/reference/langgraph-javascript",
+ "oss/javascript/reference/deepagents-javascript"
]
},
{
diff --git a/src/oss/deepagents/backends.mdx b/src/oss/deepagents/backends.mdx
index 5001d70970..1d1c2d56bc 100644
--- a/src/oss/deepagents/backends.mdx
+++ b/src/oss/deepagents/backends.mdx
@@ -37,6 +37,20 @@ agent = create_deep_agent(
```
:::
+:::js
+```typescript
+import { createDeepAgent, StateBackend } from "deepagents";
+
+// By default we provide a StateBackend
+const agent = createDeepAgent();
+
+// Under the hood, it looks like
+const agent2 = createDeepAgent({
+ backend: (rt) => new StateBackend(rt), // Note that the tools access State through the runtime.state
+});
+```
+:::
+
**How it works:**
- Stores files in LangGraph agent state for the current thread.
- Persists across multiple agent turns on the same thread via checkpoints.
@@ -47,17 +61,28 @@ agent = create_deep_agent(
### FilesystemBackend (local disk)
+:::python
```python
from deepagents.backends import FilesystemBackend
agent = create_deep_agent(
- backend=FilesystemBackend(root_dir="/Users/nh/Desktop/")
+ backend=FilesystemBackend(root_dir=".", virtual_mode=True)
)
```
+:::
+
+:::js
+```typescript
+import { createDeepAgent, FilesystemBackend } from "deepagents";
+
+const agent = createDeepAgent({
+ backend: new FilesystemBackend({ rootDir: ".", virtualMode: true }),
+});
+```
+:::
**How it works:**
- Reads/writes real files under a configurable `root_dir`.
-- Note: `root_dir` must be an absolute path.
- You can optionally set `virtual_mode=True` to sandbox and normalize paths under `root_dir`.
- Uses secure path resolution, prevents unsafe symlink traversal when possible, can use ripgrep for fast `grep`.
@@ -68,13 +93,30 @@ agent = create_deep_agent(
### StoreBackend (LangGraph Store)
+:::python
```python
+from langgraph.store.memory import InMemoryStore
from deepagents.backends import StoreBackend
agent = create_deep_agent(
- backend=(lambda rt: StoreBackend(rt)) # Note that the tools access Store through the runtime.store
+ backend=(lambda rt: StoreBackend(rt)), # Note that the tools access Store through the runtime.store
+ store=InMemoryStore()
)
```
+:::
+
+:::js
+```typescript
+import { createDeepAgent, StoreBackend } from "deepagents";
+import { InMemoryStore } from "@langchain/langgraph";
+
+const store = new InMemoryStore()
+const agent = createDeepAgent({
+ backend: (rt) => new StoreBackend(rt),
+ store
+});
+```
+:::
**How it works:**
- Stores files in a LangGraph `BaseStore` provided by the runtime, enabling cross‑thread durable storage.
@@ -89,18 +131,37 @@ agent = create_deep_agent(
:::python
```python
from deepagents import create_deep_agent
-from deepagents.backends import FilesystemBackend
-from deepagents.backends.composite import build_composite_state_backend
+from deepagents.backends import CompositeBackend, StateBackend, StoreBackend
+from langgraph.store.memory import InMemoryStore
composite_backend = lambda rt: CompositeBackend(
- default=StateBackend(rt)
+ default=StateBackend(rt),
routes={
"/memories/": StoreBackend(rt),
- "/docs/": CustomBackend()
}
)
-agent = create_deep_agent(backend=composite_backend)
+agent = create_deep_agent(
+ backend=composite_backend,
+ store=InMemoryStore() # Store passed to create_deep_agent, not backend
+)
+```
+:::
+
+:::js
+```typescript
+import { createDeepAgent, CompositeBackend, StateBackend, StoreBackend } from "deepagents";
+import { InMemoryStore } from "@langchain/langgraph";
+
+const compositeBackend = (rt) => new CompositeBackend(
+ new StateBackend(rt),
+ {
+ "/memories/": new StoreBackend(rt),
+ }
+);
+
+const store = new InMemoryStore()
+const agent = createDeepAgent({ backend: compositeBackend, store });
```
:::
@@ -129,12 +190,12 @@ Route parts of the namespace to different backends. Commonly used to persist `/m
:::python
```python
from deepagents import create_deep_agent
-from deepagents.backends import FilesystemBackend
-from deepagents.backends.composite import build_composite_state_backend
+from deepagents.backends import CompositeBackend, StateBackend, FilesystemBackend
composite_backend = lambda rt: CompositeBackend(
+ default=StateBackend(rt),
routes={
- "/memories/": FilesystemBackend(root_dir="/deepagents/myagent"),
+ "/memories/": FilesystemBackend(root_dir="/deepagents/myagent", virtual_mode=True),
},
)
@@ -142,6 +203,21 @@ agent = create_deep_agent(backend=composite_backend)
```
:::
+:::js
+```typescript
+import { createDeepAgent, CompositeBackend, FilesystemBackend, StateBackend } from "deepagents";
+
+const compositeBackend = (rt) => new CompositeBackend(
+ new StateBackend(rt),
+ {
+ "/memories/": new FilesystemBackend({ rootDir: "/deepagents/myagent", virtualMode: true }),
+ },
+);
+
+const agent = createDeepAgent({ backend: compositeBackend });
+```
+:::
+
Behavior:
- `/workspace/plan.md` → StateBackend (ephemeral)
- `/memories/agent.md` → FilesystemBackend under `/deepagents/myagent`
diff --git a/src/oss/deepagents/customization.mdx b/src/oss/deepagents/customization.mdx
index 92d2542661..6e50bbf008 100644
--- a/src/oss/deepagents/customization.mdx
+++ b/src/oss/deepagents/customization.mdx
@@ -24,7 +24,25 @@ agent = create_deep_agent(
:::js
```typescript
-// TODO: Add JS implementation
+import { ChatAnthropic } from "@langchain/anthropic";
+import { ChatOpenAI } from "@langchain/openai";
+import { createDeepAgent } from "deepagents";
+
+// Using Anthropic
+const agent = createDeepAgent({
+ model: new ChatAnthropic({
+ model: "claude-sonnet-4-20250514",
+ temperature: 0,
+ }),
+});
+
+// Using OpenAI
+const agent2 = createDeepAgent({
+ model: new ChatOpenAI({
+ model: "gpt-5",
+ temperature: 0,
+ }),
+});
```
:::
@@ -51,7 +69,13 @@ agent = create_deep_agent(
:::js
```typescript
-// TODO: Add JS implementation
+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({
+ systemPrompt: researchInstructions,
+});
```
:::
@@ -90,7 +114,49 @@ agent = create_deep_agent(
:::js
```typescript
-// TODO: Add JS implementation
+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({
+ tools: [internetSearch],
+});
```
:::
diff --git a/src/oss/deepagents/human-in-the-loop.mdx b/src/oss/deepagents/human-in-the-loop.mdx
index 5e96a27ee4..c1b68270f2 100644
--- a/src/oss/deepagents/human-in-the-loop.mdx
+++ b/src/oss/deepagents/human-in-the-loop.mdx
@@ -52,7 +52,53 @@ agent = create_deep_agent(
:::js
```typescript
-// TODO: Add JS implementation
+import { tool } from "langchain";
+import { createDeepAgent } from "deepagents";
+import { MemorySaver } from "@langchain/langgraph";
+import { z } from "zod";
+import { v4 as uuidv4 } from 'uuid'; // install uuid package: npm install uuid
+
+const deleteFile = tool(
+ async ({ path }: { path: string }) => {
+ return `Deleted ${path}`;
+ },
+ {
+ name: "delete_file",
+ description: "Delete a file from the filesystem.",
+ schema: z.object({
+ path: z.string(),
+ }),
+ },
+);
+
+const sendEmail = tool(
+ async ({ to, subject, body }: { to: string; subject: string; body: string }) => {
+ return `Sent email to ${to}`;
+ },
+ {
+ name: "send_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: "claude-sonnet-4-5-20250929",
+ tools: [deleteFile, sendEmail],
+ interruptOn: {
+ delete_file: true, // Default: approve, edit, reject
+ read_file: false, // No interrupts needed
+ send_email: { allowedDecisions: ["approve", "reject"] }, // No editing
+ },
+ checkpointer, // Required!
+});
```
:::
@@ -83,7 +129,16 @@ interrupt_on = {
:::js
```typescript
-// TODO: Add JS implementation
+const interruptOn = {
+ // Sensitive operations: allow all options
+ delete_file: { allowedDecisions: ["approve", "edit", "reject"] },
+
+ // Moderate risk: approval or rejection only
+ write_file: { allowedDecisions: ["approve", "reject"] },
+
+ // Must approve (no rejection allowed)
+ critical_operation: { allowedDecisions: ["approve"] },
+};
```
:::
@@ -139,7 +194,51 @@ print(result["messages"][-1]["content"])
:::js
```typescript
-// TODO: Add JS implementation
+import { v4 as uuidv4 } from "uuid";
+import { Command } from "@langchain/langgraph";
+
+// Create config with thread_id for state persistence
+const config = { configurable: { thread_id: uuidv4() } };
+
+// Invoke the agent
+let result = await agent.invoke({
+ messages: [{ role: "user", content: "Delete the file temp.txt" }],
+}, config);
+
+// Check if execution was interrupted
+if (result.__interrupt__) {
+ // Extract interrupt information
+ const interrupts = result.__interrupt__[0].value;
+ const actionRequests = interrupts.actionRequests;
+ const reviewConfigs = interrupts.reviewConfigs;
+
+ // Create a lookup map from tool name to review config
+ const configMap = Object.fromEntries(
+ reviewConfigs.map((cfg) => [cfg.actionName, cfg])
+ );
+
+ // Display the pending actions to the user
+ for (const action of actionRequests) {
+ const reviewConfig = configMap[action.name];
+ console.log(`Tool: ${action.name}`);
+ console.log(`Arguments: ${JSON.stringify(action.args)}`);
+ console.log(`Allowed decisions: ${reviewConfig.allowedDecisions}`);
+ }
+
+ // Get user decisions (one per actionRequest, in order)
+ const decisions = [
+ { type: "approve" } // User approved the deletion
+ ];
+
+ // Resume execution with decisions
+ result = await agent.invoke(
+ new Command({ resume: { decisions } }),
+ config // Must use the same config!
+ );
+}
+
+// Process final result
+console.log(result.messages[result.messages.length - 1].content);
```
:::
@@ -180,7 +279,33 @@ if result.get("__interrupt__"):
:::js
```typescript
-// TODO: Add JS implementation
+const config = { configurable: { thread_id: uuidv4() } };
+
+let result = await agent.invoke({
+ messages: [{
+ role: "user",
+ content: "Delete temp.txt and send an email to admin@example.com"
+ }]
+}, config);
+
+if (result.__interrupt__) {
+ const interrupts = result.__interrupt__[0].value;
+ const actionRequests = interrupts.actionRequests;
+
+ // Two tools need approval
+ console.assert(actionRequests.length === 2);
+
+ // Provide decisions in the same order as actionRequests
+ const decisions = [
+ { type: "approve" }, // First tool: delete_file
+ { type: "reject" } // Second tool: send_email
+ ];
+
+ result = await agent.invoke(
+ new Command({ resume: { decisions } }),
+ config
+ );
+}
```
:::
@@ -215,7 +340,27 @@ if result.get("__interrupt__"):
:::js
```typescript
-// TODO: Add JS implementation
+if (result.__interrupt__) {
+ const interrupts = result.__interrupt__[0].value;
+ const actionRequest = interrupts.actionRequests[0];
+
+ // Original args from the agent
+ console.log(actionRequest.args); // { to: "everyone@company.com", ... }
+
+ // User decides to edit the recipient
+ const decisions = [{
+ type: "edit",
+ editedAction: {
+ name: actionRequest.name, // Must include the tool name
+ args: { to: "team@company.com", subject: "...", body: "..." }
+ }
+ }];
+
+ result = await agent.invoke(
+ new Command({ resume: { decisions } }),
+ config
+ );
+}
```
:::
@@ -249,7 +394,25 @@ agent = create_deep_agent(
:::js
```typescript
-// TODO: Add JS implementation
+const agent = createDeepAgent({
+ tools: [deleteFile, readFile],
+ interruptOn: {
+ delete_file: true,
+ read_file: false,
+ },
+ subagents: [{
+ name: "file-manager",
+ description: "Manages file operations",
+ systemPrompt: "You are a file management assistant.",
+ tools: [deleteFile, readFile],
+ interruptOn: {
+ // Override: require approval for reads in this subagent
+ delete_file: true,
+ read_file: true, // Different from main agent!
+ }
+ }],
+ checkpointer
+});
```
:::
diff --git a/src/oss/deepagents/long-term-memory.mdx b/src/oss/deepagents/long-term-memory.mdx
index 7594eac82a..001f5e12dd 100644
--- a/src/oss/deepagents/long-term-memory.mdx
+++ b/src/oss/deepagents/long-term-memory.mdx
@@ -3,51 +3,70 @@ title: Long-term memory
description: Learn how to extend deep agents with persistent memory across threads
---
-Deep agents come with a local filesystem to offload memory. This filesystem is stored in state and is therefore **transient to a single thread**—files are lost when the conversation ends.
+Deep agents come with a local filesystem to offload memory. By default, this filesystem is stored in agent state and is **transient to a single thread**—files are lost when the conversation ends.
-You can extend deep agents with **long-term memory** by providing a LangGraph `Store` and setting `use_longterm_memory=True`. This enables persistent storage that survives across threads and conversations.
+You can extend deep agents with **long-term memory** by using a **CompositeBackend** that routes specific paths to persistent storage. This enables hybrid storage where some files persist across threads while others remain ephemeral.
## Setup
+Configure long-term memory by using a `CompositeBackend` that routes the `/memories/` path to a `StoreBackend`:
+
:::python
```python
from deepagents import create_deep_agent
+from deepagents.backends import CompositeBackend, StateBackend, StoreBackend
from langgraph.store.memory import InMemoryStore
-store = InMemoryStore() # Or any other Store object
+def make_backend(runtime):
+ return CompositeBackend(
+ default=StateBackend(runtime), # Ephemeral storage
+ routes={
+ "/memories/": StoreBackend(runtime) # Persistent storage
+ }
+ )
+
agent = create_deep_agent(
- store=store,
- use_longterm_memory=True
+ store=InMemoryStore(), # Required for StoreBackend
+ backend=make_backend
)
```
:::
:::js
```typescript
-// TODO: Add JS implementation
+import { createDeepAgent } from "deepagents";
+import { CompositeBackend, StateBackend, StoreBackend } from "deepagents";
+import { InMemoryStore } from "@langchain/langgraph-checkpoint";
+
+const agent = createDeepAgent({
+ store: new InMemoryStore(), // Required for StoreBackend
+ backend: (config) => new CompositeBackend(
+ new StateBackend(config), // Ephemeral storage
+ { "/memories/": new StoreBackend(config) } // Persistent storage
+ ),
+});
```
:::
## How it works
-When long-term memory is enabled, deep agents maintain **two separate filesystems**:
+When using `CompositeBackend`, deep agents maintain **two separate filesystems**:
### 1. Short-term (transient) filesystem
-- Stored in the agent's state
+- Stored in the agent's state (via `StateBackend`)
- Persists only within a single thread
- Files are lost when the thread ends
-- Accessed through standard paths: `/notes.txt`
+- Accessed through standard paths: `/notes.txt`, `/workspace/draft.md`
### 2. Long-term (persistent) filesystem
-- Stored in a LangGraph Store
+- Stored in a LangGraph Store (via `StoreBackend`)
- Persists across all threads and conversations
-- Files survive indefinitely
-- Accessed through the special prefix: `/memories/notes.txt`
-
-## The /memories/ path convention
+- Survives agent restarts
+- Accessed through paths prefixed with `/memories/`: `/memories/preferences.txt`
-**The key to long-term memory is the `/memories/` path prefix:**
+### Path routing
+The `CompositeBackend` routes file operations based on path prefixes:
- Files with paths starting with `/memories/` are stored in the Store (persistent)
- Files without this prefix remain in transient state
- All filesystem tools (`ls`, `read_file`, `write_file`, `edit_file`) work with both
@@ -68,7 +87,15 @@ agent.invoke({
:::js
```typescript
-// TODO: Add JS implementation
+// Transient file (lost after thread ends)
+await agent.invoke({
+ messages: [{ role: "user", content: "Write draft to /draft.txt" }],
+});
+
+// Persistent file (survives across threads)
+await agent.invoke({
+ messages: [{ role: "user", content: "Save final report to /memories/report.txt" }],
+});
```
:::
@@ -97,7 +124,20 @@ agent.invoke({
:::js
```typescript
-// TODO: Add JS implementation
+import { v4 as uuidv4 } from "uuid";
+
+// Thread 1: Write to long-term memory
+const config1 = { configurable: { thread_id: uuidv4() } };
+await agent.invoke({
+ messages: [{ role: "user", content: "Save my preferences to /memories/preferences.txt" }],
+}, config1);
+
+// Thread 2: Read from long-term memory (different conversation!)
+const config2 = { configurable: { thread_id: uuidv4() } };
+await agent.invoke({
+ messages: [{ role: "user", content: "What are my preferences?" }],
+}, config2);
+// Agent can read /memories/preferences.txt from the first thread
```
:::
@@ -110,8 +150,11 @@ Store user preferences that persist across sessions:
:::python
```python
agent = create_deep_agent(
- store=store,
- use_longterm_memory=True,
+ store=InMemoryStore(),
+ backend=lambda rt: CompositeBackend(
+ default=StateBackend(rt),
+ routes={"/memories/": StoreBackend(rt)}
+ ),
system_prompt="""When users tell you their preferences, save them to
/memories/user_preferences.txt so you remember them in future conversations."""
)
@@ -120,7 +163,14 @@ agent = create_deep_agent(
:::js
```typescript
-// TODO: Add JS implementation
+const agent = createDeepAgent({
+ store: new InMemoryStore(),
+ backend: (config) => new CompositeBackend(
+ new StateBackend(config),
+ { "/memories/": new StoreBackend(config) }
+ ),
+ systemPrompt: `When users tell you their preferences, save them to /memories/user_preferences.txt so you remember them in future conversations.`,
+});
```
:::
@@ -131,8 +181,11 @@ An agent can update its own instructions based on feedback:
:::python
```python
agent = create_deep_agent(
- store=store,
- use_longterm_memory=True,
+ store=InMemoryStore(),
+ backend=lambda rt: CompositeBackend(
+ default=StateBackend(rt),
+ routes={"/memories/": StoreBackend(rt)}
+ ),
system_prompt="""You have a file at /memories/instructions.txt with additional
instructions and preferences.
@@ -146,7 +199,18 @@ agent = create_deep_agent(
:::js
```typescript
-// TODO: Add JS implementation
+const agent = createDeepAgent({
+ store: new InMemoryStore(),
+ backend: (config) => new CompositeBackend(
+ new StateBackend(config),
+ { "/memories/": new StoreBackend(config) }
+ ),
+ systemPrompt: `You have a file at /memories/instructions.txt with additional instructions and preferences.
+
+ Read this file at the start of conversations to understand user preferences.
+
+ When users provide feedback like "please always do X" or "I prefer Y", update /memories/instructions.txt using the edit_file tool.`,
+});
```
:::
@@ -173,7 +237,16 @@ agent.invoke({
:::js
```typescript
-// TODO: Add JS implementation
+// Conversation 1: Learn about a project
+await agent.invoke({
+ messages: [{ role: "user", content: "We're building a web app with React. Save project notes." }],
+});
+
+// Conversation 2: Use that knowledge
+await agent.invoke({
+ messages: [{ role: "user", content: "What framework are we using?" }],
+});
+// Agent reads /memories/project_notes.txt from previous conversation
```
:::
@@ -184,8 +257,11 @@ Maintain research state across sessions:
:::python
```python
research_agent = create_deep_agent(
- store=store,
- use_longterm_memory=True,
+ store=InMemoryStore(),
+ backend=lambda rt: CompositeBackend(
+ default=StateBackend(rt),
+ routes={"/memories/": StoreBackend(rt)}
+ ),
system_prompt="""You are a research assistant.
Save your research progress to /memories/research/:
@@ -200,7 +276,21 @@ research_agent = create_deep_agent(
:::js
```typescript
-// TODO: Add JS implementation
+const researchAgent = createDeepAgent({
+ store: new InMemoryStore(),
+ backend: (config) => new CompositeBackend(
+ new StateBackend(config),
+ { "/memories/": new StoreBackend(config) }
+ ),
+ systemPrompt: `You are a research assistant.
+
+ Save your research progress to /memories/research/:
+ - /memories/research/sources.txt - List of sources found
+ - /memories/research/notes.txt - Key findings and notes
+ - /memories/research/report.md - Final report draft
+
+ This allows research to continue across multiple sessions.`,
+});
```
:::
@@ -217,13 +307,29 @@ Good for testing and development, but data is lost on restart:
from langgraph.store.memory import InMemoryStore
store = InMemoryStore()
-agent = create_deep_agent(store=store, use_longterm_memory=True)
+agent = create_deep_agent(
+ store=store,
+ backend=lambda rt: CompositeBackend(
+ default=StateBackend(rt),
+ routes={"/memories/": StoreBackend(rt)}
+ )
+)
```
:::
:::js
```typescript
-// TODO: Add JS implementation
+import { InMemoryStore } from "@langchain/langgraph-checkpoint";
+import { createDeepAgent, CompositeBackend, StateBackend, StoreBackend } from "deepagents";
+
+const store = new InMemoryStore();
+const agent = createDeepAgent({
+ store,
+ backend: (config) => new CompositeBackend(
+ new StateBackend(config),
+ { "/memories/": new StoreBackend(config) }
+ ),
+});
```
:::
@@ -237,13 +343,31 @@ from langgraph.store.postgres import PostgresStore
import os
store = PostgresStore(connection_string=os.environ["DATABASE_URL"])
-agent = create_deep_agent(store=store, use_longterm_memory=True)
+agent = create_deep_agent(
+ store=store,
+ backend=lambda rt: CompositeBackend(
+ default=StateBackend(rt),
+ routes={"/memories/": StoreBackend(rt)}
+ )
+)
```
:::
:::js
```typescript
-// TODO: Add JS implementation
+import { PostgresStore } from "@langchain/langgraph-checkpoint-postgres";
+import { createDeepAgent, CompositeBackend, StateBackend, StoreBackend } from "deepagents";
+
+const store = new PostgresStore({
+ connectionString: process.env.DATABASE_URL,
+});
+const agent = createDeepAgent({
+ store,
+ backend: (config) => new CompositeBackend(
+ new StateBackend(config),
+ { "/memories/": new StoreBackend(config) }
+ ),
+});
```
:::
@@ -251,125 +375,32 @@ agent = create_deep_agent(store=store, use_longterm_memory=True)
### Use descriptive paths
-Organize long-term files with clear, hierarchical paths:
-
-:::python
-```python
-# ✅ Good: Organized and descriptive
-/memories/user_preferences/language.txt
-/memories/projects/project_alpha/status.txt
-/memories/research/quantum_computing/sources.txt
-
-# ❌ Bad: Generic and unorganized
-/memories/temp.txt
-/memories/data.txt
-/memories/file1.txt
-```
-:::
-
-### Document what gets persisted
-
-In system prompts, clarify when to use long-term vs short-term storage:
-
-:::python
-```python
-system_prompt="""You have access to two types of storage:
-
-SHORT-TERM (paths without /memories/):
-- Current conversation notes
-- Temporary scratch work
-- Draft documents
-
-LONG-TERM (paths starting with /memories/):
-- User preferences and settings
-- Completed reports and documents
-- Knowledge that should persist across conversations
-- Project state and progress
-
-Always use /memories/ for information that should survive beyond this conversation."""
-```
-:::
-
-### Isolate storage by assistant ID
-
-For multi-tenant applications, provide an `assistant_id` to isolate storage:
+Organize persistent files with clear paths:
-:::python
-```python
-config = {
- "configurable": {
- "thread_id": "thread-123",
- },
- "metadata": {
- "assistant_id": "user-456" # Namespace isolation
- }
-}
-
-agent.invoke({"messages": [...]}, config=config)
```
-:::
-
-Each assistant gets its own namespace in the Store, preventing cross-contamination.
-
-### Use persistent stores in production
-
-:::python
-```python
-# ❌ Development only - data lost on restart
-store = InMemoryStore()
-
-# ✅ Production - data persists
-from langgraph.store.postgres import PostgresStore
-store = PostgresStore(connection_string=os.environ["DATABASE_URL"])
+/memories/user_preferences.txt
+/memories/research/topic_a/sources.txt
+/memories/research/topic_a/notes.txt
+/memories/project/requirements.md
```
-:::
-
-## Listing files
-The `ls` tool shows files from both filesystems:
+### Document the memory structure
-:::python
-```python
-agent.invoke({
- "messages": [{"role": "user", "content": "List all files"}]
-})
+Tell the agent what's stored where in your system prompt:
-# Example output:
-# Transient files:
-# - /draft.txt
-# - /temp_notes.txt
-#
-# Long-term files:
-# - /memories/user_preferences.txt
-# - /memories/project_status.txt
```
-:::
-
-Files from the Store are prefixed with `/memories/` in listings.
-
-## Limitations
-
-### Store is required
-
-You must provide a Store when enabling long-term memory:
-
-:::python
-```python
-# ❌ This will error
-agent = create_deep_agent(use_longterm_memory=True) # Missing store!
-
-# ✅ Correct
-agent = create_deep_agent(
- use_longterm_memory=True,
- store=InMemoryStore()
-)
+Your persistent memory structure:
+- /memories/preferences.txt: User preferences and settings
+- /memories/context/: Long-term context about the user
+- /memories/knowledge/: Facts and information learned over time
```
-:::
-### Agents must use correct paths
+### Prune old data
-The agent must learn to use the `/memories/` prefix for persistence. The system prompt teaches this, but the agent must follow the instructions.
+Implement periodic cleanup of outdated persistent files to keep storage manageable.
-### No automatic cleanup
+### Choose the right storage
-Long-term files persist indefinitely. There's no built-in TTL or automatic cleanup. You'll need to implement cleanup strategies if needed.
+- **Development**: Use `InMemoryStore` for quick iteration
+- **Production**: Use `PostgresStore` or other persistent stores
+- **Multi-tenant**: Consider using assistant_id-based namespacing in your store
diff --git a/src/oss/deepagents/middleware.mdx b/src/oss/deepagents/middleware.mdx
index 253003f86c..759b35d3cf 100644
--- a/src/oss/deepagents/middleware.mdx
+++ b/src/oss/deepagents/middleware.mdx
@@ -43,7 +43,19 @@ agent = create_agent(
:::js
```typescript
-// TODO: Add JS implementation
+import { createAgent, todoListMiddleware } from "langchain";
+
+// todoListMiddleware is included by default in createDeepAgent
+// You can customize it if building a custom agent
+const agent = createAgent({
+ model: "claude-sonnet-4-5-20250929",
+ middleware: [
+ todoListMiddleware({
+ // Optional: Custom addition to the system prompt
+ systemPrompt: "Use the write_todos tool to...",
+ }),
+ ],
+});
```
:::
@@ -58,6 +70,7 @@ Context engineering is a main challenge in building effective agents. This is pa
- **write_file**: Write a new file to the filesystem
- **edit_file**: Edit an existing file in the filesystem
+:::python
```python
from langchain.agents import create_agent
from deepagents.middleware.filesystem import FilesystemMiddleware
@@ -68,7 +81,7 @@ agent = create_agent(
model="claude-sonnet-4-5-20250929",
middleware=[
FilesystemMiddleware(
- long_term_memory=False, # Enables access to long-term memory, defaults to False. You must attach a store to use long-term memory.
+ backend=None, # Optional: custom backend (defaults to StateBackend)
system_prompt="Write to the filesystem when...", # Optional custom addition to the system prompt
custom_tool_descriptions={
"ls": "Use the ls tool when...",
@@ -78,15 +91,40 @@ agent = create_agent(
],
)
```
+:::
+
+:::js
+```typescript
+import { createAgent } from "langchain";
+import { createFilesystemMiddleware } from "deepagents";
+
+// FilesystemMiddleware is included by default in createDeepAgent
+// You can customize it if building a custom agent
+const agent = createAgent({
+ model: "claude-sonnet-4-5-20250929",
+ middleware: [
+ createFilesystemMiddleware({
+ backend: undefined, // Optional: custom backend (defaults to StateBackend)
+ systemPrompt: "Write to the filesystem when...", // Optional custom system prompt override
+ customToolDescriptions: {
+ ls: "Use the ls tool when...",
+ read_file: "Use the read_file tool to...",
+ }, // Optional: Custom descriptions for filesystem tools
+ }),
+ ],
+});
+```
+:::
### Short-term vs. long-term filesystem
-By default, these tools write to a local "filesystem" in your graph state. If you provide a `Store` object to your agent runtime, you can also enable saving to long-term memory, which persists **across** different threads of your agent.
+By default, these tools write to a local "filesystem" in your graph state. To enable persistent storage across threads, configure a `CompositeBackend` that routes specific paths (like `/memories/`) to a `StoreBackend`.
:::python
```python
from langchain.agents import create_agent
from deepagents.middleware import FilesystemMiddleware
+from deepagents.backends import CompositeBackend, StateBackend, StoreBackend
from langgraph.store.memory import InMemoryStore
store = InMemoryStore()
@@ -96,7 +134,10 @@ agent = create_agent(
store=store,
middleware=[
FilesystemMiddleware(
- long_term_memory=True,
+ backend=lambda rt: CompositeBackend(
+ default=StateBackend(rt),
+ routes={"/memories/": StoreBackend(rt)}
+ ),
custom_tool_descriptions={
"ls": "Use the ls tool when...",
"read_file": "Use the read_file tool to..."
@@ -109,11 +150,33 @@ agent = create_agent(
:::js
```typescript
-// TODO: Add JS implementation
+import { createAgent } from "langchain";
+import { createFilesystemMiddleware, CompositeBackend, StateBackend, StoreBackend } from "deepagents";
+import { InMemoryStore } from "@langchain/langgraph-checkpoint";
+
+const store = new InMemoryStore();
+
+const agent = createAgent({
+ model: "claude-sonnet-4-5-20250929",
+ store,
+ middleware: [
+ createFilesystemMiddleware({
+ backend: (config) => new CompositeBackend(
+ new StateBackend(config),
+ { "/memories/": new StoreBackend(config) }
+ ),
+ systemPrompt: "Write to the filesystem when...", // Optional custom system prompt override
+ customToolDescriptions: {
+ ls: "Use the ls tool when...",
+ read_file: "Use the read_file tool to...",
+ }, // Optional: Custom descriptions for filesystem tools
+ }),
+ ],
+});
```
:::
-If you enable `use_longterm_memory=True` and provide a `Store` in your agent runtime, then any files prefixed with **/memories/** are saved to the long-term memory store. Note that any agents deployed on LangGraph Platform are automatically provided with a long-term memory store.
+When you configure a `CompositeBackend` with a `StoreBackend` for `/memories/`, any files prefixed with **/memories/** are saved to persistent storage and survive across different threads. Files without this prefix remain in ephemeral state storage.
## Subagent middleware
@@ -121,6 +184,7 @@ Handing off tasks to subagents isolates context, keeping the main (supervisor) a
The subagents middleware allows you to supply subagents through a `task` tool.
+:::python
```python
from langchain_core.tools import tool
from langchain.agents import create_agent
@@ -144,7 +208,7 @@ agent = create_agent(
"description": "This subagent can get weather in cities.",
"system_prompt": "Use the get_weather tool to get the weather in a city.",
"tools": [get_weather],
- "model": "gpt-4.1",
+ "model": "gpt-4o",
"middleware": [],
}
],
@@ -152,6 +216,49 @@ agent = create_agent(
],
)
```
+:::
+
+:::js
+```typescript
+import { tool } from "langchain";
+import { createAgent } from "langchain";
+import { createSubAgentMiddleware } from "deepagents";
+import { z } from "zod";
+
+const getWeather = tool(
+ async ({ 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(),
+ }),
+ },
+);
+
+const agent = createAgent({
+ model: "claude-sonnet-4-5-20250929",
+ middleware: [
+ createSubAgentMiddleware({
+ defaultModel: "claude-sonnet-4-5-20250929",
+ defaultTools: [],
+ subagents: [
+ {
+ name: "weather",
+ description: "This subagent can get weather in cities.",
+ systemPrompt: "Use the get_weather tool to get the weather in a city.",
+ tools: [getWeather],
+ model: "gpt-4o",
+ middleware: [],
+ },
+ ],
+ }),
+ ],
+});
+```
+:::
A subagent is defined with a **name**, **description**, **system prompt**, and **tools**. You can also provide a subagent with a custom **model**, or with additional **middleware**. This can be particularly useful when you want to give the subagent an additional state key to share with the main agent.
@@ -194,7 +301,42 @@ agent = create_agent(
:::js
```typescript
-// TODO: Add JS implementation
+import { tool, createAgent } from "langchain";
+import { createSubAgentMiddleware, type SubAgent } from "deepagents";
+import { z } from "zod";
+
+const getWeather = tool(
+ async ({ 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(),
+ }),
+ },
+);
+
+const weatherSubagent: SubAgent = {
+ name: "weather",
+ description: "This subagent can get weather in cities.",
+ systemPrompt: "Use the get_weather tool to get the weather in a city.",
+ tools: [getWeather],
+ model: "gpt-4o",
+ middleware: [],
+};
+
+const agent = createAgent({
+ model: "claude-sonnet-4-5-20250929",
+ middleware: [
+ createSubAgentMiddleware({
+ defaultModel: "claude-sonnet-4-5-20250929",
+ defaultTools: [],
+ subagents: [weatherSubagent],
+ }),
+ ],
+});
```
:::
diff --git a/src/oss/deepagents/quickstart.mdx b/src/oss/deepagents/quickstart.mdx
index 2a60af41ed..97d51ae980 100644
--- a/src/oss/deepagents/quickstart.mdx
+++ b/src/oss/deepagents/quickstart.mdx
@@ -11,6 +11,7 @@ Before you begin, make sure you have an API key from a model provider (e.g., Ant
### Step 1: Install dependencies
+:::python
```bash pip
pip install deepagents tavily-python
@@ -24,6 +25,23 @@ Before you begin, make sure you have an API key from a model provider (e.g., Ant
poetry add deepagents tavily-python
```
+:::
+
+:::js
+
+ ```bash npm
+ npm install deepagents @langchain/tavily
+ ```
+
+ ```bash yarn
+ yarn add deepagents @langchain/tavily
+ ```
+
+ ```bash pnpm
+ pnpm add deepagents @langchain/tavily
+ ```
+
+:::
### Step 2: Set up your API keys
@@ -61,12 +79,59 @@ def internet_search(
:::js
```typescript
-// TODO: Add JS implementation
+import { tool } from "langchain";
+import { TavilySearch } from "@langchain/tavily";
+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)
+ .describe("Maximum number of results to return"),
+ topic: z
+ .enum(["general", "news", "finance"])
+ .optional()
+ .default("general")
+ .describe("Search topic category"),
+ includeRawContent: z
+ .boolean()
+ .optional()
+ .default(false)
+ .describe("Whether to include raw content"),
+ }),
+ },
+);
```
:::
### Step 4: Create a deep agent
+:::python
```python
# System prompt to steer the agent to be an expert researcher
research_instructions = """You are an expert researcher. Your job is to conduct thorough research and then write a polished report.
@@ -83,15 +148,50 @@ agent = create_deep_agent(
system_prompt=research_instructions
)
```
+:::
+
+:::js
+```typescript
+import { createDeepAgent } from "deepagents";
+
+// System prompt to steer the agent to be an expert researcher
+const researchInstructions = `You are an expert researcher. Your job is to conduct thorough research and then write a polished report.
+
+You have access to an internet search tool as your primary means of gathering information.
+
+## \`internet_search\`
+
+Use this to run an internet search for a given query. You can specify the max number of results to return, the topic, and whether raw content should be included.
+`;
+
+const agent = createDeepAgent({
+ tools: [internetSearch],
+ systemPrompt: researchInstructions,
+});
+```
+:::
### Step 5: Run the agent
+:::python
```python
result = agent.invoke({"messages": [{"role": "user", "content": "What is langgraph?"}]})
# Print the agent's response
print(result["messages"][-1].content)
```
+:::
+
+:::js
+```typescript
+const result = await agent.invoke({
+ messages: [{ role: "user", content: "What is langgraph?" }],
+});
+
+// Print the agent's response
+console.log(result.messages[result.messages.length - 1].content);
+```
+:::
## What happened?
diff --git a/src/oss/deepagents/subagents.mdx b/src/oss/deepagents/subagents.mdx
index e2d1169507..19e0b07480 100644
--- a/src/oss/deepagents/subagents.mdx
+++ b/src/oss/deepagents/subagents.mdx
@@ -50,6 +50,7 @@ For complex workflows, use a pre-built LangGraph graph:
## Using SubAgent
+:::python
```python
import os
from typing import Literal
@@ -86,6 +87,66 @@ agent = create_deep_agent(
subagents=subagents
)
```
+:::
+
+:::js
+```typescript
+import { tool } from "langchain";
+import { TavilySearch } from "@langchain/tavily";
+import { createDeepAgent } from "deepagents";
+import { ChatAnthropic } from "@langchain/anthropic";
+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 = {
+ name: "research-agent",
+ description: "Used to research more in depth questions",
+ systemPrompt: "You are a great researcher",
+ tools: [internetSearch],
+ model: new ChatAnthropic({model:"claude-sonnet-4-5-20250929"}), // Optional override, defaults to main agent model
+};
+const subagents = [researchSubagent];
+
+const agent = createDeepAgent({
+ model: new ChatAnthropic({model:"claude-sonnet-4-5-20250929"}),
+ subagents: subagents,
+});
+```
+:::
## Using CompiledSubAgent
@@ -123,7 +184,31 @@ agent = create_deep_agent(
:::js
```typescript
-// TODO: Add JS implementation
+import { createDeepAgent, CompiledSubAgent } from "deepagents";
+import { createAgent } from "langchain";
+
+// Create a custom agent graph
+const customGraph = createAgent({
+ model: yourModel,
+ tools: specializedTools,
+ prompt: "You are a specialized agent for data analysis...",
+});
+
+// Use it as a custom subagent
+const customSubagent: CompiledSubAgent = {
+ name: "data-analyzer",
+ description: "Specialized agent for complex data analysis tasks",
+ runnable: customGraph,
+};
+
+const subagents = [customSubagent];
+
+const agent = createDeepAgent({
+ model: "claude-sonnet-4-5-20250929",
+ tools: [internetSearch],
+ systemPrompt: researchInstructions,
+ subagents: subagents,
+});
```
:::
@@ -181,7 +266,24 @@ research_subagent = {
:::js
```typescript
-// TODO: Add JS implementation
+const researchSubagent = {
+ name: "research-agent",
+ description: "Conducts in-depth research using web search and synthesizes findings",
+ systemPrompt: `You are a thorough researcher. Your job is to:
+
+ 1. Break down the research question into searchable queries
+ 2. Use internet_search to find relevant information
+ 3. Synthesize findings into a comprehensive but concise summary
+ 4. Cite sources when making claims
+
+ Output format:
+ - Summary (2-3 paragraphs)
+ - Key findings (bullet points)
+ - Sources (with URLs)
+
+ Keep your response under 500 words to maintain clean context.`,
+ tools: [internetSearch],
+};
```
:::
@@ -207,7 +309,17 @@ email_agent = {
:::js
```typescript
-// TODO: Add JS implementation
+// ✅ Good: Focused tool set
+const emailAgent = {
+ name: "email-sender",
+ tools: [sendEmail, validateEmail], // Only email-related
+};
+
+// ❌ Bad: Too many tools
+const emailAgentBad = {
+ name: "email-sender",
+ tools: [sendEmail, webSearch, databaseQuery, fileUpload], // Unfocused
+};
```
:::
@@ -230,7 +342,7 @@ subagents = [
"description": "Analyzes financial data and market trends",
"system_prompt": "You are an expert financial analyst...",
"tools": [get_stock_price, analyze_fundamentals],
- "model": "openai:gpt-4o", # Better for numerical analysis
+ "model": "openai:gpt-5", # Better for numerical analysis
},
]
```
@@ -238,7 +350,22 @@ subagents = [
:::js
```typescript
-// TODO: Add JS implementation
+const subagents = [
+ {
+ name: "contract-reviewer",
+ description: "Reviews legal documents and contracts",
+ systemPrompt: "You are an expert legal reviewer...",
+ tools: [readDocument, analyzeContract],
+ model: "claude-sonnet-4-5-20250929", // Large context for long documents
+ },
+ {
+ name: "financial-analyst",
+ description: "Analyzes financial data and market trends",
+ systemPrompt: "You are an expert financial analyst...",
+ tools: [getStockPrice, analyzeFundamentals],
+ model: "gpt-5", // Better for numerical analysis
+ },
+];
```
:::
@@ -266,7 +393,19 @@ data_analyst = {
:::js
```typescript
-// TODO: Add JS implementation
+const dataAnalyst = {
+ systemPrompt: `Analyze the data and return:
+ 1. Key insights (3-5 bullet points)
+ 2. Overall confidence score
+ 3. Recommended next actions
+
+ Do NOT include:
+ - Raw data
+ - Intermediate calculations
+ - Detailed tool outputs
+
+ Keep response under 300 words.`,
+};
```
:::
@@ -311,7 +450,34 @@ agent = create_deep_agent(
:::js
```typescript
-// TODO: Add JS implementation
+import { createDeepAgent } from "deepagents";
+
+const subagents = [
+ {
+ name: "data-collector",
+ description: "Gathers raw data from various sources",
+ systemPrompt: "Collect comprehensive data on the topic",
+ tools: [webSearch, apiCall, databaseQuery],
+ },
+ {
+ name: "data-analyzer",
+ description: "Analyzes collected data for insights",
+ systemPrompt: "Analyze data and extract key insights",
+ tools: [statisticalAnalysis],
+ },
+ {
+ name: "report-writer",
+ description: "Writes polished reports from analysis",
+ systemPrompt: "Create professional reports from insights",
+ tools: [formatDocument],
+ },
+];
+
+const agent = createDeepAgent({
+ model: "claude-sonnet-4-5-20250929",
+ systemPrompt: "You coordinate data analysis and reporting. Use subagents for specialized tasks.",
+ subagents: subagents,
+});
```
:::
@@ -333,6 +499,8 @@ Each subagent works with clean context focused only on its task.
**Solutions**:
1. **Make descriptions more specific:**
+
+ :::python
```python
# ✅ Good
{"name": "research-specialist", "description": "Conducts in-depth research on specific topics using web search. Use when you need detailed information that requires multiple searches."}
@@ -340,8 +508,21 @@ Each subagent works with clean context focused only on its task.
# ❌ Bad
{"name": "helper", "description": "helps with stuff"}
```
+ :::
+
+ :::js
+ ```typescript
+ // ✅ Good
+ { name: "research-specialist", description: "Conducts in-depth research on specific topics using web search. Use when you need detailed information that requires multiple searches." }
+
+ // ❌ Bad
+ { name: "helper", description: "helps with stuff" }
+ ```
+ :::
2. **Instruct main agent to delegate:**
+
+ :::python
```python
agent = create_deep_agent(
system_prompt="""...your instructions...
@@ -351,6 +532,19 @@ Each subagent works with clean context focused only on its task.
subagents=[...]
)
```
+ :::
+
+ :::js
+ ```typescript
+ const agent = createDeepAgent({
+ systemPrompt: `...your instructions...
+
+ IMPORTANT: For complex tasks, delegate to your subagents using the task() tool.
+ This keeps your context clean and improves results.`,
+ subagents: [...]
+ });
+ ```
+ :::
### Context still getting bloated
@@ -359,6 +553,8 @@ Each subagent works with clean context focused only on its task.
**Solutions**:
1. **Instruct subagent to return concise results:**
+
+ :::python
```python
system_prompt="""...
@@ -366,8 +562,21 @@ Each subagent works with clean context focused only on its task.
Do NOT include raw data, intermediate search results, or detailed tool outputs.
Your response should be under 500 words."""
```
+ :::
+
+ :::js
+ ```typescript
+ systemPrompt: `...
+
+ IMPORTANT: Return only the essential summary.
+ Do NOT include raw data, intermediate search results, or detailed tool outputs.
+ Your response should be under 500 words.`
+ ```
+ :::
2. **Use filesystem for large data:**
+
+ :::python
```python
system_prompt="""When you gather large amounts of data:
1. Save raw data to /data/raw_results.txt
@@ -376,6 +585,18 @@ Each subagent works with clean context focused only on its task.
This keeps context clean."""
```
+ :::
+
+ :::js
+ ```typescript
+ systemPrompt: `When you gather large amounts of data:
+ 1. Save raw data to /data/raw_results.txt
+ 2. Process and analyze the data
+ 3. Return only the analysis summary
+
+ This keeps context clean.`
+ ```
+ :::
### Wrong subagent being selected
@@ -383,6 +604,7 @@ Each subagent works with clean context focused only on its task.
**Solution**: Differentiate subagents clearly in descriptions:
+:::python
```python
subagents = [
{
@@ -395,3 +617,19 @@ subagents = [
}
]
```
+:::
+
+:::js
+```typescript
+const subagents = [
+ {
+ name: "quick-researcher",
+ description: "For simple, quick research questions that need 1-2 searches. Use when you need basic facts or definitions.",
+ },
+ {
+ name: "deep-researcher",
+ description: "For complex, in-depth research requiring multiple searches, synthesis, and analysis. Use for comprehensive reports.",
+ }
+];
+```
+:::
diff --git a/src/oss/reference/deepagents-javascript.mdx b/src/oss/reference/deepagents-javascript.mdx
new file mode 100644
index 0000000000..bd59558703
--- /dev/null
+++ b/src/oss/reference/deepagents-javascript.mdx
@@ -0,0 +1,4 @@
+---
+title: Deep Agents
+url: https://reference.langchain.com/javascript/deepagents/
+---