Skip to main content
This topic describes how to use the ibm-watsonx-orchestrate-sdk observability decorators to instrument a LangGraph-based agent. LangGraph is a Python framework for building stateful, graph-based AI agents whose logic is expressed as nodes in a StateGraph. The SDK manages span creation, nesting, authentication, and export internally, so only a few decorator additions to your agent code are required. Use this approach when:
  • Your agent is built with LangGraph.
  • You want the finest level of trace detail: per-LLM-call, per-tool-call, and per-agent-node spans with structured metadata.
  • You prefer decorator-based instrumentation over manually writing tracer and exporter code.
For an approach that requires no SDK dependency and uses the standard OpenTelemetry SDK instead, see Exporting observability traces with OpenTelemetry.

How it works

The SDK wraps the same OpenTelemetry export pipeline as the OpenTelemetry export approach, but manages it for you:
The setup follows four steps:
  1. Initialize a Client with your API key and instance URL.
  2. Create a TracerConfig that identifies the agent and workspace that the exported spans belong to, by using the registered agent’s agent_id, workspace_id, and environment. On AWS deployments, the SDK derives the tenant context automatically from the JWT token. On IBM Cloud, pass tenant_id explicitly because the IAM token does not contain tenant information.
  3. Build a Tracer from the configuration and register it globally with register_tracer() to make it available to all SDK decorators.
  4. Apply decorators to the relevant functions. Each decorator is a Python @ annotation that intercepts function calls at runtime to create and export spans without modifying your function logic.
After watsonx Orchestrate receives the spans, they appear in Analyze > [Agent name] > Overview and Conversations, showing total conversations, token counts, average duration, and the usage trend chart.

Before you begin

Complete the following setup before you instrument your agent:
  1. Import the LangGraph agent through the watsonx Orchestrate UI to create an agent entry and obtain a valid Agent ID. For more information, see Importing LangGraph agents.
  2. Copy the Agent ID from the registered agent.
  3. For IBM Cloud: Copy the Workspace ID. Call the List workspaces API to fetch the workspaces from a tenant.
  4. Copy the Tenant ID for your instance. The Tenant ID has the format <account-id>_<instance-id>. Obtain it in one of the following ways:
    • From the instance CRN in Profile > About.
    • From the browser DevTools console, run WO_Meta to retrieve its properties.
    When you use the SDK on AWS deployments, the tenant context is derived automatically from the JWT token inside Client. On IBM Cloud, the IAM token does not contain tenant information, so you must pass the Tenant ID explicitly as tenant_id in TracerConfig.
  5. Obtain an API key and the corresponding IAM or MCSP token URL that is authorized to call the trace ingestion endpoint. For more information, see Authenticating to the API.
  6. Note the instance URL for your watsonx Orchestrate instance. This URL is the base URL of the ingestion endpoint and has the format https://api.watson-orchestrate.ibm.com/instances/<instance-id>. For more information, see Getting the API endpoint.
Save the Agent ID, Tenant ID, API key, token URL, and instance URL values for use in the procedure.

Procedure

1

Installing the SDK

Because the SDK is currently a pre-release build, install it from Test PyPI.To perform a quick install, run:
BASH
For a project with a requirements.txt, add the following entries:
Then install the dependencies:
BASH
2

Configuring the tracer

At module load time, create a Client, build a TracerConfig, and register the tracer globally. Complete this step once, before any decorated functions are called.
Python
Key points:
  • Pass api_key and instance_url to Client.
  • On AWS, the SDK derives the tenant context automatically from the JWT token, so tenant_id is not required.
  • On IBM Cloud, the IAM API key generates a user-level token that does not include tenant information. Pass tenant_id explicitly in TracerConfig to avoid a ValueError: Trace injection mode requires the following parameters: tenant_id at startup.
  • The only valid values for environment are "draft" and "live".
  • Tracer uses DynamicAuthOTLPSpanExporter to refresh tokens automatically. Long-running agent processes do not need to be restarted when an access token expires.
3

Decorating agent functions

Apply the SDK decorators to the functions that make up your agent. Manual span creation is not required.The following table shows which decorator to apply and where:

General-purpose helper calls: @trace_call

Use @trace_call for helper logic such as validation or response formatting. Set capture_input=True or capture_output=True to record function arguments and return values as span attributes.
Python

Tool calls: @trace_tool_call

Use @trace_tool_call on functions that are also decorated with LangChain’s @tool decorator. The SDK records each tool invocation as a distinct span with tool-specific metadata.
@tool must be the outermost decorator. Place @tool above @trace_tool_call in the source file, with @trace_tool_call applied directly to the function.
Python

LLM calls: @trace_llm_call

Wrap the function that invokes the LLM with @trace_llm_call. Set model and provider so that the analytics view correctly attributes token and latency metrics.
Python

Agent node: @trace_agent_call

Apply @trace_agent_call to the top-level LangGraph node that represents the agent decision step. The agent_name parameter labels this trace in the analytics view. The agent_id in TracerConfig identifies the watsonx Orchestrate agent instance to which the trace belongs.
Python

Graph factory: @configure_tracing

Apply @configure_tracing to the factory function that builds and returns the LangGraph StateGraph. This decorator propagates tracing context through the compiled graph.
Python

Result

After the decorated agent runs, the SDK exports the captured spans to watsonx Orchestrate by using the Client credentials and the configured agent_id and tenant context. The traces are visible in watsonx Orchestrate under Analyze > [Agent name] > Overview and Conversations. Per-call span detail is available in the Conversations drill-down view.

Troubleshooting

Verifying trace ingestion
If traces do not appear on the Analytics page, use the Get Traces API to confirm whether the ingestion endpoint received them. If the API returns your traces, ingestion was successful. If the Get Traces API returns an empty list, the spans were not received. Check the following items:
  • 401 Unauthorized on startup: The API key or instance URL passed to Client is incorrect. Verify that both values match the watsonx Orchestrate instance where the agent is registered.
  • Token expiry during a long run: The DynamicAuthOTLPSpanExporter refreshes tokens automatically. If authentication failures persist, confirm that the API key has not been revoked and that the instance URL is reachable from the agent host.
  • agent_id or workspace_id not found: The values passed to TracerConfig must match the Agent ID and Workspace ID shown in the watsonx Orchestrate UI for the registered agent. Verify both values against the registration entry.
  • @configure_tracing not applied: If @configure_tracing is missing from the graph factory function, tracing context is not propagated through the compiled graph, and child spans may not be associated with the correct root span.