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.

Both SDKs are built on OpenTelemetry, so most of your code maps over directly.

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 a handful of bespoke decorators.
PathWhenEffort
A — Google ADK integrationADK is in use3 lines at startup
B — Auto-capture with OpenInferencelangfuse.openai, langfuse.langchain, Anthropic via instrumentorDrop one import, register one instrumentor
C — Manual translationBespoke @observe, start_as_current_observation, custom spansPer-call-site rename

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

Langfuse’s from langfuse.openai import OpenAI (and the langfuse.langchain.CallbackHandler) get replaced by an OpenInference instrumentor 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, -langchain, -bedrock, -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 replace from langfuse.openai import OpenAI with the stock import — the instrumentor wraps the client automatically:
from openai import OpenAI

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

Path C: Manual translation

For bespoke @observe() decorators, manual context managers, and identity helpers, translate per the tables.

Setup

LangfuseBento
pip install langfusepip install bentolabs-sdk
LANGFUSE_PUBLIC_KEY, LANGFUSE_SECRET_KEY, LANGFUSE_HOSTBENTOLABS_API_KEY
Langfuse(...) / get_client()bento.init(api_key=...)
langfuse.flush()bento.flush()

Decorators

LangfuseBento
@observe() on a handler@bento.interaction
@observe() on a tool@bento.tool
@observe(as_type="generation", ...)Replace body with bento.track_ai(...)

Multi-step / context managers

LangfuseBento
start_as_current_observation(as_type="span", ...)with bento.begin(...) as t:
Nested as_type="span" (tool)t.tool_span(...)

Identity

LangfuseBento
update_current_trace(...)bento.update_current_trace(...)
update_current_observation(...)bento.update_current_span(...)
propagate_attributes(...)bento.propagate_attributes(...)

What’s gone

LangfuseWhere it goes
langfuse.score(...)bento.update_current_trace(properties={"score_<name>": value})
langfuse.get_prompt(...)Move prompts to code or config; stash version in properties
Datasets / dataset runsNo primitive yet

Watch out for

  • session_id vs convo_id. Bento uses session_id everywhere except bento.track_ai, which uses convo_id. Same attribute under the hood.
  • metadataproperties. Direct rename. Langfuse magic keys (langfuse_user_id, etc.) don’t exist; use the real kwargs.
  • No OpenAI drop-in. Use Path B (OpenInference) instead of trying to find a from bento.openai import OpenAI equivalent.

Side-by-side

Langfuse
from langfuse import observe, propagate_attributes
from langfuse.openai import OpenAI

client = OpenAI()

@observe()
def answer(user_id, session_id, question):
    with propagate_attributes(user_id=user_id, session_id=session_id, tags=["prod"]):
        resp = client.chat.completions.create(
            model="gpt-4o-mini",
            messages=[{"role": "user", "content": question}],
            name="answer-llm",
        )
        return resp.choices[0].message.content
Bento
import bentolabs_sdk as bento
from openai import OpenAI

bento.init(api_key="bl_pk_...")
client = OpenAI()

@bento.interaction
def answer(user_id, session_id, question):
    with bento.propagate_attributes(user_id=user_id, session_id=session_id, tags=["prod"]):
        resp = client.chat.completions.create(
            model="gpt-4o-mini",
            messages=[{"role": "user", "content": question}],
        )
        reply = resp.choices[0].message.content
        bento.track_ai(
            event="answer-llm",
            model="gpt-4o-mini",
            provider="openai",
            input=question,
            output=reply,
        )
        return reply

See also

Configuration

init(), identity getters, env vars.

Tracking events

The bento.track_ai reference.