Keyboard shortcuts

Press ← or → to navigate between chapters

Press ? to show this help

Press Esc to hide this help

Gestion de l’historique

Le runtime conserve l’historique de conversation pour chaque session d’agent et envoie au modèle un historique de travail destiné au fournisseur. Deux limites complémentaires opèrent sur des représentations différentes :

  1. L’élagage du budget de jetons agit sur l’historique de travail ChatMessage exposé au fournisseur et supprime les tours complets les plus anciens jusqu’à ce que le contexte estimé tienne dans le budget de jetons.
  2. Conservation de tours complets applique la limite d’historique configurée dans le profil d’exécution à l’historique structuré Agent::history (ConversationMessage) ainsi qu’à l’historique ChatMessage destiné au fournisseur, utilisé par la boucle d’agent héritée.

Les deux limites conservent les tours de manière atomique. Un tour commence à un véritable message utilisateur et comprend la réponse de l’assistant, ainsi que les appels d’outils et leurs résultats, jusqu’au message utilisateur suivant. L’élagage ne sépare donc jamais un appel d’outil de son résultat. Un message utilisateur dont le texte commence par [Tool results] est traité comme faisant partie du tour précédent, et non comme un nouveau tour.

Rétention sur l’ensemble du tour

history_trim::trim_to_recent_turns applique le budget de tokens. history_trim::trim_to_recent_turn_count et history_trim::trim_conversation_to_recent_turns appliquent la limite de tours configurée pour les deux représentations de l’historique. Chacune conserve le tour complet le plus récent même lorsque la valeur configurée est 0. Ce comportement est intentionnel : préserver un tour courant complet est plus sûr que d’abandonner ses messages les plus récents ou de casser un échange d’outil.

Les messages système en tête sont conservés. Lorsqu’aucun rognage n’est nécessaire, l’ordre et la structure des messages restent inchangés.

Budget de jetons

Le budget de tokens provient de ResolvedRuntime::effective_context_budget() :

  • Les profils existants conservent le budget historique de 32 000 tokens lorsque ni max_context_tokens ni context_compact_ratio n’est défini, plafonné par la capacité configurée du modèle sélectionné lorsque cette capacité est inférieure.
  • max_context_tokens reste un budget absolu. Une valeur explicite de 0 désactive la réduction proactive basée sur le budget de tokens.
  • Définir context_compact_ratio active un budget relatif au modèle : la valeur context_window de l’alias/modèle du fournisseur sélectionné (ou un repli à 32 000 lorsque sa capacité est inconnue), multipliée par le ratio. Les valeurs en dehors de (0.0, 1.0] sont traitées comme non définies. Lorsque les deux paramètres sont présents, max_context_tokens constitue un plafond à la baisse sur le budget dérivé du ratio.
  • Lorsque history_pruning.enabled est défini avec une valeur positive pour history_pruning.max_tokens, cette valeur réduit le budget (jamais à la hausse), ce qui permet aux opérateurs de tronquer plus tôt.
  • Chaque budget effectif positif est plafonné par la capacité configurée du modèle sélectionné. La valeur de repli 32 000 est un stub de compatibilité, et non la réalité du modèle : lorsque le profil du fournisseur ne déclare aucun context_window et que le profil d’exécution définit un max_context_tokens positif, ce budget est respecté et devient également l’opérande de fenêtre (de sorte qu’un ratio s’applique à lui) au lieu d’être ramené à 32 000. La valeur sentinelle zéro explicite reste zéro et continue de désactiver la réduction proactive.

Le budget effectif est une cible de réduction proactive, et non une limite stricte de requête. Après avoir supprimé tous les anciens tours éligibles, le runtime conserve le tour complet le plus récent, même s’il dépasse toujours cette cible. Il envoie la requête lorsque les messages préparés, les images, les hooks et les schémas d’outils tiennent dans la fenêtre de contexte du modèle résolue. Une requête qui dépasse encore cette capacité échoue avant l’envoi au fournisseur ; augmenter seule la cible proactive ne peut pas la rendre acceptable. Cette vérification de capacité s’applique également lorsque la réduction proactive est désactivée (max_context_tokens = 0) ainsi qu’à la requête de résumé finale, après l’atteinte de la limite d’itérations des outils.

