Saltar al contenido
Explorar conocimiento

patrón · intermedio · 4 min de lectura

Query Expansion

Query expansion genera variantes de una consulta para mejorar el recall de la recuperación, cubriendo sinónimos, paráfrasis y sub-consultas que el usuario no expresó explícitamente.

No requiere conocimientos previos.

Alcance en breve

Cubre

  • query expansion as generating multiple query variants to increase retrieval coverage
  • techniques: synonym expansion, LLM-generated paraphrases, sub-queries, and multi-query retrieval
  • precision and recall trade-offs

No cubre

  • embedding model selection
  • metadata filtering (covered separately)
  • query rewriting for structured databases (SQL)

Supone

  • The reader understands retrieval, RAG, and basic prompt engineering concepts.

Resumen

Query expansion es una técnica que toma la consulta original del usuario y genera múltiples variantes para recuperar un conjunto más amplio de documentos relevantes. En lugar de buscar una sola vez, el sistema genera varias versiones de la consulta, busca cada una, y combina los resultados.

Las técnicas comunes incluyen expansión por sinónimos, generación de paráfrasis con LLM, descomposición en sub-preguntas, y multi-query retrieval donde el LLM reformula la misma pregunta desde diferentes ángulos.

Alcance y supuestos

Este paquete cubre query expansion: técnicas, cuándo usarlas, trade-offs entre recall y precisión, y consideraciones de costo y latencia.

No cubre embedding models, metadata filtering ni re-ranking en profundidad. Asume que entiendes recuperación, RAG y conceptos básicos de prompt engineering.

Modelo mental

Piensa en un detective que recibe una descripción vaga de un sospechoso. En vez de buscar una sola vez, el detective prepara varias descripciones: "hombre alto", "persona de 1.80m", "tipo delgado de chaqueta azul". Cada versión cubre un ángulo distinto y aumenta la probabilidad de encontrar al sospechoso.

Query expansion hace lo mismo con consultas de búsqueda: más versiones, más cobertura.

Uso práctico

Usa query expansion cuando:

  • ✅ Las consultas de usuario son cortas o ambiguas ("error en app" → expandir a "error de conexión", "fallo de autenticación", "bug de interfaz").
  • ✅ El vocabulario del usuario difiere del vocabulario de los documentos.
  • ✅ Necesitas maximizar recall (encontrar todo lo relevante) aunque sea a costa de algo de precisión.
  • ❌ La consulta ya es precisa y específica ("RUT 12.345.678-9"): expandir solo agrega ruido.
  • ❌ El costo de múltiples consultas supera el beneficio para tu caso de uso.

Ejemplo trabajado: expansión con LLM para consultas de soporte

Un LLM genera variantes de la consulta original para cubrir distintos ángulos:

async function expandQuery(userQuery: string): Promise<string[]> {
  const variants = await llm.complete({
    prompt: `Genera 3 formas alternativas de preguntar lo mismo para búsqueda documental. Cada variante en una línea:\n\nUsuario: "${userQuery}"`,
  });

  const expanded = [userQuery, ...variants.trim().split("\n")];

  // Buscar con cada variante y combinar resultados
  const allResults = new Map<string, { doc: Document; scores: number[] }>();

  for (const query of expanded) {
    const results = await search(query, { topK: 5 });
    results.forEach((r, i) => {
      const existing = allResults.get(r.id);
      if (existing) {
        existing.scores.push(1 / (i + 1));
      } else {
        allResults.set(r.id, { doc: r, scores: [1 / (i + 1)] });
      }
    });
  }

  // Ordenar por score acumulado
  return [...allResults.entries()]
    .sort((a, b) => {
      const avgA = a[1].scores.reduce((s, v) => s + v, 0) / a[1].scores.length;
      const avgB = b[1].scores.reduce((s, v) => s + v, 0) / b[1].scores.length;
      return avgB - avgA;
    })
    .slice(0, 5)
    .map(([_, { doc }]) => doc);
}

El costo son N consultas en vez de 1. Pero para consultas ambiguas, el recall puede mejorar significativamente porque el sistema busca desde múltiples ángulos.

Evidencia

Fuentes citadas