Compartir a través de


Generación de resultados estructurados con agentes

En este paso del tutorial se muestra cómo generar una salida estructurada con un agente, donde el agente se basa en el servicio de finalización de chat de Azure OpenAI.

Importante

No todos los tipos de agente admiten la salida estructurada. En este paso se usa un ChatClientAgent, que admite la salida estructurada.

Prerrequisitos

Para conocer los requisitos previos e instalar paquetes NuGet, consulte el paso Creación y ejecución de un agente sencillo en este tutorial.

Creación del agente con salida estructurada

ChatClientAgent se construye sobre cualquier implementación de IChatClient. ChatClientAgent utiliza el soporte para salida estructurada proporcionado por el cliente de chat subyacente.

Al crear el agente, tiene la opción de proporcionar la instancia predeterminada ChatOptions que se usará para el cliente de chat subyacente. Esta ChatOptions instancia le permite elegir una opción preferida ChatResponseFormat.

Hay disponibles varias opciones para ResponseFormat :

En este ejemplo se crea un agente que genera una salida estructurada en forma de un objeto JSON que se ajusta a un esquema específico.

La manera más fácil de generar el esquema es definir un tipo que represente la estructura de la salida que desee del agente y, a continuación, usar el AIJsonUtilities.CreateJsonSchema método para crear un esquema a partir del tipo.

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));

A continuación, puede crear una ChatOptions instancia que use este esquema para el formato de respuesta.

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")
};

Esta ChatOptions instancia se puede usar al crear el agente.

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
        });

Advertencia

DefaultAzureCredential es conveniente para el desarrollo, pero requiere una consideración cuidadosa en producción. En producción, considere usar una credencial específica (por ejemplo, ManagedIdentityCredential) para evitar problemas de latencia, sondeos de credenciales no deseados y posibles riesgos de seguridad de los mecanismos de respaldo.

Ahora puedes simplemente ejecutar el agente con información textual que el agente puede usar para rellenar la salida estructurada.

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

A continuación, la respuesta del agente se puede deserializar en la PersonInfo clase mediante el Deserialize<T> método en el objeto de respuesta.

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

Cuando se realiza una transmisión, la respuesta del agente se envía como una serie de actualizaciones, y solo se puede deserializar la respuesta una vez que se hayan recibido todas las actualizaciones. Debe ensamblar todas las actualizaciones en una única respuesta antes de deserializarla.

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);

Sugerencia

Consulte los ejemplos de .NET para obtener ejemplos completos de ejecución.

Ejemplo de streaming

Sugerencia

Consulte los ejemplos de .NET para obtener ejemplos completos de ejecución.

En este paso del tutorial se muestra cómo generar una salida estructurada con un agente, donde el agente se basa en el servicio de finalización de chat de Azure OpenAI.

Importante

No todos los tipos de agente admiten la salida estructurada. Agent admite la salida estructurada cuando se usa con clientes de chat compatibles.

Prerrequisitos

Para conocer los requisitos previos e instalar paquetes, consulte el paso Crear y ejecutar un agente sencillo en este tutorial.

Creación del agente con salida estructurada

Agent se construye sobre cualquier implementación de cliente de chat que admita la salida estructurada. Agent usa el response_format parámetro para especificar el esquema de salida deseado.

Al crear o ejecutar el agente, puede proporcionar un modelo Pydantic que defina la estructura de la salida esperada.

Se admiten varios formatos de respuesta en función de las funcionalidades subyacentes del cliente de chat.

En este ejemplo se crea un agente que genera una salida estructurada en forma de un objeto JSON que se ajusta a un esquema de modelo Pydantic.

En primer lugar, defina un modelo Pydantic que represente la estructura de la salida que desea del agente:

from pydantic import BaseModel

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

Ahora puede crear un agente mediante el cliente de chat de 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."
)

Ahora puede ejecutar el agente con información textual y especificar el formato de salida estructurado mediante el response_format parámetro :

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

La respuesta del agente contendrá la salida estructurada en la propiedad value, a la que se puede acceder directamente como instancia de modelo 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")

Cuando se transmite, agent.run(..., stream=True) devuelve un ResponseStream. El finalizador integrado de la secuencia maneja automáticamente el análisis de salida estructurada, por lo que puede iterar para obtener actualizaciones en tiempo real, y a continuación, llamar a get_final_response() para obtener el resultado analizado.

# 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}")

Si no necesita procesar actualizaciones de streaming individuales, puede omitir la iteración por completo; get_final_response() consumirá automáticamente la secuencia:

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}")

Ejemplo completo

# 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())

Pasos siguientes