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 langfuseUsage
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
| Option | Type | Default | Description |
|---|---|---|---|
publicKey | string | Required | Langfuse public API key |
secretKey | string | Required | Langfuse secret API key |
baseUrl | string | "https://us.cloud.langfuse.com" | API endpoint (use EU URL or self-hosted) |
release | string | undefined | Tag traces with a version (e.g., git SHA) |
flushAt | number | 1 | Events to buffer before sending |
flushInterval | number | 1000 | Max ms between flushes |
name | string | "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:
| What | Hooks used | What's captured |
|---|---|---|
| User messages | onUserMessageCallback | Input text |
| Agent execution | beforeAgent / afterAgent | Input, output, models used, sub-agent hierarchy |
| LLM calls | beforeModel / afterModel / onModelError | Request, response, token usage, errors |
| Tool calls | beforeTool / afterTool / onToolError | Arguments, results, errors |
| Run lifecycle | beforeRun / afterRun / onEvent | Start/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()thenclose()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
| Issue | Fix |
|---|---|
| No data in Langfuse | Verify API keys. Check network connectivity. Ensure plugin is registered. |
| Missing traces | Call flush() then close() in short-lived processes before exit. |
High flushAt buffering data | Lower flushAt or flushInterval for faster delivery. |
| Auth errors | Check keys are correct, have permissions, and match the right project. |
| Performance impact | Increase flushAt and flushInterval to batch more aggressively. |