次の方法で共有


エージェントを使用した構造化出力の生成

このチュートリアルの手順では、エージェントを使用して構造化された出力を生成する方法について説明します。この場合、エージェントは Azure OpenAI Chat Completion サービス上に構築されます。

Important

すべてのエージェントの種類が構造化出力をサポートしているわけではありません。 この手順では、構造化された出力をサポートする ChatClientAgentを使用します。

[前提条件]

前提条件と NuGet パッケージのインストールについては、このチュートリアルの 「エージェントの作成と実行 」の手順を参照してください。

構造化された出力を使用してエージェントを作成する

ChatClientAgentは、IChatClientインプリメンテーションの上に構築されています。 ChatClientAgentは、基になるチャット クライアントによって提供される構造化された出力のサポートを使用します。

エージェントを作成するときに、基になるチャット クライアントに使用する既定の ChatOptions インスタンスを指定するオプションがあります。 この ChatOptions インスタンスを使用すると、優先する ChatResponseFormatを選択できます。

ResponseFormatのさまざまなオプションを使用できます。

  • 組み込みの ChatResponseFormat.Text プロパティ: 応答はプレーン テキストになります。
  • 組み込みの ChatResponseFormat.Json プロパティ: 応答は、特定のスキーマのない JSON オブジェクトになります。
  • カスタム ChatResponseFormatJson インスタンス: 応答は、特定のスキーマに準拠する JSON オブジェクトになります。

この例では、特定のスキーマに準拠する JSON オブジェクトの形式で構造化された出力を生成するエージェントを作成します。

スキーマを生成する最も簡単な方法は、エージェントからの出力の構造を表す型を定義し、 AIJsonUtilities.CreateJsonSchema メソッドを使用して型からスキーマを作成することです。

using System.Text.Json;
using System.Text.Json.Serialization;
using Microsoft.Extensions.AI;

public class PersonInfo
{
    public string? Name { get; set; }
    public int? Age { get; set; }
    public string? Occupation { get; set; }
}

JsonElement schema = AIJsonUtilities.CreateJsonSchema(typeof(PersonInfo));

その後、応答形式にこのスキーマを使用する ChatOptions インスタンスを作成できます。

using Microsoft.Extensions.AI;

ChatOptions chatOptions = new()
{
    ResponseFormat = ChatResponseFormat.ForJsonSchema(
        schema: schema,
        schemaName: "PersonInfo",
        schemaDescription: "Information about a person including their name, age, and occupation")
};

この ChatOptions インスタンスは、エージェントの作成時に使用できます。

using System;
using Azure.AI.OpenAI;
using Azure.Identity;
using Microsoft.Agents.AI;
using OpenAI;

AIAgent agent = new AzureOpenAIClient(
    new Uri("https://<myresource>.openai.azure.com"),
    new DefaultAzureCredential())
        .GetChatClient("gpt-4o-mini")
        .AsAIAgent(new ChatClientAgentOptions()
        {
            Name = "HelpfulAssistant",
            Instructions = "You are a helpful assistant.",
            ChatOptions = chatOptions
        });

Warnung

DefaultAzureCredential は開発には便利ですが、運用環境では慎重に考慮する必要があります。 運用環境では、待機時間の問題、意図しない資格情報のプローブ、フォールバック メカニズムによる潜在的なセキュリティ リスクを回避するために、特定の資格情報 ( ManagedIdentityCredential など) を使用することを検討してください。

これで、エージェントが構造化された出力を入力するために使用できるテキスト情報を使用してエージェントを実行できます。

var response = await agent.RunAsync("Please provide information about John Smith, who is a 35-year-old software engineer.");

その後、応答オブジェクトの PersonInfo メソッドを使用して、エージェント応答を Deserialize<T> クラスに逆シリアル化できます。

var personInfo = response.Deserialize<PersonInfo>(JsonSerializerOptions.Web);
Console.WriteLine($"Name: {personInfo.Name}, Age: {personInfo.Age}, Occupation: {personInfo.Occupation}");

ストリーミング時には、エージェントの応答は一連の更新としてストリーミングされ、すべての更新プログラムを受信した後にのみ応答を逆シリアル化できます。 逆シリアル化する前に、すべての更新を 1 つの応答にアセンブルする必要があります。

var updates = agent.RunStreamingAsync("Please provide information about John Smith, who is a 35-year-old software engineer.");
personInfo = (await updates.ToAgentResponseAsync()).Deserialize<PersonInfo>(JsonSerializerOptions.Web);

ヒント

実行可能な完全な例については、 .NET サンプル を参照してください。

ストリーミングの例

ヒント

実行可能な完全な例については、 .NET サンプル を参照してください。

このチュートリアルの手順では、エージェントを使用して構造化された出力を生成する方法について説明します。この場合、エージェントは Azure OpenAI Chat Completion サービス上に構築されます。

Important

すべてのエージェントの種類が構造化出力をサポートしているわけではありません。 Agentは、互換性のあるチャット クライアントで使用する場合の構造化された出力をサポートします。

[前提条件]

