LangChain Free code examples in Python and JavaScript
The most widely used orchestration library, and LangGraph for stateful agents.
Try it without writing code: Document Summarizer — free in the browser.
WHAT THIS PAGE COVERS
LangGraph, because a graph is the honest shape of a real agent.
gpt-5.4-mini
langchain
Model ids change. If a sample returns a 404 on the model, that is the first thing to check against the official docs.
The provider is an extra, not a separate top-level package: langchain[openai] rather than langchain plus langchain-openai in the common case.
pip install "langchain[openai]" langgraph
export OPENAI_API_KEY="sk-your-key" # macOS / Linux
setx OPENAI_API_KEY "sk-your-key" # Windows, then open a new shell
create_agent from langchain.agents. A plain function is a tool — the docstring is the description the model reads, and the type hints are the schema.
from langchain.agents import create_agent
def get_stock(code: str) -> str:
"""Get the current stock level for a single product code."""
return f"{code}: 42 units"
agent = create_agent(
model="gpt-5.4-mini",
tools=[get_stock],
system_prompt="You are a concise warehouse assistant.",
)
result = agent.invoke(
{"messages": [{"role": "user", "content": "How many X-17 do we have?"}]}
)
print(result["messages"][-1].content_blocks)
stream() with mode 'updates' shows each node as it finishes, which is how you find out the agent called the wrong tool rather than staring at a slow final answer.
for chunk in agent.stream(
{"messages": [{"role": "user", "content": "How many X-17 do we have?"}]},
stream_mode="updates",
):
for node, update in chunk.items():
# node is "model" or "tools" — watching this is how you debug
# an agent that answers confidently without calling anything.
print(node, update)
A GRAPH IS THE HONEST SHAPE OF A REAL AGENT. Branches, retries and human approval are edges and nodes; expressed as prompt instructions they are a state machine you cannot see, test or resume.
from typing import TypedDict
from langgraph.graph import StateGraph, START, END
class Review(TypedDict):
code: str
findings: list[str]
approved: bool
def analyse(state: Review) -> Review:
return {**state, "findings": ["unbounded loop at line 42"]}
def needs_human(state: Review) -> str:
# A real edge, not a sentence in a prompt hoping to be obeyed.
return "approve" if state["findings"] else END
def approve(state: Review) -> Review:
return {**state, "approved": True}
builder = StateGraph(Review)
builder.add_node("analyse", analyse)
builder.add_node("approve", approve)
builder.add_edge(START, "analyse")
builder.add_conditional_edges("analyse", needs_human)
builder.add_edge("approve", END)
graph = builder.compile()
A checkpointer is what makes the graph durable. interrupt_before stops at a node, the state is persisted against a thread id, and a later process resumes it — which is the whole argument for a graph over a loop.
from langgraph.checkpoint.memory import InMemorySaver
# In production this is Postgres or Redis; the interface is the same.
graph = builder.compile(
checkpointer=InMemorySaver(),
interrupt_before=["approve"],
)
config = {"configurable": {"thread_id": "review-118"}}
graph.invoke({"code": source, "findings": [], "approved": False}, config)
# ... minutes or days later, in a different process ...
state = graph.get_state(config)
print("waiting at:", state.next)
# Passing None means "carry on from where you stopped".
graph.invoke(None, config)
createAgent and tool are both named exports of `langchain` itself. The provider package is separate, and zod describes the tool arguments.
npm install langchain zod @langchain/openai @langchain/langgraph
export OPENAI_API_KEY="sk-your-key"
tool() pairs the function with a zod schema — that schema is what the model sees, so describe() on each field is prompt text rather than documentation.
import { createAgent, tool } from "langchain";
import * as z from "zod";
const getStock = tool(
(input) => `${input.code}: 42 units`,
{
name: "get_stock",
description: "Get the current stock level for a single product code.",
schema: z.object({
code: z.string().describe("The product code, e.g. X-17"),
}),
},
);
const agent = createAgent({
model: "gpt-5.4-mini",
tools: [getStock],
});
console.log(
await agent.invoke({
messages: [{ role: "user", content: "How many X-17 do we have?" }],
}),
);
streamMode 'updates' emits each node as it completes. Watching which tool fired is how you catch an agent that answers from memory instead of calling anything.
const stream = await agent.stream(
{ messages: [{ role: "user", content: "How many X-17 do we have?" }] },
{ streamMode: "updates" },
);
for await (const chunk of stream) {
for (const [node, update] of Object.entries(chunk)) {
console.log(node, JSON.stringify(update).slice(0, 200));
}
}
Branches and approvals belong in edges. Written as instructions in a prompt they are a state machine with no type, no test and no way to resume after a restart.
import { StateGraph, START, END, Annotation } from "@langchain/langgraph";
const Review = Annotation.Root({
code: Annotation(),
findings: Annotation({ default: () => [] }),
approved: Annotation({ default: () => false }),
});
const builder = new StateGraph(Review)
.addNode("analyse", () => ({
findings: ["unbounded loop at line 42"],
}))
.addNode("approve", () => ({ approved: true }))
.addEdge(START, "analyse")
.addConditionalEdges("analyse", (state) =>
state.findings.length ? "approve" : END,
)
.addEdge("approve", END);
const graph = builder.compile();
A checkpointer plus a thread id makes the run durable. The process that resumes it does not have to be the one that started it — that is what a graph buys over a loop in memory.
import { MemorySaver } from "@langchain/langgraph";
const durable = builder.compile({
checkpointer: new MemorySaver(), // Postgres or Redis in production
interruptBefore: ["approve"],
});
const config = { configurable: { thread_id: "review-118" } };
await durable.invoke({ code: source }, config);
// ... later, possibly in another process ...
const state = await durable.getState(config);
console.log("waiting at:", state.next);
// null means "carry on from where you stopped".
await durable.invoke(null, config);
QUESTIONS
Which languages are the LangChain examples in?
Python and JavaScript. Every sample runs as pasted and reads its credentials from an environment variable — no key is ever written into the code.
Which package do I install for LangChain?
The samples use langchain. The install step on each language tab gives the exact command.
Which LangChain model do these examples use?
gpt-5.4-mini, checked against the official documentation on 26 September 2026. Model ids change often; if a call returns a model-not-found error, check the current list in the official docs.
Where is the official LangChain documentation?
https://python.langchain.com/docs/introduction/ — it is linked at the bottom of this page, and it is the authority whenever it disagrees with a sample here.
ALSO IN FRAMEWORKS & SDKS
The authority
Official LangChain documentation
Model names, pricing and rate limits change faster than any page here can. When this page and the official docs disagree, the official docs are right.
https://python.langchain.com/docs/introduction/