AI Agents Trong Production
Observability, tracing, evaluation và quản lý chi phí khi deploy agent thực tế
Thách Thức Production
Chạy agent ở local thì dễ. Chạy ở production thì khác:
- Observability: Agent đang làm gì? Tại sao nó chọn tool này?
- Cost: Mỗi LLM call tốn tiền. Multi-step agents = nhiều calls
- Latency: Users không muốn đợi 30 giây cho mỗi response
- Reliability: Agent fail rate bao nhiêu? Recovery strategy?
Tracing & Observability
Trace Anatomy
Trace (1 user request)
├── Span: User input processing
├── Span: LLM call #1 (planning)
│ ├── Token usage: 500 input, 200 output
│ └── Duration: 1.2s
├── Span: Tool call: searchDocuments
│ └── Duration: 0.8s
├── Span: LLM call #2 (with tool results)
│ ├── Token usage: 1500 input, 300 output
│ └── Duration: 2.1s
└── Span: Response generation
Tích Hợp Langfuse
import { Langfuse } from "langfuse";
import { generateText } from "ai";
import { openai } from "@ai-sdk/openai";
const langfuse = new Langfuse({
publicKey: process.env.LANGFUSE_PUBLIC_KEY!,
secretKey: process.env.LANGFUSE_SECRET_KEY!,
baseUrl: process.env.LANGFUSE_BASE_URL
});
async function tracedAgent(userMessage: string, userId: string) {
// Tạo trace
const trace = langfuse.trace({
name: "agent-response",
userId,
metadata: { source: "web-app" }
});
// Span cho planning
const planSpan = trace.span({ name: "planning" });
const result = await generateText({
model: openai("gpt-4o-mini"),
tools: { /* ... */ },
maxSteps: 5,
prompt: userMessage,
// Callback cho mỗi step
onStepFinish: (step) => {
trace.span({
name: step.toolCalls?.[0]?.toolName || "llm-generation",
input: step.toolCalls?.[0]?.args,
output: step.toolResults?.[0]?.result,
metadata: {
tokenUsage: step.usage,
model: "gpt-4o-mini"
}
});
}
});
planSpan.end();
// Log final output
trace.generation({
name: "final-response",
input: userMessage,
output: result.text,
usage: {
promptTokens: result.usage.promptTokens,
completionTokens: result.usage.completionTokens
}
});
// Score quality (optional)
trace.score({ name: "response-quality", value: 0.9 });
await langfuse.shutdownAsync();
return result.text;
}
Key Metrics
Metrics Bắt Buộc
| Metric | Mô tả | Target |
|---|---|---|
| Latency P95 | 95th percentile response time | < 10s |
| Token Usage | Tokens/request trung bình | Monitor trend |
| Error Rate | % requests thất bại | < 5% |
| Tool Call Success | % tool calls thành công | > 95% |
| Cost per Request | Chi phí trung bình/request | Monitor trend |
Dashboard Setup
// Custom metrics tracking
interface AgentMetrics {
requestId: string;
userId: string;
timestamp: Date;
totalLatencyMs: number;
llmCalls: number;
toolCalls: number;
totalTokens: number;
estimatedCost: number;
success: boolean;
errorType?: string;
}
async function logMetrics(metrics: AgentMetrics) {
// Lưu vào Supabase cho dashboard
await supabase.from("agent_metrics").insert(metrics);
}
Cost Management
Token Cost Calculator
const PRICING = {
"gpt-4o": { input: 2.50 / 1_000_000, output: 10.00 / 1_000_000 },
"gpt-4o-mini": { input: 0.15 / 1_000_000, output: 0.60 / 1_000_000 }
};
function calculateCost(
model: keyof typeof PRICING,
inputTokens: number,
outputTokens: number
): number {
const pricing = PRICING[model];
return inputTokens * pricing.input + outputTokens * pricing.output;
}
Chiến Lược Giảm Cost
1. Model Routing
// Dùng model nhỏ cho tasks đơn giản
function selectModel(taskComplexity: "simple" | "medium" | "complex") {
switch (taskComplexity) {
case "simple": return openai("gpt-4o-mini");
case "medium": return openai("gpt-4o-mini");
case "complex": return openai("gpt-4o");
}
}
2. Prompt Caching
// Cache system prompts (OpenAI tự xử lý)
// Giảm input tokens bằng cách reuse prefix
const cachedSystemPrompt = `
[Dài, chi tiết system prompt]
Prompt này sẽ được cache sau lần gọi đầu tiên.
`;
3. Token Budget
// Giới hạn tokens cho mỗi request
const result = await generateText({
model: openai("gpt-4o-mini"),
maxTokens: 500, // Giới hạn output
maxSteps: 3, // Giới hạn vòng lặp
prompt: userMessage
});
Error Handling & Recovery
async function resilientAgent(message: string) {
const maxRetries = 3;
for (let attempt = 1; attempt <= maxRetries; attempt++) {
try {
const result = await generateText({
model: openai("gpt-4o-mini"),
prompt: message,
// Timeout
abortSignal: AbortSignal.timeout(30000)
});
return result.text;
} catch (error) {
console.error(`Attempt ${attempt} failed:`, error);
if (attempt === maxRetries) {
// Fallback response
return "Xin lỗi, tôi đang gặp sự cố. Vui lòng thử lại sau.";
}
// Exponential backoff
await new Promise(r => setTimeout(r, 1000 * Math.pow(2, attempt)));
}
}
}
Tổng Kết
- Tracing mọi bước của agent với Langfuse
- Monitor 5 metrics chính: latency, tokens, errors, tool success, cost
- Cost management: model routing, prompt caching, token budgets
- Error recovery: retries với exponential backoff, fallback responses
- Production agents cần observability first — bạn không thể fix cái bạn không thấy