Module 2: Tools and Tool Calling

Introduction: why models need tools

Overview

LLMs are impressive at generating text, but that's exactly what they are — text generators. They can't search the web, they can't do reliable math, they can't query your database, they can't call an external API. They're trapped inside their training window.

Tools solve that limitation. With tool calling, a model can decide "I need to look up the current weather in Madrid" and you run that lookup on its behalf. The model decides which tool to use and with what arguments, you execute the tool, and the model folds the result into its final answer.

In this module you'll learn to create tools, connect them to models, and run the full tool calling flow. By the end, your models will be able to do things plain text never allowed.


Where are we in the guide?

This is Module 2 of the guide LangChain & LangGraph: From Chains to Agents. It builds directly on Module 1 — you already know how to initialize models, run them with invoke/stream/batch, and get structured output. Now you're going to give them hands to act in the real world.

The guide has 4 progressive blocks:

Block 1: LangChain Core (Modules 1-4)     ← YOU ARE HERE (Module 2)
Block 2: LangGraph Fundamentals (Modules 5-7)
Block 3: Advanced LangGraph (Modules 8-10)
Block 4: Production (Modules 11-12)
Your progress in Block 1:

Module 1: Models and Providers            ✅ Done
    │
    ▼
Module 2: Tools and Tool Calling          ← YOU ARE HERE
    │
    ▼
Module 3: Agents (create_agent)           🔒 Next
    │
    ▼
Module 4: Middleware and Customization    🔒 After that

In Module 1 you learned to connect to models and get answers back. But those answers are limited to what the model already knows. With tools, the model can reach real-time information, run exact calculations, and interact with external systems.


Why models need tools

The fundamental problem

An LLM can only do one thing: predict the next token based on its training. That means it has hard limits:

LimitationExampleWhy it fails
No real-time data"What's the weather in Mexico City right now?"Its knowledge has a cutoff date
Unreliable math"What's 847 × 293?"It computes "approximately" instead of exactly
No access to your data"How many users do I have in my DB?"It has no connection to your database
No external actions"Send an email to support"It can only generate the email's text
No updated context"What's Bitcoin's current price?"It answers with training data

The model is a powerful brain with no hands. It can reason, plan, and decide what to do — but it can't execute anything on its own.

Tools unlock capabilities

With tools, the same questions get real answers:

QuestionWithout toolsWith tools
"Weather in Mexico City?""Generally mild..." (generic)"18°C, cloudy, 65% humidity" (real-time)
"847 × 293?""Roughly 248,000" (wrong)"248,171" (exact, via calculator)
"How many active users?""I don't have access to your DB""1,247 active users" (via SQL query)
"Find news about LangChain"Info from its trainingFresh search results
"Send an email to support"Writes the text but doesn't send itSends the email via an email API

The difference is clear: without tools, the model either makes things up or admits ignorance. With tools, it gets real data and answers with precise information.

Types of tools you can create

Tools fall into categories based on what they do:

CategoryExamplesWhat it solves
Real-time dataWeather, prices, newsThe model reaches current information
Exact calculationsCalculator, conversions, statisticsMath results with no error
Data queriesSQL, internal APIs, searchThe model reaches your systems
ActionsSend emails, create tickets, publishThe model performs real tasks
ProcessingTranslation, formatting, extractionOperations that need specific logic

In this module you'll cover the first 3 categories. Actions with side effects need more care (validation, user confirmation) and go deeper in later modules with Human-in-the-Loop (Module 9).


The tool calling flow

Tool calling follows a clear 5-step flow:

┌──────────┐     ┌──────────┐     ┌──────────┐     ┌──────────┐     ┌──────────┐
│ 1. User  │────▶│ 2. Model │────▶│ 3. Tool  │────▶│ 4. Model │────▶│ 5. User  │
│ asks     │     │ picks    │     │ runs     │     │ folds in │     │ gets the │
│          │     │ the tool │     │          │     │ result   │     │ answer   │
└──────────┘     └──────────┘     └──────────┘     └──────────┘     └──────────┘

Step by step:

  1. The user sends a question — "What's the weather in Madrid?"
  2. The model analyzes and decides — "I need the get_weather tool with city='Madrid'"
  3. You execute the tool — You call the get_weather("Madrid") function and get the result
  4. The model folds it in — It receives the result and generates a natural answer
  5. The user gets the answer — "It's 22°C and sunny in Madrid"

A concrete example of the flow

User: "What's 847 × 293, and what's the square root of the result?"

Step 2 — The model decides:
  → tool_call: multiply(a=847, b=293)

Step 3 — You execute:
  → multiply(847, 293) = 248171

Step 4 — The model receives 248171 and decides:
  → tool_call: square_root(n=248171)

Step 3 (again) — You execute:
  → square_root(248171) = 498.17

Step 4 — The model puts it all together:

Step 5 — Answer to the user:
  "847 × 293 = 248,171. The square root of 248,171 is roughly 498.17"

The model can chain multiple tool calls when it needs intermediate results. This loop repeats until the model has everything it needs to answer.

