Aspire como plano de control local
RAG.AppHost/AppHost.cs define el entorno local.
AppHost conecta dependencias locales con API y worker
var qdrant = builder.AddContainer("qdrant", "qdrant/qdrant")
.WithHttpEndpoint(port: 6333, targetPort: 6333, name: "http")
.WithVolume("rag-qdrant-data", "/qdrant/storage");
var minio = builder.AddContainer("minio", "minio/minio")
.WithArgs("server", "/data", "--console-address", ":9001")
.WithHttpEndpoint(port: 9000, targetPort: 9000, name: "api");RAG.AppHost/AppHost.cs define el entorno local.
Inicia:
- Qdrant en los puertos
6333y6334. - MinIO en los puertos
9000y9001. - API en
http://127.0.0.1:5080/. - Worker como proceso en segundo plano.
- Ollama solo cuando Gemini no está seleccionado.
El AppHost también crea volúmenes Docker persistentes:
rag-qdrant-datarag-minio-datarag-ollama-data
Esos volúmenes permiten que los vectores indexados, los archivos cargados y los modelos descargados de Ollama sobrevivan reinicios de contenedores.
Nota de producción: estos servicios se exponen en puertos locales fijos y MinIO usa credenciales de ejemplo. Eso es aceptable para este proyecto de aprendizaje, que no está pensado para producción, pero un despliegue real debería usar redes privadas, secretos administrados y acceso restringido a servicios.
Aspire inyecta configuración en la API y en el worker mediante variables de entorno:
.WithEnvironment("Rag__Qdrant__BaseUrl", qdrant.GetEndpoint("http"))
.WithEnvironment("Rag__Storage__ServiceUrl", minio.GetEndpoint("api"))
.WithEnvironment("Rag__DatabasePath", databasePath)
La sintaxis de doble guion bajo mapea variables de entorno a secciones de configuración de .NET. Por ejemplo, Rag__Qdrant__BaseUrl se convierte en Rag:Qdrant:BaseUrl.
Selección del proveedor de IA
El AppHost elige Gemini cuando GEMINI_API_KEY está presente:
GEMINI_API_KEY present -> Gemini
otherwise -> Ollama
Puedes sobrescribirlo con:
export RAG_AI_PROVIDER="Gemini"
| Opción | Pros | Contras |
|---|---|---|
| LLM local con Ollama | Mantiene prompts y contenido de documentos en tu máquina. Funciona bien para experimentar offline después de descargar los modelos. Evita costos por solicitud de API. | Requiere recursos locales de CPU/GPU, memoria y disco. Las descargas de modelos pueden ser grandes. En hardware modesto, las respuestas suelen ser más lentas que en APIs alojadas. |
| LLM alojado por API con Gemini | No requiere alojar modelos localmente. Suele dar respuestas más rápidas y mejor calidad de modelo. Es más fácil de escalar más allá de una sola máquina de desarrollo. | Envía prompts y contexto recuperado del documento a un servicio externo. Requiere API key, acceso de red y facturación/cuotas del proveedor. |
Los valores predeterminados actuales de Gemini son:
- Modelo de embeddings:
gemini-embedding-2 - Modelo de chat:
gemini-2.5-pro
Los valores predeterminados locales de Ollama son:
- Modelo de embeddings:
nomic-embed-text - Modelo de chat:
llama3.2
Nota: RAG usa dos tipos de modelos porque la recuperación y la generación de respuestas son trabajos distintos. El modelo de embeddings convierte chunks de documentos y preguntas del usuario en vectores numéricos, llamados embeddings, que capturan significado semántico. El almacén vectorial usa esos embeddings para encontrar chunks relacionados con la pregunta. Luego el modelo de chat recibe la pregunta más los chunks recuperados y escribe la respuesta final.