Lab 15 — OpenTelemetry Tracing
Architect emite spans OpenTelemetry siguiendo las GenAI Semantic Conventions. Cada span incluye modelo, tokens, coste y duración. Visualiza las trazas en Jaeger para debuggear y optimizar.
Concepto clave
Nivel: Avanzado
Duración estimada: 30 minutos. Features: OTel, telemetry.
Architect emite spans OpenTelemetry siguiendo las GenAI Semantic Conventions. Cada span incluye: modelo, tokens, coste, duración. La traza completa permite debuggear y optimizar ejecuciones.
Setup
mkdir -p ~/architect-labs/lab-15 && cd ~/architect-labs/lab-15
git init && mkdir -p src tests Levantar Jaeger para visualizar trazas
docker run -d --name jaeger \
-p 16686:16686 \
-p 4317:4317 \
-p 4318:4318 \
jaegertracing/all-in-one:latest
echo "Jaeger UI: http://localhost:16686" Proyecto de ejemplo
src/analyzer.py
def analyze_text(text):
words = text.split()
return {
"word_count": len(words),
"char_count": len(text),
"unique_words": len(set(w.lower() for w in words))
} tests/test_analyzer.py
from src.analyzer import analyze_text
def test_analyze():
result = analyze_text("hello world hello")
assert result["word_count"] == 3
assert result["unique_words"] == 2 git add -A && git commit -m "initial" Ejercicio 1: Configurar OTel
.architect.yaml
llm:
model: openai/gpt-4.1
api_base: http://localhost:4000/v1
api_key_env: LITELLM_API_KEY
telemetry:
enabled: true
exporter: otlp
endpoint: http://localhost:4317 Ejercicio 2: Ejecutar con trazas
architect run "Expande src/analyzer.py con funciones: \
sentiment_score(text) que devuelva -1..1, \
readability_score(text) con Flesch-Kincaid, \
extract_keywords(text, top_n=5). \
Añade tests para todas." \
--config .architect.yaml \
--confirm-mode yolo Ejercicio 3: Visualizar en Jaeger
Abre http://localhost:16686 en el navegador. Busca el servicio “architect” y encuentra la traza:
architect.session
├── architect.llm.call (model=gpt-4.1, tokens_in=X, tokens_out=Y, cost=$Z)
│ └── duration: Xms
├── architect.tool.read_file (path=src/analyzer.py)
├── architect.llm.call (model=gpt-4.1, ...)
├── architect.tool.write_file (path=src/analyzer.py)
├── architect.tool.write_file (path=tests/test_analyzer.py)
├── architect.llm.call (model=gpt-4.1, ...)
└── architect.tool.run_command (command=pytest) Consejo
En Jaeger puedes filtrar por duración para encontrar las llamadas LLM más lentas, o por tags para filtrar por modelo o coste.
Ejercicio 4: Trazas en Ralph Loop
architect loop "Corrige cualquier test que falle en tests/" \
--check "pytest tests/ -v" \
--config .architect.yaml \
--confirm-mode yolo \
--max-iterations 3 Cada iteración del Ralph Loop genera su propio span:
architect.session
├── architect.ralph.iteration.1
│ ├── architect.llm.call
│ ├── architect.tool.edit_file
│ └── architect.check (command=pytest, passed=false)
├── architect.ralph.iteration.2
│ ├── architect.llm.call
│ ├── architect.tool.edit_file
│ └── architect.check (command=pytest, passed=true)
└── architect.ralph.complete (iterations=2, success=true) Ejercicio 5: Exportar trazas a JSON
Alternativa sin Jaeger — exportar a archivo JSON:
# Alternativa: exportar a archivo JSON
telemetry:
enabled: true
exporter: json-file
endpoint: traces/ architect run "Añade docstrings a src/analyzer.py" \
--config .architect.yaml --confirm-mode yolo
ls traces/
# architect-trace-XXXXXX.json Cleanup
docker stop jaeger && docker rm jaeger Resumen
| Config | Descripción |
|---|---|
telemetry.enabled | Activa tracing |
telemetry.exporter | otlp, json-file, console |
telemetry.endpoint | URL del collector |
| Spans | session, llm.call, tool.*, check, ralph.iteration |
| Attributes | model, tokens, cost, duration, file_path |
Siguiente lab
Lab 16: Competitive Eval — Compara modelos con la misma tarea.