[![.NET](https://yellow-cdn.veclightyear.com/2b54e442/5f69f40a-8de1-4aa7-9a58-991033897823.svg?branch=main)](https://github.com/jodendaal/OpenAI.Net/actions/workflows/dotnet-desktop.yml) [![NuGet Badge](https://buildstats.info/nuget/OpenAI.Net.Client)](https://www.nuget.org/packages/OpenAI.Net.Client) ![badge](https://img.shields.io/endpoint?url=https://gist.githubusercontent.com//jodendaal/1823aaf39c6273b92442849479616daf/raw/OpenAI.Net-code-coverage.json) [![Stryker Mutation testing badge](https://img.shields.io/endpoint?style=flat&url=https%3A%2F%2Fbadge-api.stryker-mutator.io%2Fgithub.com%2Fjodendaal%2FOpenAI.Net%2Fmain)](https://dashboard.stryker-mutator.io/reports/github.com/jodendaal/OpenAI.Net/main) [![license](https://yellow-cdn.veclightyear.com/2b54e442/2788c105-7e9e-4d7a-81d0-ce14e07203a6.svg)](https://github.com/jodendaal/OpenAI.Net/blob/main/LICENSE) [![Visitors](https://api.visitorbadge.io/api/visitors?path=https%3A%2F%2Fgithub.com%2Fjodendaal%2FOpenAI.Net&countColor=%2344be16&style=flat&labelStyle=lower)](https://visitorbadge.io/status?path=https%3A%2F%2Fgithub.com%2Fjodendaal%2FOpenAI.Net)
<img src="https://yellow-cdn.veclightyear.com/2b54e442/7b0c0532-c1ea-4b0f-9c4e-0d04be19db58.svg" alt="OpenAI" width="300"/>
# OpenAI.Net
我们的 .NET OpenAI 库专为使用 C# 轻松集成 OpenAI API 而设计。作为一个由社区维护的库,我们确保其保持最新并经过全面测试,支持 .NET Core 6.0 及以上版本。
通过直观的 API,我们的库简化了使用 OpenAI 强大自然语言处理工具的过程。此外,我们处理了 HTTP 客户端的使用,以防止套接字耗尽和 DNS 更新失败,确保开发人员享受顺畅且可靠的体验。我们的库还支持 OpenAI 流式 API,使开发人员能够实时处理和分析大量数据。
Youtube 教程:[使用 .NET 创建自己的 ChatGPT 克隆:一步步指南](https://www.youtube.com/watch?v=hRkVGSMijjs&t=51s)
# 开始使用
安装软件包 [Nuget package](https://www.nuget.org/packages/OpenAI.Net.Client)
```powershell
Install-Package OpenAI.Net.Client
使用提供的扩展方法注册服务
services.AddOpenAIServices(options => {
options.ApiKey = builder.Configuration["OpenAI:ApiKey"];
});
注意:我们建议使用环境变量、配置文件或密钥文件来安全地存储 API 密钥。详情请参见 这里。
示例使用
您可以查看使用流式 API 的控制台应用程序、Web 应用程序和 Blazor 应用程序的示例 这里。
您也可以查看集成测试中的使用示例 这里。
下面是一个简单的控制台应用程序示例。
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using OpenAI.Net;
namespace ConsoleApp
{
internal class Program
{
static async void Main(string[] args)
{
using var host = Host.CreateDefaultBuilder(args)
.ConfigureServices((builder, services) =>
{
services.AddOpenAIServices(options => {
options.ApiKey = builder.Configuration["OpenAI:ApiKey"];
});
})
.Build();
var openAi = host.Services.GetService<IOpenAIService>();
var response = await openAi.TextCompletion.Get("How long until we reach mars?");
if (response.IsSuccess)
{
foreach(var result in response.Result.Choices)
{
Console.WriteLine(result.Text);
}
}
else
{
Console.WriteLine($"{response.ErrorMessage}");
}
}
}
}
配置 Http 客户端选项
注册扩展允许通过 IHttpClientBuilder 接口配置 http 客户端。 这允许例如为添加 Polly 重试策略。请参见示例 这里。
services.AddOpenAIServices(options => {
options.ApiKey = builder.Configuration["OpenAI:ApiKey"];
},
(httpClientOptions) => {
httpClientOptions.AddPolicyHandler(GetRetryPolicy());
});
static IAsyncPolicy<HttpResponseMessage> GetRetryPolicy()
{
return HttpPolicyExtensions
.HandleTransientHttpError()
.WaitAndRetryAsync(3, retryAttempt => TimeSpan.FromSeconds(Math.Pow(2,
retryAttempt)));
}
示例
模型类型
模型类型字符串可以在 ModelTypes 类中找到。
ModelTypes.GPT35Turbo
完成
var response = await service.TextCompletion.Get("Say this is a test",(o) => {
o.MaxTokens = 1024;
o.BestOf = 2;
});
完成流
await foreach(var response in service.TextCompletion.GetStream("Say this is a test"))
{
Console.WriteLine(response?.Result?.Choices[0].Text);
}
使用数组输入完成
var prompts = new List<string>()
{
"Say this is a test",
"Say this is not a test"
};
var response = await service.TextCompletion.Get(prompts,(o) => {
o.MaxTokens = 1024;
o.BestOf = 2;
});
聊天
var messages = new List<Message>
{
Message.Create(ChatRoleType.System, "You are a helpful assistant."),
Message.Create(ChatRoleType.User, "Who won the world series in 2020?"),
Message.Create(ChatRoleType.Assistant, "The Los Angeles Dodgers won the World Series in 2020."),
Message.Create(ChatRoleType.User, "Where was it played?")
};
var response = await service.Chat.Get(messages,o => {
o.MaxTokens = 1000;
});
聊天流
var messages = new List<Message>
{
Message.Create(ChatRoleType.System, "You are a helpful assistant."),
Message.Create(ChatRoleType.User, "Who won the world series in 2020?"),
Message.Create(ChatRoleType.Assistant, "The Los Angeles Dodgers won the World Series in 2020。"),
Message.Create(ChatRoleType.User, "Where was it played?")
};
await foreach (var t in service.Chat.GetStream(messages))
{
Console.WriteLine(t?.Result?.Choices[0].Delta?.Content);
}
音频
获取转录
var response = await OpenAIService.Audio.GetTranscription(@"Audio\TestTranscription.m4a");
获取翻译
var response = await OpenAIService.Audio.GetTranslation(@"Audio\Translation.m4a");
文本编辑
var messages = new List<Message>
{
Message.Create(ChatRoleType.System, "You are a spell checker. Fix the spelling mistakes"),
Message.Create(ChatRoleType.User, "What day of the wek is it?"),
};
var response = await OpenAIService.Chat.Get(messages, o => {
o.MaxTokens = 1000;
});
图片编辑
使用文件路径
var response = await service.Images.Edit("A cute baby sea otter", @"Images\BabyCat.png", @"Images\Mask.png", o => {
o.N = 99;
});
使用文件字节
var imageBytes = File.ReadAllBytes("Images/BabyCat.png");
var maskBytes = File.ReadAllBytes("Images/Mask.png");
var response = await service.Images.Edit("A cute baby sea otter", imageBytes, maskBytes, o => {
o.N = 99;
});
```csharp
var response = await service.Images.Edit("A cute baby sea otter",File.ReadAllBytes(@"Images\BabyCat.png"), File.ReadAllBytes(@"Images\BabyCat.png"), o => {
o.N = 99;
});
图片生成
var response = await service.Images.Generate("A cute baby sea otter",2, "1024x1024");
图片变体
使用文件路径
var response = await service.Images.Variation(@"Images\BabyCat.png", o => {
o.N = 2;
o.Size = "1024x1024";
});
使用文件字节
var response = await service.Images.Variation(File.ReadAllBytes(@"Images\BabyCat.png"), o => {
o.N = 2;
o.Size = "1024x1024";
});
精调创建
var response = await service.FineTune.Create("myfile.jsonl", o => {
o.BatchSize = 1;
});
获取所有精调
var response = await service.FineTune.Get();
按ID获取精调
var response = await service.FineTune.Get("fineTuneId");
获取精调事件
var response = await service.FineTune.GetEvents("fineTuneId");
删除精调
var response = await service.FineTune.Delete("modelId");
取消精调
var response = await service.FineTune.Cancel("fineTuneId");
文件上传
使用文件路径
var response = await service.Files.Upload(@"Images\BabyCat.png");
使用文件字节
var response = await service.Files.Upload(bytes, "mymodel.jsonl");
获取文件内容
var response = await service.Files.GetContent("fileId");
获取文件详情
var response = await service.Files.Get("fileId");
获取所有文件
var response = await service.Files.Get();
文件删除
var response = await service.Files.Delete("1");
创建嵌入
var response = await service.Embeddings.Create("The food was delicious and the waiter...", "text-embedding-ada-002", "test");
获取所有模型
var response = await service.Models.Get();
按ID获取模型
var response = await service.Models.Get("babbage");
创建内容审核
var response = await service.Moderation.Create("input text", "test");
测试
该项目通过单元测试达到了100%的代码覆盖率,并通过了Stryker变异测试的100%通过率。
查看最新的Stryker报告这里。
我们还为每个服务进行了集成测试。
这应该能为该库的未来使用提供信心。
支持的API
完全支持所有当前的API
贡献
欢迎贡献。
对任何PR的最低要求。
-
必须包括单元测试并保持100%的覆盖率。
-
必须通过Stryker变异测试100%
-
应该有集成测试
请我喝咖啡
https://www.buymeacoffee.com/timdoestech?new=1