Skip to main content

risicare

AI agent observability and error diagnosis for Python.

PyPI version Downloads Python License: MIT

Monitor your AI agents in production. Trace every LLM call, detect errors automatically, and get AI-generated fix suggestions — with a single init().

Quickstart

pip install risicare
import risicare
from openai import OpenAI

# Initialize — auto-instruments all detected LLM providers
risicare.init(
    api_key="rsk-...",
    endpoint="https://app.risicare.ai",
)

client = OpenAI()  # Automatically traced by risicare

@risicare.agent(name="research-agent")
def research(query: str) -> str:
    response = client.chat.completions.create(
        model="gpt-4",
        messages=[{"role": "user", "content": query}],
    )
    return response.choices[0].message.content

result = research("What is quantum computing?")
risicare.shutdown()

That's it. Your agent's LLM calls, latency, token usage, and costs now appear in the Risicare dashboard.

Prompt content is NOT captured by default

Since 0.2.1, trace_content defaults to False. Your prompts and completions stay in your process. Everything else — model, token counts, latency, cost, message roles, errors, and any attributes you set — is captured as normal, so the dashboard, cost tracking and error diagnosis all work unchanged.

To send prompt and completion text as well, opt in:

risicare.init(api_key="rsk-...", trace_content=True)
# or set RISICARE_TRACE_CONTENT=true

Upgrading from 0.2.0 or earlier? This is a behaviour change: content that used to be sent is no longer sent unless you opt in. In those versions the flag also did not work for content you set by hand — trace_content=False did not stop a span.set_attribute("gen_ai.prompt.0.content", ...) from reaching us. Both are fixed together.

When capture is off, content-bearing attributes are replaced with <risicare:content-omitted> rather than removed, so "no prompt was sent" stays distinguishable from "capture is off".

If you want content captured but redacted first, use the mask hook — it is independent of this switch and runs on every content-bearing field before export:

risicare.init(api_key="rsk-...", trace_content=True, mask=lambda key, value: ...)

Features

  • Auto-instrumentation — Detects and patches LLM providers on init(), zero code changes
  • 12 LLM providers — OpenAI, Anthropic, Google, Mistral, Groq, Cohere, Together, Ollama, HuggingFace, Cerebras, Bedrock, Vertex AI
  • 8 host-detected — DeepSeek, xAI, Fireworks, Baseten, Novita, BytePlus, vLLM, and any OpenAI-compatible API via base_url
  • 10 framework integrations — LangChain, LangGraph, CrewAI, AutoGen, Instructor, LlamaIndex, LiteLLM, DSPy, Pydantic AI, OpenAI Agents
  • Error Diagnosis (beta) — LLM-powered root cause analysis with fix suggestions; auto-apply not yet wired (see "Error Diagnosis" section below)
  • 13 built-in scorers — Faithfulness, relevance, toxicity, hallucination, and more
  • Streaming support — Full streaming trace enrichment with token counts
  • OpenTelemetry bridge — Compatible with existing OTel pipelines
  • Non-blocking — All telemetry is async, never slows your app

LLM Providers

# Auto-patching (default) — detects installed providers automatically
risicare.init(api_key="rsk-...", endpoint="https://app.risicare.ai")

# Disable auto-patching if needed
risicare.init(api_key="rsk-...", endpoint="https://app.risicare.ai", auto_patch=False)

All 12 native providers:

Provider Package Provider Package
OpenAI openai Anthropic anthropic
Google Gemini google-generativeai Mistral mistralai
Cohere cohere Groq groq
Together AI together Ollama ollama
AWS Bedrock boto3 Google Vertex AI google-cloud-aiplatform
Cerebras cerebras-cloud-sdk HuggingFace huggingface-hub

Plus 8 auto-detected via OpenAI base_url: DeepSeek, xAI, Fireworks, Baseten, Novita, BytePlus, vLLM, and any OpenAI-compatible API.

Framework Integrations

pip install risicare[langchain]    # LangChain + LangGraph
pip install risicare[crewai]       # CrewAI
pip install risicare[autogen]      # AutoGen
pip install risicare[instructor]   # Instructor
pip install risicare[litellm]      # LiteLLM
pip install risicare[dspy]         # DSPy
pip install risicare[pydantic-ai]  # Pydantic AI
pip install risicare[llamaindex]   # LlamaIndex
pip install risicare[all]          # Everything

Core API

import risicare

risicare.init(api_key, endpoint)            # Initialize (auto-patches providers)
risicare.shutdown(timeout_ms=5000)          # Flush pending spans and close

@risicare.agent(name="my-agent")            # Trace a function with agent identity
@risicare.trace                             # Trace any function (decorator or CM)
@risicare.session(session_id="sess-1")      # Group traces into user sessions

risicare.report_error(exception)            # Report caught errors for diagnosis
risicare.score(trace_id, "quality", 0.92)   # Record evaluation score [0.0-1.0]

risicare.enable() / risicare.disable()      # Runtime tracing control
risicare.is_enabled()                       # Check tracing status

Decision Phases

Structure your traces to see how your agent thinks, decides, and acts:

