| name | langfuse-cost-tuning |
| description | Monitor and optimize LLM costs using Langfuse analytics and dashboards.
Use when tracking LLM spending, identifying cost anomalies,
or implementing cost controls for AI applications.
Trigger with phrases like "langfuse costs", "LLM spending",
"track AI costs", "langfuse token usage", "optimize LLM budget".
|
| allowed-tools | Read, Write, Edit |
| version | 1.0.0 |
| license | MIT |
| author | Jeremy Longshore <jeremy@intentsolutions.io> |
Langfuse Cost Tuning
Overview
Track, analyze, and optimize LLM costs using Langfuse observability data.
Prerequisites
- Langfuse tracing with token usage
- Understanding of LLM pricing models
- Access to Langfuse analytics dashboard
LLM Cost Reference
| Model | Input (per 1M) | Output (per 1M) |
|---|
| GPT-4 Turbo | $10.00 | $30.00 |
| GPT-4o | $5.00 | $15.00 |
| GPT-4o-mini | $0.15 | $0.60 |
| GPT-3.5 Turbo | $0.50 | $1.50 |
| Claude 3 Opus | $15.00 | $75.00 |
| Claude 3 Sonnet | $3.00 | $15.00 |
| Claude 3 Haiku | $0.25 | $1.25 |
Instructions
Step 1: Track Token Usage in Generations
import { Langfuse } from "langfuse";
const langfuse = new Langfuse();
const MODEL_PRICING: Record<
string,
{ input: number; output: number }
> = {
"gpt-4-turbo": { input: 10.0, output: 30.0 },
"gpt-4o": { input: 5.0, output: 15.0 },
"gpt-4o-mini": { input: 0.15, output: 0.6 },
"gpt-3.5-turbo": { input: 0.5, output: 1.5 },
"claude-3-opus": { input: 15.0, output: 75.0 },
"claude-3-sonnet": { input: 3.0, output: 15.0 },
"claude-3-haiku": { input: 0.25, output: 1.25 },
};
function calculateCost(
model: ,
: ,
:
): {
pricing = [model] || { : , : };
inputCost = (promptTokens / ) * pricing.;
outputCost = (completionTokens / ) * pricing.;
inputCost + outputCost;
}
() {
generation = trace.({
: ,
model,
: messages,
});
response = openai...({
model,
messages,
});
usage = response.!;
cost = (model, usage., usage.);
generation.({
: response.[].,
: {
: usage.,
: usage.,
: usage.,
},
: {
: cost,
: model,
},
});
response;
}
Step 2: Create Cost Dashboard Queries
async function getCostAnalytics(days: number = 30) {
const langfuse = new Langfuse();
const fromDate = new Date();
fromDate.setDate(fromDate.getDate() - days);
const generations = await langfuse.fetchGenerations({
fromTimestamp: fromDate,
});
const costByModel: Record<string, number> = {};
const costByDay: Record<string, number> = {};
const tokensByModel: Record<string, { prompt: number; completion: number }> = {};
for (const gen of generations.data) {
const model = gen.model || "unknown";
const date = new Date(gen.startTime).toISOString().split()[];
cost = gen.?. || (
model,
gen.?. || ,
gen.?. ||
);
costByModel[model] = (costByModel[model] || ) + cost;
costByDay[date] = (costByDay[date] || ) + cost;
(!tokensByModel[model]) {
tokensByModel[model] = { : , : };
}
tokensByModel[model]. += gen.?. || ;
tokensByModel[model]. += gen.?. || ;
}
{
: .(costByModel).( a + b, ),
costByModel,
costByDay,
tokensByModel,
: generations..,
};
}
Step 3: Implement Cost Alerts
interface CostAlert {
type: "daily" | "hourly" | "per-request";
threshold: number;
action: "warn" | "block" | "notify";
}
const COST_ALERTS: CostAlert[] = [
{ type: "daily", threshold: 100, action: "warn" },
{ type: "daily", threshold: 500, action: "notify" },
{ type: "per-request", threshold: 1, action: "warn" },
];
class CostMonitor {
private hourlySpend: Map<string, number> = new Map();
private dailySpend: Map<string, number> = new Map();
trackCost(cost: number) {
const hourKey = new Date().().(, );
dayKey = ().().(, );
..(
hourKey,
(..(hourKey) || ) + cost
);
..(
dayKey,
(..(dayKey) || ) + cost
);
.(cost);
}
() {
dayKey = ().().(, );
dailyTotal = ..(dayKey) || ;
( alert ) {
: ;
(alert.) {
:
currentValue = dailyTotal;
;
:
currentValue = requestCost;
;
:
;
}
(currentValue >= alert.) {
.(alert, currentValue);
}
}
}
() {
message = ;
(alert.) {
:
.(message);
;
:
.(message);
;
:
();
}
}
() {
(process..!, {
: ,
: .({ : message }),
});
}
() {
dayKey = ().().(, );
{
: ..(dayKey) || ,
: - (..(dayKey) || ),
};
}
}
costMonitor = ();
Step 4: Implement Cost Optimization Strategies
interface ModelSelector {
selectModel(task: string, inputLength: number): string;
}
class CostOptimizedModelSelector implements ModelSelector {
selectModel(task: string, inputLength: number): string {
const simpleTasks = ["summarize", "classify", "extract"];
if (simpleTasks.some((t) => task.toLowerCase().includes(t))) {
return "gpt-4o-mini";
}
if (inputLength < 500) {
return "gpt-4o-mini";
}
const complexTasks = ["analyze", "reason", "code", "math"];
if (complexTasks.some((t) => task.toLowerCase().includes(t))) {
;
}
;
}
}
(): {
optimized = prompt.(, ).();
optimized = optimized.(, );
optimized;
}
responseCache = <, { : ; : }>();
(): <> {
cacheKey = ;
cached = responseCache.(cacheKey);
(cached && .() - cached..() < ttlMs) {
.();
cached.;
}
response = (prompt, model);
responseCache.(cacheKey, { response, : () });
response;
}
Step 5: Generate Cost Reports
async function generateCostReport(period: "daily" | "weekly" | "monthly") {
const days = period === "daily" ? 1 : period === "weekly" ? 7 : 30;
const analytics = await getCostAnalytics(days);
const report = `
# LLM Cost Report - ${period.charAt(0).toUpperCase() + period.slice(1)}
Generated: ${new Date().toISOString()}
## Summary
- Total Cost: $${analytics.totalCost.toFixed(2)}
- Total Generations: ${analytics.generationCount}
- Average Cost per Generation: $${(analytics.totalCost / analytics.generationCount).toFixed(4)}
## Cost by Model
${Object.entries(analytics.costByModel)
.sort(([, a], [, b]) => b - a)
.map(([model, cost]) => `- ${model}: $${cost.toFixed(2)}`)
.join("\n")}
## Token Usage by Model
${Object.entries(analytics.tokensByModel)
.map(
([model, tokens]) =>
`- ${model}: ${tokens.prompt.toLocaleString()} prompt, ${tokens.completion.toLocaleString()} completion`
)
.join("\n")}
## Recommendations
${generateRecommendations(analytics)}
`;
return report;
}
function (): {
: [] = [];
gpt4Cost = analytics.[] || ;
totalCost = analytics.;
(gpt4Cost > totalCost * ) {
recommendations.(
);
}
( [model, tokens] .(analytics.)) {
{ prompt, completion } = tokens ;
(completion > prompt * ) {
recommendations.(
);
}
}
recommendations. >
? recommendations.()
: ;
}
Output
- Token usage tracking in generations
- Cost analytics dashboard
- Real-time cost alerts
- Model selection optimization
- Caching and prompt optimization
- Automated cost reports
Cost Optimization Strategies
| Strategy | Potential Savings | Implementation Effort |
|---|
| Model downgrade | 50-90% | Low |
| Prompt optimization | 10-30% | Low |
| Response caching | 20-60% | Medium |
| Batch processing | 10-20% | Medium |
| Sampling | Variable | Medium |
Error Handling
| Issue | Cause | Solution |
|---|
| Missing usage data | SDK not capturing | Verify generation.end() includes usage |
| Inaccurate costs | Wrong pricing | Update MODEL_PRICING regularly |
| Budget exceeded | No alerts | Implement cost alerts |
| Report failures | API limits | Add pagination to fetchGenerations |
Resources
Next Steps
For reference architecture, see langfuse-reference-architecture.