Skip to main content
GitHub

Providers

Auto-instrumentation for LLM providers.

Risicare automatically instruments popular LLM providers. In Python, add import risicare to your entrypoint and set RISICARE_API_KEY and RISICARE_TRACING=true, or call risicare.init(). In JavaScript, call init() and a patchX() function. You do not change your agent logic.

Streams

In Python, a traced stream=True call returns a proxy of the provider's stream object for OpenAI, Anthropic, Groq, Cerebras and Together, and a proxy of the response object for Google. It works as the provider's own object does: for, async for, with and async with, .response, the OpenAI stream() helper, and LangChain stream() / astream(). Ollama and Hugging Face return a plain generator, as they do without the SDK. Mistral streaming calls are not traced.

The span is sent when the stream is read to its end. A stream that you stop reading and drop, or never read, still sends a span, with status ok and no token counts.

Supported Providers

Python SDK

The Python SDK patches the provider libraries itself: there are no explicit patchX() calls (that is the JS SDK's model). A provider library that you import after init() is traced too: the import order does not matter.

JavaScript SDK

The JS SDK supports 12 native providers through explicit patchX() calls — Python's list with Vercel AI in place of Vertex AI, which the JS SDK does not support — plus 8 host-detected providers through patchOpenAI():

Additional JS providers (Google, Mistral, Groq, Cohere, Together, Ollama, HuggingFace, Cerebras, Bedrock) follow the same pattern — import from risicare/<provider> and call patchX(client). See the JS SDK reference for the full list.

How It Works

When you call risicare.init(), the SDK patches the supported provider libraries that are already imported:

import risicare
from openai import OpenAI
 
risicare.init()
 
client = OpenAI()
 
# This call is automatically traced
response = client.chat.completions.create(
    model="gpt-4o",
    messages=[{"role": "user", "content": "Hello!"}]
)

Captured Data

For each LLM call, the SDK captures:

FieldDescription
modelModel name (gpt-4o, claude-sonnet-5-5, etc.)
providerProvider name (openai, anthropic, etc.)
prompt_tokensInput token count
completion_tokensOutput token count
total_tokensTotal token count
latency_msRequest duration
temperatureSampling temperature
max_tokensMaximum output tokens
promptInput prompt (if trace_content=True)
completionOutput completion (if trace_content=True)

The Python SDK does not compute cost. The JavaScript SDK sends a cost from its own table. The server calculates cost from the token counts and its price table, and its cost wins for each model that the table knows. See Cost Tracking.

Manual Instrumentation

If auto-instrumentation doesn't meet your needs:

from risicare import trace, SpanKind
 
@trace(name="custom-llm-call", kind=SpanKind.LLM_CALL)
def call_custom_llm(prompt: str) -> str:
    # Your custom LLM call
    return response

You can also set provider and model attributes manually:

from risicare import get_tracer, SpanKind
 
tracer = get_tracer()
 
with tracer.start_span("custom-llm", kind=SpanKind.LLM_CALL) as span:
    span.set_attribute("llm.provider", "custom")
    span.set_attribute("llm.model", "my-model")
    response = call_llm(prompt)

Next Steps

Select a provider to see detailed integration guides: