¿Cómo se crea un índice de Chroma a partir de documentos JSON-L?
Comenzar con un proyecto de indexación de documentos puede parecer una tarea compleja, pero con las herramientas adecuadas, se puede simplificar en gran medida. La meta es transformar una base de datos JSON-L en un índice de Chroma que pueda procesar consultas de usuario de manera eficiente. ¡Veamos cómo hacerlo!
¿Cómo preparar los documentos?
En primer lugar, es esencial tener un ambiente de programación listo y la base de datos, en este caso, un archivo JSON-L. Nuestro primer paso es convertir este archivo en un formato que Langchain pueda procesar.
Conversión a formato Langchain: Esto se logra mediante una función de Python que cargue los documentos desde un path especificado. Supongamos que llamamos a esta función loadDocuments. Esta función utiliza docs.json.lloader para convertir cada línea del JSON-L en un document de Langchain.
defloadDocuments(filePath):from utils import docs.json.loader
loader = docs.json.loader(filePath) data = loader.load()return data
¿Cómo dividir los documentos?
Una vez que los documentos están en formato adecuado, es necesario dividirlos en fragmentos más pequeños. Esto se hace para que puedan ser procesados por embeddings, que convertirán los documentos en números.
Uso de un text splitter: Utilizamos recursive character text splitter de Langchain. Este nos permite establecer un chunk_size adecuado, que para embeddings grandes como los de OpenAI puede ser de 1600 caracteres.
from langchain.textsplitters import recursive_character_text_splitter
text_splitter = recursive_character_text_splitter(chunk_size=1600, chunk_overlap=160)split_documents = text_splitter.split_documents(data)
¿Cómo obtener el path correcto de los documentos?
Para facilitar el proceso, podemos definir una función que obtenga automáticamente el path correcto hacia nuestros documentos. Esta puede ser una función simple de utils, por ejemplo, getFilePath.
from utils import getFilePath
file_path = getFilePath()print("Path to documents:", file_path)
¿Cómo verificar el proceso?
Es importante verificar cuántos fragmentos de documentos tenemos y cómo se ve uno en detalle. Esto nos ayuda a entender que el proceso de división se ha llevado a cabo correctamente.
defmain():# Cargar y dividir documentos documents = loadDocuments(getFilePath()) split_documents = split_documents(documents)# Imprimir resultadosprint("Número total de documentos:",len(split_documents))print("Primer documento:", split_documents[0])
A través de estos pasos, pasamos de tener un archivo JSON-L grande a más de 1800 fragmentos de documentos, cada uno con información clave como el contenido de la página y metadatos sobre el creador y el repositorio asociado. Este proceso nos prepara para la próxima etapa que incluye la conversión de esos documentos en embeddings y su almacenamiento en una base de datos vectorial como Chroma.
¿Está todo listo? ¡Es hora de seguir explorando y avanzar hacia la creación de un modelo de chat efectivo!
Les muestro cual serīa el código para cargar los datos usando la clase JSONLoader de langchain.
<code>from langchain.document_loadersimportJSONLoader # importar clase
from langchain.text_splitterimportRecursiveCharacterTextSplitterfrom utils import get_file_path
# funcion metadata para retornar title, repo_owner, repo_name en la metadata del documento
def metadata_func(record: dict,metadata: dict)-> dict: metadata["title"]= record.get("title") metadata["repo_owner"]= record.get("repo_owner") metadata["repo_name"]= record.get("repo_name")return metadata
def load_documents(path): loader =JSONLoader( path, json_lines=True, # indica que el archivo es un jsonl
jq_schema=".", # indica que el jsonl tiene un solo elemento por linea, más info en https://python.langchain.com/docs/modules/data_connection/document_loaders/json#common-json-structures-with-jq-schema
content_key="text", # indica que el contenido del documento está en la llave "text" metadata_func=metadata_func, # indica que la función metadata_func se usará para obtener la metadata del documento
) data = loader.load() text_splitter =RecursiveCharacterTextSplitter( chunk_size=1600, length_function=len, chunk_overlap=160)return text_splitter.split_documents(data)
y así quedaría un Documento:
A Enero 2025:
Si hicieron una descarga recientemente, para que conversation_ai funcione deben cambiar el path en con config.yaml
En mi caso jsonl_database_path: data/docs_en_2025_01_10.jsonl
A enero de 2026, se debe actualizar los imports para obtener la clase Document y RecursiveCharacterTextSplitter
# se debe instalar la libreria langchain-text-splittersfrom langchain_text_splitters import RecursiveCharacterTextSplitter
from langchain_core.documents import Document
Para ejecutar el text_extractor.py usando uv para crear el entorno virtual.
branch : start
Para hacer split con tokens
def load_documents(file_path: str): loader =DocsJSONLLoader(file_path) data = loader.load()print(f"Documents loaded: {len(data)}") # Split by tokens
text_splitter_recursive =RecursiveCharacterTextSplitter.from_tiktoken_encoder( model_name="gpt-4", chunk_size=500, chunk_overlap=50,)return text_splitter_recursive.split_documents(data)```def load\_documents(file\_path: str):  loader =DocsJSONLLoader(file\_path)  data = loader.load() print(f"Documents loaded: {len(data)}")  \# Split by tokens
  text\_splitter\_recursive =RecursiveCharacterTextSplitter.from\_tiktoken\_encoder(  model\_name="gpt-4",  chunk\_size=500,  chunk\_overlap=50, ) return text\_splitter\_recursive.split\_documents(data)
Excelente, cada ves se aterriza más lo que podemos hacer apps con esto, esta supremo este curso.