LangChain Tutorial
LangChain is an open-source Python and JavaScript framework for building applications on large language models. It provides model integrations, tool definitions, prompt templates, composable chains and a ready tool-calling agent, so developers can connect a model to external functions and data with little custom code.
- Model integrations: Provider packages expose chat models, such as Claude, through one common interface, so switching providers requires minimal modification.
- Tools: The
@tooldecorator converts a typed Python function into a tool definition that the model can request with arguments. - Agents: An agent constructor combines a model, a tool list and a system prompt into an iterative reasoning and acting loop.
- Chains: The pipe operator composes prompts, models and output parsers into a fixed, predictable pipeline without autonomous decisions.
- Messages: Every step exchanges typed message objects, so tool invocations, observations and final answers remain inspectable.
For example, a LangChain agent receives a report of a 5xx spike on the checkout service, calls its log, metric and deployment tools, and proposes a rollback that only runs after an engineer approves it.
The identical agent appears in the Claude Agent SDK tutorial and the LangGraph tutorial. This LangChain Python agent places the approval rule inside the tool itself, which is the simplest pattern that the prebuilt agent supports.
Prerequisites
- Python 3.11: LangChain requires Python 3.10 or later, and the examples target version 3.11.
- Agent fundamentals: Familiarity with tool calling and the ReAct agent pattern of reasoning, acting and observing.
- Credentials: An Anthropic API key stored in the
ANTHROPIC_API_KEYenvironment variable, never written into the code. - Optional comparison: Reading the Claude Agent SDK tutorial first clarifies which responsibilities each framework handles automatically.
Setup
Create a virtual environment and install LangChain with the Anthropic integration at pinned versions.
python3.11 -m venv .venv
source .venv/bin/activate
pip install langchain==1.0.0 langchain-anthropic==1.0.0
export ANTHROPIC_API_KEY="paste-your-key-here"Step 1: Write the Incident Tools in Plain Python
The tool logic is written without any framework dependency, so its behaviour can be tested deterministically on any machine. The rollback function contains the approval guard, and without an approved identifier it only records a pending request instead of changing production. Save the module as incident_tools.py.
# incident_tools.py: canned data and plain functions, before any LangChain code.
import json
LOGS = {
"checkout": [
"14:05:12 ERROR POST /api/pay 502 payment client timeout after 2000 ms",
"14:05:13 ERROR POST /api/pay 502 payment client timeout after 2000 ms",
"14:06:40 WARN retry budget exhausted for payments-api",
],
}
METRICS = {"checkout": {"5xx_rate": "12.0%", "baseline_5xx_rate": "0.2%", "p95_latency_ms": 2140}}
DEPLOYS = {
"checkout": [
{"version": "v2.4.1", "at": "14:03", "change": "payment client timeout 5000 ms to 2000 ms"},
],
}
def read_logs(service):
return "\n".join(LOGS.get(service, ["no log lines found"]))
def get_metrics(service):
return json.dumps(METRICS.get(service, {}))
def list_recent_deploys(service):
return json.dumps(DEPLOYS.get(service, []))
def rollback_deploy(service, version, approved):
# The guard lives in code: without a human approval, only a request is recorded.
key = f"{service}@{version}"
if key not in approved:
return f"PENDING_APPROVAL: rollback of {key} needs an on-call engineer"
return f"ROLLED_BACK: {service} is back on the release before {version}"
if __name__ == "__main__":
print(get_metrics("checkout"))
print(list_recent_deploys("checkout"))
print(rollback_deploy("checkout", "v2.4.1", approved=set()))
print(rollback_deploy("checkout", "v2.4.1", approved={"checkout@v2.4.1"}))Output:
{"5xx_rate": "12.0%", "baseline_5xx_rate": "0.2%", "p95_latency_ms": 2140}
[{"version": "v2.4.1", "at": "14:03", "change": "payment client timeout 5000 ms to 2000 ms"}]
PENDING_APPROVAL: rollback of checkout@v2.4.1 needs an on-call engineer
ROLLED_BACK: checkout is back on the release before v2.4.1- Deterministic guard: The rollback outcome depends exclusively on the approved set, never on the model's wording or reasoning.
- Readable observations: Each tool returns a concise string, which the model receives as the observation for its next decision.
- Framework independence: The same module serves the other two tutorials, which isolates the differences between the frameworks themselves.
Step 2: Define LangChain Tools with @tool
The @tool decorator inspects the function name, the type hints and the docstring, then generates the JSON schema that the model receives. The approved set is loaded from an environment variable that only the on-call engineer configures, so the model has no mechanism to grant its own approval.
# lc_tools.py: the incident functions wrapped as LangChain tools.
import os
from langchain_core.tools import tool
import incident_tools as it
APPROVED_ROLLBACKS = {k for k in os.environ.get("APPROVED_ROLLBACKS", "").split(",") if k}
@tool
def read_logs(service: str) -> str:
"""Read recent error log lines for a service."""
return it.read_logs(service)
@tool
def get_metrics(service: str) -> str:
"""Get the current 5xx rate, its baseline and p95 latency for a service."""
return it.get_metrics(service)
@tool
def list_recent_deploys(service: str) -> str:
"""List deploys of a service in the last 24 hours, with their changes."""
return it.list_recent_deploys(service)
@tool
def rollback_deploy(service: str, version: str) -> str:
"""Roll back a production deploy. Returns PENDING_APPROVAL until an engineer approves it."""
return it.rollback_deploy(service, version, APPROVED_ROLLBACKS)
TOOLS = [read_logs, get_metrics, list_recent_deploys, rollback_deploy]- Descriptive docstrings: The model selects tools by reading these descriptions, so each one states precisely what the tool returns.
- Typed arguments: The
strannotations become required string parameters, and LangChain validates the arguments before the function executes.
Step 3: Build a LangChain Agent Example with Claude
The ChatAnthropic class reads the API key from the environment automatically. The LangChain create_agent() function combines the model, the tools and the system prompt into a tool-calling loop that terminates when the model produces a final answer without further tool requests. Earlier LangChain releases used AgentExecutor, which now resides in a separate legacy package.
# triage_agent.py: the LangChain incident triage agent.
from langchain.agents import create_agent
from langchain_anthropic import ChatAnthropic
from lc_tools import TOOLS
SYSTEM = (
"You are an on-call triage agent. Read logs, metrics and recent deploys before "
"naming a cause. If a recent deploy explains the errors, call rollback_deploy. "
"If the result is PENDING_APPROVAL, stop and ask the engineer to approve it."
)
model = ChatAnthropic(model="claude-sonnet-5", temperature=0, max_tokens=1024)
agent = create_agent(model=model, tools=TOOLS, system_prompt=SYSTEM)
GOAL = "The checkout service has a 5xx spike. Find the likely cause and propose an action."
result = agent.invoke({"messages": [{"role": "user", "content": GOAL}]})
for message in result["messages"]:
for call in getattr(message, "tool_calls", []):
print(f"Tool call: {call['name']} {call['args']}")
print(f"Agent: {result['messages'][-1].text}")- Temperature zero: A deterministic sampling setting reduces variation between investigations of the same incident.
- Message history: The returned state contains every human, AI and tool message, which supports auditing and debugging.
Step 4: Summarise the Incident with a Chain
A chain is a fixed pipeline in which the application, not the model, determines every step. Here, a prompt template, the same model and a string parser transform the agent's findings into a short, consistently formatted note for the incident channel.
# incident_note.py: an LCEL chain that formats the agent's findings.
from langchain_core.output_parsers import StrOutputParser
from langchain_core.prompts import ChatPromptTemplate
from triage_agent import model, result
prompt = ChatPromptTemplate.from_messages([
("system", "Write a three-line incident note: impact, likely cause, next action."),
("human", "{findings}"),
])
note_chain = prompt | model | StrOutputParser()
print(note_chain.invoke({"findings": result["messages"][-1].text}))Output
The LangChain code was not executed for this page, so the output is illustrative. The first run stops at the approval guard; the engineer then exports APPROVED_ROLLBACKS=checkout@v2.4.1 and runs the agent again.
Tool call: get_metrics {'service': 'checkout'}
Tool call: read_logs {'service': 'checkout'}
Tool call: list_recent_deploys {'service': 'checkout'}
Tool call: rollback_deploy {'service': 'checkout', 'version': 'v2.4.1'}
Agent: The 5xx rate is 12.0% against a 0.2% baseline, caused by payment client
timeouts after v2.4.1 cut the timeout to 2000 ms. The rollback of v2.4.1 is
PENDING_APPROVAL; please approve it to proceed.
Impact: checkout 5xx rate at 12.0% (baseline 0.2%).
Likely cause: v2.4.1 reduced the payment client timeout to 2000 ms.
Next action: roll back v2.4.1 after on-call approval.- Tool order: The model chose the order of tool calls; a different run may read the logs first.
- Guard in practice: The rollback tool was called but returned a pending status, so nothing changed in production.
- Limitation: A second run repeats the investigation. The LangGraph tutorial pauses and resumes the same run instead, and LangChain offers a human-in-the-loop middleware for the same purpose.
Common Errors
ImportError: cannot import name 'AgentExecutor' from 'langchain.agents': The code follows an older tutorial, so switch tocreate_agent()or install the legacy package that now contains the executor.ValueError: Function must have a docstring if description not provided.: A decorated tool has no docstring, so add a one-line description of what the tool does.ModuleNotFoundError: No module named 'langchain_anthropic': The integration package is missing from the active environment, so install it with the pinned version.anthropic.NotFoundError: The model identifier is incorrect or unavailable to the account, so compare it with the current model list in the Anthropic documentation.anthropic.AuthenticationError: The API rejected the key with status 401, so confirm that the environment variable is exported in the same terminal session.GraphRecursionError: The agent exceeded its step limit, usually because a tool keeps returning an unhelpful result, so tighten the tool descriptions and the system prompt.
Next Steps
- Graph control: Replace the retry with a true pause and resume in the LangGraph tutorial.
- Approval design: Review approval patterns in human-in-the-loop systems.
- Role-based teams: Split triage and remediation across agents in the CrewAI tutorial.
- Framework selection: Compare the options in LangGraph vs CrewAI vs AutoGen.
Quick Quiz
Pick an answer to check yourself. Nothing is saved.
Question 1 / 3
1. In the LangChain triage agent, what prevents an unapproved production rollback?
Frequently Asked Questions
Is LangChain still used for building agents?
LangChain remains a widely used framework for connecting language models to tools, prompts and data sources. Its agent constructor now runs on LangGraph internally, so an agent can later move to a custom graph without rewriting its tools.
What is the difference between LangChain and LangGraph?
LangChain provides model integrations, tools, prompts and a ready agent loop. LangGraph is a lower-level library for writing that loop as an explicit graph with state, branches, persistence and human interrupts.
Does LangChain work with Claude?
Yes. The langchain-anthropic package provides the ChatAnthropic class, which reads the API key from the ANTHROPIC_API_KEY environment variable and supports tool calling and structured output.
Why does a LangChain tool need a docstring?
The @tool decorator turns the docstring into the tool description that the model reads. Without it the decorator raises an error, and a vague description leads the model to call the wrong tool.
Related Articles
- Claude Agent SDK TutorialClaude Agent SDK tutorial: build an incident triage agent in Python with custom tools, an in-process MCP server and an approval check before rollbacks.
- LangGraph TutorialLangGraph tutorial: build an incident triage agent as a StateGraph with nodes, conditional edges and a human approval interrupt before a rollback.
- Tool Calling (Function Calling) in LLMLearn how tool calling works in LLMs: JSON Schema tool definitions, model tool calls, argument validation and tool results, with a Python DevOps example.
- ReAct Agent ExplainedLearn how a ReAct agent alternates thought, action and observation, with a Python example that traces a failing unit test to a commit and opens a ticket.
- LangGraph vs CrewAI vs AutoGenLangGraph vs CrewAI vs AutoGen compared: control model, state, human-in-the-loop, multi-agent style and learning curve, with one incident agent in each.
- CrewAI TutorialCrewAI tutorial in Python: define agents with roles, tasks and a sequential crew that triages a 5xx spike, with a human approval gate before any rollback.