rag-service/RAG/docs/INGESTA.md
2026-04-05 17:49:35 +02:00

17 KiB

Ingesta

Proyecto: Workspace de tools IA para empresas
Modulo: RAG
Ultima actualizacion: 2026-04-02
Ultima modificacion por: Agente tools IA para potenciar servicios empresariales
Estado: En definicion


Proposito

Definir que es la ingesta dentro del sistema RAG, que responsabilidades tiene y que debe dejar preparado para el resto de modulos.


Que es la ingesta

La ingesta es el punto de entrada del conocimiento al RAG.

Su funcion es recibir fuentes de informacion y convertirlas en entradas manejables para el sistema, dejandolas listas para su posterior procesado, indexacion y recuperacion.

No debe encargarse de todo el pipeline. Su objetivo es incorporar y registrar correctamente las fuentes.


Responsabilidades de la ingesta

La ingesta debe ocuparse de:

  1. Recibir una fuente de informacion.
  2. Identificar su tipo.
  3. Leer su contenido o referencia.
  4. Registrar metadatos basicos.
  5. Entregar el resultado a la fase de procesado.

Tipos de fuente previstos

La primera version puede empezar por documentos, pero la ingesta debe nacer pensada para admitir mas tipos de fuente.

Fuentes previstas:

  • archivos locales
  • carpetas
  • documentacion de proyecto
  • codigo fuente de proyecto
  • repositorios
  • endpoints o APIs
  • bases de datos
  • otras fuentes conectables en el futuro

Alcance de la primera version

La primera version de la ingesta debe centrarse en:

  • leer archivos de documentacion
  • leer PDFs con texto extraible
  • leer codigo fuente del proyecto
  • recorrer carpetas concretas
  • registrar que fuente entro al sistema
  • dejar preparada la extension a nuevas fuentes mas adelante

Caso practico inicial:

  • carpeta docs/ del workspace como primera fuente real de prueba
  • carpeta RAG/src/ como primera fuente real de prueba para el modo codigo

Salida esperada de la ingesta

La ingesta no debe devolver aun conocimiento recuperable final. Debe devolver una representacion normalizada de la fuente para el siguiente modulo.

Esa salida deberia incluir como minimo:

  • identificador de fuente
  • tipo de fuente
  • origen o ruta
  • contenido bruto o accesible
  • fecha de lectura
  • metadatos basicos disponibles

Metadatos minimos aceptados

La primera propuesta aceptada para metadatos minimos del sistema es esta:

  • source_id
  • source_type
  • source_path o source_ref
  • document_id
  • chunk_id
  • title
  • updated_at
  • hash
  • status
  • version
  • tags

Metadatos recomendados adicionales para la capa de embeddings:

  • embedding_provider
  • embedding_model
  • embedding_dimensions

No todos tendran el mismo peso en la v1, pero conviene que el diseño nazca preparado para soportarlos.

Por que se adopta este conjunto:

  • source_id, document_id y chunk_id permiten trazabilidad y actualizacion por niveles.
  • source_type y source_path o source_ref permiten entender de donde salio cada entrada.
  • title mejora legibilidad, depuracion y futuras recuperaciones.
  • updated_at, hash, status y version preparan el sistema para cambios, invalidez y evolucion de contenido.
  • tags deja abierta una capa ligera de clasificacion sin obligar a una taxonomia compleja en la v1.

Jerarquia de identificacion

Se adopta una jerarquia simple de 3 niveles:

  1. source
  • origen logico de ingesta
  • ejemplos: carpeta docs/, carpeta src/, repositorio, API, tabla o coleccion externa
  1. document
  • unidad concreta dentro de la fuente
  • ejemplos: docs/HISTORIAL_SESIONES.md, src/app/main.ts, manual_cliente.pdf
  1. chunk
  • fragmento recuperable del documento

Esta separacion permite actualizar una pieza concreta sin tener que tratar toda la fuente como si hubiera cambiado por completo.

Por que se adopta esta jerarquia:

  • una carpeta o repositorio no debe ser la unica unidad de control, porque los cambios reales suelen ocurrir a nivel de documento.
  • un mismo documento debe poder actualizarse sin reingestar toda la fuente completa.
  • el chunk debe ser la unidad de recuperacion, no de identidad principal del conocimiento.
  • esta estructura se parece a un sistema de versionado por niveles, y deja abierta la puerta a historico, reindexacion parcial y auditoria.

Criterio para los identificadores

