目录
介绍
本周,OpenAI推出了GPT4-turbo、GPT、GPT Store等。他们还发布了名为Assistant API的新API。它是新的,没有C#库。所以,我开发了它。
我添加了助手流式处理API支持!请检查一下!
如何使用?
通过Nuget下载
HigLabo.OpenAI
HigLabo.OpenAI就是。
您可以在以下位置查看示例代码:
主类是OpenAIClient。为OpenAI API创建OpenAIClient类。
var apiKey = "your api key of OpenAI";
var cl = new OpenAIClient(apiKey);
对于Azure终结点。
var apiKey = "your api key of OpenAI";
var cl = new OpenAIClient(new AzureSettings
(apiKey, "https://tinybetter-work-for-our-future.openai.azure.com/", "MyDeploymentName"));
调用ChatCompletion终结点。
var cl = new OpenAIClient("API KEY");
var p = new ChatCompletionsParameter();
p.Messages.Add(new ChatMessage(ChatMessageRole.User, $"How to enjoy coffee?"));
p.Model = "gpt-4";
var res = await cl.ChatCompletionsAsync(p);
foreach (var choice in res.Choices)
{
Console.Write(choice.Message.Content);
}
Console.WriteLine();
Console.WriteLine();
Console.WriteLine("----------------------------------------");
Console.WriteLine("Total tokens: " + res.Usage.Total_Tokens);
使用具有服务器发送事件的ChatCompletion终结点。
var cl = new OpenAIClient("API KEY");
var result = new ChatCompletionStreamResult();
await foreach (string text in cl.ChatCompletionsStreamAsync("How to enjoy coffee?", "gpt-4", result, CancellationToken.None))
{
Console.Write(text);
}
Console.WriteLine();
Console.WriteLine("Finish reason: " + result.GetFinishReason());
带有函数调用的ChatCompletion。
var cl = new OpenAIClient("API KEY");
var p = new ChatCompletionsParameter();
//ChatGPT can correct Newyork,Sanflansisco to New york and San Flancisco.
p.Messages.Add(new ChatMessage(ChatMessageRole.User,
$"I want to know the whether of these locations. Newyork, Sanflansisco, Paris, Tokyo."));
p.Model = "gpt-4";
{
var tool = new ToolObject("function");
tool.Function = new FunctionObject();
tool.Function.Name = "getWhether";
tool.Function.Description = "This service can get whether of specified location.";
tool.Function.Parameters = new
{
type = "object",
properties = new
{
locationList = new
{
type = "array",
description = "Location list that you want to know.",
items = new
{
type = "string",
}
}
}
};
p.Tools = new List<ToolObject>();
p.Tools.Add(tool);
}
{
var tool = new ToolObject("function");
tool.Function = new FunctionObject();
tool.Function.Name = "getLatLong";
tool.Function.Description =
"This service can get latitude and longitude of specified location.";
tool.Function.Parameters = new
{
type = "object",
properties = new
{
locationList = new
{
type = "array",
description = "Location list that you want to know.",
items = new
{
type = "string",
}
}
}
};
p.Tools = new List<ToolObject>();
p.Tools.Add(tool);
}
var result = new ChatCompletionStreamResult();
await foreach (var text in cl.ChatCompletionsStreamAsync(p, result, CancellationToken.None))
{
Console.Write(text);
}
Console.WriteLine();
foreach (var f in result.GetFunctionCallList())
{
Console.WriteLine("Function name is " + f.Name);
Console.WriteLine("Arguments is " + f.Arguments);
}
通过ChatCompletion终结点使用视觉API。
var cl = new OpenAIClient("API KEY");
var p = new ChatCompletionsParameter();
var message = new ChatImageMessage(ChatMessageRole.User);
message.AddTextContent("Please describe this image.");
message.AddImageFile(Path.Combine(Environment.CurrentDirectory, "Image", "Pond.jpg"));
p.Messages.Add(message);
p.Model = "gpt-4-vision-preview";
p.Max_Tokens = 300;
var result = new ChatCompletionStreamResult();
await foreach (var text in cl.ChatCompletionsStreamAsync(p, result, CancellationToken.None))
{
Console.Write(text);
}
上传文件进行微调或传递给助手。
var p = new FileUploadParameter();
p.File.SetFile("my_file.pdf", File.ReadAllBytes("D:\\Data\\my_file.pdf"));
p.Purpose = "assistants";
var res = await client.FileUploadAsync(p);
Console.WriteLine(res);
图像生成。
var cl = new OpenAIClient("API KEY");
var res = await cl.ImagesGenerationsAsync("Blue sky and green field.");
foreach (var item in res.Data)
{
Console.WriteLine(item.Url);
}
通过API创建Assistant。
var cl = new OpenAIClient("API KEY");
var p = new AssistantCreateParameter();
p.Name = "Legal tutor";
p.Instructions = "You are a personal legal tutor.
Write and run code to legal questions based on passed files.";
p.Model = "gpt-4-1106-preview";
p.Tools = new List<ToolObject>();
p.Tools.Add(new ToolObject("code_interpreter"));
p.Tools.Add(new ToolObject("retrieval"));
var res = await cl.AssistantCreateAsync(p);
Console.WriteLine(res);
将文件添加到助手。
var cl = new OpenAIClient("API KEY");
var res = await cl.FilesAsync();
foreach (var item in res.Data)
{
if (item.Purpose == "assistants")
{
var res1 = await cl.AssistantFileCreateAsync(id, item.Id);
}
}
调用Assistant流式处理API。
var assistantId = "your assistant Id";
var threadId = "your thread Id";
if (threadId.Length == 0)
{
var res = await cl.ThreadCreateAsync();
threadId = res.Id;
}
{
var p = new MessageCreateParameter();
p.Thread_Id = threadId;
p.Role = "user";
p.Content = "Hello! I want to know how to use OpenAI assistant API
to get stream response.";
var res = await cl.MessageCreateAsync(p);
}
{
var p = new RunCreateParameter();
p.Assistant_Id = assistantId;
p.Thread_Id = threadId;
p.Stream = true;
var result = new AssistantMessageStreamResult();
await foreach (string text in cl.RunCreateStreamAsync
(p, result, CancellationToken.None))
{
Console.Write(text);
}
Console.WriteLine();
// You can get each server sent event value by these property.
Console.WriteLine(JsonConvert.SerializeObject(result.Thread));
Console.WriteLine(JsonConvert.SerializeObject(result.Run));
Console.WriteLine(JsonConvert.SerializeObject(result.RunStep));
Console.WriteLine(JsonConvert.SerializeObject(result.Message));
}
类体系结构
主要类别有:
- OpenAIClient
- XXXParameter
- XXXAsync
- XXXResponse
- RestApiResponse
- QueryParameter
OpenAIClient
此类管理api密钥和调用终结点。
可以在intellisense中将所有终结点视为方法。
我为所有端点提供具有必需参数的方法。这些是调用终结点的最简单方法。
var res = await cl.AudioTranscriptionsAsync("GoodMorningItFineDayToday.mp3"
, new MemoryStream(File.ReadAllBytes("D:\\Data\\Dev\\GoodMorningItFineDayToday.mp3"))
, "whisper-1");
OpenAI提供三种类型的端点。这些内容类型是json、form-data和server-sent-event。例子就在那里。
Json端点:
表单数据端点:
流终结点:
因此,我提供了SendJsonAsync、SendFormDataAsync、GetStreamAsync方法来调用这些端点。这些类管理http标头和content-type并正确处理响应。
您可以使用传递参数对象来调用端点。
var p = new AudioTranscriptionsParameter();
p.File.SetFile("GoodMorningItFineDayToday.mp3",
new MemoryStream(File.ReadAllBytes("D:\\Data\\Dev\\GoodMorningItFineDayToday.mp3")));
p.Model = "whisper-1";
var res = await cl.SendFormDataAsync<AudioTranscriptionsParameter,
AudioTranscriptionsResponse>(p, CancellationToken.None);
但是这个方法需要参数和响应的类型,所以我提供了易于使用的方法。
var p = new AudioTranscriptionsParameter();
p.File.SetFile("GoodMorningItFineDayToday.mp3",
new MemoryStream(File.ReadAllBytes("D:\\Data\\Dev\\GoodMorningItFineDayToday.mp3")));
p.Model = "whisper-1";
var res = await cl.AudioTranscriptionsAsync(p);
XXX测量仪
我提供了表示端点所有值的参数类。
例如,这是创建助手终结点。
这是AssistantCreateParameter类。
/// <summary>
/// Create an assistant with a model and instructions.
/// <seealso href="https://api.openai.com/v1/assistants">
/// https://api.openai.com/v1/assistants</seealso>
/// </summary>
public partial class AssistantCreateParameter : RestApiParameter, IRestApiParameter
{
string IRestApiParameter.HttpMethod { get; } = "POST";
/// <summary>
/// ID of the model to use. You can use the List models API to see all of
/// your available models, or see our Model overview for descriptions of them.
/// </summary>
public string Model { get; set; } = "";
/// <summary>
/// The name of the assistant. The maximum length is 256 characters.
/// </summary>
public string? Name { get; set; }
/// <summary>
/// The description of the assistant. The maximum length is 512 characters.
/// </summary>
public string? Description { get; set; }
/// <summary>
/// The system instructions that the assistant uses.
/// The maximum length is 32768 characters.
/// </summary>
public string? Instructions { get; set; }
/// <summary>
/// A list of tool enabled on the assistant.
/// There can be a maximum of 128 tools per assistant.
/// Tools can be of types code_interpreter, retrieval, or function.
/// </summary>
public List<ToolObject>? Tools { get; set; }
/// <summary>
/// A list of file IDs attached to this assistant.
/// There can be a maximum of 20 files attached to the assistant.
/// Files are ordered by their creation date in ascending order.
/// </summary>
public List<string>? File_Ids { get; set; }
/// <summary>
/// Set of 16 key-value pairs that can be attached to an object.
/// This can be useful for storing additional information about the object
/// in a structured format. Keys can be a maximum of 64 characters long
/// and values can be a maximum of 512 characters long.
/// </summary>
public object? Metadata { get; set; }
string IRestApiParameter.GetApiPath()
{
return $"/assistants";
}
public override object GetRequestBody()
{
return new {
model = this.Model,
name = this.Name,
description = this.Description,
instructions = this.Instructions,
tools = this.Tools,
file_ids = this.File_Ids,
metadata = this.Metadata,
};
}
}
这些参数类是从API文档生成的。您可以在 Github上看到实际的生成器代码。
XXXAsync
生成这些方法。我生成了四种方法,您可以轻松调用这些方法。
AssistantCreate终结点的示例。
public async ValueTask<AssistantCreateResponse> AssistantCreateAsync(string model)
public async ValueTask<AssistantCreateResponse>
AssistantCreateAsync(string model, CancellationToken cancellationToken)
public async ValueTask<AssistantCreateResponse>
AssistantCreateAsync(AssistantCreateParameter parameter)
public async ValueTask<AssistantCreateResponse>
AssistantCreateAsync(AssistantCreateParameter parameter,
CancellationToken cancellationToken)
从本质上讲,有两种类型的方法。
一种是传递值仅需要参数。
AssistantCreate终结点所需的模型。因此,我生成:
public async ValueTask<AssistantCreateResponse> AssistantCreateAsync(string model)
此方法易于使用,只需使用必需的参数即可调用终结点。
另一个可以使用所有参数值调用api端点。
您可以像这样创建参数:
var p = new AssistantCreateParameter();
p.Name = "Legal tutor";
p.Instructions = "You are a personal legal tutor.
Write and run code to legal questions based on passed files.";
p.Model = "gpt-4-1106-preview";
p.Tools = new List<ToolObject>();
p.Tools.Add(new ToolObject("code_interpreter"));
p.Tools.Add(new ToolObject("retrieval"));
并将其传递给方法。
var res = await cl.AssistantCreateAsync(p);
XXXResponse
响应类表示api端点的实际响应数据。
例如,Retrieve assistant终结点返回assistant对象。
我提供AssistantObjectResponse。(我创建了这个类,而不是代码生成。
public class AssistantObjectResponse: RestApiResponse
{
public string Id { get; set; } = "";
public int Created_At { get; set; }
public DateTimeOffset CreateTime
{
get
{
return new DateTimeOffset
(DateTime.UnixEpoch.AddSeconds(this.Created_At), TimeSpan.Zero);
}
}
public string Name { get; set; } = "";
public string Description { get; set; } = "";
public string Model { get; set; } = "";
public string Instructions { get; set; } = "";
public List<ToolObject> Tools { get; set; } = new();
public List<string>? File_Ids { get; set; }
public object? MetaData { get; set; }
public override string ToString()
{
return $"{this.Id}\r\n{this.Name}\r\n{this.Instructions}";
}
}
您可以获取api endpoint的响应值。
RestApi响应
有时,您希望获取响应的元数据。您可以获取响应文本、创建此响应的请求对象等。
这是RestApiResponse类。
public abstract class RestApiResponse : IRestApiResponse
{
object? IRestApiResponse.Parameter
{
get { return _Parameter; }
}
HttpRequestMessage IRestApiResponse.Request
{
get { return _Request!; }
}
string IRestApiResponse.RequestBodyText
{
get { return _RequestBodyText; }
}
HttpStatusCode IRestApiResponse.StatusCode
{
get { return _StatusCode; }
}
Dictionary<String, String> IRestApiResponse.Headers
{
get { return _Headers; }
}
string IRestApiResponse.ResponseBodyText
{
get { return _ResponseBodyText; }
}
}
这些属性是隐藏属性。您可以通过投射到RestApiResponse类来访问它:
var p = new AssistantCreateParameter();
p.Name = "Legal tutor";
p.Instructions = "You are a personal legal tutor.
Write and run code to legal questions based on passed files.";
p.Model = "gpt-4-1106-preview";
var res = await cl.AssistantCreateAsync(p);
var iRes = res as RestApiResponse;
var responseText = iRes.ResponseBodyText;
Dictionary<string, string> responseHeaders = iRes.Headers;
var parameter = iRes.Parameter as AssistantCreateParameter;
您可以通过RestApiResponse将响应文本记录到您自己的日志数据库中。
QueryParameter
一些api端点提供过滤器、分页功能。您可以按QueryParameter类指定条件。
您可以按如下方式指定顺序:
var p = new MessagesParameter();
p.Thread_Id = "thread_xxxxxxxxxxxx";
p.QueryParameter.Order = "asc";
结论
我对OpenAI GPT、GPT商店等感到非常兴奋。如果你也对OpenAI感兴趣,我的库可能会对你的工作有所帮助。使用愉快!
https://www.codeproject.com/Articles/5372480/Csharp-OpenAI-Library-that-Supports-Assistants-str