Abierto a propuestas

Rodrigo
Torres

Ingeniero de IA y fundador de Árkos

clientes desde 2020
45+
proyectos entregados
50+
personas en el equipo
9
años de IA en producción
2
  • SUNAT, pasarelas y libros contables
  • Dirijo a nueve personas y sigo en el código

Fundé una consultora de nueve personas. Seis años entregando software, dos con modelos en producción.

BM25 + búsqueda vectorial // Reciprocal Rank Fusion // servidores MCP // FastAPI // Step Functions // AWS Lambda // CDK // DynamoDB // walk-forward // PostgreSQL // facturación electrónica // pytest

Pregúntale a la página

Buscador escrito para esta página: 39 pasajes, BM25 más vectorial fusionados con RRF. No es PrecioVivo, que es el sistema del caso y corre sobre un catálogo de precios.

Lo que mide ese buscador

Escribí un gold set y la fusión perdió una vez

El buscador de arriba estaba descrito como híbrido y calificado por nadie. Veintiséis preguntas, cada una con los pasajes que de verdad la responden, marcados leyendo los pasajes y no leyendo lo que devolvía la búsqueda. Tres configuraciones que se diferencian en una sola cosa cada una.

Solo léxica (BM25)

0.692

Recall@4 · [0.50, 0.83]

MRR
0.608
NDCG@4
0.574
Solo vectorial

0.885

Recall@4 · [0.71, 0.96]

MRR
0.835
NDCG@4
0.800
Fusionadas con RRFConfiguración

0.923

Recall@4 · [0.76, 0.98]

MRR
0.789
NDCG@4
0.756
Cómo se lee la corrida

La mitad léxica sola falla ocho de veintiséis, y las ocho son preguntas que no comparten ninguna palabra con su pasaje: si construye solo o acompañado, si alguna vez rompió producción, cuánto pretende ganar. Eso es exactamente lo que un índice vectorial existe para resolver.

La fusión recupera una pregunta que ninguna de las dos mitades encuentra por su cuenta, y es la prueba de que fusionar no es decoración: dos señales débiles en listas distintas suman a una posición que ninguna alcanzaba sola.

También paga por ello. El MRR de la fusión (0.789) queda por debajo del de la vectorial sola (0.835): mete la respuesta en los cuatro más veces, y la deja algo más abajo dentro de esos cuatro. Con cuatro pasajes yendo al modelo eso importa poco, y con un solo resultado en pantalla importaría mucho.

En inglés la fusión queda por debajo de la vectorial sola, 0.769 contra 0.846, y pierde las tres preguntas donde discrepan. Con n de 26 el test de signos da p = 0.25, que no distingue eso del azar. Cambiar la configuración por idioma con esa evidencia sería ajustar el sistema al gold set, así que corre la misma en los dos.

El intervalo de Wilson es la parte que no se puede saltar. Un recall de 0.923 sobre 26 casos es 0.923 [0.76, 0.98]: el sistema puede estar en 0.76 y el gold set no lo sabría. Veintiséis casos son un punto de partida, no una respuesta.

Un defecto real salió de aquí. Las dos listas entraban a la fusión con profundidades distintas: la léxica entera, la vectorial cortada en 12. BM25 se queda con todo pasaje que puntúe sobre cero, mediana de 31 de 39, así que un pasaje en el puesto 30 seguía recibiendo voto y ninguna coincidencia vectorial comparable podía responderle. Cortar las dos a la misma profundidad subió el recall en español de 0.885 a 0.923. La corrección se justifica por el argumento; la cifra solo dice cuánto costaba.

¿Te suena?

Contratar a un ingeniero de IA es contratar cifras que nadie puede verificar.

Casi todo portafolio de IA afirma resultados sin decir cómo se midieron ni dónde falla el sistema. Yo publico la condición de medición junto a cada número, y una sección entera dedicada a lo que se rompe. Si algo no lo puedo enlazar a su fuente, no aparece.

Cómo trabajo ↗
Medida, fuente sin publicar: fuentes por publicar. Cada cifra las espera antes de contar como probada.fuentes por publicar. Cada cifra las espera antes de contar como probada.
37
Cómo busca el sistema