前提条件とパッケージのインストールについては、このチュートリアルの 「エージェントの作成と実行 」の手順を参照してください。

構造化された出力を使用してエージェントを作成する

Agentは、構造化された出力をサポートするチャット クライアント実装の上に構築されています。 Agentでは、response_format パラメーターを使用して目的の出力スキーマを指定します。

エージェントを作成または実行するときに、予想される出力の構造を定義する Pydantic モデルを提供できます。

基になるチャット クライアント機能に基づいて、さまざまな応答形式がサポートされます。

この例では、Pydantic モデル スキーマに準拠する JSON オブジェクトの形式で構造化された出力を生成するエージェントを作成します。

まず、エージェントから必要な出力の構造を表す Pydantic モデルを定義します。

from pydantic import BaseModel

class PersonInfo(BaseModel):
    """Information about a person."""
    name: str | None = None
    age: int | None = None
    occupation: str | None = None

これで、Azure OpenAI チャット クライアントを使用してエージェントを作成できます。

from agent_framework.azure import AzureOpenAIChatClient
from azure.identity import AzureCliCredential

# Create the agent using Azure OpenAI Chat Client
agent = AzureOpenAIChatClient(credential=AzureCliCredential()).as_agent(
    name="HelpfulAssistant",
    instructions="You are a helpful assistant that extracts person information from text."
)

これで、テキスト情報を使用してエージェントを実行し、 response_format パラメーターを使用して構造化出力形式を指定できます。

response = await agent.run(
    "Please provide information about John Smith, who is a 35-year-old software engineer.",
    response_format=PersonInfo
)

エージェントの応答には、pydantic モデル インスタンスとして直接アクセスできる、 value プロパティに構造化された出力が含まれます。

if response.value:
    person_info = response.value
    print(f"Name: {person_info.name}, Age: {person_info.age}, Occupation: {person_info.occupation}")
else:
    print("No structured data found in response")

ストリーミング時に、 agent.run(..., stream=True)ResponseStreamを返します。 ストリームの組み込みファイナライザーは、構造化された出力の解析を自動的に処理するため、リアルタイムの更新を反復処理し、 get_final_response() を呼び出して解析された結果を取得できます。

# Stream updates in real time, then get the structured result
stream = agent.run(query, stream=True, options={"response_format": PersonInfo})
async for update in stream:
    print(update.text, end="", flush=True)

# get_final_response() returns the AgentResponse with the parsed value
final_response = await stream.get_final_response()

if final_response.value:
    person_info = final_response.value
    print(f"Name: {person_info.name}, Age: {person_info.age}, Occupation: {person_info.occupation}")

個々のストリーミング更新を処理する必要がない場合は、イテレーションを完全にスキップできます。 get_final_response() はストリームを自動的に使用します。

stream = agent.run(query, stream=True, options={"response_format": PersonInfo})
final_response = await stream.get_final_response()

if final_response.value:
    person_info = final_response.value
    print(f"Name: {person_info.name}, Age: {person_info.age}, Occupation: {person_info.occupation}")

完全な例

# Copyright (c) Microsoft. All rights reserved.

import asyncio

from agent_framework.openai import OpenAIResponsesClient
from pydantic import BaseModel

"""
OpenAI Responses Client with Structured Output Example

This sample demonstrates using structured output capabilities with OpenAI Responses Client,
showing Pydantic model integration for type-safe response parsing and data extraction.
"""


class OutputStruct(BaseModel):
    """A structured output for testing purposes."""

    city: str
    description: str


async def non_streaming_example() -> None:
    print("=== Non-streaming example ===")

    agent = OpenAIResponsesClient().as_agent(
        name="CityAgent",
        instructions="You are a helpful agent that describes cities in a structured format.",
    )

    query = "Tell me about Paris, France"
    print(f"User: {query}")

    result = await agent.run(query, options={"response_format": OutputStruct})

    if structured_data := result.value:
        print("Structured Output Agent:")
        print(f"City: {structured_data.city}")
        print(f"Description: {structured_data.description}")
    else:
        print(f"Failed to parse response: {result.text}")


async def streaming_example() -> None:
    print("=== Streaming example ===")

    agent = OpenAIResponsesClient().as_agent(
        name="CityAgent",
        instructions="You are a helpful agent that describes cities in a structured format.",
    )

    query = "Tell me about Tokyo, Japan"
    print(f"User: {query}")

    # Stream updates in real time using ResponseStream
    stream = agent.run(query, stream=True, options={"response_format": OutputStruct})
    async for update in stream:
        if update.text:
            print(update.text, end="", flush=True)
    print()

    # get_final_response() returns the AgentResponse with structured output parsed
    result = await stream.get_final_response()

    if structured_data := result.value:
        print("Structured Output (from streaming with ResponseStream):")
        print(f"City: {structured_data.city}")
        print(f"Description: {structured_data.description}")
    else:
        print(f"Failed to parse response: {result.text}")


async def main() -> None:
    print("=== OpenAI Responses Agent with Structured Output ===")

    await non_streaming_example()
    await streaming_example()


if __name__ == "__main__":
    asyncio.run(main())

次のステップ