Skip to content

langchain-samples/a2a-cross-workspace-tracing

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

A2A Distributed Tracing

Demonstrates how to get unified distributed traces when two LangGraph agents communicate via the A2A (Agent-to-Agent) protocol.

Architecture

Agent A (Port 2024)                          Agent B (Port 8000)
┌──────────────────────┐                     ┌──────────────────────┐
│  create_agent        │                     │  create_agent        │
│                      │   A2A JSON-RPC      │                      │
│  call_agent_b tool ──┼──────────────────►  │  context manager     │
│                      │   + langsmith-trace  │  tracing_context     │
│                      │   + baggage headers  │  + parent (nesting)  │
│                      │   + workspace-id     │  + client (routing)  │
└──────────────────────┘                     └──────────────────────┘
         │                                            │
         └──────────── Unified trace in LangSmith ────┘
              (works across workspaces!)

How it works

Unlike RemoteGraph which has a built-in distributed_tracing=True flag, A2A is a standard HTTP protocol with no automatic trace propagation. The trick is to manually include LangSmith trace headers in the A2A HTTP request:

Agent A (caller) - Propagates trace context + workspace info in the A2A call:

run_tree = ls.get_current_run_tree()
if run_tree:
    trace_headers = run_tree.to_headers()
    headers.update(trace_headers)

# Send workspace ID so Agent B can route traces back to us
headers["langsmith-workspace-id"] = os.getenv("LANGSMITH_WORKSPACE_ID")
headers["langsmith-project"] = os.getenv("LANGSMITH_PROJECT")

httpx.post(f"{url}/a2a/{assistant_id}", json=payload, headers=headers)

Agent B (callee) - Uses a cross-workspace Client to write traces to the caller's workspace:

@contextmanager
def graph(config):
    conf = config.get("configurable", {})
    caller_workspace_id = conf.get("langsmith-workspace-id")

    if caller_workspace_id and cross_workspace_key:
        # Route traces to the caller's workspace
        client = Client(
            api_key=cross_workspace_key,
            workspace_id=caller_workspace_id,
        )
        with tracing_context(
            parent=conf.get("langsmith-trace"),
            client=client,
            project_name=conf.get("langsmith-project"),
        ):
            yield compiled_graph

The LangGraph API server's A2A endpoint automatically forwards HTTP headers through to config["configurable"], making langsmith-trace, langsmith-workspace-id, and langsmith-project available to the context manager.

Running the example

You need three terminal windows:

Terminal 1 - Start Agent B (port 8000):

cd agent_b
uv sync
uv run langgraph dev --port 8000 --no-browser

Terminal 2 - Start Agent A (port 2024):

cd agent_a
uv sync
uv run langgraph dev --port 2024 --no-browser

Terminal 3 - Run the test:

uv sync
uv run python test_a2a_tracing.py

Then check LangSmith for a unified trace where Agent B's execution is nested under Agent A's trace.

Cross-workspace tracing

This example supports cross-workspace tracing — Agent B can write traces to Agent A's workspace even when they belong to different workspaces/organizations.

How it works

  1. Agent A sends its LANGSMITH_WORKSPACE_ID as a header alongside the trace headers
  2. Agent B reads the workspace ID from config["configurable"]
  3. Agent B creates a langsmith.Client using a cross-workspace API key (LS_CROSS_WORKSPACE_KEY) targeting the caller's workspace
  4. tracing_context(parent=..., client=..., project_name=...) both nests the trace under Agent A and routes it to Agent A's workspace

Setup for cross-workspace

Add these to your .env:

# A cross-workspace personal API key (must have access to both workspaces)
LS_CROSS_WORKSPACE_KEY="lsv2_pt_..."

# Agent A's workspace ID (find in LangSmith Settings > Workspace)
LANGSMITH_WORKSPACE_ID="your-workspace-id-here"

Without LANGSMITH_WORKSPACE_ID set, the example falls back to same-workspace tracing (the original behavior).

About

Demonstrates how to get unified distributed traces when two LangGraph agents communicate via the A2A protocol running on LangSmith's Agent Server.

Resources

Contributing

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages