Auto-Tracing
Registra todas tus llamadas LLM automáticamente sin modificar tu código existente.
Cero configuración
No modificas tu código existente
Trazabilidad total
Todas las llamadas se registran
Métricas precisas
Timing, costos, errores capturados
Debugging simple
Ve qué pasó en cada conversación
Opción 1: Cliente con Tracing Integrado
La forma más simple. Usa el cliente de AstrApp que incluye tracing automático.
import { getAstrApp } from '@/lib/astrapp/client'
const cloudJars = getAstrApp()
// Crear cliente con tracing automatico
const llmClient = cloudJars.createTracedLLMClient(
'openai',
process.env.OPENAI_API_KEY!
)
// Hacer llamada (se registra automaticamente en Opik)
const response = await llmClient.chat({
model: 'gpt-4o',
messages: [
{ role: 'system', content: 'Eres un asistente de ventas.' },
{ role: 'user', content: '¿Cuanto cuesta el plan pro?' }
],
temperature: 0.7,
metadata: {
conversationId: 'conv-123',
userId: 'user-456'
}
})
// Trace creado automaticamente con:
// - Input: messages
// - Output: response content
// - Metadata: conversationId, userId, tokens, durationOpción 2: Envolver Función Existente
Si ya tienes código LLM funcionando, envuélvelo sin modificarlo.
import OpenAI from 'openai'
import { getAstrApp } from '@/lib/astrapp/client'
const openai = new OpenAI({ apiKey: process.env.OPENAI_API_KEY })
const cloudJars = getAstrApp()
// Tu funcion existente
async function generateSalesResponse(userMessage: string) {
const completion = await openai.chat.completions.create({
model: 'gpt-4o',
messages: [
{ role: 'system', content: 'Eres un bot de ventas.' },
{ role: 'user', content: userMessage }
]
})
return completion.choices[0].message.content
}
// Envolver con tracing (no modifica la funcion original)
const tracedGenerateSalesResponse = cloudJars.wrapWithTracing(
'sales-bot-response',
generateSalesResponse
)
// Usar normalmente (se registra automaticamente)
const response = await tracedGenerateSalesResponse('¿Tienen soporte 24/7?')Opción 3: Tracing Manual
Si necesitas control total sobre qué se registra.
import { traceLLMCall } from '@/lib/opik/auto-trace'
const params = {
model: 'gpt-4o',
messages: [
{ role: 'user', content: '¿Ofrecen trial gratuito?' }
],
temperature: 0.7,
metadata: {
conversationId: 'conv-999',
userSegment: 'enterprise'
}
}
const response = await traceLLMCall(
'trial-inquiry', // Nombre del trace
params, // Parametros
async () => {
// Tu logica personalizada
const result = await fetch('https://api.openai.com/v1/chat/completions', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${process.env.OPENAI_API_KEY}`
},
body: JSON.stringify({
model: params.model,
messages: params.messages,
temperature: params.temperature
})
})
return result.json()
},
['sales', 'trial-inquiry', 'enterprise'] // Tags
)Datos capturados automáticamente
nameNombre identificador
sales-bot-response
inputPrompt/mensajes enviados
{ messages: [...] }
outputRespuesta del modelo
{ content: "..." }
start_timeInicio de la llamada
2024-12-20T10:00:00Z
duration_msDuración en ms
1850
metadataDatos personalizados
{ conversationId, leadScore }
tagsEtiquetas para filtrar
['sales', 'gpt-4o']
usageTokens consumidos
{ prompt: 50, completion: 120 }
errorSi hubo error
{ error: true, message: "..." }
| Campo | Descripción | Ejemplo |
|---|---|---|
| name | Nombre identificador | sales-bot-response |
| input | Prompt/mensajes enviados | { messages: [...] } |
| output | Respuesta del modelo | { content: "..." } |
| start_time | Inicio de la llamada | 2024-12-20T10:00:00Z |
| duration_ms | Duración en ms | 1850 |
| metadata | Datos personalizados | { conversationId, leadScore } |
| tags | Etiquetas para filtrar | ['sales', 'gpt-4o'] |
| usage | Tokens consumidos | { prompt: 50, completion: 120 } |
| error | Si hubo error | { error: true, message: "..." } |
Mejores prácticas
Hacer
// Agregar metadata util
metadata: {
conversationId: 'conv-123', // Para rastrear conversaciones
userId: 'user-456', // Para analisis por usuario
leadScore: 0.85, // Para correlacionar calidad
intent: 'pricing_inquiry', // Para agrupar por tipo
source: 'website_chat' // Para analizar canales
}
// Usar tags descriptivos
tags: [
'sales', // Categoria general
'objection-handling', // Tipo especifico
'price-objection', // Subcategoria
'gpt-4o' // Modelo usado
]No hacer
// NUNCA registrar datos sensibles
metadata: {
creditCardNumber: '1234-5678-9012-3456', // NUNCA
password: 'secret123', // NUNCA
apiKey: 'sk-...' // NUNCA
}
// En su lugar, usar IDs hasheados
metadata: {
userId: 'user-hash-abc123', // ID hasheado
conversationId: 'conv-456', // Identificador
leadScore: 0.75 // Metrica
}Ver tus traces
Opción 1: Opik UI
Abre http://localhost:5173 en tu navegador. Ve a "Traces" y filtra por tags.
Opción 2: API de AstrApp
const cloudJars = getAstrApp()
// Ver todas las conversaciones (traces)
const conversations = await cloudJars.getConversations({
limit: 100
})
// Filtrar por outcome
const converted = await cloudJars.getConversations({
outcome: 'converted'
})Troubleshooting
Traces no aparecen en Opik
- 1.Verifica que Opik está corriendo:
docker-compose ps - 2.Revisa
.env.localtieneNEXT_PUBLIC_OPIK_URL - 3.Abre la consola del navegador y busca errores
Resumen
createTracedLLMClient()Nuevas integraciones
Ventaja: Más simple
wrapWithTracing()Código existente
Ventaja: No modifica funciones
traceLLMCall()Control fino
Ventaja: Máxima flexibilidad
| Método | Uso | Ventaja |
|---|---|---|
| createTracedLLMClient() | Nuevas integraciones | Más simple |
| wrapWithTracing() | Código existente | No modifica funciones |
| traceLLMCall() | Control fino | Máxima flexibilidad |
Recomendación: Usa createTracedLLMClient() para el 90% de los casos.
Siguiente
Métricas