Carga documentos

Intermedio
LangChain
LangChain
Actualizado: 08/07/2025

¡Desbloquea el curso completo!

IA
Ejercicios
Certificado
Entrar

Clase Document en LangChain

En el ecosistema de LangChain, toda la información textual se estructura utilizando la clase Document, que actúa como el contenedor fundamental para trabajar con textos en aplicaciones de RAG. Esta clase proporciona una interfaz estandarizada que permite a LangChain procesar, indexar y recuperar información de manera consistente, independientemente del origen de los datos.

La clase Document se encuentra en el módulo langchain_core.documents y representa la unidad básica de información con la que trabajaremos a lo largo de todo el módulo. Cada documento encapsula tanto el contenido textual como los metadatos asociados, creando una estructura rica en información que facilita las operaciones posteriores de búsqueda y recuperación.

from langchain_core.documents import Document

# Crear un documento básico
documento = Document(
    page_content="LangChain es un framework para desarrollar aplicaciones con modelos de lenguaje.",
    metadata={"fuente": "documentacion_oficial", "fecha": "2024-01-15"}
)

print(f"Contenido: {documento.page_content}")
print(f"Metadatos: {documento.metadata}")

Estructura interna de Document

La clase Document está diseñada con una arquitectura minimalista pero efectiva. Internamente, mantiene dos atributos principales que definen completamente la información que contiene. Esta simplicidad no es casual, sino que responde a la necesidad de crear una estructura que sea fácil de serializar, transmitir y procesar por diferentes componentes del sistema.

El diseño inmutable de los documentos garantiza la integridad de los datos durante todo el pipeline de procesamiento. Una vez creado un documento, sus propiedades fundamentales no pueden modificarse accidentalmente, lo que previene errores comunes en aplicaciones complejas donde múltiples componentes manipulan la misma información.

# Explorar la estructura de un documento
documento = Document(
    page_content="Python es un lenguaje de programación versátil y potente.",
    metadata={
        "autor": "Guido van Rossum",
        "año": 1991,
        "tipo": "lenguaje_programacion",
        "paradigmas": ["orientado_objetos", "funcional", "imperativo"]
    }
)

# Acceder a los atributos principales
print(f"Tipo de page_content: {type(documento.page_content)}")
print(f"Tipo de metadata: {type(documento.metadata)}")
print(f"Claves de metadata: {list(documento.metadata.keys())}")

Creación de documentos desde diferentes fuentes

La flexibilidad de la clase Document permite crear instancias desde múltiples tipos de fuentes de información. Esta capacidad es fundamental para construir sistemas RAG que puedan integrar datos heterogéneos de manera uniforme.

Desde texto simple:

# Documento con contenido mínimo
doc_simple = Document(page_content="Este es un texto de ejemplo.")

# Documento con metadatos básicos
doc_con_metadata = Document(
    page_content="Las funciones lambda en Python permiten crear funciones anónimas.",
    metadata={"tema": "programacion", "dificultad": "intermedio"}
)

Desde estructuras de datos complejas:

# Simular datos de una API o base de datos
datos_articulo = {
    "titulo": "Introducción a Machine Learning",
    "contenido": "El aprendizaje automático es una rama de la inteligencia artificial...",
    "autor": "Dr. Ana García",
    "fecha_publicacion": "2024-03-10",
    "tags": ["ML", "IA", "Python"],
    "categoria": "tecnologia"
}

# Crear documento estructurado
documento_articulo = Document(
    page_content=f"{datos_articulo['titulo']}\n\n{datos_articulo['contenido']}",
    metadata={
        "autor": datos_articulo["autor"],
        "fecha": datos_articulo["fecha_publicacion"],
        "tags": datos_articulo["tags"],
        "categoria": datos_articulo["categoria"],
        "tipo_documento": "articulo"
    }
)

Manipulación y transformación de documentos

Los documentos en LangChain están diseñados para ser inmutables en su estructura básica, pero esto no impide crear nuevas versiones modificadas cuando sea necesario. Esta aproximación garantiza la trazabilidad y previene modificaciones accidentales durante el procesamiento.

