Compactage

À mesure que les conversations grandissent, le nombre de jetons de l'historique des conversations peut dépasser les fenêtres contextuelles du modèle, ou bien entraîner une augmentation des coûts. Les stratégies de compactage réduisent la taille de l’historique des conversations tout en préservant un contexte important, afin que les agents puissent continuer à fonctionner sur des interactions longues.

Important

L’infrastructure de compactage est actuellement expérimentale. Pour l’utiliser, vous devez ajouter #pragma warning disable MAAI001.

Important

L’infrastructure de compactage est actuellement expérimentale en Python. Importer des types de compactage à partir de agent_framework.

Go prend en charge le compactage via le package agent/compaction. Inscrivez une stratégie de compactage en tant que agent.ContextProvider telle afin qu’elle puisse compacter l’historique des sessions avant chaque exécution.

Pourquoi le compactage est important

Chaque appel à un LLM inclut l’historique complet des conversations. Sans compactage :

  • Limites de jetons : les conversations dépassent finalement la fenêtre de contexte du modèle, ce qui provoque des erreurs.
  • Coût : les invites plus volumineuses consomment davantage de jetons, ce qui augmente les coûts d’API.
  • Latence : plus de jetons d’entrée signifient des temps de réponse plus lents.

Le compactage résout ces problèmes en supprimant, en réduisant ou en récapitulant les parties plus anciennes de la conversation.

Concepts de base

Applicabilité : agents d’historique en mémoire uniquement

Le compactage s’applique uniquement aux agents qui gèrent leur propre historique de conversations en mémoire. Les agents qui s’appuient sur un contexte ou un état de conversation gérés par le service ne bénéficient pas du compactage, car ce dernier en assure déjà la gestion. Voici quelques exemples d’agents gérés par le service :

  • Agents Foundry : le contexte est géré par le serveur par le service Microsoft Foundry.
  • API de Réponses avec stockage activé (valeur par défaut) : l’état de conversation est stocké et géré par le service OpenAI.
  • Agents Copilot Studio : le contexte de conversation est géré par le service Copilot Studio.

Pour ces types d’agents, la configuration d’une stratégie de compactage n’a aucun effet. Le compactage n’est pertinent que lorsque l’agent conserve sa propre liste de messages en mémoire et passe l’historique complet au modèle sur chaque appel.

Le compactage fonctionne sur une MessageIndex — une vue structurée d'une liste plate de messages qui regroupe les messages en unités atomiques, appelées instances de MessageGroup. Chaque groupe suit son nombre de messages, son nombre d’octets et son nombre estimé de jetons.

Groupes de messages

Un MessageGroup représente les messages liés logiquement qui doivent être conservés ou supprimés ensemble. Par exemple, un message d’assistant contenant des appels d’outil et ses messages de résultat d’outil correspondants forment un groupe atomique : la suppression d’un message sans l’autre entraînerait des erreurs d’API LLM.

Chaque groupe a un MessageGroupKind:

Type Description
System Un ou plusieurs messages système. Est toujours conservé pendant le compactage.
User Message d’utilisateur unique qui démarre un nouveau tour.
AssistantText Réponse texte simple de l’Assistant (aucun appel d’outil).
ToolCall Un message d'assistant avec des appels d’outils et les messages de résultat de l’outil correspondants, traités en tant qu'unité atomique.
Summary Message condensé produit par un compactage de synthèse.

Déclencheurs

Un CompactionTrigger est un délégué qui évalue si le compactage devrait se poursuivre en fonction des métriques actuelles MessageIndex.

public delegate bool CompactionTrigger(MessageIndex index);

La CompactionTriggers classe fournit des méthodes de fabrique courantes :

Déclencheur Se déclenche quand
CompactionTriggers.Always Chaque fois (sans condition).
CompactionTriggers.Never Jamais (désactive le compactage).
CompactionTriggers.TokensExceed(maxTokens) Le nombre de jetons inclus dépasse le seuil.
CompactionTriggers.MessagesExceed(maxMessages) Le nombre de messages inclus dépasse le seuil.
CompactionTriggers.TurnsExceed(maxTurns) Le nombre de tours d'utilisateur inclus dépasse le seuil.
CompactionTriggers.GroupsExceed(maxGroups) Le nombre de groupes inclus dépasse le seuil.
CompactionTriggers.HasToolCalls() Il existe au moins un groupe d’appels d’outil qui n’est pas exclu.

