AI

Azure AI Search : diagnostiquer un échec partiel d'indexer avant le reset

Un runbook de production pour séparer source, tracking, skillset et erreurs documentaires dans Azure AI Search avant rerun, reprise ciblée ou reset de l'indexer.

06 oct. 2026 azureai-searchindexerretrievalragmicrosoft-foundryskillsetobservabilityagentopsrunbookrollbackproduction

Un agent d’exploitation commence à retourner des procédures incomplètes après qu’un indexer Azure AI Search nocturne a terminé en succès partiel. La majorité des documents a été traitée, quelques éléments ont échoué et l’index continue à répondre. Le réflexe consiste souvent à reset l’indexer puis à tout reconstruire.

Cette action efface le suivi incrémental et transforme une panne documentaire bornée en retraitement global. Elle peut augmenter la charge d’enrichissement, écraser des documents sains et laisser le corpus dans un nouvel état mixte sans expliquer les premiers échecs. Le cas fil rouge est un corpus de runbooks stocké dans Azure Blob Storage, enrichi par un skillset et consommé par un agent Microsoft Foundry. L’objectif est de restaurer la complétude sans perdre les preuves nécessaires pour choisir rerun incrémental, reprise ciblée, quarantaine ou reset complet.

Figer le run touché et l’impact utilisateur

Partez d’une exécution précise, pas du dernier badge de statut. Relevez l’indexer, l’index, la source, le skillset, la fenêtre d’exécution, le changement de configuration, les compteurs traités et en échec, puis les parcours de retrieval affectés.

yaml incident-indexer.yml
incident:
detected_utc: 2026-10-06T14:20:00Z
search_service: search-ops-prod
indexer: runbooks-blob-indexer
target_index: runbooks-v12
datasource: runbooks-prod
skillset: runbooks-enrichment-v7
execution_start_utc: 2026-10-06T13:00:03Z
execution_status: transientFailure
items_processed: 1842
items_failed: 17

impact:
missing_document_keys: pending
affected_journeys: [incident_triage, rollback_lookup]
agent_mode: read_only_with_corpus_warning

change_window:
source_release: docs-2026-10-06.2
indexer_definition_digest: <sha256>
skillset_definition_digest: <sha256>

N’assimilez pas 17 échecs à 17 documents absents. Un élément source peut produire plusieurs documents de recherche, écraser une ancienne version ou échouer après une partie de l’arbre d’enrichissement. Inversement, l’index peut conserver une version périmée issue d’un run précédent. Validez l’impact par clé documentaire et version attendue.

Lire l’historique avant de modifier l’état

Le statut global indique si l’objet indexer peut fonctionner. Chaque exécution possède son propre résultat, ses listes d’erreurs et d’avertissements, ses compteurs et ses états de tracking. Capturez la réponse avant qu’un reset ajoute une entrée ou qu’un run planifié plus récent chasse les preuves utiles.

bash 01-capturer-statut-indexer.sh
SERVICE="search-ops-prod"
INDEXER="runbooks-blob-indexer"
API_VERSION="2024-07-01"
TOKEN="<entra-access-token>"

curl -sS \
-H "Authorization: Bearer $TOKEN" \
"https://$SERVICE.search.windows.net/indexers/$INDEXER/status?api-version=$API_VERSION" \
> indexer-status-before-action.json

jq '{
status,
lastResult,
executionHistory: [.executionHistory[] | {
  status, startTime, endTime, itemsProcessed, itemsFailed,
  initialTrackingState, finalTrackingState, errors, warnings
}]
}' indexer-status-before-action.json

Conservez la réponse brute dans les preuves restreintes de l’incident. Regroupez les échecs par code, message, clé documentaire et nom du skill. Des échecs répétés au même étage pointent vers un défaut déterministe ; des timeouts dispersés suggèrent une dépendance ou une pression de capacité.

Les warnings comptent lorsqu’ils retirent du contenu dont dépend un agent. Champ tronqué, format non supporté, entrée de skill manquante ou warning de projection peuvent préserver un run vert tout en dégradant le retrieval.

Séparer quatre plans de panne

Lisez le pipeline comme quatre contrats :

text plans-panne-indexer.txt
1. Accès source
 Identité, réseau, throttling, disponibilité des objets et change detection

2. Tracking incrémental
 High-water mark, timestamps, suivi des suppressions et fin du run précédent

3. Transformation
 Parsing, field mappings, entrées de skills, réponses des custom skills et projections

4. Index cible
 Compatibilité du schéma, validité des clés, dimensions vectorielles,
 taille documentaire et capacité d'écriture

Preuve requise pour chaque élément en échec
 identifiant source -> clé documentaire -> étage fautif -> code d'erreur
 -> version attendue -> version indexée -> visibilité dans le retrieval

Un 403 sur la source ne se corrige pas en modifiant un champ d’index. Une dimension vectorielle incohérente ne se répare pas en ouvrant un firewall. Un timeout de custom skill ne prouve pas que le document source est corrompu. Gardez ces frontières explicites pour préserver la plus petite action corrective.

Pour les custom skills, corrélez la fenêtre d’exécution avec les logs de la dépendance grâce à l’identifiant d’opération ou de document. Mesurez la distribution des statuts et latences, pas seulement la moyenne. Une seule classe de documents lents peut consommer la fenêtre d’exécution pendant que les documents ordinaires réussissent.

Prouver ce qui manque réellement au corpus

Construisez un jeu de réconciliation depuis le manifeste source attendu, pas uniquement depuis le compteur d’échecs. Chaque élément doit posséder une clé stable, une version de contenu, un scope d’accès et une projection attendue.

