Overview
Tools allow language models to interact with external systems, APIs, and databases. LangChain provides flexible tool abstractions for defining and using tools.
The simplest way to create a tool:
Import:
import { tool } from "@langchain/core/tools";
import { z } from "zod";
Example:
const weatherTool = tool(
async ({ location }) => {
// Implementation
return `Weather in ${location}: Sunny, 72°F`;
},
{
name: "get_weather",
description: "Get the current weather for a location",
schema: z.object({
location: z.string().describe("The city name")
})
}
);
const result = await weatherTool.invoke({ location: "San Francisco" });
Class-based tool definition with schema validation.
import { StructuredTool } from "@langchain/core/tools";
import { z } from "zod";
class CalculatorTool extends StructuredTool {
name = "calculator";
description = "Evaluate a mathematical expression";
schema = z.object({
expression: z.string().describe("The expression to evaluate")
});
async _call({ expression }: z.infer<typeof this.schema>) {
try {
return String(eval(expression));
} catch (error) {
return `Error: ${error.message}`;
}
}
}
const calculator = new CalculatorTool();
Create tools without schema validation:
import { DynamicTool } from "@langchain/core/tools";
const simpleTool = new DynamicTool({
name: "random_number",
description: "Generate a random number",
func: async () => String(Math.random())
});
Create structured tools without extending a class:
import { DynamicStructuredTool } from "@langchain/core/tools";
import { z } from "zod";
const searchTool = new DynamicStructuredTool({
name: "web_search",
description: "Search the web for information",
schema: z.object({
query: z.string(),
limit: z.number().optional()
}),
func: async ({ query, limit = 10 }) => {
// Perform search
return `Found ${limit} results for "${query}"`;
}
});
The tool name (must be unique)
Description of what the tool does (helps the model choose when to use it)
Zod schema defining the tool’s input parameters
If true, return tool output directly without further model processing
Default: false
Content-Only Response
const tool = tool(
async ({ query }) => {
return "Search results...";
},
{ name: "search", schema: z.object({ query: z.string() }) }
);
Content + Artifact Response
const tool = tool(
async ({ code }) => {
const result = executeCode(code);
return {
content: `Executed successfully. Output: ${result.output}`,
artifact: result.fullData
};
},
{
name: "code_executor",
schema: z.object({ code: z.string() }),
responseFormat: "content_and_artifact"
}
);
import { ChatOpenAI } from "@langchain/openai";
import { tool } from "@langchain/core/tools";
import { z } from "zod";
const tools = [
tool(
async ({ a, b }) => String(a + b),
{
name: "add",
description: "Add two numbers",
schema: z.object({
a: z.number(),
b: z.number()
})
}
),
tool(
async ({ a, b }) => String(a * b),
{
name: "multiply",
description: "Multiply two numbers",
schema: z.object({
a: z.number(),
b: z.number()
})
}
)
];
const model = new ChatOpenAI().bindTools(tools);
const response = await model.invoke([
["human", "What is 25 + 17?"]
]);
if (response.tool_calls && response.tool_calls.length > 0) {
const toolCall = response.tool_calls[0];
const tool = tools.find(t => t.name === toolCall.name);
const result = await tool.invoke(toolCall.args);
console.log(result); // "42"
}
Runtime Context
Access runtime information in tools:
import { tool } from "@langchain/core/tools";
const contextTool = tool(
async ({ query }, config) => {
const userId = config?.configurable?.userId;
return `Searching for ${query} (user: ${userId})`;
},
{
name: "search",
schema: z.object({ query: z.string() })
}
);
await contextTool.invoke(
{ query: "cats" },
{ configurable: { userId: "alice" } }
);
Organize related tools:
const mathTools = [
addTool,
subtractTool,
multiplyTool,
divideTool
];
const searchTools = [
webSearchTool,
documentSearchTool,
imageSearchTool
];
const allTools = [...mathTools, ...searchTools];
const model = new ChatOpenAI().bindTools(allTools);
Error Handling
const safeTool = tool(
async ({ expression }) => {
try {
return String(eval(expression));
} catch (error) {
return `Error: ${error.message}. Please provide a valid expression.`;
}
},
{
name: "calculator",
description: "Evaluate mathematical expressions",
schema: z.object({ expression: z.string() })
}
);
Creating Tools Guide
Complete guide to building tools
Agents
Using tools with agents