Skip to main content

Observability and mesh layer for multi-agent AI systems — track what your agents decided, why they decided it, and how they're connected.

Project description

AgentWeave

Observability for multi-agent AI systems. Track what your agents decided, why they decided it, and how much it cost.

AgentWeave wraps your Python agent code with W3C PROV-O compatible OpenTelemetry spans. Three decorators. Full decision provenance. Works with any OTLP backend.

Trace waterfall in Grafana Tempo showing a Gemini 2.5 Pro call with PROV-O span attributes
Trace waterfall in Grafana Tempo — a Gemini 2.5 Pro call with PROV-O span attributes (model, provider, agent ID, latency)

Multi-provider trace list showing Gemini and Claude calls side by side
Multi-provider trace list — Gemini and Claude Sonnet calls from the same proxy, one unified view

Architecture

graph LR
    subgraph Agents
        A1[Claude Agent<br><small>Python / Node.js</small>]
        A2[Gemini Agent<br><small>Python / Node.js</small>]
        A3[Any Agent<br><small>OpenAI, etc.</small>]
    end

    subgraph AgentWeave Proxy :4000
        P[Multi-Provider<br>Proxy]
    end

    subgraph Upstream LLMs
        AN[api.anthropic.com]
        GO[generativelanguage<br>.googleapis.com]
    end

    subgraph Observability
        OT[OTLP Collector<br><small>Tempo / Jaeger / Langfuse</small>]
        GR[Grafana<br>Dashboard]
    end

    A1 -- "ANTHROPIC_BASE_URL" --> P
    A2 -- "GOOGLE_GENAI_BASE_URL" --> P
    A3 -. "@trace_llm decorator" .-> OT

    P -- "/v1/messages" --> AN
    P -- "/v1beta/models/*" --> GO
    P -- "OTel spans" --> OT
    OT --> GR

How it works: Agents point their SDK base URL at the proxy. The proxy auto-detects the provider from the request path, forwards the call upstream, extracts token counts and metadata, and emits an OTel span — all transparently. For Python agents, you can also use the @trace_llm / @trace_tool / @trace_agent decorators directly.

Why

When an agent delegates to another agent, calls an LLM ten times searching for a photo, and finally deploys a result — none of that is visible today. You see the output. You don't see the chain.

AgentWeave makes the chain the first-class artifact:

agent.nix                          94ms
├── llm.claude-sonnet-4-6          81ms  ← prompt_tokens=847, completion_tokens=312
├── tool.image_search               52ms
├── llm.claude-sonnet-4-6          79ms  ← prompt_tokens=847, completion_tokens=312
├── tool.image_search               51ms
├── llm.claude-sonnet-4-6          80ms  ← found it
└── tool.deploy_portfolio           48ms

Every span carries PROV-O provenance: what was consumed, what was generated, which agent made the call, which model ran it.

Install

pip install agentweave

Quickstart

from agentweave import AgentWeaveConfig, trace_agent, trace_llm, trace_tool

# One-time setup — point at any OTLP HTTP endpoint
AgentWeaveConfig.setup(
    agent_id="my-agent-v1",
    agent_model="claude-sonnet-4-6",
    otel_endpoint="http://localhost:4318",  # Grafana Tempo, Jaeger, etc.
)

# Wrap your LLM calls
@trace_llm(provider="anthropic", model="claude-sonnet-4-6",
           captures_input=True, captures_output=True)
def call_claude(messages: list) -> ...:
    return client.messages.create(...)

# Wrap your tool calls
@trace_tool(name="web_search", captures_input=True, captures_output=True)
def web_search(query: str) -> str:
    ...

# Wrap your agent turns
@trace_agent(name="my-agent")
async def handle(message: str) -> str:
    response = call_claude(messages=[{"role": "user", "content": message}])
    return web_search(response.content[0].text)

That's it. All three spans link to the same trace ID. Open Grafana Tempo (or any OTLP backend) and you see the waterfall.

Decorators

@trace_agent

Root span for an agent turn. Nests all downstream tool and LLM calls.

@trace_agent(name="nix", captures_input=True, captures_output=True)
def handle(message: str) -> str: ...

@trace_tool

Span for any tool call — file ops, API calls, shell commands, A2A delegation.

@trace_tool(name="delegate_to_max", captures_input=True, captures_output=True)
def delegate_to_max(task: str) -> dict: ...

@trace_llm

Span for LLM invocations. Auto-extracts token counts and stop reason from the response (Anthropic, OpenAI, and Google Gemini conventions supported).

@trace_llm(provider="anthropic", model="claude-sonnet-4-6",
           captures_input=True, captures_output=True)
