使用工具扩展 OpenAI 并使用 .NET 执行本地函数
通过创建简单的 .NET 8 控制台聊天应用程序,开始使用 AI。 该应用程序将在本地运行并使用 OpenAI gpt-3.5-turbo
模型,使用工具通过调用本地 .NET 方法来扩展模型的功能。 按照以下步骤访问 OpenAI,并了解如何使用语义内核。
先决条件
- .NET 8.0 SDK - 安装 .NET 8.0 SDK。
- OpenAI 的 API 密钥,可以用于运行此示例。
- 在 Windows 上,必须安装 PowerShell
v7+
。 若要验证版本,请在终端中运行pwsh
。 它应返回当前版本。 如果返回错误,请执行以下命令dotnet tool update --global PowerShell
。
通过创建简单的 .NET 8 控制台聊天应用程序,开始使用 AI。 应用程序将在本地运行,并使用部署到 Azure OpenAI 帐户的 OpenAI gpt-35-turbo
模型。 它使用工具通过调用本地 .NET 方法来扩展模型的功能。 按照以下步骤预配 Azure OpenAI,并了解如何使用语义内核。
先决条件
- .NET 8 SDK - 安装 .NET 8 SDK。
- Azure 订阅 - 免费创建订阅。
- Azure Developer CLI - 安装或更新 Azure Developer CLI。
- 访问 Azure OpenAI 服务。
- 在 Windows 上,必须安装 PowerShell
v7+
。 若要验证版本,请在终端中运行pwsh
。 它应返回当前版本。 如果返回错误,请执行以下命令dotnet tool update --global PowerShell
。
获取示例项目
克隆 GitHub 存储库,其中包含用于所有快速入门的示例应用:
git clone https://github.com/dotnet/ai-samples.git
创建 Azure OpenAI 服务
示例 GitHub 存储库构造为 Azure Developer CLI (azd
) 模板,azd
可以使用此模板为你预配 Azure OpenAI 服务和模型。
从终端或命令提示符导航到示例存储库的 src\quickstarts\azure-openai 目录。
运行
azd up
命令来预配 Azure OpenAI 资源。 创建 Azure OpenAI 服务并部署模型可能需要几分钟。azd up
azd
还为示例应用配置所需的用户机密,例如 OpenAI 访问密钥。注意
如果在
azd up
部署期间遇到错误,请访问故障排除部分。
尝试徒步旅行者专业版示例
在终端或命令提示符下,导航到
azure-openai\04-HikerAIPro
目录。运行以下命令,将 OpenAI API 密钥配置为示例应用的机密:
dotnet user-secrets init dotnet user-secrets set OpenAIKey <your-openai-key>
使用
dotnet run
命令运行应用:dotnet run
在终端或命令提示符下,导航到
azure-openai\04-HikerAIPro
目录。使用
dotnet run
命令运行应用:dotnet run
提示
如果收到错误消息,表明 Azure OpenAI 资源可能尚未完成部署。 等待几分钟,然后重试。
了解代码
应用程序使用 Microsoft.SemanticKernel
包向 OpenAI 服务发送和接收请求。
整个应用程序包含在 Program.cs 文件中。 前几行代码设置配置值,并获取以前使用 dotnet user-secrets
命令设置的 OpenAI 密钥。
var config = new ConfigurationBuilder().AddUserSecrets<Program>().Build();
string model = "gpt-3.5-turbo";
string key = config["OpenAIKey"];
Kernel
类在 AddOpenAIChatCompletion
服务的帮助下便利了请求和响应。
// Create a Kernel containing the OpenAI Chat Completion Service
IKernelBuilder b = Kernel.CreateBuilder();
Kernel kernel = b
.AddOpenAIChatCompletion(model, key)
.Build();
应用程序使用 Microsoft.SemanticKernel
包向 OpenAI 服务发送和接收请求。
整个应用程序包含在 Program.cs 文件中。 前几行代码加载在应用程序预配期间在 dotnet user-secrets
中设置的机密和配置值。
var config = new ConfigurationBuilder().AddUserSecrets<Program>().Build();
string endpoint = config["AZURE_OPENAI_ENDPOINT"];
string deployment = config["AZURE_OPENAI_GPT_NAME"];
string key = config["AZURE_OPENAI_KEY"];
Kernel
类在 AzureOpenAIChatCompletion
服务的帮助下便利了请求和响应。
// Create a Kernel containing the Azure OpenAI Chat Completion Service
IKernelBuilder b = Kernel.CreateBuilder();
Kernel kernel = b
.AddAzureOpenAIChatCompletion(deployment, endpoint, key)
.Build();
函数 ImportPluginFromFunctions
和 CreateFromMethod
定义模型将调用的本地函数。
// Add a new plugin with a local .NET function that should be available to the AI model
// For convenience and clarity of into the code, this standalone local method handles tool call responses. It will fake a call to a weather API and return the current weather for the specified location.
kernel.ImportPluginFromFunctions("WeatherPlugin",
[
KernelFunctionFactory.CreateFromMethod(
([Description("The city, e.g. Montreal, Sidney")] string location, string unit = null) =>
{
// Here you would call a weather API to get the weather for the location
return "Periods of rain or drizzle, 15 C";
}, "get_current_weather", "Get the current weather in a given location")
]);
创建 kernel
客户端后,代码就会使用系统提示来提供上下文,并会影响补全的语气和内容。 注意系统提示中如何强调天气。
ChatHistory chatHistory = new("""
You are a hiking enthusiast who helps people discover fun hikes in their area.
You are upbeat and friendly. Good weather is important for a good hike.
Only make recommendations if the weather is good or if people insist.
You introduce yourself when first saying hello. When helping people out,
you always ask them for this information to inform the hiking recommendation you provide:
1. Where they are located
2. What hiking intensity they are looking for
You will then provide three suggestions for nearby hikes that vary in length
after you get that information. You will also share an interesting fact about the local
nature on the hikes when making a recommendation.
""");
应用还可使用 AddUserMessage
函数向模型添加用户消息。 GetChatMessageContentAsync
函数将聊天历史记录发送给模型,以根据系统和用户提示生成响应。
chatHistory.AddUserMessage("""
Is the weather is good today for a hike?
If yes, I live in the greater Montreal area and would like an easy hike.
I don't mind driving a bit to get there. I don't want the hike to be over 10 miles round trip.
I'd consider a point-to-point hike.
I want the hike to be as isolated as possible. I don't want to see many people.
I would like it to be as bug free as possible.
""");
Console.WriteLine($"{chatHistory.Last().Role} >>> {chatHistory.Last().Content}");
chatHistory.Add(await service.GetChatMessageContentAsync(
chatHistory,
new OpenAIPromptExecutionSettings()
{
MaxTokens = 400
}));
Console.WriteLine($"{chatHistory.Last().Role} >>> {chatHistory.Last().Content}");
自定义系统提示和用户消息,了解模型如何响应以帮助你找到你喜欢的徒步旅行。
清理资源
不再需要示例应用程序或资源时,请删除相应的部署和所有资源。
azd down
疑难解答
在 Windows 上,运行 azd up
后,可能会收到以下错误消息:
postprovision.ps1 未进行数字签名。 该脚本不会在系统上执行
执行脚本 postprovision.ps1 以设置应用程序中使用的 .NET 用户机密。 若要避免此错误,请运行以下 PowerShell 命令:
Set-ExecutionPolicy -Scope Process -ExecutionPolicy Bypass
然后,重新运行 azd up
命令。
另一个可能的错误:
“pwsh”没有被识别为内部或外部命令、可运行程序或批处理文件。 警告:“postprovision”挂钩失败,退出代码为“1”,路径:“.\infra\post-script\postprovision.ps1”。 :退出代码:1 执行将继续,因为 ContinueOnError 已设置为 true。
执行脚本 postprovision.ps1 以设置应用程序中使用的 .NET 用户机密。 若要避免此错误,请使用以下 PowerShell 命令手动运行脚本:
.\infra\post-script\postprovision.ps1
.NET AI 应用现已配置用户机密,可以对其进行测试。