Cercanía es la medida

Un índice vectorial no guarda palabras, guarda direcciones. Cada fragmento es un punto y responder una consulta es preguntar qué puntos apuntan hacia el mismo lado. Acerca el cursor y mira lo que hace cada trazo: eso es lo que ocurre 9,125 veces cuando escribes una pregunta.

El campo responde al cursor. El índice responde a la consulta.

Medido, no estimadoTodas las mediciones ↗

Cada cifra con la condición en la que se tomó

Medida, fuente sin publicar: la corrida de evaluación con jina-embeddings-v3Aporte de la vectorial
0.862

Recall de la búsqueda aislada del piso determinista, con el embebedor real. Con el de juguete daba 0.759: la diferencia es lo único que prueba que la mitad semántica no es decoración

Por verificar: la corrida de evaluaciónViolaciones del gold set
2

Con el embebedor real. Preguntar por papaya, que no está en el catálogo, devuelve fichas de papa: 0.6444 contra 0.6656, dos centésimas. Ningún umbral las separa sin matar las preguntas agregadas

Medida, fuente sin publicar: definición de las herramientasHerramientas MCP
8

Servidor MCP en producción del sistema RAG

Medida, fuente sin publicar: esquema OpenAPIRutas FastAPI
13

La misma superficie, expuesta por HTTP

Por verificar: salida de las dos suitesTests del RAG
392 + 77

392 en pytest, 77 en vitest

Por verificar: notebook de validaciónGradient boosting
0.1711

Misma validación walk-forward. Perdió contra AR(1)

Experiencia

Fundador y líder técnico de Árkos. Diseño la arquitectura y construyo, no solo dirijo.

6años de desarrollo
2años de IA en producción
50+proyectos entregados
45+clientes
20+sistemas en producción
9personas en el equipo
Medida, fuente sin publicar: caso con métricas del clienteSolutec

2+ años en producción, 650 órdenes de trabajo al mes, 15 usuarios, 45% menos tiempo de cierre

Medida, fuente sin publicar: caso con métricas del clienteAll White Vacations

4,000 reservas, 43% menos overbooking

Medida, fuente sin publicar: salida de la suiteRestHUB

49 módulos de backend, 130 pantallas, 2,371 tests en 281 archivos, 5 locales, 500 transacciones diarias

Medida, fuente sin publicar: repositorioSignMed

MediaPipe, secuencias de 35 frames, CNN y LSTM en TensorFlow. Corregí escalada de privilegios, secreto por defecto commiteado y lectura sin límite de archivos subidos

Medida, fuente sin publicar: caso con métricas del clienteFacturArkos

60% menos tiempo de emisión

Medida, fuente sin publicar: ficha en las tiendasRapiditos

Flutter sobre backend Spring Boot, publicada en App Store y Google Play

Medida, fuente sin publicar: caso con métricas del clienteClínica Juan Pablo II

78% de citas gestionadas digitalmente

Medida, fuente sin publicar: caso con métricas del clienteSolutec DHA

40% más consultas mensuales por canal digital

Los límites tienen la misma jerarquía que los resultados.

Medida, fuente sin publicar: la corrida de evaluación con el embebedor realSistema RAG

Papaya devuelve papa, y no lo arreglé en recuperación

Dónde y por qué

Preguntar por un producto que no está en el catálogo devuelve el más parecido por nombre. Papaya puntúa 0.6444 y papa 0.6656: dos centésimas. Probé el umbral obvio y no funciona, porque cualquier corte que las separe mata las preguntas agregadas, que puntúan 0.5151. Lo resolví avisando al modelo desde el filtro léxico, que ya sabía que ninguna palabra coincidía con el catálogo. La evaluación sigue reportando las dos violaciones: no relajé el gold set.

Medida, fuente sin publicar: cálculo del tamaño de estadoPronóstico en AWS

Se rompe a los 510 productos

Dónde y por qué

514 bytes por elemento del Map contra el tope de 256 KB de estado de Step Functions. Sobre ese número hay que paginar el Map o mover la carga a S3.

¿Conversamos?

Respondo rápido y sin plantilla.