# Documento original
doc_original = Document(
    page_content="FastAPI es un framework web moderno para Python.",
    metadata={"framework": "FastAPI", "lenguaje": "Python"}
)

# Crear una versión enriquecida
doc_enriquecido = Document(
    page_content=doc_original.page_content,
    metadata={
        **doc_original.metadata,  # Mantener metadatos originales
        "version": "0.104.1",
        "fecha_actualizacion": "2024-01-20",
        "rendimiento": "alto"
    }
)

print(f"Metadatos originales: {len(doc_original.metadata)} elementos")
print(f"Metadatos enriquecidos: {len(doc_enriquecido.metadata)} elementos")

Trabajando con colecciones de documentos

En aplicaciones RAG reales, raramente trabajamos con documentos individuales. La clase Document está optimizada para funcionar eficientemente en colecciones grandes, donde cada documento mantiene su identidad pero puede procesarse junto con otros de manera coordinada.

# Crear una colección de documentos relacionados
documentos_python = [
    Document(
        page_content="Las listas en Python son estructuras de datos mutables y ordenadas.",
        metadata={"tema": "estructuras_datos", "tipo": "lista", "nivel": "basico"}
    ),
    Document(
        page_content="Los diccionarios permiten almacenar pares clave-valor de manera eficiente.",
        metadata={"tema": "estructuras_datos", "tipo": "diccionario", "nivel": "basico"}
    ),
    Document(
        page_content="Las clases en Python implementan el paradigma de programación orientada a objetos.",
        metadata={"tema": "poo", "tipo": "clase", "nivel": "intermedio"}
    )
]

# Operaciones sobre la colección
temas_unicos = set(doc.metadata.get("tema") for doc in documentos_python)
documentos_basicos = [doc for doc in documentos_python if doc.metadata.get("nivel") == "basico"]

print(f"Temas encontrados: {temas_unicos}")
print(f"Documentos básicos: {len(documentos_basicos)}")

Serialización y persistencia

La clase Document incluye métodos nativos para serialización, lo que facilita el almacenamiento y la transmisión de documentos entre diferentes componentes del sistema. Esta capacidad es esencial para construir aplicaciones escalables que requieran persistir grandes volúmenes de documentos.

import json

# Crear documento para serializar
documento = Document(
    page_content="Django es un framework web de alto nivel para Python.",
    metadata={
        "framework": "Django",
        "tipo": "web",
        "licencia": "BSD",
        "primera_version": "2005-07-15"
    }
)

# Serializar a diccionario
doc_dict = {
    "page_content": documento.page_content,
    "metadata": documento.metadata
}

# Convertir a JSON
doc_json = json.dumps(doc_dict, ensure_ascii=False, indent=2)
print("Documento serializado:")
print(doc_json)

# Deserializar desde JSON
doc_desde_json = json.loads(doc_json)
documento_restaurado = Document(
    page_content=doc_desde_json["page_content"],
    metadata=doc_desde_json["metadata"]
)

print(f"\nDocumento restaurado correctamente: {documento_restaurado.page_content[:50]}...")

La clase Document establece los cimientos sobre los que se construye todo el sistema de procesamiento de información en LangChain. Su diseño simple pero robusto permite manejar desde casos de uso básicos hasta aplicaciones empresariales complejas, manteniendo siempre la consistencia y la integridad de los datos.

page_content y metadata

Guarda tu progreso

Inicia sesión para no perder tu progreso y accede a miles de tutoriales, ejercicios prácticos y nuestro asistente de IA.

Progreso guardado
Asistente IA
Ejercicios
Iniciar sesión gratis

Más de 25.000 desarrolladores ya confían en CertiDevs

Los dos atributos fundamentales de la clase Document definen completamente la información que contiene cada instancia. El page_content almacena el texto principal que será procesado por los modelos de lenguaje, mientras que metadata proporciona contexto adicional que enriquece la información y facilita operaciones avanzadas como filtrado y clasificación.

El atributo page_content

El page_content es una cadena de texto que contiene la información principal del documento. Este atributo debe ser tratado como el contenido que será directamente procesado por los modelos de lenguaje durante las operaciones de búsqueda y generación de respuestas.

from langchain_core.documents import Document

