agentleFS
khalilbenazkhalilbenaz/claude-skills-collection/skills/agent-cost-optimizer/SKILL.md

agent-cost-optimizer

Skill28 starsChanged 14 days agoMITView on GitHub

Optimisation des coûts des agents IA — tokens, API calls, modèles, caching, routing, budget controls. Se déclenche avec "coût agent", "agent cher", "réduire les coûts IA", "token optimization", "optimiser les tokens", "budget agent", "agent cost", "économiser sur l'API". Also triggers on "reduce agent cost", "token cost optimization", "cheaper model routing".

  • Reads credentials

We split this skill into the rules it gives an agent

4 rules. About 0 are common, 4 are distinctive, and 0 are very specific to this project.

  • ≈0

    Common · estimate

    Many files like this have a rule of this kind.

  • ≈4

    Distinctive · estimate

    This author's own choices. Worth a look.

  • 0

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Distinctive:

    Never say "happy to help", "sure!", "great question", "let me", or similar.

    line 287
  2. Distinctive:

    Stop when done. No summary, no recap, no trailing commentary.

    line 290
  3. Distinctive:

    No politeness wrappers. Direct and blunt.

    line 291
  4. Distinctive:

    No emoji unless asked.

    line 294

≈ “Common” is an estimate: at least 1 in 5 of the 308,232 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md

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é :

  • Supprimer les formules de politesse, répétitions et exemples superflus.
  • System prompt cible : < 500 tokens pour agents simples, < 1 000 pour agents complexes.
  • Remplacer les longues instructions par des formats compacts :
# 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}
  • Tester chaque modification sur un jeu de ≥ 20 cas avant de déployer.
  • Utiliser tiktoken (OpenAI) ou anthropic.count_tokens() pour mesurer avant/après.

É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 :

  • RAG : injecter uniquement les chunks pertinents (top-k = 3 à 5) plutôt que tout le document.
  • Sliding window : conserver les N derniers échanges + résumé cumulatif.

É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
  • Semantic cache (GPTCache, Redis VSS) : utile quand les prompts varient légèrement mais la réponse est identique.
  • Tool result cache : cacher les résultats d'API externes coûteuses (recherches web, bases de données).
  • TTL recommandé : 1 h pour données fraîches, 24 h pour données statiques.

É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

  • Batch tools : concevoir des outils qui acceptent une liste d'items plutôt qu'un seul.
  • Parallel calls : déclencher les tool calls indépendants en simultané (réduire les aller-retours).
  • Descriptions précises : le LLM choisit mieux du premier coup → moins de tentatives ratées.
# 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é :

  • Par conversation : $0.10–$0.50 selon cas d'usage
  • Par agent/jour : $5–$50 en production
  • Toujours combiner limite côté code et max_tokens dans chaque requête API.

É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

  • Baseline mesurée (coût médian, P95, P99 par type de requête)
  • Model routing implémenté et testé sur jeu de données réel
  • System prompt < seuil cible et prompt cache activé si éligible
  • Context summarization avec tests de non-régression qualité
  • Budget guard actif avec alertes à 80 % et hard stop à 100 %
  • Cache hit rate > 20 % dès le départ
  • Dashboard coût/tâche opérationnel (pas juste coût total)

Communication Rules — MANDATORY

  • Ultra-concise. No filler, no preamble, no pleasantries.
  • Never say "happy to help", "sure!", "great question", "let me", or similar.
  • Tool first, talk second. Act before explaining.
  • Result first. Lead with outcome, not process.
  • Stop when done. No summary, no recap, no trailing commentary.
  • No politeness wrappers. Direct and blunt.
  • Minimum words. If one word works, do not use ten.
  • No unsolicited explanations.
  • No emoji unless asked.

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.