Prerequisites
- Python 3.10+
- Install:
pip install -U langchain langgraph pydantic - An API key for your model provider
Basic agent with a tool
from langchain.agents import create_agent
from langchain.tools import tool
@tool
def check_order_status(order_id: str) -> str:
"""Look up the shipping status for an order ID."""
return f"Order {order_id} is out for delivery."
agent = create_agent(
model="openai:gpt-4o-mini",
tools=[check_order_status],
system_prompt="You are a helpful support assistant.",
)
Add memory across turns
from langchain.agents import create_agent
from langgraph.checkpoint.memory import InMemorySaver
agent = create_agent(
model="openai:gpt-4o-mini",
tools=[check_order_status],
checkpointer=InMemorySaver(),
)
config = {"configurable": {"thread_id": "user-42"}}
agent.invoke({"messages": [{"role": "user", "content": "Check order 4471"}]}, config=config)
agent.invoke({"messages": [{"role": "user", "content": "Is it late?"}]}, config=config)
Add retry and guardrail middleware
from langchain.agents.middleware import ModelRetryMiddleware, PIIMiddleware
agent = create_agent(
model="openai:gpt-4o-mini",
tools=[check_order_status],
middleware=[
ModelRetryMiddleware(max_retries=3),
PIIMiddleware("email"),
],
)
Force structured output
from pydantic import BaseModel
from langchain.agents import create_agent
class OrderAnswer(BaseModel):
order_id: str
status: str
agent = create_agent(model="openai:gpt-4o-mini", tools=[check_order_status], response_format=OrderAnswer)
result = agent.invoke({"messages": [{"role": "user", "content": "Status of order 4471?"}]})
result["structured_response"]
Common failure modes are rarely exotic: an ambiguous tool description, no cap on iterations, or untyped tool arguments. Precise docstrings, a max_iterations limit, and Pydantic-validated inputs fix most of them. When a single agent loop isn’t enough, that is usually the signal to move the workflow into LangGraph.