TypeScriptADK-TS

Langfuse Plugin

Add observability and tracing to your agents with Langfuse

The Langfuse Plugin automatically records everything your agent does — user messages, LLM calls, tool executions, errors, and token usage — and sends it to Langfuse for tracing and monitoring. No manual instrumentation needed.

This is especially useful for:

  • Debugging — see exactly what happened in a failed agent run
  • Token tracking — know how many tokens each model call uses
  • Performance monitoring — track latency across agents, tools, and LLM calls
  • Multi-agent visibility — trace nested agent hierarchies with parent-child spans

Quick start

import { AgentBuilder, LangfusePlugin } from "@iqai/adk";

const { runner } = await AgentBuilder.withModel("gpt-4o")
  .withDescription("My assistant")
  .withPlugins(
    new LangfusePlugin({
      publicKey: process.env.LANGFUSE_PUBLIC_KEY!,
      secretKey: process.env.LANGFUSE_SECRET_KEY!,
    }),
  )
  .build();

Your agent runs are now visible in the Langfuse dashboard.

Installation

The Langfuse SDK is a separate dependency:

pnpm add @iqai/adk langfuse

Usage

import { AgentBuilder, LangfusePlugin } from "@iqai/adk";

const { runner } = await AgentBuilder.withModel("gpt-4o")
  .withDescription("Calendar assistant")
  .withPlugins(
    new LangfusePlugin({
      publicKey: process.env.LANGFUSE_PUBLIC_KEY!,
      secretKey: process.env.LANGFUSE_SECRET_KEY!,
      flushAt: 5,
    }),
  )
  .build();
import { LlmAgent, LangfusePlugin } from "@iqai/adk";

const agent = new LlmAgent({
  name: "calendar_specialist",
  description: "Agent for calendar scheduling",
  plugins: [
    new LangfusePlugin({
      publicKey: process.env.LANGFUSE_PUBLIC_KEY!,
      secretKey: process.env.LANGFUSE_SECRET_KEY!,
    }),
  ],
});
import { AgentBuilder, LangfusePlugin } from "@iqai/adk";

const { runner } = await AgentBuilder.withModel("gpt-4o")
  .withDescription("Production agent")
  .withPlugins(
    new LangfusePlugin({
      publicKey: process.env.LANGFUSE_PUBLIC_KEY!,
      secretKey: process.env.LANGFUSE_SECRET_KEY!,
      baseUrl: "https://eu.cloud.langfuse.com", // EU region
      release: "v1.2.3",      // tag traces with version
      flushAt: 10,             // batch 10 events before sending
      flushInterval: 5000,     // or flush every 5s
    }),
  )
  .build();

Configuration

OptionTypeDefaultDescription
publicKeystringRequiredLangfuse public API key
secretKeystringRequiredLangfuse secret API key
baseUrlstring"https://us.cloud.langfuse.com"API endpoint (use EU URL or self-hosted)
releasestringundefinedTag traces with a version (e.g., git SHA)
flushAtnumber1Events to buffer before sending
flushIntervalnumber1000Max ms between flushes
namestring"langfuse_plugin"Plugin name for identification

For development, use flushAt: 1 (immediate visibility). For production, use flushAt: 10 and flushInterval: 5000 (fewer API calls).

What gets traced

The plugin hooks into every stage of the agent lifecycle:

WhatHooks usedWhat's captured
User messagesonUserMessageCallbackInput text
Agent executionbeforeAgent / afterAgentInput, output, models used, sub-agent hierarchy
LLM callsbeforeModel / afterModel / onModelErrorRequest, response, token usage, errors
Tool callsbeforeTool / afterTool / onToolErrorArguments, results, errors
Run lifecyclebeforeRun / afterRun / onEventStart/end, all emitted events

Flush and shutdown

By default, the client batches and flushes automatically. For explicit control:

// Force send all buffered data (doesn't shut down — can keep recording)
await langfusePlugin.flush();

// Gracefully shutdown after flushing (no more recording after this)
await langfusePlugin.close();

When to call manually:

  • Short-lived processes (serverless, scripts, cron) — call flush() then close() before exit
  • Long-running servers — you usually don't need to; the Runner calls close() during shutdown

Customizing serialization

The plugin converts complex Content and Event objects to structured logs. Override toPlainText if you need custom formatting:

class CustomLangfusePlugin extends LangfusePlugin {
  toPlainText(data: any): string {
    return super.toPlainText(data);
  }
}

Environment-specific configuration

import { LangfusePlugin } from "@iqai/adk";

const langfusePlugin = new LangfusePlugin(
  process.env.NODE_ENV === "production"
    ? {
        publicKey: process.env.LANGFUSE_PUBLIC_KEY!,
        secretKey: process.env.LANGFUSE_SECRET_KEY!,
        flushAt: 10,
        flushInterval: 5000,
      }
    : {
        publicKey: process.env.LANGFUSE_PUBLIC_KEY!,
        secretKey: process.env.LANGFUSE_SECRET_KEY!,
        flushAt: 1,
        flushInterval: 1000,
      },
);

Troubleshooting

IssueFix
No data in LangfuseVerify API keys. Check network connectivity. Ensure plugin is registered.
Missing tracesCall flush() then close() in short-lived processes before exit.
High flushAt buffering dataLower flushAt or flushInterval for faster delivery.
Auth errorsCheck keys are correct, have permissions, and match the right project.
Performance impactIncrease flushAt and flushInterval to batch more aggressively.

Next steps