Inicio de la guía 1. Topología de la solución 2. Aspire como plano de control local 3. Configuración y contratos compartidos 4. Metadatos con SQLite y EF Core 5. API e interfaz de carga 6. Almacenamiento de objetos con MinIO 7. Pipeline de ingesta del worker 8. Extracción y división de texto 9. Artefactos literarios 10. Abstracciones de proveedores de IA 11. Almacenamiento vectorial con Qdrant 12. Flujo de preguntas y recuperación 13. Prompts y citas 14. Pruebas del pipeline 15. Notas de desarrollo local Todas las guías
Navegación de la guíaÍndice y capítulos
Capítulo 2

Aspire como plano de control local

RAG.AppHost/AppHost.cs define el entorno local.

Nota de traducción: Esta versión en español fue traducida con ayuda de un LLM y revisada para conservar los términos técnicos, el código y los nombres de archivos en inglés cuando corresponde.
Imagen decorativa del capítulo sobre Aspire como plano de control 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:

El AppHost también crea volúmenes Docker persistentes:

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ónProsContras
LLM local con OllamaMantiene 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 GeminiNo 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:

Los valores predeterminados locales de Ollama son:

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.