19 KiB
19 KiB
RF-MGN-018-002: Bases de Conocimiento
Módulo: MGN-018 - AI Agents & Chatbots Prioridad: P1 Story Points: 13 Estado: Definido Fecha: 2025-12-05
Descripción
El sistema debe permitir crear bases de conocimiento (Knowledge Bases) que los agentes de IA pueden consultar para dar respuestas precisas basadas en información específica del tenant. Las bases de conocimiento soportan documentos en múltiples formatos que se procesan, segmentan y vectorizan para búsqueda semántica (RAG).
Actores
- Actor Principal: Tenant Admin
- Actores Secundarios:
- Sistema (procesa y vectoriza documentos)
- AI Agent (consulta KB)
- Embedding API (genera vectores)
Precondiciones
- Tenant debe tener feature
ai_agents_enabled - Créditos de IA suficientes para procesamiento
- Espacio de almacenamiento disponible según plan
Flujo Principal - Crear Base de Conocimiento
- Admin accede a "AI Agents > Bases de Conocimiento"
- Admin selecciona "Nueva Base de Conocimiento"
- Admin ingresa nombre y descripción
- Admin configura opciones:
- Idioma principal
- Modelo de embeddings
- Chunk size y overlap
- Sistema crea KB vacía
- Admin sube documentos
- Sistema procesa cada documento:
- Extrae texto
- Segmenta en chunks
- Genera embeddings
- Almacena en vector store
- Sistema confirma procesamiento exitoso
- Admin asigna KB a uno o más agentes
Flujo Alternativo - Agregar Documentos
- Admin accede a KB existente
- Admin selecciona "Agregar documentos"
- Admin arrastra archivos o usa selector
- Sistema valida formato y tamaño
- Sistema encola para procesamiento
- Sistema notifica cuando procesamiento termina
- Documentos quedan disponibles para consulta
Formatos Soportados
| Formato | Extensiones | Límite Tamaño | Notas |
|---|---|---|---|
| 50 MB | OCR si es escaneado | ||
| Word | .docx, .doc | 25 MB | Preserva estructura |
| Excel | .xlsx, .xls | 10 MB | Cada hoja como documento |
| PowerPoint | .pptx, .ppt | 50 MB | Texto de slides |
| Texto | .txt, .md | 10 MB | Plain text |
| HTML | .html, .htm | 10 MB | Extrae texto limpio |
| CSV | .csv | 10 MB | Filas como documentos |
| JSON | .json | 10 MB | Estructurado |
Procesamiento de Documentos
Pipeline de Procesamiento
┌─────────────┐ ┌─────────────┐ ┌─────────────┐
│ Upload │────▶│ Parser │────▶│ Chunker │
│ File │ │ (Format) │ │ │
└─────────────┘ └─────────────┘ └─────────────┘
│
▼
┌─────────────┐ ┌─────────────┐ ┌─────────────┐
│ Store │◀────│ Vector │◀────│ Embedding │
│ (pgvector)│ │ Index │ │ Generator │
└─────────────┘ └─────────────┘ └─────────────┘
Chunking Strategy
interface ChunkingConfig {
strategy: 'fixed' | 'semantic' | 'paragraph';
// Para fixed strategy
chunk_size: number; // Caracteres por chunk (default: 1000)
chunk_overlap: number; // Solapamiento (default: 200)
// Para semantic strategy
max_chunk_size: number;
min_chunk_size: number;
separator_regex?: string;
// Metadata a incluir
include_title: boolean;
include_page_number: boolean;
include_source_url: boolean;
}
Modelo de Embeddings
interface EmbeddingConfig {
provider: 'openai' | 'cohere' | 'custom';
model: string; // "text-embedding-3-small", "text-embedding-3-large"
dimensions: number; // 1536 para OpenAI small
// Procesamiento batch
batch_size: number; // Chunks por llamada API
concurrent_batches: number;
}
Búsqueda RAG
Query Processing
interface RAGQuery {
query: string;
knowledge_base_ids: string[];
// Opciones de búsqueda
top_k: number; // Número de chunks a retornar (default: 5)
similarity_threshold: number; // Mínimo de similitud (default: 0.7)
rerank?: boolean; // Re-ranking de resultados
// Filtros
filters?: {
document_ids?: string[];
metadata?: Record<string, any>;
date_range?: { from: Date; to: Date };
};
}
interface RAGResult {
chunks: Array<{
content: string;
document_id: string;
document_name: string;
page_number?: number;
similarity_score: number;
metadata: Record<string, any>;
}>;
// Contexto formateado para LLM
formatted_context: string;
// Estadísticas
search_time_ms: number;
total_chunks_searched: number;
}
Reglas de Negocio
- RN-1: Máximo de KBs según plan (ej: 3 para Professional)
- RN-2: Máximo de documentos por KB según plan
- RN-3: Tamaño total de KB según plan (ej: 500MB)
- RN-4: Documentos duplicados se detectan y evitan
- RN-5: Re-procesamiento consume créditos adicionales
- RN-6: KBs no asignadas a agentes no se consultan
- RN-7: Eliminar documento elimina todos sus chunks
Criterios de Aceptación
- Admin puede crear KB con nombre y configuración
- Todos los formatos de documento soportados
- Progress bar durante procesamiento
- Vista de chunks generados por documento
- Búsqueda de prueba disponible
- Asignación de KB a múltiples agentes
- Estadísticas de uso de KB
- Eliminar documentos individual o masivamente
- Re-procesar documentos si hay errores
- Exportar lista de documentos
Entidades Involucradas
ai_agents.knowledge_bases
CREATE TABLE ai_agents.knowledge_bases (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
tenant_id UUID NOT NULL REFERENCES core_tenants.tenants(id),
-- Información básica
name VARCHAR(100) NOT NULL,
description TEXT,
language VARCHAR(10) DEFAULT 'es',
-- Configuración de chunking
chunking_config JSONB DEFAULT '{
"strategy": "fixed",
"chunk_size": 1000,
"chunk_overlap": 200
}',
-- Configuración de embeddings
embedding_config JSONB DEFAULT '{
"provider": "openai",
"model": "text-embedding-3-small",
"dimensions": 1536
}',
-- Estado
status VARCHAR(20) DEFAULT 'active',
-- Estadísticas
total_documents INT DEFAULT 0,
total_chunks INT DEFAULT 0,
total_size_bytes BIGINT DEFAULT 0,
total_tokens_used BIGINT DEFAULT 0,
-- Timestamps
created_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP,
last_queried_at TIMESTAMPTZ,
created_by UUID,
CONSTRAINT chk_status CHECK (status IN ('active', 'processing', 'archived'))
);
CREATE INDEX idx_kb_tenant ON ai_agents.knowledge_bases(tenant_id);
ai_agents.kb_documents
CREATE TABLE ai_agents.kb_documents (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
knowledge_base_id UUID NOT NULL REFERENCES ai_agents.knowledge_bases(id) ON DELETE CASCADE,
-- Información del archivo
original_filename VARCHAR(255) NOT NULL,
file_type VARCHAR(20) NOT NULL, -- pdf, docx, txt, etc.
file_size_bytes BIGINT NOT NULL,
storage_path VARCHAR(500), -- Path en cloud storage
-- Procesamiento
status VARCHAR(20) NOT NULL DEFAULT 'pending',
-- pending, processing, completed, failed
processing_started_at TIMESTAMPTZ,
processing_completed_at TIMESTAMPTZ,
error_message TEXT,
-- Resultados
chunks_count INT DEFAULT 0,
pages_count INT,
tokens_used INT DEFAULT 0,
-- Metadata extraída
title VARCHAR(500),
author VARCHAR(200),
created_date DATE,
custom_metadata JSONB DEFAULT '{}',
-- Hash para detectar duplicados
content_hash VARCHAR(64), -- SHA-256 del contenido
-- Timestamps
created_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP,
created_by UUID,
CONSTRAINT chk_doc_status CHECK (status IN ('pending', 'processing', 'completed', 'failed'))
);
CREATE INDEX idx_kb_docs_kb ON ai_agents.kb_documents(knowledge_base_id);
CREATE INDEX idx_kb_docs_status ON ai_agents.kb_documents(status);
CREATE INDEX idx_kb_docs_hash ON ai_agents.kb_documents(content_hash);
ai_agents.kb_chunks
-- Usar extensión pgvector
CREATE EXTENSION IF NOT EXISTS vector;
CREATE TABLE ai_agents.kb_chunks (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
document_id UUID NOT NULL REFERENCES ai_agents.kb_documents(id) ON DELETE CASCADE,
knowledge_base_id UUID NOT NULL REFERENCES ai_agents.knowledge_bases(id) ON DELETE CASCADE,
tenant_id UUID NOT NULL, -- Para particionamiento y queries rápidos
-- Contenido
content TEXT NOT NULL,
content_tokens INT NOT NULL,
-- Posición en documento
chunk_index INT NOT NULL,
page_number INT,
start_char INT,
end_char INT,
-- Vector embedding
embedding vector(1536), -- Dimensión de OpenAI text-embedding-3-small
-- Metadata
metadata JSONB DEFAULT '{}',
-- {
-- "title": "Sección 2.1",
-- "headers": ["Capítulo 2", "Introducción"],
-- "source_url": "https://..."
-- }
created_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP
);
-- Índices para búsqueda vectorial
CREATE INDEX idx_kb_chunks_document ON ai_agents.kb_chunks(document_id);
CREATE INDEX idx_kb_chunks_kb ON ai_agents.kb_chunks(knowledge_base_id);
CREATE INDEX idx_kb_chunks_tenant ON ai_agents.kb_chunks(tenant_id);
-- Índice HNSW para búsqueda de similitud (mejor rendimiento)
CREATE INDEX idx_kb_chunks_embedding ON ai_agents.kb_chunks
USING hnsw (embedding vector_cosine_ops)
WITH (m = 16, ef_construction = 64);
ai_agents.kb_agent_assignments
CREATE TABLE ai_agents.kb_agent_assignments (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
agent_id UUID NOT NULL REFERENCES ai_agents.agents(id) ON DELETE CASCADE,
knowledge_base_id UUID NOT NULL REFERENCES ai_agents.knowledge_bases(id) ON DELETE CASCADE,
-- Configuración específica para este agente
priority INT DEFAULT 1, -- Si hay múltiples KBs, orden de búsqueda
search_weight DECIMAL(3,2) DEFAULT 1.0, -- Peso en resultados
created_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP,
CONSTRAINT uq_agent_kb UNIQUE (agent_id, knowledge_base_id)
);
API Endpoints
Crear Knowledge Base
// POST /api/v1/knowledge-bases
interface CreateKBRequest {
name: string;
description?: string;
language?: string;
chunking_config?: ChunkingConfig;
embedding_config?: EmbeddingConfig;
}
Subir Documentos
// POST /api/v1/knowledge-bases/{id}/documents
// Content-Type: multipart/form-data
// Response
interface UploadResponse {
document_id: string;
filename: string;
status: 'pending';
estimated_processing_time_seconds: number;
}
Consultar Estado de Procesamiento
// GET /api/v1/knowledge-bases/{id}/documents/{docId}/status
interface ProcessingStatus {
status: 'pending' | 'processing' | 'completed' | 'failed';
progress_percent?: number;
chunks_created?: number;
error_message?: string;
}
Búsqueda de Prueba
// POST /api/v1/knowledge-bases/{id}/search
interface SearchRequest {
query: string;
top_k?: number;
similarity_threshold?: number;
}
interface SearchResponse {
results: Array<{
content: string;
document_name: string;
page_number?: number;
similarity_score: number;
}>;
search_time_ms: number;
}
Función de Búsqueda Vectorial
-- Función para búsqueda semántica
CREATE OR REPLACE FUNCTION ai_agents.search_knowledge_base(
p_tenant_id UUID,
p_kb_ids UUID[],
p_query_embedding vector(1536),
p_top_k INT DEFAULT 5,
p_similarity_threshold DECIMAL DEFAULT 0.7
)
RETURNS TABLE (
chunk_id UUID,
document_id UUID,
document_name VARCHAR,
content TEXT,
page_number INT,
similarity_score DECIMAL
) AS $$
BEGIN
RETURN QUERY
SELECT
c.id,
c.document_id,
d.original_filename,
c.content,
c.page_number,
(1 - (c.embedding <=> p_query_embedding))::DECIMAL AS similarity
FROM ai_agents.kb_chunks c
JOIN ai_agents.kb_documents d ON c.document_id = d.id
WHERE c.tenant_id = p_tenant_id
AND c.knowledge_base_id = ANY(p_kb_ids)
AND d.status = 'completed'
AND (1 - (c.embedding <=> p_query_embedding)) >= p_similarity_threshold
ORDER BY c.embedding <=> p_query_embedding
LIMIT p_top_k;
END;
$$ LANGUAGE plpgsql;
Interfaz de Usuario
Vista de Knowledge Base
┌─────────────────────────────────────────────────────────────────┐
│ 📚 Base de Conocimiento: Productos 2025 │
├─────────────────────────────────────────────────────────────────┤
│ │
│ Documentos: 24 Chunks: 1,458 Tamaño: 45.2 MB │
│ │
│ [+ Agregar documentos] [⚙️ Configuración] [🔍 Probar búsqueda]│
│ │
├─────────────────────────────────────────────────────────────────┤
│ │
│ ☐ Nombre Tipo Tamaño Estado Chunks │
│ ───────────────────────────────────────────────────────────────│
│ ☐ catalogo-2025.pdf PDF 12.4 MB ✅ Listo 342 │
│ ☐ manual-usuario.docx DOCX 2.1 MB ✅ Listo 89 │
│ ☐ precios-mayoreo.xlsx XLSX 1.2 MB ✅ Listo 156 │
│ ☐ faq-clientes.md MD 45 KB ✅ Listo 23 │
│ ☐ politicas-devolucion.pdf PDF 890 KB ⏳ 45% - │
│ │
│ [Eliminar seleccionados] │
└─────────────────────────────────────────────────────────────────┘
Modal de Búsqueda de Prueba
┌─────────────────────────────────────────────────────────────────┐
│ 🔍 Probar Búsqueda en Knowledge Base │
├─────────────────────────────────────────────────────────────────┤
│ │
│ Consulta: │
│ ┌─────────────────────────────────────────────────────────────┐│
│ │ ¿Cuál es la política de devoluciones para productos ││
│ │ electrónicos? ││
│ └─────────────────────────────────────────────────────────────┘│
│ │
│ Top K: [5 ▼] Umbral similitud: [0.7 ▼] [🔍 Buscar] │
│ │
├─────────────────────────────────────────────────────────────────┤
│ │
│ Resultados (3 encontrados en 45ms): │
│ │
│ ┌───────────────────────────────────────────────────────────┐ │
│ │ 📄 politicas-devolucion.pdf (pág. 3) Score: 0.92 │ │
│ │ │ │
│ │ "Los productos electrónicos tienen un período de │ │
│ │ devolución de 30 días desde la fecha de compra..." │ │
│ └───────────────────────────────────────────────────────────┘ │
│ │
│ ┌───────────────────────────────────────────────────────────┐ │
│ │ 📄 faq-clientes.md Score: 0.85 │ │
│ │ │ │
│ │ "P: ¿Puedo devolver un televisor? R: Sí, dentro de..." │ │
│ └───────────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────┘
Referencias
Dependencias
- RF Requeridos: RF-018-001 (Configuración de Agentes)
- Bloqueante para: RF-018-003 (Procesamiento de Mensajes)