Combiner des déclencheurs avec CompactionTriggers.All(...) (AND logique) ou CompactionTriggers.Any(...) (OR logique) :

// Compact only when there are tool calls AND tokens exceed 2000
CompactionTrigger trigger = CompactionTriggers.All(
    CompactionTriggers.HasToolCalls(),
    CompactionTriggers.TokensExceed(2000));

Déclencheur et cible

Chaque stratégie a deux prédicats :

  • Déclencheur : contrôle quand commence le compactage. Si le déclencheur retourne false, la stratégie est ignorée entièrement.
  • Cible : contrôle quand le compactage s’arrête. Les stratégies excluent de façon incrémentielle les groupes et réévaluent la cible après chaque étape, s’arrêtant dès que la cible retourne true.

Lorsqu’aucun objectif n’est spécifié, il est défini par défaut sur l’inverse du déclencheur : le compactage s’arrête dès que la condition du déclencheur n’est plus remplie.

Le compactage fonctionne sur une liste plate d’objets Message. Les messages sont annotés avec des métadonnées de groupe léger et les stratégies mutent ces annotations en place pour marquer les groupes comme exclus avant que la liste des messages ne soit projetée vers le modèle.

Groupes de messages

Les messages sont regroupés en unités atomiques. Chaque groupe est affecté à un GroupKind:

Type Description
system Messages système. Est toujours conservé pendant le compactage.
user Message d’utilisateur unique.
assistant_text Réponse de texte d’assistant brut (aucun appel de fonction).
tool_call Un message assistant avec des appels de fonction ainsi que les messages de résultat de l’outil correspondants, traités comme une unité atomique.

Stratégies de compactage

Un CompactionStrategy est un protocole : tout async appelable qui accepte un list[Message] et le modifie sur place, en retournant True lorsqu'il a modifié quoi que ce soit.

class CompactionStrategy(Protocol):
    async def __call__(self, messages: list[Message]) -> bool: ...

Générateur de jetons

Les stratégies conscientes des jetons acceptent une TokenizerProtocol implémentation. L'outil intégré CharacterEstimatorTokenizer utilise une heuristique de 4 caractères par jeton :

from agent_framework import CharacterEstimatorTokenizer

tokenizer = CharacterEstimatorTokenizer()

Transmettez un tokenizer personnalisé lorsque vous avez besoin d’un nombre de jetons précis pour l’encodage d’un modèle spécifique.

Compactage s’exécute en tant que fournisseur de contexte. Les stratégies peuvent inspecter l’historique des sessions avant chaque exécution et réduire les groupes de messages plus anciens tout en préservant le contexte le plus récent.

Le paquet Go inclut des types de stratégie tels que ToolResultStrategy, SlidingWindowStrategy et PipelineStrategy, ainsi que des fonctions utilitaires de déclenchement telles que MessagesExceed et TurnsExceed.

Stratégies de compactage

Toutes les stratégies héritent de la classe de base abstraite CompactionStrategy . Chaque stratégie préserve les messages systèmes et respecte un MinimumPreserved seuil qui protège les groupes non-systémiques les plus récents contre la suppression.

Les stratégies de compactage sont importées à partir de agent_framework.

Les stratégies de compactage sont importées à partir de github.com/microsoft/agent-framework-go/agent/compaction.

StratégieDeCompactageParTroncature

StratégieDeTroncation

Approche la plus simple : supprime les groupes de messages non système les plus anciens jusqu’à ce que la condition cible soit remplie.

  • Respecte les limites des groupes atomiques (les messages d’appel d’outil et de résultat sont supprimés ensemble).
  • Idéal pour les backstops de budget de jetons durs.
  • MinimumPreserved a la valeur par défaut 32.
// Drop oldest groups when tokens exceed 32K, keeping at least 10 recent groups
TruncationCompactionStrategy truncation = new(
    trigger: CompactionTriggers.TokensExceed(0x8000),
    minimumPreserved: 10);
  • Lorsqu’un tokenizer est fourni, la métrique est le nombre de jetons ; sinon, la métrique est le nombre de messages.
  • preserve_system a la valeur par défaut True.
from agent_framework import CharacterEstimatorTokenizer, TruncationStrategy

