TellWorldAI World Archive
Ask中文

Home›Practice›Practice

Practice

Tools in LangChain

Turn ordinary Python or TypeScript functions into agent tools, covering names, schemas, return values and errors.

Who this is for and what you will build

This article is for readers who already run a first LangChain agent and want it to call functions they wrote. By the end you will know how to define a tool with @tool, name it and describe it, declare its inputs, control what it returns, and handle its errors.

What a tool is

A tool is a callable function with well-defined inputs and outputs, passed to a chat model. The model decides when to call a tool and which arguments to pass[1]. Tool calls can be traced and debugged with LangSmith[1].

Writing a tool in Python

The simplest way is the @tool decorator from langchain.tools. By default, the function's docstring becomes the tool description, and the model uses it to decide when the tool is relevant[1]:

from langchain.tools import tool

@tool
def search_database(query: str, limit: int = 10) -> str:
    """Search the customer database for records matching the query.

    Args:
        query: Search terms to look for
        limit: Maximum number of results to return
    """
    return f"Found {limit} results for '{query}'"

Type hints are required, because they define the input schema the model sees. Keep the docstring short and say what the tool is for and what its arguments mean[1].

Writing a tool in JavaScript

The JavaScript version imports tool from langchain and uses zod to describe the input. The name, description and schema are passed in the second argument[1]:

import * as z from "zod"
import { tool } from "langchain"

const searchDatabase = tool(
  ({ query, limit }) => `Found ${limit} results for '${query}'`,
  {
    name: "search_database",
    description: "Search the customer database for records matching the query.",
    schema: z.object({
      query: z.string().describe("Search terms to look for"),
      limit: z.number().describe("Maximum number of results to return"),
    }),
  }
);

Naming tools and writing descriptions

In Python, the tool name defaults to the function name. To choose a more descriptive name, write @tool("web_search")[1]:

@tool("web_search")  # Custom name
def search(query: str) -> str:
    """Search the web for information."""
    return f"Results for: {query}"

print(search.name)  # web_search

The @tool decorator also accepts a description argument that replaces the generated description[1]. Use snake_case names such as web_search rather than Web Search. Some model providers reject names with spaces or special characters, so letters, digits, underscores and hyphens give the widest compatibility[1].

Declaring complex inputs

When a tool takes several parameters, define them in a Pydantic model, pass the model through the args_schema argument, and describe each field with Field(description=...). A JSON Schema can be passed the same way[1].

Two reserved argument names

config and runtime are reserved, and using either as a tool argument causes a runtime error[1]. To read conversation state, context or long-term storage, add a runtime: ToolRuntime parameter. ToolNode injects it at call time and it is not included in the schema the model sees. Read conversation state through runtime.state[1].

Return values

A tool can return a string, an object, multimodal content, or a Command. A plain return value is wrapped in a ToolMessage and sent back to the model[1].

Returning directly and skipping the model

Setting return_direct to True makes the agent return the tool's output immediately, without another pass through the model[1]. The rule for parallel calls matters. If the model calls an ordinary tool in the same step, the agent does not exit; it sends every result back to the model. The loop ends only when every tool in that step has return_direct=True[1]. Results that still need reasoning, summarization or chaining with other tools are not a good fit for this setting[1].

A tool that returns a Command targeting the current graph must also include a ToolMessage with the matching tool_call_id in Command.update. Otherwise ToolNode raises a ValueError[1].

Handling errors

When a tool fails, agent middleware can retry the failed call or return a custom error message[1].

Common problems

  • A name rejected by the provider: usually the name contains a space or a special character. Switch to snake_case, as described above[1].
  • Built-in server-side tools: some models ship with web search or code interpreter tools that run on the provider's side. They are different from the tools you write yourself[1].
  • Reserved names: config and runtime cannot be used as argument names, as covered above[1].

Next steps

LangChain offers a large set of prebuilt tools and toolkits for web search, code interpretation and database access, and the integrations page lists them[1]. LangChain also supports tools that come from MCP servers[1].

Adapted from the Tools page of LangChain's open-source documentation[1], released under the MIT License.

Sources

  1. 1
    ToolsLangChain docs (MIT)

Cite this page: Tools in LangChain. TellWorld, https://www.tellworld.net/practice/practice-langchain-tools. Updated 2026-11-14

Related news

View all