LangChain Tool Calling

A chat model can only produce text. It cannot check today's weather, query a database, or send an email by itself. Tool calling gives the model a way to request those actions. The model does not run anything. It writes a structured request that says which tool to use and which inputs to pass, and your code runs the tool and reports back.

Restaurant Analogy

A customer places an order with a waiter, the kitchen cooks the meal, and the waiter returns with the plate. The customer never enters the kitchen. In tool calling, the model is the customer, your code is the waiter, and the tool is the kitchen.

 User: "What is the weather in Pune?"
        |
        v
 Model → request: get_weather(city="Pune")
        |
        v
 Your code runs get_weather("Pune") → "31°C, sunny"
        |
        v
 Model reads the result → "It is 31°C and sunny in Pune."

Defining a Tool

The @tool decorator turns an ordinary Python function into a tool. The function name, the type hints, and the docstring form the instructions the model reads. A clear docstring leads to correct choices.

from langchain_core.tools import tool

@tool
def get_weather(city: str) -> str:
    """Return the current weather for a city."""
    return f"31 degrees Celsius and sunny in {city}"

@tool
def add_numbers(a: int, b: int) -> int:
    """Add two whole numbers."""
    return a + b

Attaching Tools to a Model

The method bind_tools shares the tool descriptions with the model on every call.

model_with_tools = model.bind_tools([get_weather, add_numbers])

ai_message = model_with_tools.invoke("What is the weather in Pune?")
print(ai_message.tool_calls)

The printed list looks like this.

[{'name': 'get_weather', 'args': {'city': 'Pune'}, 'id': 'call_abc123'}]

The model chose a tool, filled the argument, and stopped. Your code now owns the next step.

Running the Tool and Replying

from langchain_core.messages import HumanMessage

messages = [HumanMessage("What is the weather in Pune?")]
ai_message = model_with_tools.invoke(messages)
messages.append(ai_message)

for call in ai_message.tool_calls:
    tool_message = get_weather.invoke(call)   # returns a ToolMessage
    messages.append(tool_message)

final = model_with_tools.invoke(messages)
print(final.content)

Passing the whole call dictionary to the tool returns a ToolMessage that carries the matching call id. The model uses that id to link each result to its request.

The Message Trail

 1. HumanMessage   "What is the weather in Pune?"
 2. AIMessage      tool_calls: get_weather(city="Pune")
 3. ToolMessage    "31 degrees Celsius and sunny in Pune"
 4. AIMessage      "It is 31°C and sunny in Pune."

Several Tools in One Reply

Some questions need more than one tool. The model may request several calls at once, and your loop handles each one in turn. Match results to calls by id, not by position.

Skipping the Tool

The model decides whether a tool is necessary. A question like "Write a short poem" returns plain text with an empty tool_calls list. Check the list before running anything.

if ai_message.tool_calls:
    run_tools(ai_message)
else:
    print(ai_message.content)

Writing Tools That Models Understand

Name Clearly

Choose verbs and nouns that describe the action, such as search_orders or calculate_tax.

Describe Precisely

State what the tool does, what each input means, and what the tool returns.

Keep Inputs Simple

Use basic types such as text, numbers, and true or false values. Complex nested inputs raise the chance of mistakes.

Return Short Results

Send back only the data the model needs. Huge outputs fill the context window.

Forcing or Limiting Tool Use

Some providers let you require a tool call or restrict choices to one tool. Use this feature when your workflow always needs a specific action, such as extracting data.

Real-World Scenario

A shop owner wants a chat assistant that checks stock levels. The developer writes a tool named check_stock that takes a product code and returns the quantity from the inventory system. A customer asks whether the blue backpack is available. The model requests check_stock with the right code, the app runs the function, and the model replies that five units remain. The model never touches the database directly. The app keeps control, and the customer receives a live answer.

Practice Tasks

  1. Write two tools, one for converting temperature and one for counting words in text.
  2. Bind both tools to a model and print the tool_calls for three different questions.
  3. Ask a question that needs no tool and confirm that tool_calls stays empty.
  4. Rewrite a vague docstring into a precise one and compare how often the model picks the tool.

Key Points

  • Tool calling lets a model request actions in structured form.
  • The model never runs the tool. Your code does.
  • @tool converts a function, and bind_tools shares it with the model.
  • ToolMessage results flow back so the model can write the final answer.
  • Clear names and docstrings drive accurate tool choices.