Partager via


Microsoft Agent Framework : conversations multitours et gestion des threads

Le Microsoft Agent Framework fournit une prise en charge intégrée de la gestion des conversations à plusieurs tours avec des agents IA. Cela inclut la maintenance du contexte entre plusieurs interactions. Différents types d’agents et services sous-jacents utilisés pour générer des agents peuvent prendre en charge différents types de thread, et l’infrastructure de l’agent extrait ces différences, fournissant une interface cohérente pour les développeurs.

Par exemple, lors de l'utilisation d'un ChatClientAgent basé sur un agent de fonderie, l'historique des conversations est conservé dans le service. Lorsque vous utilisez un ChatClientAgent basé sur l'achèvement de chat avec gpt-4.1, l'historique des conversations est conservé en mémoire et géré par l'agent.

Le AgentThread type est l’abstraction qui représente un thread de conversation avec un agent. AIAgent les instances sont sans état et la même instance d’agent peut être utilisée avec plusieurs AgentThread instances. Tout état est donc conservé dans le AgentThread. Un AgentThread peut représenter l’historique des conversations ainsi que tout autre état dont l’agent a besoin pour conserver plusieurs interactions. L’historique des conversations peut être stocké dans le thread lui-même ou à distance, avec la AgentThread seule référence à l’historique des conversations distantes. L’état AgentThread peut également inclure des souvenirs ou des références à des souvenirs stockés à distance.

Conseil / Astuce

Pour en savoir plus sur l’historique des conversations et la mémoire dans l’infrastructure de l’agent, consultez l’historique et la mémoire de l’agent.

Création d’AgentThread

AgentThread les instances peuvent être créées de deux manières :

  1. En appelant GetNewThread l’agent.
  2. En exécutant l’agent et en ne fournissant pas de AgentThread. Dans ce cas, l’agent va créer un élément jetable AgentThread avec un thread sous-jacent qui sera utilisé uniquement pendant la durée de l’exécution.

Certains threads sous-jacents peuvent être créés de manière permanente dans un service sous-jacent, où le service le requiert ; par exemple, les agents Foundry ou les réponses OpenAI. Tout nettoyage ou suppression de ces threads est la responsabilité de l’utilisateur.

// Create a new thread.
AgentThread thread = agent.GetNewThread();
// Run the agent with the thread.
var response = await agent.RunAsync("Hello, how are you?", thread);

// Run an agent with a temporary thread.
response = await agent.RunAsync("Hello, how are you?");

Stockage « AgentThread »

AgentThread les instances peuvent être sérialisées et stockées pour une utilisation ultérieure. Cela permet de préserver le contexte de conversation entre différentes sessions ou appels de service.

Dans les cas où l’historique des conversations est stocké dans un service, le sérialisé AgentThread contient un ID du thread dans le service. Dans les cas où l’historique des conversations est géré en mémoire, les données sérialisées AgentThread contiendront les messages eux-mêmes.

// Create a new thread.
AgentThread thread = agent.GetNewThread();
// Run the agent with the thread.
var response = await agent.RunAsync("Hello, how are you?", thread);

// Serialize the thread for storage.
JsonElement serializedThread = await thread.SerializeAsync();
// Deserialize the thread state after loading from storage.
AgentThread resumedThread = await agent.DeserializeThreadAsync(serializedThread);

// Run the agent with the resumed thread.
var response = await agent.RunAsync("Hello, how are you?", resumedThread);

Le Microsoft Agent Framework fournit une prise en charge intégrée de la gestion des conversations à plusieurs tours avec des agents IA. Cela inclut la maintenance du contexte entre plusieurs interactions. Différents types d’agents et services sous-jacents utilisés pour générer des agents peuvent prendre en charge différents types de threads, et l’Infrastructure agent extrait ces différences, fournissant une interface cohérente pour les développeurs.

Par exemple, lors de l’utilisation d’un ChatAgent basé sur un agent Foundry, l’historique des conversations est conservé dans le service. Lors de l’utilisation d’une ChatAgent fonction basée sur la complétion de conversation avec gpt-4, l’historique des conversations est maintenu en mémoire et géré par l’agent.

Les différences entre les modèles de threading sous-jacents sont abstraites via le AgentThread type.

Relation Agent/AgentThread

AIAgent les instances sont sans état et la même instance d’agent peut être utilisée avec plusieurs AgentThread instances.

Tous les agents ne prennent pas en charge tous les types de threads. Par exemple, si vous utilisez un service de réponses avec ChatClientAgent, les instances AgentThread créées par cet agent ne fonctionneront pas avec un service utilisant l'agent Foundry ChatClientAgent. Cela est dû au fait que ces services prennent tous les deux en charge l’enregistrement de l’historique des conversations dans le service, et que AgentThread n’a qu’une référence à ce thread géré par le service.

Il est donc considéré comme dangereux d’utiliser une AgentThread instance créée par un agent avec une autre instance d’agent, sauf si vous connaissez le modèle de threading sous-jacent et ses implications.

