Agente 404
Agente 404
Volver al blog
Inteligencia Artificial

RAG en producción sobre pgvector: chunking semántico y rerank eficiente

Implementar RAG sólido en producción sobre pgvector implica aciertos y errores en chunking, rerank y costes a volumen. En Agente 404 desglosamos los patrones que escalan y ahorran €.

20 de abril de 20265 min de lectura
RAG en producción sobre pgvector: chunking semántico y rerank eficiente

Integrar Retrieval-Augmented Generation (RAG) basado en PostgreSQL y pgvector permite incorporar conocimiento propio a modelos de IA generativa. El flujo típico —indexar textos, recuperar embeddings, consultar con LLM— parece trivial en entorno demo, pero la fricción real llega con miles o millones de consultas, latencias constantes de sub-600ms, y datasets con cientos de millones de tokens.

En este artículo veremos cómo llevamos RAG en producción usando chunking semántico y rerank avanzado con OpenAI y Anthropic sobre pgvector, optimizando costes, throughput y calidad para cargas reales de negocio.

Arquitectura RAG sobre pgvector: mínimo necesario para escalar

Stack y patrones de integración

  • Backend en Node.js (TypeScript 5.4) o Python (FastAPI 0.110+, asyncio) para servir queries y orquestar pipelines.
  • PostgreSQL Aurora con extensión pgvector 0.7+ para el almacenamiento de embeddings y metadatos.
  • Embeddings generados con OpenAI text-embedding-3-large (1536 dims) o Anthropic claude-3-embeddings-v1.
  • Redis (Upstash) opcional para caching semántico y control de consultas repetidas.
  • AWS Lambda y Vercel Functions para ejecución sin servidor y autoescalado crítico.
«Una consulta típica RAG a 10 documentos candidatos consume ~0,0025$ en embeddings y LLM (OpenAI), pero cada 100ms extra y cada consulta fallida suma en costes de soporte y frustración»

Diagrama simplificado del pipeline

  • Usuario realiza una consulta (prompt).
  • El backend genera embedding del prompt.
  • Consulta a SELECT ... ORDER BY embedding <=> $embedding LIMIT k en pgvector para k candidatos.
  • Opcional: rerank semántico en backend o con LLM.
  • Prompt final a LLM (OpenAI, Anthropic) con contexto top-N.

Fragmento real de consulta con pgvector

WITH query_embedding AS (
  SELECT '[[embedding vector aquí]]'::vector(1536) AS embedding
)
SELECT id, content, metadata, embedding <=> query_embedding.embedding AS distance
FROM documents, query_embedding
WHERE metadata->>'status' = 'active'
ORDER BY embedding <=> query_embedding.embedding
LIMIT 10;

Chunking semántico en la indexación: errores típicos y patrones que escalan

¿Por qué importa el chunking?

  • Chunks demasiado pequeños (ej. 100-200 tokens): contexto poco relevante, incremento de queries, más coste en prompt.
  • Chunks grandes (>1.500 tokens): embeddings diluidos, latencias altas en postgres, pérdida de granularidad.
Chunk sizeMétricaVentajaProblema típico
100-200 tokens~96% recall@10Rápido, cheapContexto pobre
400-600 tokens~91% precision@3Equilibrio memoria/calidadPrompt largo si top-k grande
1500-2000 tokens~70% recall@10Menos queriesLatencia y embeddings peores

Implementar chunking semántico en Python

from nltk.tokenize import sent_tokenize
from typing import List

MAX_TOKENS = 512

def chunk_text_semantic(text: str) -> List[str]:
    sentences = sent_tokenize(text)
    chunks = []
    buffer = []
    tokens = 0
    for sentence in sentences:
        sentence_tokens = len(sentence.split())
        if tokens + sentence_tokens > MAX_TOKENS:
            chunks.append(' '.join(buffer))
            buffer = [sentence]
            tokens = sentence_tokens
        else:
            buffer.append(sentence)
            tokens += sentence_tokens
    if buffer:
        chunks.append(' '.join(buffer))
    return chunks
  • La variabilidad semántica se maximiza usando puntuación y entidades como delimitadores, no cortes ciegos por token.
  • Nuestros experimentos muestran reducción de 12% en queries fallidas a LLM ajustando de 200 a 500 tokens por chunk.

Rerank: cuándo y cómo aplicar reranqueado embebido y con LLM

¿Por qué rerank?

  • PostgreSQL/pgvector ofrece ANN exacto o aproximado, pero ignora matices sintácticos y órdenes lógicos.
  • El rerank mejora la relevancia real según el usuario y permite filtrar «falsos positivos semánticos».

Opciones de rerank aplicadas en Agente 404

MétodoCoste consultaLatencia mediaPrecisión top-3
Solo embedding~0,00002$30ms72%
Rerank ML (bm25+ o reranker MiniLM)~0,00012$110ms81%
LLM rerank (OpenAI v4)~0,00110$620ms93%
import { Configuration, OpenAIApi } from 'openai';
const openai = new OpenAIApi(new Configuration({ apiKey: process.env.OPENAI_API_KEY }));

