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:
- Detects the error from trace data
- Extracts relevant context (spans, messages, tool I/O)
- Classifies using the error taxonomy
- 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):
| Module | Focus Area |
|---|---|
| PERCEPTION | Input processing |
| REASONING | Logic and inference |
| TOOL | Tool execution |
| MEMORY | State management |
| OUTPUT | Response generation |
| COORDINATION | Workflow control |
| COMMUNICATION | Inter-agent messages |
| ORCHESTRATION | Lifecycle management |
| CONSENSUS | Agreement protocols |
| RESOURCES | Shared 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_codeare 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:
- View trace detail
- Click "Diagnose"
- 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
| Metric | Target |
|---|---|
| Detection to diagnosis | < 5s P50 |
| Classification accuracy | > 90% |
| Fix suggestion relevance | > 80% |
| Cache hit rate | > 50% |