Compartir a través de


Uso de herramientas funcionales con aprobaciones de intervención humana

En este paso del tutorial se muestra cómo usar herramientas de función que requieren aprobación humana con un agente, donde el agente se basa en el servicio de finalización de chat de Azure OpenAI.

Cuando los agentes requieren cualquier entrada de usuario, por ejemplo, para aprobar una llamada de función, esto se conoce como patrón human-in-the-loop. Una ejecución del agente que requiere la entrada del usuario, se completará con una respuesta que indica qué entrada es necesaria para el usuario, en lugar de completar con una respuesta final. El llamador del agente es entonces responsable de recuperar la entrada necesaria del usuario y devolverla al agente como parte de una nueva ejecución del agente.

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.

Crea el agente con herramientas funcionales

Al usar funciones, es posible indicar para cada función, si requiere aprobación humana antes de ejecutarse. Para ello, envuelve la instancia AIFunction en una instancia ApprovalRequiredAIFunction.

Este es un ejemplo de una herramienta de función simple que falsifica la obtención del tiempo para una ubicación determinada.

using System;
using System.ComponentModel;
using System.Linq;
using Azure.AI.OpenAI;
using Azure.Identity;
using Microsoft.Agents.AI;
using Microsoft.Extensions.AI;
using OpenAI;

[Description("Get the weather for a given location.")]
static string GetWeather([Description("The location to get the weather for.")] string location)
    => $"The weather in {location} is cloudy with a high of 15°C.";

Para crear un AIFunction y luego encapsularlo en un ApprovalRequiredAIFunction, puede hacer lo siguiente:

AIFunction weatherFunction = AIFunctionFactory.Create(GetWeather);
AIFunction approvalRequiredWeatherFunction = new ApprovalRequiredAIFunction(weatherFunction);

Al crear el agente, ahora puede proporcionar la función que requiere aprobación al agente pasando una lista de herramientas al método CreateAIAgent.

AIAgent agent = new AzureOpenAIClient(
    new Uri("https://<myresource>.openai.azure.com"),
    new AzureCliCredential())
     .GetChatClient("gpt-4o-mini")
     .CreateAIAgent(instructions: "You are a helpful assistant", tools: [approvalRequiredWeatherFunction]);

Puesto que ahora tiene una función que requiere aprobación, el agente puede responder con una solicitud de aprobación, en lugar de ejecutar la función directamente y devolver el resultado. Puede comprobar el contenido de la respuesta para cualquier FunctionApprovalRequestContent instancia, lo que indica que el agente requiere la aprobación del usuario para una función.

AgentThread thread = agent.GetNewThread();
AgentRunResponse response = await agent.RunAsync("What is the weather like in Amsterdam?", thread);

var functionApprovalRequests = response.Messages
    .SelectMany(x => x.Contents)
    .OfType<FunctionApprovalRequestContent>()
    .ToList();

Si hay solicitudes de aprobación de funciones, se puede encontrar el detalle de la llamada de función, incluidos el nombre y los argumentos, en la FunctionCall propiedad de la FunctionApprovalRequestContent instancia. Esto se puede mostrar al usuario para que pueda decidir si aprobar o rechazar la llamada de función. En este ejemplo, suponga que hay una solicitud.

FunctionApprovalRequestContent requestContent = functionApprovalRequests.First();
Console.WriteLine($"We require approval to execute '{requestContent.FunctionCall.Name}'");

Una vez que el usuario haya proporcionado su entrada, puede crear una FunctionApprovalResponseContent instancia mediante el CreateResponse método en FunctionApprovalRequestContent. Pase true para aprobar la llamada de función o false para rechazarla.

A continuación, el contenido de la respuesta se puede pasar al agente en un nuevo UserChatMessage, junto con el mismo objeto de hilo para recuperar el resultado del agente.

var approvalMessage = new ChatMessage(ChatRole.User, [requestContent.CreateResponse(true)]);
Console.WriteLine(await agent.RunAsync(approvalMessage, thread));

Siempre que use herramientas de funciones con aprobaciones humanas en el bucle, recuerde verificar las instancias de FunctionApprovalRequestContent en la respuesta, después de ejecutar cada agente, hasta que se hayan aprobado o rechazado todas las llamadas de funciones.

En este paso del tutorial se muestra cómo usar herramientas de función que requieren aprobación humana con un agente.

Cuando los agentes requieren cualquier entrada de usuario, por ejemplo, para aprobar una llamada de función, esto se conoce como patrón human-in-the-loop. Una ejecución del agente que requiere la entrada del usuario, se completará con una respuesta que indica qué entrada es necesaria para el usuario, en lugar de completar con una respuesta final. El llamador del agente es entonces responsable de recuperar la entrada necesaria del usuario y devolverla al agente como parte de una nueva ejecución del agente.

