OpenAI-API-dotnet icon indicating copy to clipboard operation
OpenAI-API-dotnet copied to clipboard

Add Function calling

Open techjb opened this issue 2 years ago • 9 comments

OpenAI has recently added Functions calling. Would be amazing to have it implemented on this library.

techjb avatar Jun 14 '23 04:06 techjb

I started looking into this and had some quick success with setting it up with NJsonSchema. Not sure if Newtonsoft provides anything similar, but I've got a working fork I scrambled together now if you want to test it out.

hansjm10 avatar Jun 14 '23 05:06 hansjm10

I was working towards doing something like this manually ("You can call me as you would a SQL API and I will respond with the data you need to answer the query".) It would be really cool is to actually take it a step further.. and have it call back into an actual function. ie:

decimal GetTodaysTemperatureInCelcius(string zipCode) { return 23.4; }
var results = await api.Chat.CreateChatCompletionAsync(new ChatRequest()
      {
          Model = Model.ChatGPTTurbo0613,
          Temperature = 0.2,
          MaxTokens = 2000,
          Messages = Messages
      },
      GetTodaysTemperatureInCelcius
);

Then, if ChatGPT comes back with a function call, CreateChatCompletionAsync could use DynamicInvoke on the function(s) you pass in - passing params to it from ChatGPT.

Then it could then transparently call ChatGPT with the data returned from calling GetTodaysTemperatureInCelcius, and return the results of that response as results.

Too crazy? I honestly think that this particular feature (being able to handle functions in a convenient and robust way) is going to make/break the libraries/frameworks that interact with ChatGPT.

henkin avatar Jun 14 '23 20:06 henkin

Yes, you can share the fork, I will try to contribute.

techjb avatar Jun 15 '23 09:06 techjb

Also interested in getting this working. Feel free to share and I'll help out where I can.

chrish-slingshot avatar Jun 15 '23 15:06 chrish-slingshot

following and will contribute as needed

bluewilliams avatar Jun 15 '23 18:06 bluewilliams

Do we want to implement a basic json schema using JTokens or use an outside library? I don't think the OpenAI functions aren't structured incredibly complex based off of their examples.

https://github.com/openai/openai-cookbook/blob/main/examples/How_to_call_functions_with_chat_models.ipynb

hansjm10 avatar Jun 15 '23 18:06 hansjm10

@hansjm10 You were missing a line in the Chat Request constructor - you need to add:

this.Functions = basedOn.Functions;

on line 151.

I'm constructing my functions like this:

var functions = new List<Functions>();
                functions.Add(new Functions
                {
                    Name = "generate_image",
                    Description = "Generate an image using Stable Diffusion",
                    Parameters = JObject.Parse(@"{
    ""type"": ""object"",
    ""properties"": {
        ""prompt"": {
            ""type"": ""string"",
            ""description"": ""The text prompt to use which describes the contents of the image""
        },
        ""style"": {
            ""type"": ""string"",
            ""enum"": [ ""anime"", ""mixed"", ""realistic"" ]
        }
    },
    ""required"": [ ""prompt"", ""style"" ]
}")
                });

                var conversation = Client.Chat.CreateConversation(new ChatRequest { Model = "gpt-3.5-turbo-16k" });
                conversation.RequestParameters.Functions = functions;

chrish-slingshot avatar Jun 15 '23 20:06 chrish-slingshot

@chrish-slingshot Great got it working now using CreateConversation and test is passing.

I'd like to get this to work using CreateChatCompletionAsync but still getting weird null reference errors. I think it has to do with how the ChatRequest is getting deserialized, unfortunately stepping through it the response looks totally fine and just errors out after CreateChatCompletionAsync is awaited.

hansjm10 avatar Jun 15 '23 22:06 hansjm10

@hansjm10 looks pretty good

techjb avatar Jun 16 '23 08:06 techjb