Кешування LLM-відповідей: Exact та Semantic Cache

LLM-запити дорогі та повільні. Особливо коли 30–40% з них дублюються або семантично схожі. Кешування LLM — найдешевший спосіб знизити обидва показники. Наша компанія має 10+ років досвіду в AI/ML та понад 50 реалізованих проєктів із впровадження exact та semantic кешування LLM під ключ: від простого

Напрямки AI-розробки

Часті запитання

Останні роботи

  • image_website-b2b-advance_0.webp
    Розробка сайту компанії B2B ADVANCE
    1441
  • image_web-applications_feedme_466_0.webp
    Розробка веб-додатків для компанії FEEDME
    1301
  • image_websites_belfingroup_462_0.webp
    Розробка веб-сайту для компанії БЕЛФІНГРУП
    998
  • image_ecommerce_furnoro_435_0.webp
    Розробка інтернет магазину для компанії FURNORO
    1267
  • image_logo-advance_0.webp
    Розробка логотипу компанії B2B Advance
    713
  • image_crm_enviok_479_0.webp
    Розробка веб-додатків для компанії Enviok
    1006

LLM-запити дорогі та повільні. Особливо коли 30–40% з них дублюються або семантично схожі. Кешування LLM — найдешевший спосіб знизити обидва показники. Наша компанія має 10+ років досвіду в AI/ML та понад 50 реалізованих проєктів із впровадження exact та semantic кешування LLM під ключ: від простого exact match до семантичного пошуку за ембеддингами. Exact cache дає hit rate до 35%, Semantic cache — ще 28%, і разом вони закривають 63% запитів без виклику LLM. При типовому навантаженні 5000 запитів/день це значна економія коштів — до $10,000 на місяць на GPT-4o або $15,000 на Claude. Оцінимо ваш проєкт за 1 день — просто зв'яжіться з нами.

Головний біль — кожен повторний запит до GPT-4o або Claude летить в API та оплачується. При типовому навантаженні 5000 запитів/день 30% — дублікати. Exact cache на Redis повертає відповідь за 5–15 мс замість 2–5 секунд — це в 100 разів швидше. Semantic cache додає ще 20–28% збігів за змістом, навіть якщо формулювання інше. Провали контексту при частих однотипних питаннях також усуваються — кеш гарантує стабільну відповідь без галюцинацій. Exact та Semantic cache — два основні види кешування LLM, які ми комбінуємо для максимальної ефективності.

Як влаштований Exact Cache?

Просто: хешуємо промпт (messages, model, temperature) та зберігаємо відповідь у Redis. При повторному запиті з тим же хешем — повертаємо без виклику LLM. Підходить для FAQ, форм, шаблонних запитів. Exact cache обробляє запит у 100 разів швидше, ніж Semantic cache (5–15 мс проти 50–100 мс).

Реалізація Exact Cache
import hashlib import json import redis from typing import Optional from functools import wraps class ExactLLMCache: def __init__(self, redis_url: str = "redis://localhost:6379", ttl: int = 3600): self.redis = redis.from_url(redis_url) self.ttl = ttl def _make_key(self, messages: list[dict], model: str, temperature: float) -> str: """Створює ключ кешу з параметрів запиту""" cache_input = { "messages": messages, "model": model, "temperature": temperature, } content = json.dumps(cache_input, sort_keys=True, ensure_ascii=False) return f"llm:exact:{hashlib.sha256(content.encode()).hexdigest()}" def get(self, messages: list[dict], model: str, temperature: float = 0) -> Optional[str]: key = self._make_key(messages, model, temperature) cached = self.redis.get(key) if cached: return cached.decode() return None def set(self, messages: list[dict], model: str, temperature: float, response: str): key = self._make_key(messages, model, temperature) self.redis.setex(key, self.ttl, response.encode()) def cached_complete(self, complete_fn): """Декоратор для кешування функцій""" @wraps(complete_fn) def wrapper(messages, model="gpt-4o", temperature=0, **kwargs): cached = self.get(messages, model, temperature) if cached: return cached result = complete_fn(messages, model=model, temperature=temperature, **kwargs) self.set(messages, model, temperature, result) return result return wrapper 

Навіщо потрібен Semantic Cache?

Exact кеш ловить лише однакові запити, але користувачі часто переформульовують питання. Semantic Cache вирішує цю проблему: перетворюємо питання на ембеддинг, шукаємо у векторній БД схожі, і при косинусній схожості >0.92 повертаємо відповідь. Ефективно для чатів, де формулювання відрізняються. Семантичний кеш хоч і повільніший за точний (50–100 мс vs 5–15 мс), але краще справляється з варіаціями питань.

Реалізація Semantic Cache
from openai import OpenAI import numpy as np from dataclasses import dataclass @dataclass class CachedEntry: query_embedding: list[float] question: str answer: str model: str created_at: float class SemanticLLMCache: """Кеш на основі векторної схожості питань""" def __init__( self, similarity_threshold: float = 0.92, max_entries: int = 10000, ): self.openai = OpenAI() self.threshold = similarity_threshold self.entries: list[CachedEntry] = [] def _get_embedding(self, text: str) -> list[float]: response = self.openai.embeddings.create( model="text-embedding-3-small", input=text, ) return response.data[0].embedding def _cosine_similarity(self, a: list[float], b: list[float]) -> float: a_arr = np.array(a) b_arr = np.array(b) return np.dot(a_arr, b_arr) / (np.linalg.norm(a_arr) * np.linalg.norm(b_arr)) def get(self, question: str, model: str = None) -> Optional[str]: """Шукає схоже питання в кеші""" if not self.entries: return None query_embedding = self._get_embedding(question) best_similarity = 0 best_answer = None for entry in self.entries: if model and entry.model != model: continue similarity = self._cosine_similarity(query_embedding, entry.query_embedding) if similarity > best_similarity: best_similarity = similarity best_answer = entry.answer if best_similarity >= self.threshold: return best_answer return None def set(self, question: str, answer: str, model: str): """Додає запис до кешу""" import time embedding = self._get_embedding(question) entry = CachedEntry( query_embedding=embedding, question=question, answer=answer, model=model, created_at=time.time(), ) self.entries.append(entry) # Обмежуємо розмір кешу if len(self.entries) > 10000: self.entries = sorted(self.entries, key=lambda e: e.created_at)[-10000:] 

