Build agents with LangGraph
LangGraph is an open-source Python framework that models an agent as a graph: nodes do work (call a model, run a tool), edges decide what happens next. The platform runs unmodified LangGraph agents. This page gives you the author contract, the Crusoe helpers, and a complete agent you can deploy right now.
Before you begin
- You can deploy: account, CLI, and sign-in per deploy an agent.
- Python knowledge. You do not need LangGraph installed locally to deploy — the build happens on the platform.
The contract
Your directory must contain a graph.py that defines a module-level variable named graph, and it must be a compiled graph (a StateGraph you called .compile() on) whose state is LangGraph's MessagesState — that is, its input is a dict shaped like {"messages": [...]}.
Why that shape? The harness stores every conversation as a canonical event log and replays it into your graph as messages on each turn — that is what makes turn 2 remember turn 1. A graph over MessagesState accepts that replay natively.
The easiest way to satisfy the contract is LangGraph's own create_react_agent, which returns exactly such a compiled graph. If the module-level graph is missing, your agent crash-loops at startup and the harness startup error appears in the agent's status message.
An optional requirements.txt is installed at build time, constrained against the base image's frozen dependency set: if you pin a package version that conflicts with the base image, the build fails with a readable error in the status message field — instead of your pod crash-looping at import time. That trade is deliberate.
What the base image already provides
The LangGraph base image ships langgraph, langchain-core, langchain-openai, and the first-party crusoe_langchain package, on Python 3.12. Most agents need no extra dependencies.
The Crusoe helpers: crusoe_langchain
import crusoe_langchain as crusoe
crusoe.foundry_model()— returns a LangChainChatOpenAIpointed at the platform's managed inference endpoint (MODEL_BASE_URL, usingCHAT_MODELandMODEL_API_KEY). With no arguments it uses the configuredCHAT_MODEL; the platform default when nothing is set iszai/GLM-5.2. Pin a model in code withcrusoe.foundry_model("nvidia/NVIDIA-Nemotron-3-Super-120B-A12B"). You can also bring your own native LangChain model (for exampleChatOpenAIorChatVertexAIwith your own credentials) — the harness runs it as-is.crusoe.run_python— a tool that runs Python in the platform's code sandbox (isolated, single-use, 20-second cap).crusoe.search_memory— a tool that searches the agent's long-term memory bank and returns the top 5 snippets.
The platform tools run in-process; tools you author yourself are sandboxed by default (TOOL_SANDBOX, set env TOOL_SANDBOX=false to opt out). See tools.
Complete example: langgraph-minimal
The platform's canonical LangGraph example, complete and runnable as-is. Two files.
my-graph-agent/graph.py:
"""A minimal LangGraph agent for the Crusoe platform.
The author contract (mirrors ADK's module-level ``root_agent``): expose a
module-level ``graph`` that is a COMPILED StateGraph over ``MessagesState``.
``create_react_agent`` returns exactly that - a compiled graph whose input is
``{"messages": [...]}`` - so the harness can replay the canonical session log
into it each turn and stream its output.
"""
from langgraph.prebuilt import create_react_agent
import crusoe_langchain as crusoe
graph = create_react_agent(
# foundry_model() with no args uses the platform default (zai/GLM-5.2
# unless CHAT_MODEL is injected/overridden). Override by name with
# crusoe.foundry_model("nvidia/NVIDIA-Nemotron-3-Super-120B-A12B"), or
# bring your own native model (e.g. ChatVertexAI/ChatOpenAI) - the
# harness runs it as-is.
crusoe.foundry_model(),
tools=[crusoe.run_python, crusoe.search_memory],
prompt=(
"You are Research Buddy, a research assistant. Use the run_python tool "
"for calculations and the search_memory tool to recall things you were "
"told to remember."
),
)
my-graph-agent/requirements.txt:
# The harness-langgraph base image already provides langgraph, langchain-core,
# langchain-openai and crusoe_langchain, so this agent needs no extra
# dependencies. Add third-party packages your graph imports here; they are
# installed against the base image's constraints (a conflicting pin fails the
# build rather than crash-looping the pod).
Deploy and test it
- Deploy. The CLI sees
graph.pyand auto-detects the framework aslanggraph:
platformctl deploy ./my-graph-agent --name my-graph-agent
You should see:
packaging ./my-graph-agent...
uploading my-graph-agent (1.4 KiB, framework=langgraph)...
build 7a3b9c1d-2e4f-4a6b-8c0d-1e2f3a4b5c6d accepted
status: -> building
status: building -> deploying
status: deploying -> ready
my-graph-agent is ready at http://my-graph-agent.cai-p-x7k2q.svc.cluster.local
- Talk to it. Once deployed, a LangGraph agent answers the exact same HTTP API as every other agent — callers can't tell the frameworks apart:
platformctl invoke my-graph-agent "Compute 2**32 in python."
You should see:
2**32 is 4294967296.
(session: 9d8c7b6a-5e4f-4d3c-2b1a-0f9e8d7c6b5a)
tool_call: run_python called with args={'code': 'print(2**32)'}
- Clean up when you're done:
platformctl delete my-graph-agent