@risicare.agent(name="planner")
def plan(query: str):
    @risicare.trace_think
    def analyze():
        return llm.chat("Analyze this query...")

    @risicare.trace_decide
    def choose_action(analysis):
        return llm.chat("Pick the best action...")

    @risicare.trace_act
    def execute(action):
        return run_tool(action)

    analysis = analyze()
    action = choose_action(analysis)
    return execute(action)

Error Diagnosis

Beta status (2026-05): detect → diagnose → suggest is shipped and runs against Together.AI Llama-3.3-70B with a circuit-breaker / template-only fallback. Suggested fixes land in your dashboard as status=draft for human review. Automatic deployment, A/B rollout, and learning-from-outcomes (stages 4–6 in our docs) are in development and not yet wired in production. Treat this as AI-assisted error diagnosis today; auto-apply will follow.

When your agent fails, Risicare:

  1. Classifies the error (154 codes across TOOL, MEMORY, REASONING, OUTPUT, etc.)
  2. Diagnoses the root cause using AI analysis
  3. Generates a fix suggestion you can review in the dashboard and apply manually
try:
    result = my_agent(user_input)
except Exception as e:
    risicare.report_error(e)  # Triggers diagnosis pipeline; fix lands as draft for review

Scoring & Evaluation

# Custom scores
risicare.score(trace_id="tr-123", name="quality", value=0.92)

# 13 built-in scorers, runnable from the dashboard or POST /v1/evaluations:
#   RAG      faithfulness, answer_relevancy, context_precision,
#            context_recall, hallucination
#   Safety   toxicity, bias, pii_leakage
#   Agent    task_completion, tool_correctness, goal_accuracy
#   General  g_eval, factuality

OpenTelemetry

pip install risicare[otel]
risicare.init(api_key="rsk-...", otel_bridge=True)
# Compatible with any OTel-instrumented application

Known limitation — span loss during a backend outage

The SDK does not currently survive a sustained outage of the Risicare backend, and the loss is silent to your application (it is logged, but nothing raises and flush() will not fail your request path).

The HTTP exporter opens a circuit breaker after 5 consecutive failed export calls and holds it open for 60 seconds, returning failure immediately without touching the network. Queued spans get 3 re-queue attempts, which against an open breaker resolve in microseconds — so they are dropped — and for the remainder of the cooldown the SDK will not retry even after your backend is healthy again.

Measured, for a 1,000-span cohort emitted during the outage:

outage delivered
4 s 1000 / 1000
5 s 500 / 1000
6 s + 0 / 1000

The thresholds are counted in failed calls, not seconds — where the 5th consecutive failure falls in wall-clock time depends on your span rate and on how fast your endpoint fails. Treat the table as one measured shape, not a constant.

Nothing is lost on a clean shutdown(), and short blips that stay under the 5-failure threshold are fully survivable. Tracked as F-SDKBLIP-001.

A note on debug=True

debug=True attaches a console exporter in addition to any HTTP exporter. That exporter writes every span attribute to stdout with no redaction — the SDK performs none of its own, so prompts, completions and anything else you put in attributes go to your console verbatim. It is a local-development switch, not a diagnostic one.

If you are debugging a delivery problem ("spans are NOT reaching ..."), raise the SDK's logger instead. This prints the HTTP status and transport error and does not print span payloads:

import logging
logging.getLogger("risicare").setLevel(logging.DEBUG)

Measured for a failing export: the logger surfaces the transport error and emits no span payload, while debug=True emits the payload and no HTTP status.

Requirements

  • Python 3.10+

Documentation

Support

During the public beta, please file detailed reproduction steps for any SDK or platform issue — fast feedback shapes GA.

License

MIT

Release files for risicare 0.3.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for risicare 0.3.0
File Size Uploaded
risicare-0.3.0.tar.gz 313.1 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for risicare 0.3.0
File Interpreter ABI Platform
risicare-0.3.0-py3-none-any.whl Python 3 none any Details

Total release size: 571.9 kB

Release files / risicare-0.3.0.tar.gz

Download URL risicare-0.3.0.tar.gz
Size 313.1 kB
Tags Source
SHA-256 checksum
How to use checksums
da4b30416218e99bffd7025fd522c6eae131557c0c1397ec73eeef906f26afcc
BLAKE2b-256 checksum
How to use checksums
b49456e6787375dcd780146b219343125f29671bd1d75d49c23741e6f3e7f359
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.3

Release files / risicare-0.3.0-py3-none-any.whl

Download URL risicare-0.3.0-py3-none-any.whl
Size 258.8 kB
Tags Python 3
SHA-256 checksum
How to use checksums
cfac05d1d4342c141c9d153bc0311947c2525422adae4f98857dae204dc34783
BLAKE2b-256 checksum
How to use checksums
656b00961ba4a76897f374ca7944a5a8413bc1d6ef6f4d522ad023b86e1a63f2
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.3

Release history Release notifications | RSS feed

This release

0.3.0 This release

2 release files

0.2.2

2 release files

0.2.0

2 release files

0.1.14

2 release files

0.1.12

2 release files

0.1.11

2 release files

0.1.10

2 release files

0.1.9

2 release files

0.1.8

2 release files

0.1.7

2 release files

0.1.6

2 release files

0.1.5

2 release files

0.1.4

2 release files

0.1.3

2 release files

0.1.2

2 release files

0.1.1

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page