This article is published in English.
Your First Tool-Using AI Agent with LangChain
Build a small LangChain math agent in Python: initialize a chat model, register tools, let the LLM choose which function to call, and see multi-step tool use.
A short Python + LangChain exercise builds a calculator-style agent that may invoke addition, subtraction, multiplication, division, or square-root helpers when needed.
Arithmetic is incidental. The useful lesson is watching an LLM that receives callable helpers and chooses which helper to invoke and at which step.
Sample questions the finished agent can tackle:
Multiply 25 by 4. Take the square root of 144, then multiply that result by 5.
Rather than scripting the exact calculation sequence, several helpers are registered. The model picks among them from the user’s wording.
1. Initialize the model
Begin by constructing the chat model:
from langchain.chat_models import init_chat_model
model = init_chat_model("openai:gpt-4o-mini")
Nothing agent-like exists yet — only a text model that can read and write.
2. Register callable helpers
Agents become useful when they leave pure text generation and may invoke application functions.
Define five minimal helpers:
from langchain.tools import tool
import math
@tool
def add(a: float, b: float) -> float:
"""Add two numbers."""
return a + b
@tool
def subtract(a: float, b: float) -> float:
"""Subtract two numbers."""
return a - b
@tool
def multiply(a: float, b: float) -> float:
"""Multiply two numbers."""
return a * b
@tool
def divide(a: float, b: float) -> float:
"""Divide two numbers."""
if b == 0:
raise ValueError("Cannot divide by zero.")
return a / b
@tool
def square_root(a: float) -> float:
"""Calculate the square root of a number."""
if a < 0:
raise ValueError("Cannot calculate square root of a negative number.")
return math.sqrt(a)
Decorating with @tool exposes each function in a form the agent runtime understands.
Two details steer the model:
- Annotated parameters declare expected argument kinds.
a: float
b: float
- Docstrings supply plain-language descriptions the model reads when deciding relevance.
For agent tooling, a function’s narrative description is part of the control surface, not decoration.
"""Multiply two numbers."""
3. Wire the agent
Attach the helpers to the model:
from langchain.agents import create_agent
agent = create_agent(
model=model,
tools=[
add,
subtract,
multiply,
divide,
square_root
],
)
From here the chat model can act as an agent rather than a one-shot answerer.
Typical steps include:
- Parse the user’s intent
- Judge whether a helper is required
- Pick a helper
- Supply arguments
- Consume the helper’s return value
- Decide whether another step is needed
- Emit the final reply
At a high level:
User
↓
Agent
↓
Should I use a tool?
↓
Choose tool
↓
Execute tool
↓
Get result
↓
Final response
Multi-step questions may repeat that loop.
4. Execute a run
A thin wrapper is enough to drive it:
def run_agent(question: str):
"""Run the agent and print the execution trace."""
print(f"User: {question}")
result = agent.invoke({
"message": [("user", question)],
})
print("Agent:", result)
Invoke with a simple question:
run_agent("What is 25 multiplied by 4?")
Notice there is no instruction that says “call multiply.”
Only the catalog of helpers was provided.
Given the wording and each helper’s description, the model concludes multiplication is appropriate.
5. Chaining more than one helper
Try a compound prompt:
run_agent(
"Calculate the square root of 144 and multiply the result by 5."
)
Two operations are required.
A conceptual trace looks like:
User:
Calculate √144 × 5
↓
Agent chooses square_root
↓
square_root(144)
↓
12
↓
Agent chooses multiply
↓
multiply(12, 5)
↓
60
↓
Final answer
That loop — choose, call, observe, choose again — is the essence of tool-using agents.
Application code need not encode the full operation order up front.
The model can derive the next step from remaining helpers and conversation state.
6. Contrast with a plain LLM
Without tools, a model might invent “The answer is 60” as text.
With helpers registered, it can hand numeric work to real functions.
The control shift
Text-only path: User → model → answer string
versus:
Tool-using agent
User
↓
LLM
↓
Choose tool
↓
Execute code
↓
Observe result
↓
LLM
↓
Answer
The model no longer has to perform every computation itself.
It proposes which action should run next; the application decides which actions exist and how they execute.
7. The boundary worth protecting
The calculator is a teaching toy.
The durable idea is the split between model judgment and application authority.
Natural language understanding and action selection fit the LLM well.
Executing those actions belongs in Python under your control.
The model may conclude it needs division.
Your process owns the divide implementation and its side effects.
Swap the toy math helpers for domain operations such as:
get_customer()
search_transactions()
create_report()
send_email()
query_database()
get_weather()
create_ticket()
and the same orchestration pattern starts to resemble production agent designs.
Recap of the exercise
A handful of modules produced an agent able to:
- Interpret free-form questions
- Choose among several registered helpers
- Bind arguments correctly
- Combine helpers inside one session
- Feed helper outputs back into later reasoning
- Answer the user after the chain completes
In short: an LLM that selects and runs actions, not one that only emits prose.