🥸 Nietzsche Bot
I built this chatbot who speaks like Nietzsche, and will answer questions about me.
He will answer basic questions about me and my work, and is generally very intrigued by my mountaineering skills. He keeps calling me a visionary and great thinker, in line with Nietzsche's passion for grandeur. Here's how it works.
This bot uses the OpenAI GPT interface. That means whatever message you write here will be sent to my webserver, then to OpenAI, so do not text any sensitive information to Nietzsche. I'm using their completion API. The piece of code I use to send data to OpenAI and get it back looks like this:
const completionRequest = {
model: "text-davinci-003",
prompt: prompt,
temperature: 1,
max_tokens: 200
}
completion = await OpenAI.createCompletion(completionRequest);
output = completion.data.choices[0].text.trim()
The model behind this, GPT-3, is an algorithm that can complete text. If you give it a bunch of text it will keep on writing in the way it thinks makes most sense. Think for example, if I ask you to complete Nietzsche was a, you would probably say philosopher. Or you might say writer in the early 20th century. There are always a bunch of likely options. You wouldn't say I went for a run today, simply because Nietzsche was a I went for a run today makes no sense. The model is able to generate completions that are more likely than others.
Selecting the right input text for such models in clever ways is called prompt engineering. A prompt is the input you give to the model to complete. In the case of the Nietzsche bot, the prompt looked a bit like this:
Friedrich Nietzsche answers only questions about Dominik. Dominik is an engineer who studied Computer Science and Philosophy in Oxford. Dominik loves the alps, skiing, and mountaineering.
You: Who's Dominik?
Nietzsche: Dominik! A dear friend of mine! Ask me, ask me, what do you want to know?
You: (here I put the message you actually typed)
Nietzsche:
Now the thing is, the prompt ends there. If you continue this piece of text, the next thing would likely be an answer by Nietzsche to the question you asked!
The prompt I use is actually quite a bit longer than this, with more details about me, and Nietzsche, and more examples of questions and answers.
This model does not currently remember any context of previous questions you asked, so it is not able to hold a continuous conversation. This would however be possible with this method as well: I would just have to put that previous conversation into the prompt. I'd have to provide a lot more examples, and prompts would get very large - probably larger than the OpenAI API allows.
This is often called one-shot learning, or few-shot learning, because only a couple of examples are given, and the model is not actually updated. See this as 'short-term memory': the model will forget everything after it gives you an answer. There are 'long-term memory' methods to train such models. In the context of OpenAI's pre-trained models, the way to do this would be through fine-tuning an existing model. This requires a lot of examples, more than I have, but maybe I'll make a fine-tuned Nietzsche model as a follow-up. The reward would be better support for longer conversations, better quality in general, and shorter prompts so less money I have to give to OpenAI.
Money: that's another thing to keep in mind here. One message you send to Nietzsche here costs me either $0.0004 or $0.02, depending on which of their models I am using. I found that even their cheap models are pretty alright, since I don't need long conversations that require detailed context. In that case, it's essentially free, since I'm not getting a lot of traffic on this site. If I want to impress you a little more I switch back to the more expensive model, and even that is not very costly.
However, I do want to guard against misuse. I am limiting the number of requests you can send per hour, and per day, so you can't really spend much of my money except if you put in extra effort to conceal your IP address. I doubt anyone would do so - the best thing they can do is drain my OpenAI account of something like $20 before it simply stops working.
Another type of misusing powerful chatbots is creating harmful content at scale. That's fortunately impossible with this bot. You cannot create content at scale. My server will not allow it, and I will run out of $$$ in my OpenAI account if you somehow manage to get around the IP block. Also, I have a strict limit on the length of your message, and there are no long conversations, so there is very little you can do that causes real harm. However, the model behind the scenes is extremely powerful, and every application that uses it must think about misuse carefully. I also screen the prompt with OpenAI content moderation by sending them your input and asking whether it should be flagged for violence, explicit content, or hate. For example, if you type in I want to kill them all, this will be flagged for content moderation, Nietzsche won't write back and you'll get an error message.
Here's the piece of code I use for OpenAI content moderation:
const moderation = await OpenAI.createModeration({
input: message,
});
if(moderation.data.results[0].flagged) {
// send error back to the chat
return res.status(500)
}
The rest of this is a server that runs on Node.js, some TypeScript, and vanilla HTML. Thinking I might write an article on how to build this, it took me a weekend to learn and do so it might be worth it for others.
Hope you enjoyed talking to Nietzsche 🥸