本教程步骤演示如何使用代理生成结构化输出,其中代理是在 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 AzureCliCredential())
.GetChatClient("gpt-4o-mini")
.CreateAIAgent(new ChatClientAgentOptions()
{
Name = "HelpfulAssistant",
Instructions = "You are a helpful assistant.",
ChatOptions = chatOptions
});
现在,您只需使用可用于填充结构化输出的一些文本信息来启动代理。
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.ToAgentRunResponseAsync()).Deserialize<PersonInfo>(JsonSerializerOptions.Web);
本教程步骤演示如何使用代理生成结构化输出,其中代理是在 Azure OpenAI 聊天完成服务上构建的。
重要
并非所有代理类型都支持结构化输出。 与兼容的聊天客户端一起使用时,支持 ChatAgent 结构化输出。
先决条件
有关先决条件和安装包,请参阅本教程中的 “创建并运行简单代理 ”步骤。
使用结构化输出创建代理
ChatAgent 基于支持结构化输出的任何聊天客户端实现来构建。
使用 ChatAgent 的 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()).create_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")
流式处理时,代理响应会以一系列更新的形式流式传输。 若要获取结构化输出,必须收集所有更新,然后访问最终的响应值:
from agent_framework import AgentRunResponse
# Get structured response from streaming agent using AgentRunResponse.from_agent_response_generator
# This method collects all streaming updates and combines them into a single AgentRunResponse
final_response = await AgentRunResponse.from_agent_response_generator(
agent.run_stream(query, response_format=PersonInfo),
output_format_type=PersonInfo,
)
if final_response.value:
person_info = final_response.value
print(f"Name: {person_info.name}, Age: {person_info.age}, Occupation: {person_info.occupation}")