# Exclude oldest groups when tokens exceed 32 000, trimming to 16 000
truncation = TruncationStrategy(
    max_n=32_000,
    compact_to=16_000,
    tokenizer=CharacterEstimatorTokenizer(),
)

SlidingWindowCompactionStrategy

SlidingWindowStrategy

Supprime le contenu de conversation plus ancien pour conserver uniquement la fenêtre la plus récente des échanges, respectant les unités de conversation logiques plutôt que le nombre de messages arbitraires. Les messages système sont conservés dans l’ensemble.

  • Idéal pour limiter la longueur des conversations de manière prévisible.

Supprime les utilisateurs les plus anciens et leurs groupes de réponse associés, fonctionnant sur des limites de tour logique plutôt que sur des groupes individuels.

  • Un tour commence par un message utilisateur et inclut tous les groupes d’assistants et d’appels d’outils suivants jusqu’au message utilisateur suivant.
  • MinimumPreserved utilise par défaut 1 (ce qui préserve au moins le groupe non système le plus récent).
// Keep only the last 4 user turns
SlidingWindowCompactionStrategy slidingWindow = new(
    trigger: CompactionTriggers.TurnsExceed(4));

Conserve uniquement les groupes non système les plus récents keep_last_groups , à l’exclusion de tout ce qui est plus ancien.

  • preserve_system a la valeur par défaut True.
from agent_framework import SlidingWindowStrategy

# Keep only the last 20 non-system groups
sliding_window = SlidingWindowStrategy(keep_last_groups=20)

StratégieDeCompactionDesRésultatsOutil

Réduit les groupes d'appels d'outils plus anciens en messages récapitulatifs compacts, en conservant une trace lisible sans la lourdeur complète des messages.

  • Ne touche pas les messages utilisateur ni les réponses d’assistant simple.
  • Il est préférable d'adopter une stratégie préliminaire pour récupérer de l'espace à partir des résultats détaillés des outils.
  • Remplace les groupes d’appels d’outils multi-messages (appel d’assistant + résultats de l’outil) par un résumé court comme [Tool calls: get_weather, search_docs].
  • MinimumPreserved par défaut à 2, ce qui garantit que les interactions de l'outil actuel restent visibles.
// Collapse old tool results when tokens exceed 512
ToolResultCompactionStrategy toolCompaction = new(
    trigger: CompactionTriggers.TokensExceed(0x200));
  • Se réduit à des messages récapitulatifs compacts tels que [Tool results: get_weather: sunny, 18°C].
  • Les groupes d’appels d’outils les plus récents keep_last_tool_call_groups sont laissés inchangés.
from agent_framework import ToolResultCompactionStrategy

# Collapse all but the newest tool-call group
tool_result = ToolResultCompactionStrategy(keep_last_tool_call_groups=1)

StratégieDeCompactageParRésumé

StratégieDeRésumé

Utilise un LLM pour synthétiser les anciennes parties de la conversation, en les remplaçant par un seul message de synthèse.

  • Une invite par défaut conserve les faits clés, les décisions, les préférences utilisateur et les résultats des appels d’outil.
  • Nécessite un client LLM distinct pour résumer : un modèle plus petit et plus rapide est recommandé.
  • Il est idéal pour préserver le contexte conversationnel tout en réduisant considérablement le nombre de tokens.
  • Vous pouvez fournir une commande de synthèse personnalisée.
  • Protège les messages système et les groupes non système les plus récents MinimumPreserved (par défaut : 4).
  • Envoie les anciens messages à un autre IChatClient avec une instruction de synthèse, puis insère le résumé en tant que groupe MessageGroupKind.Summary.
// Summarize older messages when tokens exceed 1280, keeping the last 4 groups
SummarizationCompactionStrategy summarization = new(
    chatClient: summarizerChatClient,
    trigger: CompactionTriggers.TokensExceed(0x500),
    minimumPreserved: 4);

Vous pouvez fournir une demande de synthèse personnalisée :

