Cache de respostas
A jangada pode cachear respostas do LLM para economizar tokens e latência —
plugado via LLM(..., cache=...). O cliente consulta o cache antes de chamar
o provider e o popula depois de uma resposta bem-sucedida. Dois modos: exato
e semântico.
Cache exato
Acerta só quando a requisição é idêntica (mesmo método, escopo
provider/model/params e mensagens). LRU com max_size e ttl opcionais,
sem custo de embedding.
from jangada_ai import LLM, ExactCache
llm = LLM("openai", "gpt-4o-mini", cache=ExactCache(max_size=512, ttl=3600))
llm.complete("Resuma a teoria da relatividade.") # chama o provider
llm.complete("Resuma a teoria da relatividade.") # vem do cache (idêntico)Cache semântico
Acerta quando a pergunta é suficientemente parecida com uma anterior do mesmo
escopo (similaridade de cosseno ≥ threshold). Reusa LLM.embed + um
vector_store do RAG. Após o acerto semântico, aplica um filtro exato de
escopo (provider/model/params/método) para alta precisão.
from jangada_ai import LLM, SemanticCache
embedder = LLM("openai", "text-embedding-3-small")
cache = SemanticCache(embedder, threshold=0.85)
llm = LLM("openai", "gpt-4o-mini", cache=cache)
llm.complete("Qual a capital da França?")
llm.complete("Me diga a capital francesa.") # paráfrase → acerta o cacheCalibre o threshold por modelo de embedding
A escala de cosseno varia muito entre modelos — não existe número mágico:
| Modelo de embedding | Paráfrase (≈) | Pergunta distinta (≈) |
|---|---|---|
text-embedding-3-small (OpenAI) | 0.62 | 0.11 |
gemini-embedding-001 (Gemini) | 0.90 | 0.49 |
O padrão é 0.85 (meio-termo). Meça paráfrases vs. perguntas distintas no seu
modelo e escolha um corte entre as duas distribuições. Alto demais = cache
morto; baixo demais = respostas erradas (falso-positivo).
O que não é cacheado
- Chamadas com tools ou MCP (
tools=/mcp_servers=). - Streaming (
stream/astream). - Respostas vindas de fallback (só o candidato primário popula o cache).
- Recusas de guardrail.
complete/parse e suas versões async compartilham a mesma chave. O cache é
local ao processo (a Completion fica em memória; o vector store é usado só
para a similaridade).
O que mudou na 1.9.0
- A chave inclui o schema do
parse:parse(p, A)seguido deparse(p, B)não devolve mais o objeto do tipoA. SemanticCachesepara por contexto: system, histórico anterior e partes não-texto (imagens) entram no escopo. "sim" ou "continue" em conversas diferentes não dão mais hit com a resposta de outra conversa.- O hit devolve uma cópia com
cost=0.0ecached=True— somar custos numFlow/Agentnão conta de novo uma chamada que não foi paga, e mexer no objeto devolvido não altera o que está no cache. - Evicção e expiração limpam o vector store do
SemanticCache(antes as entradas mortas ficavam lá e derrubavam a taxa de acerto). - Erro no cache não derruba a chamada: falha no
get/set(ex.: o embedder do cache semântico tomou rate limit) vira miss, com log emDEBUG. ExactCacheeSemanticCachesão seguros entre threads.