🤖 Agents IA

agent-cost-optimizer

Optimisation des coûts des agents IA — tokens, API calls, modèles, caching, routing, budget controls.

⚡ Installation & lancement en 1 commande

Copiez-collez dans votre terminal : le skill s'installe dans ~/.claude/skills et Claude Code se lance directement dessus.

macOS / Linux
curl -fsSL https://raw.githubusercontent.com/khalilbenaz/claude-skills-collection/main/install.sh | sh -s -- agent-cost-optimizer --launch
Windows (PowerShell)
iex "& { $(iwr -useb https://raw.githubusercontent.com/khalilbenaz/claude-skills-collection/main/install.ps1) } agent-cost-optimizer -Launch"

🚀 Déjà installé ?

claude "/agent-cost-optimizer"

Ou tapez /agent-cost-optimizer dans une session Claude Code, ou décrivez simplement votre besoin — le skill se déclenche automatiquement via le skill-router.

🔑 Déclencheurs automatiques

Le skill s'active automatiquement quand votre demande contient :

coût agentagent cherréduire les coûts IAtoken optimizationoptimiser les tokensbudget agentagent costéconomiser sur l'API

📦 Installation manuelle

git clone https://github.com/khalilbenaz/claude-skills-collection.git cp -r claude-skills-collection/skills/agent-cost-optimizer ~/.claude/skills/

Payload du plugin : skills/agent-cost-optimizer · source éditable : agent-skills/cost-optimizer

📖 Manuel

Agent Cost Optimizer

Quand utiliser ce skill

Dès qu'un agent IA consomme trop de tokens, que la facture API dépasse le budget, ou qu'on cherche à passer en production à coût maîtrisé. S'applique aussi pour mettre en place des garde-fous préventifs avant le déploiement.


Workflow

Étape 1 — Audit baseline (ne rien optimiser sans mesure)

Objectif : identifier les 20 % de requêtes qui causent 80 % du coût.

# Structure minimale de log — ajouter à chaque appel LLM
import anthropic, time

client = anthropic.Anthropic()

def call_with_cost_log(messages, model, system=""):
    t0 = time.time()
    resp = client.messages.create(
        model=model, max_tokens=1024,
        system=system, messages=messages
    )
    cost = (
        resp.usage.input_tokens  * pricing[model]["in"]  +
        resp.usage.output_tokens * pricing[model]["out"]
    )
    print(f"[COST] model={model} in={resp.usage.input_tokens} "
          f"out={resp.usage.output_tokens} cost_usd={cost:.5f} "
          f"latency_ms={int((time.time()-t0)*1000)}")
    return resp

Tarifs 2026 indicatifs (vérifier anthropic.com/pricing) :

ModèleInput / 1M tokensOutput / 1M tokens
claude-haiku-3-5$0.80$4.00
claude-sonnet-4$3.00$15.00
claude-opus-4$15.00$75.00
gpt-4o-mini$0.15$0.60
gemini-2.0-flash$0.10$0.40

Critère de décision : si le coût médian par requête > $0.02, optimiser en priorité. Si variance > 10×, le routing est le levier le plus impactant.


Étape 2 — Model routing (levier le plus rapide)

Router chaque tâche vers le modèle le moins cher capable de la traiter.

ROUTING_RULES = {
    "simple":   "claude-haiku-3-5",   # classification, extraction, reformulation
    "moderate": "claude-sonnet-4",    # raisonnement, synthèse, code standard
    "complex":  "claude-opus-4",      # architecture, décisions critiques, audit
}

def classify_task(prompt: str) -> str:
    """Classifier cheap (Haiku) pour décider du modèle à utiliser."""
    resp = client.messages.create(
        model="claude-haiku-3-5", max_tokens=10,
        messages=[{"role": "user", "content":
            f"Complexity of this task (simple/moderate/complex):\n{prompt[:300]}"}]
    )
    return resp.content[0].text.strip().lower()

def route(prompt: str):
    level = classify_task(prompt)
    return ROUTING_RULES.get(level, "claude-sonnet-4")
Règle : le coût du classifier doit être < 5 % du coût économisé. Haiku à $0.80/M tokens convient parfaitement.

Étape 3 — Prompt optimization

Compacter sans dégrader la qualité :

# MAUVAIS (verbose)
Tu es un assistant utile et bienveillant. Lorsque l'utilisateur te pose une question,
tu dois répondre de manière claire et structurée en utilisant le format JSON...

# BON (concis)
Réponds UNIQUEMENT en JSON valide. Schéma: {"answer": str, "confidence": float}

Étape 4 — Prompt caching (Anthropic natif)

