Skip to main content
GitHub

Overview

How Risicare's diagnosis engine works.

Risicare automatically diagnoses agent failures using a 4-stage LLM-powered pipeline.

How It Works

When an error occurs in your agent, Risicare:

  1. Detects the error from trace data
  2. Extracts relevant context (spans, messages, tool I/O)
  3. Classifies using the error taxonomy
  4. Suggests potential fixes
Error Detected → Context Extraction → Classification → Fix Suggestion
    (auto)           (100ms)            (1-2s)          (500ms)

Diagnosis Pipeline

Stage 1: Context Extraction

Extract relevant information from the error trace:

  • Error span and parent spans
  • Recent LLM prompts and completions
  • Tool inputs and outputs
  • Agent state and messages
  • Surrounding context (before/after)

Max context: 50 spans, 100K tokens

Stage 2: Taxonomy Classification

Classify the error using the 10-module taxonomy (154 error codes across 31 categories):

ModuleFocus Area
PERCEPTIONInput processing
REASONINGLogic and inference
TOOLTool execution
MEMORYState management
OUTPUTResponse generation
COORDINATIONWorkflow control
COMMUNICATIONInter-agent messages
ORCHESTRATIONLifecycle management
CONSENSUSAgreement protocols
RESOURCESShared resource access

Classification uses a heuristic-first approach: a pattern matcher with 379 rules attempts to classify the error before any LLM call. A regex match assigns a fixed confidence of 0.9 and the LLM step is skipped; if no rule matches, the error falls back to the LLM classifier. This keeps typical classification under 100ms and reduces LLM costs.

LLM fallback: meta-llama/Llama-3.3-70B-Instruct-Turbo via Together.AI (used only when no pattern matches). gpt-4o-mini is used instead only when an OpenAI key is configured (production has none).

Stage 3: Root Cause Analysis

Deep analysis of why the error occurred:

  • Identify contributing factors
  • Trace causal chain
  • Distinguish symptoms from causes
  • Assess severity and impact

Model: meta-llama/Llama-3.3-70B-Instruct-Turbo via Together.AI (detailed reasoning). When an OpenAI key is configured, gpt-4o is used instead as a fallback; production runs the Together.AI default.

Stage 4: Fix Suggestion

Recommend fixes based on the diagnosis:

  • Template-first: deterministic fix templates keyed by error_code are applied when one exists
  • LLM fallback: generate a new fix from the root cause when no template matches
  • Rank fixes by confidence (minimum 0.5 to be included)

Stored knowledge base is planned, not built

A persistent cross-diagnosis knowledge base (the knowledge_patterns / fix_templates tables) is planned but not yet implemented — those tables do not exist in production. Stage 4 today is template-first plus LLM fallback only.

Diagnosis Output

A completed diagnosis shows the error classification, root cause analysis, confidence score, and recommended fix:

{
  "diagnosis_id": "diag-abc123",
  "trace_id": "trace-xyz789",
  "error_code": "TOOL.EXECUTION.TIMEOUT",
  "module": "TOOL",
  "category": "EXECUTION",
  "subcategory": "TIMEOUT",
  "confidence": 0.92,
  "root_cause": {
    "summary": "External API timeout due to large payload",
    "factors": [
      "Payload size: 2.5MB exceeds typical 100KB",
      "No timeout configured on API call",
      "Single retry with no backoff"
    ],
    "evidence": []
  },
  "suggested_fixes": [
    {
      "type": "retry",
      "confidence": 0.85,
      "description": "Add exponential backoff retry",
      "config": {
        "max_retries": 3,
        "initial_delay_ms": 1000,
        "exponential_base": 2.0,
        "max_delay_ms": 30000,
        "jitter": true,
        "retry_on": []
      }
    },
    {
      "type": "parameter",
      "confidence": 0.70,
      "description": "Increase timeout to 60s",
      "config": {
        "timeout_ms": 60000
      }
    }
  ]
}

evidence is always empty

root_cause.evidence is shown above as [] because that is the only value the API can return. The diagnoses table has no evidence column, so the read path hardcodes an empty list — as it does for reasoning_chain. The root-cause analyzer can parse evidence out of the model response, but nothing persists it, so it never reaches the API. Do not build against these two fields.

Triggering Diagnosis

Automatic

Diagnosis runs automatically when:

  • Span has status: error
  • Error rate exceeds threshold
  • Latency exceeds P99 baseline

Reporting caught exceptions

The diagnosis pipeline auto-detects unhandled exceptions. For exceptions you catch in a try/except, use report_error() to feed them to the self-healing pipeline:

from risicare import report_error
 
try:
    result = tool.execute()
except ToolError as e:
    report_error(e)          # Triggers diagnosis → fix generation
    result = fallback()

report_error() never raises. Inside a traced context it records the error on the current span. Outside any trace it creates a standalone error span with automatic deduplication (same error type + message suppressed for 5 minutes).

Manual

Trigger diagnosis via API:

curl -X POST "https://app.risicare.ai/api/v1/diagnoses" \
  -H "Authorization: Bearer rsk-..." \
  -H "Content-Type: application/json" \
  -d '{"trace_id": "trace-xyz789", "span_id": "span-abc123"}'

Or from the dashboard:

  1. View trace detail
  2. Click "Diagnose"
  3. View diagnosis results

Diagnosis Caching

Similar errors use cached diagnoses:

  • Cache key: error_code + stack_trace_hash
  • Cache TTL: 24 hours
  • Cache hit rate: ~60% target (the cache is per-process in-memory and not shared across worker processes)

Performance

MetricTarget
Detection to diagnosis< 5s P50
Classification accuracy> 90%
Fix suggestion relevance> 80%
Cache hit rate> 50%

Next Steps