Skip to main content

Agent Observability Python Framework Module: LangGraph

agento11y-langgraph provides callback handlers that map LangGraph lifecycle events into agento11y generation recorder lifecycles.

Installation

pip install agento11y agento11y-langgraph
pip install langgraph langchain-openai

Usage

from agento11y import Client
from agento11y_langgraph import with_agento11y_langgraph_callbacks

client = Client()
config = with_agento11y_langgraph_callbacks(None, client=client, provider_resolver="auto")

End-to-end example (graph invoke + stream)

from typing import TypedDict

from langchain_core.runnables import RunnableConfig
from langchain_openai import ChatOpenAI
from langgraph.graph import END, StateGraph
from agento11y import Client
from agento11y_langgraph import with_agento11y_langgraph_callbacks


class GraphState(TypedDict):
    prompt: str
    answer: str


client = Client()
llm = ChatOpenAI(model="gpt-4o-mini", temperature=0)


def run_model(state: GraphState, config: RunnableConfig) -> GraphState:
    response = llm.invoke(
        state["prompt"],
        config=config,
    )
    return {"prompt": state["prompt"], "answer": str(response.content).strip()}


workflow = StateGraph(GraphState)
workflow.add_node("model", run_model)
workflow.set_entry_point("model")
workflow.add_edge("model", END)
graph = workflow.compile()

agento11y_config = with_agento11y_langgraph_callbacks(
    None,
    client=client,
    provider_resolver="auto",
    agent_name="langgraph-example",
    agent_version="1.0.0",
)

# Non-stream graph invocation.
out = graph.invoke(
    {"prompt": "Explain SLO burn rate in one paragraph.", "answer": ""},
    config=agento11y_config,
)
print(out["answer"])

# Streamed graph events.
for _event in graph.stream(
    {"prompt": "List three practical alerting tips.", "answer": ""},
    config=agento11y_config,
):
    pass

client.shutdown()

Workflow step capture

Enable capture_workflow_steps=True to record each graph node as a workflow step. This enables the Workflow tab in the conversation detail view, showing node execution order, duration, input/output state, and which LLM generations ran inside each node. The Dependencies tab remains available for the generation-level DAG built from parent_generation_ids.

Always set conversation_title to a short human-readable label — it appears as the conversation name in the Agent Observability UI. Without it, the title falls back to an opaque auto-generated ID.

from agento11y import Client
from agento11y_langgraph import Agento11yLangGraphHandler

client = Client()
handler = Agento11yLangGraphHandler(
    client=client,
    agent_name="my-pipeline",
    conversation_title="My Pipeline Run",
    capture_workflow_steps=True,
)

# Reuse the `graph` from the end-to-end example above. The node must pass its
# received `config` into `llm.invoke(...)` so generations link to the workflow step.
result = graph.invoke(
    {"prompt": "Explain why my dashboard is slow.", "answer": ""},
    config={"callbacks": [handler]},
)
client.shutdown()

The handler automatically:

  • Detects graph root and direct-child nodes
  • Creates a workflow step per node with input_state, output_state, and timestamps
  • Links LLM generation IDs to their parent step via linked_generation_ids
  • Tracks sequential parent_step_ids so the DAG edges are correct

Two things silently break the linkage:

  • The node's config parameter must be annotated RunnableConfig. LangGraph inspects the annotation to decide whether to inject the config. Annotate it dict[str, Any] and LangGraph will not pass it, so the node's generations land outside the workflow step.
  • A custom generation exporter must implement export_workflow_steps. With capture_workflow_steps=True the client calls it on every flush; an exporter without the method logs a warning per batch and drops the steps.

Conversation grouping

The handler resolves the conversation id per invocation, in this order:

  1. conversation_id / session_id / group_id in the callback metadata, invocation params, or configurable
  2. The LangGraph thread_id
  3. The handler's conversation_id constructor argument
  4. A synthetic per-run id

Pass conversation_id on the constructor when your application owns the conversation identity and does not use a LangGraph checkpointer. Per-invocation identity still wins, so a handler built once per process cannot override a checkpointed thread_id.

handler = Agento11yLangGraphHandler(
    client=client,
    agent_name="my-pipeline",
    conversation_id=request.conversation_id,
    conversation_title="My Pipeline Run",
)

Without any of these, each run becomes its own conversation.

Persistent thread example (LangGraph checkpointer)

from langgraph.checkpoint.memory import MemorySaver

