Course navigation
AgentsLesson 3 of 9

Tool Calling

Agent Types used multiply inside create_agent. This page is what @tool adds on top of a normal function — then a script you can run.

@tool

Slap @tool on a function. LangChain picks up the name from the function, the description from the docstring, and the argument types from your hints. Your code still runs as plain Python — return a string the model can use on the next pass.

Keep the function name in snake_case (that is what OpenAI sees). Type every parameter. One clear docstring line beats a paragraph.

from langchain.tools import tool

TAGS = {
    "a": "Creates a hyperlink. Use href for the URL.",
    "title": "Sets the browser tab title.",
}

@tool
def lookup_html_tag(tag_name: str) -> str:
    """Look up a short description of an HTML tag by name."""
    key = tag_name.strip().lower().lstrip("<").rstrip(">")
    return TAGS.get(key, f"No entry for '{tag_name}'.")

print(lookup_html_tag.name)        # lookup_html_tag
print(lookup_html_tag.description) # first line of docstring
print(lookup_html_tag.args)        # schema sent to the model

What OpenAI gets

Passing tools=[lookup_html_tag] sends JSON like below — not the function body. The demo prints lookup_html_tag.args first so you can sanity-check before calling the API.

One entry in the tools list

name: lookup_html_tag
description: Look up a short description of an HTML tag by name.
parameters:
  tag_name: string  (required)
From the function name, docstring, and type hints — not your .py file. Sloppy docstrings → wrong tool or no call.

tool_calls on one question

Sometimes the assistant reply is only a tool_calls block, no user text yet. LangChain calls lookup_html_tag, pushes the return value back in, and asks the model again for the final sentence.

When the model picks lookup_html_tag:

user: What does <a> do?
tool_calls: lookup_html_tag("a")
tool: <a>: Creates a hyperlink…
assistant: answer text
create_agent handles the middle. You pass messages in, read the last one out.

Same create_agent call as multiply — swap the tool:

from langchain.agents import create_agent

agent = create_agent(model="openai:gpt-4o-mini", tools=[lookup_html_tag])

result = agent.invoke({
    "messages": [{"role": "user", "content": "What does the <a> tag do? Use lookup_html_tag."}],
})
print(result["messages"][-1].content)

Run the demo

Venv from Project Setup. Download, then:

tool_calling_demo.py

Schema printout + one <a> question

OPENAI_API_KEY in .env, same as LangChain Basics.
tool_calling_demo.py
"""tool_calling_demo.py"""
from langchain.tools import tool
# same TAGS dict as the RAG HTML demos
@tool
def lookup_html_tag(tag_name: str) -> str:
python tool_calling_demo.py
PowerShell — (.venv) active
(.venv) PS C:\projects\langchain-course> python tool_calling_demo.py
Tool name: lookup_html_tag
Description: Look up a short description of an HTML tag by name.
Args schema: {'tag_name': {'type': 'string'}}
Question: What does the <a> tag do? Use lookup_html_tag.
Tool returned: <a>: Creates a hyperlink. Use href for the URL.
Answer: The <a> tag creates a hyperlink; set href to the destination URL.
Schema lines print first. Then one question that forces a tool hit.

Custom tool names and Pydantic args later: Tools docs.

What's Next

Next: ReAct Framework.