+150 XP

Guardrails : permissions, revue et coût

Un agent capable de lire votre Drive, d'envoyer des emails en votre nom et d'appeler des API payantes est un employé junior qui a vos credentials et aucun manager. Les guardrails sont le manager. Cette leçon porte sur la construction des review gates, des limites de permissions et des contrôles de coût qui permettent à une automatisation basée sur Gemini de tourner sans devenir un risque.

Les trois modes de défaillance

Tout agent non supervisé échoue de l'une de ces trois façons :

  1. Mauvaise action, conséquence réelle. Il envoie un brouillon à un client, supprime les mauvaises lignes ou merge une pull request qui casse la production.
  2. Accès trop large. On lui a donné « Drive » alors qu'il avait besoin d'un seul dossier : une prompt injection ou un appel d'outil halluciné atteint tout.
  3. Coût qui dérape. Une boucle appelle Gemini Pro mille fois, ou une recherche grounded s'exécute sur chacune des 50 000 lignes d'un sheet.

Les guardrails s'y superposent nettement : review gates pour la conséquence, scopes pour l'accès, budgets et routage de modèle pour le coût. Traitez-les comme trois contrôles distincts, car corriger l'un ne fait rien pour les autres.

Permissions et scopes : accorder le minimum

Commencez par restreindre ce que l'agent *peut* toucher, avant de vous soucier de ce qu'il *devrait* faire.

Scopes OAuth dans Apps Script et Workspace

Quand vous construisez une automatisation dans Apps Script (la façon la plus courante de brancher Gemini sur Gmail, Sheets et Docs), les scopes se déclarent, ils ne se supposent pas. Fixez-les explicitement dans `appsscript.json` plutôt que de laisser l'éditeur en accorder de larges automatiquement :

json
{
  "oauthScopes": [
    "https://www.googleapis.com/auth/spreadsheets.currentonly",
    "https://www.googleapis.com/auth/gmail.compose",
    "https://www.googleapis.com/auth/script.external_request"
  ]
}

Notez spreadsheets.currentonly (ce seul sheet, pas tous les sheets) et gmail.compose (créer des brouillons, sans pouvoir envoyer). Cette seule différence entre gmail.compose et gmail.send sépare un agent qui *propose* un email d'un agent qui l'*envoie*. Prenez le scope le plus étroit par défaut et obligez un humain à franchir la ligne.

Comptes de service et Vertex AI

Côté Vertex AI, un agent (par exemple construit avec l'Agent Development Kit) tourne sous un compte de service. Appliquez la même discipline avec IAM :

  • Donnez au compte de service roles/aiplatform.user, pas Owner.
  • S'il lit depuis BigQuery, accordez roles/bigquery.dataViewer sur le *dataset spécifique*, pas sur le projet.
  • Ne donnez jamais à un agent autonome un accès en écriture à la facturation, à IAM ou à la suppression de ressources.

Le principe : une identité par agent. Un compte de service par automatisation permet de lire l'audit log et de répondre à « qu'a fait *cet* agent » sans démêler des credentials partagés.

Gems et extensions

Dans l'application grand public Gemini, l'équivalent du scope, ce sont les Extensions activées (Gmail, Drive, Maps, etc.) et ce qu'un Gem est autorisé à référencer. Un Gem ne peut pas s'accorder l'accès à un connecteur que vous n'avez pas activé. Pour tout ce qui touche à des données sensibles, construisez l'automatisation dans Apps Script ou Vertex AI où les scopes sont explicites, pas dans un Gem où l'accès est large et à l'échelle du compte.

Ce que vous n'automatisez jamais sans supervision

Certaines actions doivent *toujours* s'arrêter pour un humain, quelle que soit la confiance du modèle. Gardez cette liste courte et absolue :

  • Envoi de communication externe. Email, messages Chat, tout ce qu'un client voit.
  • Changements de données irréversibles. Suppressions, écrasements, changements de schéma, paiements, remboursements.
  • Code qui part en production. Merge, déploiement, push sur une branche protégée.
  • Dépenser de l'argent au-delà d'un seuil par action (un appel d'API payant, une ressource cloud).
  • Accorder des accès à qui ou quoi que ce soit.

Gemini Code Assist et le Gemini CLI vont déjà dans ce sens : le CLI vous montre une commande shell ou une modification de fichier proposée et attend confirmation avant d'exécuter. Cette étape de confirmation n'est pas une friction à supprimer. C'est le review gate qui fait son travail. Quand vous construisez vos propres agents, copiez ce pattern au lieu de le contourner.

Review gates humains

Un review gate est un arrêt délibéré où l'agent produit une *proposition*, la conserve quelque part de visible, et attend une approbation humaine explicite avant d'exécuter. Le travail de l'agent s'arrête à « rédigé ». Celui d'une personne commence à « approuvé ».

Le pattern draft-and-wait

Le gate le plus propre dans Workspace est le brouillon Gmail. L'agent écrit l'email mais utilise le scope compose, donc le message atterrit dans Brouillons, pas dans la boîte du destinataire. L'humain relit et clique sur Envoyer. Aucune UI supplémentaire, et le gate est un outil que tout utilisateur comprend déjà.

Voici ce pattern de bout en bout : classifier un email entrant avec Gemini, puis créer une réponse en *brouillon* qu'un humain doit approuver.

python
import os
from google import genai

client = genai.Client(api_key=os.environ["GEMINI_API_KEY"])

REVIEW_PROMPT = """You are a support triage assistant.
Read the customer email and return JSON:
{"category": "...", "needs_human": true|false, "draft_reply": "..."}
Set needs_human=true for refunds, legal, or anything you are unsure about.
Never promise refunds or commitments in draft_reply."""

def triage(email_body: str) -> dict:
    resp = client.models.generate_content(
        model="gemini-2.5-flash",
        contents=[REVIEW_PROMPT, email_body],
        config={"response_mime_type": "application/json"},
    )
    return resp.parsed

def handle(email_body: str):
    result = triage(email_body)
    # L'agent N'ENVOIE JAMAIS. Il crée seulement un brouillon pour revue.
    create_gmail_draft(result["draft_reply"], flagged=result["needs_human"])
    return result

Deux guardrails sont intégrés. On demande au modèle de signaler lui-même les remboursements et les incertitudes (needs_human), et le plafond d'action est un brouillon, pas un envoi. Même si le modèle se trompe, le pire cas est un *brouillon* non relu dans un dossier, pas un email indésirable dans la boîte d'un client.

Routage par niveau de confiance

Tous les éléments n'appellent pas le même niveau d'examen. Routez par risque :

  • Exécution automatique pour les actions à faible enjeu, entièrement réversibles (mettre un label sur un email, ajouter un tag d'agenda).
  • Mise en file pour revue pour les enjeux moyens (une réponse en brouillon, une mise à jour de tableur proposée).
  • Escalade vers une personne nommée, avec le contexte joint, pour les enjeux élevés.

Laissez le modèle renvoyer son propre signal needs_human *et* appliquez des règles dures dans le code. Ne faites jamais confiance au modèle seul pour décider si quelque chose est dangereux, car une prompt injection peut inverser ce flag. La règle au niveau du code (« category == refund escalade toujours ») est le vrai guardrail ; l'auto-évaluation du modèle est un confort par-dessus.

Build agents with the Agent Development Kit

Watch on YouTube

Garder le coût sous contrôle

Le coût dérape en silence. L'agent fonctionne, la sortie a l'air correcte, et la facture arrive en fin de mois. Construisez les contrôles avant d'en avoir besoin.

Router vers le modèle le moins cher par défaut

Le levier le plus important est le choix du modèle. Gemini Flash coûte une fraction de Gemini Pro par token et est assez rapide pour la classification, l'extraction, le routage et la synthèse. Réservez Pro au raisonnement réellement difficile. Bon réglage par défaut : chaque étape utilise Flash, et vous *promouvez* une étape vers Pro seulement quand vous pouvez dire pourquoi.

python
def pick_model(task_complexity: str) -> str:
    # Économique par défaut. Escalade seulement pour le raisonnement difficile.
    return "gemini-2.5-pro" if task_complexity == "hard" else "gemini-2.5-flash"

Réduire ce que vous envoyez et stocker ce qui est réutilisable

  • La taille du contexte, c'est du coût. Le long contexte est une capacité, pas une consigne d'empiler tout le Drive dans chaque appel. Envoyez le morceau pertinent, pas le corpus.
  • Cachez les préfixes répétés. Si chaque appel partage un gros system prompt fixe ou un document, utilisez le context caching pour ne pas payer plein tarif les mêmes tokens à répétition.
  • Groundez à bon escient. Le grounding avec Google Search ajoute de la valeur et du coût. Activez-le pour les étapes qui ont besoin de faits récents, désactivez-le pour les autres.

Plafonner la boucle

Les agents bouclent. Une boucle de raisonnement sans plafond peut appeler le modèle des dizaines de fois sur une seule tâche. Fixez toujours un plafond d'itérations dur et un budget de tokens par run, et échouez en mode fermé quand vous l'atteignez :

python
MAX_STEPS = 6

def run_agent(task, step=0):
    if step >= MAX_STEPS:
        return escalate(task, reason="step_limit_reached")
    # ... une étape de raisonnement/outil ...

Surveiller la facture au niveau plateforme

Sur Vertex AI et Google Cloud, définissez un budget et des alertes de budget pour être notifié (ou déclencher un plafonnement automatique) avant que la dépense ne franchisse un seuil. Une alerte de facturation est votre dernière ligne de défense quand un guardrail dans le code a été oublié. Pour un usage par clé API depuis AI Studio, surveillez la consommation dans la console et faites tourner les clés qui fuient. Les budgets n'arrêtent pas la dépense par eux-mêmes : associez-les aux plafonds dans le code ci-dessus.

Vérification des acquis

1. Selon la leçon, pourquoi les review gates, les scopes et les budgets doivent-ils être traités comme trois contrôles distincts ?

2. Quelle est la différence pratique clé entre les scopes « gmail.compose » et « gmail.send », et pourquoi la leçon recommande-t-elle « compose » par défaut ?

3. La leçon décrit un agent non supervisé comme « un employé junior qui a vos credentials et aucun manager ». Quel est le sens visé par cette analogie ?

CHOIX MULTIPLES

4. Sélectionnez TOUS les exemples ci-dessous qui relèvent du mode de défaillance « accès trop large » ou de la bonne façon de le prévenir.

Sélectionnez toutes les réponses correctes.

CHOIX MULTIPLES

5. Sélectionnez TOUTES les affirmations qui reflètent le principe d'octroi de permissions minimales tel que décrit dans la leçon.

Sélectionnez toutes les réponses correctes.

Mise en pratique : un rapport hebdomadaire sous review gate

Voici comment les trois contrôles se combinent dans une automatisation réaliste. Une automatisation hebdomadaire lit un Sheet de ventes, rédige un email de synthèse pour la direction, et attend l'approbation.

  • Scope : Apps Script avec spreadsheets.currentonly et gmail.compose. Il peut lire ce seul sheet et créer un brouillon. Il ne peut pas envoyer, ni toucher aux autres fichiers.
  • Coût : Flash pour la synthèse (Pro est surdimensionné pour « résume ce tableau »). Un appel par semaine, avec le sheet réduit au dernier trimestre, pas tout l'historique.
  • Review gate : la sortie est un brouillon Gmail adressé à la direction. Une personne le lit lundi matin et l'envoie, le modifie ou le supprime.

Aucune partie de ce dispositif ne peut envoyer un email à qui que ce soit, dépenser de façon significative ou modifier des données sans un humain. C'est l'objectif : une automatisation dont la *pire défaillance réaliste* est un brouillon que quelqu'un supprime. Concevez chaque agent pour que son mode de défaillance soit inoffensif par construction, pas en espérant que le modèle se tienne bien.

Logging : le guardrail dont vous n'avez besoin qu'une fois

Loggez chaque action de l'agent : l'entrée, le modèle et les tokens utilisés, l'action proposée, et si un humain l'a approuvée. Quand quelque chose se passe mal (et cela finira par arriver), le log est ce qui permet de savoir ce qui s'est passé et de prouver ce qui ne s'est pas passé. Dans Apps Script, écrivez dans un sheet de log dédié ou faites console.log vers Cloud Logging. Sur Vertex AI, utilisez les callbacks de l'ADK pour capturer chaque appel d'outil. Une action que votre système ne peut pas expliquer est une action à laquelle vous ne pouvez pas faire confiance.

Points clés

  • Le scope avant le comportement. Accordez le scope OAuth ou le rôle IAM le plus étroit qui fonctionne (gmail.compose et non gmail.send, un dataset et non le projet), et faites tourner une identité par agent pour que l'audit log soit lisible.
  • Rendez le mode de défaillance inoffensif. Construisez les agents pour que le pire résultat réaliste soit un *brouillon* qu'un humain supprime. N'automatisez jamais sans supervision les envois, suppressions, paiements, déploiements ou octrois d'accès.
  • Appliquez les gates dans le code, pas dans le prompt. Laissez le modèle signaler le risque par commodité, mais placez les vraies règles « escalade toujours » dans votre flux de contrôle, là où une prompt injection ne peut pas les inverser.
  • Flash par défaut, boucle plafonnée. Utilisez Gemini Flash sauf si une étape nécessite Pro, cachez le contexte répété, réduisez ce que vous envoyez, et fixez une limite d'itérations dure pour qu'aucun run ne parte en vrille.
  • Appuyez-vous sur les budgets plateforme et les logs. Les alertes de facturation Cloud rattrapent ce que votre code laisse passer, et un log d'actions complet est ce qui vous permet de faire confiance à l'automatisation (ou de la révoquer) plus tard.