Getting Started
Installation, client initialization, and first run with decorators or client API.
Getting Started
Installation
pip install multirun
# With LangGraph adapter
pip install multirun[langgraph]
# Development (tests, linting)
pip install multirun[dev]Initialize the client
Two options: connect to a remote runtime, or run locally in-memory.
Remote runtime
import multirun
multirun.init("http://localhost:8989", api_key="your-api-key")The API key is sent as Authorization: ApiKey <key> on every request. Keys are workspace-scoped — all runs created with a key belong to that workspace.
Local (no server)
import multirun
client = multirun.init_local()All operations work in-memory. Useful for testing and development.
Using decorators (recommended)
Decorators are the simplest way to instrument your agents.
import asyncio
import multirun
from multirun import run, step, checkpoint
from multirun.models import Budget
multirun.init("http://localhost:8989", api_key="your-api-key")
@step(retry=3, checkpoint=True)
async def call_llm(prompt: str) -> str:
"""Retries up to 3 times; checkpoints after success."""
return await your_llm_call(prompt)
@step
async def process(response: str) -> dict:
"""Simple step — no retry, no checkpoint."""
return {"processed": response.upper()}
@run(budget=Budget(max_tokens=10000, max_cost_usd=0.10))
async def my_agent(query: str) -> dict:
response = await call_llm(query)
return await process(response)
async def main():
async with multirun.get_client():
result = await my_agent("What is the weather?")
print(result)
asyncio.run(main())Key points:
@runcreates a tracked run with budget enforcement.@stepregisters each call as a transactional step with optional retry.@checkpointsaves a durable checkpoint after the function returns.- All decorators work with both
@decoratorand@decorator(...)syntax.
See Decorators for full parameter reference.
Using the client directly
For lower-level control, use MultiRunClient methods directly.
import asyncio
from multirun import MultiRunClient, Budget, StepKind
async def main():
client = MultiRunClient.connect("http://localhost:8989", api_key="your-key")
async with client:
run = await client.start_run("my_agent", budget=Budget(max_tokens=10000))
step = await client.start_step(run, "call_llm", kind=StepKind.LLM_CALL)
# ... your work here ...
await client.complete_step(step, tokens_used=500, latency_ms=120)
await client.complete_run(run, result=b"serialized_result")
asyncio.run(main())See Client for the full API.
Authentication
| Method | Header | Used by |
|---|---|---|
| API key | Authorization: ApiKey <raw_key> | SDK, programmatic access |
| JWT (Cognito) | Authorization: Bearer <cognito-jwt> | Web UI, account management |
- Run and step endpoints accept either method (dual-auth).
- API keys are workspace-scoped.
- The raw key is returned once when created and must be stored securely.
Next steps
- Configuration — env vars,
MultiRunConfig - Context —
RunContext,AgentContext, checkpointing & replay - LangGraph adapter — durable graph execution