OpenAI Web APIs in .NET C# - Exploring Functionality
February 1, 2023
• 1,687 views
This video is the first of a multi-part video series where I explore working with OpenAI's web APIs! This is all done in C# and #dotnet.
Join me as I try to explore OpenAI's web API in C#! This entire video is me experimenting and given that I am very new to many concepts in AI, I make many incorrect assumptions. The purpose of this video is:
- To show you how I approach experimentation of new tools and APIs
- Demonstrating how you can call Web API's in C# (in particular, the OpenAI ones!)
It'...
View Transcript
foreign [Music] okay so everyone in the entire world is talking about this right now um you've probably played around with it if you haven't it's worth going to check out so I recommend you do because it's pretty awesome um and as a programmer I see a lot of content coming out right now that's people talking about you know like it's just gonna replace everyone's jobs like um I'm trying to explore some ways that I can try to take advantage of it and um one thing that I've thought of that I'm really bad at that I think that AI can help me with is content creation for this game that I've been trying to build on the side for about 15 to 20 years now and it's something that when I go to program parts of this game um the content piece just never really gets
attention because to be honest I like writing software and I'm really bad at being I don't know creative when it comes to putting content together for it so what I mean by content in this case actually is like lore in history and things like that I have a lot of ideas but when it comes to actually you know writing out like a story for example the the story writing I'm very poor at and it takes a lot of energy for me to do but it's also something that's important and it needs attention so what I'm thinking about doing is using AI to help with that and I wanted to create a video about what I'm thinking of doing so before diving into any more if you could do me a favor and like the video if you're enjoying the content so far and the concept
um if you could subscribe to the channel that'd be awesome and leave a comment below and I'll get back to you if you have any questions or thoughts all right so I am at the open AI playground where you can actually try out some of these um capabilities that they offer on the API directly in the browser and play around with it to see how things are going to look so my thought process that I would like to do is basically I believe the concept would be called fine-tuning a model and I would like to basically over time train a model that's already you know in existence if you consider chat GPT for example knows a lot about the world already I would like to start training it on this fictional world that I am trying to create and that way if I can tell
it some of the history and things like that I can ask it to get creative and maybe start creating the skeleton of some short stories or generate just some more generic pieces that you know from my perspective would just take a lot of my time to create from scratch and if it's able to do it then I can go refine them and polish them after so my thought is that if I can train it on information about this world then I can ask it for more information as an output and then from there over time I can retrain it back into the model and basically let it totally understand like all of the lore in history for this game world so I'm pretty excited about that so on this playground page what I'm able to do um to be completely transparent I haven't played around
with all the parameters yet nor do I understand them in their entirety but I want to dive into seeing what I'm able to do with what's available so just for context I'm going to jump back over to the pricing page to talk a little bit about what's going on here and I'll zoom in a little bit and the idea is that they have some different models that are available to use and again these are not the chat GPT models I I think that's like a it comes after The DaVinci model if I'm not mistaken and it's uh it's definitely significantly better but my point is that I want to play with the API to get started and from my perspective I probably just want to go as cheap as I can to start but um once things are working and I'm kind of if I
can prove that the concept works then I would kind of go up to a higher cost uh model and and essentially retrain it on that and just for some context the reason I'm saying that is that if I started with something like DaVinci um we're talking about like orders of magnitude more expensive for cost right they talk about um I think 1K tokens roughly translating to 750 words of information and I'm talking about building out the lore for an entire game Universe um that's going to be a lot of text and I'd rather try to prototype some parts of it um in an inexpensive way and then when it's good to go I can say look I'm gonna I'm gonna bite the bullet I'm going to switch to the expensive one train it up and then I'm I feel content about the strategy that I
have and I'm going to paste in what I would consider a simple snippet of lore context for my Game World the game is called macaris it has a continent in the game world that is called masterous and on the bottom portion of that continent there is a desert so I'm gonna paste that in here so it just says there is a desert called the solitaris desert in the southern portion of the continent of macarus and a fantasy world um so it's actually kind of a creative statement I'm not it's not what I want but I'm not totally I don't know upset by that um so maybe I should do something like any oops medieval fantasy world I wonder if I do that if it will not maybe go right to machines and stuff so let's just give that a quick try the desert is located
near a small town and is known for its vast and sand filled desert I mean that is weird but uh the desert is also the location of a number of large salt pads which give the town its name okay so I don't like this at all but it didn't talk about machines so it's interesting at least that the concept so far is such that I can give it some information and it's gonna give me something back that's creative right and for context as well like I would never use this to basically just blindly go generate all the content for my lore and stuff like that because that would end up having some ridiculous machines and salt pad towns and stuff like that but it at least might serve as a basis for going like if I give it a bunch of information can it start
to tell me um useful things so let's go jump over to the most expensive model and just see if uh if we get something dramatically better or something like that right let's uh let's go down here I lost my cursor there we go assault Terrace desert is an expansive Wasteland that stretches across the southern part of the continent of macris oh man like this already reads super cool right it is a Barren it's inhospitable Place filled with sand dunes Rocky outcroppings and sparse vegetation it's home to a number of dangerous creatures we like this right it's a fantasy uh role-playing game such as giant scorpions giant spiders and venomous snakes cool okay the desert is also known to be home to several tribes of nomadic humans I mean this is neat cool um it's a treacherous Place scorching heat during the day near freezing at
night extreme danger a few Travelers ever attempt to cross it yeah like cool like and then it's created actually a city right so those that do however can find their way to the city of uh cathal I'm assuming is how you might pronounce that I maybe I should ask the AI which lies on the edge of the desert and is the only known City in the area very cool so infinitely better than the the cheapest model um and that's okay because again I want to look at and we haven't got to the actual API calls yet but I want to look at being able to um basically feed it a lot of lore that already exists and then have it get creative a little bit more beyond that so for example um because I have not told it it doesn't know that it's uh that
there are multiple cities in the desert um so and there I have not created one that's called cathol there are a few different other cities like that so I wonder if I gave it more information we should jump into some of the API calls that we can use from uh open AI here all right so I'm gonna go ahead here and get a new uh project created in visual studio um it's of course going to be in C sharp here so I'm going to call it lorebot because for my purposes I want to use it for lore creation but as we're going through this I mean basically we're going to be creating a lightweight c-sharp API to use open AI apis I mean what better way to get started with doing something like this then asking chat GPT itself how do we talk to your
apis and I've gone ahead and done that and it's kind of cool so here is the response we get okay so it actually printed out the code in C sharp to go be like to go do this um now I what I have not done is I have not gone and actually confirmed uh which API calls and stuff we want to make but this is pretty awesome because um if you've worked with web apis in general um you're going to need some type of class to be able to make the requests out to the Internet so there's your HTTP client in this case um you can see that it is down here um I can't highlight because I just took this picture here but in this section where it's creating a request it's actually formatting things to be um you know to the spec of
the API adding in your API key for authorization using the HTTP client to actually send the request get the response back and then it uses newtonsoft to deserialize it which is super cool um so I I think this is great great I have it pasted on my clipboard so I'm going to go ahead and get started by dropping that directly in to our application here let me Zoom back out a little bit I don't think I have newtonsoft installed um let me go ahead and do that newtonsoft oh almost at 3 billion downloads incredible okay let me get that thank you chat GPT for generating this for us but what I'm gonna have to do is I'll need to get an API key uh okay so we're gonna go ahead and just basically copy this generate text method because that was a good starting point
there's a lot of other things you could and should be doing if you're building an API like this like good error handling and stuff like that but we're just going to kind of get started with a copy of this one for uploading files we're going to have to go look I think we needed a purpose and we need a file so I'm just going to quickly jump back over here we can see yeah we need purpose um and file like this so purpose and file I'll jump back over so purpose and that needs to be equal to fine tune if I recall correctly fine tune and then the actual file and I think it needs to look like that I haven't run this yet so we're about to see how broken it actually is when I go to try it and then I was thinking
um the response that comes back is got a few different parameters on it but for right now I only really care about the ID um I mean what I would probably do if I was building out a more um thoughtful API is actually like API wrapper to the open AI API I mean is that I would probably have like a um a dto a data transfer object that maps to the response and I think it has like the file size and the ID and stuff but I honestly only care about the ID and uh for error handling now I'm just going to let it blow up when it blows up so if it's wrong we'll get an exception and that's okay for now um we'll sort it out but I think I just want to get the ID oops I can't see where I'm typing
um and upload file I'll call it async because I think generally I like doing this kind of stuff and that might be okay I have no idea so we'll find out all right so I went to go debug some stuff and realize I totally mixed up about the API requirements for this upload file a sync part and that it's using multi-part form data so I don't have a ton of experience with putting together good web requests and stuff like this and C sharp so this is going to be a bit um hacked together but a couple things that I totally messed up so just wanted to call that out I'm going to come right back to it but before I forget the Json structure that we had um I had a small typo in it and I had put a comma at the end of
the line you can just kind of see it right by my beside my head here in the video but um I had left a comma in here because I originally structured the whole thing um kind of like one big Json object and it's not supposed to be like that so that comma has got to come out that was one part and then jumping back over to this API if you recall we had copied this whole method because I thought that that would be a good starting point for us and it is and it also isn't so I had to change a bunch of stuff but I also wanted to make sure the authorization was put in I said hey screw that we're not doing that every time you'll notice it's gone from down here as well I'm putting it right on our client as a
default so any other things we need to add it'll put the authorization header in there for us when it comes to uploading a file um this is the structure we're going to be using um you can read more about this online I did a quick stack Overflow just to get some some thoughts um so you can make multi multi-part form data we need to have purpose as satisfying tune and then I'm pretty sure there's two parameters here and there's name and file name so I think name is for the actual um for the form data perspective and file name is uh another parameter we can use here so I have them both as file because I'm not sure what we need to do or what we can change but let's go ahead and run this um let me press F5 here all right we'll step
over this guy we get our um API instance instantiated so that means that we've also set up a HTTP client with headers um as default for authorization which is awesome we'll step in here and make a new form add the two parts to it just a quick note too I am using stream content here this way I don't have to go read in the whole file this one's pretty small but if I had a whole Wiki worth of content I'd have to pull that all into memory at once and we can leverage streaming in this case to do that more effectively on memory usage and then we will do a post and we're hitting that route that we took off of their API page with our form passed into it Let Me Wait a second there so something happened and let's check the response string
awesome we don't have a failure let me open that sorry the text is tiny but it says object file we have an ID on there awesome it says it's for fine tune um file name oh that looks like that's probably um this second file I bet I I we should try seeing if we can change that because that would be kind of cool that's the number of bytes the creation date the status and there's no details so that's cool so the next line here puts that into a dynamic object for us there's lots of information on the internet if you want to check out what dynamic actually does some people don't like using it that's cool you can do whatever you'd like um but we're gonna do we're gonna pull ID off of there and just for a brief note like what dynamic is allowing
us to do is that um I didn't actually go create a class anywhere I mean you can see all the code here in front of us I didn't create a class anywhere that had the type information that we kind of see present on this set of data I didn't go make that so Dynamic is allowing us to actually say dot ID and get a property or a field called ID off of this object without having to go create the type anywhere so um like one of the only times I ever find it valuable is kind of stuff like this otherwise you might go handcraft classes that map to API responses lots of different ways to do stuff um I generally don't like to say right and wrong so it's kind of whatever fits your needs so we can pull off the ID if I step
over nice it didn't throw an exception console right line and we'll read so boom there is our first API call to open AI sapi I said it right fine tune okay so let's see what happens we're kind of just double checking things right we're posting again um that's the URL because I copied it right from the site we made sure to have this we're serializing this payload which I think has what we need this was the only mandatory thing I believe I got a 200 back that's good news oh look at all this juicy information awesome and now we have an ID starts with the Ft prefix so we know it's a fine tune so so far so good okay next step we're going to want to check the status of our fine tune because like we talked about earlier it's going to be a
job that runs so yet another API we call um just going to do a quick check up here but it's a get not a post which we had before we still need authorization but it looks like the only parameter we have is right in the URL itself and that was the last thing we were printing to the console so we got it and this one should be pretty easy so I'm going to go ahead and jump over to the code again I'm going to do the thing I do where I just copy a method because I'm lazy and let's copy this one but we do know right that we have a um we have a get not a post so we'll call it get fine oops I've somehow missed an entire G get fine tune and we need the the fine tune ID we don't
need this part anymore not for this call we will change the actual API endpoint we need to format this string and that is going to have the fine tune ID it will be a get now not a post and there is no content we're just getting something and that's how it gets worked um and then in terms of the response that we want um it had a lot of information about events and stuff which right now is probably above my head but I think um just to get started like maybe we just want to get the status coming back um and yeah maybe let's go with that um this is where maybe we might do something like a more complex object that actually has the event information maybe it has different statuses that's all cool um we're just kind of doing a rough approach here
and experimenting I call it rapid prototyping right so um we'll pull the status off if it says succeeded great if not maybe this is where we actually want to do like a polling kind of thing I have no idea yet so let's find out um get fine-tuned status I gotta spell that right too and actually for people watching this is where pair programming and stuff is super handy because you have other people's eyes like I bet you everyone watching this watch me type status incorrectly and was like oh man this guy's an idiot um but we make mistakes right and if you're pair programming or working together on stuff other people can be catching little mistakes like that um so let's go ahead jump back to the program here um I'm gonna write job status equals await open a i API Dot and we're going
to pass in the fine tune ID and I think this will be kind of interesting I'm gonna I'm gonna get a little bit wild here I'm going to delete all the break points they're all gone I'm curious because I have no idea how long these jobs actually take I'm only giving it like two lines I don't know if it basically comes back borderline instantaneous we check the status and it's done so let's find out um maybe it says something other than succeeded and that'll give us some insight about how we want to look at this I'm also assuming this is going to work the first time and it could totally just not um but let's try it pending cool so I don't know why I was so excited about that it was something then other than succeeded right so super neat I bet you we
can do a little Loop here and we won't get super aggressive maybe we'll wait like I don't know five seconds in between or something and we can see the status of it uh changing over time so um let's do this um while true and by the way um I'm just doing this quickly so I'm not anytime I type while true I usually feel sick to my stomach because I'm like I've seen so many issues come up in production code where people have uh infinite loops and stuff like that because of stuff like a wild true but let me go do this and check the job status if job status doesn't equal actually let me get a little bit better here sorry uh is it succeeded I can't recall this example had it status succeeded right so so if it succeeded um I probably want to
have one for failed so maybe instead of just that I will say if it's pending maybe that's a better way to do it if it's pending another thing I generally don't like to do is a thread dot sleep even a it's a little bit better to do like a weight uh attach delay how many milliseconds well let's do five seconds right um let's try that the reason I like task delays is because uh you can do cancellation tokens and stuff in production code so a little bit more flexible so if it's pending we're going to delay and then we're gonna go back to the top of the loop otherwise we're gonna break out um by the way uh personal just like style of mine I guess when I write loops and things like that um I generally like checking conditions and either continuing or breaking
out kind of thing um sometimes you'll see people get code that's like super nested with all their conditions and stuff but uh not my style so um so all done um but maybe let's get a little bit more um informative here job status we're going to pull this out so we're going to pull the job status out and then we'll be able to see the last um the last status we get so just to double check before we run this um oh it's smart enough to know that what's it complaining about converting null oh whatever okay yeah unnecessary assignment it knows we don't need to do it okay so we're gonna have a job status pulled out uh so we're going to Loop this says Loop for forever right but we're going to call the API that we were looking at if it still says
it's pending we're going to sleep for five seconds once we wake up because it was pending before we're going to try again and we're going to keep doing this basically for forever I don't have a timeout built in um unless we'd call this and we get something that's not pending when that happens and I don't know what all the possible answers are we know succeeded as one um we'll say like it's all done and here's what the status is so let's rock and roll and this part's super boring so maybe what I could have done is done another console right line to see what's going on here because I don't know how many seconds it's been but it's been at least five and I'm getting antsy so uh maybe let's do that just so we can see a little bit more information and this is
already assigned to me we're going to need a solid Video Edit here to not have anyone waiting never mind look at that it finished by the time I finished blabbing um so that's cool um I didn't need extra console right lines to show that it was still pulling for us but um what did that take Maybe 20 to 30 seconds of me blabbering nonsense that's pretty cool so so far what we've been able to do is upload some training data we've been able to do some fine tuning like submit the job and then actually pull and wait for the the tuning to finish so this is super exciting so far what's next okay I think I think this might work um maybe we can save some time and comment all of this other stuff out for now we know that we've been running this let's
comment that out we should be able to ask for the models and then get right into it so again no idea if this is going to work yet that's half the fun right especially when you're recording a video to go on social media so here's all the the models like I was saying um okay and then at the bottom our code is going to sorry let me scroll down at the same time here I know it's kind of tricky to follow our code does this last or default thing where it's looking for the last one that contains personal so that's gotta be this one and then we can ask a question so that's super cool what did I teach it maybe I should say like where is talvash located no [Laughter] um well that's not right um there might also be another API for this
too because it's this is a completion one uh let's see that's funny I was so excited I thought we had it oh no I think that's right right it's a completion so what did it actually spit back here talvash is located in the city of whatever what is the name of the city okay maybe because we haven't actually run this API together maybe um let's have a look through the actual response that comes back okay so let's try that I'm going to copy this so just so we're using the same input right okay so we'll ask the same question where is it located and we have this response which is really weird and interesting right um sorry that text is probably extremely tiny but it keeps like we saw it actually output exactly what uh what it said before and it keeps kind of like
rambling like it says it's located in this random spot it's actually the same output as before and then it says what's the name of the city and then it keeps kind of going on like it asks what's the name of the city again what's the name of the city what's the name of the city so for some reason it kept blabbing on about it now that's really weird to me I don't know um why it's like that so maybe what we could try doing is we saw that when we were testing it online the the Ada model was a little bit wonky right so um maybe let's try retraining it using DaVinci perhaps right so I'm going to uncomment this we will retrain um and where was that training code or the fine tuning rate um we should actually make this a parameter we'll use
a base model ID um and then our code is going to break in program.cs but we should be able to now put DaVinci here maybe let's try this and see if it is less chaotic so I'm going to copy this again just so we have the same reference text when we're asking it a question and maybe one more thing we should do is print out what the current model is or yeah the latest model right console right line latest model latest model to use is going to be I need a dollar sign there for our string interpolation latest personal model ID okay so we're going to run this I don't know if the DaVinci training is going to take even longer so I might need uh Jamal the magic editor man to edit this video and speed it up but um I unfortunately have to
sit here and wait and watch it no matter what so we'll see you in a sec all right so I took a quick break there for just a moment I was trying to figure out what the heck was going on and I think there just might be a time delay but um just a quick note I changed the code um a little bit just to filter out only personal models instead of all of those like 70 or so models and now we just have um this da Vinci one at the bottom so suddenly it started showing up um uh I didn't change the ordering or anything and if you recall we just had the addo one at the bottom here um now it's da Vinci so anyway now we have the DaVinci one um I think I lost on my clipboard what I was typing
before so um where is I think it was this where is towel cash located oh I don't want to spoil it I want to see right in the console no totally totally made up and not using what information we provided it so interesting though perhaps it just means that we need a lot more actual training data um and that actually might make sense right the fact that if you're thinking about machine learning and AI like training sets are enormous so I think my original thought process was that I could use this kind of like chat GPT when you ask it a question and it responds it has some like conversational context here so far that's lacking in what I'm trying to do um but maybe I just have to play around with it and actually feed it more variations of like sample questions and give
it the same content to go along with it so anyway I hope that this was at least useful for seeing some of the open AI API calls and how you can wrap them in C sharp if I just jump back to the code here you can see a lot of the time it's a really simple and sort of a consistent pattern we're using where we have this Dynamic object we create really just to give us some flexibility with um you know not recreating all of the types that they have in their API and then we can serialize them to Json super easily right so that's useful um and then we're mostly posting stuff but we also put in some get methods as well um we move the authorization right up into one spot on the HTTP client and then um I would say the other
major thing we did was and this is you know you can decide to do it however you'd like but we use Dynamic here to be able to deserialize and then pull other information off of this so this is my first attempt at doing any of this so it was a really interesting learning experience I might poke around at some of the other apis that are available but so far my idea for being able to train and fine-tune a model looks like it either needs a ton more examples in the fine tuning or I need to look at some other different apis and perhaps it will carry forward some of that context another thing to point out is that my thought process is coming from chat GPT where it seems to contain the context and the conversation the models that we're using right now like The
DaVinci one for example is still way behind where chat GPT is at so perhaps it just doesn't have that capability and I haven't actually tested that to begin with so I might have just made some incorrect assumptions but maybe this framework still could work and maybe it's worth going forward with the concept I want some of the more advanced models are available I can look at doing something like this and pulling from the the wiki I have for my knowledge base so anyway maybe that was interesting a different take on some of the chat GPT stuff instead of just the Doom and Gloom about how it's going to replace all of us um if you enjoyed the video please give it a thumbs up uh leave a comment below let me know what you think and if if you enjoy the content please subscribe to
the channel so we'll see you next time thanks
Frequently Asked Questions
What is the main purpose of using OpenAI APIs in my .NET C# project?
I'm using OpenAI APIs to help with content creation for a game I've been developing. Specifically, I want to fine-tune a model to generate lore and story elements for my game world.
How do I start fine-tuning a model with OpenAI APIs?
To start fine-tuning a model, I first upload my training data using the API, specifying the purpose as 'fine-tune'. Once the data is uploaded, I can submit a job to fine-tune the model and then check its status until it's completed.
What should I do if the generated content from the API isn't what I expected?
These FAQs were generated by AI from the video transcript.If the generated content isn't what I expected, I plan to provide more detailed training data and examples. The quality of the output often depends on the amount and relevance of the training data, so refining that is key.
