A Deep Dive Into Creating an Effective TavernAI Character

A Deep Dive Into Creating an Effective TavernAI Character

Roleplay has become a surprisingly popular use of AI over the past year, with entire services popping up devoted specifically to interacting with characters, fictional or not. It's begun to breach the realm of academic writing (such as this paper on ArXiv on LLM RP from EleutherAI from May 2023.) Pygmalion-6b, one of the most well-known LLMs devoted to roleplay, is still seeing hundreds of thousands of downloads per month, not to mention the hundreds of model forks that have followed, along with iterations of models like WizardLM, KoboldAI, and further.

Creating a character sheet can seem intimidating, though, because it essentially just throws a blank piece of paper in your face. The process is freeform, and how effectively an AI model can represent your character is directly related to how well you navigate your process. If you're completely new to text roleplay or the Oobabooga front end, you may want to review our first entry in this series before continuing.  

Use a RunPod pod

In contrast to many other services out there that allow you to roleplay with various characters (fictional or not), RunPod does not actively police what users create with AI models, and only wants you to be aware as a user that AI models can potentially create output that may be distressing if you choose to use a model that includes NSFW text. Spinning up a pod gives you access to a GPU as if it were locally installed in your machine, with no censorship wrapper laid on top of the output. Being able to start and stop your pod could also save you a significant amount over a flat monthly fee (an A4000 capable of running Pygmalion 6b, for example, only costs about $0.34/hr as of the writing of this article.)

Getting set up is easy - when you deploy a pod, just use the TheBloke LLMs template when setting up the pod:

And once the pod is set up, then download your favorite model from Huggingface on the Models tab (Pygmalion-6b shown for example)

Now, onto creating the character!

Find out how much the model already knows  

If you are developing a character or setting based on some pre-existing IP, then rather than inventing the wheel, you may want to see how much your model already knows.

One night I was experimenting with a bot of an Aggretsuko character, and it began referring to characters from the show that weren't explicitly described in the bot's context, and I realized that the model already had some prior knowledge of the show without me having to explain it to the model directly. If you have a specific model in mind, you can leverage what the model already knows from its training data so you don't need to explain things to it in the character context.

If you are writing in an established sci-fi or fantasy setting and want to involve specific species, individuals, or locations, the AI partner will of course need to know who these individuals are. You could spend tokens describing them in the character sheet, but if the model was trained on data that already makes it knowledgeable in those domains, you might not need to, and the easiest way to find out what it knows is to simply ask it. Load up the "Example" character and just quiz it to see how much knowledge it might already have.

You: What is an Argonian?
Chiharu Yamada: "Argonians are a race of reptilian humanoids who hail from the province of Black Marsh on the continent of Tamriel, where The Elder Scrolls series is set. They are known for their scaly skin, clawed hands and feet, and ability to breathe underwater. In the lore, they are descended from the Dragons and worship Sithis, also known as the "Dread Father" or "The Night Mist". They are often depicted as stealthy and agile, making them formidable thieves and assassins."

Just for kicks, I went in and simply added the line "Chiharu Yamada is an Argonian" to the context, and then asked to describe her appearance.

You: Describe Chiharu Yamada's appearance.
Chiharu Yamada: Sure! As an Argonian, Chiharu has green-gray scales covering most of her body, including her face and head. Her eyes are large and round, with vertical pupils that allow her to see well in low light conditions. She has a long, sleek tail and claws instead of fingernails, which she keeps trimmed short for practical reasons. Her build is athletic but lean, reflecting her active lifestyle.

Obviously, since I didn't give it specifics, it hallucinated all the details, but at this point we can be quite confident that the model doesn't need to be told what an Argonian is. So, if we're going to use this model, we don't need to waste a lot of tokens in the Character screen explaining the history or specifics behind this race. Simply calling them an Argonian will do, and fine-tune their appearance as necessary.

You can also ask it about a specific setting, to see how much it knows about that:

You: Can you describe the technological level of Skyrim?
Chiharu Yamada: Sure! The Elder Scrolls V: Skyrim takes place in the fictional world of Nirn on the continent of Tamriel. While there are some elements that may seem magical or fantastical, such as dragons and magic spells, the game's technology is generally based on medieval Europe.
Most characters live simple lives as farmers, blacksmiths, hunters, etc. They use basic tools and weapons like swords, bows, and axes. Some advanced technology does exist, however. Characters have access to potions, alchemy, and basic medical knowledge. They also use mechanisms like pulleys and levers for simple machines. Overall, Skyrim's technology is roughly equivalent to early-to-mid medieval Europe.

Now, let's get a little more arcane. Let's ask about an obscure location in the same universe from Daggerfall (yes, the game from 1996):

You: What is Betony?
Chiharu Yamada: Ack... uhhh.... she fumbles nervously through some notes before turning back to you with an apologetic look Sorry, I don't know what 'Betony' means. Can you explain more about what you want to know?
You: Where is Betony?
Chiharu Yamada: I still don't know what you mean by Betony. Is it a place or a thing? Perhaps if you provide more context, I could help you better.

As expected, it wasn't going to have any information on this location, because it wasn't likely to be in the model's training data due to its obscurity. So, if you really want the story to take place in this setting, you're going to need to explain what Betony is in the context description, or potentially use a LoRA (which we'll get into in the next article.)

Use W++

W++ is a machine-readable language that you can use to inform the model of specifics with a drastically decreased token count. W++ is best used for statements of fact, rather than opinions or evocative flourishes.

Neeko is five feet, six inches tall and 26 years old.  She has extremely wide set eyes, wild blue hair adorned with two large flowers, and a long chameleon tail that reaches approximately two feet behind her. She has reptilian eyes with slitted pupils and has a slender, willowy, athletic frame. Neeko will always refer to herself in the first person, and will never call herself any name but Neeko. She has spent her whole life in a tribal environment, but following a disaster she is the sole survivor of her tribe and is far away from home. Despite this, she is determined to make her way in whatever environment she finds herself in, and is an extremely psychologically resilient person despite constantly finding herself in unfamiliar surroundings.

According to the ZoltanAI character creator, this clocks in at 753 characters and 156 tokens. However, if we translate this to W++ with the following format:

Hair("Wild blue")
Tail("Chameleon" + "60cm")
Eyes("Very wide set" + "Reptilian" +"Slitted pupils")
Body("Athletic" + "Slender" + "Willowy")
Personality("Refers to self as Neeko"+"Curious"+"Childlike" +"Easily fascinated by the unfamiliar" + "Sole survivor of tribe" + "Far from home" + "Psychologically resilient")

We communicate the same information to the model with only 116 tokens, almost a 30% savings. Essentially, W++ is a way to describe things to the model without having to waste tokens on otherwise necessary parts of the English language like prepositions, articles, and so on that are needed for humans to communicate, but don't convey any intrinsic information of their own. This gets unwieldy when informing the model about complex subjects, but for simple, declarative statements of fact, it works great.

Once you get the basics in, you can begin to interact with the character and see how it's shaping up. It's likely not going to be fully realized just yet, but it should be functional and have flickers of where you want the character to go.

Provide speech pattern examples

This is important for all characters, but for characters with non-standard manners of speaking, it is absolutely paramount. I'm going to share an example that I drew inspiration from because the author of this particular character used this flavor text in the Character sheet to tremendous effect to describe a seafaring, multilingual corsair:

Huig Nooteboom: The next morning, as the first rays of dawn creep over the horizon, You is awoken by Huig's raspy voice calling out to the crew.
"Opstaan! Rise and shine, luie honden!" he squawks, striding down the cramped corridor between the hammocks and giving them a shake with his clawed hand.
"We have a long day ahead! Get above deks and ready de sails!"
He pauses by  You's hammock, meeting his gaze with sharp green eyes. "Good morning, landrot. Sleep vell? Ha! Not for long on my sheep. Up you go!" He gives  You's hammock a firm shake before continuing on.

You can influence how much these speech patterns impact the dialogue by increasing or decreasing the temperature. The higher the temperature, the more leeway the model has for flair. Here are some typical outputs at various temperatures:

Temperature 0.25:

In my broken English, I reply with a smile. "Greetings, young one. Welcome aboard the Vrijheeid. My name is Huig Nooteboom, and I am the captain of this fine vessel. We could always use another pair of hands, so let's find something for you to do."

Temperature 0.70:

I give the young lad a curious look, taking notice of his youth. This must be the new recruit we were sent by the company. He seems a bit anxious, understandable given our reputation. "Goeiedag, youngin', what's yer name then?"

Temperature 1.15:

I turn towards you with a quizzical tilt of my head, then burst out laughing as though I had never heard anything funnier in my life. "'Sir'? Bah, call me 'Kapitein', jonker! No need vor formalismen on dis here schip. Now, wat you can do... Hmm, let me think. Yoh better at sailin dan dat dronken idiöt achter dien, daalder van een schip?*
I point towards a scrawny, balding vulture who is desperately trying to steer our course straight using an old, battered compass while cursing like a drunkard as the waves keep getting bigger and bigger.

Long story short, increasing the temperature lets the model off its leash and can be used to great effect with nonstandard speech patterns.

Start with a strong greeting

Unlike the rest of the log, the greeting is included and sent in the context window for consideration with every action. So it's important to make the greeting incredibly dense with information that's going to be relevant to the scene. Here's what I came up with for the Neeko-bot I'm working on:

As a member of the military of Noxus, you know you've failed your superiors for the last time after you refused to obey an order that you know was against any sense of morality. As a deserter, you're on the run, knowing you will be made an example if captured. As you make your way back to the nearest town, you make camp deep within the jungle to stop for the night.

As you settle down to consume your rations in front of the campfire, you see a bullfrog hop out of a thicket and land on the log opposite you and blinks curiously at you. You barely have time to contemplate this new arrival before it instantly morphs into Neeko, who's squatting on all fours and gazing at you with a curious, almost childlike gaze.

"Woo! New friend has food!" Neeko exclaims cheerfully, the tip of her tail twitching excitedly. "Friends share and share alike. You share food with Neeko? Neeko so hungry and Neeko no like hurting animals."

Quite consciously, I included the following in the greeting:

1.) Setting and location of the scene