SummarizationCompactionStrategy summarization = new(
    chatClient: summarizerChatClient,
    trigger: CompactionTriggers.TokensExceed(0x500),
    summarizationPrompt: "Summarize the key decisions and user preferences only.");
  • Se déclenche quand le nombre de messages non système inclus dépasse target_count + threshold.
  • Conserve les messages récents proches target_count, soumis aux limites du groupe de messages ; récapitule les groupes complets les plus anciens qui correspondent au budget d’entrée du récapitulateur.
  • Nécessite un SupportsChatGetResponse client.
  • Limite l’invite de synthèse et la transcription à 8 000 jetons estimés par défaut. Il sélectionne les groupes de messages complets. Un groupe n’est donc jamais fractionné pour s’adapter au budget.
  • Définissez max_summary_input_tokens=None pour désactiver la limite d’entrée du récapitulateur ou passer tokenizer= lorsque vous avez besoin d’un comptage de jetons spécifique au modèle. Si aucun groupe complet n’est adapté, la synthèse est ignorée et l’historique existant reste inchangé.
from agent_framework import SummarizationStrategy

# Summarize when non-system message count exceeds 6, retaining the 4 newest
summarization = SummarizationStrategy(
    client=summarizer_client,
    target_count=4,
    threshold=2,
)

Fournissez une invite de synthèse personnalisée :

summarization = SummarizationStrategy(
    client=summarizer_client,
    target_count=4,
    prompt="Summarize the key decisions and user preferences only.",
)

Contrôlez le budget de demande de synthèse indépendamment de la cible d’historique conservé :

from agent_framework import CharacterEstimatorTokenizer, SummarizationStrategy

summarization = SummarizationStrategy(
    client=summarizer_client,
    target_count=4,
    threshold=2,
    max_summary_input_tokens=16_000,
    tokenizer=CharacterEstimatorTokenizer(),
)

StratégieDeCompactageDuPipeline

Compose plusieurs stratégies dans un pipeline séquentiel. Chaque stratégie opère sur le résultat de la précédente, permettant une compaction progressive par couches, allant de légère à agressive.

  • Le propre déclencheur du pipeline est CompactionTriggers.Always : chaque stratégie enfant évalue son propre déclencheur indépendamment.
  • Les stratégies s’exécutent dans l’ordre, donc mettre les stratégies les plus douces en premier.
PipelineCompactionStrategy pipeline = new(
    new ToolResultCompactionStrategy(CompactionTriggers.TokensExceed(0x200)),
    new SummarizationCompactionStrategy(summarizerChatClient, CompactionTriggers.TokensExceed(0x500)),
    new SlidingWindowCompactionStrategy(CompactionTriggers.TurnsExceed(4)),
    new TruncationCompactionStrategy(CompactionTriggers.TokensExceed(0x8000)));

Ce pipeline :

  1. Décroît les anciens résultats de l’outil (léger).
  2. Résume les anciennes étendues de conversation (modérées).
  3. Conserve uniquement les 4 dernières interactions utilisateur (mode agressif).
  4. Supprime les groupes les plus anciens s’ils dépassent encore le budget (mesure de secours d’urgence).

SelectiveToolCallCompactionStrategy

Exclut entièrement les anciens groupes d'appels d'outils, en conservant uniquement le dernier keep_last_tool_call_groups.

  • Ne touche pas aux messages d'utilisateur ou de l'assistant basique.
  • Convient mieux lorsque le phénomène de vibration de l'outil prédomine l'utilisation des jetons et que l'historique complet de l'outil n'est pas nécessaire.
from agent_framework import SelectiveToolCallCompactionStrategy

# Keep only the most recent tool-call group
selective_tool = SelectiveToolCallCompactionStrategy(keep_last_tool_call_groups=1)

StratégieComposéeDeBudgetDeJetons

Compose plusieurs stratégies dans un pipeline séquentiel piloté par un budget de jeton. Chaque stratégie enfant s'exécute dans l'ordre et s'arrête dès que le budget est rempli. Un mécanisme de repli intégré exclut les groupes les plus anciens si les stratégies seules ne peuvent pas atteindre l'objectif.

  • Les stratégies s’exécutent dans l’ordre ; placez d’abord les stratégies les plus douces.
  • early_stop=True (valeur par défaut) s’arrête dès que le budget du jeton est satisfait.
from agent_framework import (
    CharacterEstimatorTokenizer,
    SelectiveToolCallCompactionStrategy,
    SlidingWindowStrategy,
    SummarizationStrategy,
    TokenBudgetComposedStrategy,
    ToolResultCompactionStrategy,
)

tokenizer = CharacterEstimatorTokenizer()

