Installation
Quick Start
What Gets Traced
The DSPy integration automatically captures:- Module calls — input kwargs, output text (from Prediction result), configured model name
- Token usage — prompt and completion tokens from
get_lm_usage()or theusageattribute - Finish reason — completion finish reason (e.g.
stop,length) extracted from the LM history - Errors — exception type and message captured in event properties, then re-raised
dspy.Predict, dspy.ChainOfThought, and custom dspy.Module subclasses.
Configuration
| Parameter | Type | Default | Description |
|---|---|---|---|
api_key | str | None | None | Raindrop API key. If omitted, telemetry is disabled. |
user_id | str | None | None | Associate all events with a user. |
convo_id | str | None | None | Group events into a conversation. |
project_id | str | None | None | Route events to a specific project (slug); omit for the default Production project. |
tracing_enabled | bool | True | Enable OpenTelemetry tracing. |
bypass_otel_for_tools | bool | True | Bypass OTEL instrumentation for tool calls. |
debug | bool | False | Enable debug logging (sets logger to DEBUG level). |
Projects
Route events to a specific project by passing its slug asproject_id:
project_id sets the X-Raindrop-Project-Id header on every event. Omit it (or pass "default") to use your org’s default Production project, which is the existing behavior. The same option is accepted by the create_raindrop_dspy(...) factory. Invalid slugs are ignored with a warning and no header is sent.
Multiple projects in one process
Available inraindrop-ai>=0.0.56. When one service runs several DSPy modules
that should report to different projects, create one RaindropDSPy wrapper
per project. Each wrapper owns its own raindrop.Raindrop client, so the two
route independently — there is no shared module-level state:
raindrop.Raindrop yourself and pass
it via client=:
Identifying Users
Useidentify() to associate a user with traits after initialization:
traits parameter accepts a dictionary with string, int, bool, or float values.
Tracking Signals
Usetrack_signal() to attach user feedback or edits to an AI event:
| Parameter | Type | Default | Description |
|---|---|---|---|
event_id | str | required | The event ID to associate the signal with. |
name | str | required | Signal name (e.g. "thumbs_up", "user_feedback"). |
signal_type | "default" | "feedback" | "edit" | "default" | Signal type. |
timestamp | str | None | None | Optional ISO-8601 timestamp. |
properties | dict | None | None | Optional extra properties. |
attachment_id | str | None | None | Optional attachment identifier. |
comment | str | None | None | Optional comment text. |
after | str | None | None | Optional “after” value for edit signals. |
sentiment | "POSITIVE" | "NEGATIVE" | None | None | Optional sentiment. |
Flushing and Shutdown
Always callshutdown() before your process exits to ensure all telemetry is shipped:
Finish Reason Tracking
The integration extractsfinish_reason from the DSPy LM history automatically.
After each call, it inspects dspy.settings.lm.history for the last response and
reads response.choices[0].finish_reason. The value (e.g. stop, length) is
included in event properties as dspy.finish_reason.
Token Tracking
Token usage is extracted from the DSPyPrediction result:
get_lm_usage()— returns{model: {prompt_tokens, completion_tokens}}. Tokens are summed across models if multiple LMs are used.usageattribute — fallback for older DSPy versions. Supports both dict and object formats.
ai.usage.prompt_tokens and ai.usage.completion_tokens.
Factory Function
Thecreate_raindrop_dspy factory function is available for backwards compatibility:
Async Support
DSPy modules with asyncforward methods are automatically detected and wrapped:
Captured Properties
Each event includes the following properties when available:| Property | Description |
|---|---|
ai.usage.prompt_tokens | Input token count |
ai.usage.completion_tokens | Output token count |
dspy.finish_reason | Completion finish reason (e.g. stop, length) |
error.type | Exception class name (on error) |
error.message | Exception message (on error) |