llm-caching – skill Agent & Tự động hóa cho agent AI
Triển khai bộ nhớ đệm LLM đa tầng với khớp chính xác, tương đồng ngữ nghĩa và prompt caching phía nhà cung cấp.
Cài skill llm-caching bằng một lệnh
Chọn công cụ bạn đang dùng, copy lệnh và dán vào terminal. Skill sẽ nằm trong thư mục skills của công cụ đó và sẵn sàng dùng ở phiên làm việc tiếp theo.
Claude Code
mkdir -p ~/.claude/skills && curl -fsSL https://skill.dn1nguoi.com/z/llm-caching-66cf8.tgz | tar xz -C ~/.claude/skills
Gọi trong Claude Code: /llm-caching – rồi mô tả công việc bạn muốn làm.
Codex
mkdir -p ~/.codex/skills && curl -fsSL https://skill.dn1nguoi.com/z/llm-caching-66cf8.tgz | tar xz -C ~/.codex/skills
Gọi trong Codex: $llm-caching – rồi mô tả công việc bạn muốn làm.
Hermes Agent
mkdir -p ~/.hermes/skills && curl -fsSL https://skill.dn1nguoi.com/z/llm-caching-66cf8.tgz | tar xz -C ~/.hermes/skills
Gọi trong Hermes Agent: /llm-caching – rồi mô tả công việc bạn muốn làm.
DeepSeek
mkdir -p ~/.deepcode/skills && curl -fsSL https://skill.dn1nguoi.com/z/llm-caching-66cf8.tgz | tar xz -C ~/.deepcode/skills
Gọi trong DeepSeek: /llm-caching – rồi mô tả công việc bạn muốn làm.
Nội dung SKILL.md
Nội dung SKILL.md gốc bằng tiếng Anh.
LLM Caching
Cut LLM costs and latency with exact match, semantic, and provider-side caching layers.
When to Use This Skill
Use this skill when:
- The same or similar queries are asked repeatedly (FAQ bots, support tools)
- LLM API costs are growing and you need immediate savings
- Serving high request volumes where repeated queries cause bottlenecks
- Implementing prompt caching for long system prompts (Anthropic/OpenAI)
- Building offline-capable AI features that need response persistence
Caching Layers
Cache examples are incomplete until authorization/data boundaries are included. Partition by tenant/user access scope and include model revision, system/developer prompts, conversation/tool context, parameters, locale and source/policy version in keys or eligibility filters. Never serve a privileged cached answer across users merely because queries are similar. Hashing prompts is not encryption: restrict/encrypt stored queries/results, honor deletion/retention and invalidate when permissions/data change. Avoid semantic reuse for sensitive or time-dependent answers unless evaluated false-hit risk is acceptable. Similarity thresholds/latencies/savings are examples, not calibrated guarantees. Cache warming is paid generation: bound concurrency, requests and budget before running.
Request → Exact Cache → Semantic Cache → Provider Cache → LLM API
↓ hit ↓ hit ↓ hit
instant ~5ms 50-80% cheaperLayer 1: Exact Match Cache (Redis)
import hashlib
import json
import redis
from openai import OpenAI
r = redis.Redis(host="localhost", port=6379, decode_responses=True)
client = OpenAI()
def build_cache_key(model: str, messages: list, temperature: float) -> str:
"""Deterministic key from request parameters."""
payload = json.dumps({
"model": model,
"messages": messages,
"temperature": temperature,
}, sort_keys=True)
return f"llm:exact:{hashlib.sha256(payload.encode()).hexdigest()}"
def cached_completion(model: str, messages: list, temperature: float = 0.0,
ttl: int = 3600) -> dict:
key = build_cache_key(model, messages, temperature)
# Check cache
if cached := r.get(key):
return json.loads(cached)
# Call API
response = client.chat.completions.create(
model=model, messages=messages, temperature=temperature
)
result = response.model_dump()
# Cache only eligible responses; temperature 0 does not guarantee determinism.
if temperature == 0.0:
r.setex(key, ttl, json.dumps(result))
return resultLayer 2: Semantic Cache (GPTCache)
from gptcache import cache, Config
from gptcache.adapter import openai
from gptcache.embedding import Onnx
from gptcache.manager import CacheBase, VectorBase, get_data_manager
from gptcache.similarity_evaluation.distance import SearchDistanceEvaluation
# Configure GPTCache with Qdrant backend
def init_gptcache(cache_obj, llm: str):
onnx = Onnx() # local embedding model
data_manager = get_data_manager(
CacheBase("redis"), # metadata store
VectorBase("qdrant",
host="localhost",
port=6333,
collection_name=f"llm-cache-{llm}",
dimension=onnx.dimension),
)
cache_obj.init(
embedding_func=onnx.to_embeddings,
data_manager=data_manager,
similarity_evaluation=SearchDistanceEvaluation(),
config=Config(similarity_threshold=0.80), # 80% similarity = cache hit
)
cache.set_openai_key()
init_gptcache(cache, "gpt-4o-mini")
# Now openai calls are automatically cached
response = openai.ChatCompletion.create(
model="gpt-4o-mini",
messages=[{"role": "user", "content": "What is machine learning?"}],
)
# Second call with similar question ("Explain machine learning") → cache hitCustom Semantic Cache (Illustrative)
from sentence_transformers import SentenceTransformer
from qdrant_client import QdrantClient
from qdrant_client.models import Distance, VectorParams, PointStruct, Filter, FieldCondition, Range
import numpy as np
import uuid
import time
embed_model = SentenceTransformer("BAAI/bge-small-en-v1.5") # fast, 33M params
qdrant = QdrantClient("http://localhost:6333")
CACHE_COLLECTION = "semantic-cache"
SIMILARITY_THRESHOLD = 0.88
CACHE_TTL_SECONDS = 86400 # 24h
# Create collection once
qdrant.create_collection(
collection_name=CACHE_COLLECTION,
vectors_config=VectorParams(size=384, distance=Distance.COSINE),
on_disk_payload=True,
)
def semantic_cache_lookup(query: str, model: str) -> str | None:
embedding = embed_model.encode(query).tolist()
results = qdrant.query_points(
collection_name=CACHE_COLLECTION,
query=embedding,
query_filter=Filter(must=[
FieldCondition(key="model", match={"value": model}),
FieldCondition(key="expires_at", range=Range(gte=time.time())),
]),
limit=1,
score_threshold=SIMILARITY_THRESHOLD,
)
if results.points:
return results.points[0].payload["response"]
return None
def semantic_cache_store(query: str, response: str, model: str):
embedding = embed_model.encode(query).tolist()
qdrant.upsert(
collection_name=CACHE_COLLECTION,
points=[PointStruct(
id=str(uuid.uuid4()),
vector=embedding,
payload={
"query": query,
"response": response,
"model": model,
"created_at": time.time(),
"expires_at": time.time() + CACHE_TTL_SECONDS,
},
)],
)
def smart_llm_call(query: str, model: str = "gpt-4o-mini") -> dict:
# 1. Semantic lookup
if cached_response := semantic_cache_lookup(query, model):
return {"response": cached_response, "source": "semantic_cache", "cost": 0}
# 2. LLM call
response = client.chat.completions.create(
model=model,
messages=[{"role": "user", "content": query}],
)
text = response.choices[0].message.content
cost = litellm.completion_cost(response)
# 3. Store in cache
semantic_cache_store(query, text, model)
return {"response": text, "source": "llm_api", "cost": cost}Gateway-Level Semantic Cache
If LLM traffic already goes through a gateway (see llm-gateway), the semantic cache can live there instead of in each application. LiteLLM's cache: true setting is one option; Bifrost's semantic_cache plugin is another. Bifrost checks an exact-match hash first and runs the vector similarity search only on a miss. It needs a vector store (RediSearch-compatible Redis/Valkey, Weaviate, Qdrant or Pinecone) and an embedding model for the semantic path, and it only caches requests that carry a cache key (the x-bf-cache-key header, or a configured default_cache_key).
{
"vector_store": { "enabled": true, "type": "redis", "config": { "addr": "redis:6379" } },
"plugins": [{
"enabled": true,
"name": "semantic_cache",
"config": {
"provider": "openai",
"embedding_model": "text-embedding-3-small",
"dimension": 1536,
"threshold": 0.85,
"ttl": "1h"
}
}]
}Layer 3: Provider-Side Prompt Caching
# Anthropic — cache long system prompts (saves 90% on cached input tokens)
import anthropic
anthropic_client = anthropic.Anthropic()
# Long system prompt — mark for caching
SYSTEM_PROMPT = open("knowledge-base.txt").read() # e.g., 50k tokens
def call_with_prompt_cache(user_question: str) -> str:
response = anthropic_client.messages.create(
model="claude-sonnet-4-6",
max_tokens=1024,
system=[
{"type": "text", "text": "You are a helpful assistant."},
{
"type": "text",
"text": SYSTEM_PROMPT,
"cache_control": {"type": "ephemeral"}, # cache this block
}
],
messages=[{"role": "user", "content": user_question}],
)
# Log cache efficiency
usage = response.usage
cache_savings = usage.cache_read_input_tokens * 0.9 # 90% discount on cached
print(f"Cache hits: {usage.cache_read_input_tokens} tokens "
f"(saved ~${cache_savings * 3.0 / 1_000_000:.4f})")
return response.content[0].text
# OpenAI — automatic for repeated prefixes (≥1,024 tokens)
# No code change needed; cached tokens appear in usage.prompt_tokens_details
response = client.chat.completions.create(
model="gpt-4o-mini",
messages=[
{"role": "system", "content": LONG_SYSTEM_PROMPT}, # auto-cached
{"role": "user", "content": user_question},
]
)
cached = response.usage.prompt_tokens_details.cached_tokens
print(f"OpenAI cached {cached} tokens")Cache Warming
async def warm_cache(common_queries: list[… (nội dung đầy đủ có trong gói tải về)
Skill liên quan
- llm-ops – LLM Operations: RAG, embeddings, cơ sở dữ liệu vector, fine-tuning, prompt engineering…
- llm-prompt-optimizer – Dùng khi cải thiện prompt cho bất kỳ LLM nào. Áp dụng các kỹ thuật prompt engineering đã…
- loki-mode – Quy trình đa tác nhân phiên bản 2.35.x (cũ) để biến PRD đã giới hạn phạm vi thành triển…
- longbridge-derivatives – Hướng dẫn tuyển chọn từ nguồn gốc cho Longbridge Derivatives; dùng khi quy trình phù hợp…
- longbridge-quant – Hướng dẫn tuyển chọn từ nguồn gốc cho Longbridge Quant; dùng khi quy trình phù hợp với…
- lore – Bộ nhớ dự án Markdown cho AI agent. Dùng cho quyết định, kiến trúc, quy ước, phạm vi…
- m365-agents-dotnet – Microsoft 365 Agents SDK cho .NET. Xây dựng agent đa kênh cho Teams/M365/Copilot Studio…
- m365-agents-py – Microsoft 365 Agents SDK cho Python. Xây dựng agent đa kênh cho Teams/M365/Copilot…