Extender Paperless-ngx con inteligencia artificial
Qué cubre este artículo sobre Paperless-ngx con IA
- Cómo extender Paperless-ngx con Ollama para funcionalidades de IA.
- Cómo funcionan la clasificación automática, etiquetado y resumen de documentos.
- Cómo utilizar scripts personalizados y hooks post-consumo.
- Ejemplos prácticos para facturas, contratos y correspondencia.
- Mejores prácticas para precisión, seguridad y rendimiento.
Introducción: Paperless-ngx con IA explicado de forma clara
Paperless-ngx es un sistema de gestión documental: escaneas documentos, Paperless-ngx realiza OCR, los indexa y los hace buscables. Con IA avanzas un paso más: el modelo clasifica documentos automáticamente, asigna etiquetas, genera resúmenes y extrae metadatos. En lugar de organizar manualmente, la IA lo hace por ti.
Este artículo está dirigido a usuarios que deseen extender Paperless-ngx con capacidades de IA. Los conceptos fundamentales los encontrarás en Automatización de documentos y Ollama.
¿Por qué necesito Paperless-ngx con IA?
Paperless-ngx realiza OCR y búsqueda de texto completo, pero su clasificación se basa en reglas. Con IA, el sistema entiende el contenido: «Esto es una factura de la empresa X por 1.234 €, vencimiento el 15.03» en lugar de simplemente «Contiene la palabra factura». La IA clasifica con mayor precisión y extrae datos estructurados.
Paperless-ngx con IA en pocas palabras
Paperless-ngx procesa documentos (OCR, indexación). Un script post-consumo invoca Ollama: la IA clasifica, etiqueta y resume el documento. Los resultados se guardan en Paperless-ngx.
La idea central es clara: Paperless-ngx administra, la IA comprende.
¿A quién va dirigido este artículo?
- Usuarios de Paperless-ngx que quieren funcionalidades de IA.
- Trabajadores de oficina que necesitan procesar documentos automáticamente.
- Administradores de sistemas que desean extender la gestión documental con IA.
- Empresas que automatizan el procesamiento de facturas y contratos.
Tener experiencia previa con Paperless-ngx y Ollama es útil.
Términos clave
- Paperless-ngx - Sistema de gestión documental. Cuándo es útil: la base.
- Ollama - Servidor de modelos local. Cuándo es útil: el motor de IA.
- Post-Consume Script - Script ejecutado después de importar un documento. Cuándo es útil: para procesamiento con IA.
- OCR - Reconocimiento óptico de caracteres. Cuándo es útil: para documentos escaneados.
- Tags - Etiquetas temáticas. Cuándo es útil: para categorización.
- Custom Fields - Campos personalizados. Cuándo es útil: para metadatos de IA.
- RAG - Generación aumentada por recuperación. Cuándo es útil: para preguntas sobre documentos.
Configuración: Paperless-ngx + Ollama
Docker Compose
version: "3.8"
services:
paperless:
image: ghcr.io/paperless-ngx/paperless-ngx:latest
container_name: paperless
restart: unless-stopped
ports:
- "8000:8000"
volumes:
- paperless_data:/usr/src/paperless/data
- paperless_media:/usr/src/paperless/media
- ./scripts:/usr/src/paperless/scripts # Custom Scripts
environment:
- PAPERLESS_OCR_LANGUAGE=deu
- PAPERLESS_POST_CONSUME_SCRIPT=/usr/src/paperless/scripts/post_consume.py
- PAPERLESS_OLLAMA_URL=http://ollama:11434
networks:
- paperless-network
ollama:
image: ollama/ollama:latest
container_name: ollama
restart: unless-stopped
ports:
- "11434:11434"
volumes:
- ollama_data:/root/.ollama
networks:
- paperless-network
volumes:
paperless_data:
paperless_media:
ollama_data:
networks:
paperless-network:
driver: bridge
Script post-consumo
#!/usr/bin/env python3
# /usr/src/paperless/scripts/post_consume.py
# Se ejecuta después de cada importación de documento
import os
import sys
import json
import requests
OLLAMA_URL = os.environ.get("PAPERLESS_OLLAMA_URL", "http://ollama:11434")
def call_ollama(prompt, model="llama3.1", format=None):
"""Invocar Ollama"""
body = {
"model": model,
"messages": [{"role": "user", "content": prompt}],
"stream": False
}
if format:
body["format"] = format
response = requests.post(
f"{OLLAMA_URL}/api/chat",
json=body,
timeout=120
)
return response.json()["message"]["content"]
def main():
# Paperless-ngx proporciona información del documento como argumentos
doc_id = sys.argv[1] if len(sys.argv) > 1 else None
doc_file = sys.argv[2] if len(sys.argv) > 2 else None
# Leer el texto del documento (ya procesado por OCR)
text_file = doc_file.replace(".pdf", ".txt")
if os.path.exists(text_file):
with open(text_file) as f:
text = f.read()
else:
text = ""
if not text:
return
# 1. Clasificar
category = call_ollama(f"""Clasifica el documento:
- rechnung: Factura, Invoice
- vertrag: Contrato, Contract
- bericht: Informe, Report
- korrespondenz: Carta, E-mail
- sonstiges: Cualquier otra cosa
Documento: {text[:3000]}
Responde solo con la categoría.""")
# 2. Generar etiquetas
tags = call_ollama(f"""Asigna 3-5 etiquetas para el documento.
Documento: {text[:2000]}
Responde como JSON array: ["tag1", "tag2", ...]""", format="json")
# 3. Resumen
summary = call_ollama(f"""Resume el documento en 3 oraciones.
Documento: {text[:4000]}""")
# 4. Extraer metadatos
metadata = call_ollama(f"""Extrae:
- datum: Fecha del documento
- absender: Quién lo creó
- betreff: De qué se trata
- betrag: Si es una factura, el importe
Documento: {text[:3000]}
Responde como JSON.""", format="json")
# Salida para Paperless-ngx
result = {
"category": category.strip().lower(),
"tags": json.loads(tags),
"summary": summary,
"metadata": json.loads(metadata)
}
print(json.dumps(result))
if __name__ == "__main__":
main()
Ejemplo práctico 1: Procesar facturas automáticamente
def process_invoice(text):
"""Procesar factura"""
# Extraer datos estructurados
data = call_ollama(f"""Extrae de la factura:
- rechnungsnummer
- datum
- betrag (solo número)
- waehrung
- absender
- faelligkeitsdatum
Factura: {text}
Responde como JSON.""", format="json")
invoice = json.loads(data)
# Guardar en base de datos o como campos personalizados
save_invoice_metadata(doc_id, invoice)
# Mover a carpeta
move_to_folder(doc_id, "rechnungen")
return invoice
Ejemplo práctico 2: Analizar contratos
def analyze_contract(text):
"""Analizar contrato"""
analysis = call_ollama(f"""Analiza el contrato:
1. Tipo de contrato (Arrendamiento, Compra, Servicio, ...)
2. Partes contratantes
3. Vigencia
4. Plazo de terminación
5. Cláusulas especiales
6. Riesgos
Contrato: {text[:6000]}
Responde como JSON.""", format="json")
result = json.loads(analysis)
# Añadir riesgos como comentario
if result.get("risiken"):
add_comment(doc_id, f"Riesgos: {result['risiken']}")
return result
Ejemplo práctico 3: Resumir correspondencia
def summarize_correspondence(text):
"""Resumir correspondencia"""
summary = call_ollama(f"""Resume la correspondencia:
- ¿Quién escriba a quién?
- ¿De qué se trata?
- ¿Qué se solicita u ofrece?
- ¿Hay plazos?
Texto: {text[:4000]}""")
# Guardar como campo personalizado
set_custom_field(doc_id, "zusammenfassung", summary)
return summary
Flujo: tubería completa
Documento escaneado/subido
│
▼
Paperless-ngx OCR
│
▼
Script post-consumo
│
├─► Ollama: clasificar
├─► Ollama: generar etiquetas
├─► Ollama: crear resumen
├─► Ollama: extraer metadatos
│
▼
Paperless-ngx almacena:
- Etiquetas
- Campos personalizados
- Comentarios
│
▼
Opcional: mover a carpeta
Opcional: alerta para documentos críticos
RAG para documentos
def setup_rag(documents):
"""Indexar todos los documentos para búsqueda semántica"""
for doc in documents:
# Dividir texto en fragmentos
chunks = split_into_chunks(doc.text, 500)
for i, chunk in enumerate(chunks):
# Crear embedding
embedding = get_embedding(chunk)
# Guardar en Qdrant
qdrant.upsert(
collection="dokumente",
points=[{
"id": f"{doc.id}_{i}",
"vector": embedding,
"payload": {
"doc_id": doc.id,
"text": chunk,
"title": doc.title
}
}]
)
Con esto puedes hacer preguntas sobre tus documentos:
- “¿Qué dice el contrato de arrendamiento sobre rescisión?”
- “¿Cuáles son las facturas mayores a 1000 €?”
Consulta RAG local.
Consideraciones de seguridad
- Documentos confidenciales: los documentos pueden contener datos sensibles. Usa IA local, no servicios en la nube. Consulta Protección de datos.
- Inyección de prompts: los documentos pueden contener inyecciones. Consulta Inyección de prompts.
- Control de acceso: Paperless-ngx tiene permisos de usuario y grupo. Úsalos.
- Auditoría: registra todo procesamiento con IA. Consulta Auditoría.
- Copias de seguridad: haz backup de documentos y base de datos regularmente. Consulta Copias de seguridad.
Trampa típicas
- Errores de OCR: los documentos escaneados tienen errores OCR. Los resultados de la IA pueden ser incorrectos como resultado.
- Longitud de contexto: los documentos grandes deben dividirse en fragmentos. Consulta Longitud de contexto.
- Clasificación incorrecta: la IA puede clasificar mal. Usa puntuaciones de confianza o revisión manual.
- Rendimiento: documentos grandes con muchas llamadas a IA significa lentitud. Procesa de forma asincrónica.
- Errores en el script: si el script post-consumo falla, el documento no se procesa. Añade logging.
Enlaces relacionados
- Automatización de documentos - documentos con IA.
- RAG local - hacer documentos buscables.
- Ollama - servidor de modelos.
- PDF y OCR - preparar documentos.
- Copias de seguridad - protección de datos.
- Inyección de prompts - seguridad.
Puntos clave:
- Paperless-ngx + Ollama: OCR + comprensión con IA.
- Script post-consumo para clasificación automática, etiquetado y resúmenes.
- Extracción de datos estructurada para facturas, contratos y correspondencia.
- RAG para búsqueda semántica de documentos.
- Seguridad: validación, control de acceso y procesamiento local.
Preguntas frecuentes
¿Cómo conecto Paperless-ngx con Ollama?
¿Qué puede automatizar la IA?
¿Sigo necesitando OCR?
¿Qué tan precisa es la clasificación?
¿Puedo buscar en los documentos?
¿Qué tan rápido es el procesamiento?
¿Mis documentos están seguros?
¿Qué formatos se admiten?
Referencias y lecturas complementarias
- Paperless-ngx - documentación.
- Paperless-ngx Scripts - scripts post-consumo.
- Ollama - servidor de modelos local.
- Tesseract OCR - motor OCR.


