Inicio / Artículos / RAG de producción en Azure: fragmentación, búsqueda híbrida, filtros y citaciones

RAG de producción en Azure: fragmentación, búsqueda híbrida, filtros y citaciones

La recuperación empresarial requiere fragmentos conscientes de la estructura, búsqueda híbrida, filtros ACL, reclasificación, prompts basados en datos concretos y evaluación, no una demostración en PDF.

1350 palabras

Las demostraciones de RAG parecen sencillas: PDF → fragmentos → embeddings → base de datos vectorial → hacer la consulta al modelo. Pero luego llegan cinco mil documentos y alguien pide la regla de reembolso para viajes internacionales. La parte difícil es incorporar de manera fiable las pruebas adecuadas al modelo.

1. Comience con los datos, no con el LLM

Evalúe las fuentes, el control de acceso, la actualidad y los formatos antes de elegir un modelo de chat. Un corpus de mala calidad genera respuestas erróneas y coherentes.

2. Fragmentación: no divida ciegamente cada N caracteres

Prefiera divisiones que tengan en cuenta la estructura (títulos, páginas, tablas) con solapamiento. Las tablas de tarifas y las cláusulas de políticas odian los métodos simples basados en caracteres.

3. Generación de embeddings

Utilice siempre la misma implementación para generar embeddings; registre la dimensión y el ID del modelo con cada índice. Mezclar modelos destruye silenciosamente la capacidad de recuperación de información.

document = {
   "document_id": "HR-2026-001",
   "title": "Employee Benefits Policy",
   "department": "HR",
   "country": "India",
   "version": "2026.1",
   "effective_date": "2026-01-01",
   "source": "HR Portal"
}
def chunk_text(text, size=1000):
   return [
     text[i:i + size]
     for i in range(0, len(text), size)
]
def chunk_by_sections(document):
  chunks = []
  for section in document.sections:
    chunks.append({
      "title": section.title,
      "content": section.text,
      "document_id": document.id
    })
  return chunks
pip install openai azure-identity
from openai import OpenAI
from azure.identity import DefaultAzureCredential, get_bearer_token_provider

token_provider = get_bearer_token_provider(
  DefaultAzureCredential(),
  "https://ai.azure.com/.default"
)

client = OpenAI(
  base_url="https://YOUR-RESOURCE.openai.azure.com/openai/v1/",
  api_key=token_provider
)

response = client.embeddings.create(
  model="text-embedding-3-small",
  input="Employees are eligible after completing 12 months of service."
)
vector = response.data[0].embedding
{
  "id": "HR-2026-001-004",
  "document_id": "HR-2026-001",
  "title": "Employee Benefits Policy",
  "content": "...",
  "country": "India",
  "version": "2026.1",
  "content_vector": embedding
}
from azure.search.documents import SearchClient
from azure.search.documents.models import VectorizedQuery

query = "Can I work remotely from another country?"

query_vector = client.embeddings.create(
  model="text-embedding-3-small",
  input=query
).data[0].embedding

vector_query = VectorizedQuery(
  vector=query_vector,
  k_nearest_neighbors=10,
  fields="content_vector"
)

results = search_client.search(
  search_text=query,
  vector_queries=[vector_query],
  top=5,
  select=["title", "content", "document_id", "country"]
)
results = search_client.search(
  search_text=query,
  vector_queries=[vector_query],
  filter="country eq 'India'",
  top=5
)
context = "\n\n".join(
  f"Source: {r['title']}\n{r['content']}"
  for r in results
)
prompt = f"""
You are an enterprise policy assistant.
Answer the user's question using only the provided evidence.
If the evidence does not contain the answer, say that you don't have enough information.
Do not invent policies.
Evidence: {context}
Question: {query}
"""
{
  "document_id": "HR-2026-001",
  "page": 14,
  "section": "Eligibility",
  "content": "..."
}
def answer_question(question):

  # 1. Embed the question
  vector = embed(question)

  # 2. Hybrid retrieval
  candidates = search(
    query=question,
    vector=vector,
    top=20
  )

  # 3. Apply metadata/business filters
  candidates = apply_filters(candidates)

  # 4. Rerank
  ranked = rerank(question, candidates)

  # 5. Keep only useful evidence
  evidence = ranked[:5]

  # 6. Build grounded prompt
  prompt = build_prompt(
    question,
    evidence
  )

  # 7. Generate answer
  response = generate(prompt)

  # 8. Return answer + citations
  return {
    "answer": response,
    "sources": extract_sources(evidence)
  }
