Примечание.
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
На этом шаге руководства показано, как создать структурированные выходные данные с агентом, где агент основан на службе завершения чата Azure OpenAI.
Это важно
Не все типы агентов поддерживают структурированные выходные данные. На этом шаге используется объект 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
});
Предупреждение
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}");
При потоковой трансляции ответ агента передается в виде серии обновлений, и его можно десериализовать только после получения всех обновлений. Перед десериализацией необходимо собрать все обновления в один ответ.
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.
Это важно
Не все типы агентов поддерживают структурированные выходные данные. Поддерживает вывод структурированных данных Agent при использовании с совместимыми клиентами чата.
Предпосылки
Для ознакомления с предварительными требованиями и установкой пакетов см. шаг "Создание и запуск простого агента" в этом руководстве.
Создание агента со структурированными выходными данными
Agent построен поверх любой реализации клиента чата, поддерживающей структурированный вывод.
Agent Использует response_format параметр для указания требуемой выходной схемы.
При создании или запуске агента можно указать модель Pydantic, которая определяет структуру ожидаемых выходных данных.
Поддерживаются различные форматы ответов на основе базовых возможностей клиента чата.
В этом примере создается агент, который создает структурированные выходные данные в виде объекта JSON, соответствующего схеме модели Pydantic.
Сначала определите модель 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
)
Ответ агента будет содержать структурированные выходные данные в свойстве value , доступ к которому можно получить непосредственно в качестве экземпляра модели Pydantic:
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())