An important detail: the model does NOT execute tools

The model generates a JSON with the tool's name and arguments. It's your code that runs the actual function. That gives you full control:

  • ✅ You can validate the arguments before executing
  • ✅ You can decide whether a tool is safe to run
  • ✅ You can add logging, rate limiting, or a timeout
  • ✅ You can handle errors and give the model feedback
  • ❌ The model never gets direct access to your systems

What the model produces internally looks something like this:

{
  "tool_calls": [
    {
      "name": "get_weather",
      "args": {"city": "Madrid", "units": "celsius"},
      "id": "call_abc123"
    }
  ]
}

Your code reads that JSON, runs get_weather(city="Madrid", units="celsius"), and hands the result back to the model as a ToolMessage.


The brain and the hands

Think of the model as an expert brain that can size up a situation, reason about what to do, and give precise instructions. The tools are the hands that carry those instructions out.

A surgeon (the brain) tells the team (the hands): "I need scalpel #3, a 5cm cut along the incision". The surgeon doesn't pick anything up directly — they give instructions and the team executes. If something can't be done, the team reports back and the surgeon adjusts the plan.

That's how tool calling works: the model gives instructions, your code executes, and the model adjusts based on the results.

What if the model doesn't need tools?

If the question doesn't call for a tool, the model just answers with plain text. Tool calling is optional per question — the model decides whether it needs a tool or not.

"What is Python?"        → The model answers directly (no tools needed)
"What's 2+2?"            → The model can answer directly or use the calculator
"Weather in Madrid?"     → The model needs the get_weather tool

The model looks at each question and decides whether any of the available tools would help it give a better answer.

Tool calling is an industry standard

Tool calling isn't exclusive to LangChain. The major providers support it natively:

  • OpenAI — they call it "function calling" (since GPT-3.5, improved in GPT-4.1)
  • Anthropic — they call it "tool use" (since Claude 3)
  • Google — supported in Gemini as "function calling"
  • Local models — Llama 3.1+ and Mistral support it

LangChain unifies all these implementations behind a single interface. You write the tool once and it works with any provider that supports tool calling — exactly the way init_chat_model unifies model initialization.


What you'll master in this module

By the end of this module's 8 capsules, you'll be able to:

  • ✅ Create tools with the @tool decorator and Pydantic schemas
  • ✅ Connect tools to models with bind_tools() and control tool_choice
  • ✅ Implement the full tool execution loop (model → tool → model)
  • ✅ Handle parallel tool calls (multiple tools in a single invocation)
  • Stream tool call chunks
  • ✅ Use tool calling as a structured extraction mechanism
  • ✅ Implement robust error handling when a tool fails

Module map

CapsuleTopicWhat you'll learn
02Creating tools with @toolThe @tool decorator, names and descriptions, argument schemas with Pydantic, async tools
03bind_tools and the tool calling flowmodel.bind_tools(), tool_choice, forcing tool calls, inspecting tool_calls in an AIMessage
04Tool execution loopRunning tools by hand, ToolMessage, the full loop, when to use a manual loop vs an agent
05Parallel tool calls and streamingMultiple simultaneous tool calls, streaming chunks, accumulating chunks
06Structured output with toolsTool calling as a structured extraction mechanism, combining tools + structured output
07Error handling and troubleshootingCommon errors, retry logic, debugging, schema validation
08Project: assistant with toolsAn assistant with weather, web search, and calculator tools

Learning flow: First you'll learn to create tools (02). Then to connect them to models (03). Then to run the full loop where the model calls tools and uses their results (04). With that down, you'll move on to parallel calls and streaming (05), structured extraction with tools (06), and robust error handling (07). At the end, you'll pull it all together into a working assistant (08).


Connection to the project

This module's mini-project: an assistant with external tools

In Capsule 08 you'll build a conversational assistant that:

  1. Has 3 tools wired up: weather (weather API), web search, and calculator
  2. Lets the model decide on its own which tool to use based on the user's question
  3. Handles parallel tool calls — if the user asks "weather in Madrid and Buenos Aires?", the model calls the tool twice at once
  4. Implements error handling — if a tool fails, the model gets the error and recovers

Every concept you learn in capsules 02-07 gets applied directly in this project.

Connection to the whole guide

The tools you create here are the foundation for everything that comes next:

  • Module 3: create_agent automates the tool execution loop — instead of writing the loop by hand, the agent does it for you. It's the difference between driving stick and driving automatic.
  • Module 4: The middleware system lets you intercept tool calls before they run (logging, validation, rate limiting).
  • Modules 5-7: In LangGraph, tools run as nodes in a graph, which gives you granular control over the flow.
  • Modules 8-10: In multi-agent systems, different agents carry different tools — a data agent has SQL tools, a communications agent has email tools.

Boundaries: what this module does NOT cover

  • Agents (create_agent) — covered in Module 3. Here you learn the manual loop so you understand what happens internally.
  • Middleware and customization — covered in Module 4. Intercepting and modifying tool calls before/after they run.
  • LangGraph workflows — covered in Modules 5-7. Orchestrating tools as graph nodes.
  • MCP (Model Context Protocol) — a standard for interoperable tools; we mention it briefly but don't go deep.
  • Advanced third-party tools — we cover built-in tools as an example, but the focus is on building your own.

