De un enfoque ingenuo a una implementación RAG en documentos de 10-K de la SEC: fragmentación y búsqueda híbrida.
Por qué falló la pipeline RAG de un libro de texto en documentos de 10-K de 300 páginas y las soluciones: fragmentos según la sección, recuperación híbrida, reclasificación con codificador cruzado, validación y citas de metadatos.
Fuentes: **How I Built a RAG Pipeline on Legal & Financial Documents and What Actually Broke?**
Un pipeline que parecía correcto pero devolvía resultados erróneos
Imagínese un pipeline RAG para los informes SEC 10-K que tomó tres semanas en construirse, con integración de LangChain, ChromaDB como almacén vectorial, un script de ingesta en Python bien estructurado y una interfaz Streamlit pulida. Una primera prueba sencilla consiste en determinar qué aspectos críticos de la auditoría se relacionan con el reconocimiento de ingresos. El sistema responde, completamente seguro de sí mismo, sobre la compensación de los ejecutivos, de una sección completamente diferente. “Alucinación” no es del todo la palabra adecuada. El texto es real, pero proviene de la sección incorrecta de un documento de 300 páginas, y el sistema no se dio cuenta de nada.
Parecerse a un sistema RAG y funcionar como uno son cosas diferentes. A continuación se presentan las decisiones de fragmentación, los fallos en la recuperación de información, los experimentos con embeddings, el conjunto de evaluación creado por necesidad, y la versión que finalmente redujo la revisión manual en un 65%. Cualquiera que desarrolle funcionalidades basadas en LLMs a partir de documentos reales, y no de PDFs ficticios, puede ahorrarse semanas de aprendizaje improductivo.
Por qué es difícil recuperar información de los informes 10-K
Tratar un informe 10-K como un PDF ordinario es subestimarlo. Un documento presentado por una empresa pública de tamaño medio o grande tiene de 150 a 400 páginas, con tablas financieras, notas al pie que hacen referencia a otras notas, textos legales que se extienden por decenas de páginas, descripciones de riesgos y comentarios de la dirección. El objetivo de la recuperación era identificar los Asuntos Críticos de Auditoría (CAM, por sus siglas en inglés), donde los auditores explican las áreas más complejas o que requieren mayor juicio en su trabajo.
Lo que un lector desea encontrar, como términos relacionados con riesgos y juicios de auditoría, está distribuido de manera desigual. Está concentrado en ciertas secciones, escrito en vocabulario especializado y vinculado a cifras que carecen de significado fuera de contexto. Al tratar el documento como un conjunto de fragmentos aislados, el sistema de recuperación elige la mayoría de las veces los incorrectos, exactamente como lo hizo la primera versión.
Dos métodos uno al lado del otro
La diferencia entre las versiones contiene todas las lecciones aprendidas.
La versión 1 seguía el diseño típico de los libros de texto: se ingresaba el PDF, se dividía en fragmentos de 500 tokens con una superposición de 50 tokens, se integraban mediante el modelo text-embedding-ada-002 de OpenAI, se almacenaban en ChromaDB, se recuperaban los 5 fragmentos más relevantes para una consulta y se pasaban a GPT-4 para generar un resumen. Funcionaba bien con consultas simples en documentos limpios, pero fallaba de tres maneras específicas al tratar con un archivo denso de 300 páginas.
Version 2 cuenta con muchas más etapas: ingestión de PDF, una capa de detección de secciones, particionamiento consciente de las secciones con tamaños que varían según el tipo de sección, etiquetado de metadatos para cada fragmento, un modelo de incrustación consciente del dominio, almacenamiento en ChromaDB con metadatos detallados, reescritura de consultas, recuperación híbrida (semántica más por palabras clave), reclasificación, validación y, finalmente, generación. Cada etapa existe por una razón, la cual se explicará a continuación.
Primer problema: los fragmentos fijos separan el contexto
El error más básico de la V1 era el uso de fragmentos de 500 tokens, que se dividían dondequiera que cayera ese conteo. Un documento 10-K está naturalmente estructurado. Un CAM consta de un encabezado, una descripción, la respuesta del auditor y, con frecuencia, un enlace a una nota financiera; su longitud puede llegar a 600 o 800 tokens. Dividirlo en partes de 500 tokens solía partir un CAM por la mitad, con la descripción en un fragmento y la respuesta en otro, por lo que ninguno de ellos era útil por sí solo.
La solución consistió en añadir una capa de detección de secciones antes del proceso de fragmentación. pdfplumber analizó la estructura del documento para identificar los límites de las secciones, los títulos, los subtítulos y los bordes de las tablas, y luego la fragmentación se realizó dentro de cada sección y no entre ellas, utilizando tamaños que respetaban los saltos naturales. Las tablas financieras densas se dividieron en fragmentos pequeños de aproximadamente 200 a 300 tokens para mantener la posibilidad de buscar detalles a nivel de fila. Las secciones narrativas como los informes de riesgos recibieron fragmentos más grandes, de hasta 800 a 900 tokens, para preservar la integridad de cada unidad lógica. La superposición entre fragmentos se mantuvo en el 10% del tamaño de cada uno. Este único cambio mejoró notablemente la relevancia de las búsquedas antes de realizar cualquier otra modificación.
Segundo problema: embeddings que no capturaban el lenguaje financiero
text-embedding-ada-002 es un modelo versátil y potente, aunque no fue entrenado específicamente en texto financiero o legal, y esa limitación se hace evidente con documentos de auditoría densos. Una consulta sobre las áreas de juicio en el reconocimiento de ingresos obtuvo fragmentos relacionados con los ingresos y con el concepto de juicio en general. Algunos provenían de discusiones de la dirección, otros de notas al pie y unos pocos de declaraciones de riesgos no relacionadas, y el propio CAM para el reconocimiento de ingresos no se encontró de manera fiable.
Se probaron dos alternativas. El modelo más reciente de OpenAI, text-embedding-3-large, mejoró de manera significativa la calidad de la recuperación de información. Un enfoque híbrido que combinó la búsqueda vectorial densa con la búsqueda por palabras clave BM25 dispersa y fusionó los resultados superó a cualquiera de los métodos por separado. La lógica es sencilla: la recuperación densa encuentra contenido conceptualmente relacionado, mientras que la recuperación dispersa encuentra terminología exacta. En textos financieros, la redacción exacta es de suma importancia. “Asunto crítico de auditoría” no es lo mismo que “problema significativo de auditoría” en el lenguaje legal, y contar con ambos aumenta sustancialmente la precisión. La parte basada en búsqueda dispersa utilizó la biblioteca Python rank_bm25, y una función simple de fusión de rangos recíprocos combinó las dos listas de resultados antes de realizar un nuevo ordenamiento.
Tercer fallo: falta de validación, respuestas erróneas seguras
Este fue el problema más silencioso y peligroso. En V1, los fragmentos defectuosos obtenidos de la recuperación seguían haciendo que el LLM respondiera, y GPT-4 es muy bueno para parecer seguro de sí mismo con poco contexto. Sus respuestas no eran obviamente incorrectas; eran resúmenes plausibles de los fragmentos que llegaban, incluso cuando esos fragmentos provenían de la parte incorrecta del documento.
Solo un pequeño conjunto de evaluación reveló el problema: 30 pares de pregunta y respuesta verificados a mano contra documentos específicos, cada uno etiquetado con los fragmentos de origen exactos que deberían aparecer. Según estas pruebas, V1 recuperaba los fragmentos de origen correctos en aproximadamente el 55% de los casos, mientras que en el 45% restante generaba texto coherente basado en material irrelevante.
Dos cambios solucionaron el problema. El primero fue una etapa de reclasificación: un codificador cruzado de HuggingFace llamado ms-marco-MiniLM-L-6-v2 volvió a calificar los diez fragmentos recuperados, y solo los tres mejores pasaron al generador. Los codificadores cruzados funcionan más lentamente que los biencodificadores, pero clasifican con mucha mayor precisión, ya que la consulta y un fragmento candidato se leen como una sola entrada en lugar de dos separadas.
El segundo cambio fue una puerta de validación antes de la generación. Esta verificaba que los fragmentos recuperados contuvieran los identificadores de sección esperados según los metadatos del momento de la ingestión. Por ejemplo, cuando una pregunta sobre CAMs devolvía fragmentos de las tablas de compensación, la validación fallaba y el sistema reescribía la consulta e intentaba nuevamente hasta dos veces antes de etiquetar la respuesta como de baja confianza. Esto diferencia una demostración de un sistema en producción: la demostración abarca el escenario óptimo, mientras que el sistema en producción maneja el 45% de los casos en los que ese escenario no se da.
Metadatos en cada fragmento
Una decisión de diseño que rara vez se menciona en los tutoriales de RAG es la inclusión de metadatos detallados en cada fragmento. Cada fragmento de la colección ChromaDB contenía los siguientes campos:
section_type, la sección del documento 10-K de la que proviene, como CAM, divulgación de riesgos, estados financieros, notas al pie o discusión de la direcciónsection_title, el título exacto que aparece encima del contenidopage_range, las páginas del documento original que abarca el fragmentodocument_id, el número de registro, formado por el símbolo de la empresa más el año fiscalhas_table, un valor booleano que indica la presencia de datos tabularesfiscal_year, el período contable al que corresponde
Los metadatos cumplían dos funciones. Permitían una búsqueda filtrada: para una pregunta relacionada con la auditoría, la búsqueda podía filtrarse previamente a un tipo de sección denominado critical_audit_matter antes de realizar la búsqueda vectorial, lo que reducía significativamente el rango de resultados. También servían como base para la capa de citaciones de la interfaz de usuario, ya que cada resumen indicaba las páginas y secciones de las que se extraía la información, permitiendo a los auditores verificar la fuente de inmediato.
En las herramientas de auditoría financiera, las citaciones son obligatorias. Un auditor que no pueda verificar el origen de un resumen no puede confiar en él, y la generación de citaciones a partir de los metadatos convirtió al sistema de algo meramente curioso en algo con el que sus usuarios realmente podían trabajar.
El sistema final
El pipeline completo que redujo el esfuerzo de revisión en auditorías en un 65% consta de tres capas.
- Ingestión: pdfplumber, detección de secciones, fragmentación variable, extracción de metadatos, incrustación con text-embedding-3-large, y posterior almacenamiento en ChromaDB con todos los metadatos.
- Consulta: reescritura de la consulta (reformulación mediante un LLM para mayor especificidad), recuperación filtrada con un prefiltrado de metadatos según el tipo de sección cuando sea aplicable, recuperación híbrida densa más BM25 para obtener los 10 mejores resultados, reclasificación con cross-encoder hasta los 3 mejores, verificación de validez, generación con GPT-4, adjuntamiento de citas y visualización en la interfaz de usuario.
- Evaluación: conjunto de datos de 30 elementos, seguimiento de la precisión en la recuperación y puntuación de la calidad de las respuestas, utilizando un LLM como evaluador para determinar relevancia, fidelidad y completitud.
La interfaz de Streamlit ofrecía a los auditores un cuadro de consulta, el resumen generado, citas de fuentes que se mostraban al solicitarlas, y un indicador de confianza obtenido de la fase de validación.
Qué hacer de manera diferente
- Construya primero el conjunto de datos de evaluación. Se compiló por desesperación cuando V1 falló, y debería haberse creado desde el primer día. Nada mejora sin mediciones, y “parece mejor” no es una métrica.
- Diseñe el esquema de metadatos con antelación. Tomó tiempo lograrlo correctamente, pero cada hora invertida se compensó muchas veces en la calidad de la recuperación de información y en las funcionalidades de la interfaz que permitió. Los metadatos merecen un trato prioritario en la arquitectura.
- Suponga que el analizador de PDF pasa por alto cosas. pdfplumber es excelente, pero las celdas fusionadas, los encabezados rotados o los marcadores de notas al pie dentro de las celdas en tablas financieras aún pueden confundirlo. Registre cada anomalía en la extracción y revise ese registro periódicamente, ya que los fallos silenciosos en la extracción son los errores más difíciles de rastrear posteriormente.
- Cuestiona cada valor predeterminado. El tamaño de bloque predeterminado, el modelo de incrustación predeterminado y el valor top-k predeterminado existen porque funcionan de manera aceptable en promedio, pero un tipo de documento puede no ser promedio. Prueba cada uno con datos reales.
El resultado
Después de su implementación, el sistema extrajo y resumió los Asuntos Críticos de Auditoría con un 65% menos de esfuerzo de revisión manual que el proceso que reemplazó. Al actuar como revisor en la primera pasada, localizó las secciones relevantes y redactó resúmenes estructurados, de modo que los auditores pasaron de extraer y sintetizar a verificar y juzgar.
Ese último punto es el más importante. El objetivo nunca fue reemplazar el juicio del auditor, sino eliminar los pasos mecánicos y laboriosos para que el juicio experto se aplicue donde realmente importa. Los sistemas LLM bien diseñados no reemplazan la experiencia profesional; la redirigen.
Leer más
- AegisOps: Un agente SRE autónomo con cuatro capas de memoria — Cómo un agente LangGraph ReAct resuelve incidentes en Kubernetes, con memoria episódica pgvector, niveles de autonomía controlados por políticas, dieciséis herramientas y un registro de auditoría completo.
- Comparación de 16 arquitecturas RAG: qué patrón se adapta a qué problema — Un recorrido por dieciséis patrones RAG en cuatro categorías, desde recuperación estándar e híbrida hasta diseños basados en agentes, grafos y federados, con un orden de desarrollo mes a mes.