Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

agent-otel-tracing

The ReAct loop is a trace. Instrument an AI agent as a distributed trace and read its synthetic signals — tokens, cache hit rate, iterations, tool errors, latency — straight from the spans. Companion code for the book Código Sintético / Synthetic Code (Chapter 18).

🇬🇧 English · 🇪🇸 Español


English

The idea

You cannot govern what you cannot see. The discipline is reliability engineering: the four golden signals — latency, traffic, errors, saturation (Beyer et al., 2016) — and the three pillars (logs, metrics, traces). The open standard that unifies them is OpenTelemetry, and its central concept seems built for us: the ReAct loop is a trace. The task is the root span; each thought, model call and tool run is a child span with duration, attributes and result.

tarea.code-review                      [root span]  agent.prompt_version=reviewer-v3
├── llm.call          tokens.in/out, cache.read
├── tool.read_file    is_error=false
├── llm.call          tokens.in/out, cache.read
├── tool.run_tests    is_error=true        <-- a real signal, not a crash
└── llm.call          tokens.in/out, cache.read

Run it (no SDK, no collector)

The agent depends on a tiny Tracer port, so the whole loop runs against an in-memory tracer:

git clone https://github.com/sergioide007/agent-otel-tracing
cd agent-otel-tracing
python examples/trace_code_review.py    # trace tree + synthetic signals, offline
python -m unittest discover -s tests     # 6 tests, no SDK

For real traces, install the SDK and swap the adapter — the agent code does not change:

pip install opentelemetry-api opentelemetry-sdk
# use OpenTelemetryTracer instead of InMemoryTracer

Use it

from agent_tracing import TracedAgent, InMemoryTracer, ToolRegistry, extract_signals
from agent_tracing.adapters import FakeLlm  # or a real LlmPort

tracer = InMemoryTracer()                                  # or OpenTelemetryTracer()
agent = TracedAgent(llm, tools, tracer, prompt_version="reviewer-v3")
answer = agent.run("Review the PR diff for app.py")

signals = extract_signals(tracer.spans)
print(signals.as_dict())   # tokens, cache_hit_rate, iterations, tool_error_rate, latency

The attribute that pays for the whole trace

agent.prompt_version on the root span. When the eval pass rate drops on a Tuesday at 15:40, that one label says in seconds whether it was the new prompt, a silent provider model update, or a shift in the inputs. Without it: three days of archaeology.

LLMOps without ceremony (Chapter 18)

A team of three needs no platform: version the composite (prompt + context + tools + model id) in Git and tag it; test it in CI with the eval suite (eval-harness-minimal); deploy with a canary (a second consumer group on the same log — see kafka-agent-citizen); and watch drift with the evals themselves. Alerts compare against a moving baseline, never an absolute — in non-deterministic systems the change informs and the absolute value lies. The one absolute-value alert is the budget cut, and it does not ask permission.


Español

La idea

No se gobierna lo que no se ve. La disciplina madre es la ingeniería de fiabilidad: las cuatro señales doradas —latencia, tráfico, errores, saturación (Beyer et al., 2016)— y los tres pilares (logs, métricas, trazas). El estándar abierto que los unifica es OpenTelemetry, y su concepto central parece diseñado para nosotros: el bucle ReAct es una traza. La tarea es el span raíz; cada pensamiento, llamada al modelo y ejecución de herramienta, un span hijo con duración, atributos y resultado.

Ejecutarlo (sin SDK, sin colector)

git clone https://github.com/sergioide007/agent-otel-tracing
cd agent-otel-tracing
python examples/trace_code_review.py    # árbol de trazas + señales sintéticas, offline
python -m unittest discover -s tests     # 6 tests, sin SDK

Para trazas reales: pip install opentelemetry-api opentelemetry-sdk y usa OpenTelemetryTracer en vez de InMemoryTracer — el código del agente no cambia.

El atributo que paga toda la traza

agent.prompt_version en el span raíz. Cuando la tasa de evals cae un martes a las 15:40, esa etiqueta dice en segundos si fue el prompt nuevo, una actualización silenciosa del modelo del proveedor, o un cambio en las entradas. Sin ella: tres días de arqueología.

Las señales sintéticas (cap. 18)

tokens entrada/salida, tasa de acierto de caché, iteraciones por tarea, tasa de error de herramientas, latencia de la traza raíz — todas derivadas de la instrumentación que el agente ya emite. Las alertas comparan contra línea base móvil, nunca un valor absoluto; la única alerta de valor absoluto es el corte de presupuesto, y esa no pide permiso.


Article / Artículo

  • 🇬🇧 The ReAct loop is a trace: agentic observability — Medium
  • 🇪🇸 El bucle ReAct es una traza: observabilidad agéntica — LinkedIn

References / Referencias

  • Beyer, B. et al. (2016). Site Reliability Engineering. O'Reilly.
  • OpenTelemetry. OpenTelemetry documentation. opentelemetry.io/docs.
  • Sculley, D. et al. (2015). Hidden technical debt in machine learning systems. NeurIPS.
  • Breck, E. et al. (2017). The ML test score. IEEE Big Data.

License

MIT © Sergio Perez Ruiz. See LICENSE.

About

The ReAct loop is a trace. Instrument an AI agent as a distributed trace and read its synthetic signals — tokens, cache hit rate, iterations, tool errors, latency — straight from the spans.

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages