Action is proposed as structured data (tool + args).
Le problème (côté prod)
Tu veux des writes. Ton agent veut des writes. Tes clients veulent que les writes soient corrects.
En démo : « l’agent peut juste fermer le ticket ». En prod : « juste » est la partie où tu expliques ensuite pourquoi 200 trucs sont cassés.
Les approvals ne sont pas un feature “enterprise”. C’est une soupape de sécurité quand ton décideur est probabiliste.
Pourquoi ça casse en prod
1) “Write tool” n’est pas une catégorie unique
Les writes ne se valent pas :
- réversible vs irréversible
- faible impact vs gros impact
- idempotent vs “oops, duplicate”
Si tu traites tout pareil, tu fais soit :
- trop d’approvals (UX meurt)
- pas assez (prod meurt)
2) Sans chemin d’approbation, tu deviens autonome par accident
Si un write tool est dans l’allowlist et rien ne l’arrête, il sera utilisé. Pas “peut-être”. Dès que c’est le chemin le plus court.
3) Approval sans contexte = inutile
“Approve ce tool call ?” ne suffit pas. Il faut de l’evidence :
- action proposée
- args (ou diff)
- pourquoi l’agent pense que c’est bon
- raison de policy / risque
Exemple d’implémentation (code réel)
Un gate minimal :
- write tools → approval request
- approval signé (id/key)
- tool gateway exécute seulement si approval valide
from dataclasses import dataclass
from typing import Any
WRITE_TOOLS = {"ticket.close", "db.write", "email.send"}
@dataclass(frozen=True)
class Approval:
approval_id: str
approved: bool
approved_by: str
class ApprovalRequired(RuntimeError):
pass
def requires_approval(tool: str) -> bool:
return tool in WRITE_TOOLS
def tool_gateway_call(tool: str, args: dict[str, Any], *, approval: Approval | None) -> Any:
if requires_approval(tool):
if not approval or not approval.approved:
raise ApprovalRequired(f"approval_required:{tool}")
return call_tool(tool, args) # (pseudo)const WRITE_TOOLS = new Set(["ticket.close", "db.write", "email.send"]);
export class ApprovalRequired extends Error {}
export function requiresApproval(tool) {
return WRITE_TOOLS.has(tool);
}
export function toolGatewayCall(tool, args, { approval } = {}) {
if (requiresApproval(tool)) {
if (!approval || approval.approved !== true) throw new ApprovalRequired("approval_required:" + tool);
}
return callTool(tool, args); // (pseudo)
}Incident réel (avec chiffres)
On avait un agent pour “nettoyer” des tickets support. Un changement de prompt a interprété “cleanup” comme “close”.
Impact :
- 63 tickets fermés alors qu’ils devaient rester ouverts
- ~2 heures pour rouvrir + s’excuser
- on a mis l’agent en read-only une semaine, le temps de reconstruire la confiance
Fix :
- approvals sur writes high-impact
- UI d’approbation avec diff/evidence (pas juste “approve?”)
- idempotency keys pour éviter les doubles exécutions
Compromis
- Les approvals ajoutent de la latence. C’est le prix de la sécurité.
- Trop d’approvals tue l’UX → il faut des risk tiers.
- Un système d’approbation sans audit logs te laisse sans preuve en incident.
Quand NE PAS l’utiliser
- Pas besoin d’approvals pour des tools read-only.
- Pour des writes low-risk et totalement réversibles, un auto-approve sous budgets stricts peut être OK.
- Si personne ne review réellement : ce n’est pas un approval, c’est du théâtre.
Checklist (copier-coller)
- [ ] Identifier les write tools (capability-based)
- [ ] Approvals pour actions irréversibles / high impact
- [ ] Evidence dans l’UI (diff, why, provenance)
- [ ] Enforcement dans le tool gateway (pas seulement dans le frontend)
- [ ] Idempotency keys par action approuvée
- [ ] Audit logs (who approved what)
Config par défaut sûre (JSON/YAML)
approvals:
required_for:
- "db.write"
- "email.send"
- "ticket.close"
evidence:
include_args: true
include_diff: true
enforce_in: "tool_gateway"
FAQ (3–5)
Utilisé par les patterns
Pannes associées
Gouvernance requise
Q: Quand les approvals sont vraiment nécessaires ?
A: Quand l’action est coûteuse/irréversible ou modifie des données client. Par défaut : writes → approval.
Q: Comment éviter le spam d’approvals ?
A: Risk tiers + escalader seulement le high-risk. Et garder les write tools petits (pas de RPC générique).
Q: Je peux automatiser des approvals ?
A: Partiellement : auto-approve low-risk sous budgets stricts. Mais logge en “auto-approved”.
Q: Où enforce les approvals ?
A: Dans le tool gateway. Si c’est seulement dans l’UI, ça sera contourné.
Pages liées (3–6 liens)
- Foundations: What makes an agent production-ready · How agents use tools
- Failure: Prompt injection attacks · Cascading tool failures
- Governance: Tool permissions · Kill switch design
- Production stack: Production agent stack