Порівняння Exact та Semantic Cache

Характеристика Exact Cache Semantic Cache
Принцип Хеш промпту Векторна схожість
Сховище Redis ChromaDB / Qdrant
Latency (p95) 5–15 мс 50–100 мс
Hit rate до 35% до 28%
Використання Часто повторювані запити Семантично схожі питання
Складність реалізації Низька Середня

Exact та Semantic cache – два основні види кешування LLM, які ми комбінуємо для досягнення максимального hit rate.

Комбінований кеш: Redis + векторне сховище

У production ми об'єднуємо обидва підходи: спочатку перевіряємо exact cache (Redis), потім semantic (ChromaDB). Це дає мінімальну latency та максимальний hit rate. Така комбінація exact та semantic кешування LLM дозволяє досягти 63% попадань.

Production реалізація
import chromadb import time class ProductionSemanticCache: """Production-ready кеш: Redis для exact, Chroma для semantic""" def __init__(self): self.redis = redis.from_url("redis://localhost:6379") self.chroma = chromadb.HttpClient(host="localhost", port=8000) self.collection = self.chroma.get_or_create_collection("llm_cache") self.openai = OpenAI() self.similarity_threshold = 0.93 self.exact_ttl = 3600 self.semantic_ttl = 86400 # 24 години def get(self, question: str, model: str) -> Optional[dict]: # 1. Exact match спочатку (швидко) exact_key = f"llm:exact:{hashlib.md5(f'{question}:{model}'.encode()).hexdigest()}" exact_hit = self.redis.get(exact_key) if exact_hit: return {"answer": exact_hit.decode(), "cache_type": "exact"} # 2. Semantic match embedding = self.openai.embeddings.create( model="text-embedding-3-small", input=question, ).data[0].embedding results = self.collection.query( query_embeddings=[embedding], n_results=1, where={"model": model}, ) if results["distances"] and results["distances"][0]: distance = results["distances"][0][0] similarity = 1 - distance # Chroma використовує косинусну відстань if similarity >= self.similarity_threshold: answer = results["documents"][0][0] return {"answer": answer, "cache_type": "semantic", "similarity": similarity} return None def set(self, question: str, answer: str, model: str): # Exact cache у Redis exact_key = f"llm:exact:{hashlib.md5(f'{question}:{model}'.encode()).hexdigest()}" self.redis.setex(exact_key, self.exact_ttl, answer.encode()) # Semantic cache у Chroma embedding = self.openai.embeddings.create( model="text-embedding-3-small", input=question, ).data[0].embedding self.collection.add( ids=[f"{int(time.time())}_{hash(question)}"], embeddings=[embedding], documents=[answer], metadatas=[{"model": model, "question": question, "created_at": time.time()}], ) 

Як виміряти ефективність кешу?

Для оцінки впроваджуємо метрики: hit rate, latency p95, cost per request. Типові показники: exact hit 35%, semantic hit 28%, середня latency знижується з 2.3 с до 0.4 с. Для моніторингу використовуємо дашборди з алертами при падінні hit rate нижче порогу. Поріг косинусної схожості 0.92 обраний емпірично — він мінімізує false positives, зберігаючи до 95% релевантних збігів. При порозі 0.95 hit rate падає на 12%, при 0.90 — зростає кількість невірних відповідей.

Кейс нашого клієнта: FAQ-бот на 5000 запитів/день

Ми впровадили для клієнта (сервіс технічної підтримки) комбінований exact та semantic кеш LLM. До впровадження всі запити йшли напряму в GPT-4o. Наша команда (10+ років досвіду, понад 50 проєктів) налаштувала рішення. Результати:

Метрика До кешу Після кешу
Витрати на LLM 100% 37%
Економія $8,000/міс
Середня latency 2.3 сек 0.4 сек
Exact hit rate 0% 35%
Semantic hit rate 0% 28%

Економія 63% (до $8,000 на місяць) — лише за рахунок кешування, без зміни моделі. Отримайте консультацію інженера — розрахуємо потенційну економію для вашого проєкту.

Що входить у нашу роботу

  1. Аналітика — аудит ваших запитів, виявлення патернів, розрахунок потенційного hit rate.
  2. Архітектура — вибір стеку (Redis / Chroma / Qdrant), проектування схеми кешу.
  3. Реалізація — написання production-коду (Python, інтеграція з вашим LLM-провайдером).
  4. Тестування — A/B тест із заміром latency та cost на ваших даних.
  5. Моніторинг — дашборд hit rate, dashboard latency, алерти при падінні ефективності.
  6. Документація та навчання — передача коду, інструкції, навчання команди.

Терміни орієнтовно

• Exact cache (Redis): 0.5–1 день • Semantic cache (Chroma + embeddings): 2–3 дні • Повне production-рішення з моніторингом: 1 тиждень

Гарантуємо стабільну роботу кешу, підтримку після впровадження та прозору звітність. Замовте аудит вашого проєкту — оцінимо hit rate та економію за 1 день.