Skip to content

Commit a8baf36

Browse files
authored
docs: document structured output for subagents (#3426)
- Document the `response_format` / `responseFormat` field on the SubAgent config, added in [deepagentsjs#290](langchain-ai/deepagentsjs#290). - Rewrite the "Structured output" section in the subagents page with code examples for both Python and JS.
1 parent 2eb51ca commit a8baf36

1 file changed

Lines changed: 73 additions & 9 deletions

File tree

src/oss/deepagents/subagents.mdx

Lines changed: 73 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ For most use cases, define subagents as dictionaries matching the @[`SubAgent`]
6060
| `middleware` | `list[Middleware]` | Optional. Additional middleware for custom behavior, logging, or rate limiting.<br></br>Does not inherit from main agent. |
6161
| `interrupt_on` | `dict[str, bool]` | Optional. Configure [human-in-the-loop](/oss/deepagents/human-in-the-loop) for specific tools. Subagent value overrides main agent. Requires checkpointer.<br></br>Inherits from main agent by default. Subagent value overrides the default. |
6262
| `skills` | `list[str]` | Optional. [Skills](/oss/deepagents/skills) source paths. When specified, the subagent will load skills from these directories (e.g., `["/skills/research/", "/skills/web-search/"]`). This allows subagents to have different skill sets than the main agent.<br></br>Does not inherit from main agent. Only the general-purpose subagent inherits the main agent's skills. When a subagent has skills, it runs its own independent @[`SkillsMiddleware`] instance. Skill state is fully isolated—a subagent's loaded skills are not visible to the parent, and vice versa. |
63+
| `response_format` | `ResponseFormat` | Optional. [Structured output](/oss/langchain/structured-output) schema for the subagent. When set, the parent receives the subagent's result as JSON instead of free-form text. Accepts Pydantic models, `ToolStrategy(...)`, `ProviderStrategy(...)`, or a raw schema type. See [Structured output](#structured-output). |
6364
| `permissions` | `list[FilesystemPermission]` | Optional. [Filesystem permission rules](/oss/deepagents/permissions) for the subagent. When set, **replaces** the parent agent's permissions entirely.<br></br>Inherits from main agent by default. |
6465

6566
:::
@@ -76,6 +77,7 @@ For most use cases, define subagents as dictionaries matching the @[`SubAgent`]
7677
| `middleware` | `list[Middleware]` | Optional. Additional middleware for custom behavior, logging, or rate limiting.<br></br>Does not inherit from main agent. |
7778
| `interrupt_on` | `dict[str, bool]` | Optional. Configure [human-in-the-loop](/oss/deepagents/human-in-the-loop) for specific tools. Subagent value overrides main agent. Requires checkpointer.<br></br>Inherits from main agent by default. Subagent value overrides the default. |
7879
| `skills` | `list[str]` | Optional. [Skills](/oss/deepagents/skills) source paths. When specified, the subagent will load skills from these directories (e.g., `["/skills/research/", "/skills/web-search/"]`). This allows subagents to have different skill sets than the main agent.<br></br>Does not inherit from main agent. Only the general-purpose subagent inherits the main agent's skills. When a subagent has skills, it runs its own independent @[`SkillsMiddleware`] instance. Skill state is fully isolated—a subagent's loaded skills are not visible to the parent, and vice versa. |
80+
| `responseFormat` | `ResponseFormat` | Optional. [Structured output](/oss/langchain/structured-output) schema for the subagent. When set, the parent receives the subagent's result as JSON instead of free-form text. Accepts Zod schemas, JSON schema objects, `toolStrategy(...)`, or `providerStrategy(...)`. See [Structured output](#structured-output). |
7981

8082
:::
8183

@@ -223,21 +225,83 @@ In this case the subagent with the name `"research-agent"`, will have `{'lc_agen
223225

224226
## Structured output
225227

226-
All subagents support [structured output](/oss/langchain/structured-output) which you can use to validate the subagent's output.
228+
Subagents support [structured output](/oss/langchain/structured-output), so the parent agent receives predictable, parseable JSON instead of free-form text.
227229

228230
:::python
229-
You can set a desired structured output schema by passing it as the `response_format` argument to the call to `create_agent()`.
230-
When the model generates the structured data, it’s captured and validated.
231-
The structured object itself is not returned to the parent agent.
232-
When using structured output with subagents, include the structured data in the `ToolMessage`.
231+
Pass `response_format` on the subagent config. When the subagent finishes, its structured response is JSON-serialized and returned as the `ToolMessage` content to the parent agent. The schema accepts anything supported by @[`create_agent`]: Pydantic models, `ToolStrategy(...)`, `ProviderStrategy(...)`, or a raw schema type.
232+
233+
```python
234+
from pydantic import BaseModel, Field
235+
236+
from deepagents import create_deep_agent
237+
238+
239+
class ResearchFindings(BaseModel):
240+
"""Structured findings from a research task."""
241+
summary: str = Field(description="Summary of findings")
242+
confidence: float = Field(description="Confidence score from 0 to 1")
243+
sources: list[str] = Field(description="List of source URLs")
244+
245+
research_subagent = {
246+
"name": "researcher",
247+
"description": "Researches topics and returns structured findings",
248+
"system_prompt": "Research the given topic thoroughly. Return your findings.",
249+
"tools": [web_search],
250+
"response_format": ResearchFindings,
251+
}
252+
253+
agent = create_deep_agent(
254+
model="claude-sonnet-4-6",
255+
subagents=[research_subagent],
256+
)
257+
258+
result = await agent.ainvoke(
259+
{"messages": [{"role": "user", "content": "Research recent advances in quantum computing"}]}
260+
)
261+
262+
# The parent's ToolMessage contains JSON-serialized structured data:
263+
# '{"summary": "...", "confidence": 0.87, "sources": ["https://..."]}'
264+
```
233265
:::
266+
234267
:::js
235-
You can set a desired structured output schema by passing it as the `responseFormat` argument to the call to `createAgent()`.
236-
When the model generates the structured data, it’s captured and validated. The structured object itself is not returned to the parent agent.
237-
When using structured output with subagents, include the structured data in the `ToolMessage`.
268+
Pass `responseFormat` on the subagent config. When the subagent finishes, its structured response is JSON-serialized and returned as the `ToolMessage` content to the parent agent. The schema accepts anything supported by `createAgent`: Zod schemas, JSON schema objects, `toolStrategy(...)`, or `providerStrategy(...)`.
269+
270+
```typescript
271+
import { z } from "zod";
272+
import { createDeepAgent } from "deepagents";
273+
274+
const ResearchFindings = z.object({
275+
summary: z.string().describe("Summary of findings"),
276+
confidence: z.number().describe("Confidence score from 0 to 1"),
277+
sources: z.array(z.string()).describe("List of source URLs"),
278+
});
279+
280+
const researchSubagent = {
281+
name: "researcher",
282+
description: "Researches topics and returns structured findings",
283+
systemPrompt: "Research the given topic thoroughly. Return your findings.",
284+
tools: [webSearch],
285+
responseFormat: ResearchFindings,
286+
};
287+
288+
const agent = createDeepAgent({
289+
model: "claude-sonnet-4-6",
290+
subagents: [researchSubagent],
291+
});
292+
293+
const result = await agent.invoke({
294+
messages: [{ role: "user", content: "Research recent advances in quantum computing" }],
295+
});
296+
297+
// The parent's ToolMessage contains JSON-serialized structured data:
298+
// '{"summary": "...", "confidence": 0.87, "sources": ["https://..."]}'
299+
```
238300
:::
239301

240-
For more information, see [response format](/oss/langchain/structured-output#response-format).
302+
Without `response_format`, the parent receives the subagent's last message text as-is. With it, the parent always gets valid JSON matching the schema, which is useful when the parent needs to process the result programmatically or pass it to downstream tools.
303+
304+
For full details on schema types and strategies (tool calling vs. provider-native), see [Structured output](/oss/langchain/structured-output).
241305

242306
## The general-purpose subagent
243307

0 commit comments

Comments
 (0)