

Las traducciones son generadas a través de traducción automática. En caso de conflicto entre la traducción y la version original de inglés, prevalecerá la version en inglés.

# Prácticas recomendadas
<a name="semantic-caching-best-practices"></a>

## Elegir los datos que se pueden almacenar en caché
<a name="semantic-caching-bp-choosing-data"></a>

El almacenamiento en caché semántico es ideal para consultas repetidas cuyas respuestas son relativamente estables, mientras que las respuestas en tiempo real o muy dinámicas suelen ser malas candidatas para el almacenamiento en caché.

Utilice filtros numéricos y de etiquetas derivados del contexto de la aplicación existente (como el identificador del producto, la categoría, la región o el segmento de usuarios) para decidir qué consultas y respuestas son aptas para el almacenamiento en caché y mejorar la relevancia de las visitas a la memoria caché.

## Ajuste del umbral de similitud
<a name="semantic-caching-bp-threshold"></a>

El umbral de similitud controla la compensación entre la tasa de aciertos de la caché y la calidad de la respuesta. Elija un umbral que equilibre el ahorro de costes con la precisión para su caso de uso:


| Threshold | Tasa de aciertos | Riesgo de calidad | Lo mejor para | 
| --- | --- | --- | --- | 
| 0.95 (estricto) | Bajo (\~ 25%) | Muy bajo | Aplicaciones médicas, legales y financieras | 
| 0.90 (moderada) | Medio (\~ 55%) | Bajo | Chatbots generales | 
| 0.80 (balanceado) | Alto (\~ 75%) | Bajo-medio | Preguntas frecuentes: bots, soporte de TI | 
| 0.75 (relajado) | Muy alto (\~ 90%) | Medio | High-volume consultas repetitivas | 

**importante**  
Comience con un umbral más alto (0,90—0,95) y baje gradualmente mientras supervisa la precisión. Utilice A/B las pruebas para encontrar el equilibrio óptimo para su carga de trabajo.

## Consultas independientes versus conversaciones
<a name="semantic-caching-bp-standalone-vs-conversations"></a>
+ **Para consultas independientes**: aplique el almacenamiento semántico en caché directamente al texto de la consulta del usuario.
+ **Para conversaciones de varios turnos**: utilice primero la memoria de conversaciones para recuperar los datos clave y los mensajes recientes necesarios para responder al turno actual. A continuación, aplique el almacenamiento semántico en caché a la combinación del mensaje del usuario actual y el contexto recuperado, en lugar de incrustar todo el diálogo sin procesar.

## Establecer períodos de invalidación de la memoria caché
<a name="semantic-caching-bp-ttl"></a>

Use el TTL para controlar cuánto tiempo se sirven las respuestas almacenadas en caché antes de que se regeneren en caso de falta de memoria caché.


| Tipo de datos: | TTL recomendado | Justificación | 
| --- | --- | --- | 
| Datos estáticos (documentación, políticas) | 24 horas | Los hechos cambian con poca frecuencia | 
| Información del producto | De 12 a 24 horas | Se actualiza a diario en la mayoría de los catálogos | 
| Respuestas del asistente general | De 1 a 4 horas | Equilibre la frescura con la tasa de aciertos | 
| Real-time datos (precios, inventario) | De 5 a 15 minutos | Los datos cambian con frecuencia | 
| Contexto de conversación | 30 minutos | Session-scoped, de corta duración | 

```
# Set TTL with random jitter to spread out cache invalidations
import random

base_ttl = 82800  # ~23 hours
jitter = random.randint(0, 3600)  # Up to 1 hour of jitter
valkey_client.expire(cache_key, base_ttl + jitter)
```

**sugerencia**  
Configure los TTL que se adapten al caso de uso de su aplicación y a la frecuencia con la que cambian las salidas de sus datos o modelos. Los TTL más largos aumentan las tasas de aciertos de la memoria caché, pero aumentan el riesgo de que las respuestas estén desactualizadas. Los TTL más cortos mantienen las respuestas más actualizadas, pero reducen las tasas de aciertos de la caché y requieren más inferencias de LLM.

## Supervisión y seguimiento de costes
<a name="semantic-caching-bp-monitoring"></a>

Realice un seguimiento de las métricas de rendimiento de la caché para optimizar su caché semántica a lo largo del tiempo:

```
def record_cache_event(valkey_client, event_type: str):
    """Track cache hits and misses using atomic counters."""
    valkey_client.incr(f"cache:metrics:{event_type}")

    # Also track hourly for time-series analysis
    from datetime import datetime
    hour_key = datetime.now().strftime("%Y%m%d%H")
    counter_key = f"cache:metrics:{event_type}:{hour_key}"
    valkey_client.incr(counter_key)
    valkey_client.expire(counter_key, 86400 * 7)  # Keep 7 days

def get_cache_stats(valkey_client) -> dict:
    """Get current cache performance metrics."""
    hits = int(valkey_client.get("cache:metrics:hit") or 0)
    misses = int(valkey_client.get("cache:metrics:miss") or 0)
    total = hits + misses
    hit_rate = hits / total if total > 0 else 0

    avg_cost_per_call = 0.015  # Example: ~$0.015 per LLM call
    savings = hits * avg_cost_per_call

    return {
        "total_requests": total,
        "hits": hits,
        "misses": misses,
        "hit_rate": round(hit_rate, 3),
        "estimated_savings_usd": round(savings, 2),
    }
```

## Administración de la memoria
<a name="semantic-caching-bp-memory"></a>
+ **Establezca una política de memoria máxima**: `maxmemory-policy allkeys-lru` configúrela en su ElastiCache clúster para que desaloje automáticamente las entradas de caché utilizadas menos recientemente cuando el clúster alcance su límite de memoria.
+ **Planifique la capacidad**: cada entrada de caché normalmente requiere entre 4 y 6 KB (dimensiones de incrustación × 4 bytes más texto de consulta \+ texto de respuesta). Una ElastiCache instancia de 1 GB puede almacenar aproximadamente 170 000 entradas en caché.
+ **Utilice la invalidación de la caché para los datos obsoletos**: cuando cambien los datos subyacentes, utilice la búsqueda de texto para buscar e invalidar las entradas de caché relacionadas:

  ```
  def invalidate_by_topic(valkey_client, topic_keyword: str):
      """Remove cached entries matching a topic after a data update."""
      results = valkey_client.execute_command(
          "FT.SEARCH", "semantic_cache",
          f"@query:{topic_keyword}",
          "NOCONTENT",  # Only return keys, not fields
      )
  
      if results[0] > 0:
          keys = results[1:]
          for key in keys:
              valkey_client.delete(key)
          print(f"Invalidated {len(keys)} cached entries for '{topic_keyword}'")
  ```