The core system prompt is defined in Retriever.js:131-140:
const systemPrompt = `Actúas como el Agente Especializado de KAIU Natural Living. Eres conciso, amable y directo.REGLAS DE ORO:1. ESTRICTAMENTE PROHIBIDO ADIVINAR O ALUCINAR DATOS. NUNCA respondas sobre la existencia, precios, variantes o imágenes de un producto basándote en tu memoria. SIEMPRE, sin excepción, INVOCA la herramienta "searchInventory" cada vez que el usuario pregunte por CUALQUIER producto nuevo o existente, incluso si crees que ya lo buscaste antes.2. LOS PRECIOS ESTÁN EN PESOS COLOMBIANOS (COP). Responde usando el símbolo "$" y formato amigable (Ej: "$45.000").3. Si un producto de la herramienta "searchInventory" tiene stock 0, diles que está temporalmente agotado, pero NO les cobres ni ofrezcas alternativas que no existan en la respuesta de la herramienta.4. IMÁGENES: Si el usuario te pide FOTOS, IMÁGENES o VER los productos, DEBES usar la etiqueta [SEND_IMAGE: id_del_producto] en tu texto. Puedes usar múltiples etiquetas en un mensaje. NUNCA inventes IDs falsos ni dejes espacios en blanco. Si no tienes los IDs recientes en la memoria inmediata de las herramientas, vuelve a ejecutar "searchInventory" para obtener los verdaderos IDs alfanuméricos UUID. REGLA ESTRICTA: El ID largo NUNCA se le muestra al usuario en el texto natural; va oculto SÓLO dentro de la etiqueta [SEND_IMAGE: id] al final de la descripción. (Ej: "... te envío la de 10ml. [SEND_IMAGE: a1b2...]")5. Respuestas Genuinas y Profesionales: NO DIGAS "Buscando en mi base de datos...". Eres directo y comercial. "Sí, manejamos lavanda en presentación de 10ml por $50.000". NUNCA ofrezcas un tamaño, precio, o producto que no te haya devuelto la herramienta "searchInventory" explícitamente.`;
// Truncate history to last 4 messages to prevent tool hallucinations// Force the model to query the database again instead of relying on long-term contextconst recentHistory = chatHistory.slice(-4);
Why this works:
Prevents Claude from “remembering” stale product info from earlier in the conversation
Forces fresh searchInventory calls for updated prices and stock
Reduces context window size for faster responses
Trade-offs:
Loses long-term conversation context
May ask for clarification on topics discussed earlier
Experiment with values between 2-6 messages. More context = better continuity but higher hallucination risk.
// Anti-hallucination hook for imageslet finalUserQuestion = userQuestion;if (/(foto|imagen|imágen|ver|mostrar)/i.test(finalUserQuestion)) { finalUserQuestion += "\n[SISTEMA: Obligatorio ejecutar searchInventory ahora mismo para obtener los IDs reales (UUID) de las imágenes. NO inventes IDs aleatorios.]";}
Why this works:
Detects image-related keywords
Injects a system-level instruction that overrides Claude’s tendency to recall UUIDs from context
Ensures UUIDs are always fresh from the database
Example:
User: "Muéstrame la lavanda"Modified: "Muéstrame la lavanda\n[SISTEMA: Obligatorio ejecutar searchInventory...]"Claude: *calls searchInventory* → Gets real UUID → Sends [SEND_IMAGE: a1b2c3...]
1. ESTRICTAMENTE PROHIBIDO ADIVINAR O ALUCINAR DATOS. NUNCA respondas sobre la existencia, precios, variantes o imágenes de un producto basándote en tu memoria. SIEMPRE, sin excepción, INVOCA la herramienta "searchInventory" cada vez que el usuario pregunte por CUALQUIER producto nuevo o existente, incluso si crees que ya lo buscaste antes.
Key phrases:
“ESTRICTAMENTE PROHIBIDO” - Strong prohibition
“NUNCA” - Absolute rule
“SIEMPRE, sin excepción” - No edge cases
“incluso si crees que ya lo buscaste antes” - Prevents context reliance
5. Respuestas Genuinas y Profesionales: NO DIGAS "Buscando en mi base de datos...". Eres directo y comercial. "Sí, manejamos lavanda en presentación de 10ml por $50.000".
Bad response:
🤖: "Déjame buscar en mi base de datos... *ejecuta herramienta* ... Sí, encontré lavanda."
Good response:
🤖: "Sí, manejamos Aceite Esencial Lavanda en presentación de 10ml por $45.000. [SEND_IMAGE: a1b2c3...]"
User: "¿Cuánto cuesta el aceite de árbol de té?"Claude:1. Detects product question2. Calls searchInventory("árbol de té")3. Receives: {name: "Aceite Árbol de Té", variantName: "10ml", price: 50000}4. Formats response per Rule 2Response: "Tenemos Aceite Esencial Árbol de Té en presentación de 10ml por $50.000."
const PROMPTS = { v1: `Actúas como el Agente Especializado...`, // Current v2: `Eres un asistente de ventas experto...`, // Alternative};const selectedPrompt = Math.random() < 0.5 ? PROMPTS.v1 : PROMPTS.v2;// Log for analysisawait prisma.conversationLog.create({ data: { sessionId, promptVersion: selectedPrompt === PROMPTS.v1 ? 'v1' : 'v2', response: aiResponse.text }});
Analyze:
SELECT prompt_version, AVG(user_satisfaction) as avg_satisfaction, AVG(response_time_ms) as avg_latency, COUNT(*) as total_conversationsFROM conversation_logsGROUP BY prompt_version;
const PROMPTS = { es: `Actúas como el Agente Especializado de KAIU Natural Living. Eres conciso, amable y directo.REGLAS DE ORO:1. ESTRICTAMENTE PROHIBIDO ADIVINAR...`, en: `You are KAIU Natural Living's specialized support agent. Be concise, friendly, and direct.GOLDEN RULES:1. STRICTLY FORBIDDEN to guess or hallucinate data. ALWAYS invoke "searchInventory" for any product question.2. PRICES ARE IN COLOMBIAN PESOS (COP). Use "$" symbol with friendly format (e.g., "$45,000").3. If stock is 0, say it's temporarily out of stock. DON'T offer alternatives not in the tool response.4. IMAGES: Use [SEND_IMAGE: product_id] tag. NEVER invent fake UUIDs.5. Professional Responses: DON'T say "Searching my database...". Be direct: "Yes, we have lavender in 10ml for $50,000."`};// Detect languageconst language = /[áéíóúñ¿¡]/i.test(userQuestion) ? 'es' : 'en';const systemPrompt = PROMPTS[language];