test_cases = [
  {
    "question": "What is the India travel allowance?",
    "expected_source": "travel-policy-india.pdf"
  },
  {
    "question": "How long is parental leave?",
    "expected_source": "leave-policy-2026.pdf"
  }
]

4. Almacenar embeddings en Azure AI Search

Conservar texto, vectores y metadatos filtrables (id del documento, producto, región, grupo ACL, updated_at).

5. La búsqueda híbrida supera a la basada únicamente en vectores para la mayoría de las empresas

Combinar similitud densa con BM25/palabras clave para identificadores, códigos y nombres propios poco comunes.

6. Filtrar antes de desperdiciar contexto

Aplicar filtros de seguridad y de arrendamiento en la consulta, no después de que el modelo ya haya procesado fragmentos prohibidos.

7. La recuperación no constituye el contexto final

Volver a clasificar, eliminar duplicados y ajustar según el presupuesto de tokens. Más fragmentos ≠ respuestas mejores.

8. Construir la instrucción a partir de evidencias

Las instrucciones deben requerir respuestas únicamente de los pasajes proporcionados y indicar cuando falte evidencia.

9. Fundamentación con citas

Indique los IDs o páginas de los pasajes para que los usuarios puedan verificarlo. Una fluidez sin citaciones constituye un riesgo.

10. Un proceso listo para implementarse

Ingestión → fragmentación → incrustación → indexación → recuperación híbrida → filtrado → reclasificación → generación de prompts → creación del contenido → citaciones → evaluación.

11. Qué suele fallar

Fragmentación deficiente; metadatos de mala calidad; recuperación solo con vectores; contexto excesivo; falta de conjunto de evaluación; ausencia de citaciones; permisos ACL faltantes; cambios silenciosos en los modelos de incrustación; falta de información sobre actualización.

Cierre

RAG en producción es una recuperación de información con un endpoint de LLM integrado, no al revés. Invierta en fragmentación, búsqueda híbrida, filtros, citaciones y evaluación; el modelo de chat es solo la etapa final.

Mantenga un conjunto de preguntas estándar por dominio: búsquedas por ID exacto, preguntas para parafrasear y casos negativos de ACL. Automatícelas en CI cada vez que cambien los ajustes de particionamiento o incrustación.

Mantenga un conjunto de preguntas estándar por dominio: búsquedas por ID exacto, preguntas para parafrasear y casos negativos de ACL. Automatícelas en CI cada vez que cambien los ajustes de particionamiento o incrustación.

Mantenga un conjunto de preguntas estándar por dominio: búsquedas por ID exacto, preguntas para parafrasear y casos negativos de ACL. Automatícelas en CI cada vez que cambien los ajustes de particionamiento o incrustación.

Mantenga un conjunto de preguntas estándar por dominio: búsquedas por ID exacto, preguntas para parafrasear y casos negativos de ACL. Automatícelas en CI cada vez que cambien los ajustes de particionamiento o incrustación.

Mantenga un conjunto de preguntas estándar por dominio: búsquedas por ID exacto, preguntas para parafrasear y casos negativos de ACL. Automatícelas en CI cada vez que cambien los ajustes de particionamiento o incrustación.

Mantenga un conjunto de preguntas estándar por dominio: búsquedas por ID exacto, preguntas para parafrasear y casos negativos de ACL. Automatícelas en CI cada vez que cambien los ajustes de particionamiento o incrustación.

Mantenga un conjunto de preguntas estándar por dominio: búsquedas por ID exacto, preguntas para parafrasear y casos negativos de ACL. Automatícelas en CI cada vez que cambien los ajustes de particionamiento o incrustación.

Mantenga un conjunto de preguntas estándar por dominio: búsquedas por ID exacto, preguntas para parafrasear y casos negativos de ACL. Automatícelas en CI cada vez que cambien los ajustes de particionamiento o incrustación.

