RAG y Base de Conocimiento
Aprende a construir un sistema de Retrieval-Augmented Generation (RAG) para que tu bot responda con informacion precisa y actualizada.
Que es RAG
RETRIEVAL-AUGMENTED GENERATION (RAG)
| Paso | Descripcion |
|---|---|
| PREGUNTA | "¿Cuales son los beneficios de la empresa?" |
| RETRIEVAL | Buscar en base de conocimiento usando busqueda semantica |
| DOCUMENTOS RELEVANTES | Politica de beneficios, FAQ de compensaciones, Manual del empleado |
| GENERATION | LLM genera respuesta usando los documentos como contexto |
| RESPUESTA | "Ofrecemos seguro medico, vales de despensa, fondo de ahorro..." |
Arquitectura del Sistema
Componentes
SISTEMA RAG TALIVO
DOCUMENTOS:
- Vacantes
- Politicas
- FAQ
- Articulos
INDEXACION:
- Chunking
- Embeddings
- Almacenar
VECTOR STORE (Redis)
- Almacena embeddings
- Busqueda por similitud
QUERY:
- Usuario pregunta
- Se convierte a Embedding
- Busqueda en vector store
CHUNKS RELEVANTES:
- Se recuperan los chunks mas similares
LLM:
- Genera respuesta con contexto
Fuentes de Conocimiento
Tipos de Fuentes
1. DESCRIPCIONES DE VACANTES
- Se indexan automaticamente
- Titulo y descripcion
- Requisitos
- Responsabilidades
- Beneficios
- Ubicacion y modalidad
2. ARTICULOS DE AYUDA
- Contenido de help-content/
- Guias de uso
- FAQ
- Documentacion
3. POLITICAS DE EMPRESA
- Documentos corporativos
- Codigo de conducta
- Politicas de RH
- Beneficios detallados
- Procesos internos
4. FAQ PERSONALIZADAS
- Preguntas frecuentes
- Por vacante
- Por departamento
- Generales
5. DOCUMENTOS SUBIDOS
- PDFs y documentos
- Manuales
- Presentaciones
- Materiales de onboarding
Agregar Fuentes
Interfaz para agregar conocimiento:
| Campo | Valor |
|---|---|
| Fuentes Activas | |
| Vacantes | 15 indexadas |
| Articulos de ayuda | 45 |
| FAQ | 23 |
| Politicas | pendiente |
Agregar nueva fuente:
- Tipo: Documento PDF
- Archivo: [Seleccionar...]
- Categoria: Beneficios
- Visible para: Candidatos
Proceso de Indexacion
Chunking (Fragmentacion)
Un documento largo se divide en "chunks" manejables:
Documento Original (5000 palabras)
CHUNKING - Estrategias:
- Por parrafos (natural)
- Por tamaño fijo (500 tokens)
- Por semantica (temas)
- Hibrido (parrafos + overlap)
Configuracion por defecto:
- Tamaño: 500 tokens
- Overlap: 50 tokens
- Separador: parrafos
Resultado: [Chunk 1] [Chunk 2] [Chunk 3] ... [Chunk N]
Embeddings (Vectorizacion)
Cada chunk se convierte en un vector numerico:
Chunk: "Ofrecemos seguro de gastos medicos mayores para todos los empleados y sus familias..."
EMBEDDING MODEL: text-embedding-ada-002 / 1536 dimensiones
Vector: [0.023, -0.156, 0.089, ..., 0.045] (1536 numeros que representan el significado)
Almacenamiento en Redis
// Estructura almacenada
{
"id": "doc_123_chunk_5",
"content": "Ofrecemos seguro de gastos medicos...",
"embedding": [0.023, -0.156, ...],
"metadata": {
"sourceType": "policy",
"sourceId": "benefits-policy",
"title": "Politica de Beneficios",
"section": "Seguro Medico",
"lastUpdated": "2024-01-15",
"owner": "company_1"
}
}
Busqueda Semantica
Como Funciona
-
Usuario pregunta: "¿Tienen seguro dental?"
-
Convertir pregunta a embedding: [0.045, -0.123, 0.067, ...]
-
Buscar vectores similares (cosine similarity)
| Chunk | Similarity |
|---|---|
| Chunk "seguro medico" | 0.89 |
| Chunk "beneficios" | 0.85 |
| Chunk "vacaciones" | 0.45 |
- Retornar top K chunks (similarity > threshold): [Chunk "seguro medico", Chunk "beneficios"]
Configurar Busqueda
{
"search": {
"algorithm": "cosine",
"topK": 5,
"minScore": 0.7,
"reranking": {
"enabled": true,
"model": "cross-encoder"
},
"filters": {
"sourceType": ["policy", "faq"],
"owner": "{{company.id}}"
},
"boosts": {
"title_match": 1.5,
"recent": 1.2
}
}
}
Generacion de Respuestas
Prompt con Contexto
prompt = f"""
Eres un asistente de reclutamiento de {company_name}.
Responde la pregunta del candidato usando SOLO la informacion proporcionada.
Si no tienes suficiente informacion, indica que no lo sabes.
CONTEXTO:
{rag_chunks}
DATOS DEL CANDIDATO:
- Nombre: {candidate_name}
- Vacante: {job_title}
- Etapa: {process_step}
PREGUNTA: {user_question}
RESPUESTA:
"""
Ejemplo Completo
PREGUNTA: "¿Tienen seguro dental?"
CONTEXTO RECUPERADO:
[Chunk 1] "Ofrecemos seguro de gastos medicos mayores que incluye cobertura dental basica para el empleado..."
[Chunk 2] "Beneficios adicionales: Plan dental premium opcional con cobertura para ortodoncia y tratamientos esteticos..."
PROMPT AL LLM: "Usando la informacion anterior, responde la pregunta del candidato..."
RESPUESTA GENERADA:
"¡Si! Tenemos dos opciones de cobertura dental:
Cobertura basica: Incluida en tu seguro de gastos medicos, cubre consultas, limpiezas y tratamientos basicos.
Plan premium (opcional): Puedes contratar cobertura extendida que incluye ortodoncia y tratamientos esteticos.
¿Te gustaria saber mas sobre alguno de estos planes?"
Configurar RAG para el Bot
En el Reclutador Virtual
{
"type": "recruiter_bot",
"configuration": {
"rag": {
"enabled": true,
"sources": [
{ "type": "job_positions", "filter": { "id": "{{job.id}}" } },
{ "type": "help_articles", "category": "faq-candidatos" },
{ "type": "company_policies", "public": true },
{ "type": "custom_faq" }
],
"search": {
"topK": 5,
"minScore": 0.7,
"includeMetadata": true
},
"generation": {
"model": "gpt-4",
"temperature": 0.3,
"maxTokens": 500,
"systemPrompt": "custom_recruiter_prompt"
},
"fallback": {
"noResults": "No tengo informacion sobre eso. Te comunico con un reclutador.",
"lowConfidence": "No estoy 100% seguro. Deja que confirme con el equipo."
}
}
}
}
Agregar FAQ Personalizada
Para agregar preguntas frecuentes especificas:
| Campo | Valor |
|---|---|
| Pregunta* | ¿Ofrecen trabajo 100% remoto? |
| Respuesta* | Dependiendo del puesto, ofrecemos: Hibrido (3 dias casa, 2 oficina), 100% remoto para algunos roles, Presencial para posiciones clave |
| Aplica a | [x] Todas las vacantes |
| Palabras clave | remoto, home office, hibrido |
Mantener el Conocimiento
Actualizacion Automatica
El sistema actualiza automaticamente:
Vacantes:
- Al crear: Indexar
- Al modificar: Re-indexar
- Al cerrar: Marcar como inactivo (no eliminar)
Articulos de Ayuda:
- Detectar cambios (hash)
- Re-indexar si cambio
- Programado cada 24h
Politicas:
- Manual (cuando se actualizan)
Re-indexacion Manual
Cuando re-indexar manualmente:
- Despues de cambios importantes
- Al agregar nuevas fuentes
- Si las respuestas no son correctas
- Periodicamente (mensual)
Como:
- Ir a Base de Conocimiento
- Seleccionar fuente
- Click "Re-indexar"
- Esperar confirmacion
Monitoreo de Calidad
Metricas de RAG
Dashboard de RAG:
| Metrica | Valor |
|---|---|
| Consultas hoy | 234 |
| Promedio de chunks por query | 3.2 |
| Score promedio de relevancia | 0.82 |
| Queries sin resultados | 12 (5%) |
| Queries escaladas | 8 (3%) |
Top queries sin resultado:
- "horario flexible" (sin match)
- "plan de carrera" (bajo score)
- "estacionamiento" (sin info)
Feedback Loop
Mejorar el RAG con feedback:
- Candidato hace pregunta
- Bot responde usando RAG
- Opciones de feedback:
- Util (guardar como buena)
- No util (revisar)
- Incompleta (agregar info)
- Usar feedback para:
- Ajustar relevancia
- Agregar FAQs faltantes
- Identificar gaps
- Mejorar chunking
Construir Bot RAG desde Cero
Paso 1: Definir Fuentes
-
Identificar todo el conocimiento necesario:
- Vacantes actuales
- Informacion de empresa
- Beneficios y compensaciones
- Proceso de seleccion
- FAQ existentes
- Politicas relevantes
-
Organizar por categoria:
- job_info: Detalles de vacantes
- company: Informacion general
- benefits: Compensaciones
- process: Como funciona el proceso
- faq: Preguntas frecuentes
Paso 2: Indexar Contenido
// Indexar una fuente manualmente
await vectorSearchService.indexDocument({
id: "benefits-policy-2024",
content: policyContent,
metadata: {
type: "policy",
category: "benefits",
title: "Politica de Beneficios 2024",
owner: companyId
},
chunkingOptions: {
size: 500,
overlap: 50
}
});
Paso 3: Configurar Busqueda
// Buscar contenido relevante
const results = await vectorSearchService.search({
query: userQuestion,
filters: {
owner: companyId,
type: ["job_info", "faq", "benefits"]
},
topK: 5,
minScore: 0.7
});
Paso 4: Generar Respuesta
// Generar respuesta con contexto
const response = await generateResponse({
question: userQuestion,
context: results.chunks,
candidateInfo: {
name: candidate.name,
job: job.title
},
tone: "professional_friendly",
maxLength: 300
});
Paso 5: Manejar Casos Edge
// Manejar cuando no hay resultados
if (results.chunks.length === 0 || results.maxScore < 0.7) {
return {
response: "No tengo informacion sobre eso. Te comunico con un reclutador.",
action: "escalate",
reason: "no_rag_results"
};
}
Buenas Practicas
Calidad del Contenido
DO:
- Contenido claro y estructurado
- Informacion actualizada
- Respuestas completas
- Formato consistente
- Revisar periodicamente
DON'T:
- Informacion desactualizada
- Contenido duplicado
- Texto muy largo sin estructura
- Jerga interna confusa
- Omitir detalles importantes
Chunking Efectivo
Recomendaciones:
- Tamaño: 300-500 tokens
- Overlap: 10-20% del tamaño
- Respetar limites semanticos
- Incluir contexto en cada chunk
- Probar diferentes estrategias
Proximos Pasos
- Flow Builder - Editor visual
- Ejecucion y Monitoreo - Ver logs
- Ejemplos Practicos - Implementaciones