pipeline = TokenBudgetComposedStrategy(
    token_budget=16_000,
    tokenizer=tokenizer,
    strategies=[
        ToolResultCompactionStrategy(keep_last_tool_call_groups=1),
        SummarizationStrategy(client=summarizer_client, target_count=4, threshold=2),
        SlidingWindowStrategy(keep_last_groups=20),
    ],
)

Ce pipeline :

  1. Décroît les anciens résultats de l’outil (léger).
  2. Résume les anciennes étendues de conversation (modérées).
  3. Garde uniquement les 20 derniers groupes (agressifs).
  4. Revient à l'exclusion la plus ancienne si le budget est encore dépassé (mécanisme de sauvegarde d'urgence).

Utilisation du compactage avec un agent

Encapsulez une stratégie de compactage dans un CompactionProvider et enregistrez-la en tant que AIContextProvider. Passez soit une stratégie unique, soit un PipelineCompactionStrategy au constructeur.

Inscription auprès de l’API builder

Inscrivez le fournisseur sur ChatClientBuilder en utilisant UseAIContextProviders. Le fournisseur s’exécute à l’intérieur de la boucle d’appel d’outils, compactant les messages avant chaque appel LLM.

IChatClient agentChatClient = openAIClient.GetChatClient(deploymentName).AsIChatClient();
IChatClient summarizerChatClient = openAIClient.GetChatClient(deploymentName).AsIChatClient();

PipelineCompactionStrategy compactionPipeline =
    new(
        new ToolResultCompactionStrategy(CompactionTriggers.TokensExceed(0x200)),
        new SummarizationCompactionStrategy(summarizerChatClient, CompactionTriggers.TokensExceed(0x500)),
        new SlidingWindowCompactionStrategy(CompactionTriggers.TurnsExceed(4)),
        new TruncationCompactionStrategy(CompactionTriggers.TokensExceed(0x8000)));

AIAgent agent =
    agentChatClient
        .AsBuilder()
        .UseAIContextProviders(new CompactionProvider(compactionPipeline))
        .BuildAIAgent(
            new ChatClientAgentOptions
            {
                Name = "ShoppingAssistant",
                ChatOptions = new()
                {
                    Instructions = "You are a helpful shopping assistant.",
                    Tools = [AIFunctionFactory.Create(LookupPrice)],
                },
            });

AgentSession session = await agent.CreateSessionAsync();
Console.WriteLine(await agent.RunAsync("What's the price of a laptop?", session));

Tip

Utilisez un modèle plus petit et moins cher (par exemple gpt-4o-mini) pour le client de conversation de synthèse afin de réduire les coûts tout en conservant la qualité de résumé.

Si une seule stratégie est nécessaire, transmettez-la directement à CompactionProvider sans l’encapsuler dans un PipelineCompactionStrategy:

agentChatClient
    .AsBuilder()
    .UseAIContextProviders(new CompactionProvider(
        new SlidingWindowCompactionStrategy(CompactionTriggers.TurnsExceed(20))))
    .BuildAIAgent(...);

Inscription à travers ChatClientAgentOptions

Le fournisseur peut également être spécifié directement sur ChatClientAgentOptions.AIContextProviders:

AIAgent agent = agentChatClient
    .AsBuilder()
    .BuildAIAgent(new ChatClientAgentOptions
    {
        AIContextProviders = [new CompactionProvider(compactionPipeline)]
    });

Note

Lors de l'enregistrement via ChatClientAgentOptions, le CompactionProvidern'est pas engagé pendant la boucle d’appel d’outils. Les fournisseurs de contexte au niveau de l’agent s’exécutent avant le stockage de l’historique des conversations. Par conséquent, tous les messages de synthèse synthétiques générés par CompactionProvider peuvent faire partie de l’historique persistant lors de l’utilisation ChatHistoryProvider. Pour compacter uniquement le contexte de demande en cours tout en conservant l’historique stocké d’origine, inscrivez le fournisseur sur le ChatClientBuilder par UseAIContextProviders(...) à la place.

Compactage ad hoc

CompactionProvider.CompactAsync applique une stratégie à une liste de messages arbitraires sans session d’agent active :

IEnumerable<ChatMessage> compacted = await CompactionProvider.CompactAsync(
    new TruncationCompactionStrategy(CompactionTriggers.TokensExceed(8000)),
    existingMessages);