def call_claude(messages: list) -> anthropic.Message: ...

@trace_llm(provider="google", model="gemini-2.5-pro",
           captures_input=True, captures_output=True)
def call_gemini(contents: list) -> genai.GenerateContentResponse: ...

Captured automatically:

  • prov.llm.prompt_tokens / prov.llm.completion_tokens / prov.llm.total_tokens
  • prov.llm.stop_reason (end_turn, tool_use, STOP, etc.)
  • prov.llm.prompt_preview and prov.llm.response_preview (first 512 chars, when captures_input/output=True)

PROV-O Attributes

Attribute Description
prov.activity Name of the activity (tool/agent/llm)
prov.activity.type tool_call, agent_turn, or llm_call
prov.agent.id Agent identifier
prov.agent.model Model name
prov.used Serialized inputs consumed by the activity
prov.wasGeneratedBy Output produced by the activity
prov.wasAssociatedWith Agent responsible for the activity
prov.llm.provider LLM provider (anthropic, openai, google)
prov.llm.model Model name
prov.llm.prompt_tokens Input token count
prov.llm.completion_tokens Output token count
prov.llm.total_tokens Total tokens
prov.llm.stop_reason Why the model stopped

Full schema: agentweave/schema.py

Proxy — multi-provider observability gateway

For agents you can't instrument with decorators (Node.js, Claude Code, OpenClaw), run the AgentWeave proxy — a transparent HTTP server that sits between your agents and their LLM providers.

The proxy auto-detects the provider from the request path:

Path pattern Provider Upstream
/v1/messages Anthropic api.anthropic.com
/v1beta/models/... Google Gemini generativelanguage.googleapis.com
/v1/models/... Google Gemini generativelanguage.googleapis.com
pip install "agentweave[proxy]"
agentweave proxy start --port 4000 --endpoint http://localhost:4318 --agent-id my-agent

Point your agents at the proxy:

# Anthropic agents
export ANTHROPIC_BASE_URL=http://localhost:4000

# Google Gemini agents
export GOOGLE_GENAI_BASE_URL=http://localhost:4000

One port, all providers. Every LLM call gets a span — no SDK changes, no framework lock-in.

Full setup guide: docs/proxy-setup.md

Backends

AgentWeave emits standard OTLP HTTP — works with any compatible backend:

Backend Setup
Grafana Tempo otel_endpoint="http://tempo:4318" — recommended for self-hosted
Jaeger otel_endpoint="http://jaeger:4318"
Langfuse v3 otel_endpoint="https://cloud.langfuse.com/api/public/otel" + auth headers
Any OTel Collector Point at the collector's OTLP HTTP receiver
Console (dev) from agentweave import add_console_exporter; add_console_exporter()

Development

git clone https://github.com/arniesaha/agentweave
cd agentweave
pip install -e ".[dev]"
pytest                          # 24 tests
python examples/simple_agent.py
python examples/nix_max_delegation.py

License

MIT

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

agentweave_sdk-0.1.1.tar.gz (844.5 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

agentweave_sdk-0.1.1-py3-none-any.whl (18.9 kB view details)

Uploaded Python 3

File details

Details for the file agentweave_sdk-0.1.1.tar.gz.

File metadata

  • Download URL: agentweave_sdk-0.1.1.tar.gz
  • Upload date:
  • Size: 844.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for agentweave_sdk-0.1.1.tar.gz
Algorithm Hash digest
SHA256 c9d8bbc5870feca85470a6ee91ae64a72b48824ed6be3920e3141b7562b5bcaa
MD5 5bdf1502b0a537d5fd227b36103ede05
BLAKE2b-256 e6895656677e15479634d4a114471f848435745c00a710cf7f2ad191a2f91e2c

See more details on using hashes here.

Provenance

The following attestation bundles were made for agentweave_sdk-0.1.1.tar.gz:

Publisher: publish.yml on arniesaha/agentweave

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file agentweave_sdk-0.1.1-py3-none-any.whl.

File metadata

  • Download URL: agentweave_sdk-0.1.1-py3-none-any.whl
  • Upload date:
  • Size: 18.9 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for agentweave_sdk-0.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 b183c3e85fc66d74a33661cf3077c5c447541e5151f2b53cda6fa42d47fec184
MD5 91d4e64bee7678989b38913ff1b4fe21
BLAKE2b-256 4e7aaa5fc3a17e4f5976204c79b20d68c97e1ed970b145a02b05c37bbc4d49f8

See more details on using hashes here.

Provenance

The following attestation bundles were made for agentweave_sdk-0.1.1-py3-none-any.whl:

Publisher: publish.yml on arniesaha/agentweave

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page