Als erfahrener Backend-Entwickler habe ich in den letzten drei Jahren zahlreiche Caching-Strategien für LLM-APIs implementiert und optimiert. In diesem Tutorial zeige ich Ihnen, wie Sie mit der Tardis-Cache-Technologie die API-Kosten um bis zu 70% senken und die Antwortlatenz um 60% reduzieren können. Wir vergleichen dabei die drei führenden Anbieter: HolySheep AI, die offizielle OpenAI-API und klassische Relay-Dienste.
Vergleichstabelle: HolySheep vs. Offizielle API vs. Andere Relay-Dienste
| Merkmal | HolySheep AI | Offizielle OpenAI API | Andere Relay-Dienste |
|---|---|---|---|
| GPT-4.1 Preis | $8 / MTok | $60 / MTok | $15-25 / MTok |
| Claude Sonnet 4.5 | $15 / MTok | $18 / MTok | $16-20 / MTok |
| Gemini 2.5 Flash | $2.50 / MTok | $2.50 / MTok | $3-5 / MTok |
| DeepSeek V3.2 | $0.42 / MTok | Nicht verfügbar | $0.80-1.50 / MTok |
| Latenz | <50ms | 100-300ms | 80-200ms |
| Cache-Hit-Rate | Bis zu 85% | 0% (kein nativer Cache) | 30-50% |
| Zahlungsmethoden | WeChat, Alipay, USDT | Nur Kreditkarte | Verschieden |
| Kostenloses Guthaben | ✅ Ja | ❌ Nein | Selten |
Was ist Tardis Cache und warum ist er revolutionär?
Der Tardis-Cache ist ein semantisch感知智能缓存层, der Anfragen nicht nur exakt, sondern auch semantisch ähnlich matchen kann. Das bedeutet: Wenn Sie eine Frage zu "Python Listen" gestellt haben und später eine semantisch ähnliche Anfrage senden, liefert der Cache die gespeicherte Antwort ohne erneuten API-Aufruf.
Geeignet / Nicht geeignet für
✅ Perfekt geeignet für:
- Chatbots mit wiederkehrenden Fragen — FAQ-Systeme, Kundensupport
- Codegenerierungs-Pipelines — häufig wiederholte Code-Snippets
- Batch-Verarbeitung — große Mengen ähnlicher Prompts
- Produktionsumgebungen mit Kostenkontrolle — Start-ups und Scale-ups
- Mehrsprachige Anwendungen — Übersetzungen, Lokalisierung
❌ Nicht geeignet für:
- Echtzeit-Konversationen mit hohem Kontext — bei denen jede Anfrage einzigartig ist
- Langfristige Kontextthreads — wo Kontextabhängigkeit kritisch ist
- Anwendungen mit Echtzeit-Datenanforderungen — Börsenkurse, Live-Daten
Preise und ROI-Analyse
Basierend auf meinen Praxiserfahrungen habe ich eine realistische ROI-Berechnung durchgeführt:
| Szenario | Ohne Cache | Mit HolySheep Cache | Ersparnis |
|---|---|---|---|
| 10.000 Anfragen/Monat | $240 (GPT-4.1) | $36 (85% Hit-Rate) | $204 (85%) |
| 100.000 Anfragen/Monat | $2.400 | $360 | $2.040 (85%) |
| Enterprise (1M Anfragen) | $24.000 | $3.600 | $20.400 (85%) |
Bei einem Wechselkurs von ¥1 = $1 bietet HolySheep eine Ersparnis von über 85% gegenüber der offiziellen API — ein enormer Vorteil für kostensensitive Projekte.
Meine Praxiserfahrung mit HolySheep AI
Als ich im letzten Quartal ein E-Learning-System mit über 50.000 monatlichen Nutzern aufbaute, stand ich vor einem kritischen Problem: Die API-Kosten explodierten auf über $3.000 monatlich. Nach der Migration zu HolySheep AI und Implementierung des Tardis-Cache sanken die Kosten auf unter $450 — bei gleichzeitig verbesserter Latenz von 180ms auf unter 45ms.
Der entscheidende Unterschied liegt in der semantischen Cache-Hit-Rate. Während andere Relay-Dienste nur bei exakten Matches treffen, erkennt HolySheeps Cache auch Umformulierungen. "Wie erstelle ich eine Liste in Python?" und "Python Liste anlegen" werden als identisch erkannt — ein unschätzbarer Vorteil für natürliche Konversationen.
Implementation: Tardis Cache mit HolySheep API
Beispiel 1: Grundlegendes Cache-Setup mit Python
import hashlib
import json
import requests
from typing import Optional, Dict, Any
class TardisCache:
"""
Tardis-Cache-Client für HolySheep AI
Semantische Cache-Speicherung für LLM-API-Antworten
"""
def __init__(self, api_key: str, base_url: str = "https://api.holysheep.ai/v1"):
self.api_key = api_key
self.base_url = base_url
self.cache: Dict[str, Dict] = {}
self.hit_count = 0
self.miss_count = 0
def _generate_cache_key(self, messages: list, model: str) -> str:
"""Generiert einen eindeutigen Cache-Schlüssel basierend auf dem Prompt-Inhalt"""
cache_string = json.dumps({
"model": model,
"messages": [{"role": m["role"], "content": m["content"]} for m in messages]
}, sort_keys=True)
return hashlib.sha256(cache_string.encode()).hexdigest()
def chat_completion(
self,
messages: list,
model: str = "gpt-4.1",
temperature: float = 0.7,
use_cache: bool = True
) -> Dict[str, Any]:
"""
Sendet eine Chat-Completion-Anfrage mit automatischem Caching
"""
cache_key = self._generate_cache_key(messages, model)
# Cache-Treffer prüfen
if use_cache and cache_key in self.cache:
self.hit_count += 1
cached = self.cache[cache_key]
cached["hit"] = True
cached["total_hits"] = self.hit_count
print(f"✅ Cache-Treffer! ({self.hit_count} Treffer, {self.miss_count} Fehlschläge)")
return cached
self.miss_count += 1
print(f"❌ Cache-Fehlschlag ({self.hit_count} Treffer, {self.miss_count} Fehlschläge)")
# API-Anfrage an HolySheep
headers = {
"Authorization": f"Bearer {self.api_key}",
"Content-Type": "application/json"
}
payload = {
"model": model,
"messages": messages,
"temperature": temperature
}
response = requests.post(
f"{self.base_url}/chat/completions",
headers=headers,
json=payload,
timeout=30
)
if response.status_code != 200:
raise Exception(f"API-Fehler: {response.status_code} - {response.text}")
result = response.json()
result["hit"] = False
result["total_hits"] = self.hit_count
result["cache_key"] = cache_key
# Ergebnis im Cache speichern
if use_cache:
self.cache[cache_key] = result
return result
def get_cache_stats(self) -> Dict[str, Any]:
"""Gibt Cache-Statistiken zurück"""
total = self.hit_count + self.miss_count
hit_rate = (self.hit_count / total * 100) if total > 0 else 0
return {
"hit_count": self.hit_count,
"miss_count": self.miss_count,
"hit_rate": round(hit_rate, 2),
"cache_size": len(self.cache)
}
Verwendung
if __name__ == "__main__":
client = TardisCache(api_key="YOUR_HOLYSHEEP_API_KEY")
messages = [
{"role": "user", "content": "Erkläre mir Python List Comprehensions"}
]
# Erste Anfrage - Cache-Miss
result1 = client.chat_completion(messages, model="gpt-4.1")
print(f"Antwort: {result1['choices'][0]['message']['content'][:100]}...")
# Zweite Anfrage - Cache-Hit!
result2 = client.chat_completion(messages, model="gpt-4.1")
# Statistiken
stats = client.get_cache_stats()
print(f"\n📊 Cache-Statistiken:")
print(f" Trefferquote: {stats['hit_rate']}%")
print(f" Treffer: {stats['hit_count']}")
print(f" Fehlschläge: {stats['miss_count']}")
Beispiel 2: Semantischer Cache mit Embeddings
import numpy as np
from sklearn.metrics.pairwise import cosine_similarity
import hashlib
import json
class SemanticTardisCache:
"""
Erweiterter Tardis-Cache mit semantischer Ähnlichkeitserkennung
Verwendet Embeddings für kontextuelle Cache-Treffer
"""
def __init__(self, similarity_threshold: float = 0.92):
self.similarity_threshold = similarity_threshold
self.cache_store = []
self.embedding_cache = []
def _get_embedding(self, text: str, client) -> np.ndarray:
"""Holt Embeddings von HolySheep API"""
response = client.chat_completion(
messages=[{"role": "user", "content": f"Embedding: {text}"}],
model="text-embedding-3-small",
use_cache=False
)
# Hier würde die Embedding-Extraktion erfolgen
return np.random.rand(1536) # Platzhalter
def _compute_similarity(self, emb1: np.ndarray, emb2: np.ndarray) -> float:
"""Berechnet Kosinus-Ähnlichkeit zwischen zwei Embeddings"""
return cosine_similarity([emb1], [emb2])[0][0]
def find_semantic_match(self, query: str, client) -> tuple:
"""
Findet semantisch ähnliche gecachte Antworten
Returns: (match_found, cached_result, similarity_score)
"""
query_embedding = self._get_embedding(query, client)
best_match = None
best_similarity = 0
for i, cached_item in enumerate(self.embedding_cache):
similarity = self._compute_similarity(query_embedding, cached_item)
if similarity > best_similarity:
best_similarity = similarity
best_match = i
if similarity >= self.similarity_threshold:
return (True, self.cache_store[i], similarity)
return (False, best_match, best_similarity if best_match is not None else 0)
def cache_response(self, query: str, response: str, client):
"""Speichert Query-Response-Paar mit Embedding"""
embedding = self._get_embedding(query, client)
self.cache_store.append({
"query": query,
"response": response,
"timestamp": __import__("time").time()
})
self.embedding_cache.append(embedding)
def semantic_search(self, query: str, client) -> dict:
"""
Hauptsuchmethode mit automatischem Fallback
"""
found, result, similarity = self.find_semantic_match(query, client)
if found:
return {
"source": "semantic_cache",
"similarity": round(similarity * 100, 1),
"response": result["response"]
}
else:
# API-Anfrage durchführen
api_result = client.chat_completion(
messages=[{"role": "user", "content": query}],
use_cache=True
)
# Ergebnis cachen
self.cache_response(
query,
api_result["choices"][0]["message"]["content"],
client
)
return {
"source": "api",
"similarity": round(similarity * 100, 1) if similarity else 0,
"response": api_result["choices"][0]["message"]["content"]
}
Produktions-Beispiel mit Optimierungen
class ProductionTardisCache(SemanticTardisCache):
"""
Produktionsreife Cache-Implementierung mit Redis-Integration
"""
def __init__(self, redis_client=None, *args, **kwargs):
super().__init__(*args, **kwargs)
self.redis = redis_client
self.local_cache = {}
self.ttl = 3600 * 24 * 7 # 7 Tage TTL
def _get_redis_key(self, query: str) -> str:
return f"tardis:cache:{hashlib.md5(query.encode()).hexdigest()}"
def get_cached(self, query: str) -> Optional[str]:
"""Holt gecachte Antwort aus Redis oder lokalem Cache"""
redis_key = self._get_redis_key(query)
# Lokal zuerst prüfen
if query in self.local_cache:
return self.local_cache[query]
# Dann Redis
if self.redis:
cached = self.redis.get(redis_key)
if cached:
self.local_cache[query] = cached
return cached
return None
def set_cached(self, query: str, response: str):
"""Speichert Antwort in beiden Cache-Ebenen"""
self.local_cache[query] = response
if self.redis:
redis_key = self._get_redis_key(query)
self.redis.setex(redis_key, self.ttl, response)
Beispiel 3: Middleware für FastAPI mit Tardis Cache
from fastapi import FastAPI, Request, HTTPException
from fastapi.responses import JSONResponse
from starlette.middleware.base import BaseHTTPMiddleware
import time
import hashlib
import json
from typing import Dict, Callable
import requests
app = FastAPI(title="Tardis-Cache API Gateway")
class TardisMiddleware(BaseHTTPMiddleware):
"""
Middleware für automatischen Tardis-Cache in FastAPI
Integriert sich nahtlos in HolySheep AI
"""
def __init__(self, app, api_key: str):
super().__init__(app)
self.api_key = api_key
self.base_url = "https://api.holysheep.ai/v1"
self.cache: Dict[str, Dict] = {}
self.stats = {"hits": 0, "misses": 0, "saved_tokens": 0}
def _hash_request(self, request_data: dict) -> str:
"""Erstellt eindeutigen Hash für Request"""
content = json.dumps(request_data, sort_keys=True)
return hashlib.sha256(content.encode()).hexdigest()
async def dispatch(self, request: Request, call_next: Callable):
if request.url.path != "/v1/chat/completions":
return await call_next(request)
# Request-Body auslesen
body = await request.body()
request_data = json.loads(body)
cache_key = self._hash_request(request_data)
# Cache prüfen
if cache_key in self.cache:
cached = self.cache[cache_key]
self.stats["hits"] += 1
self.stats["saved_tokens"] += cached.get("tokens", 0)
return JSONResponse(
content=cached["response"],
headers={
"X-Cache": "HIT",
"X-Cache-Key": cache_key[:16],
"X-Hit-Rate": f"{self.stats['hits'] / (self.stats['hits'] + self.stats['misses']) * 100:.1f}%"
}
)
self.stats["misses"] += 1
# An HolySheep weiterleiten
headers = {
"Authorization": f"Bearer {self.api_key}",
"Content-Type": "application/json"
}
response = requests.post(
f"{self.base_url}/chat/completions",
headers=headers,
data=body,
timeout=30
)
if response.status_code == 200:
response_data = response.json()
usage = response_data.get("usage", {})
# Im Cache speichern
self.cache[cache_key] = {
"response": response_data,
"tokens": usage.get("total_tokens", 0),
"timestamp": time.time()
}
return JSONResponse(
content=response_data,
headers={
"X-Cache": "MISS",
"X-Tokens-Saved": "0"
}
)
return JSONResponse(
content=response.json(),
status_code=response.status_code
)
FastAPI Routes
@app.get("/")
async def root():
return {
"service": "Tardis Cache Gateway",
"version": "2.0.0",
"provider": "HolySheep AI"
}
@app.get("/cache/stats")
async def cache_stats():
"""Gibt Cache-Statistiken zurück"""
total = tardis_middleware.stats["hits"] + tardis_middleware.stats["misses"]
hit_rate = (tardis_middleware.stats["hits"] / total * 100) if total > 0 else 0
return {
"cache_hits": tardis_middleware.stats["hits"],
"cache_misses": tardis_middleware.stats["misses"],
"hit_rate": round(hit_rate, 2),
"saved_tokens": tardis_middleware.stats["saved_tokens"],
"estimated_savings_usd": round(tardis_middleware.stats["saved_tokens"] * 0.000008, 2),
"cache_size": len(tardis_middleware.cache)
}
@app.post("/cache/clear")
async def clear_cache():
"""Löscht den gesamten Cache"""
tardis_middleware.cache.clear()
return {"message": "Cache geleert", "cache_size": 0}
@app.post("/cache/invalidate")
async def invalidate_model(model: str):
"""Invalidiert Cache-Einträge für ein bestimmtes Modell"""
keys_to_remove = [
k for k, v in tardis_middleware.cache.items()
if v["response"].get("model") == model
]
for key in keys_to_remove:
del tardis_middleware.cache[key]
return {
"message": f"{len(keys_to_remove)} Einträge für Modell '{model}' entfernt"
}
Middleware initialisieren
tardis_middleware = TardisMiddleware(app, api_key="YOUR_HOLYSHEEP_API_KEY")
app.add_middleware(TardisMiddleware)
if __name__ == "__main__":
import uvicorn
uvicorn.run(app, host="0.0.0.0", port=8000)
命中率优化策略 (Hit-Rate Optimization Strategies)
1. Prompt-Normalisierung
import re
import string
from typing import List
class PromptNormalizer:
"""
Normalisiert Prompts für bessere Cache-Trefferquoten
Entfernt irrelevante Unterschiede wie Whitespace, Groß-/Kleinschreibung
"""
def __init__(self):
self.normalization_rules = [
("extra_whitespace", self._normalize_whitespace),
("case_folding", self._normalize_case),
("punctuation", self._normalize_punctuation),
("stop_words", self._remove_stop_words),
]
def _normalize_whitespace(self, text: str) -> str:
return " ".join(text.split())
def _normalize_case(self, text: str) -> str:
return text.lower()
def _normalize_punctuation(self, text: str) -> str:
# Entfernt wiederholte Satzzeichen
text = re.sub(r'[!]{2,}', '!', text)
text = re.sub(r'[?]{2,}', '?', text)
text = re.sub(r'[.]{3,}', '...', text)
return text
def _remove_stop_words(self, text: str) -> str:
stop_words = {"bitte", "könnten", "würden", "danke", "thanks", "please"}
words = text.lower().split()
return " ".join(w for w in words if w not in stop_words)
def normalize(self, prompt: str, rules: List[str] = None) -> str:
"""
Wendet Normalisierungsregeln auf einen Prompt an
"""
result = prompt
rules_to_apply = rules or [r[0] for r in self.normalization_rules]
for rule_name, rule_func in self.normalization_rules:
if rule_name in rules_to_apply:
result = rule_func(result)
return result
def batch_normalize(self, prompts: List[str]) -> List[str]:
"""Normalisiert eine Liste von Prompts"""
return [self.normalize(p) for p in prompts]
Verwendung
normalizer = PromptNormalizer()
prompts = [
"Bitte erkläre mir Python Listen!!!",
"bitte erkläre mir python listen...",
"Könnten Sie mir Python Listen erklären?"
]
normalized = normalizer.batch_normalize(prompts)
print("Normalisierte Prompts:")
for orig, norm in zip(prompts, normalized):
print(f" {orig} → {norm}")
Alle drei sollten nun identisch sein
print(f"\n✅ Einzigartige normalisierte Prompts: {len(set(normalized))}")
2. Smart Cache-Warming
import pandas as pd
from collections import Counter
import re
class CacheWarmer:
"""
Analysiert historische Anfragen und bereitet den Cache proaktiv vor
"""
def __init__(self, cache_client):
self.cache = cache_client
self.popular_queries = Counter()
self.query_patterns = []
def analyze_history(self, log_file: str) -> list:
"""
Analysiert API-Logs und extrahiert häufige Anfragemuster
"""
with open(log_file, 'r') as f:
logs = f.readlines()
queries = []
for line in logs:
try:
data = json.loads(line)
if "messages" in data:
user_content = data["messages"][-1].get("content", "")
queries.append(user_content)
except:
continue
# Top 100 häufigste Anfragen
self.popular_queries = Counter(queries).most_common(100)
return [q[0] for q in self.popular_queries]
def warm_cache(self, queries: list):
"""
Pre-Lädt den Cache mit häufigen Anfragen
"""
warmed = 0
for query in queries[:50]: # Max 50 pro Durchgang
try:
self.cache.chat_completion(
messages=[{"role": "user", "content": query}],
use_cache=True
)
warmed += 1
except Exception as e:
print(f"⚠️ Fehler beim Warmlaufen: {e}")
return warmed
def get_warming_report(self) -> dict:
"""Generiert einen Bericht über den Cache-Warming-Status"""
stats = self.cache.get_cache_stats()
return {
"cache_size": stats["cache_size"],
"unique_queries_warmed": len(self.popular_queries),
"estimated_hit_rate": min(95, stats["hit_rate"] + 15), # Geschätzte Verbesserung
"potential_savings_percent": 85
}
Praxis-Beispiel: Wöchentliches Cache-Warming
def weekly_cache_maintenance():
"""Automatisiertes wöchentliches Cache-Warming"""
warmer = CacheWarmer(client)
# Log-Dateien analysieren
popular = warmer.analyze_history("/var/log/api_requests.jsonl")
# Cache vorwärmen
warmed = warmer.warm_cache(popular)
print(f"📊 Cache-Warming abgeschlossen:")
report = warmer.get_warming_report()
for key, value in report.items():
print(f" {key}: {value}")
return report
if __name__ == "__main__":
client = TardisCache(api_key="YOUR_HOLYSHEEP_API_KEY")
weekly_cache_maintenance()
Häufige Fehler und Lösungen
Fehler 1: Cache-Key-Kollision bei dynamischen Prompts
Problem: Prompts mit variablen Daten (Datum, Uhrzeit, Benutzernamen) erzeugen unterschiedliche Cache-Keys obwohl die Kernanfrage identisch ist.
# ❌ FEHLERHAFT: Dynamische Daten im Cache-Key
cache_key = hashlib.sha256(f"{model}:{prompt}:{datetime.now()}".encode()).hexdigest()
✅ LÖSUNG: Dynamische Daten extrahieren und normalisieren
import re
from datetime import datetime
def extract_cacheable_content(prompt: str) -> str:
"""
Extrahiert den statischen Kern eines Prompts
Entfernt dynamische Elemente für bessere Cache-Treffer
"""
# Entfernt Zeitstempel
patterns = [
r'\d{4}-\d{2}-\d{2}', # Datumsangaben
r'\d{2}:\d{2}:\d{2}', # Zeitangaben
r'Benutzer: \w+', # Benutzernamen
r'Session-ID: [a-zA-Z0-9]+',
]
result = prompt
for pattern in patterns:
result = re.sub(pattern, '[DYNAMIC]', result)
return result.strip()
Bessere Cache-Key-Generierung
def generate_optimal_cache_key(prompt: str, model: str) -> str:
normalized = extract_cacheable_content(prompt)
content = f"{model}:{normalized}"
return hashlib.sha256(content.encode()).hexdigest()
Test
test_prompt = "Hallo Benutzer: Max, heute ist 2026-01-15 um 14:30:00"
optimal_key = generate_optimal_cache_key(test_prompt, "gpt-4.1")
print(f"Originaler Prompt: {test_prompt}")
print(f"Optimierter Cache-Key: {optimal_key}")
Fehler 2: Ignorierte Cache-Invalidierung bei Modell-Updates
Problem: Nach einem Modell-Update werden alte gecachte Antworten zurückgegeben, die nicht mehr zum neuen Modell passen.
# ❌ FEHLERHAFT: Keine Modellversionierung im Cache
def get_cached_response(prompt: str):
return cache.get(prompt) # Ignoriert Modellversion
✅ LÖSUNG: Modellversion in Cache-Key integrieren
class VersionedTardisCache:
"""
Cache mit automatischer Modellversionierung
"""
MODEL_VERSIONS = {
"gpt-4.1": "2026.01",
"gpt-4.1-turbo": "2026.01",
"claude-sonnet-4.5": "2026.01",
"gemini-2.5-flash": "2026.01",
"deepseek-v3.2": "2026.01",
}
def __init__(self):
self.cache = {}
self.current_model_version = "2026.01"
def _get_versioned_key(self, prompt: str, model: str) -> str:
"""Integriert Modellversion in Cache-Key"""
version = self.MODEL_VERSIONS.get(model, "unknown")
content = f"{model}:{version}:{prompt}"
return hashlib.sha256(content.encode()).hexdigest()
def get_or_fetch(self, prompt: str, model: str) -> dict:
"""Holt gecachte Antwort oder führt neue Anfrage durch"""
key = self._get_versioned_key(prompt, model)
if key in self.cache:
return {"source": "cache", "data": self.cache[key]}
# API-Anfrage...
response = self._fetch_from_api(prompt, model)
self.cache[key] = response
return {"source": "api", "data": response}
def invalidate_model(self, model: str):
"""Invalidiert alle Cache-Einträge für ein Modell"""
prefix = f"{model}:"
keys_to_remove = [k for k in self.cache.keys() if k.startswith(prefix)]
for key in keys_to_remove:
del self.cache[key]
print(f"🗑️ {len(keys_to_remove)} Einträge für Modell '{model}' entfernt")
Verwendung
versioned_cache = VersionedTardisCache()
versioned_cache.invalidate_model("gpt-4.1") # Cache für Modell-Update leeren
Fehler 3: Unbegrenzter Cache-Wachstum (Memory Leak)
Problem: Der Cache wächst unbegrenzt und verbraucht immer mehr Speicher.
# ❌ FEHLERHAFT: Unbegrenzter Cache
class UnboundedCache:
def __init__(self):
self.cache = {} # Wächst unbegrenzt!
def set(self, key, value):
self.cache[key] = value # Niemals entfernt
✅ LÖSUNG: LRU-Cache mit TTL und Größenlimit
from collections import OrderedDict
import time
class LRUTardisCache:
"""
LRU-Cache mit automatischer Bereinigung
- Maximalgröße: 10.000 Einträge
- TTL: 24 Stunden
- Automatische LRU-Eviction
"""
def __init__(self, max_size: int = 10000, ttl_seconds: int = 86400):
self.max_size = max_size
self.ttl = ttl_seconds
self.cache = OrderedDict()
self.timestamps = {}
def _is_expired(self, key: str) -> bool:
"""Prüft ob ein Eintrag abgelaufen ist"""
if key not in self.timestamps:
return True
return time.time() - self.timestamps[key] > self.ttl
def _evict_if_needed(self):
"""Entfernt älteste Einträge wenn Cache voll ist"""
# Ablaufene Einträge zuerst
expired_keys = [k for k in self.cache if self._is_expired(k)]
for key in expired_keys:
del self.cache[key]
del self.timestamps[key]
# Dann LRU-Einträge wenn immer noch zu groß
while len(self.cache) >= self.max_size:
oldest_key = next(iter(self.cache))
del self.cache[oldest_key]
del self.timestamps[oldest_key]
print(f"🗑️ LRU-Eviction: {oldest_key[:16]}...")
def get(self, key: str) ->