OrkaJS
Orka.JS

Cache

Optimisez vos performance en évitant les appels redondants grâce au cache intelligent. Réduisez coûts et latence via des stratégiesIn-Memory ou Redis.

Pourquoi le Cache ?

Les appels API LLM sont coûteux et lents. Lorsque le même prompt est envoyé plusieurs fois (ex : questions utilisateur répétées, traitement par lots ou itérations de développement), le cache évite les appels API redondants en retournant instantanément les résultats précédemment calculés.

0ms

Latence cache hit (vs 500-3000ms appel API)

$0

Coût par réponse en cache

100%

Résultats déterministes

# Architecture

Le système de cache d'Orka JS est composé de trois couches qui fonctionnent ensemble :

Infrastructure de Stockage

La colonne vertébrale du cache. MemoryCache pour la vitesse, RedisCache pour la distribution.

CacheStore

Accélération des Réponses

Enveloppe les adaptateurs pour servir des résultats instantanés, éliminant les coûts API.

CachedLLM

Persistance Vectorielle

Évite les calculs de vecteurs redondants pour les chunks répétés dans les pipelines RAG.

CachedEmbeddings

# MemoryCache (En Mémoire)

Le store de cache le plus simple. Les données sont stockées en processus via une Map. Aucune dépendance externe requise. Idéal pour le développement, les serveurs mono-instance et les processus de courte durée.

memory-cache.ts
import { MemoryCache } from '@orka-js/cache';
 
const cache = new MemoryCache({
maxSize: 1000, // Maximum number of entries (default: 1000)
ttlMs: 1000 * 60 * 30, // Time-to-live: 30 minutes (optional)
namespace: 'my-app' // Key prefix for isolation (optional)
});
 
// Basic operations
await cache.set('key', { data: 'value' });
const value = await cache.get('key'); // { data: 'value' }
const exists = await cache.has('key'); // true
await cache.delete('key');
await cache.clear();
 
// Get cache statistics
const stats = cache.getStats();
console.log(stats);
// { hits: 42, misses: 8, size: 150, hitRate: 0.84 }

Simplicité Native

Zéro dépendance externe. Opère entièrement dans la mémoire du processus Node.js.

Standalone

Expiration Temporelle (TTL)

Contrôle granulaire du Time-To-Live. Les données s'auto-détruisent après expiration.

Auto-Clean

Politique d'Éviction LRU

Plafonnement automatique. Supprime les entrées les plus anciennes pour éviter le débordement.

LRU Strategy

Isolation Logique

Partitionnement par namespace. Plusieurs caches indépendants dans une même instance.

Multitenant

Télémétrie Hit/Miss

Statistiques intégrées pour surveiller l'efficacité et optimiser le taux de succès.

Monitoring

# RedisCache (Distribué)

Pour les environnements de production avec plusieurs instances de serveur, Redis fournit un cache partagé et persistant. Les données survivent aux redémarrages du serveur et sont accessibles depuis n'importe quelle instance.

📦 Installation Requise

RedisCache nécessite le package redis :

npm install redis
import { RedisCache } from '@orka-js/cache';
 
const cache = new RedisCache({
url: 'redis://localhost:6379', // Redis connection URL
keyPrefix: 'orka:', // Key prefix (default: 'orka:')
ttlMs: 1000 * 60 * 60, // TTL: 1 hour (optional)
});
 
// Connect to Redis (auto-connects on first operation)
await cache.connect();
 
// Same API as MemoryCache
await cache.set('key', { data: 'value' });
const value = await cache.get('key');
 
// Disconnect when done
await cache.disconnect();
MemoryCacheSpeed Optimized
Zéro installation de dépendance
Vitesse d'accès nanoseconde
Données volatiles au redémarrage
Isolé à une seule instance
RedisCacheScale Optimized
État persistant après reload
État partagé via le cluster
Nécessite un serveur Redis
Surcharge réseau (~1-2ms)

# CachedLLM — Cache de Réponses LLM

CachedLLM enveloppe n'importe quel LLMAdapter et met en cache les réponses de manière transparente. Il implémente l'interface LLMAdapter, vous pouvez donc l'utiliser comme remplacement direct partout où vous utilisez un LLM.

cached-llm.ts
import { OpenAIAdapter } from '@orka-js/openai';
import { MemoryCache } from '@orka-js/cache';
import { CachedLLM } from '@orka-js/cache';
 
// 1. Create your LLM adapter
const llm = new OpenAIAdapter({
apiKey: process.env.OPENAI_API_KEY!,
model: 'gpt-4o-mini'
});
 
// 2. Create a cache store
const cache = new MemoryCache({ maxSize: 500, ttlMs: 1000 * 60 * 30 });
 
// 3. Wrap with CachedLLM
const cachedLLM = new CachedLLM(llm, cache, {
ttlMs: 1000 * 60 * 60 // Override TTL: cache for 1 hour
});
 
// First call — hits the API (~800ms)
const result1 = await cachedLLM.generate('What is TypeScript?');
console.log(result1.content); // "TypeScript is a typed superset..."
 
// Second call — instant from cache (~0ms)
const result2 = await cachedLLM.generate('What is TypeScript?');
console.log(result2.content); // Same response, from cache
 
// Use in Orka config — transparent replacement
import { createOrka } from 'orkajs';
 
const orka = createOrka({
llm: cachedLLM, // ← Drop-in replacement
vectorDB: /* ... */
});
 
// All orka.ask(), orka.generate(), etc. now use caching
const answer = await orka.ask({
question: 'What is TypeScript?',
knowledge: 'docs'
});

Hachage Déterministe

Combine le prompt brut avec tous les paramètres du modèle (température, maxTokens, etc.) pour garantir une correspondance exacte.