Mantenga un conjunto de preguntas estándar por dominio: búsquedas por ID exacto, preguntas para parafrasear y casos negativos de ACL. Automatícelas en CI cada vez que cambien los ajustes de particionamiento o incrustación.

Mantenga un conjunto de preguntas estándar por dominio: búsquedas por ID exacto, preguntas para parafrasear y casos negativos de ACL. Automatícelas en CI cada vez que cambien los ajustes de particionamiento o incrustación.

Mantenga un conjunto de preguntas estándar por dominio: búsquedas por ID exacto, preguntas para parafrasear y casos negativos de ACL. Automatícelas en CI cada vez que cambien los ajustes de particionamiento o incrustación.

Mantenga un conjunto de preguntas estándar por dominio: búsquedas por ID exacto, preguntas para parafrasear y casos negativos de ACL. Automatícelas en CI cada vez que cambien los ajustes de particionamiento o incrustación.

Mantenga un conjunto de preguntas estándar por dominio: búsquedas por ID exacto, preguntas para parafrasear y casos negativos de ACL. Automatícelas en CI cada vez que cambien los ajustes de particionamiento o incrustación.

Mantenga un conjunto de preguntas estándar por dominio: búsquedas por ID exacto, preguntas para parafrasear y casos negativos de ACL. Automatícelas en CI cada vez que cambien los ajustes de particionamiento o incrustación.

Mantenga un conjunto de preguntas estándar por dominio: búsquedas por ID exacto, preguntas para parafrasear y casos negativos de ACL. Automatícelas en CI cada vez que cambien los ajustes de particionamiento o incrustación.

Mantenga un conjunto de preguntas estándar por dominio: búsquedas por ID exacto, preguntas para parafrasear y casos negativos de ACL. Automatícelas en CI cada vez que cambien los ajustes de particionamiento o incrustación.

Mantenga un conjunto de preguntas estándar por dominio: búsquedas por ID exacto, preguntas para parafrasear y casos negativos de ACL. Automatícelas en CI cada vez que cambien los ajustes de particionamiento o incrustación.

Mantenga un conjunto de preguntas estándar por dominio: búsquedas por ID exacto, preguntas para parafrasear y casos negativos de ACL. Automatícelas en CI cada vez que cambien los ajustes de particionamiento o incrustación.

Mantenga un conjunto de preguntas estándar por dominio: búsquedas por ID exacto, preguntas para parafrasear y casos negativos de ACL. Automatícelas en CI cada vez que cambien los ajustes de particionamiento o incrustación.

Mantenga un conjunto de preguntas estándar por dominio: búsquedas por ID exacto, preguntas para parafrasear y casos negativos de ACL. Automatícelas en CI cada vez que cambien los ajustes de particionamiento o incrustación.

La evaluación debe encontrarse en el mismo repositorio que la configuración de particionamiento: cuando alguien “solo ajusta” los solapamientos, el paquete de referencia debe fallar antes de que los usuarios se den cuenta.

La búsqueda híbrida sigue necesitando buenos analizadores y listas de sinónimos para el jerga del dominio; los embeddings por sí solos no podrán corregir un código de política escrito incorrectamente.

Documente el contrato del campo ACL en una sola página para que cada nueva tarea de ingreso escriba las mismas afirmaciones que espera el filtro de recuperación.

La evaluación debe encontrarse en el mismo repositorio que la configuración de particionamiento: cuando alguien “solo ajusta” los solapamientos, el paquete de referencia debe fallar antes de que los usuarios se den cuenta.

Lecturas relacionadas

  • Preguntas y respuestas sobre PDFs Grounded en Azure AI Search y agentes Foundry — Indexar PDFs de cursos privados con embeddings, conectar un agente Foundry al índice vectorial y solucionar los problemas de autenticación e instrucciones que hacen que RAG parezca defectuoso.
  • Cuando las citas parecen perfectas y el número de empleados sigue estando incorrecto — Un sistema RAG para salarios citó el PDF correcto pero siguió contando erróneamente a doce empleados como uno solo; la búsqueda híbrida, la compresión sensible a tablas y los seguimientos de pipeline lo solucionaron.