# Ejemplo básico de page_content
documento = Document(page_content="Las funciones en Python pueden recibir argumentos por defecto.")

# Acceder al contenido
print(f"Contenido: {documento.page_content}")
print(f"Longitud: {len(documento.page_content)} caracteres")
print(f"Tipo: {type(documento.page_content)}")

El contenido puede incluir texto estructurado con saltos de línea, lo que es especialmente útil cuando trabajamos con documentos que mantienen formato específico:

# Documento con estructura de párrafos
contenido_estructurado = """Título: Programación Funcional en Python

La programación funcional es un paradigma que trata la computación como la evaluación de funciones matemáticas.

Características principales:
- Inmutabilidad de datos
- Funciones como ciudadanos de primera clase
- Ausencia de efectos secundarios"""

documento_estructurado = Document(
    page_content=contenido_estructurado,
    metadata={"tipo": "tutorial", "formato": "texto_plano"}
)

print(documento_estructurado.page_content)

El atributo metadata

Los metadatos proporcionan información contextual sobre el documento que no forma parte del contenido principal pero resulta crucial para el procesamiento inteligente. Este atributo es un diccionario Python que puede contener cualquier información adicional relevante.

# Ejemplo completo de metadatos
documento_completo = Document(
    page_content="NumPy es la biblioteca fundamental para computación científica en Python.",
    metadata={
        "biblioteca": "NumPy",
        "lenguaje": "Python",
        "categoria": "computacion_cientifica",
        "version_minima": "1.21.0",
        "dependencias": ["Python >= 3.8"],
        "fecha_creacion": "2024-01-15",
        "autor": "Equipo NumPy",
        "nivel_dificultad": "intermedio",
        "palabras_clave": ["arrays", "matrices", "vectorizacion"]
    }
)

# Explorar los metadatos
print("Metadatos disponibles:")
for clave, valor in documento_completo.metadata.items():
    print(f"  {clave}: {valor}")

Tipos de datos en metadata

Los metadatos pueden contener diversos tipos de datos Python, lo que proporciona flexibilidad para almacenar información estructurada:

# Metadatos con diferentes tipos de datos
documento_mixto = Document(
    page_content="Flask es un microframework web para Python.",
    metadata={
        "nombre": "Flask",                    # string
        "es_microframework": True,            # boolean
        "año_creacion": 2010,                # integer
        "popularidad": 8.5,                  # float
        "frameworks_relacionados": [         # list
            "Django", "FastAPI", "Bottle"
        ],
        "configuracion": {                   # dict anidado
            "debug": True,
            "puerto": 5000,
            "host": "localhost"
        },
        "tags": {"web", "python", "micro"},  # set (se convierte a list)
        "ultima_actualizacion": None         # None
    }
)

# Acceder a diferentes tipos
print(f"Es microframework: {documento_mixto.metadata['es_microframework']}")
print(f"Frameworks relacionados: {documento_mixto.metadata['frameworks_relacionados']}")
print(f"Puerto por defecto: {documento_mixto.metadata['configuracion']['puerto']}")

Patrones comunes de metadata

Existen patrones establecidos para organizar metadatos que facilitan el procesamiento posterior y la integración con otros componentes de LangChain:

Información de origen:

documento_origen = Document(
    page_content="La documentación oficial de Python está disponible en docs.python.org",
    metadata={
        "fuente": "docs.python.org",
        "url": "https://docs.python.org/3/tutorial/",
        "fecha_acceso": "2024-01-20",
        "seccion": "tutorial",
        "idioma": "es"
    }
)

Clasificación y categorización:

documento_clasificado = Document(
    page_content="Los decoradores en Python permiten modificar el comportamiento de funciones.",
    metadata={
        "categoria": "programacion",
        "subcategoria": "python_avanzado",
        "dificultad": "intermedio",
        "tiempo_lectura": 5,  # minutos
        "prerequisitos": ["funciones", "closures"]
    }
)

Información de procesamiento:

documento_procesado = Document(
    page_content="Machine Learning es una rama de la inteligencia artificial.",
    metadata={
        "procesado_en": "2024-01-20T10:30:00Z",
        "version_procesador": "1.0.2",
        "tokens_estimados": 12,
        "idioma_detectado": "es",
        "confianza_idioma": 0.95
    }
)

