| name | langchain-tools |
| description | Guide to using tool integrations in LangChain including pre-built toolkits, Tavily, Wikipedia, and custom tools |
| language | js |
langchain-tools (JavaScript/TypeScript)
Overview
Tools enable LLMs to interact with external systems, perform calculations, search the web, query databases, and more. They extend model capabilities beyond text generation, making agents truly actionable.
Key Concepts
- Tools: Functions that agents can call to perform specific tasks
- Tool Calling: Models decide when and how to use tools based on user queries
- Toolkits: Collections of related tools
- Tool Schema: Describes tool parameters using Zod or JSON Schema
Tool Selection Decision Table
| Tool/Toolkit | Best For | Package | Key Features |
|---|
| Tavily Search | Web search | @langchain/community | AI-optimized search API |
| Wikipedia | Encyclopedia queries | @langchain/community | Wikipedia API access |
| Calculator | Math operations | @langchain/community | Expression evaluation |
| DuckDuckGo Search | Privacy-focused search | @langchain/community | No API key needed |
| Browser Tools | Web automation | @langchain/community | Headless browsing |
| Vector Store Tools | Semantic search | Based on vector store | Query your data |
| Custom Tools | Your specific needs | @langchain/core/tools | Define any function |
When to Choose Each Tool
Choose Tavily if:
- You need high-quality web search
- You want AI-optimized results
- You're building research/RAG applications
Choose Wikipedia if:
- You need encyclopedic knowledge
- Factual information is required
- Free, no API key needed
Choose Custom Tools if:
- You have specific business logic
- You need to integrate proprietary systems
- Built-in tools don't meet your needs
Code Examples
Tavily Search Tool
import { TavilySearchResults } from "@langchain/community/tools/tavily_search";
const searchTool = new TavilySearchResults({
maxResults: 3,
apiKey: process.env.TAVILY_API_KEY,
});
const results = await searchTool.invoke("Latest AI news");
console.log(results);
import { ChatOpenAI } from "@langchain/openai";
import { createReactAgent } from "@langchain/langgraph/prebuilt";
const model = new ChatOpenAI({ modelName: "gpt-4" });
const agent = createReactAgent({
llm: model,
tools: [searchTool],
});
const response = await agent.invoke({
messages: [{ role: "user", content: "What's new in AI today?" }]
});
Wikipedia Tool
import { WikipediaQueryRun } from "@langchain/community/tools/wikipedia_query_run";
const wikipediaTool = new WikipediaQueryRun({
topKResults: 3,
maxDocContentLength: 4000,
});
const result = await wikipediaTool.invoke("Artificial Intelligence");
console.log(result);
Calculator Tool
import { Calculator } from "@langchain/community/tools/calculator";
const calculator = new Calculator();
const result = await calculator.invoke("sqrt(144) + 5 * 3");
console.log(result);
const mathAgent = createReactAgent({
llm: model,
tools: [calculator],
});
DuckDuckGo Search (No API Key)
import { DuckDuckGoSearch } from "@langchain/community/tools/duckduckgo_search";
const searchTool = new DuckDuckGoSearch({
maxResults: 5,
});
const results = await searchTool.invoke("LangChain framework");
Custom Tool with Zod Schema
import { tool } from "@langchain/core/tools";
import { z } from "zod";
const weatherTool = tool(
async ({ location, unit = "celsius" }) => {
const data = await fetchWeather(location, unit);
return `The weather in ${location} is ${data.temp}°${unit === "celsius" ? "C" : "F"}`;
},
{
name: "get_weather",
description: "Get the current weather for a location. Use this when users ask about weather.",
schema: z.object({
location: z.string().describe("The city name, e.g., 'San Francisco'"),
unit: z.enum(["celsius", "fahrenheit"]).optional().describe("Temperature unit"),
}),
}
);
const agent = createReactAgent({
llm: model,
tools: [weatherTool],
});
const response = await agent.invoke({
messages: [{ role: "user", content: "What's the weather in London?" }]
});
Custom Tool - Class-Based
import { StructuredTool } from "@langchain/core/tools";
import { z } from "zod";
class DatabaseQueryTool extends StructuredTool {
name = "database_query";
description = "Query the customer database for information";
schema = z.object({
customerId: z.string().describe("Customer ID to look up"),
});
async _call({ customerId }: { customerId: string }): Promise<string> {
const customer = await db.getCustomer(customerId);
return JSON.stringify(customer);
}
}
const dbTool = new DatabaseQueryTool();
Vector Store as Tool
import { createRetrieverTool } from "langchain/tools/retriever";
import { MemoryVectorStore } from "langchain/vectorstores/memory";
import { OpenAIEmbeddings } from "@langchain/openai";
const vectorStore = await MemoryVectorStore.fromTexts(
["LangChain is a framework...", "Agents use tools..."],
[{}, {}],
new OpenAIEmbeddings()
);
const retrieverTool = createRetrieverTool(
vectorStore.asRetriever(),
{
name: "knowledge_base",
description: "Search the knowledge base for information about LangChain",
}
);
const agent = createReactAgent({
llm: model,
tools: [retrieverTool],
});
Multiple Tools Example
import { ChatOpenAI } from "@langchain/openai";
import { TavilySearchResults } from "@langchain/community/tools/tavily_search";
import { Calculator } from "@langchain/community/tools/calculator";
import { tool } from "@langchain/core/tools";
import { z } from "zod";
import { createReactAgent } from "@langchain/langgraph/prebuilt";
const searchTool = new TavilySearchResults({ maxResults: 3 });
const calculator = new Calculator();
const customTool = tool(
async ({ query }) => {
return `Custom result for: ${query}`;
},
{
name: "custom_lookup",
description: "Look up custom information",
schema: z.object({
query: z.string().describe("The query to look up"),
}),
}
);
const agent = createReactAgent({
llm: new ChatOpenAI({ modelName: "gpt-4" }),
tools: [searchTool, calculator, customTool],
});
const response = await agent.invoke({
messages: [{
role: "user",
content: "Search for the population of Tokyo and calculate if it doubled"
}]
});
Tool with Error Handling
import { tool } from "@langchain/core/tools";
import { z } from "zod";
const apiTool = tool(
async ({ endpoint }) => {
try {
const response = await fetch(`https://api.example.com/${endpoint}`);
if (!response.ok) {
return `API error: ${response.statusText}`;
}
const data = await response.json();
return JSON.stringify(data);
} catch (error) {
return `Failed to call API: ${error.message}`;
}
},
{
name: "api_call",
description: "Call external API",
schema: z.object({
endpoint: z.string().describe("API endpoint to call"),
}),
}
);
Boundaries
What Agents CAN Do
✅ Use pre-built tools
- Tavily search, Wikipedia, Calculator
- DuckDuckGo, web browsers
- Any tool from LangChain community
✅ Create custom tools
- Define functions with Zod schemas
- Implement class-based tools
- Convert retrievers to tools
✅ Combine multiple tools
- Give agents access to many tools
- Let models choose appropriate tools
- Chain tool calls
✅ Handle tool responses
- Parse tool output
- Use results in conversation
- Error handling
What Agents CANNOT Do
❌ Execute arbitrary code safely
- Cannot run untrusted code
- Need sandboxing for code execution
❌ Bypass authentication
- Tools need proper API keys
- Cannot access protected resources without credentials
❌ Guarantee tool selection
- Model decides which tool to use
- Cannot force specific tool usage (without prompting)
❌ Use tools model doesn't support
- Not all models support tool calling
- Need GPT-4, Claude 3, or similar
Gotchas
1. API Keys Required
const tool = new TavilySearchResults();
await tool.invoke("query");
const tool = new TavilySearchResults({
apiKey: process.env.TAVILY_API_KEY,
});
Fix: Set required API keys in environment variables.
2. Model Must Support Tools
import { ChatOpenAI } from "@langchain/openai";
const model = new ChatOpenAI({ modelName: "gpt-3.5-turbo-instruct" });
const model = new ChatOpenAI({ modelName: "gpt-4" });
const modelWithTools = model.bindTools([myTool]);
Fix: Use models that support function calling (GPT-4, Claude 3, etc.).
3. Tool Description Matters
const tool = tool(
async ({ x }) => x * 2,
{
name: "tool1",
description: "A tool",
schema: z.object({ x: z.number() }),
}
);
const tool = tool(
async ({ number }) => number * 2,
{
name: "double_number",
description: "Multiply a number by 2. Use this when the user wants to double a value.",
schema: z.object({
number: z.number().describe("The number to double"),
}),
}
);
Fix: Write clear descriptions that help the model know when to use the tool.
4. Schema Validation
const tool = tool(
async ({ location }) => {
return location.toUpperCase();
},
{
name: "format_location",
description: "Format location",
schema: z.object({ location: z.any() }),
}
);
const tool = tool(
async ({ location }) => {
return location.toUpperCase();
},
{
name: "format_location",
description: "Format location name to uppercase",
schema: z.object({
location: z.string().describe("Location name"),
}),
}
);
Fix: Use specific Zod schemas for type safety.
Links and Resources
Official Documentation
Package Installation
npm install @langchain/community
npm install @langchain/core
npm install @langchain/openai