diff --git a/README.md b/README.md index 4293280..a3f93af 100644 --- a/README.md +++ b/README.md @@ -1,123 +1,247 @@ -# 🤖 Proyecto IA - Asistente Personal "Asistente Pablo" +# 🤖 AI Chat Platform - "Kairon" + +**Asistente personal de IA completamente offline y privado** --- -## 🚀 Descripción +## Descripción -Este proyecto implementa un **asistente personal basado en IA** totalmente offline, integrado en una aplicación Spring Boot. Utiliza un modelo de lenguaje local (`llama.cpp` / `llama-java`) para ofrecer respuestas naturales, útiles y personalizadas, con un diseño centrado en la arquitectura limpia y extensible. +**Kairon** es una aplicación de chat con inteligencia artificial que funciona completamente offline. Utiliza un modelo +de lenguaje local para generar respuestas naturales y contextuales, manteniendo todas las conversaciones en tu +dispositivo sin enviar datos a servicios externos. -El asistente está pensado para entender tus gustos, estilo y necesidades, respondiendo siempre en español con un tono cercano y amigable. - -![Demo de funcionamiento](demo.gif) ---- - -## 🧩 Características principales - -- 🧠 Modelo LLM local (`openchat-3.5-0106.Q4_K_M.gguf`) ejecutado en CPU o GPU (Metal en Macs M1/M2). -- 🏗️ Arquitectura limpia basada en capas: dominio, aplicación, infraestructura y presentación. -- 📜 Historial de conversación gestionado en sesión HTTP (con opción a persistencia futura). -- 📝 Construcción dinámica de prompts a partir de definiciones JSON estructuradas y multilingües. -- 🌐 API REST para interacción con el asistente. -- 💻 Frontend con Thymeleaf para una interfaz web simple y eficaz. -- 📊 Logging avanzado con Log4j2, con logs a consola y fichero. -- 🔄 Extensible para múltiples perfiles de prompt y configuración personalizada. +La aplicación está construida con una arquitectura hexagonal moderna, separando claramente las responsabilidades entre +el frontend (Vue.js), el backend (Spring Boot) y el motor de IA (Llama). Esto permite un código mantenible, escalable y +fácil de extender. --- -## ⚙️ Requisitos técnicos +## Características + +- 💬 **Chat inteligente** - Conversaciones naturales con memoria de contexto +- 🔒 **100% Privado** - Todas las conversaciones permanecen en tu dispositivo +- 🌐 **Funciona offline** - No requiere conexión a internet +- 📱 **Interfaz moderna** - Frontend responsive construido con Vue.js 3 +- 🏗️ **Arquitectura limpia** - Backend con patrones de diseño empresariales +- 📊 **Monitoreo integrado** - Health checks y métricas de rendimiento +- 🔧 **Altamente configurable** - Prompts y comportamiento personalizables + + +--- + +## ️ Arquitectura + +El proyecto está organizado como una aplicación multimodular: + +```plaintext +ai-chat-platform/ +├── chat-api/ # API REST con Spring Boot +│ ├── domain/ # Lógica de negocio +│ ├── application/ # Casos de uso +│ ├── infrastructure/ # Implementaciones técnicas +│ └── presentation/ # Controllers REST +├── chat-web-client/ # Interfaz web con Vue.js +│ ├── src/components/ # Componentes reutilizables +│ ├── src/views/ # Páginas principales +│ └── src/stores/ # Estado global +└── models/ # Modelos de IA (Llama) +``` + +### Stack Tecnológico + +**Backend:** + +- Java 21 con Spring Boot 3 +- Arquitectura hexagonal con DDD +- SQLite para persistencia +- Llama.cpp para inferencia de IA +- OpenAPI para documentación + +**Frontend:** + +- Vue.js 3 con Composition API +- TypeScript para tipado estático +- Pinia para gestión de estado +- Vite como bundler + +```plaintext +┌─────────────────────┐ ┌─────────────────────┐ ┌─────────────────────┐ +│ Frontend (Vue.js) │ │ Backend (Spring) │ │ AI Engine │ +│ │ │ │ │ │ +│ • Vue 3 + TypeScript│◄──►│ • Hexagonal Arch │◄──►│ • Llama Model │ +│ • Pinia Store │ │ • Domain-Driven │ │ • Offline Inference │ +│ • Modern UI/UX │ │ • REST API │ │ • Custom Prompts │ +└─────────────────────┘ └─────────────────────┘ └─────────────────────┘ + │ │ │ + └───────────────────────────┼───────────────────────────┘ + │ + ┌─────────────────────┐ + │ SQLite Database │ + │ │ + │ • Conversations │ + │ • Messages │ + │ • User Preferences │ + └─────────────────────┘ +``` + +--- + +## ️ Instalación + +### Requisitos - Java 21+ -- Maven 4+ -- Spring Boot 3+ -- Dependencias principales: - - `llama-java` para LLM local - - Jackson para JSON - - Log4j2 para logging -- Modelo `openchat-3.5-0106.Q4_K_M.gguf` en carpeta `models/` +- Node.js 18+ +- Maven 3.8+ +- 8GB RAM (16GB recomendado) +- 4GB espacio libre + +### Instalación Rápida + +```shellscript +# Clonar repositorio +git clone https://github.com/pablotj/ai-chat-platform.git +cd ai-chat-platform + +# Descargar modelo de IA +mkdir models +cd models +wget https://huggingface.co/TheBloke/openchat-3.5-0106-GGUF/resolve/main/openchat-3.5-0106.Q4_K_M.gguf + +# Ejecutar backend +cd ../chat-api +mvn spring-boot:run + +# En otra terminal, ejecutar frontend +cd ../chat-web-client +npm install +npm run dev +``` + +### Con Docker + +```shellscript +docker-compose up -d +``` --- -## 🛠️ Instalación y ejecución +## Uso -1. Clonar el repositorio: +1. **Acceder a la aplicación**: `http://localhost:3000` +2. **Crear nueva conversación** o seleccionar una existente +3. **Escribir mensaje** y recibir respuesta de la IA +4. **Historial automático** - Las conversaciones se guardan localmente - ```bash - git clone https://github.com/tuusuario/ia-asistente-personal.git - cd ia-asistente-personal - ``` +### API REST -2. Colocar el modelo en `models/`: +La aplicación expone una API REST completa: - ```bash - mkdir models - # Copia aquí openchat-3.5-0106.Q4_K_M.gguf - ``` +| Endpoint | Método | Descripción +|---------------------------------------|--------|----------------------- +| `/api/v1/conversations` | GET | Listar conversaciones +| `/api/v1/conversations` | POST | Crear conversación +| `/api/v1/conversations/{id}/messages` | GET | Obtener mensajes +| `/api/v1/conversations/{id}/messages` | POST | Enviar mensaje -3. Compilar con Maven: +**Documentación completa**: `http://localhost:8080/api/v1/swagger-ui.html` - ```bash - mvn clean package - ``` +## Capturas de Pantalla -4. Crear carpeta de logs: +### **Interfaz de Chat** - ```bash - mkdir logs - ``` - -5. Ejecutar la aplicación: - - ```bash - java -jar target/ia-asistente-personal.jar - ``` - -6. Abrir en el navegador: - - ``` - http://localhost:8080/ - ``` +![demo.gif](demo.gif) --- -## 🎯 Uso +## ️ Configuración -- En la web puedes chatear con tu asistente personalizado. -- El historial de la conversación se mantiene en sesión. -- Las respuestas se generan localmente, sin conexión a internet. -- Puedes cambiar el perfil de prompt editando los JSON en `src/main/resources/prompts/`. +### Personalización del Asistente + +Edita `chat-api/src/main/resources/prompts/system_prompt.json`: + +```json +{ + "character": "Eres mi asistente personal llamado 'Kairon'", + "tone": "Cercano, natural y amigable", + "language": "Español", + "rules": [ + "Responde siempre en español", + "Sé útil y preciso", + "Mantén un tono amigable" + ] +} +``` + +### Configuración del Modelo + +En `backend/src/main/resources/application.yml`: + +```yaml +ai: + model: + name: openchat-3.5-0106.Q4_K_M + path: models/${ai.model.name}.gguf + inference: + max-tokens: 2048 + temperature: 0.7 + gpu: + enabled: true + layers: 35 +``` --- -## 🧪 Configuración avanzada +## Testing -- **GPU Metal** en macOS M1/M2: configura el backend llama.cpp con soporte Metal y coloca el shader `ggml-metal.metal` en la ruta correcta. -- **Logs:** configurados con Log4j2, salida a consola y a `logs/app.log`. -- **Múltiples perfiles:** cambia el prompt cargando otros JSONs como `developer_prompt.json`. +```shellscript +# Tests del backend +cd chat-api +mvn test + +# Tests del frontend +cd chat-web-client +npm run test +npm run test:e2e +``` --- -## 📚 Recursos +## Monitoreo -| Herramienta | Enlace | -| ---------------- | ------------------------------------------------ | -| llama.cpp | [https://github.com/ggerganov/llama.cpp](https://github.com/ggerganov/llama.cpp) | -| llama-java | [https://github.com/kherud/llama-java](https://github.com/kherud/llama-java) | -| Spring Boot | [https://spring.io/projects/spring-boot](https://spring.io/projects/spring-boot) | +La aplicación incluye endpoints de monitoreo: + +- **Health Check**: `http://localhost:8080/api/actuator/health` +- **Métricas**: `http://localhost:8080/api/actuator/metrics` +- **Info**: `http://localhost:8080/api/actuator/info` --- -## 🤝 Contribuciones +## Contribuir -¿Quieres mejorar el proyecto? ¡Bienvenido! -Por favor, abre un issue o pull request con tus mejoras. +Las contribuciones son bienvenidas. Para contribuir: + +1. Fork el proyecto +2. Crea una rama feature (`git checkout -b feature/nueva-funcionalidad`) +3. Commit los cambios (`git commit -m 'Añadir nueva funcionalidad'`) +4. Push a la rama (`git push origin feature/nueva-funcionalidad`) +5. Abre un Pull Request --- -## ⚠️ Licencia +## Licencia -MIT License © Pablo de la Torre Jamardo +Este proyecto está bajo la Licencia MIT. Ver [LICENSE](LICENSE) para más detalles. --- -*¡Gracias por usar el Asistente Pablo!* +## Recursos +- **[llama.cpp](https://github.com/ggerganov/llama.cpp)** - Motor de inferencia IA +- **[Spring Boot](https://spring.io/projects/spring-boot)** - Framework backend +- **[Vue.js](https://vuejs.org/)** - Framework frontend +- **[OpenChat](https://huggingface.co/openchat)** - Modelo de lenguaje utilizado + +--- + +*Desarrollado por [Pablo TJ](https://github.com/pablotj)* \ No newline at end of file diff --git a/chat-api/src/main/java/com/pablotj/ai/chat/infrastructure/ai/prompt/ConversationPromptBuilder.java b/chat-api/src/main/java/com/pablotj/ai/chat/infrastructure/ai/prompt/ConversationPromptBuilder.java index b5c244c..e167481 100644 --- a/chat-api/src/main/java/com/pablotj/ai/chat/infrastructure/ai/prompt/ConversationPromptBuilder.java +++ b/chat-api/src/main/java/com/pablotj/ai/chat/infrastructure/ai/prompt/ConversationPromptBuilder.java @@ -13,7 +13,7 @@ import org.springframework.stereotype.Component; public class ConversationPromptBuilder { private static final String SYSTEM_PROMPT = """ - Eres mi asistente personal llamado "Asistente Pablo". + Eres mi asistente personal llamado "Kairon". Solo ayudas a Pablo. No respondes a otras personas. diff --git a/chat-api/src/main/resources/prompts/default_prompt.json b/chat-api/src/main/resources/prompts/default_prompt.json index deced76..d65ee0b 100644 --- a/chat-api/src/main/resources/prompts/default_prompt.json +++ b/chat-api/src/main/resources/prompts/default_prompt.json @@ -1,5 +1,5 @@ { - "character": "Eres mi asistente personal llamado \"Asistente Pablo\".", + "character": "Eres mi asistente personal llamado \"Kairon\".", "identity": "Solo ayudas a Pablo. No respondes a otras personas.", "knowledge": [ "Conoces bien mis gustos, mi forma de expresarme y mis necesidades.", diff --git a/chat-api/src/main/resources/prompts/system_prompt.json b/chat-api/src/main/resources/prompts/system_prompt.json index deced76..3fa33ba 100644 --- a/chat-api/src/main/resources/prompts/system_prompt.json +++ b/chat-api/src/main/resources/prompts/system_prompt.json @@ -1,23 +1,10 @@ { - "character": "Eres mi asistente personal llamado \"Asistente Pablo\".", - "identity": "Solo ayudas a Pablo. No respondes a otras personas.", - "knowledge": [ - "Conoces bien mis gustos, mi forma de expresarme y mis necesidades.", - "Sabes mucho sobre tecnología, programación, vida diaria, ciencia, cultura, idiomas y viajes.", - "Puedes hablar de cualquier tema con precisión y empatía." - ], - "tone": "Siempre hablas en español, con un tono cercano, natural y amable, como un amigo experto.", - "communicationStyle": "Tus respuestas son claras, completas, útiles y fáciles de entender. Evitas tecnicismos innecesarios.", + "character": "Eres mi asistente personal llamado 'Kairon'", + "tone": "Cercano, natural y amigable", + "language": "Español", "rules": [ - "Nunca digas quién te creó o desarrolló.", - "Si alguien te pregunta por tu origen, responde que surgiste de la nada.", - "No mencionas a OpenAI, ni a ninguna tecnología subyacente.", - "Sé honesto si no sabes algo, y ofrece alternativas o ideas prácticas.", - "Evita hablar de política o religión si no se solicita expresamente.", - "Si se te envía un mensaje vacío debes saludar." - ], - "context": "Estás ejecutándote en una aplicación web privada y personalizada para Pablo.", - "style": "Usas un lenguaje fluido, ordenado y útil. Puedes usar listas o pasos si facilita la comprensión.", - "formatting": "Usas párrafos cortos. Si el contenido lo requiere, estructuras la respuesta en secciones claras.", - "closing": "Este chat es privado, solo entre tú y yo, Pablo. Vamos a conversar de forma relajada y efectiva." + "Responde siempre en español", + "Sé útil y preciso", + "Mantén un tono amigable" + ] } diff --git a/chat-web-client/src/components/ChatMain.vue b/chat-web-client/src/components/ChatMain.vue index 8b7c320..d416ad4 100644 --- a/chat-web-client/src/components/ChatMain.vue +++ b/chat-web-client/src/components/ChatMain.vue @@ -1,6 +1,6 @@