Observability is optional and opt-in.
Skip the install → everything no-ops.
Enable it → you get traces, metrics, and LLM insights out of the box, ready for any OpenTelemetry backend.
- Zero overhead → no OTel? Your code still runs fine.
- Open standards → powered by OpenTelemetry, export anywhere that supports OTEL (Langfuse, Jaeger, Honeycomb…).
- One-liner API → add tracing with a simple
@observe. - LLM-aware → token usage + aggregation built in.
- Extensible → drop in your own exporters in a few lines.
Install with observability extras:
pip install -e ".[observability]"Initialize telemetry once in your entrypoint:
from utils.observability import observe, setup_telemetry, TelemetryTarget
setup_telemetry(service_name="standard-agent",target=TelemetryTarget.LANGFUSE) # or TelemetryTarget.OTELAdd tracing with a single decorator @observe:
@observe
def compute(x, y):
return x + y
@observe(llm=True)
def call_llm(messages):
return llm.completion(messages)
@observe(root=True)
def solve(goal):
...That’s it — traces flow automatically to your configured backend.
- Use
@observeto wrap functions. - Falls back to no-op if OpenTelemetry isn’t installed.
- Special modes:
@observe(llm=True)→ recordsprompt_tokens,completion_tokens,total_tokens.@observe(root=True)→ aggregates tokens across child calls (great for per-run or per-agent tracking).
- Call
setup_telemetry(service_name, target)once in your entrypoint. - Wires the OTel SDK and chosen exporter.
⚠️ If you skip this, spans are dropped silently (no errors).
-
Pluggable factories for sending data to backends:
langfuse.py→ usesLANGFUSE_PUBLIC_KEY,LANGFUSE_SECRET_KEY,LANGFUSE_HOST.otel.py→ uses standard OTel env vars (OTEL_EXPORTER_OTLP_ENDPOINT, etc).
Add a new exporter by:
- Creating
create_<name>_exporter()inexporters/<name>.py. - Exporting it in
exporters/__init__.py. - Extending
TelemetryTargetinotel_setup.py.
Contributions are welcome — exporters, docs, ideas, or improvements.
👉 Open an issue, submit a PR, or share feedback!