Se trabajara con estos tres identificadores:

  • source_id: identifica la fuente logica
  • document_id: identifica el documento concreto
  • chunk_id: identifica cada fragmento recuperable

La carpeta docs/ puede ser una source, pero docs/HISTORIAL_SESIONES.md debe tener su propio document_id para poder detectar cambios, reindexar y mantener trazabilidad fina.

Por que se decide asi:

  • si source_id absorbiera toda la identidad, perderiamos control fino sobre los documentos internos.
  • si solo identificaramos chunks, perderiamos una unidad intermedia clave para actualizacion, limpieza y observabilidad.
  • separar estos tres identificadores permite mantener el sistema simple pero preparado para crecer.

Propuesta concreta para construir los identificadores

Se adopta esta propuesta inicial.

source_id

Formato: src:<tenant>:<source_kind>:<source_name>

Ejemplos:

  • src:default:folder:workspace-docs
  • src:default:folder:project-code
  • src:default:manual:client-upload
  • src:cliente-a:repo:backend-api
  • src:cliente-a:api:java-docs

Que representa:

  • el origen logico de ingesta
  • no un archivo concreto
  • debe mantenerse estable aunque cambien documentos internos

Que significa tenant:

  • es el espacio logico de separacion de datos
  • sirve para distinguir clientes, proyectos, entornos o contextos aislados dentro del mismo RAG
  • en la v1 puede usarse simplemente default cuando aun no necesitemos separar nada

Para que nos sirve en nuestro sistema:

  • deja preparado el RAG para dar servicio a varios clientes o aplicaciones sin mezclar su informacion
  • permite que una misma arquitectura y un mismo servicio RAG trabajen para varios consumidores
  • facilita crecer hacia un modelo centralizado en el que mejoramos el RAG una vez y varios clientes o apps se benefician

Ejemplo practico de multi-tenant:

  • src:cliente-a:folder:workspace-docs
  • src:cliente-b:folder:workspace-docs

Ambos pueden tener un archivo llamado docs/manual.md, pero seguiran siendo distintos porque pertenecen a tenants diferentes.

Esto evita mezclar conocimiento de clientes o proyectos distintos dentro del mismo sistema.

Reglas:

  • tenant: default si no hay cliente o espacio separado aun
  • source_kind: tipo logico de fuente, por ejemplo folder, repo, manual, api, db
  • source_name: nombre corto, legible y estable

document_id

Formato: doc:<source_id>:<document_key>

Ejemplos:

  • doc:src:default:folder:workspace-docs:docs/historial_sesiones.md
  • doc:src:default:folder:project-code:src/app/main.ts
  • doc:src:default:manual:client-upload:manual_cliente.pdf
  • doc:src:cliente-a:api:java-docs:list

Que representa:

  • el documento o unidad concreta dentro de una fuente
  • es la unidad principal para detectar cambios, desapariciones o reingesta selectiva

Reglas:

  • usar ruta relativa si existe
  • si no existe ruta, usar nombre normalizado o referencia estable
  • evitar espacios y diferencias cosmeticas innecesarias en el identificador

chunk_id

Formato: chk:<document_id>:<chunk_mode>:<chunk_index>

Ejemplos:

  • chk:doc:src:default:folder:workspace-docs:docs/historial_sesiones.md:documental:0001
  • chk:doc:src:default:folder:project-code:src/app/main.ts:codigo:0003

Que representa:

  • cada fragmento recuperable del documento

Reglas:

  • chunk_mode: permite distinguir si el chunk fue generado en modo documental o codigo
  • chunk_index: indice secuencial con padding para mantener orden legible

Ejemplo practico simple:

Supongamos esta fuente:

  • source_id: src:default:folder:workspace-docs

Y dentro de ella dos documentos:

  • document_id: doc:src:default:folder:workspace-docs:docs/readme.md
  • document_id: doc:src:default:folder:workspace-docs:docs/historial_sesiones.md

Si docs/readme.md se parte en 3 chunks documentales:

  • chk:doc:src:default:folder:workspace-docs:docs/readme.md:documental:0001
  • chk:doc:src:default:folder:workspace-docs:docs/readme.md:documental:0002
  • chk:doc:src:default:folder:workspace-docs:docs/readme.md:documental:0003

Y docs/historial_sesiones.md se parte en 2 chunks documentales:

  • chk:doc:src:default:folder:workspace-docs:docs/historial_sesiones.md:documental:0001
  • chk:doc:src:default:folder:workspace-docs:docs/historial_sesiones.md:documental:0002

El 0001 no compite con el 0001 del otro documento.

