Launch Week 3: Five days of launches

Switch from Langfuse V2 to Confident AI

Move your traces from Langfuse SDK v2 to Confident AI with confident-trace. Your decorators, traces and trace fields map one to one.

Overview

Langfuse SDK v2 sends traces through its own ingestion API, not OpenTelemetry. confident-trace replaces it with standard OpenTelemetry spans. In Python, the decorator API maps one to one: init() replaces the OpenAI integration, @observe() becomes @span, and langfuse_context becomes update_trace() and update_span(). In TypeScript, the Langfuse v2 client's traces, spans and generations become span, updateTrace() and auto instrumentation.

In this guide, you will:

  • Pick a migration method: one copyable prompt for your coding agent, or manual.
  • Install confident-trace and replace the Langfuse keys with one CONFIDENT_API_KEY.
  • Replace the traced OpenAI calls with init() so auto instrumentation emits the model spans.
  • Rename @observe() to @span so every trace carries a name, an input and an output.
  • Move trace and observation updates onto update_trace() and update_span() so users, sessions, tags and metadata stay on your traces.
  • See what changes once the traces land in Confident AI: evals on every trace, datasets curated from production, alerts when quality drops.
$200 in migration credits, applied after your callBook a call, show us your current setup, and we map your traces, datasets and prompts together. Applied as a coupon to your first paid invoice, one per organization.Book a migration call

Prerequisites

  • A Project API Key, CONFIDENT_API_KEY (for example confident_us_proj_...). Retrieve yours here.
  • Python 3.10+ for the Python SDK, or Node.js 22+ for the TypeScript SDK.
  • Your existing Langfuse setup on SDK v2: Python langfuse>=2,<3 (run pip show langfuse) or TypeScript langfuse@2 (run npm ls langfuse). The before snippets below follow the Langfuse v2 SDKs, last released as Python 2.60.10 and TypeScript 2.8.0.

Choose a Migration Method

MethodWhat you doLangfuse SDK v2
Coding-agent migrationGive your coding assistant one prompt and review its changesSupported. See Switch in One Prompt below
Manual migrationMake the SDK changes yourself, step by stepSupported. See Switch Manually below
OpenTelemetry migrationAdd a Confident AI exporter and keep your Langfuse instrumentationNot available. Langfuse SDK v2 sends traces through the Langfuse ingestion API, not OpenTelemetry, so there is no span to redirect. It is available from Langfuse Python SDK v3 and TypeScript SDK v4

Switch in One Prompt

Give the prompt below to your coding assistant, such as Claude Code, Cursor or Codex, from the root of your repository. It finds your Langfuse integration, confirms the SDK version, makes the changes from this guide, and tells you what still needs your hands. Review the diff before you merge it.

Prompt
Migrate this codebase from Langfuse to Confident AI using confident-trace.

1. Find every Langfuse integration: imports of langfuse, @observe, langfuse_context, langfuse.openai, Langfuse() and new Langfuse() clients, langfuse.trace(), trace.span(), trace.generation(), the Langfuse CallbackHandler, and LANGFUSE_* environment variables.
2. Confirm the installed Langfuse SDK version with pip show langfuse or npm ls langfuse. This migration is for Langfuse SDK v2. If the major version is different, stop and tell me which version you found.
3. Make the changes from https://www.confident-ai.com/docs/guides/migrate-to-langfuse-alternative-v2:
   - install confident-trace and call init() once at startup
   - replace langfuse.openai, and generations around OpenAI calls, with the plain OpenAI client
   - rename @observe() to @span, and replace trace.span() with span in TypeScript
   - move langfuse_context.update_current_trace() and langfuse.trace() fields onto update_trace() (updateTrace() in TypeScript), with session_id as thread_id (threadId)
   - move update_current_observation() and span.update() onto update_span() (updateSpan())
   - keep generations for model calls auto instrumentation does not cover as LLM spans with update_span()
   - remove the Langfuse CallbackHandler from LangChain callbacks
   - replace the LANGFUSE_* variables with CONFIDENT_API_KEY, and the Langfuse flush calls with flush() / shutdown()
4. Preserve existing tracing behavior where possible: the same span names, nesting, inputs, outputs, users, sessions, tags and metadata.
5. Do not delete Langfuse prompt, dataset or score calls. List them for me instead.
6. When you are done, summarize every change and list anything that needs manual configuration, such as setting CONFIDENT_API_KEY, the EU endpoint, or model calls you could not map.

