-: And in this video we're gonna cover
how you can do prompt chaining.
So prompt chaining is a process
of decomposing a task into a series of steps,
where each LLM call will basically process
of the output of the previous one.
You can think of it like a series of steps
you can see in this diagram.
So let's go and install a couple of packages.
So we'll install OpenAI Pydantic,
then we're gonna do some imports,
so we input the operating system,
typing Pydantic and OpenAI.
Then you will need to set your OpenAI key.
And we've also created a client.
We are going to generate a story and a plot outline.
And then with those plot outlines,
we're going to then generate
a bunch of different actual stories.
Now the first thing we're gonna do
is also generate our story-based model.
And we're gonna have a title story author.
And I also want plurals.
So we've got the class stories, which is a stories key
with a list of stories.
So we've got the title story and author.
We've also got a function
that I'm gonna set up called serial_chain_workflow,
which takes a topic and the number of stories.
I'm just gonna generate a doc string for this.
And then we're then going to have the stories plot prompt.
And this is going to be an f-string,
which will say, generate number of stories about topic,
and we'll say generate, instead of stories,
we'll say generate story
plot ideas for stories about this topic.
These should be short and concise for a children's book.
Why not?
And we'll also say later on these plot ideas
will be used to generate full stories.
And we'll just split this onto a couple of different lines
'cause that's, I'll read a bit better.
Okay. The next thing we're gonna do is we're going
to use the structured outputs API from OpenAI.
And this basically allows us
to use those Pydantic models that we had before.
So we'll call it stories_plot_response,
and we're gonna actually use the
client.beta.chat completions.
And then we use the .parse function instead.
The .parse function allows us
to specifically get a Pydantic model.
So it will be able to look for a story
or a list of stories as a Pydantic model.
And how that works is you use the response format
and then you basically end up putting the response format
and then you put in what you want there.
So we are also gonna want one more Pydantic model.
So I'm just gonna go up here
and we're gonna add class StoryPlot.
We'll have class StoryPlots,
and that will just be a list of story plots.
And then in our scenario
I want a response format of story plots.
We're gonna use the messages as well for this.
And the messages that we're gonna put in here
is the StoryPlots prompt.
We're also going to set the temperature
to be around 0.6 for a bit more creativity.
We're also going to set the model to be GPT-4o mini.
Then after that, we're gonna go, if not stories.choices
or stories_plot.choices0.message.past,
We're actually gonna raise a value error.
And the reason why we're doing this is sometimes if you look
at the plot response, it has a past chat completion,
but in the .choices that might not actually exist
and the .parse also might be a none type.
You can see that here.
So it's good to have some validation error in here.
And then we can just go and test this out.
So we have three story plots.
Okay, so we've done some sequential work,
but the next thing that we want to do
is for each of these plots,
we also want to then generate a story.
So for example, we could have here, instead of returning,
we could then just store this
and say, stories as a python list.
And then we could loop over each story,
and then we could generate a story prompt.
And there you go. So now we're also then saying that we want
to generate a response format of a story
using that client.beta.chat_completion.parse.
And we're parsing in the story prompt,
which is generate a story
based on the following plot plot plot,
and then we have the story response, which is coming back.
And then from that, then what we wanna do is we want
to check does that story response exist?
And if not, when maybe we could raise an error.
If you wanted to be a little bit less secure,
you could do something like this
but you could just continue,
if it is a valid story, we add it to the stories list.
And then what we can then do is return a Pydantic model,
which is our stories.
So I'm just gonna go and give that a go.
And then we'll also save that.
So we'll do serial_chain_workflow, the story,
and we'll do something like data science and engineering.
And we'll see,
now we should get back three stories
which have been generated from their plots.
And you can see that this is increasing the amount of time
that this takes to run.
So obviously this chain is a sequential chain,
and the fact is, is we're first generating all the plots.
If there's an error
and we don't have any plots, then we raise the error.
Then we have a Python list here.
And for each individual plot,
what we then do is generate a story here.
And we then, if we don't have a story,
we just continue to the next iteration of that for loop.
But if we do have a story, we append that in.
And then we return a Pydantic model
at the end with these stories.
And you can see here now we've got these different stories.
So what we'll do is we'll go into the stories
and we'll do .stories,
and then you can see we've got our Python list,
and I can do square bracket 0.
And then we can, for example, do the .title.
And then you can see we've got
"Mia and the Missing Crystal."
And we can also do things like get the entire story.
Okay, so you've learned about prompt chaining,
which is basically a series of input
and output pairs going into the next one,
we've covered this also in LangChain,
but I thought it's good for you to see
how you can do this automatically using Open AI's package
and using the structured outputs API.
In the next video, we'll cover routing,
how you can easily, given a user query,
route different queries to different types of endpoints,
whether these are different LLM calls
or different functions
so that your program can determine at runtime
what to do with specific types of user queries.
Cool, I'll see you in the next one.