ToolStrategy with Pydantic model example
Example creating agent with ToolStrategy and Pydantic: from pydantic import BaseModel, Field; from typing import Literal; class ProductReview(BaseModel): rating: int | None = Field(description='The rating of the product', ge=1, le=5); sentiment: Literal['positive', 'negative'] = Field(description='The sentiment of the review'); key_points: list[str] = Field(description='The key points of the review. Lowercase, 1-3 words each.'); agent = create_agent(model='gpt-5.5', tools=tools, response_format=ToolStrategy(ProductReview)); result = agent.invoke({'messages': [{'role': 'user', 'content': "Analyze this review: 'Great product: 5 out of 5 stars. Fast shipping, but expensive'"}]}); result['structured_response'] # ProductReview(rating=5, sentiment='positive', key_points=['fast shipping', 'expensive'])
Union types in ToolStrategy example
Example creating agent with ToolStrategy and Union types: from pydantic import BaseModel, Field; from typing import Literal, Union; class ProductReview(BaseModel): rating: int | None = Field(description='The rating of the product', ge=1, le=5); sentiment: Literal['positive', 'negative'] = Field(description='The sentiment of the review'); key_points: list[str] = Field(description='The key points of the review'); class CustomerComplaint(BaseModel): issue_type: Literal['product', 'service', 'shipping', 'billing'] = Field(description='The type of issue'); severity: Literal['low', 'medium', 'high'] = Field(description='The severity of the complaint'); description: str = Field(description='Brief description of the complaint'); agent = create_agent(model='gpt-5.5', tools=tools, response_format=ToolStrategy(Union[ProductReview, CustomerComplaint])); result = agent.invoke({'messages': [{'role': 'user', 'content': "Analyze this review: 'Great product: 5 out of 5 stars. Fast shipping, but expensive'"}]}); result['structured_response'] # ProductReview(rating=5, sentiment='positive', key_points=['fast shipping', 'expensive'])
ToolStrategy with custom tool_message_content example
Example creating agent with ToolStrategy and custom tool_message_content: from pydantic import BaseModel, Field; from typing import Literal; class MeetingAction(BaseModel): task: str = Field(description='The specific task to be completed'); assignee: str = Field(description='Person responsible for the task'); priority: Literal['low', 'medium', 'high'] = Field(description='Priority level'); agent = create_agent(model='gpt-5.5', tools=[], response_format=ToolStrategy(schema=MeetingAction, tool_message_content='Action item captured and added to meeting notes!')); agent.invoke({'messages': [{'role': 'user', 'content': 'From our meeting: Sarah needs to update the project timeline as soon as possible'}]}) # Tool message returns 'Action item captured and added to meeting notes!' instead of default response data message
Custom error message in ToolStrategy example
Example specifying custom error message in ToolStrategy: ToolStrategy(schema=ProductRating, handle_errors='Please provide a valid rating between 1-5 and include a comment.') - When validation fails, the tool message will contain this custom error message instead of the default validation error details.
Handle specific exception type in ToolStrategy example
Example handling specific exception in ToolStrategy: ToolStrategy(schema=ProductRating, handle_errors=ValueError) - Agent will only retry if ValueError is raised; all other exceptions will propagate.
Custom error handler function in ToolStrategy example
Example with custom error handler function: from langchain.agents.structured_output import StructuredOutputValidationError, MultipleStructuredOutputsError; def custom_error_handler(error: Exception) -> str: if isinstance(error, StructuredOutputValidationError): return 'There was an issue with the format. Try again.'; elif isinstance(error, MultipleStructuredOutputsError): return 'Multiple structured outputs were returned. Pick the most relevant one.'; else: return f'Error: {str(error)}'; agent = create_agent(model='gpt-5.5', tools=[], response_format=ToolStrategy(schema=Union[ContactInfo, EventDetails], handle_errors=custom_error_handler))
Tools and structured output simultaneous support requirement
If tools are specified in an agent with structured output, the model must support simultaneous use of tools and structured output.
Zod schema example for createAgent in JavaScript
Example creating agent with Zod schema: import * as z from 'zod'; import { createAgent, providerStrategy } from 'langchain'; const ContactInfo = z.object({name: z.string().describe('The name of the person'), email: z.string().describe('The email address of the person'), phone: z.string().describe('The phone number of the person')}); const agent = createAgent({model: 'gpt-5.5', tools: [], responseFormat: providerStrategy(ContactInfo)}); const result = await agent.invoke({messages: [{'role': 'user', 'content': 'Extract contact info from: John Doe, john@example.com, (555) 123-4567'}]}); console.log(result.structuredResponse); // { name: 'John Doe', email: 'john@example.com', phone: '(555) 123-4567' }
Standard Schema example for createAgent in JavaScript
Example creating agent with Standard Schema: import * as v from 'valibot'; import { toStandardJsonSchema } from '@valibot/to-json-schema'; import { createAgent, providerStrategy } from 'langchain'; const ContactInfo = toStandardJsonSchema(v.object({name: v.pipe(v.string(), v.description('The name of the person')), email: v.pipe(v.string(), v.description('The email address of the person')), phone: v.pipe(v.string(), v.description('The phone number of the person'))})); const agent = createAgent({model: 'gpt-5.5', tools: [], responseFormat: providerStrategy(ContactInfo)}); const result = await agent.invoke({messages: [{'role': 'user', 'content': 'Extract contact info from: John Doe, john@example.com, (555) 123-4567'}]}); console.log(result.structuredResponse); // { name: 'John Doe', email: 'john@example.com', phone: '(555) 123-4567' }
JSON Schema example for createAgent in JavaScript
Example creating agent with JSON Schema: import { createAgent, providerStrategy } from 'langchain'; const contactInfoSchema = {'type': 'object', 'description': 'Contact information for a person.', 'properties': {'name': {'type': 'string', 'description': 'The name of the person'}, 'email': {'type': 'string', 'description': 'The email address of the person'}, 'phone': {'type': 'string', 'description': 'The phone number of the person'}}, 'required': ['name', 'email', 'phone']}; const agent = createAgent({model: 'gpt-5.5', tools: [], responseFormat: providerStrategy(contactInfoSchema)}); const result = await agent.invoke({messages: [{'role': 'user', 'content': 'Extract contact info from: John Doe, john@example.com, (555) 123-4567'}]}); console.log(result.structuredResponse); // { name: 'John Doe', email: 'john@example.com', phone: '(555) 123-4567' }
toolStrategy with Zod schema example in JavaScript
Example creating agent with toolStrategy and Zod schema: import * as z from 'zod'; import { createAgent, toolStrategy } from 'langchain'; const ProductReview = z.object({rating: z.number().min(1).max(5).optional(), sentiment: z.enum(['positive', 'negative']), keyPoints: z.array(z.string()).describe('The key points of the review. Lowercase, 1-3 words each.')}); const agent = createAgent({model: 'gpt-5.5', tools: [], responseFormat: toolStrategy(ProductReview)}); const result = await agent.invoke({'messages': [{'role': 'user', 'content': "Analyze this review: 'Great product: 5 out of 5 stars. Fast shipping, but expensive'"}]}); console.log(result.structuredResponse); // { 'rating': 5, 'sentiment': 'positive', 'keyPoints': ['fast shipping', 'expensive'] }
toolStrategy with Union types example in JavaScript
Example creating agent with toolStrategy and Union types: import * as z from 'zod'; import { createAgent, toolStrategy } from 'langchain'; const ProductReview = z.object({rating: z.number().min(1).max(5).optional(), sentiment: z.enum(['positive', 'negative']), keyPoints: z.array(z.string()).describe('The key points of the review')}); const CustomerComplaint = z.object({issueType: z.enum(['product', 'service', 'shipping', 'billing']), severity: z.enum(['low', 'medium', 'high']), description: z.string().describe('Brief description of the complaint')}); const agent = createAgent({model: 'gpt-5.5', tools: [], responseFormat: toolStrategy([ProductReview, CustomerComplaint])}); const result = await agent.invoke({messages: [{'role': 'user', 'content': "Analyze this review: 'Great product: 5 out of 5 stars. Fast shipping, but expensive'"}]}); console.log(result.structuredResponse); // { 'rating': 5, 'sentiment': 'positive', 'keyPoints': ['fast shipping', 'expensive'] }
Fallback behavior when model doesn't support native structured output
If the provider natively supports structured output for the chosen model, writing response_format=ContactInfo (or responseFormat: contactInfoSchema in JavaScript) is functionally equivalent to using ProviderStrategy or providerStrategy explicitly. If structured output is not supported, the agent will automatically fall back to a tool calling strategy.
toolStrategy with custom toolMessageContent example in JavaScript
Example creating agent with toolStrategy and custom toolMessageContent: import * as z from 'zod'; import { createAgent, toolStrategy } from 'langchain'; const MeetingAction = z.object({task: z.string().describe('The specific task to be completed'), assignee: z.string().describe('Person responsible for the task'), priority: z.enum(['low', 'medium', 'high']).describe('Priority level')}); const agent = createAgent({model: 'gpt-5.5', tools: [], responseFormat: toolStrategy(MeetingAction, {toolMessageContent: 'Action item captured and added to meeting notes!'})}); const result = await agent.invoke({messages: [{'role': 'user', 'content': 'From our meeting: Sarah needs to update the project timeline as soon as possible'}]}); // Tool message contains 'Action item captured and added to meeting notes!' instead of default response data
fakeModel structuredResponse for withStructuredOutput testing
For code that uses .withStructuredOutput(), configure the fake return value with .structuredResponse(). The schema passed to .withStructuredOutput() is ignored; the model always returns the value configured with .structuredResponse(). This keeps tests focused on application logic rather than parsing.
fakeModel structuredResponse example
Example of fakeModel .structuredResponse():
import { fakeModel } from "langchain";
import { HumanMessage } from "@langchain/core/messages";
import { z } from "zod";
const model = fakeModel()
.structuredResponse({ temperature: 72, unit: "fahrenheit" });
const structured = model.withStructuredOutput(
z.object({
temperature: z.number(),
unit: z.string(),
})
);
const result = await structured.invoke([new HumanMessage("Weather?")]);
console.log(result);
// { temperature: 72, unit: "fahrenheit" }