

Le traduzioni sono generate tramite traduzione automatica. In caso di conflitto tra il contenuto di una traduzione e la versione originale in Inglese, quest'ultima prevarrà.

# Best practice
<a name="semantic-caching-best-practices"></a>

## Scelta dei dati che possono essere memorizzati nella cache
<a name="semantic-caching-bp-choosing-data"></a>

La memorizzazione nella cache semantica è ideale per le interrogazioni ripetute le cui risposte sono relativamente stabili, mentre le risposte in tempo reale o altamente dinamiche sono spesso scarse candidate per la memorizzazione nella cache.

Utilizzate tag e filtri numerici derivati dal contesto applicativo esistente (ad esempio ID prodotto, categoria, regione o segmento di utenti) per decidere quali query e risposte sono idonee per la memorizzazione nella cache e per migliorare la rilevanza degli accessi alla cache.

## Regolazione della soglia di somiglianza
<a name="semantic-caching-bp-threshold"></a>

La soglia di somiglianza controlla il compromesso tra la frequenza di accesso alla cache e la qualità della risposta. Scegliete una soglia che bilanci i risparmi sui costi con la precisione in base al vostro caso d'uso:


| Threshold | Percentuale di successo | Rischio di qualità | Ideale per | 
| --- | --- | --- | --- | 
| 0,95 (rigoroso) | Basso (\~ 25%) | Molto basso | Applicazioni mediche, legali e finanziarie | 
| 0,90 (moderato) | Medio (\~ 55%) | Bassa | Chatbot generici | 
| 0,80 (bilanciato) | Alto (\~ 75%) | Basso—Medio | FAQ, bot, supporto IT | 
| 0,75 (rilassato) | Molto alto (\~ 90%) | Media | High-volume interrogazioni ripetitive | 

**Importante**  
Inizia con una soglia più alta (0,90-0,95) e abbassala gradualmente monitorando la precisione. Usa i A/B test per trovare l'equilibrio ottimale per il tuo carico di lavoro.

## Interrogazioni autonome e conversazioni
<a name="semantic-caching-bp-standalone-vs-conversations"></a>
+ **Per le query autonome**: applica la memorizzazione semantica nella cache direttamente sul testo della query dell'utente.
+ **Per conversazioni a turni multipli**: utilizza innanzitutto la memoria di conversazione per recuperare i fatti chiave e i messaggi recenti necessari per rispondere al turno corrente. Quindi applica la memorizzazione nella cache semantica alla combinazione del messaggio utente corrente e del contesto recuperato, invece di incorporare l'intero dialogo non elaborato.

## Impostazione dei periodi di invalidazione della cache
<a name="semantic-caching-bp-ttl"></a>

Utilizza TTL per controllare per quanto tempo vengono fornite le risposte memorizzate nella cache prima che vengano rigenerate in caso di mancata memorizzazione della cache.


| Tipo di dati | TTL consigliato | Rationale | 
| --- | --- | --- | 
| Fatti statici (documentazione, politiche) | 24 ore | I fatti cambiano raramente | 
| Informazioni sul prodotto | 12-24 ore | Aggiornato quotidianamente nella maggior parte dei cataloghi | 
| Risposte dell'assistente generale | 1—4 ore | Equilibra la freschezza con la percentuale di successo | 
| Real-time dati (prezzi, inventario) | 5—15 minuti | I dati cambiano frequentemente | 
| Contesto della conversazione | 30 minuti | Session-scoped, di breve durata | 

```
# 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)
```

**Suggerimento**  
Imposta TTL che corrispondano al caso d'uso dell'applicazione e alla frequenza con cui cambiano i dati o gli output del modello. I TTL più lunghi aumentano le percentuali di accesso alla cache, ma aumentano il rischio di risposte obsolete. TTL più brevi mantengono le risposte più fresche, ma riducono le percentuali di successo della cache e richiedono una maggiore inferenza LLM.

## Monitoraggio e tracciamento dei costi
<a name="semantic-caching-bp-monitoring"></a>

Tieni traccia delle metriche delle prestazioni della cache per ottimizzare la cache semantica nel tempo:

```
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),
    }
```

## Gestione della memoria
<a name="semantic-caching-bp-memory"></a>
+ **Imposta la policy maxmemory**: configura il ElastiCache cluster `maxmemory-policy allkeys-lru` in modo da eliminare automaticamente le voci di cache utilizzate meno di recente quando il cluster raggiunge il limite di memoria.
+ **Pianifica la capacità**: ogni voce della cache richiede in genere circa 4-6 KB (dimensioni di incorporamento × 4 byte\+testo della interrogazione\+testo della risposta). Un' ElastiCache istanza da 1 GB può memorizzare circa 170.000 voci memorizzate nella cache.
+ **Utilizza l'invalidazione della cache per i dati obsoleti: quando i dati** sottostanti vengono modificati, utilizza la ricerca testuale per trovare e invalidare le voci della cache correlate:

  ```
  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}'")
  ```