Ce qui doit déclencher l'évaluation
Tout ce qui change le comportement de l'assistant :
| Changement | Exemple | Déclenche l'évaluation ? |
|---|---|---|
| Prompt système | Ajout d'une consigne de ton | Oui |
| Modèle ou version | gemini-2.5-flash → version plus récente, ou passage à Claude | Oui |
| Paramètres | temperature, max_tokens, top_k de la recherche | Oui |
| Découpage / embeddings | Taille des extraits, nouveau modèle d'embedding | Oui (avec réindexation de test) |
| Jeu doré | Ajout de cas | Oui (pour voir le nouveau niveau de référence) |
| README, style du front | Faute de frappe | Non |
Le flux
flowchart LR
PR["Pull request : prompt v8"] --> CI["CI : run_eval.py"]
CI --> S{"Seuils respectés ?"}
S -- "Non" --> X["Check rouge : fusion bloquée"]
S -- "Oui" --> C["Commentaire : scores v7 vs v8"]
C --> REV["Revue humaine des cas qui ont changé"]
REV --> M["Fusion puis déploiement"]
GitHub Actions : un exemple complet
name: eval-llm
on:
pull_request:
paths:
- "prompts/**"
- "config/modele.yaml"
- "eval/**"
- "app/rag/**"
jobs:
eval:
runs-on: ubuntu-latest
permissions:
contents: read
id-token: write # Workload Identity Federation vers GCP (pas de clé JSON)
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: "3.12"
- run: pip install -r eval/requirements.txt
- uses: google-github-actions/auth@v2
with:
workload_identity_provider: ${{ secrets.WIF_PROVIDER }}
service_account: ${{ secrets.EVAL_SA }}
- name: Évaluation
env:
GOOGLE_CLOUD_PROJECT: ${{ vars.GCP_PROJECT }}
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
JUGE: claude
run: |
cd eval
python run_eval.py golden/assistant.jsonl --seuil 0.85 \
--seuil-categorie piege=1.0 --sortie rapport.json
- uses: actions/upload-artifact@v4
if: always()
with:
name: rapport-eval
path: eval/rapport.jsonEnsuite, dans les réglages du dépôt, rendez le check eval-llm obligatoire sur la branche principale (règle de protection de branche) : c'est lui qui rend le seuil réellement bloquant.
Le workflow s'exécute et échoue, mais la PR peut quand même être fusionnée. Que manque-t-il ?
Un check rouge n'empêche la fusion que s'il est déclaré obligatoire dans la protection de branche. Le seuil et le juge déterminent le verdict, pas son caractère bloquant.
Choisir le seuil
- Mesurez d'abord la ligne de base : le score de la version actuelle, sur plusieurs exécutions.
- Fixez le seuil un peu sous cette ligne de base pour absorber la variabilité, puis relevez-le à mesure que le système progresse (effet cliquet).
- Les catégories critiques (sécurité, refus) ont un seuil dédié, souvent 100 %.
- Avec un petit jeu doré, un cas d'écart n'est pas significatif : affichez la liste des cas qui changent de statut entre la base et la PR, c'est plus parlant qu'un pourcentage.
import json, sys
def statuts(chemin):
return {d["id"]: d["ok"] for d in json.load(open(chemin, encoding="utf-8"))["details"]}
base, pr = statuts(sys.argv[1]), statuts(sys.argv[2])
for cid in sorted(base.keys() & pr.keys()):
if base[cid] != pr[cid]:
print(f"{cid}: {'OK' if base[cid] else 'KO'} -> {'OK' if pr[cid] else 'KO'}")La version actuelle obtient 0,90, 0,87 et 0,90 sur trois exécutions. Quel seuil bloquant de départ est le plus raisonnable ?
Un seuil au-dessus de la base bloquerait toutes les PR, un seuil trop bas ne bloquerait aucune régression. Juste sous la base absorbe la variabilité tout en détectant une vraie baisse.
Exercice : adapter le workflow à Cloud Build
Votre équipe utilise Cloud Build au lieu de GitHub Actions. Écrivez un cloudbuild.yaml qui installe les dépendances, lance l'évaluation avec les mêmes seuils et échoue si le seuil n'est pas atteint. La clé Anthropic est dans Secret Manager sous le nom anthropic-api-key.
Voir la solution
steps:
- name: python:3.12
entrypoint: bash
dir: eval
secretEnv: ["ANTHROPIC_API_KEY"]
env:
- "GOOGLE_CLOUD_PROJECT=$PROJECT_ID"
- "JUGE=claude"
args:
- -c
- |
pip install -r requirements.txt
python run_eval.py golden/assistant.jsonl --seuil 0.85 \
--seuil-categorie piege=1.0 --sortie rapport.json
availableSecrets:
secretManager:
- versionName: projects/$PROJECT_ID/secrets/anthropic-api-key/versions/latest
env: ANTHROPIC_API_KEYLe code de sortie 1 de run_eval.py fait échouer l'étape, donc le build. Branchez ensuite un déclencheur Cloud Build sur les pull requests avec un filtre de fichiers (prompts/**, config/**, eval/**), et exigez son statut dans la protection de branche du dépôt.
Je sais faire
- Lister les changements qui doivent déclencher une évaluation.
- Brancher le harnais dans GitHub Actions ou Cloud Build avec un seuil global et par catégorie.
- Rendre le check réellement bloquant via la protection de branche.
- Fixer un seuil à partir d'une ligne de base mesurée, puis le relever.
- Montrer en revue les cas qui changent de statut entre deux versions.