LangGraphLangGraph 1.2 · Python 3.10+
Dashboard
0%
1
Curious builder0 XP earned · 300 to level 2
0 daysFinish a lesson to begin
Badge collection0 of 6 unlocked
38 small wins to finish your pathNext lesson →

Tools and bind_tools

A tool is a Python function a model can call. @tool turns a function into one, and model.bind_tools([...]) returns a new model that is allowed to request it.

Last updated: 29 Sep, 2026 · LangChain 1.4

A model on its own can only write text. A tool lets it look something up or take an action. The model does not run the tool; it asks for it, and your program runs it.

Creating a tool with @tool and binding it with bind_tools · from the Complete Agentic AI Course In 10 Hours · 59:50 to 64:16

A weather tool, bound to a model

The LangChain section of the video turns get_weather into a tool with the @tool decorator from langchain.tools. The docstring, "Get the weather at a location", is what the model reads once the tool is bound, and the return value is hard-coded where a real tool would call an API or a database. model.bind_tools([get_weather]) returns model_with_tools, and asking it "What's the weather like in Boston?" gets back a tool call instead of an answer. The video runs it on groq:qwen/qwen3-32b, since retired, and prints the whole response before the tool calls; this version runs the course model and prints only the tool calls:

ExampleAPI keyFrom the video, run on Groq
from langchain.chat_models import init_chat_model

model = init_chat_model("groq:openai/gpt-oss-120b")

from langchain.tools import tool

@tool
def get_weather(location:str)->str:
    """Get the weather at a location"""
    return f"It's sunny in {location}"


model_with_tools=model.bind_tools([get_weather])

response = model_with_tools.invoke("What's the weather like in Boston?")
for tool_call in response.tool_calls:
    print(f"Tool: {tool_call['name']}")
    print(f"Args: {tool_call['args']}")

The model picked get_weather and filled in location from the question, but it ran nothing: the reply only names the tool and its arguments. Running it is your code's job, or a graph's, as the ToolNode and tools_condition lesson shows. The shop's tool below looks up an order the same way.

The @tool decorator and bind_tools

python
from langchain.tools import tool

@tool
def name(arg: str) -> str:
    """What the tool does (the model reads this)."""
    return result

model_with_tools = model.bind_tools([name])   # returns a NEW model

Turning a function into a tool

Start by turning a plain function into a tool. The @tool decorator reads the type hints for the input schema and the docstring for the description the model sees.

python
from langchain.tools import tool

@tool
def lookup_order(order_id: str) -> str:
    """Look up the status of an order by its id."""   # the model reads this line
    return f"Order {order_id}: shipped on 3 March."

Calling the tool directly

Run the tool yourself with .invoke, passing its arguments as a dict. The model would ask for it, but here you call it directly to see what it returns.

python
print(lookup_order.invoke({"order_id": "A17"}))   # call the tool with its argument

The tool in a run

The tool and the call together:

Example
from langchain.tools import tool

@tool
def lookup_order(order_id: str) -> str:
    """Look up the status of an order by its id."""
    return f"Order {order_id}: shipped on 3 March."

print(lookup_order.invoke({"order_id": "A17"}))

Asking a real model for the tool

The same call with the shop's tool. The reply has no text, only the tool call.

ExampleAPI key
from langchain.chat_models import init_chat_model
from langchain.tools import tool

@tool
def lookup_order(order_id: str) -> str:
    """Look up an order by id."""
    return f"Order {order_id}: shipped on 3 March."

model = init_chat_model("groq:openai/gpt-oss-120b", temperature=0)  # uses your GROQ_API_KEY
model_with_tools = model.bind_tools([lookup_order])

reply = model_with_tools.invoke("Where is order A17?")
print(repr(reply.content))
print(reply.tool_calls[0]["name"], reply.tool_calls[0]["args"])

What @tool adds to a function

  • The type hints are required: they define the tool's input schema.
  • The docstring becomes the tool's description, which the model reads to decide when to call it.
  • bind_tools returns a NEW model that knows about the tool; the original model is unchanged.

Plain function vs @tool

Plain function@tool
A model can request itNoYes, once bound
Has a schemaNoFrom the type hints
Has a descriptionNoFrom the docstring

Where tools fit

  • Any action an agent takes: search, look up an order, send an email, run a query.
  • You give the model the tools; it chooses which to call and with what arguments.
Watch out. bind_tools returns a new model, so assign it: model = model.bind_tools([...]). If you keep calling the old model, it will never ask for a tool.
Try it yourself
  • Add a second argument to lookup_order and call it.
  • Write a refund tool and give it a clear docstring.
PreviousChat models

You understood something today that you didn't yesterday.