Condividi tramite


Utilizzo degli strumenti funzionali con un agente

Questo passaggio dell'esercitazione illustra come usare gli strumenti delle funzioni con un agente, in cui l'agente è costruito su il servizio Completamento chat OpenAI di Azure.

Importante

Non tutti i tipi di agente supportano gli strumenti delle funzioni. Alcuni potrebbero supportare solo strumenti predefiniti personalizzati, senza consentire al chiamante di fornire le proprie funzioni. Questo passaggio usa un ChatClientAgent, che supporta gli strumenti funzionali.

Prerequisiti

Per i prerequisiti e l'installazione dei pacchetti NuGet, vedere il passaggio Creare ed eseguire un agente semplice in questa esercitazione.

Creare l'agente con gli strumenti per le funzioni

Gli strumenti delle funzioni sono solo codice personalizzato che si desidera che l'agente possa invocare quando necessario. È possibile trasformare qualsiasi metodo C# in uno strumento funzione usando il AIFunctionFactory.Create metodo per creare un'istanza AIFunction dal metodo .

Se è necessario fornire descrizioni aggiuntive sulla funzione o sui relativi parametri per l'agente, in modo che possa scegliere in modo più accurato tra funzioni diverse, è possibile usare l'attributo System.ComponentModel.DescriptionAttribute nel metodo e i relativi parametri.

Ecco un esempio di uno strumento di funzione semplice che fa finta di ottenere il meteo per una determinata posizione. Viene decorato con attributi di descrizione per fornire descrizioni aggiuntive su se stesso e il relativo parametro di posizione per l'agente.

using System.ComponentModel;

