LangChain Agents
LangChain agents combine a chat model with tools and a loop: the model decides on an action, a tool runs, the result goes back to the model, and this repeats until the model gives a final answer. In LangChain 1.x you build agents with create_agent, which runs on LangGraph.
Creating an Agent
from langchain.agents import create_agent
from langchain.tools import tool
@tool
def add(a: float, b: float) -> float:
"""Add two numbers."""
return a + b
@tool
def multiply(a: float, b: float) -> float:
"""Multiply two numbers."""
return a * b
agent = create_agent(
model="ollama:llama3.2",
tools=[add, multiply],
system_prompt="You are a careful calculator. Always use tools for math.",
)
result = agent.invoke({"messages": [{"role": "user", "content": "What is (3 + 4) * 6?"}]})
print(result["messages"][-1].content)Sample output: (3 + 4) * 6 = 42.
The input and output are a state dictionary with a messages list. The last message is the final answer; earlier messages show every tool call and result, which is great for debugging.
Inspecting the Steps
for m in result["messages"]:
print(type(m).__name__, getattr(m, "tool_calls", None) or m.content)Sample output:
HumanMessage What is (3 + 4) * 6?
AIMessage [{'name': 'add', 'args': {'a': 3, 'b': 4}, ...}]
ToolMessage 7.0
AIMessage [{'name': 'multiply', 'args': {'a': 7, 'b': 6}, ...}]
ToolMessage 42.0
AIMessage (3 + 4) * 6 = 42.Using a Model Object and Structured Responses
from pydantic import BaseModel
from langchain_ollama import ChatOllama
class MathAnswer(BaseModel):
expression: str
value: float
agent = create_agent(
model=ChatOllama(model="qwen3", temperature=0),
tools=[add, multiply],
response_format=MathAnswer,
)
out = agent.invoke({"messages": [{"role": "user", "content": "2 * 9 + 1"}]})
print(out["structured_response"])Sample output: expression='2 * 9 + 1' value=19.0
LangGraph Basics
Under the hood the agent is a LangGraph graph: a "model" node and a "tools" node connected by edges, with the messages list as shared state. When you outgrow create_agent you can build your own graph with StateGraph, adding custom nodes, conditional edges, checkpointers for memory and interrupts for human approval. create_agent also supports middleware for things like summarizing long histories or adding human-in-the-loop checks.
Agent Best Practices
- Start with few tools; too many confuse small models.
- Write a system prompt that says when to use each tool.
- Add a checkpointer for memory across turns (see the memory lesson).
- Limit loops with a recursion limit in the config to avoid runaway costs.
- Trace runs in LangSmith to see why an agent made a decision.
Frequently asked questions
What replaced create_react_agent in LangChain 1.0?
create_agent from langchain.agents. It replaces langgraph.prebuilt.create_react_agent and the older AgentExecutor, which moved to langchain-classic.
Can LangChain agents run with local models?
Yes. Pass "ollama:model-name" or a ChatOllama instance. Choose a model with good tool calling support; quality varies a lot between small models.
What is the difference between a chain and an agent?
A chain follows fixed steps you define. An agent lets the model choose which tools to call and how many times, in a loop.