NAME

Langertha::Role::Langfuse - Langfuse observability integration

VERSION

version 0.202

SYNOPSIS

Langfuse is built into every Langertha engine. Just set the env vars:

export LANGFUSE_PUBLIC_KEY=pk-lf-...
export LANGFUSE_SECRET_KEY=sk-lf-...
export LANGFUSE_URL=http://localhost:3000   # optional, defaults to cloud

Then use any engine as normal — simple_chat is auto-traced:

use Langertha::Engine::OpenAI;

my $engine = Langertha::Engine::OpenAI->new(
    api_key => $ENV{OPENAI_API_KEY},
    model   => 'gpt-4o-mini',
);

my $response = $engine->simple_chat('Hello!');
$engine->langfuse_flush;  # send events to Langfuse

Or pass keys explicitly:

my $engine = Langertha::Engine::Anthropic->new(
    api_key             => $ENV{ANTHROPIC_API_KEY},
    langfuse_public_key => 'pk-lf-...',
    langfuse_secret_key => 'sk-lf-...',
    langfuse_url        => 'http://localhost:3000',
);

Manual traces for custom workflows:

my $trace_id = $engine->langfuse_trace(
    name  => 'my-workflow',
    input => { query => 'custom input' },
);

$engine->langfuse_generation(
    trace_id => $trace_id,
    name     => 'step-1',
    model    => 'gpt-4o',
    input    => 'prompt text',
    output   => 'response text',
    usage    => { input => 10, output => 5, total => 15 },
);

$engine->langfuse_flush;

DESCRIPTION

This role integrates Langertha engines with Langfuse, an open-source observability platform for LLM applications. It is composed into Langertha::Role::Chat, so every engine has Langfuse support built in.

Features:

  • Zero-config via environment variables

  • Auto-instrumentation of simple_chat calls

  • Manual trace and generation event creation

  • Batched event ingestion via Langfuse REST API

  • Basic Auth using public/secret key pair

  • Disabled by default — only active when both keys are set

Langfuse concepts:

  • Trace — Top-level unit of work (a request, a conversation turn)

  • Span — A grouping of work within a trace (an iteration, a tool call)

  • Generation — A single LLM call within a trace (with model, usage, timing)

Hierarchy: Traces contain spans and generations. Spans can nest via parent_observation_id. All observations can be updated after creation.

langfuse_public_key

Your Langfuse project public key. Auto-populated from LANGFUSE_PUBLIC_KEY environment variable if not passed.

langfuse_secret_key

Your Langfuse project secret key. Auto-populated from LANGFUSE_SECRET_KEY environment variable if not passed.

langfuse_url

Langfuse API URL. Defaults to LANGFUSE_URL env var, or https://cloud.langfuse.com if not set. Set this to your self-hosted instance URL (e.g. http://localhost:3000).

langfuse_enabled

Bool indicating whether Langfuse integration is active. Lazy — defaults to true when both public and secret keys are available (from constructor or environment variables).

langfuse_trace

my $trace_id = $engine->langfuse_trace(
    name        => 'my-trace',
    input       => { ... },
    output      => '...',
    metadata    => { ... },
    tags        => ['tag1', 'tag2'],
    user_id     => 'user-123',
    session_id  => 'session-abc',
    release     => '1.0.0',
    version     => '1',
    public      => 1,
    environment => 'production',
);

Creates a trace event. Returns the trace ID for linking generations and spans. Accepts optional tags, user_id, session_id, release, version, public, and environment fields. Calling with the same id upserts (updates) the trace.

langfuse_generation

$engine->langfuse_generation(
    trace_id              => $trace_id,
    name                  => 'chat',
    model                 => 'gpt-4o',
    input                 => '...',
    output                => '...',
    usage                 => { input => 10, output => 5, total => 15 },
    start_time            => $iso_timestamp,
    end_time              => $iso_timestamp,
    parent_observation_id => $span_id,
    model_parameters      => { temperature => 0.7, max_tokens => 1000 },
    level                 => 'DEFAULT',
    status_message        => 'OK',
    version               => '1',
);

Creates a generation event linked to a trace. trace_id is required. Accepts optional parent_observation_id for nesting under a span, model_parameters, level (DEBUG/DEFAULT/WARNING/ERROR), status_message, and version.

langfuse_span

my $span_id = $engine->langfuse_span(
    trace_id              => $trace_id,
    name                  => 'my-span',
    input                 => { ... },
    output                => '...',
    start_time            => $iso_timestamp,
    end_time              => $iso_timestamp,
    parent_observation_id => $parent_span_id,
    metadata              => { ... },
    level                 => 'DEFAULT',
    status_message        => 'OK',
    version               => '1',
);

Creates a span event for grouping work within a trace. trace_id is required. Returns the span ID. Spans can be nested via parent_observation_id.

langfuse_update_trace

$engine->langfuse_update_trace(
    id       => $trace_id,
    output   => 'final result',
    metadata => { ... },
);

Updates a trace by upserting with the same id. Uses trace-create event type (Langfuse upserts on matching body ID). id is required.

langfuse_update_span

$engine->langfuse_update_span(
    id       => $span_id,
    end_time => $iso_timestamp,
    output   => { ... },
);

Updates an existing span. id is required. Use this to set end_time and output after the span's work completes.

langfuse_update_generation

$engine->langfuse_update_generation(
    id     => $gen_id,
    output => 'final response text',
    usage  => { input => 100, output => 50, total => 150 },
);

Updates an existing generation. id is required. Use this to add output, usage, and end_time after the LLM call completes.

langfuse_flush

$engine->langfuse_flush;

Sends all batched events to the Langfuse ingestion API. Clears the batch after sending. Warns on HTTP errors but does not die.

ENVIRONMENT VARIABLES

LANGFUSE_PUBLIC_KEY — Auto-populates langfuse_public_key
LANGFUSE_SECRET_KEY — Auto-populates langfuse_secret_key
LANGFUSE_URL — Auto-populates langfuse_url (default: https://cloud.langfuse.com)

SELF-HOSTING LANGFUSE

A ready-to-use Kubernetes manifest is included in the distribution:

kubectl apply -f ex/langfuse-k8s.yaml
kubectl -n langfuse port-forward svc/langfuse-web 3000:3000 &

export LANGFUSE_PUBLIC_KEY=pk-lf-langertha
export LANGFUSE_SECRET_KEY=sk-lf-langertha
export LANGFUSE_URL=http://localhost:3000

The manifest pre-creates a project with known API keys so you can send data immediately without going through the web UI.

Dashboard: http://localhost:3000 (login: langertha@test.invalid / langertha)

GETTING LANGFUSE KEYS

For Langfuse Cloud, sign up at https://langfuse.com/ and generate API keys in your project settings.

SEE ALSO

SUPPORT

Issues

Please report bugs and feature requests on GitHub at https://github.com/Getty/langertha/issues.

CONTRIBUTING

Contributions are welcome! Please fork the repository and submit a pull request.

AUTHOR

Torsten Raudssus <torsten@raudssus.de> https://raudss.us/

COPYRIGHT AND LICENSE

This software is copyright (c) 2026 by Torsten Raudssus.

This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself.