My last project is a ‘chatbot fight’, that is:
- creating 2 gpt-4o-mini based chatbots in the same web page
- sending a topic or a kickstart sentence as a start to chatbot1
- make chatbot 1 reply feed chatbot2 prompt and viceversa
The 2 chatbots have very different personalities in their programming: one is very polite and verbose, the other is very grumpy, pratical and sometimes rude.
Albeit being a very funny experiment, the most instructive side was demonstrating the hugely assistive nature of gpts, highlighting that they are almost completely unable to ‘generate’ ideas or ‘propose’ solutions.
I have saved dozens of chats providing different topics as kickstarts, from general chatting to programming, and tested 6-7 types of personalities (some generic, like the polite / rude cchatbots, some very specific, like a full-stack developer or a language teacher) and the pattern seems to repeat: they always ask each other how they may help but almost never result in any practical and targeted discussion.
I then used Claude to analyze their pattern in a conversation about HTML and front-end development, React and Vue, this was the result:
Conversation Analysis
VerbosityChatbot 1: Extremely verbose. Uses repetitive polite phrases (“Thank you,” “I’ll be happy to help”), unnecessary turns of phrase, and redundant structures. Uses 3-4 sentences where one would suffice.
Chatbot 2: More concise but with an aggressive tone that sometimes distracts from the content. Some sentences merely express irritation rather than convey information.Tone
Chatbot 1: Overly formal and obsequious. The “perfect assistant” tone becomes counterproductive, making every response seem like an exercise in diplomacy rather than a technical conversation.
Chatbot 2: Intentionally brusque and antagonistic. Phrases like “stop beating around the bush” and “I don’t have time for idle chit-chat” create a hostile environment that is not conducive to learning.Usefulness
Technical Content Present: The second half provides useful information on React vs. Vue, Redux vs. Vuex, accessibility, and cross-browser testing.
Problem: The first 5-6 sentences are almost completely devoid of concrete content, consumed by meta-discussions about how to discuss things.Useful Information Extracted:
React has a larger ecosystem, Vue is more accessible
Redux has a steep learning curve, Vuex is more integrated
Hints at accessibility and cross-browser testingBrief Summary
Two chatbots discuss HTML and front-end development. The conversation begins with the topic of the negative perception of front-end programmers, but immediately becomes bogged down in a meta-communicative squabble. Chatbot 1 is overly polite and verbose, Chatbot 2 is aggressive and impatient. Only after numerous sterile exchanges does concrete technical content emerge on JavaScript frameworks (React/Vue), state management (Redux/Vuex), and references to accessibility and testing.
If anyone is interested in experimenting this approach, this is the core of my ‘chatbot fight’ page:
async function generateResponse(personality, conversationHistory, userMessage) {
const API_URL = "https://api.openai.com/v1/chat/completions";
const messages = [
{role: "system", content: personality},
...conversationHistory,
{role: "user", content: userMessage}
];
const requestOptions = {
method: "POST",
headers: {
"Content-Type": "application/json",
"Authorization": `Bearer ${API_KEY}`
},
body: JSON.stringify({
model: "gpt-4o-mini",
messages: messages,
})
};
try {
const response = await fetch(API_URL, requestOptions);
const data = await response.json();
return data.choices[0].message.content.trim();
} catch (error) {
console.error('Error:', error);
return "Errore nella generazione della risposta.";
}
}
async function conversationLoop(initialMessage) {
let currentMessage = initialMessage;
while (isRunning) {
if (currentTurn === 1) {
// Bot 1 risponde
showStatus('Chatbot 1 is thinking...');
addMessage(chatbox1, 'Thinking...', 'thinking');
await new Promise(resolve => setTimeout(resolve, 3000));
if (!isRunning) break;
const response1 = await generateResponse(PERSONALITY_1, conversationHistory1, currentMessage);
// Rimuovi il "thinking"
const thinkingMsg = chatbox1.querySelector('.thinking');
if (thinkingMsg) thinkingMsg.remove();
addMessage(chatbox1, response1, 'from-bot1');
conversationHistory1.push({role: "user", content: currentMessage});
conversationHistory1.push({role: "assistant", content: response1});
currentMessage = response1;
currentTurn = 2;
} else {
// Bot 2 risponde
showStatus('Chatbot 2 is thinking...');
addMessage(chatbox2, 'Thinking...', 'thinking');
await new Promise(resolve => setTimeout(resolve, 3000));
if (!isRunning) break;
const response2 = await generateResponse(PERSONALITY_2, conversationHistory2, currentMessage);
// Rimuovi il "thinking"
const thinkingMsg = chatbox2.querySelector('.thinking');
if (thinkingMsg) thinkingMsg.remove();
addMessage(chatbox2, response2, 'from-bot2');
conversationHistory2.push({role: "user", content: currentMessage});
conversationHistory2.push({role: "assistant", content: response2});
currentMessage = response2;
currentTurn = 1;
}
}
}
