LangGraph integration
LangGraph is AuditTrail's most complete integration: one helper call runs your compiled graph and emits the full span tree — orchestrator root, LLM turns, a grouped tool phase with one span per tool call, and the final response turn — with automatic timing, token and cost accounting.
This is the integration the quickstart's starter template is built on.
Install
From a checkout of the repo:
pip install -e packages/sdk-python(or start from the pre-wired template on the Quick Start page — Download ZIP, add keys, run.)
One call, whole graph
import asyncio
from audittrail import AuditTrailClient
async def main() -> None:
agent = build_graph() # your compiled LangGraph graph
async with AuditTrailClient(
api_base="https://your-audittrail-host",
api_key="sk-at-...",
agent_name="research-agent",
environment="development",
) as client:
result = await client.run_langgraph(
agent,
inputs={"messages": [("user", prompt)]},
user_prompt=prompt,
model="gpt-4o-mini",
)
print(result.trace_id, result.response, result.tool_calls)
asyncio.run(main())run_langgraph streams agent.astream_events(version="v2") and builds a
three-level hierarchy:
agent_orchestrator (root agent span)
├── parse_user_intent / chain_of_thought (LLM spans)
├── execute_tools (phase group)
│ ├── web_search (tool span)
│ └── calculator (tool span)
└── generate_response (final LLM turn)
It returns a LangGraphRunResult with trace_id, response, steps,
tool_calls, duration_ms, and error — agent exceptions (including
GraphRecursionError) are captured into .error and the orchestrator span
is always closed, so a failing run still produces a complete, inspectable
trace.
Useful knobs:
recursion_limit=60— passed through to LangGraph (its own default of 25 is too low for research-style prompts).on_step=fn— sync or async callable invoked per streamed event, for your own logging without re-parsing the stream.verbose=True— prints a run banner, per-step lines, and the trace URL when the run finishes.
Working examples in the repo
examples/langgraph-agent/— minimal template (the quickstart ZIP).examples/deep-search-agent/— a real multi-tool research agent: tool definitions + graph wiring + oneasync with AuditTrailClientblock; ~280 lines of actual user code.
Alternative: the callback handler
If you want spans to reflect LangGraph's raw event structure instead of the phase-grouped tree, pass the LangChain callback handler in your graph's config — both approaches share the same ingest pipeline.
Gotchas
- Your graph must support
astream_events(version="v2")(LangGraph ≥ 0.1 compiled graphs do). - The client is an async context manager — spans batch-flush on exit; if
you construct it without
async with, callawait client.close(). - Live streaming: spans appear in the dashboard as the agent runs — open
/traces/<trace_id>mid-run and watch the DAG fill in. When the orchestrator span closes, the server broadcaststrace_completeand the status badge flips to Complete without a refresh.