Poznámka:
Přístup k této stránce vyžaduje autorizaci. Můžete se zkusit přihlásit nebo změnit adresáře.
Přístup k této stránce vyžaduje autorizaci. Můžete zkusit změnit adresáře.
V tomto kurzu se dozvíte, jak vytvořit strukturovaný výstup pomocí agenta, kde je agent založený na službě Dokončování chatu Azure OpenAI.
Důležité
Ne všechny typy agentů nativně podporují strukturovaný výstup. Podporuje ChatClientAgent strukturovaný výstup při použití s kompatibilními chatovacími klienty.
Požadavky
Informace o požadavcích a instalaci balíčků NuGet naleznete v kroku Vytvoření a spuštění jednoduchého agenta v tomto kurzu.
Definování typu strukturovaného výstupu
Nejprve definujte typ, který představuje strukturu požadovaného výstupu z agenta.
public class PersonInfo
{
public string? Name { get; set; }
public int? Age { get; set; }
public string? Occupation { get; set; }
}
Vytvoření agenta
Vytvořte ChatClientAgent pomocí klienta chatu Azure OpenAI.
using System;
using Azure.AI.OpenAI;
using Azure.Identity;
using Microsoft.Agents.AI;
AIAgent agent = new AzureOpenAIClient(
new Uri("https://<myresource>.openai.azure.com"),
new AzureCliCredential())
.GetChatClient("gpt-4o-mini")
.AsAIAgent(name: "HelpfulAssistant", instructions: "You are a helpful assistant.");
Strukturovaný výstup s využitím runAsync<T>
Metoda RunAsync<T> je k dispozici v AIAgent základní třídě. Přijímá parametr obecného typu, který určuje strukturovaný výstupní typ.
Tento přístup je použitelný, pokud je typ strukturovaného výstupu známý v době kompilace a je potřeba zadat instanci výsledku. Podporuje primitivní typy, pole a komplexní typy.
AgentResponse<PersonInfo> response = await agent.RunAsync<PersonInfo>("Please provide information about John Smith, who is a 35-year-old software engineer.");
Console.WriteLine($"Name: {response.Result.Name}, Age: {response.Result.Age}, Occupation: {response.Result.Occupation}");
Strukturovaný výstup s formátem ResponseFormat
Strukturovaný výstup lze nakonfigurovat nastavením ResponseFormat vlastnosti AgentRunOptions při vyvolání nebo během inicializace agenta pro agenty, kteří ho podporují, jako ChatClientAgent a Foundry Agent.
Tento přístup se dá použít v těchto případech:
- Typ strukturovaného výstupu není v době kompilace znám.
- Schéma je reprezentováno jako nezpracovaný JSON.
- Strukturovaný výstup je možné nakonfigurovat pouze při vytváření agenta.
- Bez deserializace je potřeba jenom nezpracovaný text JSON.
- Používá se spolupráce mezi agenty.
Různé možnosti ResponseFormat jsou k dispozici.
- Předdefinovaná ChatResponseFormat.Text vlastnost: Odpověď bude prostý text.
- Integrovaná ChatResponseFormat.Json vlastnost: Odpověď bude objekt JSON bez konkrétního schématu.
- Vlastní ChatResponseFormatJson instance: Odpověď bude objekt JSON, který odpovídá určitému schématu.
Poznámka:
Přístup ResponseFormat nepodporuje primitivy a pole. Pokud potřebujete pracovat s primitivy nebo poli, použijte RunAsync<T> přístup nebo vytvořte typ obálky.
// Instead of using List<string> directly, create a wrapper type:
public class MovieListWrapper
{
public List<string> Movies { get; set; }
}
using System.Text.Json;
using Microsoft.Extensions.AI;
AgentRunOptions runOptions = new()
{
ResponseFormat = ChatResponseFormat.ForJsonSchema<PersonInfo>()
};
AgentResponse response = await agent.RunAsync("Please provide information about John Smith, who is a 35-year-old software engineer.", options: runOptions);
PersonInfo personInfo = JsonSerializer.Deserialize<PersonInfo>(response.Text, JsonSerializerOptions.Web)!;
Console.WriteLine($"Name: {personInfo.Name}, Age: {personInfo.Age}, Occupation: {personInfo.Occupation}");
Lze ResponseFormat také zadat pomocí nezpracovaného řetězce schématu JSON, který je užitečný, pokud není k dispozici žádný odpovídající typ .NET, například pro deklarativní agenty nebo schémata načtená z externí konfigurace:
string jsonSchema = """
{
"type": "object",
"properties": {
"name": { "type": "string" },
"age": { "type": "integer" },
"occupation": { "type": "string" }
},
"required": ["name", "age", "occupation"]
}
""";
AgentRunOptions runOptions = new()
{
ResponseFormat = ChatResponseFormat.ForJsonSchema(JsonElement.Parse(jsonSchema), "PersonInfo", "Information about a person")
};
AgentResponse response = await agent.RunAsync("Please provide information about John Smith, who is a 35-year-old software engineer.", options: runOptions);
JsonElement result = JsonSerializer.Deserialize<JsonElement>(response.Text);
Console.WriteLine($"Name: {result.GetProperty("name").GetString()}, Age: {result.GetProperty("age").GetInt32()}, Occupation: {result.GetProperty("occupation").GetString()}");
Strukturovaný výstup se streamováním
Při streamování se odpověď agenta streamuje jako řada aktualizací a odpověď můžete deserializovat pouze po přijetí všech aktualizací. Před deserializací je nutné sestavit všechny aktualizace do jediné odpovědi.
using System.Text.Json;
using Microsoft.Extensions.AI;
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 = new() { ResponseFormat = ChatResponseFormat.ForJsonSchema<PersonInfo>() }
});
> [!WARNING]
> `DefaultAzureCredential` is convenient for development but requires careful consideration in production. In production, consider using a specific credential (e.g., `ManagedIdentityCredential`) to avoid latency issues, unintended credential probing, and potential security risks from fallback mechanisms.
IAsyncEnumerable<AgentResponseUpdate> updates = agent.RunStreamingAsync("Please provide information about John Smith, who is a 35-year-old software engineer.");
AgentResponse response = await updates.ToAgentResponseAsync();
PersonInfo personInfo = JsonSerializer.Deserialize<PersonInfo>(response.Text)!;
Console.WriteLine($"Name: {personInfo.Name}, Age: {personInfo.Age}, Occupation: {personInfo.Occupation}");
Strukturovaný výstup s agenty, kteří nemají schopnost vytvářet strukturovaný výstup
Někteří agenti nativně nepodporují strukturovaný výstup, a to buď proto, že nejsou součástí protokolu, nebo proto, že agenti používají jazykové modely bez schopností strukturovaného výstupu. Jedním z možných přístupů je vytvoření vlastního dekorátorského agenta, který obalí všechny AIAgent a následně pomocí dalšího volání LLM prostřednictvím chatovacího klienta převede textovou odpověď agenta na strukturovaný JSON.
Poznámka:
Vzhledem k tomu, že tento přístup spoléhá na další volání LLM k transformaci odpovědi, nemusí být pro všechny scénáře dostačující její spolehlivost.
Referenční implementaci tohoto modelu, kterou můžete přizpůsobit vlastním požadavkům, najdete v ukázce StructuredOutputAgent.
Návod
Najdete kompletní spustitelné příklady v ukázkách .NET.
Příklad streamování
Návod
Najdete kompletní spustitelné příklady v ukázkách .NET.
V tomto kurzu se dozvíte, jak vytvořit strukturovaný výstup pomocí agenta, kde je agent založený na službě Dokončování chatu Azure OpenAI.
Důležité
Ne všechny typy agentů podporují strukturovaný výstup. Podporuje Agent strukturovaný výstup při použití s kompatibilními chatovacími klienty.
Požadavky
Informace o požadavcích a instalaci balíčků najdete v části Vytvoření a spuštění jednoduchého agenta v tomto kurzu.
Vytvoření agenta se strukturovaným výstupem
Je Agent postaven na jakékoli implementaci chatovacího klienta, která podporuje strukturovaný výstup.
Agent Použije response_format parametr k určení požadovaného výstupního schématu.
Při vytváření nebo spuštění agenta můžete poskytnout Pydantický model, který definuje strukturu očekávaného výstupu.
Různé formáty odpovědí se podporují na základě možností podkladového chatovacího klienta.
Tento příklad vytvoří agenta, který vytvoří strukturovaný výstup ve formě objektu JSON, který odpovídá schématu Pydantického modelu.
Nejprve definujte Pydantický model, který představuje strukturu požadovaného výstupu z agenta:
from pydantic import BaseModel
class PersonInfo(BaseModel):
"""Information about a person."""
name: str | None = None
age: int | None = None
occupation: str | None = None
Teď můžete vytvořit agenta pomocí chatovacího klienta 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."
)
Teď můžete spustit agenta s některými textovými informacemi a zadat formát strukturovaného výstupu pomocí parametru response_format :
response = await agent.run(
"Please provide information about John Smith, who is a 35-year-old software engineer.",
response_format=PersonInfo
)
Odpověď agenta bude obsahovat strukturovaný výstup ve value vlastnosti, ke kterému je možné přistupovat přímo jako instance modelu 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")
Při streamování vrátí agent.run(..., stream=True) hodnotu ResponseStream. Integrovaný finalizátor streamu automaticky zpracovává analýzu strukturovaného výstupu, takže můžete iterovat pomocí aktualizací v reálném čase a pak volat get_final_response() pro získání zpracovaného výsledku.
# 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}")
Pokud nepotřebujete zpracovávat jednotlivé aktualizace streamování, můžete iteraci úplně přeskočit – get_final_response() automaticky bude stream využívat:
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}")
Kompletní příklad
# 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())