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).
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
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 SDKFor 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 InMemoryTracerfrom 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, latencyagent.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.
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.
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.
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 SDKPara trazas reales: pip install opentelemetry-api opentelemetry-sdk y usa
OpenTelemetryTracer en vez de InMemoryTracer — el código del agente no cambia.
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.
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.
- 🇬🇧 The ReAct loop is a trace: agentic observability — Medium
- 🇪🇸 El bucle ReAct es una traza: observabilidad agéntica — LinkedIn
- 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.
MIT © Sergio Perez Ruiz. See LICENSE.