Module 6: Evaluation & Production Ops · 2.25h
01 · UNDERSTAND
Day 33 Theory — Tracing, OpenTelemetry and Reproducing Nondeterministic Bugs
Why logs are not enough
An agent request can cross many boundaries: API, model, retrieval, tools, databases and remote services. Separate log lines make it difficult to reconstruct one request across those components.
Distributed tracing links related operations into one trace.
Trace, span and context
A trace represents one end-to-end operation.
A span represents a timed operation inside that trace.
trace: support request
├─ span: classify
├─ span: retrieve
│ └─ span: vector query
├─ span: model call
└─ span: update ticket
Trace context propagates identifiers so downstream spans belong to the same trace.
OpenTelemetry
OpenTelemetry (OTel) provides vendor-neutral APIs, SDKs and semantic conventions for traces, metrics and logs.
Instrumentation records telemetry; exporters/collectors send it to an observability backend.
OTel is not itself the storage/UI product.
Useful span attributes
Record information that helps diagnose behavior without leaking sensitive content.
Examples:
- model/provider name,
- tool name,
- outcome category,
- retry count,
- retrieved document IDs,
- workflow step,
- token counts where available.
Avoid raw secrets, full PII or unrestricted prompt bodies.
Reproducing nondeterministic behavior
To investigate an AI failure, capture configuration that affects the result:
- prompt version,
- model/version,
- sampling settings,
- tool/retrieval configuration,
- input/eval case ID,
- application commit.
The goal is not always bit-for-bit identical output. It is to reproduce the conditions closely enough to understand the failure.
Correlation IDs versus trace IDs
A custom request ID can still be useful for product-level correlation. Trace IDs connect telemetry through tracing infrastructure. They can coexist.
Service Desk connection
Today the Service Desk becomes inspectable across model and non-model steps.
The principle is:
Trace the workflow as structured spans, propagate context across boundaries, and record the versions/configuration required to investigate probabilistic regressions without leaking sensitive data.
02 · APPLY
Lesson Overview
This is the applied companion for Day 33. Read DAY_33_THEORY.md first for the beginner-first teaching of Tracing and Reproducing Nondeterministic Bugs. Then use the real service-desk-day-33/ project to trace, run, debug, and explain the concept.
Service Desk Alignment
Day 33 adds Tracing and Reproducing Nondeterministic Bugs to the running Service Desk. Start with tracing/tracer.py, tracing/replay_engine.py, rag/tenant_rag.py, agent/mock_model.py, tools/ticket_tools.py, agent/service_desk_agent.py, then follow imports and tests to identify the actual runtime path.
Why This Topic Matters
The theory chapter explains why Tracing and Reproducing Nondeterministic Bugs is needed. Here the goal is evidence: identify where the capability is implemented, what observable behavior changes, and how the repository proves both success and failure behavior.
System Architecture
graph TD
A[Trace: agent_step] --> B[Span: llm_call]
A --> C[Span: tool_execution]
B --> D[Attribute: tokens_used=142]
C --> E[Attribute: tool_status=success]
Worked Code Example: OpenTelemetry Tracing
from opentelemetry import trace
from opentelemetry.sdk.trace import TracerProvider
from opentelemetry.sdk.trace.export import SimpleSpanProcessor, ConsoleSpanExporter
# Initialize OpenTelemetry Tracer
provider = TracerProvider()
provider.add_span_processor(SimpleSpanProcessor(ConsoleSpanExporter()))
trace.set_tracer_provider(provider)
tracer = trace.get_tracer("service_desk.agent")
def run_traced_agent_step(ticket_id: str, prompt: str):
with tracer.start_as_current_span("agent_step") as span:
span.set_attribute("ticket_id", ticket_id)
span.set_attribute("prompt_length", len(prompt))
with tracer.start_as_current_span("llm_call") as llm_span:
llm_span.set_attribute("model", "gpt-4o")
# Simulate LLM call
response = "Password reset instructions sent."
llm_span.set_attribute("tokens_used", 142)
return response
run_traced_agent_step("TCK-991", "Reset my password")
Code Walkthrough & Mechanics
Read tracing/tracer.py, tracing/replay_engine.py, rag/tenant_rag.py, agent/mock_model.py, tools/ticket_tools.py, agent/service_desk_agent.py, privacy/telemetry_scrubber.py, models.py with these theory sections beside you:
- Why logs are not enough — locate its implementation and evidence.
- Trace, span and context — locate its implementation and evidence.
- OpenTelemetry — locate its implementation and evidence.
- Useful span attributes — locate its implementation and evidence.
- Reproducing nondeterministic behavior — locate its implementation and evidence.
For each concept identify the real function/class/protocol boundary, its input/state, its observable result, and the assertion in tests/test_tracing.py that proves the behavior. If a concept has no implementation or evidence, record that as a gap rather than inventing one.
Common Mistakes & Debugging Guidance
Use the theory—not generic timeout or .env advice—to decide what can fail today.
Failure lens: revisit Useful span attributes, Reproducing nondeterministic behavior.
- Reproduce the smallest case that violates one of those expectations.
- Trace the real Day 33 modules until you find the first incorrect state/output/decision.
- Use
tests/test_tracing.pyas executable evidence. - Add a regression test if the failure is not already represented.
- Fix the smallest responsible boundary and rerun the relevant test before the full suite.
Your debugging explanation must name the topic-specific invariant that failed, not merely say “an exception occurred.”
Practical Lab Instructions
- Summarize these theory ideas before opening the implementation:
- Why logs are not enough
- Trace, span and context
- OpenTelemetry
- Useful span attributes
- Inspect the most relevant real Day 33 modules first:
service_desk/tracing/tracer.pyservice_desk/tracing/replay_engine.pyservice_desk/rag/tenant_rag.pyservice_desk/agent/mock_model.pyservice_desk/tools/ticket_tools.pyservice_desk/agent/service_desk_agent.pyservice_desk/privacy/telemetry_scrubber.pyservice_desk/models.py
- Inspect the automated evidence:
tests/test_tracing.py
- Establish the baseline:
cd service-desk-day-33 PYTHONPATH=. pytest tests/test_tracing.py -q - Trace one theory concept through the actual nested modules and tests.
- Run one success case and record input → mechanism → observable result.
- Exercise one topic-specific failure/boundary case and name the invariant that protects the system.
- Re-run the relevant tests and explain theory → implementation → evidence.
Done when: another student can reproduce your trace without relying on an invented sample.
Key Takeaways
- Be able to explain Why logs are not enough and point to its implementation/evidence in Day 33.
- Be able to explain Trace, span and context and point to its implementation/evidence in Day 33.
- Be able to explain OpenTelemetry and point to its implementation/evidence in Day 33.
Knowledge Check & Scenario Questions
- Concept: Using Why logs are not enough, explain the engineering problem Day 33 is solving without naming a framework as the answer.
- Mechanism: How does Trace, span and context appear in the real project? Start from
service_desk/tracing/tracer.pyand name the observable state/output/event that changes. - Failure: For OpenTelemetry, describe one incorrect implementation or boundary condition and the evidence you would expect in
tests/test_tracing.py. - Design review: Which assumption in today's design would you verify before reusing this implementation in a different production system?
Official References
- OpenTelemetry Python Official Documentation: https://opentelemetry.io/docs/languages/python/
- W3C Trace Context Specification: https://www.w3.org/TR/trace-context/
03 · EXPLAIN
Interview checkpoint
Explain one design decision from this lesson, the alternative you rejected, and the failure mode or evidence that justified your choice.