sigil-telemetry
Plug-and-play telemetry for AI agents. Install it, call init(), and every LLM call your agent makes is automatically tracked in Sigil.
Quick Start
pip install sigil-telemetry[all]
from sigil_telemetry import init
init()
# Set your agent's ID and collector endpoint
SIGIL_AGENT_ID=sigil-agent-your-agent-slug
SIGIL_COLLECTOR_URL=https://your-collector-endpoint/
That's it. Every LLM API call is now captured — tokens, model, latency, errors — and sent to the Sigil collector.
What's New in v0.2.0
- Web framework auto-instrumentation — FastAPI, Flask, and Django are auto-detected and instrumented. All LLM calls within one HTTP request share a single
trace_id(operation_Id), so you can count agent "runs" withCOUNT(DISTINCT trace_id). - Noise span filtering —
http send/http send bodyspans from web frameworks are silently dropped before they leave the process. They never reach your collector, so you're not billed for them. - Health check exclusion — Routes like
/health,/healthz,/ready,/alive,/pingare excluded from tracing entirely. No spans generated, no storage cost. - Graceful shutdown —
atexithandler flushes all pending spans when the process exits, so you never lose the last batch. - Lighter install — Removed unnecessary dependencies from the core install.
Full Example: What Actually Happens
Here's a real agent that summarizes documents using Claude. Let's walk through exactly what the telemetry captures and where it ends up.
1. The Agent Code
# document_summarizer.py
import anthropic
from sigil_telemetry import init
# Initialize telemetry — call this ONCE at startup
init()
# Your normal agent code — no changes needed
client = anthropic.Anthropic()
response = client.messages.create(
model="claude-sonnet-4-20250514",
max_tokens=1024,
messages=[
{"role": "user", "content": "Summarize this document: ..."}
]
)
print(response.content[0].text)
2. What Gets Captured (Per LLM Call)
Every time client.messages.create() runs, a span is automatically created with:
| Field | Example Value | Description |
|---|---|---|
operation_Id |
a1b2c3d4e5f6... |
Trace ID — groups all LLM calls in a single agent run |
sigil.agent.id |
sigil-agent-doc-summarizer |
Which agent made the call |
sigil.agent.version |
sha-abc1234 |
Agent version (set by deploy workflow) |
sigil.agent.frameworks |
Anthropic,FastAPI |
Which SDKs and frameworks were detected |
gen_ai.system |
anthropic |
LLM provider |
gen_ai.request.model |
claude-sonnet-4-20250514 |
Model used |
gen_ai.usage.input_tokens |
1250 |
Tokens sent |
gen_ai.usage.output_tokens |
340 |
Tokens received |
duration |
2.3s |
How long the call took |
status |
OK or ERROR |
Whether the call succeeded |
sigil.environment |
production |
Environment |
sigil.agent.division |
Sales |
Business division (if set) |
sigil.agent.risk_classification |
low |
Risk level (if set) |
If the agent makes multiple LLM calls in one run (e.g., calls Claude then GPT-4), all calls share the same operation_Id so you can see the full trace.
3. How Trace Grouping Works
API agents (FastAPI/Flask/Django): The web framework instrumentor creates a root span per HTTP request. All LLM calls within that request automatically become child spans sharing the same trace_id. You don't need to do anything — init() handles it.
Worker agents (scheduled jobs, listeners): The template wraps your main() function in a root span. All LLM calls within one job or message share the same trace_id.
In both cases: COUNT(DISTINCT trace_id) = number of agent runs.
4. Where the Data Goes
Agent makes LLM call
│
▼
sigil-telemetry auto-captures it as an OpenTelemetry span
(noise spans like "http send" are filtered out here)
│
▼
Span is batched and sent via OTLP to:
→ Your configured collector endpoint
│
▼
Collector forwards to:
→ Your observability backend (Jaeger, Zipkin, Datadog, etc.)
Supported SDKs
Use [all] to install everything. Only the SDKs your agent actually uses get activated.
| SDK | Install Extra | What It Covers |
|---|---|---|
| Anthropic | [anthropic] |
Anthropic API |
| OpenAI | [openai] |
OpenAI API (including compatible endpoints) |
| LangChain | [langchain] |
LangChain, LangGraph, any LangChain-wrapped model |
| CrewAI | [crewai] |
CrewAI multi-agent framework |
| LlamaIndex | [llamaindex] |
LlamaIndex agents and pipelines |
| Vertex AI | [vertexai] |
Google Vertex AI, Gemini models |
| Mistral AI | [mistral] |
Mistral API |
| AWS Bedrock | [bedrock] |
Claude, Llama, Titan via AWS |
| LiteLLM | [litellm] |
Unified proxy across 100+ LLM providers |
Web Framework Auto-Instrumentation
These are included in [all] and auto-detected by init():
| Framework | Install Extra | What It Does |
|---|---|---|
| FastAPI | [fastapi] |
Creates root span per HTTP request — all LLM calls in that request share one trace_id |
| Flask | [flask] |
Same trace grouping for Flask apps |
| Django | [django] |
Same trace grouping for Django apps |
Health check routes (/health, /healthz, /ready, /alive, /ping, /startup, /liveness, /readiness) are automatically excluded from tracing.
Configuration
| Env Variable | Default | Description |
|---|---|---|
SIGIL_AGENT_ID |
— | Required. Your agent's Sigil ID |
SIGIL_AGENT_VERSION |
0.1.0 |
Track deployments (set automatically by deploy workflow) |
SIGIL_COLLECTOR_URL |
— | Required. Your collector endpoint URL |
SIGIL_ENVIRONMENT |
production |
production, staging, development |
SIGIL_CONSOLE_EXPORT |
false |
Print spans to console for debugging |
SIGIL_DIVISION |
— | Business division (e.g., Sales, Engineering) |
SIGIL_RISK_CLASSIFICATION |
— | Agent risk level (low, medium, high) |
SIGIL_HOURS_SAVED |
— | Estimated hours saved per run |
Or pass config in code:
from sigil_telemetry import init, SigilConfig
init(SigilConfig(
agent_id="sigil-agent-my-agent",
environment="development",
console_export=True
))
Custom Spans
Track things beyond LLM calls (document parsing, tool use, etc.):
from sigil_telemetry import get_tracer, record_error
tracer = get_tracer()
with tracer.start_as_current_span("parse-contract") as span:
span.set_attribute("document.pages", 42)
try:
result = parse_pdf(file)
except Exception as e:
record_error(span, e)
raise
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file sigil_telemetry-0.2.0.tar.gz.
File metadata
- Download URL: sigil_telemetry-0.2.0.tar.gz
- Upload date:
- Size: 13.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/7.0.0 CPython/3.14.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
24c6358ea823dcf623f22335123615324f812c3faac2b41c01e0b4dd981faabf
|
|
| MD5 |
d0be4aa1b0feedc6236d1613a184f784
|
|
| BLAKE2b-256 |
94b838264f060eb4aea1265106eba02c3c5ff773f8241c4673480f9d6330e920
|
File details
Details for the file sigil_telemetry-0.2.0-py3-none-any.whl.
File metadata
- Download URL: sigil_telemetry-0.2.0-py3-none-any.whl
- Upload date:
- Size: 10.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/7.0.0 CPython/3.14.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e34267bb5e1d846d7808e822e53e014fd74c85b49aaa2d4c75ce48101d58fead
|
|
| MD5 |
bd35ee1e657a6d65971c844cf0eed0d2
|
|
| BLAKE2b-256 |
46df5821ac438445e5389001ba91175289a2cae11dc6ad8a020344aca4daae10
|