Prerrequisitos

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

Crea el agente con funcionalidades que requieren aprobación

Al usar funciones, es posible indicar para cada función, si requiere aprobación humana antes de ejecutarse. Esto se hace estableciendo el parámetro approval_mode a "always_require" cuando se usa el decorador @ai_function.

Este es un ejemplo de una herramienta de función simple que falsifica la obtención del tiempo para una ubicación determinada.

from typing import Annotated
from agent_framework import ai_function

@ai_function
def get_weather(location: Annotated[str, "The city and state, e.g. San Francisco, CA"]) -> str:
    """Get the current weather for a given location."""
    return f"The weather in {location} is cloudy with a high of 15°C."

Para crear una función que requiera aprobación, puede usar el approval_mode parámetro :

@ai_function(approval_mode="always_require")
def get_weather_detail(location: Annotated[str, "The city and state, e.g. San Francisco, CA"]) -> str:
    """Get detailed weather information for a given location."""
    return f"The weather in {location} is cloudy with a high of 15°C, humidity 88%."

Al crear el agente, ahora puede proporcionar la herramienta de función que requiere aprobación al agente pasando una lista de herramientas al constructor ChatAgent.

from agent_framework import ChatAgent
from agent_framework.openai import OpenAIResponsesClient

async with ChatAgent(
    chat_client=OpenAIResponsesClient(),
    name="WeatherAgent",
    instructions="You are a helpful weather assistant.",
    tools=[get_weather, get_weather_detail],
) as agent:
    # Agent is ready to use

Puesto que ahora tiene una función que requiere aprobación, el agente puede responder con una solicitud de aprobación, en lugar de ejecutar la función directamente y devolver el resultado. Puede comprobar la respuesta de las solicitudes de entrada del usuario, lo que indica que el agente requiere la aprobación del usuario para una función.

result = await agent.run("What is the detailed weather like in Amsterdam?")

if result.user_input_requests:
    for user_input_needed in result.user_input_requests:
        print(f"Function: {user_input_needed.function_call.name}")
        print(f"Arguments: {user_input_needed.function_call.arguments}")

Si hay solicitudes de aprobación de funciones, se puede encontrar el detalle de la llamada de función, incluidos el nombre y los argumentos, en la propiedad de la solicitud de entrada del usuario function_call. Esto se puede mostrar al usuario para que pueda decidir si aprobar o rechazar la llamada de función.

Una vez que el usuario haya proporcionado su entrada, puede crear una respuesta mediante el create_response método en la solicitud de entrada del usuario. Pase True para aprobar la llamada de función o False para rechazarla.

A continuación, la respuesta se puede pasar al agente en un nuevo ChatMessage, lo que permite obtener el resultado de vuelta desde el agente.

from agent_framework import ChatMessage, Role

# Get user approval (in a real application, this would be interactive)
user_approval = True  # or False to reject

# Create the approval response
approval_message = ChatMessage(
    role=Role.USER, 
    contents=[user_input_needed.create_response(user_approval)]
)

# Continue the conversation with the approval
final_result = await agent.run([
    "What is the detailed weather like in Amsterdam?",
    ChatMessage(role=Role.ASSISTANT, contents=[user_input_needed]),
    approval_message
])
print(final_result.text)

Manejo de aprobaciones en un bucle

Al trabajar con varias llamadas de función que requieren aprobación, es posible que tenga que controlar las aprobaciones en un bucle hasta que todas las funciones se aprueben o rechacen:

async def handle_approvals(query: str, agent) -> str:
    """Handle function call approvals in a loop."""
    current_input = query

    while True:
        result = await agent.run(current_input)

        if not result.user_input_requests:
            # No more approvals needed, return the final result
            return result.text

        # Build new input with all context
        new_inputs = [query]

        for user_input_needed in result.user_input_requests:
            print(f"Approval needed for: {user_input_needed.function_call.name}")
            print(f"Arguments: {user_input_needed.function_call.arguments}")

            # Add the assistant message with the approval request
            new_inputs.append(ChatMessage(role=Role.ASSISTANT, contents=[user_input_needed]))

            # Get user approval (in practice, this would be interactive)
            user_approval = True  # Replace with actual user input

            # Add the user's approval response
            new_inputs.append(
                ChatMessage(role=Role.USER, contents=[user_input_needed.create_response(user_approval)])
            )

        # Continue with all the context
        current_input = new_inputs

# Usage
result_text = await handle_approvals("Get detailed weather for Seattle and Portland", agent)
print(result_text)

Siempre que use herramientas de funciones con aprobaciones con humanos en el ciclo, recuerde comprobar si hay solicitudes de entrada de usuario en la respuesta después de ejecutar cada agente, hasta que todas las llamadas de funciones hayan sido aprobadas o rechazadas.

Pasos siguientes