El indice solo tiene sentido dentro de su propio document_id.

Eso permite:

  • saber a que documento pertenece cada chunk
  • conservar el orden interno del documento
  • distinguir chunks de distintos modos si algun dia un mismo documento se procesa de manera diferente

Normalizacion recomendada

Para mantener consistencia:

  • usar minusculas cuando no rompa semantica importante
  • reemplazar espacios por guion bajo o guion medio segun convenga
  • usar rutas relativas como referencia principal cuando existan
  • evitar caracteres redundantes o variables del entorno que rompan estabilidad
  • no incluir hashes dentro del identificador principal

El hash debe vivir como metadato, no como parte del ID. Asi el identificador se mantiene estable y el hash sirve para detectar cambios.


Propuesta para document_key

Se adopta esta regla general:

  • si el documento pertenece a una fuente con estructura de rutas, usar su ruta relativa normalizada dentro de la fuente
  • si el documento no tiene ruta natural, usar un nombre o referencia estable normalizada
  • si la fuente es derivada o externa, usar una referencia corta y estable que identifique la unidad documental

Formato esperado

document_key debe ser:

  • legible
  • estable
  • relativo a la fuente cuando sea posible
  • suficientemente especifico para no colisionar dentro de una misma source

Reglas de normalizacion

  1. Usar ruta relativa respecto de la fuente cuando exista.
  2. Unificar separadores a /.
  3. Eliminar prefijos absolutos del sistema.
  4. Mantener la extension del archivo si aplica.
  5. Convertir a minusculas cuando no rompa semantica importante.
  6. Reemplazar espacios por _.
  7. Evitar caracteres redundantes o decorativos.
  8. No incluir hashes, timestamps volatiles ni parametros temporales.

Ejemplos

Fuente tipo carpeta

  • fuente: src:default:folder:workspace-docs
  • archivo real: /home/pancho/Documentos/Empresa/Desarrollo/IA/docs/HISTORIAL_SESIONES.md
  • document_key: docs/historial_sesiones.md

Fuente tipo repo

  • fuente: src:default:repo:backend-api
  • archivo real: /repo/src/app/main.ts
  • document_key: src/app/main.ts

Documento suelto manual

  • fuente: src:default:manual:client-upload
  • archivo real: Manual Cliente Final.pdf
  • document_key: manual_cliente_final.pdf

Fuente derivada o externa

  • fuente: src:default:api:java-docs
  • unidad documental: documentacion de ArrayList
  • document_key: java/util/arraylist

Por que se decide asi

  • mantiene trazabilidad sin depender de rutas absolutas del entorno
  • evita que mover el proyecto de maquina o carpeta rompa la identidad del documento
  • funciona tanto para archivos estructurados como para documentos sueltos o fuentes externas
  • deja el sistema preparado para futuras ingestas derivadas sin cambiar el modelo base

Aclaracion importante:

  • document_key es una identidad interna estable
  • no debe ser la unica referencia para recargar el fichero real
  • para reingesta o recarga debe mantenerse tambien el localizador original del recurso

Documentos sueltos y fuentes por defecto

El sistema debe soportar tambien documentos sueltos que no pertenezcan de forma natural a una carpeta o coleccion preexistente.

Ejemplo:

  • un PDF entregado por un cliente

En esos casos:

  • el documento seguira teniendo su propio document_id
  • no se dejara source_id vacio o nulo
  • se usara una fuente logica por defecto para agrupar este tipo de entradas

La idea es que el sistema pueda distinguir entre:

  • documentos nacidos dentro de una fuente estructurada
  • documentos incorporados como entradas sueltas

Esto evita nulos, mantiene consistencia y deja abierta la posibilidad de definir despues varias fuentes logicas para documentos manuales, aportados por cliente o cargados desde otras vias.

Por que se decide asi:

  • un documento suelto sigue necesitando un origen logico dentro del sistema.
  • evitar null en source_id simplifica reglas internas, validaciones y futuras integraciones.
  • agrupar documentos sueltos bajo una fuente logica por defecto permite empezar simple y luego especializar si hace falta.

Vision de integracion futura

Este diseño de ingesta tambien debe facilitar que el RAG pueda integrarse mas adelante con herramientas y entornos de trabajo del propio equipo, por ejemplo OpenCode por proyecto.

La idea es que, aunque la documentacion exista fisicamente en disco, el RAG pueda ofrecer una capa practica de acceso al conocimiento del proyecto a medida que ese conocimiento crezca.

