LangGraph is a real durable runtime. Deep Agents is a strong opinionated harness on top of it. LangSmith Deployment packages both with sandboxes, auth proxy, tracing, and hosted infra. If you adopt that stack, you get a lot for free.
Kitaru is a different bet. Kitaru is a framework-agnostic durable runtime: @checkpoint wraps ordinary Python boundaries — not a graph — so the same durable execution works whether your team writes the agent in LangGraph, Pydantic AI, Claude Agent SDK, a raw Python loop, or an internal framework. And everything self-hosts inside your own infrastructure.
Use Kitaru if you are
- A platform team whose app teams use multiple agent harnesses (Pydantic AI here, LangGraph there, Claude SDK for one team, raw Python for another)
- Running on regulated or on-prem infrastructure where a hosted control plane is not acceptable
- Looking for a single-service, self-hosted runtime that plugs into Kubernetes, AWS, GCP, or Azure on your terms
- Wanting durable execution outside any one framework's graph/state-machine model
- Building your own platform and you want primitives, not a packaged product
Use LangGraph / Deep Agents if you are
- Standardizing on LangGraph or Deep Agents as the single harness across teams
- Happy to adopt LangSmith Deployment as the packaged runtime + deployment story
- Comfortable with hosted sandboxes and auth proxy from LangSmith
- Building graph-native agents where the graph abstraction is a feature, not an obstacle
LangGraph is a runtime inside one harness. Kitaru is a runtime across any harness.
Graph-native vs Python-native
LangGraph’s checkpointer, resume, and time-travel are powerful — inside the graph/state-machine model. Your agent is a graph of nodes and edges, and LangGraph persists state between supersteps.
Kitaru doesn’t require a graph. @checkpoint marks the durable boundaries around ordinary Python function calls. That means the agent harness inside a checkpoint can be anything — a LangGraph graph invocation, a Pydantic AI agent, a Claude Agent SDK turn, or hand-written code that calls an LLM. The flow body stays Python: no graph, no state schema, no nodes and edges. Just Python boundaries you can replay and resume.
@flow
def research_agent(topic: str) -> str:
plan = checkpoint(make_plan)(topic)
docs = checkpoint(retrieve)(plan)
return checkpoint(synthesize)(docs) Harness freedom
Platform teams at larger orgs rarely get to pick one harness for everyone. One team wants Pydantic AI for its typing. Another picked Deep Agents for multi-agent patterns. A third wrote a loop against the Anthropic SDK. A fourth uses an internal framework that predates all of this.
LangGraph’s durability is strongest when everyone adopts LangGraph. Kitaru’s is strongest when they don’t have to. Same durability contract, three different harnesses, one runtime.
# Pydantic AI inside a Kitaru checkpoint
@checkpoint
def plan(topic: str) -> Plan:
return pydantic_agent.run_sync(topic).output
# LangGraph inside a Kitaru checkpoint
@checkpoint
def research(plan: Plan) -> Docs:
return langgraph_app.invoke({"plan": plan})
# Claude Agent SDK inside a Kitaru checkpoint
@checkpoint
def critique(docs: Docs) -> str:
return asyncio.run(_claude_critique(docs)) Self-host vs packaged platform
LangSmith Deployment packages runtime + sandboxes + auth proxy + tracing into a managed product. That’s genuinely useful if you want to offload the platform layer.
Kitaru ships the runtime layer as a primitive you self-host. The Kitaru server is a single service deployable via Helm. Artifacts and state live in your own S3, GCS, or Azure Blob bucket. Auth is workspace-scoped. There is no mandatory hosted control plane in the path of your agent’s data.
If your security team needs to know exactly where prompts, outputs, and artifacts live, “in our own bucket” is a shorter conversation than a data-residency addendum on a hosted control plane.
Sandbox and security
LangSmith ships real security infrastructure: LangSmith Sandboxes provide ephemeral, locked-down environments for running untrusted code, and LangSmith Deployment adds authentication, monitoring, and tracing around deployed agents. Adopt their stack and you get a usable isolation story out of the box.
Kitaru takes a different posture. @checkpoint(runtime="isolated") runs a checkpoint in a separate pod or job on the stack you configured. For stronger isolation, bring your own sandbox provider. Secrets come from your own secret manager. The runtime exposes execution boundaries; policy at those boundaries belongs to your platform.
Two legitimate answers to the same problem: security packaged with the runtime, or security configurable at each execution boundary.
Versioned deployments
Both products have strong deployment stories — with different shapes.
LangSmith Deployment exposes agent endpoints (MCP, A2A, Agent Protocol, HITL, memory APIs) as part of its packaged runtime.
Kitaru deploys each flow as an immutable, auto-incrementing versioned snapshot. Consumers invoke by flow name using CLI, Python SDK, MCP, or a generated curl command pinned to a resolved version. Tag routing (default, canary, or your own exclusive tags) makes promotion and rollback a tag move, not a redeploy. Auth is workspace-scoped with no per-deployment tokens.
What makes Kitaru unique
| Feature | Kitaru | LangGraph / Deep Agents |
|---|---|---|
| Durable execution + checkpointing | Yes | Yes |
| Replay / time travel | Yes | Yes |
| Human-in-the-loop with compute released | Yes | Yes |
| Framework-agnostic: works across any Python harness | Yes | Not supported |
| Durable boundaries around ordinary Python (no graph required) | Yes | Not supported |
| Self-hosted runtime + artifact store on your own cloud | Yes | Not supported |
| Per-checkpoint isolated runtime on your stack | Yes | Not supported |
| Single-service server deployable via Helm | Yes | Not supported |
| Versioned, invocable deployments with tag-based routing | Yes | Yes |
| First-class graph/state-machine agent model | Not supported | Yes |
| Packaged sandbox + auth proxy + tracing product | Not supported | Yes |
| Hosted control plane option | Not supported | Yes |
How the two surfaces map
| Concept | LangGraph / Deep Agents | Kitaru |
|---|---|---|
| Execution model | Graph of nodes and edges with typed state | Ordinary Python with @flow + @checkpoint |
| Durable unit | A node, persisted by the checkpointer between supersteps | A checkpoint boundary around any Python call |
| Durability scope | Inside the LangGraph graph | Framework-agnostic — any harness inside a checkpoint |
| Pause / resume | Graph pause/resume via checkpointer | kitaru.wait() |
| Sandboxing | LangSmith Sandboxes (ephemeral, locked-down environments) | @checkpoint(runtime="isolated") on your configured stack |
| Deployment | LangSmith Deployment (packaged runtime + auth proxy + tracing) | flow.deploy() — immutable, versioned, tag-routed |
| Control plane | Hosted by LangSmith (or their on-prem option) | Self-hosted Helm service, artifacts in your own bucket |
Code comparison
from kitaru import flow, checkpoint, wait
@checkpoint
def plan(topic: str) -> dict:
# Any harness works inside — PydanticAI, Claude SDK, raw Python.
return pydantic_agent.run_sync(topic).output
@checkpoint
def synthesize(plan: dict) -> str:
return claude_agent.answer(plan)
@flow
def research(topic: str) -> str:
p = plan(topic)
ok = wait(name="approve", question="Plan looks right?", schema=bool)
return synthesize(p) if ok else "rejected"
# Durable ad-hoc run
handle = research.run(topic="durable agents")
# Or deploy + invoke: immutable versioned snapshots,
# tag routing, workspace-scoped auth.
research.deploy(topic="durable agents")
handle = research.invoke(topic="durable agents") from langgraph.graph import StateGraph, END
from langgraph.checkpoint.memory import MemorySaver
from typing_extensions import TypedDict
class State(TypedDict):
topic: str
plan: dict
draft: str
def plan_node(state: State) -> dict:
return {"plan": pydantic_agent.run_sync(state["topic"]).output}
def synth_node(state: State) -> dict:
return {"draft": claude_agent.answer(state["plan"])}
graph = StateGraph(State)
graph.add_node("plan", plan_node)
graph.add_node("synth", synth_node)
graph.add_edge("plan", "synth")
graph.add_edge("synth", END)
graph.set_entry_point("plan")
app = graph.compile(checkpointer=MemorySaver())
# Durability + HITL live inside the graph model;
# routing / deployment / versioning via LangSmith. Pick the runtime without picking the harness
If everyone on your team has standardized on LangGraph or Deep Agents and you’re moving onto LangSmith Deployment as the packaged runtime and platform, use what you have — Kitaru adds less. If multiple harnesses live across your teams, or a hosted control plane is not an option, Kitaru gives you one self-hosted durable runtime underneath all of them.
pip install kitaru