Microsoft Agent Framework には、AI エージェントとの複数ターンの会話を管理するための組み込みのサポートが用意されています。 これには、複数の操作にわたるコンテキストの維持が含まれます。 エージェントの構築に使用されるエージェントの種類と基になるサービスによって、異なるスレッドの種類がサポートされる場合があり、エージェント フレームワークはこれらの違いを抽象化して、開発者に一貫性のあるインターフェイスを提供します。
たとえば、Foundry agent に基づいて ChatClientAgent を使用する場合、会話履歴はサービスに永続化されます。 一方、gpt-4.1 でのチャット完了に基づいて ChatClientAgent を使用する場合、会話履歴はメモリ内にあり、エージェントによって管理されます。
AgentThread型は、エージェントとの会話スレッドを表す抽象化です。
AIAgent インスタンスはステートレスであり、同じエージェント インスタンスを複数の AgentThread インスタンスで使用できます。 したがって、すべての状態は AgentThreadに保持されます。
AgentThreadは、チャット履歴と、エージェントが複数の対話間で保持する必要があるその他の状態の両方を表すことができます。
チャット履歴は、リモート チャット履歴への参照のみを含む AgentThread を使用して、スレッド自体またはリモートに格納できます。
AgentThread状態には、リモートに格納されているメモリやメモリへの参照も含まれる場合があります。
ヒント
エージェント フレームワークでのチャット履歴とメモリの詳細については、「 エージェント チャットの履歴とメモリ」を参照してください。
AgentThread の作成
AgentThread インスタンスは、次の 2 つの方法で作成できます。
- エージェントに対して
GetNewThreadを呼び出すことによって。 - エージェントを実行し、
AgentThreadを提供しないこと。 この場合、エージェントは、実行期間中にのみ使用される基になるスレッドを含む、使い捨てAgentThreadを作成します。
基になる一部のスレッドは、基になるサービスに永続的に作成される場合があります。この場合、サービスでは Foundry Agents や OpenAI Responses など、これを必要とします。 これらのスレッドのクリーンアップまたは削除は、ユーザーの責任です。
// 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?");
AgentThreadストレージ
AgentThread インスタンスは、後で使用するためにシリアル化および格納できます。 これにより、異なるセッションまたはサービス呼び出し間で会話コンテキストを保持できます。
会話履歴がサービスに格納されている場合、シリアル化された AgentThread には、サービス内のスレッドの ID が含まれます。
会話履歴がメモリ内で管理されている場合、シリアル化された AgentThread にはメッセージ自体が含まれます。
// 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);
Microsoft Agent Framework には、AI エージェントとの複数ターンの会話を管理するための組み込みのサポートが用意されています。 これには、複数の操作にわたるコンテキストの維持が含まれます。 エージェントの構築に使用されるエージェントの種類と基になるサービスによって、異なるスレッドの種類がサポートされる場合があり、エージェント フレームワークはこれらの違いを抽象化して、開発者に一貫性のあるインターフェイスを提供します。
たとえば、Foundry エージェントに基づく ChatAgent を使用する場合、会話履歴はサービスに保持されます。 gpt-4 でのチャットの完了に基づいて ChatAgent を使用する場合、会話履歴はメモリ内にあり、エージェントによって管理されます。
基になるスレッド モデル間の違いは、 AgentThread 型を介して抽象化されます。
Agent/AgentThread リレーションシップ
AIAgent インスタンスはステートレスであり、同じエージェント インスタンスを複数の AgentThread インスタンスで使用できます。
ただし、すべてのエージェントがすべてのスレッドの種類をサポートしているわけではありません。 たとえば、応答サービスで ChatClientAgent を使用している場合、このエージェントによって作成されたインスタンス AgentThread は、Foundry Agent サービスを使用する ChatClientAgent では機能しません。
これは、これらのサービスはどちらもサービスでの会話履歴の保存をサポートしており、 AgentThread にはこのサービスマネージド スレッドへの参照しかないためです。
したがって、基になるスレッド モデルとその影響を認識していない限り、別のエージェント インスタンスを持つ 1 つのエージェントによって作成された AgentThread インスタンスを使用するのは安全でないと見なされます。
サービス/プロトコルによるスレッドのサポート
| サービス | スレッド処理のサポート |
|---|---|
| 鋳造剤 | サービスによって管理される永続的なスレッド |
| OpenAI 応答 | サービスによって管理される永続的なスレッドまたはメモリ内スレッド |
| OpenAI ChatCompletion(チャット完了機能) | メモリ内スレッド |
| OpenAI アシスタント | サービスで管理されるスレッド |
| A2A | サービスで管理されるスレッド |
AgentThread の作成
AgentThread インスタンスは、次の 2 つの方法で作成できます。
- エージェントに対して
get_new_thread()を呼び出すことによって。 - エージェントを実行し、
AgentThreadを提供しないこと。 この場合、エージェントは、実行期間中にのみ使用される基になるスレッドを含む、使い捨てAgentThreadを作成します。
基になる一部のスレッドは、基になるサービスに永続的に作成される場合があります。サービスでは、Azure AI エージェントや OpenAI 応答など、これを必要とします。 これらのスレッドのクリーンアップまたは削除は、ユーザーの責任です。
# 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?")
AgentThreadストレージ
AgentThread インスタンスは、後で使用するためにシリアル化および格納できます。 これにより、異なるセッションまたはサービス呼び出し間で会話コンテキストを保持できます。
会話履歴がサービスに格納されている場合、シリアル化された AgentThread には、サービス内のスレッドの ID が含まれます。
会話履歴がメモリ内で管理されている場合、シリアル化された AgentThread にはメッセージ自体が含まれます。
# 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)
カスタム メッセージ ストア
メモリ内スレッドの場合、カスタム メッセージ ストアの実装を提供して、メッセージの格納方法と取得方法を制御できます。
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
Agent/AgentThread リレーションシップ
Agents はステートレスであり、同じエージェント インスタンスを複数の AgentThread インスタンスで使用できます。
ただし、すべてのエージェントがすべてのスレッドの種類をサポートしているわけではありません。 たとえば、OpenAI Responses サービスとChatAgentでstore=Trueを使用している場合、このエージェントで使用AgentThreadインスタンスは、Azure AI エージェント サービスを使用するChatAgentでは動作しません。これは、thread_idsに互換性がないためです。
したがって、基になるスレッド モデルとその影響を認識していない限り、別のエージェント インスタンスを持つ 1 つのエージェントによって作成された AgentThread インスタンスを使用するのは安全でないと見なされます。
実用的なマルチターンの例
複数の相互作用にわたってコンテキストを維持する方法を示す完全な例を次に示します。
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