Manipulación avanzada de metadata

Los metadatos pueden ser modificados y enriquecidos durante el procesamiento, creando nuevas versiones de documentos con información adicional:

# Documento base
doc_base = Document(
    page_content="Pandas facilita la manipulación y análisis de datos en Python.",
    metadata={"biblioteca": "Pandas", "lenguaje": "Python"}
)

# Función para enriquecer metadatos
def enriquecer_documento(documento, informacion_adicional):
    return Document(
        page_content=documento.page_content,
        metadata={
            **documento.metadata,
            **informacion_adicional,
            "enriquecido": True,
            "timestamp_enriquecimiento": "2024-01-20T15:45:00Z"
        }
    )

# Aplicar enriquecimiento
doc_enriquecido = enriquecer_documento(doc_base, {
    "casos_uso": ["analisis_datos", "limpieza_datos", "visualizacion"],
    "complejidad": "media",
    "documentacion_url": "https://pandas.pydata.org/docs/"
})

print("Metadatos enriquecidos:")
for clave, valor in doc_enriquecido.metadata.items():
    print(f"  {clave}: {valor}")

Filtrado por metadata

Una de las ventajas principales de mantener metadatos estructurados es la capacidad de filtrar colecciones de documentos de manera eficiente:

# Colección de documentos con metadatos diversos
documentos_biblioteca = [
    Document(
        page_content="Requests simplifica las peticiones HTTP en Python.",
        metadata={"biblioteca": "Requests", "categoria": "http", "dificultad": "basico"}
    ),
    Document(
        page_content="SQLAlchemy es un ORM potente para bases de datos en Python.",
        metadata={"biblioteca": "SQLAlchemy", "categoria": "base_datos", "dificultad": "avanzado"}
    ),
    Document(
        page_content="Beautiful Soup facilita el web scraping en Python.",
        metadata={"biblioteca": "Beautiful Soup", "categoria": "web_scraping", "dificultad": "intermedio"}
    )
]

# Filtrar por dificultad
docs_basicos = [doc for doc in documentos_biblioteca 
                if doc.metadata.get("dificultad") == "basico"]

# Filtrar por categoría
docs_web = [doc for doc in documentos_biblioteca 
            if "web" in doc.metadata.get("categoria", "")]

print(f"Documentos básicos: {len(docs_basicos)}")
print(f"Documentos web: {len(docs_web)}")

# Filtrado más complejo
def filtrar_documentos(documentos, **criterios):
    resultado = []
    for doc in documentos:
        coincide = True
        for clave, valor in criterios.items():
            if doc.metadata.get(clave) != valor:
                coincide = False
                break
        if coincide:
            resultado.append(doc)
    return resultado

# Aplicar filtro personalizado
docs_filtrados = filtrar_documentos(
    documentos_biblioteca,
    categoria="http",
    dificultad="basico"
)

print(f"Documentos HTTP básicos: {len(docs_filtrados)}")

La separación clara entre contenido y metadatos en la clase Document permite construir sistemas RAG sofisticados donde la información contextual juega un papel tan importante como el contenido textual en la recuperación y generación de respuestas precisas.

Aprendizajes de esta lección

  • Comprender la estructura y propósito de la clase Document en LangChain.
  • Aprender a crear documentos desde texto simple y datos estructurados.
  • Entender la importancia y uso de los atributos page_content y metadata.
  • Conocer cómo manipular, enriquecer y filtrar colecciones de documentos.
  • Familiarizarse con la serialización y persistencia de documentos para aplicaciones escalables.

Completa LangChain y certifícate

Únete a nuestra plataforma y accede a miles de tutoriales, ejercicios prácticos, proyectos reales y nuestro asistente de IA personalizado para acelerar tu aprendizaje.

Asistente IA

Resuelve dudas al instante

Ejercicios

Practica con proyectos reales

Certificados

Valida tus conocimientos

Más de 25.000 desarrolladores ya se han certificado con CertiDevs

⭐⭐⭐⭐⭐
4.9/5 valoración