¿Cómo crear un cargador de JSON Lines en LangChain?
¿Alguna vez has enfrentado la necesidad de manejar formatos de datos que no son compatibles directamente con las herramientas que estás usando? En el mundo de la ciencia de datos y la programación, esto es más común de lo que podrías pensar. A través de este artículo, aprenderás a crear un cargador de datos que te permita manejar archivos JSON Lines, un formato aún no soportado por LangChain. Esta implementación te dará el control para personalizar cómo se cargan y gestionar los datos.
¿Qué son los JSON Lines y cómo funcionan?
JSON Lines es un formato de datos en el que cada línea es un registro JSON independiente. Esto permite trabajar de manera eficiente con grandes volúmenes de datos, ya que se pueden procesar línea por línea sin cargar todo el archivo en memoria.
Ventajas de JSON Lines:
Fácil de trabajar tanto para humanos como para máquinas.
Permite el procesamiento incremental de registros.
Ideal para flujos de datos que se transmiten en tiempo real.
Para comenzar a trabajar con JSON Lines, necesitarás instalar una librería que te permita manejarlos en Python:
pip install jsonlines
¿Cómo se crea un cargador específico?
Para esta tarea, crearemos una clase en Python que le proporcionará a LangChain la funcionalidad necesaria para manejar archivos JSON Lines. Así, podrás cargar, manipular y almacenar datos de manera personalizada según tus necesidades.
Paso a paso para crear un cargador de JSON Lines
Inicializa tu clase: Inicia con la creación de una clase en Python para manejar esta tarea.
Función para cargar datos: Define la función load para leer los datos y transformarlos en una lista de documentos.
from typing import List
from esquema import Document
import jsonlines
defload(self)-> List[Document]:with jsonlines.open(self.filepath)as reader: documents =[]for obj in reader: page_content = obj.get('text','') metadata ={'title': obj.get('title',None),'repo_owner': obj.get('repo_owner',None),'repo_name': obj.get('repo_name',None),} documents.append(Document(page_content=page_content, metadata=metadata))return documents
Manejo de errores y personalización: Asegúrate de manejar errores y personalizar el formato de los metadatos según tus necesidades. Este código proporciona una estructura básica, pero puedes modificarlo para capturar más información o diseñar otras funcionalidades.
Uso del cargador: Una vez que tu cargador esté listo, úsalo para procesar tus datos.
loader = JSONLLoader('ruta/al/archivo.jsonl')datos = loader.load()for doc in datos:print(doc)
¿Cuáles son los beneficios de personalizar tu propio cargador?
Crear tu propio cargador de datos tiene muchas ventajas. No solo puedes adaptar el proceso para ajustarse perfectamente a tus requisitos, sino que también puedes expandir las capacidades de las herramientas existentes como LangChain. Esto es especialmente útil cuando trabajas con formatos de datos no estándar o quieres garantizar que los metadatos se almacenen de una manera específica. Además, desarrollar estas habilidades te permite integrarte mejor en contextos profesionales donde los datos y su manipulación son parte esencial de las operaciones diarias.
La magia de la programación recae en que puedes moldear tus herramientas para satisfacer exactamente tus necesidades, y esta guía te brinda el conocimiento para hacerlo con confianza.
Les dejo por aquí una estructura que estoy probando para un archivo de excel en la que previamente depuramos cierta data que queremos que exista en una base vectorial, me encantaría recibir feedback:
from langchain.schemaimportDocumentfrom typing importListimport pandas as pd
classTransformerExcelLoader: def __init__(self,file_path: str): self.file_path= file_path
def load(self)->List[Document]: data = pd.read_excel(self.file_path) documents =[] # Reemplazar valores NaN con cadenas vacías data.fillna("", inplace=True)for _, fila in data.iterrows():if fila["FUENTE"]=="": page_content ="RESPUESTA "+ fila["RESPUESTA"]else: # Usar str.cat() para concatenar cadenas eficientemente
page_content ="RESPUESTA: "+ fila["RESPUESTA"]+" FUENTE: "+ fila["FUENTE"] metadata ={'empresa': fila["EMPRESA"],'area': fila["AREA"],'topico': fila["TOPICO"],'pregunta': fila["PREGUNTA"],'contexto': fila["CONTEXTO"]} documents.append(Document(page_content=page_content, metadata=metadata))return documents
Posdata: Se que hice algo de hardcoded colocando los nombres de las variables pero es una estrcutra que no esperamos cambiar en el corto plazo...
No estoy seguro de sí sea chamba de un Loader Limpiar el formato, quizá sería una alternativa tener una función que dado un excel "sucio" aplique el formato que necesites y después ya uses un Loader de Excel, de esta forma podrías hacer un pipeline uniendo cada bloque.
Adicionalmente, tendrías más control sobre el flujo de los procesos, si el día de mañana tienes una nueva columna o cambia el nombre de una variable entonces solo cambias la función "clean_excel()" y no alteras el flujo de información.
Es meramente una sugenrencia, no te puedo decir que esta tallado en piedra.
a Jan 2025
Acá la doc actualizada de JSON Loaders
Hoy en día ya contamos con loaders de JSONL, aquí dejo el link de la doc en langchain:
Dejo un ejemplo usando el loader de LangChaing y se obtiene un resultado muy similar.