PI-Conversacional: un servidor conversacional standalone
Nos propusimos demostrar que es posible poner una interfaz conversacional delante de cualquier sistema transaccional pre-existente sin modificarlo. Lo demostramos. El dominio hospitalario era el pretexto; la arquitectura de referencia, el objetivo.
Introducción
PI-Conversacional es un módulo conversacional standalone: el usuario interactúa con un sistema de información usando lenguaje natural — por texto o por voz — y recibe la respuesta en lenguaje natural, también disponible como audio. El sistema transaccional al que se conecta no sabe que este servidor existe, de modo que no requiere ajustes de ninguna índole.
La arquitectura tiene tres nodos con roles exclusivos. La VM de sistema de información aloja el sistema transaccional y el servidor MCP que expone sus operaciones como tools. La VM del servidor conversacional concentra toda la lógica de coordinación: la API Flask, el orquestador, el cliente MCP y el adaptador de Google Cloud. La máquina Windows corre el navegador con la interfaz de chat.
Cada mensaje del usuario sigue un flujo de tres pasos. Primero, el orquestador combina el mensaje, el historial de la conversación y la lista de operaciones disponibles en un prompt; el LLM devuelve un JSON con la intención reconocida y las entidades extraídas. Segundo, el cliente MCP invoca la tool correspondiente y recibe el resultado. Tercero, ese resultado se pasa a un segundo prompt y el LLM genera la respuesta en lenguaje natural.
El protocolo como bisagra
La pieza central de la arquitectura es el servidor MCP. Su rol es convertir el módulo de acceso a datos del sistema transaccional en un servicio de red que el orquestador puede invocar sin conocer ni la base de datos ni el lenguaje en que está escrito el sistema. El orquestador solo conoce el contrato MCP: nombres, descripciones y parámetros tipados de las tools disponibles.
La pregunta natural es por qué interponer MCP y no hacer que el orquestador consuma una API REST directamente. La respuesta tiene tres partes. El protocolo MCP incluye un mecanismo de descubrimiento (tools/list) que le permite al orquestador saber qué operaciones existen sin que nadie se lo haya programado explícitamente. El patrón de respuesta uniforme simplifica la ingeniería de prompts. Y el orquestador queda desacoplado del protocolo de backend: si el sistema transaccional cambia su interfaz, solo cambia el servidor MCP.
Hay además un escenario donde el servidor MCP no es una conveniencia sino la única opción: cuando el sistema transaccional no tiene interfaz de red. Una base de datos accedida solo por un módulo Python, un ERP con API interna, stored procedures. En esos casos, el servidor MCP es directamente la forma de exponerlos al mundo conversacional.
Lo que el LLM hizo por su cuenta
Al probar el sistema con consultas sobre datos del dominio hospitalario, el LLM se negó a responder en varios casos invocando políticas de privacidad. Esta negativa no viene de ningún componente del sistema: no está en el código, no está en los prompts. Es una decisión unilateral del modelo, producto de su entrenamiento en seguridad.
Esto tiene consecuencias para cualquier implementación real sobre dominios sensibles — salud, legales, financieros. La instrucción al LLM de no filtrar datos no autorizados no alcanza: el modelo puede negarse a responder incluso cuando el usuario tiene acceso legítimo. La solución completa requiere autenticación real, autorización por roles implementada en el orquestador, e inyección del contexto del usuario autenticado en los prompts.
El segundo problema es más insidioso. El sistema tiene un camino alternativo para mensajes que no corresponden a ninguna operación: cuando el LLM devuelve intención nula, el orquestador deriva al modo de asistente genérico. El problema aparece cuando el LLM falla en la clasificación: ante una consulta que sí corresponde a una operación del sistema, el modelo puede devolver intención nula. El orquestador no tiene forma de distinguir un nulo legítimo de uno espurio. El LLM responde en modo genérico sin acceso a datos, y genera una respuesta plausible pero inventada. La alucinación atraviesa toda la cadena sin que ningún componente la detecte.
Notas generales
El patrón que implementa PI-Conversacional es replicable sobre cualquier sistema transaccional que tenga un módulo de acceso a datos con funciones invocables. La secuencia es siempre la misma: identificar ese módulo, poner al lado un servidor MCP que lo importe y exponga sus funciones como tools, y conectar el orquestador conversacional al servidor MCP. El sistema transaccional no se modifica.
Las piezas que se usaron — FastMCP, LangChain, Flask, Vertex AI — se eligieron con cuidado de su ortogonalidad: cada una puede reemplazarse de forma independiente. El modelo de lenguaje es configurable por variable de entorno. El servidor MCP puede estar delante de cualquier backend. Los prompts y las intenciones están fuera del código. La ortogonalidad no es un atributo cosmético de la arquitectura. Es lo que hace que la arquitectura de referencia sea útil como punto de partida.
Stack base
El sistema corre sobre dos máquinas virtuales Ubuntu y una máquina Windows que actúa como cliente. El servidor conversacional usa Python con Flask y LangChain, detrás de nginx como reverse proxy con certificado SSL autofirmado. El servidor de información usa FastMCP sobre Python. El modelo de lenguaje es gemini-2.5-flash sobre Vertex AI, región us-central1. Los servicios de voz son Google Cloud Speech-to-Text y Text-to-Speech. La base de datos es SQLite en modo WAL con foreign keys habilitados. Todos los servicios corren como unidades systemd.