Prise en charge du multithreading par service/protocole

Service Prise en charge du threading
Agents de fonderie Threads persistants gérés par le service
Réponses OpenAI Threads persistants gérés par le service OU threads en mémoire
OpenAI ChatCompletion Threads en mémoire
Assistants OpenAI Threads de service gérés
A2A Threads de service gérés

Création d’AgentThread

AgentThread les instances peuvent être créées de deux manières :

  1. En appelant get_new_thread() l’agent.
  2. En exécutant l’agent et en ne fournissant pas de AgentThread. Dans ce cas, l’agent va créer un élément jetable AgentThread avec un thread sous-jacent qui sera utilisé uniquement pendant la durée de l’exécution.

Certains threads sous-jacents peuvent être créés de manière permanente dans un service sous-jacent, où le service requiert cela, par exemple, des agents Azure AI ou des réponses OpenAI. Tout nettoyage ou suppression de ces threads est la responsabilité de l’utilisateur.

# Create a new thread.
thread = agent.get_new_thread()
# Run the agent with the thread.
response = await agent.run("Hello, how are you?", thread=thread)

# Run an agent with a temporary thread.
response = await agent.run("Hello, how are you?")

Stockage « AgentThread »

AgentThread les instances peuvent être sérialisées et stockées pour une utilisation ultérieure. Cela permet de préserver le contexte de conversation entre différentes sessions ou appels de service.

Dans les cas où l’historique des conversations est stocké dans un service, le sérialisé AgentThread contient un ID du thread dans le service. Dans les cas où l’historique des conversations est géré en mémoire, les données sérialisées AgentThread contiendront les messages eux-mêmes.

# Create a new thread.
thread = agent.get_new_thread()
# Run the agent with the thread.
response = await agent.run("Hello, how are you?", thread=thread)

# Serialize the thread for storage.
serialized_thread = await thread.serialize()
# Deserialize the thread state after loading from storage.
resumed_thread = await agent.deserialize_thread(serialized_thread)

# Run the agent with the resumed thread.
response = await agent.run("Hello, how are you?", thread=resumed_thread)

Magasins de messages personnalisés

Pour les threads en mémoire, vous pouvez fournir une implémentation de magasin de messages personnalisée pour contrôler la façon dont les messages sont stockés et récupérés :

from agent_framework import AgentThread, ChatMessageStore, ChatAgent
from agent_framework.azure import AzureAIAgentClient
from azure.identity.aio import AzureCliCredential

class CustomStore(ChatMessageStore):
    # Implement custom storage logic here
    pass

# You can also provide a custom message store factory when creating the agent
def custom_message_store_factory():
    return CustomStore()  # or your custom implementation

async with AzureCliCredential() as credential:
    agent = ChatAgent(
        chat_client=AzureAIAgentClient(async_credential=credential),
        instructions="You are a helpful assistant",
        chat_message_store_factory=custom_message_store_factory
    )
    # Or let the agent create one automatically
    thread = agent.get_new_thread()
    # thread.message_store is not a instance of CustomStore

Relation Agent/AgentThread

Agents sont sans état et la même instance d’agent peut être utilisée avec plusieurs AgentThread instances.

Tous les agents ne prennent pas en charge tous les types de threads. Par exemple, si vous utilisez un ChatAgent avec le service OpenAI Responses, et que des instances store=True, AgentThread sont utilisées par cet agent, elles ne fonctionneront pas avec un ChatAgent utilisant le service Azure AI Agent, car les thread_ids ne sont pas compatibles.

Il est donc considéré comme dangereux d’utiliser une AgentThread instance créée par un agent avec une autre instance d’agent, sauf si vous connaissez le modèle de threading sous-jacent et ses implications.

Exemple pratique de plusieurs étapes

Voici un exemple complet montrant comment gérer le contexte entre plusieurs interactions :

from agent_framework import ChatAgent
from agent_framework.azure import AzureAIAgentClient
from azure.identity.aio import AzureCliCredential

async def multi_turn_example():
    async with (
        AzureCliCredential() as credential,
        ChatAgent(
            chat_client=AzureAIAgentClient(async_credential=credential),
            instructions="You are a helpful assistant"
        ) as agent
    ):
        # Create a thread for persistent conversation
        thread = agent.get_new_thread()

        # First interaction
        response1 = await agent.run("My name is Alice", thread=thread)
        print(f"Agent: {response1.text}")

        # Second interaction - agent remembers the name
        response2 = await agent.run("What's my name?", thread=thread)
        print(f"Agent: {response2.text}")  # Should mention "Alice"

        # Serialize thread for storage
        serialized = await thread.serialize()

        # Later, deserialize and continue conversation
        new_thread = await agent.deserialize_thread(serialized)
        response3 = await agent.run("What did we talk about?", thread=new_thread)
        print(f"Agent: {response3.text}")  # Should remember previous context

Étapes suivantes