Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.bentolabs.ai/llms.txt

Use this file to discover all available pages before exploring further.

Bento’s bento.track_ai was modeled on Raindrop’s, so most call shapes survive the port unchanged. The two real differences: Bento requires provider= on every call, and Bento’s native integration ships for Google ADK only — but you can preserve Raindrop’s auto-capture story for OpenAI / Anthropic / Bedrock by swapping to OpenInference instrumentors.

Migrate with an AI coding tool

Install the Bento docs skill so your AI coding tool has full context.

The three paths

Pick the smoothest applicable one and fall through. Most migrations end up using B for the bulk and C for the handful of bespoke decorators.
PathWhenEffort
A — Google ADK integrationADK is in use3 lines at startup
B — Auto-capture with OpenInferenceRaindrop’s auto_instrument=True captured OpenAI / Anthropic / Bedrock for youDrop the Raindrop init, register one instrumentor
C — Manual translation@raindrop.interaction / @raindrop.tool / @raindrop.task, bare track_ai callsPer-call-site rename, add provider=

Path A: Google ADK integration

If your app runs Google ADK agents, this captures every model call, tool call, and agent step automatically.
pip install "bentolabs-sdk[adk]"
import bentolabs_sdk as bento

bento.init(
    user_id=lambda: get_current_user_id(),
    session_id=lambda: get_current_session_id(),
)
bento.instrument()
That’s it. Full reference: Integrations.

Path B: Auto-capture with OpenInference

Raindrop’s auto_instrument=True (powered by Traceloop) wrapped OpenAI / Anthropic / Bedrock automatically. Bento preserves the same UX with OpenInference instrumentors registered against a BentoLabsSpanProcessor. Your call sites stay untouched — every LLM call is captured at the SDK level.
pip install openinference-instrumentation-openai
# Other libs as needed: -anthropic, -bedrock, -langchain, -llama-index
from openinference.instrumentation.openai import OpenAIInstrumentor
from opentelemetry.sdk.trace import TracerProvider
from opentelemetry import trace

from bentolabs_sdk import BentoLabsSpanProcessor

provider = TracerProvider()
provider.add_span_processor(BentoLabsSpanProcessor())
trace.set_tracer_provider(provider)

OpenAIInstrumentor().instrument(tracer_provider=provider)
Now drop raindrop.init(...) and the auto_instrument=True flag. Your existing OpenAI call sites are captured by the instrumentor:
from openai import OpenAI

client = OpenAI()
resp = client.chat.completions.create(model="gpt-4o", messages=[...])
# Bento captures the call. Nothing else to do.
For Anthropic / Bedrock: install the matching openinference-instrumentation-* and register it the same way. Full reference: OTel transport.

Path C: Manual translation

For bespoke decorators, manual track_ai calls, and identity helpers, translate per the tables.

Setup

RaindropBento
pip install raindrop-aipip install bentolabs-sdk
RAINDROP_WRITE_KEYBENTOLABS_API_KEY
import raindrop.analytics as raindropimport bentolabs_sdk as bento
raindrop.init(api_key=...)bento.init(api_key=...)
raindrop.init(auto_instrument=True, instruments={...})Use Path B instead
raindrop.flush() / raindrop.shutdown()bento.flush() / bento.shutdown()

Tracking

RaindropBento
raindrop.track_ai(...)bento.track_ai(...)add provider=
raindrop.begin(...)bento.begin(...)
interaction.track_tool(...)with interaction.tool_span(...) as ts:

Decorators

RaindropBento
@raindrop.interaction("X")@bento.interaction(event="X")
@raindrop.tool("X")@bento.tool(name="X")
@raindrop.task("X") / task_span(...)@bento.tool / tool_span(...) — no separate “task” kind

What’s gone

RaindropWhere it goes
raindrop.identify(user_id, traits)Move traits to properties= or init-time tags
raindrop.track_signal(...)bento.track_ai(event="feedback", properties={...})
raindrop.set_redact_pii(True)Scrub at the app boundary
Attachment(...) / add_attachments(...)Fold metadata into properties=; no binary support

Watch out for

  • provider= is required. Raindrop infers it via Traceloop; Bento does not. Bedrock model IDs need provider="aws_bedrock", not "anthropic".
  • identify() data is lost. No user-profile store in Bento. Port traits to per-call properties= or init-time tags.
  • OTel context. Bento detaches from any outer OTel context; Raindrop participates in it. Agent runs become standalone traces.

Side-by-side

Raindrop
import raindrop.analytics as raindrop

raindrop.init(os.getenv("RAINDROP_WRITE_KEY"), auto_instrument=True)

@raindrop.interaction("answer_question")
def answer(user_id, convo_id, question):
    raindrop.identify(user_id, {"plan": "pro"})

    resp = openai_client.chat.completions.create(
        model="gpt-4o", messages=[{"role": "user", "content": question}],
    )
    reply = resp.choices[0].message.content
    raindrop.track_ai(
        user_id=user_id, event="answer", convo_id=convo_id,
        model="gpt-4o", input=question, output=reply,
    )
    return reply
Bento
import bentolabs_sdk as bento

bento.init(api_key=os.getenv("BENTOLABS_API_KEY"))

@bento.interaction(event="answer_question")
def answer(user_id, convo_id, question):
    resp = openai_client.chat.completions.create(
        model="gpt-4o", messages=[{"role": "user", "content": question}],
    )
    reply = resp.choices[0].message.content
    bento.track_ai(
        event="answer",
        user_id=user_id,
        convo_id=convo_id,
        model="gpt-4o",
        provider="openai",                  # NEW — explicit
        input=question,
        output=reply,
        properties={"plan": "pro"},          # was raindrop.identify(...) traits
    )
    return reply

See also

Configuration

init(), identity getters, env vars.

Tracking events

The bento.track_ai reference.