La capacité et le budget sont résolus ensemble pour la route provider/modèle active. Les indices du classifieur et les changements de session explicites utilisent la même sélection de route que l’envoi au provider, de sorte que le prochain appel au modèle, la réduction proactive du contexte, le diagnostic de dépassement, l’imputation des coûts et la jauge de contexte côté client utilisent le provider/modèle sélectionné et sa paire résolue. Si le modèle sélectionné ne correspond pas au modèle configuré sur le profil du provider, la capacité est considérée comme inconnue plutôt que d’emprunter les métadonnées du profil pour un autre modèle. La valeur de repli de compatibilité interne de 32 000 reste disponible pour les calculs de sécurité, mais les clients wire ne reçoivent aucune valeur model_context_window pour une capacité inconnue.

Les tokens sont estimés par history::estimate_history_tokens : environ quatre caractères par token, plus quatre tokens de structure par message. Il s’agit d’une heuristique, et non d’un tokenizer du fournisseur. Les marqueurs [IMAGE:...] chargeables ne sont facturés à un coût fixe par image que dans les messages dont les images sont transmises : les tours utilisateur et les résultats d’outils du tour utilisateur courant. Les images d’un résultat d’outil sont les pièces jointes déclarées par l’outil, et non le texte du marqueur dans sa sortie. Les résultats d’outils plus anciens sont comptés selon la taille en octets de leurs messages, et le texte système et le texte de l’assistant sont comptés comme du texte.

La réduction proactive du budget de jetons s’exécute avant le premier appel au fournisseur d’un tour lorsque l’historique dépasse déjà le budget effectif, ainsi qu’aux limites d’appel au fournisseur entre les itérations de la boucle d’outils. Si un fournisseur signale un dépassement de la fenêtre de contexte, le mécanisme de récupération réactif existant réessaie après une réduction aux deux tiers de la taille estimée actuelle de l’historique. Il ne dérive pas de nouvelle cible de récupération à partir de la capacité du modèle. Les deux chemins conservent des tours entiers, de sorte qu’aucun ne scinde un échange d’outil.

Limite du tour complet

max_history_messages est le nom historique du paramètre d’historique dans le profil d’exécution d’un agent. Dans les agents structurés et la boucle d’agent héritée, son unité est un tour utilisateur complet plutôt qu’une ligne de message individuelle. Les appels d’outils et les résultats d’outils restent intégrés à leur tour englobant et ne consomment pas d’emplacements indépendants.

La valeur par défaut est 50 tours. Une valeur explicitement configurée fait foi, y compris 0 ; le dernier tour complet est tout de même conservé. Le nom du champ est conservé pour la compatibilité du schéma et pourra être renommé dans une future version du schéma.

Les caches d’expéditeurs de canal constituent une exception distincte : ils comptent les lignes de messages individuelles et conservent leur comportement existant où 0 correspond à la valeur par défaut.

Rognage visible

Chaque fois que la réduction selon le budget de jetons ou la limite de tour complet supprime des tours plus anciens, le runtime :

  1. Insère un fil d’Ariane avant le premier tour conservé afin que le modèle sache que le contexte antérieur a été omis.
  2. Émet HistoryTrimmed avec le nombre de messages supprimés, le nombre de tours conservés et une raison indiquant le budget de jetons ou la limite de tours.

L’événement est exposé via le transport client actif et via le chemin d’observateur utilisé par les tableaux de bord et les abonnés aux événements. La suppression n’est donc pas limitée aux journaux et n’est pas silencieuse, ni pour le modèle ni pour les clients connectés.

Le chemin hérité agent::run dans loop_.rs signale l’élagage basé sur le nombre uniquement dans les journaux, sans le breadcrumb ni l’événement HistoryTrimmed. Ce chemin sert à l’usage interactif ainsi qu’aux appels ponctuels et non interactifs issus de daemon, cron, sous-agents et SOP.

Sécurité de l’appairage

La rétention par tour entier est la principale garantie d’appariement des outils : un appel d’outil et son résultat appartiennent au même tour et sont conservés ou supprimés ensemble. Le balayage des orphelins reste un filet de sécurité final pour les historiques déjà incohérents, tels que les sessions restaurées ou modifiées en externe.

Les limites de longueur des résultats d’outils sont distinctes. max_tool_result_chars borne un résultat individuel lors de son enregistrement ; cela n’élague pas l’historique de la conversation. L’application du contexte côté fournisseur est également distincte, bien qu’un débordement du fournisseur puisse déclencher l’élagage réactif du budget de tokens du runtime.