Switch Manually

  1. Install confident-trace

    One package. Provider SDKs stay optional peers. CONFIDENT_API_KEY replaces the Langfuse public key, secret key and host. For the EU region, also set CONFIDENT_OTEL_ENDPOINT=https://eu.otel.confident-ai.com/v1/traces.

    pip uninstall langfuse
    pip install confident-trace
    export CONFIDENT_API_KEY=...
    # replaces LANGFUSE_PUBLIC_KEY, LANGFUSE_SECRET_KEY, LANGFUSE_HOST
  2. Replace the traced OpenAI calls with init()

    In Python, drop the Langfuse import of OpenAI. In TypeScript, Langfuse v2 has no OpenAI integration, so you wrapped each call in a generation. Either way, auto instrumentation now emits the span from the plain client, with the model, messages and token usage.

    from langfuse.openai import openai
    
    response = openai.chat.completions.create(
        model="gpt-4.1-mini",
        messages=[{"role": "user", "content": "Hello"}],
    )
  3. Rename @observe() to @span

    Same shape. Return values and exceptions pass through, and nested traced functions still nest. In TypeScript, Langfuse v2 has no decorator, so a trace.span() you opened and ended by hand becomes a span function.

    from langfuse.decorators import observe
    
    @observe()
    def answer(question: str) -> str:
        return openai.chat.completions.create(
            model="gpt-4.1-mini",
            messages=[{"role": "user", "content": question}],
        ).choices[0].message.content

    @observe(name="...") becomes @span(name="...").

  4. Move trace and observation updates onto update_trace() and update_span()

    langfuse_context.update_current_trace() becomes update_trace(), and session_id becomes thread_id. langfuse_context.update_current_observation() becomes update_span(). In TypeScript, the fields you passed to langfuse.trace() move onto updateTrace(), and span.update() becomes updateSpan().

    from langfuse.decorators import langfuse_context, observe
    
    @observe()
    def support_chat(question: str) -> str:
        langfuse_context.update_current_trace(
            name="support-chat",
            user_id="user-7",
            session_id="session-42",
            tags=["support"],
            metadata={"plan": "enterprise"},
        )
        langfuse_context.update_current_observation(metadata={"region": "EU"})
        return answer(question)

    A Python function decorated with @observe(as_type="generation"), or a TypeScript generation, around an OpenAI call is now redundant: auto instrumentation records the same model span. For model calls it does not cover, use an LLM span (@span(type="llm"), or withSpan({ type: "llm" }, fn) in TypeScript) and pass the model and token counts to update_span() (updateSpan()) where you passed model and usage before. For LangChain, remove the Langfuse CallbackHandler (or langfuse_context.get_current_langchain_handler()) from your callbacks. init() instruments LangChain directly.

Run your app once. The trace appears in your project's Observatory within seconds. If it does not, check that CONFIDENT_API_KEY is set in the same process and that the app flushes before it exits. flush() from confident-trace replaces langfuse_context.flush() in Python, and await tracing.shutdown() replaces await langfuse.shutdownAsync() in TypeScript.

Field Mapping

Langfuse v2confident-trace
@observe()@span
@observe(as_type="generation")Auto instrumentation, or @span(type="llm")
update_current_trace(name=...)update_trace(name=...)
update_current_trace(user_id=...)update_trace(user_id=...)
update_current_trace(session_id=...)update_trace(thread_id=...)
update_current_trace(tags=..., metadata=...)update_trace(tags=..., metadata=...)
update_current_trace(input=..., output=...)update_trace(input=..., output=...)
update_current_observation(input=..., output=..., metadata=...)update_span(input=..., output=..., metadata=...)
update_current_observation(model=...)update_span(model=...)
update_current_observation(usage_details={"input": ..., "output": ...})update_span(input_token_count=..., output_token_count=...)
langfuse_context.flush()flush()

What Changes

Tracing is where you start. Evals are where it pays off. Every trace gets a score. Low scores become dataset rows. Dataset rows become regression tests. Your next release ships against real production failures.

CapabilityLangfuseConfident AI
OpenTelemetry ingestionYesOTLP over HTTP and gRPC
Auto-instrumented providersOpenAI wrapper and LangChain callbackOpenAI, Anthropic, Google GenAI, Bedrock, 5 gateways, 16 frameworks
Built-in eval metricsManaged evaluators, custom scoring50+ research-backed metrics through DeepEval
Online evals on traces, spans and threadsTraces onlyYes
Quality-aware alerting on eval scoresSlack, webhook, GitHub ActionsEmail, Slack, Discord, Teams
Prompt and use case drift detectionNoYes
Automatic dataset curation from productionManual add to datasetIngestion tasks, filtered and tagged
Multi-turn simulationNoYes
Git-based prompt managementNoBranches, PRs, approvals, eval actions
Cross-functional workflows, no codeNoPMs and QA run evals over HTTP
Regression testing and CI gatesNoYes
Safety monitoringNoToxicity, bias, PII on production traffic

Migration Questions

Do I have to upgrade Langfuse first?

No. You move straight from Langfuse SDK v2 to confident-trace. There is no need to upgrade to Langfuse v3 or v4 on the way.

My Langfuse server is on v3. Does that change anything?

No. What matters is the SDK version in your app, not the Langfuse server version. On SDK v2, follow this guide.

Can I run both during the switch?

Yes. Langfuse v2 and confident-trace do not share a client, so both can trace the same app while you compare. Remove the Langfuse calls once you are ready to cut over.

What about my Langfuse datasets, prompts and scores?

We import them on the migration call. Langfuse exports through its public API and scheduled blob storage export. We map the result to Confident AI datasets, prompt versions and annotations.

How do I get the $200?

Book the call. After it, we apply a $200 coupon to your organization's first paid invoice. One reward per organization.

Is the TypeScript SDK ready?

The Python SDK is stable on PyPI. The TypeScript SDK is an alpha release on npm. The TypeScript snippets in this guide follow the alpha API.

Last updated on

Built byConfident AI