

Die vorliegende Übersetzung wurde maschinell erstellt. Im Falle eines Konflikts oder eines Widerspruchs zwischen dieser übersetzten Fassung und der englischen Fassung (einschließlich infolge von Verzögerungen bei der Übersetzung) ist die englische Fassung maßgeblich.

# Multi-turn Zwischenspeichern von Konversationen
<a name="semantic-caching-multi-turn"></a>

Bei Anwendungen mit Multi-Turn-Konversationen kann dieselbe Benutzernachricht je nach Kontext unterschiedliche Bedeutungen haben. Zum Beispiel bedeutet „Erzähl mir mehr“ in einer Konversation über Valkey etwas anderes als „Erzähl mir mehr“ in einer Konversation über Python.

## Die Herausforderung
<a name="semantic-caching-multi-turn-challenge"></a>

Single-prompt Caching funktioniert gut für statuslose Abfragen. Bei Multi-Turn-Konversationen müssen Sie den gesamten Konversationskontext zwischenspeichern, nicht nur die letzte Nachricht:

```
# "Tell me more" means nothing without context
# Conversation A: "What is Valkey?" -> "Tell me more"  (about Valkey)
# Conversation B: "What is Python?" -> "Tell me more"  (about Python)
```

## Strategie: kontextsensitive Cache-Schlüssel
<a name="semantic-caching-context-aware-keys"></a>

Anstatt nur die letzte Benutzernachricht einzubetten, betten Sie eine Zusammenfassung des vollständigen Konversationskontextes ein. Auf diese Weise können ähnliche Folgefragen in ähnlichen Konversationsabläufen zwischengespeicherte Antworten wiederverwendet werden.

```
def build_context_string(messages: list) -> str:
    """Build a cacheable context string from conversation messages."""
    # Use last 3 turns (6 messages: user + assistant pairs)
    recent = messages[-6:]
    parts = []
    for msg in recent:
        role = msg["role"]
        content = msg["content"][:200]  # Truncate long messages
        parts.append(f"{role}: {content}")
    return " | ".join(parts)
```

## Per-user Cache-Isolierung mit TAG-Filtern
<a name="semantic-caching-tag-filters"></a>

Verwenden Sie TAG-Felder, um zwischengespeicherte Konversationen nach Benutzer, Sitzung oder anderen Dimensionen zu isolieren. Dadurch wird verhindert, dass die zwischengespeicherten Konversationen eines Benutzers für einen anderen Benutzer zurückgegeben werden:

```
# Create index with TAG field for per-user isolation
valkey_client.execute_command(
    "FT.CREATE", "conv_cache_idx",
    "SCHEMA",
    "context_summary", "TEXT",
    "response", "TEXT",
    "user_id", "TAG",
    "turn_count", "NUMERIC",
    "embedding", "VECTOR", "HNSW", "6",
    "TYPE", "FLOAT32",
    "DIM", "1024",
    "DISTANCE_METRIC", "COSINE",
)
```

Suche mit Hybridfilterung (TAG \+ KNN):

```
def lookup_conversation_cache(messages: list, user_id: str, threshold: float = 0.12):
    """Search cache for similar conversation contexts, scoped to a user.

    Note: FT.SEARCH with COSINE distance returns a distance score where
    0 = identical and 2 = opposite. A lower score means higher similarity.
    The threshold here is a maximum distance: only return results closer
    than this value.
    """
    context = build_context_string(messages)
    query_vec = get_embedding(context)

    # Hybrid search: filter by user_id TAG + KNN on context embedding
    results = valkey_client.execute_command(
        "FT.SEARCH", "conv_cache_idx",
        f"@user_id:{{{user_id}}}=>[KNN 1 @embedding $query_vec]",
        "PARAMS", "2", "query_vec", query_vec,
        "DIALECT", "2",
    )

    if results[0] > 0:
        fields = results[2]
        field_dict = {fields[j]: fields[j+1] for j in range(0, len(fields), 2)}
        distance = float(field_dict.get("__embedding_score", "999"))
        if distance < threshold:  # Lower distance = more similar
            return {"hit": True, "response": field_dict.get("response", ""), "distance": distance}

    return {"hit": False}
```

**Anmerkung**  
Der `@user_id:{user_123}` TAG-Filter stellt sicher, dass die zwischengespeicherten Konversationen von Benutzer A nicht an Benutzer B weitergegeben werden. Die hybride Abfrage (TAG \+ KNN) wird als einziger atomarer Vorgang ausgeführt — zunächst wird nach Benutzer gefiltert und dann der nächstgelegene Konversationskontext gefunden.

## Strategien zur Cache-Isolierung
<a name="semantic-caching-isolation-strategies"></a>


| Strategie | TAG-Filter | Am besten geeignet für | 
| --- | --- | --- | 
| Per-user | @user\_id:{user\_123} | Personalisierte Assistenten | 
| Per-session | @session\_id:{sess\_abc} | Short-lived Chats | 
| Global (gemeinsam genutzt) | Kein Filter (\*) | Häufig gestellte Fragen, Bots, häufig gestellte Fragen | 
| Per-model | @model:{gpt-4} | Multi-model Bereitstellungen | 
| Per-product | @product\_id:{prod\_456} | E-commerce Assistenten | 