Agente Inteligente de Reservas con IA Trabajo Final de Máster
FoodLooker es un sistema de agente conversacional inteligente que ayuda a los usuarios a encontrar y reservar restaurantes utilizando IA generativa. Combina modelos de lenguaje (LLMs) con integraciones de servicios externos para proporcionar una experiencia de reserva completa y automatizada.
- Características Principales
- Arquitectura del Sistema
- Stack Tecnológico
- Requisitos Previos
- Instalación
- Configuración
- Ejecución del Proyecto
- Estructura del Proyecto
- Testing
- Herramientas del Agente
- Documentación Adicional
- Agente Conversacional IA: Utiliza el patrón ReAct (Reasoning + Acting) con LangGraph para razonamiento inteligente
- Búsqueda de Restaurantes: Integración con Google Maps/Places API para encontrar restaurantes según criterios del usuario
- Reservas Automatizadas:
- Sistema de reservas online (mock para demostración)
- Llamadas telefónicas automatizadas vía Twilio + ElevenLabs (text-to-speech)
- Gestión de Calendario: Integración con Google Calendar para programar reservas
- Búsqueda Web: Capacidad de buscar información adicional usando Tavily API
- Interfaz Web: Frontend interactivo con Streamlit
- API REST: Backend con FastAPI para integración con otros sistemas
- Testing Completo: Suite de tests unitarios e integración con pytest
FoodLooker implementa un patrón ReAct Agent usando LangGraph:
┌─────────────────────────────────────────────────────────┐
│ Frontend (Streamlit) │
│ http://localhost:8501 │
└──────────────────────────┬──────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────┐
│ Backend API (FastAPI) │
│ http://localhost:8000 │
│ POST /api/reservation-requests │
└──────────────────────────┬──────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────┐
│ Agent Graph (LangGraph + ReAct) │
│ │
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
│ │ Brain │────────>│ Execute │───────>│ Respond │ │
│ │ Node │ │ Node │ │ Node │ │
│ │ (LLM) │ │ (Tools) │ │ (Reply) │ │
│ └──────────┘ └──────────┘ └──────────┘ │
│ ▲ │ │
│ └────────────────────┘ │
│ (Loop hasta completar) │
└──────────────────────────┬──────────────────────────────┘
│
┌──────────────┼──────────────┐
│ │ │
▼ ▼ ▼
┌──────────┐ ┌─────────────┐ ┌──────────┐
│ Google │ │ Twilio │ │ Tavily │
│Maps/Cal. │ │+ElevenLabs │ │ Search │
└──────────┘ └─────────────┘ └──────────┘
- Brain Node: El LLM analiza el contexto de la conversación y decide la siguiente acción (buscar, reservar, llamar, responder)
- Execute Node: Ejecuta la herramienta seleccionada (maps_search, check_availability, make_booking, phone_call, etc.)
- Respond Node: Envía mensaje al usuario
- State Management: AgentState transporta mensajes, conocimiento y resultados a través del grafo
- Python 3.11+: Lenguaje principal
- LangGraph: Orquestación de agentes y flujos
- LangChain: Framework de IA para LLMs
- OpenAI GPT-4o-mini: Modelo de lenguaje
- FastAPI: Framework web para API REST
- Uvicorn: Servidor ASGI
- Flask: Servidor para servicio de llamadas
- Pydantic: Validación de datos
- Streamlit: Interfaz web interactiva
- Google Maps/Places API: Búsqueda de restaurantes
- Google Calendar API: Gestión de eventos
- Twilio: Llamadas telefónicas
- ElevenLabs: Text-to-speech
- Tavily: Búsqueda web
- Ngrok: Tunneling para webhooks
- pytest: Framework de testing
- pytest-asyncio: Tests asíncronos
- pytest-cov: Cobertura de código
- LangSmith: Trazabilidad de agentes (opcional)
- Python 3.11 o superior
- Cuenta de Google Cloud (para Maps y Calendar APIs)
- Cuenta de OpenAI (para GPT-4o-mini)
- Cuenta de Twilio (para llamadas telefónicas)
- Cuenta de ElevenLabs (para text-to-speech)
- Cuenta de Tavily (para búsqueda web)
- Docker (opcional, para ejecución en contenedor)
git clone <repository-url>
cd apipython -m venv venv
# Windows
venv\Scripts\activate
# macOS/Linux
source venv/bin/activatepip install -r requirements.txtCrea un archivo .env en la raíz del proyecto usando .env.example como plantilla:
cp .env.example .envEdita el archivo .env con tus credenciales:
# OpenAI
OPENAI_API_KEY=sk-...
MODEL_NAME=gpt-4o-mini
# Google Maps/Places
GOOGLE_MAPS_API_KEY=AIza...
# Google Calendar
GOOGLE_CREDENTIALS=credentials.json
# Twilio (Phone Calls)
TWILIO_ACCOUNT_SID=AC...
TWILIO_AUTH_TOKEN=...
FROM_TWILIO_PHONE_NUMBER=+1...
# ElevenLabs (Text-to-Speech)
ELEVENLABS_API_KEY=...
ELEVENLABS_VOICE_ID=...
# Tavily (Web Search)
TAVILY_API_KEY=tvly-...
# API Configuration
FAST_API_API_HOST=0.0.0.0
FAST_API_API_PORT=8000
STREAMLIT_PORT=8501
# LangSmith (Optional - for tracing)
LANGSMITH_API_KEY=...
LANGCHAIN_TRACING_V2=true
LANGCHAIN_PROJECT=FoodLooker- Ve a Google Cloud Console
- Crea un nuevo proyecto o selecciona uno existente
- Ve a APIs y servicios > Biblioteca
- Busca Google Calendar API
- Haz clic en Habilitar
- Ve a APIs y servicios > Pantalla de consentimiento de OAuth
- Selecciona el tipo de usuario:
- Interno: Solo usuarios de tu organización
- Externo: Cualquier usuario con cuenta de Google
- Completa la información requerida:
- Nombre de la aplicación:
FoodLooker - Correo de soporte
- Información de contacto del desarrollador
- Nombre de la aplicación:
- Configura los permisos necesarios (la aplicación configurará los SCOPES automáticamente)
- Guarda los cambios
- Ve a APIs y servicios > Credenciales
- Haz clic en Crear credenciales > ID de cliente OAuth
- Selecciona Aplicación web
- Agrega las URIs de redireccionamiento autorizadas:
http://localhost:8080/ http://127.0.0.1:8080/ - Haz clic en Crear
- Descarga el archivo JSON de credenciales
- Renombra el archivo a
credentials.json - Coloca
credentials.jsonen la raíz del proyecto
- Ve a Google Auth Platform > Público
- Desplázate hasta Usuarios de prueba
- Agrega tu cuenta de Google (ej:
tu-email@gmail.com)
- Ve a Google Maps Platform
- Asegúrate de estar en el mismo proyecto que Google Calendar
- En APIs y servicios > Biblioteca, habilita:
- Geocoding API (convertir direcciones a coordenadas)
- Places API (New) o Places API (búsqueda de lugares)
- Distance Matrix API (filtrado por tiempo de viaje)
- Ve a APIs y servicios > Credenciales
- Haz clic en Crear credenciales > Clave de API
- Copia la clave generada (esta es
GOOGLE_MAPS_API_KEY)
- Haz clic en la API Key recién creada
- En Restricciones de la aplicación:
- Selecciona Direcciones IP
- Agrega tu IP pública
- En Restricciones de API:
- Selecciona Restringir clave
- Marca las siguientes APIs:
- Distance Matrix API
- Geocoding API
- Places API (New)
- Guarda los cambios
Ejecuta todos los servicios con un solo comando:
python main.pyEste comando inicia:
- Backend API (FastAPI) en
http://localhost:8000 - Frontend (Streamlit) en
http://localhost:8501 - Servicio de llamadas (Flask) en
http://localhost:8002
Accede a la aplicación:
- 🖥️ Frontend: http://localhost:8501
- 📡 Backend API: http://localhost:8000
- 📖 API Docs: http://localhost:8000/docs
Para debuguear componentes por separado:
python agent/main.pyEjecuta el agente en modo terminal para ver el proceso de razonamiento completo.
python -m uvicorn FastAPI.api_server:app --host 0.0.0.0 --port 8000o
python FastAPI/api_server.pystreamlit run frontend/frontend.pypython backend/call_service.pyDocker simplifica la ejecución pero NO carga Streamlit ni Google Calendar (por limitaciones de autenticación OAuth).
docker build -t foodlooker .docker run -p 8000:8000 -p 8501:8501 --env-file .env foodlookerAcceso:
- 🖥️ Frontend: http://localhost:8501 (limitado)
- 📡 Backend API: http://localhost:8000
- 📖 API Docs: http://localhost:8000/docs
Ver INSTRUCCIONES_DOCKER.md para más detalles.
api/
│
├── agent/ # Sistema núcleo del agente (LangGraph + ReAct)
│ ├── graph.py # Orquestación con LangGraph (brain/execute/respond)
│ ├── main.py # Entry point para ejecución en terminal
│ ├── prompts.py # Cargador y formateador de prompts
│ ├── state.py # Gestión de estado (AgentState TypedDict)
│ └── tools.py # Implementación de herramientas externas
│
├── backend/ # Servicios backend e integraciones
│ ├── calendar_tools.py # Integración con Google Calendar
│ ├── call_service.py # Servicio de llamadas (Flask + Twilio + ElevenLabs)
│ └── google_places.py # Wrapper de Google Places API
│
├── config/
│ └── settings.py # Cargador de configuración desde .env
│
├── FastAPI/ # Backend API REST
│ ├── api_server.py # Servidor FastAPI con endpoints
│ └── test_api.py # Tests manuales de API
│
├── frontend/ # Interfaz de usuario
│ ├── frontend.py # Aplicación Streamlit (chat interactivo)
│ ├── frontend_api_helpers.py # Funciones helper para llamadas API
│ └── logo.png # Logo de la aplicación
│
├── prompts/ # Plantillas de prompts (Markdown)
│ ├── agent_system_prompt.md # Prompt del sistema principal del agente
│ ├── call_script_generation.md # Template para generar scripts de llamadas
│ └── call_result_analysis.md # Template para analizar resultados de llamadas
│
├── tests/ # Suite de tests automatizados
│ ├── conftest.py # Fixtures compartidos y mocks
│ │
│ ├── unit/ # Tests unitarios
│ │ ├── test_agent_graph.py # Tests de lógica del grafo del agente
│ │ ├── test_tools.py # Tests de herramientas del agente
│ │ ├── test_state.py # Tests de gestión de estado
│ │ ├── test_prompts.py # Tests del sistema de prompts
│ │ └── test_settings.py # Tests de configuración
│ │
│ ├── integration/ # Tests de integración
│ │ ├── test_google_places.py # Tests de Google Places API
│ │ ├── test_call_service.py # Tests del servicio de llamadas
│ │ ├── test_calendar_tools.py# Tests de integración con Calendar
│ │ └── test_api_server.py # Tests de endpoints de FastAPI
│ │
│ └── fixtures/ # Datos de prueba
│ └── mock_responses.py # Respuestas simuladas de APIs
│
├── .coveragerc # Configuración de cobertura (salida en test_results/)
├── .env # Variables de entorno (NO en git)
├── .env.example # Template de variables de entorno
├── .gitignore # Archivos ignorados por git
├── .streamlit/
│ └── config.toml # Configuración de Streamlit
├── Dockerfile # Configuración de Docker
├── INSTRUCCIONES_DOCKER.md # Guía de Docker
├── main.py # Entry point principal (orquesta todos los servicios)
├── pytest.ini # Configuración de pytest
├── README.md # Esta documentación
├── requirements.txt # Dependencias de Python
└── tool_descriptions.md # Descripción detallada de herramientas del agente
El proyecto incluye una suite completa de tests automatizados usando pytest. Los resultados se generan en test_results/.
pip install -r requirements.txtLas dependencias de testing incluyen:
pytest>=7.0.0pytest-asynciopytest-mockpytest-cov
pytestpytest tests/unit/pytest tests/integration/pytest --covEl reporte HTML de cobertura se genera en test_results/htmlcov/index.html
pytest tests/unit/test_agent_graph.py -vpytest --junitxml=test_results/junit.xmlLos resultados se guardan en:
test_results/htmlcov/: Reporte HTML de coberturatest_results/.coverage: Datos binarios de coberturatest_results/junit.xml: Reporte JUnit (opcional)
-
tests/unit/: Tests unitarios que verifican componentes individualestest_agent_graph.py: Lógica del grafo del agentetest_tools.py: Funciones de herramientastest_state.py: Gestión de estadotest_prompts.py: Sistema de promptstest_settings.py: Carga de configuración
-
tests/integration/: Tests de integración con servicios externos (usando mocks)test_google_places.py: Google Places APItest_call_service.py: Servicio de llamadastest_calendar_tools.py: Google Calendartest_api_server.py: Endpoints de FastAPI
-
tests/conftest.py: Fixtures compartidos y configuración de mocks
El agente tiene acceso a 7 herramientas principales:
Busca información en la web usando Tavily API.
Uso: Cuando el usuario solicita información que no está en el conocimiento del agente.
Busca restaurantes usando Google Maps/Places API.
Parámetros:
location: Ubicación del usuariokeywords: Tipo de comida, nombre del restaurante, etc.max_results: Número máximo de resultados (default: 5)
Verifica disponibilidad de un restaurante (sistema mock).
Parámetros:
restaurant_name: Nombre del restaurantedate: Fecha de la reservatime: Hora de la reservaparty_size: Número de personas
Realiza una reserva en el sistema mock.
Parámetros:
restaurant_name: Nombre del restaurantedate: Fecha de la reservatime: Hora de la reservaparty_size: Número de personascustomer_name: Nombre del clientecustomer_phone: Teléfono del cliente
Realiza una llamada telefónica automatizada usando Twilio y ElevenLabs.
Parámetros:
to_number: Número de teléfono del restaurantecall_purpose: Propósito de la llamadarestaurant_name: Nombre del restaurantedate,time,party_size,customer_name,customer_phone: Detalles de la reserva
Crea un evento en Google Calendar.
Parámetros:
summary: Título del eventolocation: Ubicacióndescription: Descripciónstart_time: Fecha/hora de inicio (ISO 8601)end_time: Fecha/hora de fin (ISO 8601)
Envía un mensaje de texto al usuario.
Parámetros:
message: Mensaje a enviar
Ver tool_descriptions.md para documentación detallada de cada herramienta.
- tool_descriptions.md: Descripción detallada de todas las herramientas del agente
- INSTRUCCIONES_DOCKER.md: Guía completa de Docker
prompts/: Plantillas de prompts usadas por el agente- API Docs: http://localhost:8000/docs (cuando el servidor está corriendo)
Este es un proyecto de trabajo final de máster. Para reportar issues o sugerencias, por favor contacta al autor.
Este proyecto es parte de un trabajo académico.
Trabajo Final de Máster - FoodLooker Agente Inteligente de Reservas con IA
- LangChain/LangGraph: Framework de agentes IA
- OpenAI: Modelos de lenguaje GPT
- Google Cloud: APIs de Maps, Places y Calendar
- Twilio: Servicio de llamadas telefónicas
- ElevenLabs: Text-to-speech de alta calidad
- Streamlit: Framework de interfaz web