checkpointer = MemorySaver()
graph = workflow.compile(checkpointer=checkpointer)

thread_config = {
    **with_agento11y_langgraph_callbacks(None, client=client, provider_resolver="auto"),
    "configurable": {"thread_id": "customer-42"},
}

graph.invoke({"prompt": "Remember that my timezone is UTC+1.", "answer": ""}, config=thread_config)
graph.invoke({"prompt": "What timezone did I just give you?", "answer": ""}, config=thread_config)

# Advanced usage: explicit handler wiring remains supported.
_ = graph.invoke(
    {"prompt": "manual handler wiring", "answer": ""},
    config={"callbacks": [handler]},
)

When thread_id is present, the handler records:

  • conversation_id=<thread_id>
  • metadata["agento11y.framework.run_id"]=<run id>
  • metadata["agento11y.framework.thread_id"]=<thread id>
  • generation span attributes agento11y.framework.run_id and agento11y.framework.thread_id

Behavior

  • Lifecycle mapping:
    • on_llm_start / on_chat_model_start -> generation recorder
    • System and developer messages passed to on_chat_model_start are lifted out of the input message list into system_prompt (joined with a blank line when there are several), since the wire format has no system role. An explicit invocation_params["system_prompt"] wins.
    • on_tool_start / on_tool_end / on_tool_error -> start_tool_execution
    • on_chain_start / on_chain_end / on_chain_error -> framework chain spans
    • on_retriever_start / on_retriever_end / on_retriever_error -> framework retriever spans
    • on_llm_new_token -> first-token timestamp for stream mode
  • Mode mapping: non-stream -> SYNC, stream -> STREAM.
  • Provider resolver parity:
    • explicit provider metadata when available
    • model-name inference (gpt-/o1/o3/o4 -> openai, claude- -> anthropic, gemini- -> gemini)
    • fallback -> custom
  • Framework tags/metadata are always set:
    • agento11y.framework.name=langgraph
    • agento11y.framework.source=handler
    • agento11y.framework.language=python
    • metadata["agento11y.framework.run_id"]=<run id>
    • metadata["agento11y.framework.thread_id"]=<thread id> (when present in callback metadata/config)
    • metadata["agento11y.framework.parent_run_id"] (when available)
    • metadata["agento11y.framework.component_name"] (serialized component identity)
    • metadata["agento11y.framework.run_type"] (llm, chat, tool, chain, retriever)
    • metadata["agento11y.framework.tags"] (normalized callback tags)
    • metadata["agento11y.framework.retry_attempt"] (when available)
    • metadata["agento11y.framework.langgraph.node"] (when callback context exposes node identity)
    • generation span attributes mirror low-cardinality framework metadata keys

Call client.shutdown() during teardown to flush buffered telemetry.

Metadata

Release files for agento11y-langgraph 0.18.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for agento11y-langgraph 0.18.0
File Size Uploaded
agento11y_langgraph-0.18.0.tar.gz 12.1 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for agento11y-langgraph 0.18.0
File Interpreter ABI Platform
agento11y_langgraph-0.18.0-py3-none-any.whl Python 3 none any Details

Total release size: 19.1 kB

Release files / agento11y_langgraph-0.18.0.tar.gz

Download URL agento11y_langgraph-0.18.0.tar.gz
Size 12.1 kB
Tags Source
SHA-256 checksum
How to use checksums
818b248d0606711138f83c6c9fde2a27a7612fded248937aeefbbb38df5a5178
BLAKE2b-256 checksum
How to use checksums
bad1e2ea6a5c02088a8d6e11b5daff775b220f36e3e0927a623a041b9ae0a090
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.13

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 30, 2026.

Transparency log

Release files / agento11y_langgraph-0.18.0-py3-none-any.whl

Download URL agento11y_langgraph-0.18.0-py3-none-any.whl
Size 7.0 kB
Tags Python 3
SHA-256 checksum
How to use checksums
cc7fc8c6078a0c177fcd59e86738f304bca89514a84e818f1e16dfbd117a1679
BLAKE2b-256 checksum
How to use checksums
44200119185944b471eb43ee70d9fa72e90ba1bde1b72c0c239688294559424f
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.13

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 30, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.18.0 This release

2 release files

0.17.0

2 release files

0.16.0

2 release files

0.15.0

2 release files

0.14.0

2 release files

0.12.0

2 release files

0.10.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page