Économie immédiate sur les requêtes avec system prompt identique (jusqu'à 90 % de réduction sur les tokens en cache).

response = client.messages.create(
    model="claude-sonnet-4",
    max_tokens=1024,
    system=[{
        "type": "text",
        "text": LONG_SYSTEM_PROMPT,          # > 1024 tokens pour activer le cache
        "cache_control": {"type": "ephemeral"}
    }],
    messages=messages
)
# Les appels suivants avec le même system prompt utilisent le cache (prix cache_read << prix input)

Prérequis : system prompt ≥ 1 024 tokens. En dessous, le gain est nul.


Étape 5 — Context window management

Chaque token dans le contexte est facturé à chaque appel.

MAX_CONTEXT_TOKENS = 4000  # seuil avant résumé

def maybe_summarize(messages: list, model="claude-haiku-3-5") -> list:
    total = sum(len(m["content"].split()) * 1.3 for m in messages)  # estimation rapide
    if total < MAX_CONTEXT_TOKENS:
        return messages
    # Résumer les messages anciens (garder les 4 derniers intacts)
    to_summarize = messages[:-4]
    summary_resp = client.messages.create(
        model=model, max_tokens=300,
        messages=[{"role": "user", "content":
            "Résume en 200 mots max:\n" + "\n".join(m["content"] for m in to_summarize)}]
    )
    return [{"role": "assistant", "content": "[Résumé] " + summary_resp.content[0].text}] + messages[-4:]

Stratégies complémentaires :


Étape 6 — Caching applicatif

import hashlib, json
from functools import lru_cache

# Cache exact (Redis recommandé en prod)
cache: dict = {}

def cached_llm_call(prompt: str, model: str) -> str:
    key = hashlib.sha256(f"{model}:{prompt}".encode()).hexdigest()
    if key in cache:
        return cache[key]
    result = client.messages.create(model=model, max_tokens=512,
        messages=[{"role": "user", "content": prompt}])
    text = result.content[0].text
    cache[key] = text
    return text

Étape 7 — Batch processing

# Batch API Anthropic — jusqu'à 50 % de réduction, délai < 24 h
curl https://api.anthropic.com/v1/messages/batches \
  -H "x-api-key: $ANTHROPIC_API_KEY" \
  -H "anthropic-version: 2023-06-01" \
  -d '{
    "requests": [
      {"custom_id": "task-1", "params": {"model": "claude-haiku-3-5", "max_tokens": 256,
        "messages": [{"role": "user", "content": "Classe ce texte: ..."}]}},
      {"custom_id": "task-2", "params": {"model": "claude-haiku-3-5", "max_tokens": 256,
        "messages": [{"role": "user", "content": "Résume: ..."}]}}
    ]
  }'

Adapter pour openai.batches (même principe, quota 24 h, 50 % discount).


Étape 8 — Tool call optimization

# MAUVAIS : 3 appels séquentiels = 3 tours agent
get_weather("Paris")  # appel 1
get_price("AAPL")     # appel 2
translate("hello")    # appel 3

# BON : parallel tool use (un seul tour agent)
# L'agent émet les 3 tool_use en une seule réponse si les descriptions sont claires

Étape 9 — Budget controls

class BudgetGuard:
    def __init__(self, max_usd: float):
        self.max_usd = max_usd
        self.spent = 0.0

    def charge(self, cost: float):
        self.spent += cost
        if self.spent >= self.max_usd * 0.8:
            print(f"[WARN] 80% du budget atteint ({self.spent:.4f}$/{self.max_usd}$)")
        if self.spent >= self.max_usd:
            raise RuntimeError(f"Budget dépassé : {self.spent:.4f}$ > {self.max_usd}$")

Paramétrage recommandé :


Étape 10 — Monitoring continu

Métriques minimales à tracker :

MétriqueCible
Coût par tâche complétée< $0.01
Cache hit rate> 30 %
% requêtes routées vers cheap model> 60 %
Token ratio output/input< 0.5 (éviter sur-génération)

Stack recommandée : Langfuse (open-source, self-hostable) ou LangSmith pour le tracing ; Grafana + InfluxDB pour les dashboards opérationnels.


Anti-patterns / pièges

PiègeConséquenceCorrectif
Résumé trop agressifPerte de contexte critique, hallucinationsGarder toujours les 4 derniers messages bruts
Cache sans TTLRéponses obsolètes livrées aux utilisateursTTL explicite + invalidation sur changement de données
Routing systématique vers HaikuDégradation qualité sur tâches complexesClassifier avant de router, évaluer la qualité
max_tokens trop grandSur-génération inutileCalibrer par type de tâche (extraction : 128, résumé : 512)
Optimiser avant de mesurerEffort mal cibléToujours établir la baseline d'abord
Prompt cache sur < 1 024 tokensAucun gain (seuil non atteint)Vérifier le token count avant d'activer
Ignorer le coût des embeddingsBudget RAG sous-estiméTracker embedding_tokens séparément

Checklist avant mise en production