将函数工具与代理配合使用

本教程步骤介绍如何将函数工具与代理配合使用,其中代理是在 Azure OpenAI 聊天完成服务上构建的。

重要

并非所有代理类型都支持函数工具。 有些可能仅支持自定义内置工具,而不允许调用方提供自己的函数。 此步骤使用一个 ChatClientAgent,它支持函数工具。

先决条件

有关先决条件和安装 NuGet 包,请参阅本教程中的 “创建并运行简单代理 ”步骤。

使用函数工具创建代理

函数工具只是希望代理在需要时能够调用的自定义代码。 可以通过使用AIFunctionFactory.Create方法从该方法创建AIFunction实例,将任何 C# 方法转换为函数工具。

如果需要向代理提供有关函数或其参数的其他说明,以便它可以更准确地在不同函数之间进行选择,则可以对方法及其参数使用 System.ComponentModel.DescriptionAttribute 属性。

下面是一个简单的函数工具示例,该工具用于模拟获取给定位置的天气。 它使用说明属性进行修饰,以向代理提供有关自身及其位置参数的其他说明。

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

创建代理时,现在可以通过将工具列表传递给 CreateAIAgent 方法来向代理提供函数工具。

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 AzureCliCredential())
     .GetChatClient("gpt-4o-mini")
     .CreateAIAgent(instructions: "You are a helpful assistant", tools: [AIFunctionFactory.Create(GetWeather)]);

现在,你可以像正常方式运行代理,并且代理在需要时能够调用 GetWeather 函数工具。

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

重要

并非所有代理类型都支持函数工具。 有些可能仅支持自定义内置工具,而不允许调用方提供自己的函数。 此步骤使用通过聊天客户端创建的代理,这些代理支持函数工具。

先决条件

有关先决条件和安装 Python 包,请参阅本教程中的 “创建并运行简单代理 ”步骤。

使用函数工具创建代理

函数工具只是希望代理在需要时能够调用的自定义代码。 可以通过在创建代理时将其传递给代理 tools 的参数,将任何 Python 函数转换为函数工具。

如果需要向代理提供有关函数或其参数的其他说明,以便它可以更准确地在不同的函数之间进行选择,可以使用 Python 的类型注释和 Annotated Pydantic 提供 Field 说明。

下面是一个简单的函数工具示例,该工具用于模拟获取给定位置的天气。 它使用类型注释向代理提供有关函数及其位置参数的其他说明。

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

还可以使用 ai_function 修饰器显式指定函数的名称和说明:

from typing import Annotated
from pydantic import Field
from agent_framework import ai_function

@ai_function(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."

如果你没有在name修饰器中指定descriptionai_function参数,框架将会自动使用函数的名称和文档字符串作为回退。

现在在创建代理时,可以通过将函数工具传递到 tools 参数来为代理提供功能。

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

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

现在,你可以像正常方式运行代理,并且代理在需要时能够调用 get_weather 函数工具。

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

asyncio.run(main())

使用多个函数工具创建类

还可以创建包含多个函数工具作为方法的类。 这对于将相关函数组织在一起或想要在它们之间传递状态时非常有用。


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

创建代理时,现在可以将类的所有方法作为函数提供:

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

还可以使用与以前相同的 ai_function 修饰器修饰函数。

后续步骤