Configurez la stratégie de compactage et le générateur de jetons sélectionnés directement sur Agent. Les valeurs au niveau de l’agent remplacent les valeurs par défaut configurées sur le client de conversation sous-jacent, et un seul agent.run(...) appel peut remplacer les deux.

Inscription auprès d’un agent

from agent_framework import (
    Agent,
    CharacterEstimatorTokenizer,
    SlidingWindowStrategy,
    SummarizationStrategy,
    TokenBudgetComposedStrategy,
    ToolResultCompactionStrategy,
    TruncationStrategy,
)

tokenizer = CharacterEstimatorTokenizer()

strategy = TokenBudgetComposedStrategy(
    token_budget=16_000,
    tokenizer=tokenizer,
    strategies=[
        ToolResultCompactionStrategy(keep_last_tool_call_groups=1),
        SummarizationStrategy(client=summarizer_client, target_count=4, threshold=2),
        SlidingWindowStrategy(keep_last_groups=20),
    ],
)

agent = Agent(
    client=client,
    name="ShoppingAssistant",
    instructions="You are a helpful shopping assistant.",
    compaction_strategy=strategy,
    tokenizer=tokenizer,
)

session = agent.create_session()
print(await agent.run("What's the price of a laptop?", session=session))

Tip

Utilisez un modèle plus petit et moins cher (par exemple gpt-4o-mini) pour le client de synthèse afin de réduire les coûts tout en conservant la qualité de résumé.

Si une seule stratégie est nécessaire, transmettez-la directement :

agent = Agent(
    client=client,
    compaction_strategy=SlidingWindowStrategy(keep_last_groups=20),
    tokenizer=CharacterEstimatorTokenizer(),
)

Remplacer le compactage d’une exécution

compaction_strategy Passez et tokenizer à agent.run(...) quand une demande a besoin d’une stratégie différente :

response = await agent.run(
    "Summarize the rollout risks.",
    compaction_strategy=TruncationStrategy(max_n=8_000, compact_to=4_000),
    tokenizer=tokenizer,
)

Compactage ad hoc

apply_compaction applique une stratégie à une liste de messages arbitraire en dehors d’une session d’agent active :

from agent_framework import apply_compaction, TruncationStrategy, CharacterEstimatorTokenizer

tokenizer = CharacterEstimatorTokenizer()

compacted = await apply_compaction(
    messages,
    strategy=TruncationStrategy(
        max_n=8_000,
        compact_to=4_000,
        tokenizer=tokenizer,
    ),
    tokenizer=tokenizer,
)

Créez un fournisseur de contexte de compactage et ajoutez-le aux fournisseurs de contexte de l’agent :

import (
    "github.com/microsoft/agent-framework-go/agent"
    "github.com/microsoft/agent-framework-go/agent/compaction"
    "github.com/microsoft/agent-framework-go/provider/foundryprovider"
)

compactionProvider := compaction.NewContextProvider(compaction.ContextProviderConfig{
    Strategy: &compaction.PipelineStrategy{
        Strategies: []compaction.Strategy{
            &compaction.ToolResultStrategy{
                Trigger:                compaction.MessagesExceed(7),
                MinimumPreservedGroups: 4,
            },
            &compaction.SlidingWindowStrategy{
                Trigger:               compaction.TurnsExceed(4),
                MinimumPreservedTurns: 4,
            },
        },
    },
})

a := foundryprovider.NewAgent(endpoint, token, foundryprovider.ModelDeployment(model), foundryprovider.AgentConfig{
    Config: agent.Config{
        ContextProviders: []agent.ContextProvider{compactionProvider},
    },
})

Tip

Consultez l’exemple de pipeline de compactage pour obtenir un exemple exécutable complet.

Utiliser le compactage avec l’agent Harnais

La configuration manuelle ci-dessus donne un contrôle total sur l’endroit où un fournisseur de compactage s’exécute. L’agent Harness relie plutôt le compactage dans son pipeline d’historique des appels par service afin que de longues boucles d’appel d’outils puissent compacter entre les appels de modèle.

Le compactage est désactivé par défaut. Définissez les deux HarnessAgentOptions.MaxContextWindowTokens et MaxOutputTokens créez une valeur par défaut ContextWindowCompactionStrategy, ou définissez-le CompactionStrategy pour fournir votre propre stratégie.