Esto refuerza varias decisiones tomadas en este modulo:

  • trazabilidad por fuente, documento y chunk
  • soporte para carpetas completas y documentos sueltos
  • preparacion para actualizacion de contenido
  • diseño desacoplado del tipo concreto de consumidor

Relacion con el modulo de actualizacion

La ingesta debe quedar preparada para convivir con un futuro sistema de actualizacion.

Eso implica que, desde el inicio, conviene contemplar:

  • deteccion de nuevas fuentes
  • deteccion de cambios en fuentes ya conocidas
  • posibilidad de releer una fuente
  • trazabilidad de cuando y desde donde entro una version concreta

No es necesario implementar todo esto en la primera version, pero si diseñarlo para no bloquear su evolucion posterior.


Principios de diseño

  • Simple en la primera version.
  • Desacoplada del tipo concreto de fuente.
  • Preparada para crecimiento.
  • Trazable desde el origen.
  • Compatible con futuras actualizaciones y versionado.

Uso de modelo durante la ingesta

Se acepta que el sistema RAG podra usar un modelo tambien en la fase de entrada, no solo en la fase de salida o consumo.

Su funcion no seria responder al usuario final, sino ayudar a:

  • entender mejor el contenido entrante
  • detectar tema principal y puntos clave
  • extraer estructura util
  • identificar elementos criticos o destacables
  • preparar mejor el conocimiento que luego consumira el RAG

Criterio actual:

  • en la primera fase no debemos depender obligatoriamente de modelos caros para esta tarea
  • mas adelante puede existir un modelo fijo de uso interno dentro del pipeline de ingesta
  • tambien queda abierta una futura interfaz interactiva de alimentacion en la que el usuario pueda escoger un modelo mas potente si quiere enriquecer el procesamiento

Implicacion de diseño:

La ingesta no debe quedar pensada solo como lectura mecanica de archivos. Debe poder evolucionar hacia una ingesta asistida por modelo.


Modos de ingesta previstos

Se adopta este criterio de funcionamiento:

  • por defecto, la ingesta funcionara en modo mecanico
  • ese modo seguira pudiendo usar un modelo predefinido dentro del pipeline si asi se define
  • la arquitectura debe quedar preparada desde el inicio para recibir parametros de modo o de interaccion
  • si esos parametros existen, la ingesta podra comportarse como una ingesta enriquecida o interactiva

Esto permite que la primera version funcione sin rehacer la arquitectura cuando se amplie.

Modo por defecto

Si no se reciben parametros especiales desde una interfaz:

  • la ingesta actua de forma automatica
  • usa el modelo predefinido si corresponde
  • no espera decisiones del usuario

Modo interactivo o enriquecido

Si se reciben parametros desde una interfaz o flujo enriquecido:

  • la ingesta puede detectar que no esta en modo basico
  • puede permitir cambio de modelo
  • puede recibir instrucciones, marcas o directrices del usuario
  • puede priorizar o etiquetar informacion importante antes de indexar

Objetivo de este diseño

Separar desde el inicio:

  • funcionamiento base estable y automatizable
  • enriquecimiento opcional sin romper el flujo normal de ingesta

Esto evita tener que rehacer el codigo cuando el sistema evolucione.


Enriquecimiento ligero opcional

Se deja abierta una via para un enriquecimiento ligero opcional desde etapas tempranas, siempre que no entorpezca la ingesta.

La forma mas simple de hacerlo seria:

  • mantener la ingesta mecanica como camino principal
  • ejecutar el enriquecimiento solo si llega un parametro explicito
  • limitar ese enriquecimiento a tareas pequenas y acotadas

Ejemplos adecuados para ese enriquecimiento ligero:

  • extraer tema principal
  • proponer palabras clave
  • detectar posibles puntos criticos
  • generar una descripcion corta del documento

Ejemplos que no conviene meter en esta fase ligera:

  • analisis profundo costoso
  • interacciones largas con usuario
  • multiples rondas de refinado
  • procesos que bloqueen innecesariamente la ingesta base

Criterio recomendado:

El enriquecimiento ligero debe ser:

  • opcional
  • rapido
  • barato
  • no bloqueante
  • facil de omitir sin afectar al pipeline principal

Preguntas a cerrar

  1. Si la ingesta trabajara por archivos individuales, carpetas, colecciones o todo a la vez.
  2. Como construiremos exactamente source_id, document_id y chunk_id.
  3. Que nombre tendran las fuentes logicas por defecto para documentos sueltos.
  4. Como distinguiremos entre fuente nueva, fuente actualizada y fuente obsoleta.