基本エージェントの抽象化では、エージェントを実行するためのさまざまなオプションが公開されます。 呼び出し元は、0 個、1 個、または多数の入力メッセージを指定できます。 呼び出し元は、ストリーミングと非ストリーミングのどちらかを選択することもできます。 さまざまな使用シナリオを見てみましょう。
ストリーミングと非ストリーミング
Microsoft Agent Framework では、エージェントを実行するためのストリーミング メソッドと非ストリーミング メソッドの両方がサポートされています。
ストリーミング以外の場合は、 RunAsync メソッドを使用します。
Console.WriteLine(await agent.RunAsync("What is the weather like in Amsterdam?"));
ストリーミングには、 RunStreamingAsync メソッドを使用します。
await foreach (var update in agent.RunStreamingAsync("What is the weather like in Amsterdam?"))
{
Console.Write(update);
}
ストリーミング以外の場合は、 run メソッドを使用します。
result = await agent.run("What is the weather like in Amsterdam?")
print(result.text)
ストリーミングの場合は、stream=Trueで run メソッドを使用します。 これにより、非同期的に反復処理できる ResponseStream オブジェクトが返されます。
async for update in agent.run("What is the weather like in Amsterdam?", stream=True):
if update.text:
print(update.text, end="", flush=True)
ResponseStream
run(..., stream=True)によって返されるResponseStream オブジェクトは、次の 2 つの消費パターンをサポートします。
パターン 1: 非同期反復 — リアルタイム表示のために到着したプロセスの更新:
response_stream = agent.run("Tell me a story", stream=True)
async for update in response_stream:
if update.text:
print(update.text, end="", flush=True)
パターン 2: 直接終了 — イテレーションをスキップし、完全な応答を取得します。
response_stream = agent.run("Tell me a story", stream=True)
final = await response_stream.get_final_response()
print(final.text)
パターン 3: 結合 — リアルタイム表示を反復処理し、集計された結果を取得します。
response_stream = agent.run("Tell me a story", stream=True)
# First, iterate to display streaming output
async for update in response_stream:
if update.text:
print(update.text, end="", flush=True)
# Then get the complete response (uses already-collected updates, does not re-iterate)
final = await response_stream.get_final_response()
print(f"\n\nFull response: {final.text}")
print(f"Messages: {len(final.messages)}")
エージェントの実行オプション
基本エージェントの抽象化では、エージェントの実行ごとにオプション オブジェクトを渡すことが可能ですが、抽象化レベルで実行をカスタマイズする機能は非常に限られています。 エージェントは大きく異なる可能性があるため、一般的なカスタマイズ オプションはありません。
呼び出し元が使用しているエージェントの種類を認識している場合は、型固有のオプションを渡して実行をカスタマイズできます。
たとえば、ここではエージェントはChatClientAgentであり、ChatClientAgentRunOptionsから継承するAgentRunOptions オブジェクトを渡すことができます。
これにより、呼び出し元は、ChatOptionsが構築されているIChatClientに渡される前に、エージェント レベルのオプションとマージされるカスタム ChatClientAgentを提供できます。
var chatOptions = new ChatOptions() { Tools = [AIFunctionFactory.Create(GetWeather)] };
Console.WriteLine(await agent.RunAsync("What is the weather like in Amsterdam?", options: new ChatClientAgentRunOptions(chatOptions)));
Python エージェントでは、 options パラメーターを使用した各実行のカスタマイズがサポートされています。 オプションは TypedDict として渡され、構築時 ( default_options 経由) と実行ごと ( options経由) の両方で設定できます。 各プロバイダーには、プロバイダー固有の設定の完全な IDE オートコンプリートと型チェックを提供する独自の TypedDict クラスがあります。
一般的なオプションは次のとおりです。
-
max_tokens: 生成するトークンの最大数 -
temperature: 応答生成のランダム性を制御します。 -
model_id: この特定の実行のモデルをオーバーライドします -
top_p: 核サンプリング パラメーター -
response_format: 応答形式 (構造化された出力など) を指定します。
注
toolsパラメーターとinstructions パラメーターは直接キーワード引数のままであり、options ディクショナリを介して渡されません。
from agent_framework.openai import OpenAIChatClient, OpenAIChatOptions
# Set default options at construction time
agent = OpenAIChatClient().as_agent(
instructions="You are a helpful assistant",
default_options={
"temperature": 0.7,
"max_tokens": 500
}
)
# Run with custom options (overrides defaults)
# OpenAIChatOptions provides IDE autocomplete for all OpenAI-specific settings
options: OpenAIChatOptions = {
"temperature": 0.3,
"max_tokens": 150,
"model_id": "gpt-4o",
"presence_penalty": 0.5,
"frequency_penalty": 0.3
}
result = await agent.run(
"What is the weather like in Amsterdam?",
options=options
)
# Streaming with custom options
async for update in agent.run(
"Tell me a detailed weather forecast",
stream=True,
options={"temperature": 0.7, "top_p": 0.9},
tools=[additional_weather_tool] # tools is still a keyword argument
):
if update.text:
print(update.text, end="", flush=True)
各プロバイダーには、独自の TypedDict クラス ( OpenAIChatOptions、 AnthropicChatOptions、 OllamaChatOptionsなど) があり、そのプロバイダーでサポートされているオプションの完全なセットが公開されます。
default_optionsと実行ごとの両方のoptionsが指定されている場合、実行ごとのオプションが優先され、既定値とマージされます。
応答の種類
エージェントからのストリーミング応答と非ストリーミング応答の両方に、エージェントによって生成されたすべてのコンテンツが含まれます。 コンテンツには、エージェントからの結果 (つまり、ユーザーの質問に対する回答) ではないデータが含まれる場合があります。 返されるその他のデータの例としては、関数ツールの呼び出し、関数ツール呼び出しの結果、推論テキスト、状態の更新などがあります。
返されるすべてのコンテンツが結果であるとは言えないので、他のコンテンツから結果を分離しようとするときに、特定のコンテンツ タイプを検索することが重要です。
応答からテキストの結果を抽出するには、すべてのTextContent項目のすべてのChatMessages項目を集計する必要があります。
これを簡略化するために、すべてのTextを集計するすべての応答の種類でTextContentプロパティを使用できます。
非ストリーミングの場合、すべてが 1 つの AgentResponse オブジェクトで返されます。
AgentResponse では、 Messages プロパティを使用して生成されたメッセージにアクセスできます。
var response = await agent.RunAsync("What is the weather like in Amsterdam?");
Console.WriteLine(response.Text);
Console.WriteLine(response.Messages.Count);
ストリーミングの場合、 AgentResponseUpdate オブジェクトは生成時にストリーミングされます。
各更新プログラムには、エージェントからの結果の一部と、その他のさまざまなコンテンツ項目が含まれる場合があります。
ストリーミング以外の場合と同様に、 Text プロパティを使用して、更新に含まれる結果の部分を取得し、 Contents プロパティを使用して詳細を調べることができます。
await foreach (var update in agent.RunStreamingAsync("What is the weather like in Amsterdam?"))
{
Console.WriteLine(update.Text);
Console.WriteLine(update.Contents.Count);
}
非ストリーミングの場合、すべてが 1 つの AgentResponse オブジェクトで返されます。
AgentResponse では、 messages プロパティを使用して生成されたメッセージにアクセスできます。
応答からテキストの結果を抽出するには、すべてのTextContent項目のすべてのMessage項目を集計する必要があります。
これを簡略化するために、すべてのTextを集計するすべての応答の種類でTextContentプロパティを使用できます。
response = await agent.run("What is the weather like in Amsterdam?")
print(response.text)
print(len(response.messages))
# Access individual messages
for message in response.messages:
print(f"Role: {message.role}, Text: {message.text}")
ストリーミングの場合、AgentResponseUpdateオブジェクトは、run(..., stream=True)によって返されるResponseStreamを介して生成される際にストリーミングされます。
各更新プログラムには、エージェントからの結果の一部と、その他のさまざまなコンテンツ項目が含まれる場合があります。
ストリーミング以外の場合と同様に、 text プロパティを使用して、更新に含まれる結果の部分を取得し、 contents プロパティを使用して詳細を調べることができます。
response_stream = agent.run("What is the weather like in Amsterdam?", stream=True)
async for update in response_stream:
print(f"Update text: {update.text}")
print(f"Content count: {len(update.contents)}")
# Access individual content items
for content in update.contents:
if hasattr(content, 'text'):
print(f"Content: {content.text}")
# Get the aggregated final response after streaming
final = await response_stream.get_final_response()
print(f"Complete text: {final.text}")
メッセージの種類
エージェントからの入力と出力はメッセージとして表されます。 メッセージはコンテンツ 項目に分割されます。
Microsoft Agent Framework では、 Microsoft.Extensions.AI 抽象化によって提供されるメッセージとコンテンツ タイプが使用されます。
メッセージは ChatMessage クラスによって表され、すべてのコンテンツ クラスは基本 AIContent クラスから継承されます。
さまざまな種類のコンテンツを表すために使用されるさまざまな AIContent サブクラスが存在します。 一部は基本 Microsoft.Extensions.AI 抽象化の一部として提供されますが、プロバイダーは必要に応じて独自の型を追加することもできます。
Microsoft.Extensions.AIの一般的な種類を次に示します。
| タイプ | Description |
|---|---|
| TextContent | ユーザーや開発者からの入力と、エージェントからの出力の両方が可能なテキスト コンテンツ。 通常、エージェントからのテキストの結果が含まれます。 |
| DataContent | 入力と出力の両方が可能なバイナリ コンテンツ。 エージェントとの間でイメージ、オーディオ、またはビデオのデータを渡すために使用できます (サポートされている場合)。 |
| UriContent | 通常、ホストされているコンテンツ (画像、オーディオ、ビデオなど) を指す URL。 |
| FunctionCallContent | 関数ツールを呼び出す推論サービスによる要求。 |
| FunctionResultContent | 関数ツールの呼び出しの結果。 |
Python エージェント フレームワークは、 agent_framework パッケージのメッセージとコンテンツ タイプを使用します。
メッセージは Message クラスによって表され、すべてのコンテンツ クラスは基本 Content クラスから継承されます。
さまざまな種類のコンテンツを表すために使用されるさまざまな Content サブクラスが存在します。
| タイプ | Description |
|---|---|
Content |
ファクトリ メソッド (Content.from_text()、 Content.from_data()、 Content.from_uri()) を使用した統合コンテンツ タイプ。
type プロパティを使用して、コンテンツ タイプ ("text"、"data"、"uri") を確認します。 |
FunctionCallContent |
関数ツールを呼び出す AI サービスによる要求。 |
FunctionResultContent |
関数ツールの呼び出しの結果。 |
ErrorContent |
処理が失敗したときのエラー情報。 |
UsageContent |
AI サービスからのトークンの使用状況と課金情報。 |
さまざまなコンテンツ タイプを操作する方法を次に示します。
from agent_framework import Message, Content
# Create a text message
text_message = Message(role="user", contents=["Hello!"])
# Create a message with multiple content types
image_data = b"..." # your image bytes
mixed_message = Message(
role="user",
contents=[
Content.from_text("Analyze this image:"),
Content.from_data(data=image_data, media_type="image/png"),
]
)
# Access content from responses
response = await agent.run("Describe the image")
for message in response.messages:
for content in message.contents:
if content.type == "text":
print(f"Text: {content.text}")
elif content.type == "data":
print(f"Data URI: {content.uri}")
elif content.type == "uri":
print(f"External URI: {content.uri}")