TL;DR en langage simple
- Les API de modèles sont sans état : chaque appel réexpédie souvent tout l'historique. Exemple chiffré : un thread de 40 étapes ré-envoie ~2.17M tokens d'entrée alors que le transcript effectif fait ~85K tokens. Source : https://viktor.com/blog/how-we-built-viktor-around-prompt-caching
- Le "prompt caching" transforme ce préfixe coûteux en une lecture de cache bon marché (~0.1x coût) si la représentation est byte‑stable. Résultat observé : $11.35 sans cache → $2.07 avec cache (≈81.8 % d'économie) sur Claude Opus 4.8. Source : https://viktor.com/blog/how-we-built-viktor-around-prompt-caching
- Principes clefs : SDK‑first, threads append‑only, sérialisation byte‑stable, summarisation in‑cache. Ces choix permettent de réduire le coût par thread de ≥50 % à ≥80 % selon le cas. Source : https://viktor.com/blog/how-we-built-viktor-around-prompt-caching
Méthode rapide : mesurer (3 h), prototyper cache (1 jour), canary 10 % trafic pendant 48 h avec gates (hit‑rate ≥75 %, réduction coût/thread ≥50 %). Source : https://viktor.com/blog/how-we-built-viktor-around-prompt-caching
Ce que vous allez construire et pourquoi c'est utile
Vous allez construire un moteur de threads conçu pour le "prompt caching" afin de réduire fortement le coût des workflows qui enchaînent 10–100 appels au modèle par tâche. Principes (source : https://viktor.com/blog/how-we-built-viktor-around-prompt-caching) :
- SDK‑first : exposer outils comme fonctions en code (éviter d'injecter des schémas textuels dans le prompt).
- Threads append‑only : un journal immuable d'événements (seq, type, ts, payload).
- Sérialisation byte‑stable : JSON canonique, clés triées, suppression de timestamps non déterministes.
- Summarisation in‑cache / compaction : déclencher résumé quand >40 événements ou >85k tokens.
Pourquoi utile pour vous : un agent de triage qui fait 30–50 appels par ticket peut voir la facture par ticket passer de $11.35 à $2.07 (exemple Viktor) — économie ≈81.8 %. Source : https://viktor.com/blog/how-we-built-viktor-around-prompt-caching
Avant de commencer (temps, cout, prerequis)
Source : https://viktor.com/blog/how-we-built-viktor-around-prompt-caching
Temps estimé
- Prototype minimal (mesure + rejouage) : ~3 heures.
- Intégration SDK et compaction sécurisée : 2–5 jours.
Coûts/valeurs de référence
- Thread 40 étapes : ~2.17M input tokens total (exemple), transcript ~85K tokens.
- Coût estimé (exemple Claude Opus 4.8) : $11.35 sans cache → $2.07 avec cache (≈81.8 %).
- Objectifs opérationnels : cache‑hit‑rate cible ≥75 %, réduction coût/thread ≥50 %, latence tail + <100 ms.
Prérequis techniques
- Accès API modèle et traces tokens/facturation.
- Cache rapide (ex. Redis) avec TLS ; capacité à configurer TTL (ex. 60 min).
- Librairie de tokenization et logging tokens‑per‑call.
- Possibilité de refactorer outils vers SDK (éviter texte variable dans prompt).
Checklist initiale
- [ ] Clés API et accès facturation
- [ ] Instance Redis (TLS) ou équivalent
- [ ] Tokenizer et logs tokens‑per‑call
- [ ] Thread représentatif (~40 appels) pour baseline
Sécurité : chiffrer au repos, ACL strictes et redaction PII avant mise en cache. Source : https://viktor.com/blog/how-we-built-viktor-around-prompt-caching
Installation et implementation pas a pas
Source : https://viktor.com/blog/how-we-built-viktor-around-prompt-caching
-
Mesurer la baseline (3 h)
- Rejouez 10 threads représentatifs (30–50 appels chacun), enregistrez tokens par appel, latence p95/p99, et coût estimé.
- Exemple cible : total tokens ≈2.17M pour 40 étapes ; coût de référence $11.35.
-
Sérialisation byte‑stable
- Implémentez JSON canonique (tri des clés, suppression champs éphémères).
- Test de byte‑diff : chaque sérialisation identique doit produire le même hash.
-
Cache de préfixe + compaction
- Choix clé : thread:{id}:prefix:v1 ; TTL suggéré 3600 s (60 min) ; hot_window = 30 min.
- Triggers : summary_trigger_calls = 40, summary_trigger_tokens = 85000.
-
Migrer outils vers SDK
- Exposer fonctions (sync/async), ajouter sorties immuables au log append‑only.
-
Rollout
- Canary 10 % trafic pendant 48 h ; gates : hit‑rate ≥75 %, réduction coût/thread ≥50 %, latence tail + <100 ms.
Tableau comparatif (exemple observé)
| Mesure | Sans cache | Avec prompt caching | |---:|---:|---:| | Input tokens total (thread 40 étapes) | ~2.17M | ~0.1x lecture (≈217k équiv.) | | Transcript stocké | ~85K tokens | résumé in‑cache (≈8–10K) | | Coût estimé | $11.35 | $2.07 | | Réduction | — | ≈81.8 % |
Commandes d'exemple :
# rejouer un thread et capturer tokens par appel
python run_thread_smoke.py --thread-id sample-40 --capture-tokens --out=./out --retries=3
# extraire résumé JSON (p95/p99 latence, total tokens, cost)
jq '.summary | {total_tokens, calls, cost_estimate, p95_ms, p99_ms}' ./out/sample-40-summary.json
Exemple de config (cache + compaction) :
cache:
backend: redis
prefix: "thread"
ttl_seconds: 3600 # 60 min
compaction:
hot_window_minutes: 30
summary_trigger_calls: 40
summary_trigger_tokens: 85000
provider_adapters:
opus:
explicit_breakpoints: true
recommended_ttl: 1800
Problemes frequents et correctifs rapides
Source : https://viktor.com/blog/how-we-built-viktor-around-prompt-caching
- Misses du cache liées à une sérialisation non déterministe
- Correctif : JSON canonique, tri des clés, suppression timestamps, tests byte‑diff.
- Compaction qui dégrade la qualité
- Correctif : n'appliquer la compaction que si cache‑age ≥ hot_window (ex. 30 min), A/B test, rollback si perte de qualité >3 %.
- Outils qui injectent du texte variable
- Correctif : exécuter ces outils côté SDK, append leurs sorties immuables.
- Eviction / routage fournisseur inattendu
- Correctif : adapter TTL (ex. recommended_ttl 1800 s), provider adapter, monitoring d'eviction.
Seuils de surveillance recommandés
- cache‑hit‑rate cible : ≥75 %
- réduction coût/thread visée : ≥50 % (objectif initial), idéal ≥80 % sur workflows lourds
- p95/p99 latence tail : + <100 ms
- qualité : alerter si dégradation >3 % (accuracy/acceptance)
Premier cas d'usage pour une petite equipe
Source et inspiration : https://viktor.com/blog/how-we-built-viktor-around-prompt-caching
Contexte : équipe support 2–5 personnes, agent faisant 30–50 appels par ticket. Pour un solo founder ou petite équipe (1–4 personnes) : trois (en réalité quatre) actions concrètes, peu coûteuses et rapides.
-
Prioriser et mesurer (3 actions, ~3 heures)
- Ciblez le 1 workflow le plus coûteux (par ex. le ticket qui fait 30–50 appels).
- Rejouez 5–10 instances, capturez total tokens, coût estimé et p95/p99 latence. Objectif : obtenir baseline chiffrée (ex. 2.17M tokens, $11.35).
- Résultat attendu en 3 h : métriques prêtes pour prototypage.
-
Prototype minimal en 1 jour (actionable, coûts faibles)
- Déployez un Redis managé (coût typique $5–$20/mois) ou Redis local pour tests.
- Implémentez un sérialiseur JSON canonique et une clé cache thread:{id}:prefix:v1.
- Testez hors production sur 10 threads ; objectif >50 % réduction coût/thread.
-
Règles opérationnelles simples pour la petite équipe
- Hot window : 30 minutes ; TTL par défaut : 60 minutes.
- Triggers de summarisation : 40 appels OU 85k tokens.
- Canary rapide : 10 % du trafic pendant 48 h ; critère d'acceptation : hit‑rate ≥75 % et réduction coût/thread ≥50 %.
-
Automatisations et limites pratiques pour solo founders
- Automatiser la capture tokens et le rapport quotidien (script cron : 1x/jour).
- Limiter scope initial : activez caching sur le top‑1 agent (ou 1 endpoint) pour réduire risque et effort.
- Budget guardrail : alerter si coût/mois > $100 ou augmentation tokens/thread > 20 %.
Actions opérationnelles (priorité)
- Mesurer baseline (3 h) → Prototype Redis + serializer (1 jour) → Canary 10 % / 48 h → montée progressive.
Notes techniques (optionnel)
Source : https://viktor.com/blog/how-we-built-viktor-around-prompt-caching
- Byte‑stabilité : utilisez JSON déterministe (tri des clés, suppression champs volatils). Sans byte‑stabilité, le cache ne fonctionne pas.
- Compaction in‑cache : résumer à l'intérieur du cache permet des lectures à ~0.1x coût d'une requête complète.
- SDK‑first : transformer les outils en fonctions réduit l'instabilité textuelle et permet une clé de cache stable.
- Provider adapters : encapsulez différences (breakpoints explicites, TTL, routage). Exemple : recommended_ttl 1800 s pour certains providers.
- Sécurité : chiffrement AES au repos, ACL, redaction PII avant cache.
Que faire ensuite (checklist production)
Hypotheses / inconnues
- Les APIs modèles sont sans état et renvoient l'historique à chaque appel ; Viktor documente le cas : thread 40 étapes → ~2.17M input tokens vs transcript ~85K tokens et économie $11.35 → $2.07 (≈81.8 %). Source : https://viktor.com/blog/how-we-built-viktor-around-prompt-caching
- Hypothèse à valider : une sérialisation byte‑stable + approche SDK‑first permet d'atteindre un cache‑hit‑rate ≥75 % sur vos threads. Méthodologie : mesurer baseline, prototyper, canary 10 % pendant 48 h.
Risques / mitigations
- Perte de qualité après compaction — mitigation : ne pas compacter si cache‑age < 30 min, A/B tests, rollback si dégradation >3 %.
- Misses de cache dues à dérive de sérialisation — mitigation : serializer déterministe, tests byte‑diff continus.
- Evictions / routage fournisseur — mitigation : provider adapter, TTL conservateur (ex. hot_window 30 min, recommended_ttl 1800 s), monitoring d'eviction.
- Fuite de données sensibles — mitigation : chiffrement au repos, ACL, redaction PII.
Prochaines etapes
- Construire prototype en ~3 h pour mesurer tokens‑per‑thread sur l'agent le plus lourd.
- Implémenter serializer canonique, cache Redis et provider adapter (2–5 jours).
- Lancer canary 10 % trafic pendant 48 h ; gates : cache‑hit‑rate ≥75 %, réduction coût/thread ≥50 %, latence tail + <100 ms.
- Monter progressivement : 10 → 50 → 100 % si gates OK.
Référence principale : https://viktor.com/blog/how-we-built-viktor-around-prompt-caching
(Note méthodologique : cette synthèse suit les exemples chiffrés et les choix architecturaux présentés dans l'article source.)