Skip to content

Logging Strategies for Non-Deterministic Systems

Problem Statement

Logging agent activity is tricky. Logs grow huge (one log per token?). But without detail, debugging is impossible. How do we log enough to debug without logging too much?

Solution Approach

Structured Logging (not free-form text):

{
  "timestamp": "2026-05-29T10:00:00Z",
  "trace_id": "abc123",
  "agent_id": "cloud_inference",
  "event": "inference_started",
  "input_tokens": 150,
  "context_tokens": 250,
  "model": "claude-3-sonnet",
  "temperature": 0.7,
  "seed": 12345
}

Benefits: queryable, parseable, consistent format.

Log Levels for Agents:

  • DEBUG (verbose) — every token generated; not for production
  • INFO (standard) — agent invocation, decision, token count; use in production
  • WARN (alerts) — budget exceeded, timeout approaching, low confidence
  • ERROR — failures, invalid output, exception

Sampling & Truncation:

  • Log every agent invocation (decision checkpoints)
  • Sample token stream (every 100th token, or every decision point)
  • Truncate long outputs (log first 1000 chars + "...")
  • For retries: log with idempotency key (detect retries in logs)

Capturing Non-Determinism:

{
  "event": "inference_started",
  "model_version": "claude-3-sonnet-2025-05-01",
  "temperature": 0.7,
  "seed": 42,  // If present, enables replay
  "max_tokens": 500,
  "sampler": "nucleus_p=0.9"
}

When seed/sampler available, log them. Enables exact replay if needed.

Idempotency Keys in Logs:

{
  "event": "workflow_step",
  "idempotency_key": "user:alice:expense:12345:retry_2",
  "step": "approval",
  "attempt": 2,
  "retry_reason": "timeout"
}

Queries: "show all retries for this task" or "detect duplicate execution."

When to Use

  • Always use structured logging
  • Always log agent invocations (entry/exit + decision)
  • Log token counts + model parameters
  • Sample token stream (not every token)
  • Log only failure root causes; omit success path noise

Trade-offs

Strategy Log Volume Debug Visibility Storage Cost
Log every token Very high (10-100x normal) Very high (token-level) $$$$
Log decisions only Low (10-100 bytes per invocation) Medium (know decision, not why) $
Log + sample stream Medium (1-10KB per invocation) High (decision + sample of reasoning) $$
Structured + queries Medium High (queryable; easy filtering) $$

Recommendation: Structured logging + log decisions + sample token stream for complex decisions.

Observability Hooks

Queries: - "Show all agent invocations where output_tokens > budget" - "Group by agent_pool; count of each log level" - "Find all retries; show idempotency_key duplicates" - "Which agents have high ERROR rate?"

Metrics: - Error rate per agent - Retry frequency - Average log volume (MB/hour)

Example: Multi-Turn Conversation Logs

[
  {
    "turn": 1,
    "event": "user_input",
    "message": "Summarize Q3 sales",
    "token_count": 8
  },
  {
    "turn": 1,
    "event": "agent_invocation",
    "agent": "edge_analytics",
    "input_tokens": 250,
    "context_tokens": 100,
    "model": "claude-3-sonnet"
  },
  {
    "turn": 1,
    "event": "agent_response",
    "agent": "edge_analytics",
    "output_tokens": 145,
    "decision": "insufficient_context_forward_to_cloud",
    "confidence": 0.92
  },
  {
    "turn": 1,
    "event": "agent_invocation",
    "agent": "cloud_analytics",
    "input_tokens": 500,
    "database_query": "SELECT SUM(sales) FROM orders WHERE quarter=3",
    "query_latency_ms": 245
  },
  {
    "turn": 1,
    "event": "agent_response",
    "agent": "cloud_analytics",
    "output_tokens": 320,
    "decision": "return_to_edge",
    "output_preview": "Q3 sales: $12.5M, up 15% vs Q2..."
  }
]

References