[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.";

Quando crei l'agente, puoi ora fornire lo strumento di funzione passando un elenco di strumenti al metodo AsAIAgent.

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

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

Avviso

DefaultAzureCredential è utile per lo sviluppo, ma richiede un'attenta considerazione nell'ambiente di produzione. Nell'ambiente di produzione prendere in considerazione l'uso di credenziali specifiche ,ad esempio ManagedIdentityCredential, per evitare problemi di latenza, probe di credenziali indesiderate e potenziali rischi per la sicurezza dai meccanismi di fallback.

Ora è possibile eseguire l'agente come di consueto e l'agente sarà in grado di chiamare la funzione dello strumento GetWeather quando necessario.

Console.WriteLine(await agent.RunAsync("What is the weather like in Amsterdam?"));

Importante

Non tutti i tipi di agente supportano gli strumenti delle funzioni. Alcuni potrebbero supportare solo strumenti predefiniti personalizzati, senza consentire al chiamante di fornire le proprie funzioni. Questo passaggio usa gli agenti creati tramite client di chat, che supportano gli strumenti per le funzioni.

Prerequisiti

Per i prerequisiti e l'installazione dei pacchetti Python, vedere il passaggio Creare ed eseguire un agente semplice in questa esercitazione.

Creare l'agente con gli strumenti per le funzioni

Gli strumenti delle funzioni sono solo codice personalizzato che si desidera che l'agente possa invocare quando necessario. È possibile trasformare qualsiasi funzione Python in uno strumento di funzione passandola al parametro dell'agente tools durante la creazione dell'agente.

Se è necessario fornire descrizioni aggiuntive sulla funzione o sui relativi parametri per l'agente, in modo che possa scegliere in modo più accurato tra funzioni diverse, è possibile usare le annotazioni dei tipi di Annotated Python con Field e Pydantic per fornire descrizioni.

Ecco un esempio di uno strumento di funzione semplice che fa finta di ottenere il meteo per una determinata posizione. Usa annotazioni di tipo per fornire descrizioni aggiuntive sulla funzione e il relativo parametro location all'agente.

from typing import Annotated
from pydantic import Field

def get_weather(
    location: Annotated[str, Field(description="The location to get the weather for.")],
) -> str:
    """Get the weather for a given location."""
    return f"The weather in {location} is cloudy with a high of 15°C."

È anche possibile usare l'elemento @tool Decorator per specificare in modo esplicito il nome e la descrizione della funzione:

from typing import Annotated
from pydantic import Field
from agent_framework import tool

@tool(name="weather_tool", description="Retrieves weather information for any location")
def get_weather(
    location: Annotated[str, Field(description="The location to get the weather for.")],
) -> str:
    return f"The weather in {location} is cloudy with a high of 15°C."

Se non si specificano i parametri name e description nel decoratore @tool, il framework userà automaticamente il nome della funzione e la sua docstring come fallback.

Quando si crea l'agente, è ora possibile fornire lo strumento funzione all'agente passandolo al parametro tools.

import asyncio
from agent_framework.azure import AzureOpenAIChatClient
from azure.identity import AzureCliCredential

agent = AzureOpenAIChatClient(credential=AzureCliCredential()).as_agent(
    instructions="You are a helpful assistant",
    tools=get_weather
)

Ora è possibile eseguire l'agente come di consueto e l'agente sarà in grado di chiamare la funzione dello strumento get_weather quando necessario.

async def main():
    result = await agent.run("What is the weather like in Amsterdam?")
    print(result.text)

asyncio.run(main())

Creare una classe con più strumenti per le funzioni

È anche possibile creare una classe che contiene più strumenti di funzione come metodi. Questo può essere utile per organizzare le funzioni correlate insieme o quando si desidera passare lo stato tra di essi.


class WeatherTools:
    def __init__(self):
        self.last_location = None

    def get_weather(
        self,
        location: Annotated[str, Field(description="The location to get the weather for.")],
    ) -> str:
        """Get the weather for a given location."""
        return f"The weather in {location} is cloudy with a high of 15°C."

    def get_weather_details(self) -> int:
        """Get the detailed weather for the last requested location."""
        if self.last_location is None:
            return "No location specified yet."
        return f"The detailed weather in {self.last_location} is cloudy with a high of 15°C, low of 7°C, and 60% humidity."

Quando si crea l'agente, è ora possibile fornire tutti i metodi della classe come funzioni:

tools = WeatherTools()
agent = AzureOpenAIChatClient(credential=AzureCliCredential()).as_agent(
    instructions="You are a helpful assistant",
    tools=[tools.get_weather, tools.get_weather_details]
)

È anche possibile decorare le funzioni con lo stesso @tool decorator di prima.

Esempio completo

# Copyright (c) Microsoft. All rights reserved.

import asyncio
from typing import Annotated, Any

from agent_framework import tool
from agent_framework.openai import OpenAIResponsesClient
from pydantic import Field

"""
AI Function with kwargs Example

This example demonstrates how to inject custom keyword arguments (kwargs) into an AI function
from the agent's run method, without exposing them to the AI model.

This is useful for passing runtime information like access tokens, user IDs, or
request-specific context that the tool needs but the model shouldn't know about
or provide.
"""


# Define the function tool with **kwargs to accept injected arguments
# NOTE: approval_mode="never_require" is for sample brevity. Use "always_require" in production; see samples/02-agents/tools/function_tool_with_approval.py and samples/02-agents/tools/function_tool_with_approval_and_sessions.py.
@tool(approval_mode="never_require")
def get_weather(
    location: Annotated[str, Field(description="The location to get the weather for.")],
    **kwargs: Any,
) -> str:
    """Get the weather for a given location."""
    # Extract the injected argument from kwargs
    user_id = kwargs.get("user_id", "unknown")

    # Simulate using the user_id for logging or personalization
    print(f"Getting weather for user: {user_id}")

    return f"The weather in {location} is cloudy with a high of 15°C."


async def main() -> None:
    agent = OpenAIResponsesClient().as_agent(
        name="WeatherAgent",
        instructions="You are a helpful weather assistant.",
        tools=[get_weather],
    )

    # Pass the injected argument when running the agent
    # The 'user_id' kwarg will be passed down to the tool execution via **kwargs
    response = await agent.run("What is the weather like in Amsterdam?", user_id="user_123")

    print(f"Agent: {response.text}")


if __name__ == "__main__":
    asyncio.run(main())
# Copyright (c) Microsoft. All rights reserved.

import asyncio
from typing import Annotated, Any

from agent_framework import tool
from agent_framework.openai import OpenAIResponsesClient
from pydantic import Field

"""
AI Function with kwargs Example

This example demonstrates how to inject custom keyword arguments (kwargs) into an AI function
from the agent's run method, without exposing them to the AI model.

This is useful for passing runtime information like access tokens, user IDs, or
request-specific context that the tool needs but the model shouldn't know about
or provide.
"""


# Define the function tool with **kwargs to accept injected arguments
# NOTE: approval_mode="never_require" is for sample brevity. Use "always_require" in production; see samples/02-agents/tools/function_tool_with_approval.py and samples/02-agents/tools/function_tool_with_approval_and_sessions.py.
@tool(approval_mode="never_require")
def get_weather(
    location: Annotated[str, Field(description="The location to get the weather for.")],
    **kwargs: Any,
) -> str:
    """Get the weather for a given location."""
    # Extract the injected argument from kwargs
    user_id = kwargs.get("user_id", "unknown")

    # Simulate using the user_id for logging or personalization
    print(f"Getting weather for user: {user_id}")

    return f"The weather in {location} is cloudy with a high of 15°C."


async def main() -> None:
    agent = OpenAIResponsesClient().as_agent(
        name="WeatherAgent",
        instructions="You are a helpful weather assistant.",
        tools=[get_weather],
    )

    # Pass the injected argument when running the agent
    # The 'user_id' kwarg will be passed down to the tool execution via **kwargs
    response = await agent.run("What is the weather like in Amsterdam?", user_id="user_123")

    print(f"Agent: {response.text}")


if __name__ == "__main__":
    asyncio.run(main())

Passaggi successivi