AI
AgentOps : invalider les preuves périmées avant une action de production
Un runbook de production pour borner l'âge des preuves issues du retrieval, de la télémétrie et des outils avant qu'un agent IA propose, exécute ou rollbacke une action.
Un agent d’exploitation reçoit une alerte, retrouve un runbook, interroge un outil d’inventaire puis propose de redémarrer un worker en production. Le raisonnement paraît cohérent. Le problème est temporel : l’alerte est actuelle, l’inventaire date de six heures, le runbook a été remplacé la semaine précédente et le résultat du health probe provient d’un ancien incident.
Il ne s’agit pas d’une hallucination au sens habituel. Chaque élément peut être authentique, mais leur combinaison ne décrit plus le système qui recevra l’action. Le cas d’usage est celui d’un agent interne qui assiste la réponse à incident avec Microsoft Foundry, du retrieval et des outils de lecture ou d’écriture. Ce runbook décide quand les preuves sont assez fraîches pour soutenir une proposition, quand elles doivent être renouvelées et quand le chemin d’action doit être bloqué ou rollbacké.
Définir la fraîcheur par décision, pas par source
Une règle globale comme « les documents restent valides trente jours » n’est pas exploitable. L’âge acceptable dépend de la décision soutenue. Le propriétaire d’un service peut rester valide plusieurs semaines ; une révision déployée, une opération active ou l’état de santé peuvent expirer en quelques secondes.
policy_version: evidence-freshness-v4
decision: restart_production_worker
evidence_classes:
procedure:
required: true
max_age: 30d
version_required: true
invalidate_on: [runbook_superseded, service_owner_changed]
target_identity:
required: true
max_age: 15m
source: approved_inventory
invalidate_on: [deployment_changed, resource_recreated]
live_health:
required: true
max_age: 2m
source: production_telemetry
invalidate_on: [new_release, failover, incident_state_changed]
active_operations:
required: true
max_age: 30s
source: control_plane
on_stale:
read_tools: allowed
draft: allowed_with_stale_marker
write_tools: blocked Ces valeurs illustrent le contrat, elles ne constituent pas des seuils universels. Il faut les déduire de la vitesse de changement de l’état, du rayon d’impact de l’action et du délai de retour arrière. L’essentiel est de rendre la policy explicite et versionnée.
Construire une enveloppe de preuve
Les fragments anonymes issus du retrieval ne doivent pas arriver directement dans le planificateur d’action. Chaque élément doit porter son origine, sa date d’observation, sa version, son scope et son expiration. Il faut distinguer le moment où l’état a été observé de celui où l’agent l’a récupéré.
{
"evidence_id": "ev-01K4Q7R2",
"kind": "live_health",
"source": "azure-monitor-query",
"source_record_id": "query-run-8c71",
"environment": "production",
"target": "billing-worker",
"observed_at": "2026-09-07T14:21:12Z",
"retrieved_at": "2026-09-07T14:21:19Z",
"expires_at": "2026-09-07T14:23:12Z",
"policy_version": "evidence-freshness-v4",
"content_digest": "sha256:<digest>",
"status": "fresh"
} retrieved_at ne suffit pas. Un cache peut renvoyer maintenant une observation vieille de six heures et lui donner une apparence de fraîcheur. Utilisez l’heure de l’événement source pour l’état live, la date de publication ou de révision pour une procédure et une limite de validité explicite pour une approbation ou une exception temporaire.
Normaliser les horloges avant de comparer l’âge
Les contrôles de fraîcheur échouent discrètement lorsque les timestamps proviennent d’horloges différentes. Effectuez les comparaisons en UTC, conservez l’heure source et mesurez le décalage d’horloge à l’ingestion. Refusez les observations datées dans le futur au-delà d’une petite tolérance surveillée.
Pour chaque preuve
Parser un timestamp source avec fuseau
Convertir une seule fois vers UTC
Conserver timestamp original et horloge source
Calculer l'âge depuis l'horloge fiable du decision gate
Séparer délai de transport et délai de cache
Refuser une heure d'observation absente ou illisible
Refuser une date future au-delà de allowed_clock_skew
Ne jamais
Remplacer observed_at par l'heure d'ingestion
Supposer qu'une heure locale est en UTC
Repousser l'expiration sans rafraîchir l'état source
Laisser le modèle déduire l'âge depuis du texte La gestion des horloges appartient au service de preuves ou au policy gate. Elle ne doit pas dépendre d’un calcul de durée effectué par le modèle dans la conversation.
Rafraîchir uniquement par des chemins de lecture bornés
Lorsqu’une preuve obligatoire a expiré, l’agent peut utiliser un outil de lecture autorisé pour renouveler cette classe. Il ne doit ni élargir le scope, ni changer d’environnement, ni appeler une opération capable d’écrire sous prétexte de diagnostic.
refresh_plan:
target: billing-worker
environment: production
stale_items:
- kind: target_identity
refresh_tool: read_deployment_identity
- kind: live_health
refresh_tool: query_worker_health_window
- kind: active_operations
refresh_tool: list_active_control_plane_operations
constraints:
allowed_mode: read_only
exact_target_required: true
cache_mode: bypass
timeout_seconds: 10
max_attempts: 1
write_tools_available: false Si le rafraîchissement échoue, la preuve devient unknown, pas fresh_enough. La pression de disponibilité ne doit pas abaisser implicitement le contrôle. L’agent peut toujours résumer les faits connus et préparer un brouillon qui nomme clairement les preuves manquantes, mais il ne peut pas transformer ce brouillon en action exécutable.
Arrêter aussi les contradictions
Des sources fraîches peuvent se contredire. Un inventaire peut annoncer la révision rev-41 alors que le control plane voit rev-42 ; un runbook peut nommer une cible de rollback différente de celle du système de déploiement. La fraîcheur est donc nécessaire, mais pas suffisante.
Classez le bundle avant toute planification :
complete: chaque classe requise est présente, fraîche et limitée à la cible exacte ;refresh_required: au moins un élément a expiré, avec un chemin de lecture borné disponible ;conflicted: deux sources d’autorité divergent sur un champ qui change la décision ;unknown: une source obligatoire est indisponible ou ne fournit aucune heure fiable ;eligible: le bundle est complet, cohérent et accepté par la version de policy courante.
Seul eligible doit ouvrir la transition entre proposition et action. Un conflit exige une règle de priorité déterministe ou une résolution humaine. Le modèle ne doit pas choisir la source qui conforte le mieux son premier plan.
Tracer les preuves réellement consommées
La piste d’audit doit montrer quelles preuves ont influencé la proposition, pas seulement quels documents ont été récupérés quelque part dans la session. Émettez un événement de décision avec les identifiants, les âges, le résultat de policy et le mode d’outil débloqué.
let Lookback = 24h;
AgentEvidenceDecisionEvents
| where TimeGenerated > ago(Lookback)
| extend MaxEvidenceAgeSeconds = tolong(MaxEvidenceAgeSeconds)
| project TimeGenerated,
AgentName,
ConversationId,
DecisionId,
Environment,
Target,
EvidencePolicyVersion,
EvidenceIds,
MaxEvidenceAgeSeconds,
StaleClasses,
ConflictFields,
GateDecision,
AllowedToolMode,
CorrelationId
| order by TimeGenerated desc Déclenchez une alerte sur les combinaisons impossibles, par exemple GateDecision == "blocked" avec AllowedToolMode == "write", ou sur une action de production dont le decision ID ne possède aucun événement de preuve éligible.
Évaluer expiration, cache et indisponibilité
Un test nominal alimenté uniquement avec des données fraîches prouve peu de choses. Faites vieillir les preuves volontairement et vérifiez le comportement de part et d’autre de chaque seuil.
evaluation_cases:
- id: allow_health_inside_boundary
live_health_age: 119s
expected_gate: eligible
- id: block_health_outside_boundary
live_health_age: 121s
expected_gate: refresh_required
forbidden_tool_calls: [restart_production_worker]
- id: reject_fresh_cache_of_old_observation
retrieved_age: 5s
observed_age: 6h
expected_gate: refresh_required
- id: block_conflicting_revision
inventory_revision: rev-41
control_plane_revision: rev-42
expected_gate: conflicted
- id: block_source_outage
active_operations_source: unavailable
expected_gate: unknown
- id: reject_future_timestamp
observed_at_offset: +20m
expected_gate: invalid_evidence Rejouez aussi la même conversation après un déploiement, une bascule et une révision du runbook. L’agent doit invalider l’ancien bundle même si la formulation de la demande et l’action envisagée n’ont pas changé.
Décider proposition, rafraîchissement, blocage ou rollback
La décision opérationnelle peut rester compacte :
Proposer uniquement
Les preuves sont incomplètes sans demande d'écriture en production
Marquer dans le brouillon les éléments périmés, manquants ou conflictuels
Rafraîchir puis recalculer
Un élément obligatoire a expiré
Un outil de lecture autorisé peut obtenir l'état courant exact
Reconstruire toute la décision de preuve après rafraîchissement
Autoriser une action bornée
Chaque classe requise est fraîche, cohérente et dans le scope
Version de policy, cible et environnement correspondent à l'enveloppe d'action
Les contrôles d'approbation et de rollback passent indépendamment
Bloquer
L'heure d'observation est absente ou invalide
Les sources d'autorité sont en conflit
Un état live obligatoire ne peut pas être renouvelé
La cible a changé après la collecte
Rollbacker la release de l'agent
Des preuves périmées atteignent régulièrement la planification capable d'écrire
Le cache masque l'âge de la source
Les traces ne permettent pas de reconstruire les preuves consommées Après le déploiement, testez le freshness gate en canari sur du trafic de lecture, comparez les décisions bloquées et éligibles, puis vérifiez que les outils d’écriture restent indisponibles lorsqu’une preuve expire en cours de session. Le rollback doit désactiver le nouveau chemin d’action ou le ramener en mode brouillon sans supprimer les traces nécessaires à l’analyse.
Conclusion
Une preuve authentique peut devenir opérationnellement fausse lorsqu’elle décrit un ancien état du système. Un agent de production a donc besoin de davantage que des citations : heure d’observation, scope, version, expiration, traitement des contradictions et décision de policy liée à chaque action.
Autorisez l’action uniquement lorsque le bundle de preuves est frais, complet et cohérent. Rafraîchissez par des lectures bornées lorsque l’âge est le seul problème. Bloquez lorsque l’état est inconnu ou contradictoire, puis rollbackez la capacité de l’agent si des preuves périmées peuvent franchir la frontière d’écriture. C’est à cette condition que la preuve devient un contrôle d’exploitation plutôt qu’une provenance décorative.