← Todos los proyectos

itza-rag

Un pipeline RAG local sin framework — embeddings vía Ollama, almacén en disco de dos archivos y coseno por fuerza bruta en NumPy, para que un modelo chico corriendo en tu máquina "conozca" un repo.

PythonOllamaNumPyRAG

Tengo un agente local corriendo sobre un modelo chico (qwen2.5-coder:7b) en mi propia máquina: sin browsing, sin API de pago, sin ventana de contexto para tragarse un repo entero. Para que sirviera de algo necesitaba que conociera la carpeta sobre la que trabaja. itza-rag es lo mínimo que resuelve eso: un pipeline RAG local en un solo archivo de Python, sin LangChain, sin base de datos vectorial y sin servicio de nadie.

Qué hace

Dos comandos, y ya:

itza_rag.py index  <carpeta> [--out DIR] [--exts .py,.ts,.md,...]
itza_rag.py query  "<pregunta>" --index DIR [--k 5] [--model qwen2.5-coder:7b]

index recorre la carpeta, parte los archivos en chunks, los embebe y guarda el resultado en disco. query embebe la pregunta, saca los k chunks más parecidos, los pega como contexto y se los manda al modelo local con una instrucción deliberadamente estricta: responde solo con el contexto de abajo, cita el archivo:líneas de donde lo sacaste, y si el contexto no alcanza responde NO_SE: con lo que falta. Un modelo chico obligado a citar y con permiso explícito de decir “no sé” miente muchísimo menos.

Y trae escrita su propia regla de uso, que es la parte que me importa: para “¿dónde está definido X?” se usa ripgrep, no esto. Este pipeline es para preguntas conceptuales — “¿cómo funciona X?”, “¿por qué se hizo Y así?” — que son justo las que una búsqueda literal no contesta. Saber qué herramienta no usar es la mitad del valor.

Bajo el capó

Embeddings vía Ollama. Se llama a /api/embed con nomic-embed-text, en lotes de 32, contra el Ollama que ya corre local. Sin key, sin cuota, sin que el código salga de la máquina.

Chunking distinto según el archivo. Los .md se parten por encabezado (#, ##, …), porque en un documento el encabezado es la unidad semántica. El código se parte por bloques separados por línea en blanco y luego se fusionan hasta un techo de 80 líneas, lo que evita a la vez los chunks de una sola línea (inútiles para el coseno) y los chunks gigantes que diluyen la señal. Cada chunk se guarda con su archivo y su rango de líneas — de ahí salen las citas.

El “almacén vectorial” son dos archivos. Una matriz embeddings.npy con los vectores ya normalizados y un chunks.json con los textos y su procedencia. Nada de Chroma, Pinecone ni FAISS.

La búsqueda es un producto punto. Como los vectores están normalizados al indexar, la similitud coseno es literalmente matrix @ qvec, y el top-k sale de un argsort. Es fuerza bruta y no me disculpo: para menos de ~100k chunks NumPy lo resuelve en un parpadeo, y montar un índice ANN aquí sería pagar complejidad por un problema que no tengo.

También ignora lo que hay que ignorar (.git, node_modules, dist, .venv, __pycache__, .angular, …) y respeta una lista de extensiones configurable.

El stack

  • Python 3 — solo librería estándar más NumPy. Cero frameworks de RAG.
  • Ollama en local: nomic-embed-text para embeber, qwen2.5-coder:7b (o el que le pases con --model) para responder.
  • Almacén en disco: .npy + .json, dos archivos por índice.
  • CLI con argparse, unos 200 renglones en un solo archivo.

Vale la pena mencionar

Este proyecto está en la lista justamente por lo que no tiene. Un RAG “completo” hoy son cinco dependencias, un servidor de base de datos vectorial y una capa de abstracción que hay que aprender. La versión que de verdad necesitaba —indexar una carpeta y contestar preguntas conceptuales sobre ella— cabe en un archivo que puedo leer entero en cinco minutos, y por eso puedo depurarlo y cambiarle el chunking cuando una respuesta sale mal.

Aparte, es la pieza local de un arreglo más grande: el agente chico de la máquina puede contestar sobre un repo sin mandar el código a ninguna API ni gastar de la cuota de los modelos grandes. Ese reparto —lo barato y privado en local, lo caro y capaz en la nube, y una manera clara de decidir qué va dónde— es la misma que persigue Agent Fleet Console, el otro proyecto de esta lista.

¿Un café y platicamos?

¿Te gustó lo que leíste? Construyo productos así de punta a punta — y siempre estoy para una buena plática. Hablemos del tuyo, o nomás intercambiamos ideas con un café.