async function rerankWithLLM(query: string, docs: Array<{id: string, content: string}>): Promise<string[]> {
  const prompt = `Dado la consulta: "${query}", ordénalos por relevancia:\n` +
                docs.map((d, i) => `${i+1}. ${d.content}`).join('\n');
  const res = await openai.createChatCompletion({
    model: 'gpt-4-1106-preview',
    messages: [{ role: 'user', content: prompt }],
    functions: [
      {
        name: "rank_documents",
        parameters: {
          type: "object",
          properties: {
            order: {
              type: "array",
              items: { type: "string" }
            }
          },
          required: ["order"]
        }
      }
    ],
    function_call: { name: 'rank_documents' },
    temperature: 0.0,
    max_tokens: 80
  });
  return res.data.choices[0].message.function_call.arguments.order;
}
  • Restringimos el rerank LLM a los top-7 chunks para controlar el coste (<0,0015$/query rondando 500 tokens totales).
  • Alternar entre embeddings-only o rerank LLM puede hacerse con threshold sobre score, ajustando precisión y presupuesto.

Optimización de consultas de alto volumen: claves prácticas

  1. Batch embeddings en backend: cada llamada a embedding API ahorra hasta 70% de latencia agrupando 10-20 queries (< 320ms OpenAI, 16ms/embedding).
  2. Caching semántico: Redis Upstash reduce hasta un 38% el tráfico a LLM en queries repetitivas, con hit rate >70% en flujos internos.
  3. CTEs para filtrado y logging: añade trazabilidad y filtros de permisos en SQL en una sola consulta.
  4. Colas y reintentos: integración con AWS SQS o Upstash Queue, backoff exponencial de hasta 5 reintentos en errores 429/5xx.
WITH context AS (
    SELECT id, content, embedding <=> $embedding AS dist
    FROM documents
    WHERE org_id = $org AND published = TRUE
    ORDER BY embedding <=> $embedding
    LIMIT 15
),
filtered AS (
    SELECT * FROM context WHERE dist < 0.35
)
INSERT INTO rag_queries(query, docs, org_id, ts)
SELECT $query, array_agg(id), $org, NOW()
FROM filtered;
  • Con currencía de 50+ queries/s y sizing correcto de Aurora (r6g.xlarge), mantenemos P95 < 170ms en retrieval incluyendo CTE.

Evaluación: LLM-as-judge y métricas objetivas en producción

Evaluar relevance en pipelines reales

  • Recurrimos a LLM-as-judge con prompts que piden «score relevance 1-5» y explicaciones de error para 2000+ queries de test cada semana.
  • Automatizamos evals con OpenAI SDK v4.77+ y script de logging continuo a S3/Aurora con anomalías >25% detectadas vía SQL y alertadas por Slack/GitHub.
import openai

async def llm_judge_eval(query, candidates, answer):
    prompt = f"""
    Consulta de usuario: {query}
    Contexto proporcionado: {candidates}
    Respuesta LLM: {answer}
    Evalúa la relevancia del contexto (1-5) y justifica.
    """
    completion = await openai.ChatCompletion.acreate(
        model="gpt-4-1106-preview",
        messages=[{"role": "user", "content": prompt}],
        max_tokens=120,
        temperature=0
    )
    return completion.choices[0].message.content
Estrategia evaluaciónAutomatizaciónCoberturaInsourcing necesario
Annotadores humanosNo<25%~120h/mes
LLM-as-judge>95%<5h/mes

Insight para CTO

«Automatizar la evaluación RAG con LLM reduce necesidad de insourcing hasta 40x, sacrificando < 8 puntos de correlación humana»

Impacto en la operación: cifras y riesgos de no optimizar

  • Reducir el chunk size a límites óptimos (400-600 tokens) recorta prompts de LLM un 33%, baja latencias pico de >1.4s a ~700ms y reduce coste de OpenAI en ~28% (casos reales retail y seguros).
  • Caching semántico y rerank solo LLM en top-5 ha bajado gasto mensual de inferencia de 960€ a 620€ en clientes con >50.000 queries/mes.
  • Sin evals automatizadas con LLM, la detección de regresión de calidad llevaba semanas; ahora, minutos (< 5 min MTTR secuencia incidentes-contexto mal recuperado).
  • Requisitos directos para CTO/director IT: escalar a 200QPS sin pérdidas de precisión, costes controlados bajo 0,005€/query, trazabilidad para auditoría y supervisión.
«Detectar errores de chunking o rerank tardíamente puede dilapidar hasta 2 FTEs mensuales en soporte/QA manual»

En Agente 404 implementamos diagnósticos RAG con pruebas de chunking, benchmarking y trazabilidad para sistemas sobre pgvector: encajando cifra, patrón y vínculo técnico-negocio. Consúltanos si necesitas un assessment de RAG en producción.

Te resulto util?

Compartelo con quien pueda necesitarlo

Listo para automatizar tu operacion?

Agenda una llamada de 30 minutos. Sin compromiso.