HarnessAgent agent = chatClient.AsHarnessAgent(new HarnessAgentOptions
{
    MaxContextWindowTokens = 128_000,
    MaxOutputTokens = 16_384,
});

Le harnais exécute la stratégie résolue avant chaque appel de modèle dans la boucle d’appel de fonction. Lorsqu’il crée également la valeur par défaut InMemoryChatHistoryProvider, il configure ce fournisseur avec le réducteur de conversation de la stratégie. Un personnalisé ChatHistoryProvider est utilisé comme fourni. DisableCompaction = true remplace les paramètres du jeton et CompactionStrategydéfinit MaxOutputTokens toujours ChatOptions.MaxOutputTokens lorsque le compactage est activé ou désactivé.

chatClient.AsHarnessAgent(options) et new HarnessAgent(chatClient, options) utiliser le même HarnessAgentOptions.

Le compactage est désactivé par défaut, sauf si les deux max_context_window_tokens et max_output_tokens sont définis, ou une stratégie de phase personnalisée est fournie.

agent = create_harness_agent(
    client,
    max_context_window_tokens=128_000,
    max_output_tokens=16_384,
)

Avec les paramètres de jeton, le harnais réutilise un ContextWindowCompactionStrategy pour les deux phases : la phase antérieure s’exécute avant chaque appel de modèle à l’intérieur de la boucle outil, tandis que la phase après compacte l’historique persistant après l’exécution. Remplacez l’une des phases indépendamment par before_compaction_strategy ou ; définie tokenizer= pour un tokenizer personnalisé, history_provider= pour un autre magasin d’historique ou disable_compaction=True pour désactiver les after_compaction_strategydeux phases. max_output_tokens fournit également l’option de conversation par défaut max_tokens .

L’agent Harness n’est actuellement pas disponible dans le Kit de développement logiciel (SDK) Go. Inscrivez manuellement un fournisseur de contexte de compactage, comme indiqué ci-dessus.

Choix d’une stratégie

Strategy Agressivité Conserve le contexte Nécessite LLM Idéal pour
ToolResultCompactionStrategy Faible Élevé : réduit uniquement les résultats de l’outil Non Récupération d’espace depuis la sortie verbeuse de l’outil
SummarizationCompactionStrategy Moyenne Moyen : remplace l’historique par un résumé Yes Conversations longues où le contexte importe
SlidingWindowCompactionStrategy Élevé Faible : supprime les cycles entiers Non Limites strictes de comptage de tours
TruncationCompactionStrategy Élevé Faible — supprime les groupes les plus vieux Non Backstops de budget de jeton d’urgence
PipelineCompactionStrategy Paramétrable Dépend des stratégies des enfants Ça dépend Compactage en couches avec plusieurs solutions de repli
Strategy Agressivité Conserve le contexte Nécessite LLM Idéal pour
ToolResultCompactionStrategy Faible Élevé : réduit les résultats de l’outil en messages récapitulatifs Non Récupération d’espace depuis la sortie verbeuse de l’outil
SelectiveToolCallCompactionStrategy Faible-moyenne Moyenne : supprime complètement les anciens groupes d'appels d'outils Non Suppression de l’historique des outils lorsque les résultats ne sont plus nécessaires
SummarizationStrategy Moyenne Moyen : remplace l’historique par un résumé Yes Conversations longues où le contexte importe
SlidingWindowStrategy Élevé Faible — supprime les groupes les plus vieux Non Limites fixes du nombre de groupes
TruncationStrategy Élevé Faible — supprime les groupes les plus vieux Non Mesures de soutien pour message d'urgence ou budget de jetons
TokenBudgetComposedStrategy Paramétrable Dépend des stratégies des enfants Ça dépend Compactage en couches avec un objectif de budget de jetons et plusieurs solutions de repli
Strategy Agressivité Conserve le contexte Nécessite LLM Idéal pour
ToolResultStrategy Faible Élevé - condense les résultats verbeux de l’outil Non Récupération d’espace depuis la sortie verbeuse de l’outil
SlidingWindowStrategy Élevé Faible - conserve les tours les plus récents Non Limites strictes de comptage de tours
PipelineStrategy Paramétrable Dépend des stratégies des enfants Ça dépend Compactage en couches avec plusieurs solutions de repli

Étapes suivantes