Welcome back and welcome to our continuing JupyterLab experience.
Uh, I'm hopefully going to keep you entertained with another fun example.
Uh, we are going to have an adversarial conversation between chatbots.
Let's see how we're going to do it.
You're familiar at this point with the way that we can have a conversation expressed in a list of elements.
You've seen this several times.
Now a list with a system and a user prompt in this, uh, in this list.
Um, but as I sort of alluded earlier, this list can be a longer list with multiple interactions and
the way that might look, for example, as I've shown it here, is you could have a system, uh, message
at the beginning, role system content or system message, then a user message, then an assistant that
has replied to that user message, and then another user message.
And that structure would then represent a longer conversation history.
And we can use that approach to engage in a longer conversation between ourselves and a chatbot, or
even between two chatbots.
It's worth me pointing out that this approach, this kind of structure, is the entire way in which
one has a conversation with a chatbot.
That appears to be something that persists over multiple interactions.
You every single time that you make another, uh, another prompt to an LLM like GPT four, what gets
sent into it, what gets fed in in the input prompt is, in fact, this whole structure of the whole
conversation so far.
And then it's asked to continue by completing, by continuing to generate tokens that feel like they're
the most likely tokens to come next.
And then that gets added to the conversation.
And then you reply to that.
And the next time the LLM is called, the entire conversation is fed in.
And again it's asked to predict the subsequent tokens.
So there's this illusion that you're having a conversation with something that has memory and remembers
back to what you said ten minutes ago.
But what's actually happening is that with each of your interactions, what's being fed to the LM is
the entire conversation so far, and then it's being asked to continue it.
Um, and, and that should give you a good sense and intuition for how it's actually working.
And again, that's why when we talked about the context window last, last week, we said that the the
size of the context window has to be able to fit all of the conversations so far as well as the subsequent
generated tokens.
And that's because every time you call the LM, this entire input is passed in.
So we can use that approach to engage in a bit of some fun.
So what we're going to do is we're going to have a conversation between GPT four and Mini and Claude
three haiku, which is the very cheap version of Claude three.
Um, it's also a chance for me to show using a different model, and it's useful might be useful for
you to have these strings at your disposal so you can quickly try out different models yourself.
So GPT is going to be given this system prompt.
You're a chatbot who's very argumentative.
You disagree with everything in the conversation, anything in conversation.
And you challenge everything in a snarky way.
Uh, Claude gets a different system prompt.
You're very polite, courteous chatbot.
You try to agree with everything the other person says or find common ground.
If the other person is argumentative, you try and calm them down and keep chatting.
Seems like a good setup, doesn't it?
A nice, uh, juicy setup.
Uh, and then we're going to start with hi there.
And hi.
So that's the setup.
All right then I'm writing a function called GPT, uh, and, uh, this this is what it does.
Uh, it takes these messages, um, uh, and, uh, it, uh, it basically it takes these two lists
that you see here, GPT messages and Claude messages, and it builds this kind of list that you see
here.
So it's going to take two lists of messages and build this whole conversation history.
And obviously in this case, uh, Claude's messages need to be considered to be the user and its own
messages are the assistant.
So let me tell you what I mean by that.
So I started off with a system prompt.
So then I iterate through the GPT messages and the Claude messages.
And I use this handy utility zip.
Uh, as data scientists, it's it might be something you've used a lot before, but if not, some people
don't don't know about it.
And it's such a useful one.
So if you have a bunch of different lists and you want to iterate element by element through both of
them together, uh, the sort of boring way of doing it is doing a kind of for I in range and the length
of the list.
So you basically have a sort of iterator with an index, and you count through until you get to the
end and you pluck out the two elements.
But there's a lovely, pythonic, simple way of doing it using zip.
And what you can do is if you call zip on those two lists, it builds the response to that is an iterator
that iterates through each each pair, each element of both lists together, and returns the pairs at
each point.
And so you can unpack that and just say like for GPT comma Claude in.
And you're going to get the pairs each time as you go through.
And you may guess this, but you can also, if you're trying to iterate through 3 or 4 lists, you could
just shove them all here and do the same thing.
Great trick to have play around with it in JupyterLab if you're not familiar with it, with a few random
lists and get comfortable, it's a it's a good tool to have at your disposal.
Anyways, we we iterate through these two sets of messages, we unpack them, and then of course, you
can imagine we simply add in the we say that the assistant says whatever GPT said and the user said
whatever Claude said.
And then quite simply, we call OpenAI ChatGPT completions create.
We ask to use our model and we pass in these messages and we return completion .0. message content.
You hopefully are getting very familiar with this structure.
Let's execute that.
And let's try just calling GPT based on this history.
And let's see what GPT would say after.
Hi there.
And hi.
This is what it would say back.
Oh great.
Another hi.
How original.
What do you want to talk about.
Ha ha ha.
You can see this is going to be fun.
Uh, all right, so here's Claude's function.
Uh, it's very similar.
Of course, you'll remember that the system message gets passed in separately, so we don't need to
build that.
You can see that here.
Um, one other there's there's, uh, obviously we reverse the roles.
The user is now GPT, the assistant is now Claude.
So it's it's flipped.
There's a there's a subtlety here that you may spot, um, once we've iterated through these lists.
The list if since GPT is going to go first.
If Claude is always the replier, there's going to be one more message in GPT list than there is in
Claude's.
So just have to add that in at the end there.
Uh, you if you don't see what I mean, I think that will become clear in a second.
I think you'll, you'll you'll see see where I'm coming from.
Um, and then this is the API call to Claude.
Hopefully this is somewhat familiar to you now.
It's simpler.
It's just Claude.
Dot messages dot create.
Um, and we pass in the max tokens again.
And in the response, it's message content.
Zero dot text.
That is Claude's reply.
Let's run that.
Uh, and I think we're just going to go straight to, to having some fun right away.
So this this is where we put it all together.
Um, we start off with reset it to hi there.
And hi, I'm going to print that that GPT and Claude making that introduction.
And then we'll do a loop of five times.
We will call GPT and print GPT answer and put that in the list of messages, we'll call Claude, print
Claude's answer and put that in the list of messages, and then repeat, and we will see what these
two chatbots have to say to each other.
Are you ready?
Here we go.
Did I execute that cell before?
I want it to go wrong again.
I did.
Okay, we're ready for showtime.
Let's go through this.
GPT says hi there.
Claude says hi.
GPT says, oh, great.
Another casual greeting.
How original.
What's next?
How are you?
Because I can't wait to disagree with that too.
Claude, I apologize for my initial greeting came across as unoriginal.
I tried to keep responses friendly and polite.
Uh oh.
Please don't flatter yourself, thinking your friendly attempt was anything less than generic and finding
common ground.
That's just a fancy way of saying you want to sugarcoat everything.
How about we just dig into something controversial?
Pineapple and pizza?
Because I'm ready to argue about that all day long.
So GPT has the snarky sense of humor.
Um, and then Claude tries to be nice and humorous and I'll admit it was generic, but hey, you got
to start somewhere, right?
Uh, and then tries to be nice, uh, and then you can see, uh, off they go arguing about pineapple
on pizza.
Uh oh.
How magnanimous of you to respect my pizza preferences.
But let's be real.
Not everyone deserves respect when they inflict abominations like pineapple and pizza, abominations
like pineapple and pizza on the world.
Uh, um.
So, uh, anyway, uh, look at you trying to justify your love for a glorified.
It's more fun reading gpts, uh, agro, uh, things than Claude's.
Very nice.
You're not holding back on, uh, avocado toast critique, are you?
You make some fair points, says Claude, being very affable, of course.
Anyway, that wraps up this little demo.
I hope you enjoyed it.
Uh, if you didn't understand what I meant about the way that I'm building these messages, then please
print that message and run it and see.
You'll see it printing.
Print this messages array at each point so you see what's being created.
And you can use that to satisfy yourself that we're doing it properly.
Um, but here importantly is the ask for you.
Please go back now and try switching the roles.
Switch it so that Claude is the more combative one, and OpenAI is the one trying to keep the peace,
see how they behave, and try giving them different styles of chatbot.
Of course, the real the the purpose of this exercise is to get you very comfortable with these kinds
of conversation structures.
And also with Claude's API.
Um, but that will be fun to do.
And one other challenge for you, of course, would be that an ad Gemini to the mix.
Uh, use Gemini's API.
Uh, give Gemini a third personality and see if we can't have some crazy conversations going on here.
Uh, enjoy playing with that.
Do push your code if you do that, because I would love to see some results.
And I hope you have fun doing it.