json reconciliation-document.json
{
"sourceId": "runbooks/network/dns-042.md",
"sourceVersion": "sha256:<source-digest>",
"documentKey": "runbooks-network-dns-042",
"expectedProjection": "runbook-chunks",
"expectedChunkCount": 6,
"indexedVersion": "sha256:<indexed-digest>",
"indexedChunkCount": 4,
"retrievalState": "quarantined",
"failureStage": "skill.custom-metadata",
"errorCode": "WebApiSkillResponseError"
}

Interrogez l’index avec les clés et champs de version réellement employés par l’application. Rejouez ensuite des probes de retrieval représentatives. Un nombre de documents identique ne suffit pas si les métadonnées ACL, la langue, la version source ou un chunk critique manquent.

Tant que la complétude reste inconnue, rendez la dégradation visible. Excluez les clés fautives par filtre, routez les parcours sensibles vers le dernier alias qualifié ou placez l’agent en lecture seule avec un avertissement de fraîcheur. Une réponse fluide ne doit pas masquer une base de preuves incomplète.

Choisir la reprise la plus étroite

Un rerun normal conserve le tracking incrémental. Il convient aux erreurs transitoires que la source et les dépendances savent désormais traiter. Les indexers planifiés retentent aussi le travail dans le temps : prouvez qu’un nouveau run borné ne suffit pas avant de changer l’état.

La reprise documentaire ciblée est préférable lorsque les clés en échec sont connues et que le reset sélectif est approuvé. Validez la correspondance entre identifiants source et clés d’index, surtout lorsqu’un blob produit plusieurs documents. Une clé erronée peut donner une opération propre tout en laissant le contenu fautif inchangé.

Le reset complet efface le high-water mark et force le prochain run à retraiter tous les documents. Il ne se justifie que si le tracking est invalide, si un changement global exige une régénération complète ou si le périmètre ne peut pas être borné. Le reset ne lance pas l’indexer, ne peut pas être annulé et ne supprime pas les documents orphelins absents de la source.

yaml decision-reprise.yml
normal_rerun:
when: [failures_are_transient, tracking_state_is_credible]

targeted_recovery:
when: [exact_keys_are_known, key_mapping_is_verified, selective_reset_is_approved]
controls: [snapshot_status, canary_two_documents, resume_regular_tracking]

full_reset:
when: [tracking_state_is_invalid, pipeline_wide_regeneration_is_required]
requires:
  - capacity_window
  - source_and_skill_dependency_readiness
  - qualified_index_or_alias_return_path
  - orphan_cleanup_plan

N’augmentez pas maxFailedItems comme premier correctif. Ce paramètre décide si le traitement continue ; il ne rend pas le contenu valide. Utilisez-le seulement avec un objectif de complétude, un seuil d’alerte et un chemin de quarantaine explicites.

Canaryer le correctif hors du corpus de production

Reproduisez un élément sain et deux échecs représentatifs vers un index jetable ou un index candidat versionné. Figez les octets source, la définition de l’indexer, le skillset, le schéma et les versions des dépendances.

Le canari doit prouver que les chunks attendus existent, que version source et métadonnées d’accès sont correctes, qu’aucune projection périmée ne subsiste, que l’agent retrouve la bonne preuve, qu’un document hors scope reste inaccessible et que la latence tient dans la fenêtre d’exploitation.

Promouvez via un alias d’index ou une configuration équivalente après ces contrôles. Si l’index existant est réparé en place, conservez un export des définitions et le dernier index qualifié jusqu’à la fin de la réconciliation.

Valider la reprise et garder un rollback

Après le run borné, comparez jeu de clés en échec, compteurs, transition de tracking, versions indexées et probes de retrieval. Lancez un run incrémental supplémentaire : il ne doit traiter que les contenus réellement nouveaux ou modifiés, pas rejouer le même corpus sans explication.

text gate-reprise-indexer.txt
Promouvoir
Le jeu d'échecs est vide ou chaque exclusion est explicitement acceptée
Versions et projections correspondent au manifeste source
Probes de retrieval et de contrôle d'accès réussissent
Le prochain run reprend depuis un état de tracking crédible

Maintenir la quarantaine
Certaines clés ou projections restent inexpliquées
Le comportement d'une dépendance de skill reste intermittent
La fraîcheur du corpus ne peut pas être annoncée aux consommateurs

Rollback
Rebasculer l'application vers le dernier index ou alias qualifié
Restaurer les définitions précédentes d'indexer, skillset et schéma
Suspendre la nouvelle ingestion sur le chemin affecté
Conserver sources fautives et preuves d'exécution pour le rejeu

Le rollback n’est pas un nouveau reset aveugle. Il restaure un corpus et des définitions connus pendant que le jeu source fautif reste isolé. Si l’application ne sait pas changer d’index, réduisez le scope de retrieval et désactivez les parcours d’agent capables d’écrire jusqu’au rétablissement des preuves.

Conclusion

Un run Azure AI Search partiellement réussi est un incident d’intégrité du corpus, pas seulement une erreur de planification. Le diagnostic utile relie élément source, tracking, étage fautif, document cible et impact de retrieval avant toute modification d’état.

La décision reste volontairement étroite : rerun pour un échec transitoire, reprise ciblée lorsque les clés sont prouvées, quarantaine tant que la complétude est inconnue, reset uniquement si l’état incrémental ou tout le pipeline exige une régénération. La production est rétablie lorsque le run incrémental suivant se comporte normalement et que l’agent retrouve un corpus complet, autorisé et versionné.