Skip to content

Latest commit

 

History

History
211 lines (170 loc) · 7.4 KB

README.md

File metadata and controls

211 lines (170 loc) · 7.4 KB

OpenAI.Net
OpenAI.Net

An unofficial .NET API wrapper for OpenAI.

Discord Bots

Installation

Stable builds are available through NuGet.

Install-Package OpenAI.Net

Authentication

There are 3 ways to provide your API keys, in order of precedence:

  1. Pass keys directly to APIAuthentication(string key) constructor
  2. Set environment var for OPENAI_KEY
  3. Include a config file in the local directory or in your user directory named .openai and containing the line:
OPENAI_KEY=sk-yourapikey

You use the APIAuthentication when you initialize the API as shown:

var api = new OpenAIAPI("YOUR_API_KEY_HERE");
// or
var api = new OpenAIAPI(new APIAuthentication("sk-yourapikey")); // create object manually
// or
var api = new OpenAIAPI(APIAuthentication LoadFromEnv()); // use env vars
// or
var api = new OpenAIAPI(APIAuthentication LoadFromPath()); // use config file (optionally specify where to look)
// or
var api = new OpenAIAPI(); // uses default, env, or config file

Examples

You can view built examples in the samples folder. These examples include very basic access of endpoints, as well as versions of OpenAI's example applications using this wrapper.

Completions

Given a prompt, the model will return one or more predicted completions, and can also return the probabilities of alternative tokens at each position. View on OpenAI.

var api = new OpenAIAPI(apiKeys: "YOUR_API_KEY_HERE", engine: Engine.Davinci);

var request = new CompletionRequestBuilder()
    .WithPrompt("Once upon a time")
    .WithMaxTokens(5)
    .Build();

var result = await api.Completions.CreateCompletionAsync(request);
Console.WriteLine(result.ToString());
// Should print something like ", there was a girl who"

Searches

Given a query and a set of documents or labels, the model ranks each document based on its semantic similarity to the provided query. View on OpenAI.

var api = new OpenAIAPI(apiKeys: "YOUR_API_KEY_HERE", engine: Engine.Davinci);

var request = new SearchRequestBuilder()
    .WithQuery("the president")
    .WithDocuments(new List<string>
    {
        "White House",
        "hospital",
        "school"
    })
    .Build();

var result = await api.Search.GetBestMatchAsync(request);
Console.WriteLine(result);
// Should print "White House"

Classifications

Given a query and a set of labeled examples, the model will predict the most likely label for the query. Useful as a drop-in replacement for any ML classification or text-to-label task. View on OpenAI.

var api = new OpenAIAPI(apiKeys: "YOUR_API_KEY_HERE", engine: Engine.Davinci);

var request = new ClassificationRequestBuilder()
    .WithExamples(new List<List<string>>
    {
        new List<string> { "A happy moment", "Positive" },
        new List<string> { "I am sad.", "Negative" },
        new List<string> { "I am feeling awesome", "Positive" }
    })
    .WithLabels(new List<string>
    {
        "Positive", "Negative", "Neutral"
    })
    .WithQuery("It is a raining day :(")
    .WithSearchModel(Engine.Ada)
    .WithModel(Engine.Curie)
    .Build();

var result = await api.Classifications.CreateClassificationAsync(request);
Console.WriteLine(result.Label);
// Should print "Negative"

Answers

Given a question, a set of documents, and some examples, the API generates an answer to the question based on the information in the set of documents. This is useful for question-answering applications on sources of truth, like company documentation or a knowledge base. View on OpenAI.

var api = new OpenAIAPI(apiKeys: "YOUR_API_KEY_HERE", engine: Engine.Davinci);

var request = new AnswerRequestBuilder()
    .WithDocuments(new List<string>
    {
    	"Puppy A is happy.", "Puppy B is sad."
    })
    .WithQuestion("which puppy is happy?")
    .WithSearchModel(Engine.Ada)
    .WithModel(Engine.Curie)
    .WithExamplesContext("In 2017, U.S. life expectancy was 78.6 years.")
    .WithExamples(new List<List<string>>
    {
    	new List<string> { "What is human life expectancy in the United States?", "78 years." }
    })
    .WithMaxTokens(5)
    .WithStop(new List<string>
    {
    	"\n", "<|endoftext|>"
    })
    .Build();

var result = await api.Answers.CreateAnswerAsync(request);
Console.WriteLine(result.Answers[0]);
// Should print something like "puppy A."

Fine-tunes

Coming soon. Feel free to make a pull request.

Streaming

Streaming allows you to get results as they are generated, which can help your application feel more responsive, especially on slow models like Davinci.

Using async iterators:

IAsyncEnumerable<CompletionResult> StreamCompletionEnumerableAsync(CompletionRequest request)

// Example
await foreach (var token in api.Completions.StreamCompletionEnumerableAsync(new CompletionRequest("My name is Roger and I am a principal software engineer at Salesforce.  This is my resume:", 200, 0.5, presencePenalty: 0.1, frequencyPenalty: 0.1)))
{
	Console.Write(token);
}

Or if using .NET framework or C# <8.0:

StreamCompletionAsync(CompletionRequest request, Action<CompletionResult> resultHandler)

// Example
await api.Completions.StreamCompletionAsync(
	new CompletionRequest("My name is Roger and I am a principal software engineer at Salesforce.  This is my resume:", 200, 0.5, presencePenalty: 0.1, frequencyPenalty: 0.1),
	res => ResumeTextbox.Text += res.ToString());

Document Search

The Search API is accessed via OpenAIAPI.Search:

You can get all results as a dictionary using

GetSearchResultsAsync(SearchRequest request)

// Example
var request = new SearchRequest()
{
	Query = "Washington DC",
	Documents = new List<string> { "Canada", "China", "USA", "Spain" }
};
var result = await api.Search.GetSearchResultsAsync(request);
// result["USA"] == 294.22
// result["Spain"] == 73.81

The returned dictionary maps documents to scores. You can create your SearchRequest ahead of time or use one of the helper overloads for convenience, such as

GetSearchResultsAsync(string query, params string[] documents)

// Example
var result = await api.Search.GetSearchResultsAsync("Washington DC", "Canada", "China", "USA", "Spain");

You can get only the best match using

GetBestMatchAsync(request)

And if you only want the best match but still want to know the score, use

GetBestMatchWithScoreAsync(request)

Each of those methods has similar convenience overloads to specify the request inline.

Documentation

View the documentation on OpenAI. Feel free to add me on Discord Reverse#0069 if you have any questions. Better documentation may come later.

Credits

OkGoDoIt - Original fork from December 22, 2020.