hash(prompt + options)Key Integrity

Scénario Match Exact

Entrée Identique + Config Identique = 0ms de latence. Le moteur ignore l'inférence et sert le résultat stocké.

cache_hitEfficiency

Variance de Paramètres

Changer une seule option (comme la température) déclenche une nouvelle inférence pour respecter le comportement du modèle.

cache_missPrecision

# CachedEmbeddings — Cache d'Embeddings

Embedder le même texte plusieurs fois est du gaspillage. CachedEmbeddings met en cache les vecteurs d'embedding par texte d'entrée et n'envoie à l'API que les textes non mis en cache.

cached-embeddings.ts
import { OpenAIAdapter } from '@orka-js/openai';
import { MemoryCache } from '@orka-js/cache';
import { CachedEmbeddings } from '@orka-js/cache';
 
const llm = new OpenAIAdapter({ apiKey: process.env.OPENAI_API_KEY! });
const cache = new MemoryCache({ maxSize: 10000 });
 
const cachedEmbed = new CachedEmbeddings(llm, cache, {
ttlMs: 1000 * 60 * 60 * 24 // Cache embeddings for 24 hours
});
 
// First call — computes all 3 embeddings via API
const embeddings1 = await cachedEmbed.embed([
'Hello world',
'TypeScript is great',
'Orka AI framework'
]);
 
// Second call — all 3 from cache (0 API calls)
const embeddings2 = await cachedEmbed.embed([
'Hello world',
'TypeScript is great',
'Orka AI framework'
]);
 
// Mixed call — only "New text" hits the API, others from cache
const embeddings3 = await cachedEmbed.embed([
'Hello world', // ← from cache
'New text here', // ← API call
'Orka AI framework' // ← from cache
]);

Batching Intelligent

CachedEmbeddings vérifie le cache pour chaque texte individuellement, puis regroupe uniquement les textes non mis en cache en un seul appel API. Cela signifie que si vous embeddez 100 textes et 80 sont en cache, seuls 20 sont envoyés à l'API en un seul lot.

# Configuration Production avec Redis

En production, utilisez RedisCache pour partager le cache entre plusieurs instances de serveur et persister les données entre les redémarrages.

redis-cache.ts
import { createOrka, OpenAIAdapter } from '@orka-js/core';
import { RedisCache } from '@orka-js/cache';
import { CachedLLM } from '@orka-js/cache';
import { CachedEmbeddings } from '@orka-js/cache';
 
// Shared Redis cache
const redisCache = new RedisCache({
url: process.env.REDIS_URL!, // e.g. 'redis://redis:6379'
keyPrefix: 'orka:prod:',
ttlMs: 1000 * 60 * 60 * 4 // 4 hours
});
 
const llm = new OpenAIAdapter({
apiKey: process.env.OPENAI_API_KEY!,
model: 'gpt-4o-mini'
});
 
// Cache both LLM responses and embeddings
const cachedLLM = new CachedLLM(llm, redisCache);
const cachedEmbed = new CachedEmbeddings(llm, redisCache);
 
const orka = createOrka({
llm: cachedLLM,
vectorDB: /* ... */
});
 
// All operations now use Redis-backed caching
const result = await orka.ask({
question: 'How do I deploy my app?',
knowledge: 'documentation'
});
 
// Monitor cache performance
const stats = redisCache.getStats();
console.log(`Cache hit rate: ${(stats.hitRate * 100).toFixed(1)}%`);
 
// Cleanup on shutdown
process.on('SIGTERM', async () => {
await redisCache.disconnect();
});

# Cache Store Personnalisé

Implémentez l'interface CacheStore pour créer votre propre backend de cache (ex : DynamoDB, Memcached, SQLite).

dynamodb-cache.ts
import type { CacheStore } from '@orka-js/cache';
 
class DynamoDBCache implements CacheStore {
readonly name = 'dynamodb-cache';
 
async get<T>(key: string): Promise<T | undefined> {
// Your DynamoDB get logic
}
 
async set<T>(key: string, value: T, ttlMs?: number): Promise<void> {
// Your DynamoDB put logic
}
 
async delete(key: string): Promise<boolean> {
// Your DynamoDB delete logic
}
 
async clear(): Promise<void> {
// Your DynamoDB scan + delete logic
}
 
async has(key: string): Promise<boolean> {
// Your DynamoDB exists check
}
}
 
// Use with CachedLLM
const cache = new DynamoDBCache();
const cachedLLM = new CachedLLM(llm, cache);

Bonnes Pratiques

1. Définissez des TTL Appropriés

TTL court (5-30 min) pour le contenu dynamique. TTL long (heures/jours) pour les bases de connaissances stables. Pas de TTL pour les données immuables comme les embeddings.

2. Surveillez les Taux de Hit

Utilisez getStats() pour surveiller l'efficacité du cache. Un taux de hit inférieur à 50% peut indiquer que le cache est trop petit ou le TTL trop court.

3. Ne Cachez Pas les Appels Non-Déterministes

Si vous utilisez une température élevée (>0.8) pour la génération créative, le cache peut retourner des sorties créatives obsolètes. Envisagez de désactiver le cache pour les tâches créatives.

4. Utilisez les Namespaces

Utilisez des namespaces ou préfixes de clé différents pour les différents environnements (dev, staging, prod) pour éviter la pollution du cache.

Imports Tree-shakeable

// ✅ Import only what you need
import { MemoryCache } from '@orka-js/cache';
import { CachedLLM } from '@orka-js/cache';
 
// ✅ Or import from index
import { MemoryCache, RedisCache, CachedLLM, CachedEmbeddings } from '@orka-js/cache';