LangGraph (tracing)

LangGraph is a framework for building stateful, multi-step agent workflows as graphs. Nodes represent operations such as LLM calls, tools, and routing decisions, while edges define the flow between them. Respan gives you full observability over every graph run, node, tool call, and LLM generation — and gateway routing through the OpenAI-compatible Respan endpoint.

Create an account at platform.respan.ai and grab an API key.

Run npx @respan/cli setup to set up with your coding agent.

See LangGraph gateway setup to route this integration through the Respan gateway.

Setup

1

Install packages

$pip install respan-ai respan-instrumentation-langchain langgraph langchain-openai python-dotenv
2

Set environment variables

$export RESPAN_API_KEY="YOUR_RESPAN_API_KEY"
$export RESPAN_BASE_URL="https://api.respan.ai/api"

RESPAN_API_KEY is used to export traces to Respan. Set OPENAI_API_KEY too when graph nodes call provider-backed models.

3

Initialize and run

LangGraph runs through LangChain callback managers, so use respan-instrumentation-langchain and pass LangChainInstrumentor() to Respan(instrumentations=[...]).

Python — the instrumentor patches the LangChain and LangGraph callback managers on init, so the compiled graph, every node, and their nested LLM and tool calls are traced automatically. No per-call setup.

TypeScript — the instrumentor does not patch globally. Attach langgraph.addCallback(...) at the compiled graph’s top-level app.invoke() (or app.stream()), not inside a node; LangGraph propagates it to every node. Attaching it only inside a single node yields just that node’s spans.

1from typing import TypedDict
2
3from langgraph.graph import StateGraph, START, END
4from respan import Respan
5from respan_instrumentation_langchain import LangChainInstrumentor
6
7# Activates global LangChain/LangGraph instrumentation — graph and node runs are traced automatically.
8respan = Respan(instrumentations=[LangChainInstrumentor()])
9
10class State(TypedDict):
11 topic: str
12 joke: str
13
14def generate_joke(state: State) -> dict:
15 return {"joke": f"A short joke about {state['topic']}"}
16
17graph = StateGraph(State)
18graph.add_node("generate", generate_joke)
19graph.add_edge(START, "generate")
20graph.add_edge("generate", END)
21
22app = graph.compile()
23result = app.invoke({"topic": "AI tracing"})
24print(result)
4

View your trace

Open the Traces page to see the graph execution with node spans, LLM calls, and state transitions.

Configuration

ParameterTypeDefaultDescription
api_keystr | NoneNoneFalls back to RESPAN_API_KEY env var.
base_urlstr | NoneNoneFalls back to RESPAN_BASE_URL env var.
instrumentationslist[]Plugin instrumentations to activate, e.g. LangChainInstrumentor().
include_contentboolTrueIncludes graph inputs, node inputs, and outputs on spans.
include_metadataboolTrueIncludes LangGraph tags, metadata, and serialized runnable details.
customer_identifierstr | NoneNoneDefault customer identifier for all spans.
metadatadict | NoneNoneDefault metadata attached to all spans.
environmentstr | NoneNoneEnvironment tag, e.g. "production".

Attributes

In Respan()

Set defaults at initialization — these apply to all spans.

1from respan import Respan
2from respan_instrumentation_langchain import LangChainInstrumentor
3
4respan = Respan(
5 instrumentations=[LangChainInstrumentor()],
6 customer_identifier="user_123",
7 metadata={"service": "graph-api", "version": "1.0.0"},
8)

With propagate_attributes

Override per-request using a context scope.

1from respan import propagate_attributes
2from respan_instrumentation_langchain import add_respan_callback
3
4def handle_request(user_id: str, topic: str):
5 with propagate_attributes(
6 customer_identifier=user_id,
7 thread_identifier="conv_abc_123",
8 metadata={"plan": "pro"},
9 ):
10 result = app.invoke(
11 {"topic": topic},
12 config=add_respan_callback({"run_name": "user_graph"}),
13 )
14 print(result)
AttributeTypeDescription
customer_identifierstrIdentifies the end user in Respan analytics.
thread_identifierstrGroups related messages into a conversation.
metadatadictCustom key-value pairs. Merged with default metadata.

Decorators (optional)

Decorators are not required. Graph and node runs are traced automatically by the instrumentor in Python, and when you attach the Respan callback config to the graph invocation in TypeScript. Use @workflow and @task (Python) or withWorkflow and withTask (TypeScript) to group graph runs inside larger application workflows.

1from respan import workflow, task
2from respan_instrumentation_langchain import add_respan_callback
3
4@task(name="run_joke_graph")
5def run_joke_graph(topic: str):
6 return app.invoke(
7 {"topic": topic},
8 config=add_respan_callback({"run_name": "decorated_graph"}),
9 )
10
11@workflow(name="joke_pipeline")
12def pipeline(topic: str):
13 print(run_joke_graph(topic))
14
15pipeline("AI tracing")

Examples

Streaming updates

Stream graph node updates while keeping the same trace.

1for update in app.stream(
2 {"topic": "AI tracing"},
3 config=add_respan_callback({"run_name": "streaming_graph"}),
4 stream_mode="updates",
5):
6 print(update)

Tool nodes

Tool calls inside graph nodes are captured as tool spans.

1from langchain_core.tools import tool
2from langgraph.prebuilt import ToolNode
3
4@tool
5def search_docs(query: str) -> str:
6 """Search docs."""
7 return f"Results for {query}"
8
9tools = ToolNode([search_docs])