Habiendo desarrollado flujos de trabajo LLM sin procesar para tareas de extracción estructuradas, he observado varias dificultades en ellos con el tiempo. En uno de mis proyectos, desarrollé dos flujos de trabajo independientes usando Grok y OpenAI para ver cuál funcionó mejor para la extracción estructurada. Esto fue cuando noté que ambos omitían hechos en lugares aleatorios. Además, los campos extraídos no se alinearon con el esquema.
Para contrarrestar estos problemas, configuré verificaciones especiales de manejo y validación que harían que el LLM revisara el documento (como un segundo pase) para que los hechos faltantes puedan atraparse y agregar al documento de salida. Sin embargo, múltiples corridas de validación me hicieron superar mis límites de API. Además, el avance rápido fue un verdadero cuello de botella. Cada vez que modificaba el aviso para asegurarme de que el LLM no se perdiera un hecho, se introduciría un nuevo problema. Una restricción importante que noté fue que, si bien un LLM funcionó bien para un conjunto de indicaciones, el otro no funcionaría tan bien con el mismo conjunto de instrucciones. Estos problemas me llevaron a buscar un motor de orquestación que pudiera ajustar automáticamente mis indicaciones para que coincidan con el estilo de solicitud de la LLM, manejar omisiones de hechos y asegurarse de que mi salida estuviera alineada con mi esquema.
Recientemente me encontré con Langextract y lo probé. La biblioteca abordó varios problemas que enfrentaba, particularmente en torno a la alineación del esquema y la integridad de los hechos. En este artículo, explico los conceptos básicos de LangExtract y cómo puede aumentar los flujos de trabajo LLM RAW para problemas de extracción estructurados. También pretendo compartir mi experiencia con LangExtract usando un ejemplo.
¿Por qué langextract?
Es un hecho conocido que cuando configura un flujo de trabajo LLM RAW (por ejemplo, usando OpenAI para recopilar atributos estructurados de su corpus), tendría que establecer una estrategia de fragmentación para optimizar el uso de tokens. También necesitaría agregar un manejo especial para valores faltantes y formatear inconsistencias. Cuando se trata de ingeniería rápida, tendría que agregar o eliminar instrucciones a su mensaje con cada iteración; en un intento de ajustar los resultados y manejar las discrepancias.
LangExtract ayuda a administrar lo anterior orquestando efectivamente las indicaciones y salidas entre el usuario y el LLM. Afina el aviso antes de pasarlo al LLM. En los casos en que el texto o los documentos de entrada son grandes, se ajusta los datos y los alimenta a la LLM, al tiempo que nos aseguramos de permanecer dentro de los límites de token prescritos por cada modelo (por ejemplo, ~ 8000 tokens para GPT-4 VS ~ 10000 tokens en Claude). En los casos en que la velocidad es crucial, se puede configurar la paralelización. Donde los límites del token son una restricción, se podría configurar la ejecución secuencial. Intentaré desglosar el funcionamiento de LangExtract junto con sus estructuras de datos en la siguiente sección.
Estructuras de datos y flujo de trabajo en LangExtract
A continuación se muestra un diagrama que muestra las estructuras de datos en LangExtract y el flujo de datos desde la secuencia de entrada a la secuencia de salida.
(Imagen del autor)
LangExtract almacena ejemplos como una lista de objetos de clase personalizados. Cada objeto de ejemplo tiene una propiedad llamada ‘texto’, que es el texto de muestra de un artículo de noticias. Otra propiedad es la ‘extracción_class’, que es la categoría asignada al artículo de noticias por el LLM durante la ejecución. Como ejemplo, un artículo de noticias que habla sobre un proveedor de la nube se etiquetará bajo ‘Infraestructura en la nube’. La propiedad ‘Extraction_Text’ es la salida de referencia que proporciona al LLM. Esta salida de referencia guía el LLM para inferir la salida más cercana que esperaría para un fragmento de noticias similar. La propiedad ‘text_or_documents’ almacena el conjunto de datos real que requiere extracción estructurada (en mi ejemplo, los documentos de entrada son artículos de noticias).
Las instrucciones de solicitación de pocos disparos se envían al LLM de elección (model_id) a través de LangExtract. La función ‘Extract ()’ de LangExtract reúne las indicaciones y las pasa a la LLM después de ajustar la solicitud internamente para que coincida internamente con el estilo de inmediato del LLM elegido y para evitar discrepancias del modelo. El LLM luego devuelve el resultado uno a la vez (es decir, un documento a la vez) para langextract, lo que a su vez produce el resultado en un objeto generador. El objeto generador es similar a una corriente transitoria que produce el valor extraído por el LLM. Una analogía para un generador que es un flujo transitorio sería un termómetro digital, lo que le brinda la lectura actual, pero realmente no almacena lecturas para referencia futura. Si el valor en el objeto del generador no se captura de inmediato, se pierde.
Tenga en cuenta que las propiedades ‘Max_Workers’ y ‘Extraction_Pass’ se han discutido en detalle en la sección ‘Las mejores prácticas en el uso de LangExtract’.
Ahora que hemos visto cómo funciona LangExtract y las estructuras de datos utilizadas por él, pasemos a aplicar LangExtract en un escenario del mundo real.
Una implementación práctica de langextract
El caso de uso implica la recopilación de artículos de noticias de los “Techxplore.com RSS Feeds”, relacionados con el dominio comercial de tecnología (https://techxplore.com/feeds/). Utilizamos FeedParser y TriFaltura para el análisis de URL y la extracción del texto del artículo. Las indicaciones y ejemplos son creados por el usuario y alimentados a LangExtract, que realiza orquestación para garantizar que el indicador esté sintonizado para el LLM que se está utilizando. El LLM procesa los datos en función de las instrucciones de inmediato junto con los ejemplos proporcionados y devuelve los datos a LangExtract. LangExtract una vez más realiza un postprocesamiento antes de mostrar los resultados al usuario final. A continuación se muestra un diagrama que muestra cómo fluye los datos de la fuente de entrada (RSS Feeds) en Langextract, y finalmente a través del LLM para producir extracciones estructuradas.
A continuación se muestran las bibliotecas que se han utilizado para esta demostración.
Comenzamos asignando la URL de alimentación Tech Xplore RSS a una variable ‘Feed_url’. Luego definimos una lista de ‘palabras clave’, que contiene palabras clave relacionadas con la empresa tecnológica. Definimos tres funciones para analizar y raspar los artículos de noticias de The News Feed. La función ‘get_article_urls ()’ analiza la alimentación RSS y recupera el título del artículo y la URL individual del artículo (enlace). FeedParser se usa para lograr esto. La función ‘Extract_Text ()’ usa Trifaltura para extraer el texto del artículo de la URL de artículo individual devuelta por FeedParser. La función ‘filtre_articles_by_keywords’ filtra los artículos recuperados en función de la lista de palabras clave definida por nosotros.
Al ejecutar lo anterior, obtenemos la salida
“Encontré 30 artículos en la alimentación RSS
Artículos filtrados: 15 ″
Ahora que la lista de ‘Filtered_articles’ está disponible, seguimos adelante y configuramos el mensaje. Aquí, damos instrucciones para permitir que el LLM comprenda el tipo de información de noticias que nos interesan. Como se explica en la sección “Estructuras de datos y flujo de trabajo en LangExtract”, configuramos una lista de clases personalizadas utilizando ‘data.exsampledata ()’, que es una estructura de datos incorporada en LangExtract. En este caso, utilizamos pocas solicitudes de disparo que consta de múltiples ejemplos.
Inicializamos una lista llamada ‘resultados’ y luego paseamos por el corpus ‘Filtered_articles’ y realizamos la extracción de un artículo a la vez. La salida LLM está disponible en un objeto generador. Como se vio anteriormente, al ser un flujo transitorio, el valor de salida en ‘result_generator’ se agrega inmediatamente a la lista de ‘resultados’. La variable ‘Resultados’ es una lista de documentos anotados.
Iteramos a través de los resultados en un ‘para bucle’ para escribir cada documento anotado en un archivo JSONL. Aunque este es un paso opcional, se puede usar para auditar documentos individuales si es necesario. Vale la pena mencionar que la documentación oficial de LangExtract ofrece una utilidad para visualizar estos documentos.
Realizamos la lista de ‘resultados’ para reunir cada extracción de un documento anotado uno a la vez. Una extracción no es más que uno o más atributos solicitados por nosotros en el esquema. Todas estas extracciones se almacenan en la lista ‘All_extracciones’. Esta lista es una lista aplanada de todas las extracciones del formulario. [extraction_1, extraction_2, extraction_n].
Obtenemos 55 extracciones de los 15 artículos que se reunieron antes.
El paso final implica iterar a través de la lista ‘All_extracciones’ para recopilar cada extracción. El objeto de extracción es una estructura de datos personalizada dentro de LangExtract. Los atributos se recopilan de cada objeto de extracción. En este caso, los atributos son objetos de diccionario que tienen el nombre y el valor métrico. Los atributos/nombres métricos coinciden con el esquema inicialmente solicitado por nosotros como parte del mensaje (consulte el diccionario ‘Atributos’ proporcionó la lista de ‘ejemplos’ en el objeto ‘data.extraction’). Los resultados finales se ponen a disposición en un marcado de datos, que puede usarse para un análisis posterior.
A continuación se muestra la salida que muestra las primeras cinco filas del marco de datos –
Las mejores prácticas para usar langextract de manera efectiva
Pocas de disparo
LangExtract está diseñado para funcionar con una estructura de solicitación de un solo disparo o de pocos disparos. Peque solicitante de shot requiere que dé un aviso y algunos ejemplos que expliquen la salida que espera que el LLM cedga. Este estilo de solicitud es especialmente útil en dominios complejos y multidisciplinarios como el comercio y la exportación, donde los datos y la terminología en un sector pueden ser muy diferentes de los del otro. Aquí hay un ejemplo: un fragmento de noticias dice: “El valor del oro aumentó por x” y otro fragmento dice “el valor de un tipo particular de semiconductor aumentó por y”. Aquí, aunque ambos fragmentos dicen ‘valor’, significan cosas muy diferentes. Cuando se trata de metales preciosos como el oro, el valor se basa en el precio de mercado por unidad, mientras que con los semiconductores, podría significar el tamaño del mercado o el valor estratégico. Proporcionar ejemplos específicos de dominio puede ayudar a que el LLM vaya a obtener las métricas con los matices que exige el dominio. Cuanto más los ejemplos, mejor. Un conjunto de ejemplo amplio puede ayudar tanto al modelo LLM como a Langextract a adaptarse a diferentes estilos de escritura (en artículos) y evitar las fallas en la extracción.
Pase de extracción múltiple
Un pase de extracción múltiple es el acto de que el LLM revise el conjunto de datos de entrada más de una vez para completar los detalles que faltan en su salida al final del primer pase. LangExtract guía el LLM para volver a visitar el conjunto de datos (entrada) varias veces ajustando el indicador durante cada ejecución. También administra efectivamente la salida fusionando las salidas intermedias de las primeras ejecuciones y posteriores. El número de pases que deben agregarse se proporciona utilizando el parámetro ‘Extraction_Passes’ en el módulo Extract (). Aunque un pase de extracción de ‘1’ funcionaría aquí, cualquier cosa más allá de ‘2’ ayudará a producir una salida que esté más afinada y alineada con el aviso y el esquema proporcionado. Además, un pase de extracción múltiple de 2 o más asegura que el esquema de salida esté a la par con el esquema y los atributos que proporcionó en su descripción rápida.
Paralelización
Cuando tiene documentos grandes que podrían consumir el número permitido de tokens por solicitud, es ideal para un proceso de extracción secuencial. Se puede habilitar un proceso de extracción secuencial configurando max_workers = 1. Esto hace que el langextract obligue a la LLM a procesar el indicador de manera secuencial, un documento a la vez. Si la velocidad es clave, la paralelización se puede habilitar configurando max_workers = 2 o más. Esto garantiza que múltiples hilos estén disponibles para el proceso de extracción. Además, el módulo Time.sleep () se puede usar cuando se realiza una ejecución secuencial para garantizar que no se excedan las cuotas de solicitud de LLM.
Tanto la paralelización como el pase de extracción múltiple se pueden establecer como a continuación-
Observaciones finales
En este artículo, aprendimos a usar LangExtract para casos de uso de extracción estructurada. En este momento, debe estar claro que tener un orquestador como LangExtract para su LLM puede ayudar con el ajuste rápido, la fragmentación de datos, el análisis de salida y la alineación del esquema. También vimos cómo LangExtract opera internamente mediante el procesamiento de pocas indicaciones para los disparos para adaptarse al LLM elegido y analizar la salida sin procesar del LLM a una estructura alineada por esquema.