次の方法で共有


実行中のエージェント

基本エージェントの抽象化では、エージェントを実行するためのさまざまなオプションが公開されます。 呼び出し元は、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)

ストリーミングの場合は、runstream=True メソッドを使用します。 これにより、非同期的に反復処理できる 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

ResponseStreamによって返されるrun(..., stream=True) オブジェクトは、次の 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: この特定の実行のモデルをオーバーライドします
  • 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": "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 クラス ( OpenAIChatOptionsAnthropicChatOptionsOllamaChatOptionsなど) があり、そのプロバイダーでサポートされているオプションの完全なセットが公開されます。

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オブジェクトは、ResponseStreamによって返されるrun(..., stream=True)を介して生成される際にストリーミングされます。 各更新プログラムには、エージェントからの結果の一部と、その他のさまざまなコンテンツ項目が含まれる場合があります。 ストリーミング以外の場合と同様に、 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 は、agent_framework パッケージのメッセージとコンテンツ タイプを使用します。 メッセージはMessage クラスによって表され、すべてのコンテンツ項目は、Content プロパティによって区別されるtype クラスによって表されます。

すべてのコンテンツは、各コンテンツ タイプのファクトリ メソッドを持つ統合 Content クラスによって表されます。 コンテンツ タイプを確認するには、 type プロパティを使用します。 次のコンテンツ タイプを使用できます。

コンテンツ タイプ Factory Method(ファクトリー メソッド) Description
"text" Content.from_text() 入力と出力のテキスト コンテンツ。 通常、エージェントからのテキストの結果が含まれます。
"text_reasoning" Content.from_text_reasoning() 考え方の連鎖推論をサポートするモデルからの推論テキスト。 保護されたデータを含めることができます。
"data" Content.from_data()Content.from_uri() データ URI としてエンコードされたバイナリ コンテンツ。 画像、オーディオ、ビデオ、ドキュメントに使用されます。
"uri" Content.from_uri() 画像、オーディオ、ビデオなどのホストされているコンテンツを指す URL。
"error" Content.from_error() 処理が失敗したときのエラー情報。 省略可能なエラー コードと詳細が含まれます。
"function_call" Content.from_function_call() 関数ツールを呼び出す AI サービスによる要求。
"function_result" Content.from_function_result() 関数ツールの呼び出しの結果。
"usage" Content.from_usage() AI サービスからのトークンの使用状況と課金情報。
"hosted_file" Content.from_hosted_file() プロバイダーによってホストされているファイルへの参照 (たとえば、OpenAI にアップロード)。
"hosted_vector_store" Content.from_hosted_vector_store() プロバイダーによってホストされているベクター ストアへの参照。
"code_interpreter_tool_call" Content.from_code_interpreter_tool_call() コード インタープリターを介してコードを実行するための AI サービスによる要求。
"code_interpreter_tool_result" Content.from_code_interpreter_tool_result() コード インタープリターの実行結果。
"image_generation_tool_call" Content.from_image_generation_tool_call() 画像を生成するための AI サービスによる要求。
"image_generation_tool_result" Content.from_image_generation_tool_result() イメージ生成要求の結果。
"mcp_server_tool_call" Content.from_mcp_server_tool_call() MCP サーバーでツールを呼び出す要求。
"mcp_server_tool_result" Content.from_mcp_server_tool_result() MCP サーバー ツールの呼び出しの結果。
"shell_tool_call" Content.from_shell_tool_call() シェル コマンドを実行するための AI サービスによる要求。
"shell_tool_result" Content.from_shell_tool_result() シェル ツール呼び出しの集計結果。
"shell_command_output" Content.from_shell_command_output() 1 つのシェル コマンド実行の出力。
"function_approval_request" Content.from_function_approval_request() 関数呼び出しを実行する前のユーザー承認の要求。
"function_approval_response" Content.from_function_approval_response() 関数承認要求に対するユーザーの応答。
"oauth_consent_request" Content.from_oauth_consent_request() 指定されたリンクを使用して OAuth の同意を完了するようにユーザーに要求します。

さまざまなコンテンツ タイプを操作する方法を次に示します。

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}")

次のステップ