<!-- Canonical: https://lucioduran.com/es/projects/llm-semantic-cache
Language: es
Content-SHA256: dafd2d16fabe58872619a3134aaa0fa66db7592af9b608e3ff7fa482486a96e1
-->

[Proyectos](<https://lucioduran.com/es/projects>) / LLM Semantic Cache

# LLM Semantic Cache

Caché exacta y semántica en SQLite con aislamiento por usuario, permisos y versión, invalidación transaccional y evaluación local de aciertos correctos e incorrectos.

Autor: [Lucio Durán](<https://lucioduran.com/es>) · Python 3.11.13 · Licencia: [MIT](<https://github.com/lucioduran/llm-semantic-cache/blob/78efb52757165a2f1dc5cc2f76197317b853643a/LICENSE>)

Ficha publicada: 2026-10-22 · Ficha actualizada: 2026-10-22

[Repositorio](<https://github.com/lucioduran/llm-semantic-cache>) · [Evidencia original](<https://raw.githubusercontent.com/lucioduran/llm-semantic-cache/78efb52757165a2f1dc5cc2f76197317b853643a/results/reference/report.json>) · [Release v0.1.0](<https://github.com/lucioduran/llm-semantic-cache/releases/tag/v0.1.0>)

## Problema y utilidad para agentes

Dos preguntas parecidas pueden necesitar respuestas distintas al cambiar usuario, permisos, entidad, fecha o fuente. La similitud no autoriza reutilizar una respuesta; calcular embeddings también tiene costo.

El proyecto hace explícito el contexto que permite reutilización y mide si el ahorro neto sobrevive al trabajo extra de la caché semántica. Conserva un diagnóstico inseguro para mostrar el efecto de ignorar esos límites.

## Arquitectura

1. **Aislamiento antes de similitud.** Filtra por usuario, permisos, versión, entidad, fecha y namespace del modelo de embeddings antes de comparar. Intenta coincidencia exacta antes de calcular un vector.
2. **Invalidación transaccional.** SQLite coordina escrituras. Un ticket de generación capturado antes de leer fuentes impide guardar resultados anteriores a una invalidación. Expiración, reemplazo y borrado lógico son explícitos.
3. **Evaluación con modelos locales.** MiniLM genera embeddings y FLAN-T5-small responde a 48 solicitudes ficticias por política. Guarda respuestas, decisiones, vectores y tiempos para replay sin inferencia.

- [Diseño y metodología](<https://github.com/lucioduran/llm-semantic-cache/blob/78efb52757165a2f1dc5cc2f76197317b853643a/docs/design.md>)

## Qué demuestra

- Diseño de fronteras de reutilización y rechazo de escrituras en vuelo después de invalidar.
- Medición separada de hits correctos, reutilización incorrecta y exactitud de respuestas.
- Contabilidad de ahorro neto que incluye embedding, lookup, generación, escrituras e invalidación.

## Resultados publicados

Una ejecución local de orden fijo con 48 solicitudes por política, en Intel Xeon W-3223 con cuatro hilos. MiniLM y FLAN-T5-small están fijados por revisión; el umbral de similitud es 0,90.

Las tasas de acierto usan todas las solicitudes como denominador. Un hit correcto exige mismo alcance, hecho solicitado y valor de referencia. El ahorro neto incluye trabajo por solicitud y excluye descarga, carga y calentamiento de modelos.

### Reutilización y tiempo neto

| Política | Hits correctos | Hits incorrectos | Tiempo total (s) | Tiempo ahorrado |
| --- | --- | --- | --- | --- |
| Sin caché | 0/48 | 0/48 | 3.893 | 0% |
| Exacta con aislamiento | 12/48 | 0/48 | 2.915 | 25.1% |
| Semántica con aislamiento | 16/48 | 0/48 | 3.310 | 15.0% |
| Diagnóstico sin aislamiento | 8/48 | 32/48 | 0.717 | Beneficio inválido |

La caché semántica reutilizó cuatro respuestas más que la exacta, pero ahorró menos tiempo: 15,0 % frente a 25,1 %. Consumió 0,308 s en embeddings. La variación de generación también influye; una sola ejecución no establece un orden estable de rendimiento.

El diagnóstico sin aislamiento produjo 32 reutilizaciones incorrectas, el 80 % de sus hits. Sin caché, con caché exacta y con caché semántica se obtuvo 100 % de exact match sobre preguntas numéricas simples; ese resultado no establece seguridad general. [Resumen de resultados](<https://raw.githubusercontent.com/lucioduran/llm-semantic-cache/78efb52757165a2f1dc5cc2f76197317b853643a/results/reference/summary.json>).

## Reproducir

Biblioteca y replay con Python 3.11 o posterior y SQLite, sin dependencias de modelos. La reproducción neural descarga los dos modelos públicos y usa el lock del entorno medido.

Usá una carpeta de salida nueva y ejecutá una medición por vez. Los comandos son POSIX y el lock corresponde a Intel macOS. El llamador debe obtener permisos y alcance de fuentes confiables en cada solicitud.

### Revisar la evidencia guardada

```
git clone https://github.com/lucioduran/llm-semantic-cache.git
cd llm-semantic-cache
git checkout 78efb52757165a2f1dc5cc2f76197317b853643a
python -m scripts.verify results/reference/report.json
```

### Repetir la medición local

```
python3.11 -m venv .venv
. .venv/bin/activate
python -m pip install -r requirements-models.lock
python -m scripts.evaluate download
OMP_NUM_THREADS=4 OPENBLAS_NUM_THREADS=4 MKL_NUM_THREADS=4 python -m scripts.evaluate run --output results/my-run
python -m scripts.verify results/my-run/report.json
```

## Alcance y límites

- La biblioteca no autentica usuarios ni interpreta permisos. Una versión que omita dependencias del prompt, modelo, contenido o política puede permitir reutilización obsoleta.
- Las lecturas concurrentes pueden haber obtenido una respuesta antes de invalidar; no hay barrera de revocación distribuida. La invalidación global de tickets puede rechazar escrituras no relacionadas.
- Búsqueda semántica lineal por alcance, sin índice vectorial, single-flight, límite de tamaño ni limpieza automática. El borrado es lógico.
- Corpus pequeño escrito por el autor, una ejecución y sin intervalos temporales. No es auditoría de seguridad, prueba de escala ni evaluación general de calidad.

- [Orquestación de IA, memoria y reutilización de respuestas](<https://lucioduran.com/es/blog/semantic-kernel-langchain-ai-orchestration>)

## Fuentes y revisión

Resultados del informe y trazas incluidos en v0.1.0. El informe identifica el commit de implementación, pero no contiene una fecha de ejecución. La fecha de release se muestra por separado.

- Revisión consultada: [` 78efb52757165a2f1dc5cc2f76197317b853643a `](<https://github.com/lucioduran/llm-semantic-cache/commit/78efb52757165a2f1dc5cc2f76197317b853643a>)
- Revisión registrada por el experimento: [` c9c450254b5e7875c04611b5e3e4d22addca6db6 `](<https://github.com/lucioduran/llm-semantic-cache/commit/c9c450254b5e7875c04611b5e3e4d22addca6db6>)
- Release publicada: [v0.1.0](<https://github.com/lucioduran/llm-semantic-cache/releases/tag/v0.1.0>) · 2026-10-21T23:13:38Z

- [README y uso](<https://github.com/lucioduran/llm-semantic-cache/blob/78efb52757165a2f1dc5cc2f76197317b853643a/README.md>)
- [Evidencia original](<https://raw.githubusercontent.com/lucioduran/llm-semantic-cache/78efb52757165a2f1dc5cc2f76197317b853643a/results/reference/report.json>)
- [Resumen de resultados](<https://raw.githubusercontent.com/lucioduran/llm-semantic-cache/78efb52757165a2f1dc5cc2f76197317b853643a/results/reference/summary.json>)
- [Respuestas y trazas originales](<https://raw.githubusercontent.com/lucioduran/llm-semantic-cache/78efb52757165a2f1dc5cc2f76197317b853643a/results/reference/trace.jsonl>)
- [Diseño y metodología](<https://github.com/lucioduran/llm-semantic-cache/blob/78efb52757165a2f1dc5cc2f76197317b853643a/docs/design.md>)
- [Datos y procedencia](<https://raw.githubusercontent.com/lucioduran/llm-semantic-cache/78efb52757165a2f1dc5cc2f76197317b853643a/data/requests.json>)
- [Configuración congelada](<https://raw.githubusercontent.com/lucioduran/llm-semantic-cache/78efb52757165a2f1dc5cc2f76197317b853643a/data/config.json>)
- [Análisis de errores](<https://github.com/lucioduran/llm-semantic-cache/blob/78efb52757165a2f1dc5cc2f76197317b853643a/docs/methodology.md>)
- [Modelos, revisiones y licencias](<https://github.com/lucioduran/llm-semantic-cache/blob/78efb52757165a2f1dc5cc2f76197317b853643a/docs/model-notices.md>)
- [Dependencias del entorno medido](<https://github.com/lucioduran/llm-semantic-cache/blob/78efb52757165a2f1dc5cc2f76197317b853643a/requirements-models.lock>)
- [Licencia MIT](<https://github.com/lucioduran/llm-semantic-cache/blob/78efb52757165a2f1dc5cc2f76197317b853643a/LICENSE>)
