Series 5 - Bài 1: Observability cho Agent

Monitoring service thông thường đo latency và error rate. Agent cần biết tại sao LLM quyết định gì. Đây là sự khác biệt căn bản trong observability design.

Nghe bài viết này dưới dạng podcast

Khi service của bạn fail, bạn nhìn vào logs và thấy exception. Bạn biết cái gì fail.

Khi agent của bạn cho ra kết quả sai, logs thông thường không giúp được nhiều. Bạn thấy tool được gọi, thấy kết quả trả về — nhưng không biết tại sao LLM quyết định gọi tool đó, không biết tại sao nó bỏ qua context quan trọng, không biết tại sao nó chọn approach này thay vì approach kia.

Đây là sự khác biệt căn bản: service observability đo what happened, agent observability đo why it happened.

Tại sao standard metrics không đủ

Traditional service metrics:

  Latency:    P50: 120ms, P99: 450ms
  Error rate: 0.1%
  Throughput: 1,200 req/s
  CPU:        45%

  → Bạn biết system có healthy không
  → Nhưng không biết agent có làm đúng không

Agent-specific questions:

  Tại sao agent gọi read_file 3 lần cho cùng 1 file?
  Tại sao agent ignore constraint "không thêm deps"?
  Tại sao task này tốn 15 turns thay vì 5?
  Tại sao agent chọn approach A thay vì B?
  Token nào trong context đang drive decisions?

  → Không thể trả lời bằng latency/error rate
  → Cần reasoning trace

Reasoning Trace: Core của Agent Observability

Mọi LLM call cần được captured như một span đầy đủ:

Reasoning Span:

{
  span_id: "span_abc123",
  timestamp: "2025-05-25T10:30:15Z",
  type: "llm_call",

  input: {
    messages_count: 12,
    total_tokens: 8,450,
    // snapshot của messages[] — không full content
    // mà là summary để giảm storage
    context_summary: {
      system_prompt_tokens: 1200,
      history_turns: 8,
      tool_results_count: 4,
      current_message_preview: "Fix the loan validation..."
    }
  },

  output: {
    stop_reason: "tool_use",
    output_tokens: 145,
    decision: {
      type: "tool_use",
      tool: "read_file",
      rationale_preview: "Need to see current implementation..."
      // Nếu LLM có thinking/reasoning field
    }
  },

  metrics: {
    latency_ms: 1240,
    input_tokens: 8450,
    output_tokens: 145,
    cost_usd: 0.0127
  }
}

Tool Execution Spans

Mỗi tool call là một span riêng:

Tool Span:

{
  span_id: "span_def456",
  parent_span_id: "span_abc123",  // linked to LLM call
  type: "tool_execution",

  tool: "read_file",
  input: { path: "src/loan.service.ts" },

  output: {
    success: true,
    result_size_bytes: 8240,
    result_lines: 287
    // Không log full content — privacy và storage
  },

  metrics: {
    latency_ms: 45,
    file_size_bytes: 8240
  }
}

Trace Tree: Visualize agent reasoning

Một agent session nhìn như trace tree:

[Session: fix-loan-validation]
  ├── [Turn 1]
  │   ├── LLM Call (8,450 tokens → tool_use)
  │   │   └── Tool: read_file(loan.service.ts) → 45ms
  │   └── LLM Call (12,100 tokens → tool_use)
  │       └── Tool: read_file(loan.spec.ts) → 38ms
  │
  ├── [Turn 2]
  │   ├── LLM Call (18,500 tokens → tool_use)
  │   │   └── Tool: write_file(loan.service.ts) → confirmed → 52ms
  │   └── LLM Call (22,000 tokens → tool_use)
  │       └── Tool: run_command(npm test) → 2300ms
  │
  └── [Turn 3]
      └── LLM Call (25,400 tokens → end_turn)
          └── Response: "Completed refactor..."

Metrics:
  Total turns:      3
  Total LLM calls:  5
  Total tool calls: 4
  Total tokens:     86,450
  Total cost:       $0.13
  Total duration:   8.2s

Với trace tree, bạn thấy ngay: 5 LLM calls cho 3 turns, 2 read_file trước khi write — hợp lý. Nếu có 20 LLM calls mà chỉ 1 write, đó là signal có gì bất thường.

Metrics đặc thù cho Agent

Agent-specific metrics cần track:

  Efficiency metrics:
    turns_per_task          → agent có direct hay looping?
    tool_calls_per_turn     → có gọi tools không cần thiết?
    tokens_per_task         → cost indicator
    redundant_tool_calls    → cùng tool + cùng input > 1 lần

  Quality metrics:
    task_completion_rate    → agent hoàn thành task không?
    user_confirmation_rate  → user có approve actions không?
    rollback_rate           → action phải undo bao nhiêu?

  Reliability metrics:
    consecutive_errors      → agent có stuck không?
    timeout_rate            → task có hit timeout không?
    guardrail_triggers      → guardrails có fire không?

  Cost metrics:
    cost_per_task           → avg cost mỗi task
    token_efficiency        → output quality / tokens used
    model_distribution      → % calls trên mỗi model

Alerting: Khi nào cần alert

Alert thresholds (ví dụ):

  CRITICAL:
    consecutive_errors >= 3      → agent stuck
    task_timeout                 → task chạy quá lâu
    cost_per_task > $5.00        → runaway cost

  WARNING:
    turns_per_task > 20          → efficiency thấp
    redundant_tool_calls > 3     → looping behavior
    guardrail_triggers > 2       → permission violations

  INFO:
    session_start
    task_completion
    model_fallback_triggered     → primary model fail

Storage: Balance detail vs cost

Lưu full reasoning trace tốn storage. Cần balance:

Retention strategy:

  Hot storage (30 ngày):
    Full trace với all spans
    Searchable, fast query

  Warm storage (90 ngày):
    Aggregated metrics
    Session summaries
    Error details

  Cold storage (1 năm):
    Session metadata only
    Cost aggregations
    Audit trail

Cost optimization:
  Không log full message content (tốn kém)
  Log summaries và previews
  Sample verbose traces (10% full, 100% aggregated)

Trade-off: Full Observability vs Performance

Full tracing:
  + Complete picture của agent reasoning
  + Debug bất kỳ decision nào
  - Storage cost cao
  - Latency overhead ~5-10ms mỗi span
  - Privacy concerns (tool results có thể chứa PII)

Minimal logging:
  + Cheap, fast
  - Khó debug
  - Không biết tại sao agent fail

Production recommendation: Full tracing cho 10-20% sessions (sampling), minimal cho phần còn lại. Full tracing cho mọi session có error hoặc user report.

Kết luận

  • Agent observability cần reasoning trace, không chỉ latency/error rate.
  • Mỗi LLM call và tool execution là một span trong trace tree.
  • Agent-specific metrics: turns per task, redundant calls, cost per task, completion rate.
  • Alerting theo 3 levels: critical (stuck/runaway), warning (inefficiency), info (operational).
  • Balance storage cost với observability depth bằng sampling strategy.
  • Full tracing cho errors và sampled sessions — không full trace mọi thứ.

Chưa có bình luận

Để lại bình luận

Bình luận sẽ được phê duyệt trước khi hiển thị.

Nhận bài viết mới

Mình sẽ gửi email khi có bài mới. Không spam.