Tool-calling agents let a chat model choose a typed application function instead of answering only from text. In LangChain, this pattern is useful when a request needs data from order systems, calculators, search indexes, or other code that the model should call through a controlled interface.

LangChain creates agents with create_agent(), and Python tools can be registered with the @tool decorator. The tool name, argument schema, and docstring give the model a contract; the agent loop handles the tool request, runs the Python function, and returns the tool result to the model.

The local wiring test uses a deterministic fake chat model so the tool call can be reproduced without API credentials. Replace that model with a provider-backed chat model that supports tool calling when the application is ready to call a live LLM.

Steps to build a tool-calling LangChain agent:

  1. Open an activated Python project environment.
  2. Install the current LangChain package.
    $ python3 -m pip install --upgrade langchain

    LangChain requires Python 3.10 or newer.
    Related: How to install LangChain with pip

  3. Create the tool-calling agent script.
    $ cat > langchain-agent-tool-calling.py <<'PY'
    from langchain.agents import create_agent
    from langchain.tools import tool
    from langchain_core.language_models.fake_chat_models import FakeMessagesListChatModel
    from langchain_core.messages import AIMessage, ToolMessage
    
    
    @tool
    def get_order_status(order_id: str) -> str:
        """Return the shipping status for an order ID."""
        return f"Order {order_id} is packed and ready to ship."
    
    
    class ToolCallingDemoModel(FakeMessagesListChatModel):
        def bind_tools(self, tools, **kwargs):
            return self
    
    
    model = ToolCallingDemoModel(
        responses=[
            AIMessage(
                content="",
                tool_calls=[
                    {
                        "id": "call_order_status",
                        "name": "get_order_status",
                        "args": {"order_id": "A100"},
                    }
                ],
            ),
            AIMessage(
                content="Shipping update: Order A100 is packed and ready to ship."
            ),
        ]
    )
    
    agent = create_agent(model=model, tools=[get_order_status])
    result = agent.invoke(
        {"messages": [{"role": "user", "content": "Where is order A100?"}]}
    )
    
    tool_call = next(
        message.tool_calls[0]
        for message in result["messages"]
        if getattr(message, "tool_calls", None)
    )
    tool_output = next(
        message.content
        for message in result["messages"]
        if isinstance(message, ToolMessage)
    )
    final_answer = result["messages"][-1].content
    tool_name = tool_call["name"]
    tool_args = tool_call["args"]
    
    print(f"tool called: {tool_name}")
    print(f"tool args: {tool_args}")
    print(f"tool output: {tool_output}")
    print(f"final answer: {final_answer}")
    PY

    The fake model emits one planned tool call, so the agent loop can be tested without a provider key. Replace it with a provider chat model for live requests.
    Related: How to call a chat model in LangChain

  4. Run the script and confirm that the agent calls the tool before returning the final answer.
    $ python3 langchain-agent-tool-calling.py
    tool called: get_order_status
    tool args: {'order_id': 'A100'}
    tool output: Order A100 is packed and ready to ship.
    final answer: Shipping update: Order A100 is packed and ready to ship.
  5. Remove the temporary script after the wiring test passes.
    $ rm langchain-agent-tool-calling.py