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.
Tento krok kurzu ukazuje, jak vytvořit strukturované výstupy pomocí agenta, kde je agent postaven na službě pro dokončování chatu OpenAI Azure.
Důležité
Ne všechny typy agentů nativně podporují strukturované výstupy. Podporuje ChatClientAgent strukturované výstupy při použití s kompatibilními chatovacími klienty.
Předpoklady
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 pro strukturované výstupy
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
Pomocí klienta projektů Azure AI vytvořte ChatClientAgent.
using System;
using Azure.AI.Projects;
using Azure.Identity;
using Microsoft.Agents.AI;
AIAgent agent = new AIProjectClient(
new Uri("<your-foundry-project-endpoint>"),
new DefaultAzureCredential())
.AsAIAgent(
model: "gpt-4o-mini",
name: "HelpfulAssistant",
instructions: "You are a helpful assistant.");
Výstraha
DefaultAzureCredential je vhodný pro vývoj, ale vyžaduje pečlivé zvážení v produkčním prostředí. V produkčním prostředí zvažte použití konkrétních přihlašovacích údajů (např ManagedIdentityCredential. ) k zabránění problémům s latencí, neúmyslnému testování přihlašovacích údajů a potenciálním bezpečnostním rizikům z náhradních mechanismů.
Strukturované výstupy 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 typ strukturovaných výstupů.
Tento přístup se dá použít, pokud je typ strukturovaných výstupů 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ýstupy pomocí ResponseFormat
Strukturované výstupy je možné nakonfigurovat nastavením ResponseFormat vlastnosti AgentRunOptions během vyvolání nebo při inicializaci agenta pro agenty, které to podporují, jako například ChatClientAgent a Foundry Agent.
Tento přístup se dá použít v těchto případech:
- Typ strukturovaných výstupů není v době kompilace znám.
- Schéma je reprezentováno jako nezpracovaný JSON.
- Strukturované výstupy je možné konfigurovat 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}");
ResponseFormat lze zadat také 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ýstupy 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 AIProjectClient(
new Uri("<your-foundry-project-endpoint>"),
new DefaultAzureCredential())
.AsAIAgent(new ChatClientAgentOptions()
{
Name = "HelpfulAssistant",
ChatOptions = new()
{
ModelId = "gpt-4o-mini",
Instructions = "You are a helpful assistant.",
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ýstupy s agenty bez schopností strukturovaných výstupů
Někteří agenti nativně nepodporují strukturované výstupy, a to buď proto, že nejsou součástí protokolu, nebo proto, že agenti používají jazykové modely bez schopností strukturovaných výstupů. 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
Kompletní příklady s možností spuštění najdete v ukázkách .NET.
Příklad streamování
Návod
Kompletní příklady s možností spuštění najdete v ukázkách .NET.
Tento krok kurzu ukazuje, jak vytvořit strukturované výstupy pomocí agenta, kde je agent postaven na službě pro dokončování chatu OpenAI Azure.
Důležité
Ne všechny typy agentů podporují strukturované výstupy. Podporuje Agent strukturované výstupy při použití s kompatibilními chatovacími klienty.
Předpoklady
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ými výstupy
Agent je založen na jakékoli implementaci chatovacího klienta, která podporuje strukturované výstupy.
Agent používá klíč response_format ve slovníku options ke specifikaci požadovaného výstupního schématu.
Při spuštění agenta můžete zadat jednu z následujících možností:
- Pydantický model, který definuje strukturu očekávaného výstupu.
- Mapování schématu JSON (
dict), pokud chcete parsovat JSON bez definování třídy modelu.
Slovník můžete předat options za běhu pomocí agent.run(..., options={"response_format": ...}), nebo ho nastavit při vytváření agenta prostřednictvím slovníku default_options.
Různé formáty odpovědí se podporují na základě možností podkladového chatovacího klienta.
První příklad vytvoří agenta, který vytváří strukturované výstupy ve formě objektu JSON, který odpovídá schématu modelu Pydantic.
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í klienta chatu Azure OpenAI:
import os
from agent_framework.openai import OpenAIChatCompletionClient
from azure.identity import AzureCliCredential
# Create the agent using Azure OpenAI Chat Client
agent = OpenAIChatCompletionClient(
model=os.environ["AZURE_OPENAI_CHAT_COMPLETION_MODEL"],
azure_endpoint=os.environ["AZURE_OPENAI_ENDPOINT"],
api_version=os.getenv("AZURE_OPENAI_API_VERSION"),
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ých výstupů pomocí klíče response_format ve slovníku options.
response = await agent.run(
"Please provide information about John Smith, who is a 35-year-old software engineer.",
options={"response_format": PersonInfo},
)
U formátu odpovědi modelu Pydantic obsahuje odpověď agenta strukturované výstupy ve value vlastnosti jako instanci modelu:
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")
Použití mapování schématu JSON
Pokud už máte schéma JSON jako Python mapování, předejte toto schéma přímo jako hodnotu response_format v diktu options. V tomto režimu response.value obsahuje analyzovanou hodnotu JSON (obvykle a dict nebo list) místo instance modelu Pydantic.
person_info_schema = {
"type": "object",
"properties": {
"name": {"type": "string"},
"age": {"type": "integer"},
"occupation": {"type": "string"},
},
"required": ["name", "age", "occupation"],
}
response = await agent.run(
"Please provide information about John Smith, who is a 35-year-old software engineer.",
options={"response_format": person_info_schema},
)
if response.value:
person_info = response.value
print(f"Name: {person_info['name']}, Age: {person_info['age']}, Occupation: {person_info['occupation']}")
Při streamování vrátí agent.run(..., stream=True) hodnotu ResponseStream. Integrovaný finalizátor streamu automaticky zpracovává parsování strukturovaných výstupů, takže můžete iterovat aktualizacemi v reálném čase a pak zavolat get_final_response() pro získání parsované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}")
Stejné pravidlo platí, pokud response_format se jedná o mapování schématu JSON: final_response.value obsahuje analyzovaný JSON místo instance modelu Pydantic.
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 OpenAIChatClient
from pydantic import BaseModel
"""
OpenAI Responses Client with Structured Outputs Example
This sample demonstrates using structured outputs capabilities with OpenAI Responses Client,
showing Pydantic model integration for type-safe response parsing and data extraction.
"""
class OutputStruct(BaseModel):
"""A structured outputs model for testing purposes."""
city: str
description: str
async def non_streaming_example() -> None:
print("=== Non-streaming example ===")
agent = OpenAIChatClient().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 Outputs 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 = OpenAIChatClient().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 outputs parsed
result = await stream.get_final_response()
if structured_data := result.value:
print("Structured Outputs (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 Outputs ===")
await non_streaming_example()
await streaming_example()
if __name__ == "__main__":
asyncio.run(main())
Strukturovaný výstup
Agenti v jazyce Go podporují strukturovaný výstup pomocí možnosti agent.WithStructuredOutput. Definujte strukturu Go a framework automaticky vygeneruje schéma JSON a deserializuje odpověď.
Definování typu výstupu
type PersonInfo struct {
Name string `json:"name"`
Age int `json:"age"`
Occupation string `json:"occupation"`
}
Vyžádání strukturovaného výstupu
K volání agenta a deserializaci odpovědi použijte generickou pomocnou funkci:
import (
"context"
"fmt"
"github.com/microsoft/agent-framework-go/agent"
)
func runFor[T any](ctx context.Context, a *agent.Agent, message string, opts ...agent.Option) (T, error) {
var v T
opts = append(opts, agent.WithStructuredOutput(&v), agent.Stream(false))
for _, err := range a.RunText(ctx, message, opts...) {
if err != nil {
return v, err
}
}
return v, nil
}
person, err := runFor[PersonInfo](ctx, a,
"Please provide information about John Smith, who is a 35-year-old software engineer.")
fmt.Println("Name:", person.Name)
fmt.Println("Age:", person.Age)
Zadání formátu odpovědi na úrovni agenta
Formát odpovědi můžete nastavit také v konfiguraci agenta, aby všechna spuštění vytvářela strukturovaný výstup:
import "github.com/microsoft/agent-framework-go/agent/format/jsonformat"
a := foundryprovider.NewAgent(endpoint, token, foundryprovider.ModelDeployment(model), foundryprovider.AgentConfig{
Instructions: "You are a helpful assistant.",
Config: agent.Config{
RunOptions: []agent.Option{
agent.WithResponseFormat(jsonformat.MustFor[PersonInfo]()),
},
},
})
Návod
Kompletní příklad spustitelného souboru najdete v úplné ukázce .