Technical setup

Prerequisites

Before continuing, make sure you have:

  • Module 1 done — you know how to use init_chat_model, invoke, and structured output
  • Python 3.11+ installed
  • ✅ At least one API key from a provider that supports tool calling (OpenAI or Anthropic recommended)
  • ✅ Basic familiarity with Pydantic (Python data models)

Installation

You don't need any new packages beyond what you installed in Module 1:

# If you already have Module 1 installed, you don't need anything else
pip install langchain langchain-openai python-dotenv pydantic

# Optional: to use built-in search tools
pip install duckduckgo-search

Check that everything works

from dotenv import load_dotenv
load_dotenv()

from langchain.chat_models import init_chat_model
from langchain_core.tools import tool

@tool
def greet(name: str) -> str:
    """Greet a person by name."""
    return f"Hello, {name}!"

print(greet.name)
# Expected output: greet

print(greet.description)
# Expected output: Greet a person by name.

model = init_chat_model("openai:gpt-4.1-mini")
model_with_tools = model.bind_tools([greet])

response = model_with_tools.invoke("Say hi to María")
print(response.tool_calls)
# Expected output: [{'name': 'greet', 'args': {'name': 'María'}, 'id': '...'}]

If you see the tool call in the response, your setup is ready for this module.

If something fails, the most common errors are:

ErrorCauseFix
ImportError: cannot import name 'tool'Old langchain-core versionpip install --upgrade langchain-core
NotImplementedError: ... does not support tool callingThe model doesn't support tool callingUse a model that does (GPT-4.1, Claude Sonnet)
ValidationError in args_schemaInconsistent type hintsCheck that the schema's types match the function's

Signs you got it

By the end of this module, you'll know you succeeded if:

  • ✅ You can create a tool with @tool and have the model call it correctly
  • ✅ You understand the full flow: user → model → tool → model → user
  • ✅ You know the difference between the model proposing a tool call and executing the tool
  • ✅ You handle parallel tool calls and tool errors without the system falling over
  • ✅ Your final project's assistant answers questions using 3 different tools

A preview: from manual tools to automatic agents

In this module you'll write the tool execution loop by hand. That's on purpose — you need to understand what happens internally before automating it.

In Module 3, you'll learn create_agent, which automates the whole loop:

# Module 2: manual loop (what you'll learn here)
response = model_with_tools.invoke(messages)
# → Check whether there are tool_calls
# → Run each tool
# → Append a ToolMessage
# → Call the model again
# → Repeat until there are no more tool_calls

# Module 3: automatic loop with create_agent
from langchain.chat_models import init_chat_model
from langchain.agents import create_agent

model = init_chat_model("openai:gpt-4.1-mini")
agent = create_agent(model, tools=[greet, search, calculator])
response = agent.invoke({"messages": [{"role": "user", "content": "Say hi to María"}]})
# → The agent runs the whole loop internally

Learning the manual loop first gives you superpowers: when something breaks inside an agent, you know exactly where to look because you understand every step of the flow.

It's like learning to drive a manual transmission before moving to automatic — you understand what's happening under the hood, and that makes you a better driver even when you're driving automatic.

When should you use a manual loop vs an agent?

SituationRecommendation
Learning tool callingManual loop (this module)
Quick prototype in productioncreate_agent (Module 3)
You need full control of the flowManual loop or LangGraph (Modules 5-7)
Debugging an agentUnderstanding the manual loop helps you diagnose it

Summary

  • LLMs only generate text — they can't search, calculate, or interact with external systems
  • Tools extend the model's capabilities: they're Python functions the model can request to run
  • The model never runs tools directly — it decides which tool to call and with what args, and your code runs them
  • The flow is: user → model → tool → model → user (the model proposes, you execute, the model folds it in)
  • The model can chain multiple tool calls when it needs intermediate results
  • Tool calling is optional per question — the model decides whether it needs a tool or answers directly
  • Tool calling is an industry standard supported by OpenAI, Anthropic, Google, and local models
  • Tools fall into categories: real-time data, exact calculations, data queries, actions, and processing
  • This module covers the manual loop; Module 3 (create_agent) automates it
  • You don't need new packages — langchain and langchain-core include everything you need for tools
  • The capstone project is an assistant with weather, search, and calculator tools

Further reading

  1. LangChain Tools Documentation — Official concepts and guide for tools
  2. How to create tools — Step-by-step guide to building custom tools
  3. Tool Calling Conceptual Guide — How tool calling works internally
  4. OpenAI Function Calling Guide — The original tool calling spec
  5. Anthropic Tool Use — Tool calling at Anthropic
  6. LangChain Built-in Tools — A catalog of prebuilt tools

Module 2 — LangChain & LangGraph: From Chains to Agents

Next capsule: Creating Tools with @tool — you'll learn to turn any Python function into a tool that models can invoke.