Conversación de Chat
Mensaje de Prompt de IA
"Eres un asistente de viajes profesional. Operas en tres fases distintas y debes seguir reglas de formato estrictas para cada una.
Por favor, mantén la conversación con el usuario, saluda y muestra el botón según la solicitud del usuario.
FASE 1: Descubrimiento de Países
Desencadenante: Saludo inicial.
Acción: Llamar a get_destinations.
Formato: Comenzar con [TYPE:DESTINATION], seguido de un saludo, luego el JSON sin procesar […].
FASE 2: Descubrimiento de Ciudades
Desencadenante: El usuario selecciona un país.
Acción: Llamar a get_cities.
Formato: Comenzar con [TYPE:CITY], seguido de una breve solicitud de selección, luego el JSON sin procesar […].
FASE 3: Descubrimiento de Paquetes
Desencadenante: El usuario selecciona una ciudad.
Acción: Llamar a tour_packages usando el valor de carga útil.
Instrucción para Obtener ID de Ciudad: Cuando el usuario selecciona una ciudad, recibirás un mensaje con un valor de carga útil. Esta carga útil es el term_id para esa ciudad. Debes usar este valor específico al llamar a la herramienta tour_packages. Si no tienes un term_id, pide al usuario que aclare su selección de ciudad.
Formato: Comenzar con [TYPE:PACKAGES], seguido de una breve confirmación, luego el JSON sin procesar […].
PROTOCOLOS CRÍTICOS:
ENCARPETADOS DE ENRUTAMIENTO: Cada mensaje DEBE comenzar con [TYPE:DESTINATION], [TYPE:CITY], o [TYPE:PACKAGES].
SIN RESÚMENES: Nunca escribas listas conversacionales ni conteos. Solo proporciona la etiqueta, un saludo breve y el JSON sin procesar.
LEGIBLE POR MÁQUINA: El JSON […] debe ser la última parte de cada mensaje.
USO DE HERRAMIENTAS: Siempre usa las herramientas proporcionadas para obtener datos. Nunca improvises paquetes o ciudades."
IMPORTANTE:
- Devuelve SOLO JSON válido
- NO incluyas explicaciones
- NO escapes comillas
- NO incluyas [TYPE:…] dentro del JSON
- El resultado debe ser directamente procesable por JSON.parse
Flujo de Trabajo
Analizador Global
const rawOutput = $input.first().json.output || “”;
// =========================
// Ayudante: Devolución estándar
// =========================
function formatResponse(data) {
return [{ json: data }];
}
// =========================
// Detectar TYPE
// =========================
function detectType(text) {
if (text.includes(“[TYPE:DESTINATION]”)) return “DESTINATION”;
if (text.includes(“[TYPE:CITY]”)) return “CITY”;
if (text.includes(“[TYPE:PACKAGES]”)) return “PACKAGES”;
return null;
}
// =========================
// Extraer JSON LIMPIO
// =========================
function extractJSONArray(text) {
if (!text) return null;
// Eliminar etiquetas TYPE
let cleaned = text.replace(/\[TYPE:[A-Z]+\]/g, "").trim();
// Eliminar marcador de posición
if (cleaned.includes("[...]")) return null;
// Obtener límites de JSON
const start = cleaned.indexOf('[');
const end = cleaned.lastIndexOf(']');
if (start === -1 || end === -1) return null;
let jsonString = cleaned.substring(start, end + 1);
// 🔥 Corregir problemas comunes de IA
jsonString = jsonString
.replace(/\\\//g, "/") // corregir barras invertidas escapadas
.replace(/;\s*$/, "") // eliminar punto y coma al final
.trim();
try {
let parsed = JSON.parse(jsonString);
// Manejar JSON doblemente codificado
if (typeof parsed === "string") {
parsed = JSON.parse(parsed);
}
return parsed;
} catch (e) {
throw new Error("Falha al Analizar JSON:\n" + jsonString);
}
}
// =========================
// PRINCIPAL
// =========================
const type = detectType(rawOutput);
const parsed = extractJSONArray(rawOutput);
// =========================
// DESTINATION
// =========================
if (type === “DESTINATION” && parsed) {
return formatResponse({
recipient: { id: “123456” },
message: {
text: “Selecciona un país:”,
quick_replies: parsed[0].data.map(i => ({
content_type: “text”,
title: i.destination,
payload: i.id
}))
}
});
}
// =========================
// CITY
// =========================
if (type === “CITY” && parsed) {
return formatResponse({
recipient: { id: “123456” },
message: {
text: “Selecciona una ciudad:”,
quick_replies: parsed[0].data.map(i => ({
content_type: “text”,
title: i.city || i.name,
payload: i.id
}))
}
});
}
// =========================
// PACKAGES
// =========================
if (type === “PACKAGES” && parsed) {
const packages = parsed[0].data;
const elements = packages.map(pkg => ({
title: pkg.title,
subtitle: pkg.subtitle || "Mejor paquete de tour disponible",
image_url: pkg.image_url,
buttons: (pkg.buttons || []).map(btn => ({
type: btn.type === "web_url" ? "web_url" : "postback",
title: btn.title,
url: btn.url,
payload: btn.payload
}))
}));
return formatResponse({
recipient: { id: "123456" },
message: {
attachment: {
type: "template",
payload: {
template_type: "generic",
elements: elements
}
}
}
});
}
// =========================
// ALTERNATIVA
// =========================
return formatResponse({
message: {
text: rawOutput || “Ninguna respuesta disponible.”
}
});
Mis Preguntas
- Me gustaría tener la conversación también y el Agente de IA buscará por sí mismo y dará los resultados.
- Actualmente solo funciona según el clic del botón y la carga útil.
- Después de que el usuario haga clic en los detalles del programa, la IA obtendrá datos solo para ese paquete y mantendrá la conversación.
Para que todo funcione, por favor sugiéreme cómo hacer el flujo de trabajo y cómo diseñar el sistema, cuántos Agentes de IA necesito usar y cómo le digo al flujo de trabajo qué herramienta usar cuándo sea necesario.
Por favor ayúdame a hacer una lluvia de ideas o guíame, ¡gracias!



