Skip to content

Base de Datos Vectorial (Qdrant)

Qdrant es la base de datos vectorial que permite al AI Backend realizar búsqueda semántica de alta calidad. Almacena representaciones vectoriales del contenido para recuperar los chunks más relevantes dado un query.

ColecciónPropósitoDimensionesModelo de embedding
lesson_contentEmbeddings de lecciones para búsqueda semántica1536text-embedding-3-small
tutor_contextContexto conversacional del tutor por usuario1536text-embedding-3-small
user_profilesVectores de perfil de aprendizaje por usuario1536text-embedding-3-small
quiz_questionsBanco de preguntas para deduplicación1536text-embedding-3-small

Archivo: apps/ai-backend/src/modules/vector-db/qdrant.service.ts

// Operaciones principales
search(collection: string, vector: number[], limit: number, filter?: object): Promise<SearchResult[]>
upsert(collection: string, points: VectorPoint[]): Promise<void>
healthCheck(): Promise<{ status: 'ok' | 'error'; collections: string[]; vectorCount: number }>
getCollectionInfo(collection: string): Promise<CollectionInfo>

El servicio usa lazy initialization: las colecciones se crean si no existen al primer upsert.

Archivo: apps/ai-backend/src/modules/vector-db/embedding.service.ts

  • Genera embeddings con OpenAIAdapter usando text-embedding-3-small
  • Caché en memoria (por text-hash → vector) para no regenerar embeddings idénticos
  • Los embeddings cacheados tienen TTL de 1 hora
async embed(text: string): Promise<number[]> {
const hash = sha256(text);
if (this.cache.has(hash)) return this.cache.get(hash)!;
const vector = await this.openai.createEmbedding(text, 'text-embedding-3-small');
this.cache.set(hash, { vector, cachedAt: Date.now() });
return vector;
}

Archivo: apps/ai-backend/src/modules/vector-db/indexing.service.ts

Escucha el evento lesson.published desde apps/api y automáticamente indexa la lección en Qdrant:

sequenceDiagram
participant API as apps/api
participant AI as apps/ai-backend
participant Q as Qdrant
API->>AI: POST /usecases/indexing/index-lesson {lessonId}
AI->>API: GET /internal/lessons/:id (contenido completo)
API-->>AI: { title, markdownContent, videoTranscript }
AI->>AI: EmbeddingService.embed(content)
AI->>Q: upsert('lesson_content', [{ id: lessonId, vector, payload }])
AI-->>API: { indexed: true, vectorId: lessonId }

Accesible desde el panel admin (/admin/ai/vector-db):

POST /admin/vector-db/reindex-all

Reindexará todas las lecciones publicadas. El proceso corre en background y devuelve un job ID para polling del estado.