# RAG documental

## Que es RAG

RAG significa `Retrieval-Augmented Generation`: generacion aumentada con busqueda.

En Lightdata:

```text
Usuario pregunta
  -> el backend busca docs/circuitos/tablas relevantes
  -> arma contexto corto
  -> el modelo responde con ese contexto
```

El modelo no debe tener todos los manuales pegados en cada prompt. Debe recibir solo los fragmentos necesarios.

## Por que lo necesitamos

El agente tiene que entender:

- circuitos end-to-end;
- significado de estados;
- tablas y relaciones;
- permisos por perfil;
- procesos batch;
- microservicios;
- reglas de costos y liquidaciones;
- que modulo abrir para cada tarea.

Ese conocimiento es estable, cambia con el codigo y debe venir de documentos versionados.

## Corpus inicial

Indexar estos archivos:

```text
manuales_y_circuitos/*.md
docs/*.md
docs/modulos/*.md
procesos/*.md
MS/README.md
back/lightdata_ai/*.md
```

Prioridad alta:

- `manuales_y_circuitos/02-circuitos-end-to-end.md`
- `manuales_y_circuitos/03-manual-tecnico-desarrollo.md`
- `manuales_y_circuitos/04-estado-modulos.md`
- `manuales_y_circuitos/06-microservicios-y-procesos.md`
- `manuales_y_circuitos/07-agente-logistico-ia.md`
- `manuales_y_circuitos/08-redis-cache-operativo.md`
- `docs/DICCIONARIO-DATOS.md`
- `docs/CIRCUITOS-MS.md`
- `docs/MODELO-DATOS.md`

## Chunking

Partir documentos por seccion Markdown:

```text
titulo h1
subtitulo h2/h3
contenido
path
line_start
line_end
tags
```

Tamanio recomendado:

- 400 a 900 tokens por chunk;
- solapamiento bajo, 50 a 100 tokens;
- conservar encabezados para contexto.

## Metadata

Cada chunk debe tener:

```json
{
  "id": "docs/DICCIONARIO-DATOS.md#envios_historial",
  "path": "docs/DICCIONARIO-DATOS.md",
  "titulo": "envios_historial",
  "dominio": "envios",
  "tipo": "diccionario",
  "tags": ["envios", "historial", "estado", "precioProcesado"],
  "line_start": 120,
  "line_end": 155
}
```

## Busqueda

Primera version simple:

- busqueda textual BM25/LIKE sobre indice local;
- tags manuales por path/seccion;
- ranking por coincidencias de dominio.

Version mejor:

- embeddings locales;
- vector store en Redis/SQLite/Postgres;
- reranking con reglas por modulo/intencion.

Como ya existe Gemma/Ollama local, una alternativa practica es usar embeddings locales con Ollama si el modelo de embeddings esta disponible. Si no, arrancar con busqueda textual.

## Pipeline recomendado

```text
pregunta
  -> detectar dominio/intencion
  -> buscar 5-12 chunks relevantes
  -> filtrar por score y dominio
  -> compactar a "contexto_documental"
  -> combinar con "contexto_operativo"
  -> llamar modelo
```

## Ejemplos

Pregunta:

```text
"por que no se calculo el costo del chofer?"
```

Docs a recuperar:

- proceso chofer lista de precios;
- `envios_historial.precioProcesado`;
- `costos_envios`;
- `sistema_usuarios.lista_de_precios`;
- `sistema_usuarios_accesos.estados_precio`.

Pregunta:

```text
"como se actualiza el informe por zona?"
```

Docs a recuperar:

- `docs/CIRCUITOS-MS.md`;
- `MS/README.md`;
- `ControladorInformes`;
- Redis/cache operativo si pregunta por performance.

## Prompt documental

El backend debe pasar algo asi:

```text
CONTEXTO_DOCUMENTAL:
[1] docs/DICCIONARIO-DATOS.md#envios_historial
envios_historial guarda un movimiento por cambio de estado...

[2] procesos/README.md#proceso_chofer_listaprecios
El proceso usa precioProcesado=0...
```

El modelo debe citar o nombrar las fuentes si la respuesta depende de ellas.

## Ingestion

Comando futuro sugerido:

```text
php back/lightdata_ai/scripts/index_docs.php
```

Salida:

```text
back/lightdata_ai/index/docs_index.jsonl
```

No hace falta resolver embeddings en la primera version. Lo importante es tener el contrato y los chunks.