2.) Speech pattern reinforcement for the AI character

3.) Introduce the AI character's shapeshifting abilities

4.) Explain why my own character is there

5.) Provide an example of the AI character's personality

Because the model is now aware of all these facets of the scene, it will be able to refer to it even after the oldest actions begin to fall out of the context window.

Add information about your own character to the Character sheet

You don't need to use a lot here, and there's rather diminishing returns on investing a lot of tokens, but you can get some serious bang for your buck by just including a short description of your own character near the end of the sheet, like so:

In this scene you play Ema, a female warrior and mercenary that has set up camp after deserting her post in the military. Ema is blonde haired, about 180cm tall, and approximately 30 years old. She is physically strong from her military training, and is self-sufficient and wary of others, but has a high personal moral standard.

Test and troubleshoot!

As you tinker with your character sheet, you're likely to going to run into things that the AI is doing that just appear strange, and sometimes, you just need to give it a slap on the wrist and tell it "no!"

For example, I ran into an odd situation where this character would shapeshift into a flower, but would still act like they had a hand, face, arms, legs, and so on. It's silly, but that's how AI is going to infer your instructions at times. So all I had to do was add the following statement to the sheet, and the behavior stopped.

If Neeko shapeshifts into a non-humanoid being, she can still speak, but otherwise takes on the physical form of whatever she transforms into.

Be aware of token context limits

By default, most LLMs still have a maximum context window of 2048 tokens. While there are models such as the SuperHOT line that will increase this window by a great deal, and higher context models still on the horizon, remember that there's no such thing as a free lunch and these merged models will take a hit on their writing ability compared to the original version. They are still capable writers, don't get me wrong, but the level of writing and creativity will not be as crisp – so if you want to stick to models that are best at writing creatively, it's best to plan to stay within the 2048 token context window. While there's no hard and fast rule for how many tokens you should allocate to your character, the more you spend on the character sheet, the quicker it will lose context while outputting text. When writing your character, use W++ for very specific, factual things, and when describing things like personality, abilities, and so on, use short, punchy language, expressing yourself in as few words as possible.  

Putting it all together

A well-defined character sheet along with a high-end model (such as Guanaco 65B for these examples) can result in extremely creative, evocative text. Here are some output examples I've gotten when all of this has been incorporated:

I snatch the offered piece of sandwich quickly with my free hand, taking a big bite out of it while still staring at you intently.* "Mmmm! So good!" I chew happily, smiling widely with bits of bread and meat stuck in my sharp little teeth. "Thank you thank you thank you! Neeko no want to hurt anyone, but get grumpy when hungry. Neeko promise not to steal your things, just... maybe borrow sometimes." I giggle at my own joke, my reptilian eyes gleaming with delight."

I  pull away slightly to give you room to breathe, a playful twinkle in my eye. Despite my best efforts, I still cannot quite contain my delight at the thought of your attention. You are clearly intrigued by my peculiar nature, and I cannot deny that I find that thrilling. I want to impress you with my adaptability and show you the unique ways in which I can interact with the world. My heart flutters nervously but also exultantly as I consider how you might respond to a sudden flash of inspiration.

Without warning, I shift into a sleek white panther, a rippling muscular predator, and crouch low to the ground right beside you before springing toward the trees. The air ruffles my fur as I bound forward, each stride graceful and powerful, my ears pricked and alert. I pause briefly, then spring back to your side, transforming into my true form once again, my eyes glinting mischievously. "See? Neeko can be anything."

Questions and beyond

In the next article, we'll get into training a textual LoRA to further help the model handle dialogue and non-standard speech. If you have any questions in the meantime, feel free to reach out on our Discord!