Managing Conversations
In the previous tutorial, you learned how to write effective prompts to get good responses from AI models. But what if you want to have a conversation - where the AI remembers what you talked about before?
Right now, if you ask "What is TypeScript?" and then ask "Show me an example," the AI won't know you're asking for a TypeScript example. Each question is separate. Let's fix that by learning how to manage conversation history.
Why Conversation History Matters
AI models don't remember previous messages by default. Each time you call the API, it's like talking to the AI for the first time. To have a real conversation, you need to send the entire chat history with each new message.
Think of it like this:
- Without history: Each question is independent
- With history: The AI remembers the whole conversation
Understanding Message Roles
Every message in a conversation has a role that tells the AI who said what. There are three important roles:
System: Sets the AI's behavior and personality (like giving it instructions on how to act) User: That's you - the person asking questions Assistant: That's the AI responding to your questions
// A simple message structure
interface Message {
role: "system" | "user" | "assistant";
content: string;
}
What is a System Message?
A system message is like giving the AI a job description. It tells the AI how to behave throughout the entire conversation. For example:
- "You are a helpful programming tutor"
- "You are a friendly customer service agent"
- "Keep your answers short and practical"
The system message is usually the first message in your conversation and guides all the AI's responses.
Environment Setup
Make sure you have your setup from previous tutorials:
- Google AI API key in your
.envfile @google/genaipackage installed- Basic TypeScript project structure
Working Code Example
Let's build a simple conversation system step by step.
Step 1: Create a Messages Array
const messages: Message[] = [];
This array will store our entire conversation history. Every system message, user message, and AI response goes here.
Step 2: Add a Function to Store Messages
function addMessage(role: "system" | "user" | "assistant", content: string) {
messages.push({ role, content });
}
This function adds new messages to our conversation history. We'll use it for system messages, user questions, and AI responses.
Step 3: Set Up the System Message
// Add a system message to guide the AI's behavior
addMessage(
"system",
"You are a helpful programming tutor. Keep your answers short and practical."
);
This system message tells the AI to act like a programming tutor and keep responses concise. This will affect how the AI responds throughout the entire conversation.
Step 4: Format Messages for the API
function formatMessages(): string {
return messages.map((msg) => `${msg.role}: ${msg.content}`).join("\n");
}
This converts our message array into a simple text format that the AI can understand.
Step 5: Create the Chat Function
async function chat(userMessage: string): Promise<string> {
// Add the user's message to history
addMessage("user", userMessage);
// Create the full conversation prompt
const conversationPrompt = formatMessages();
// Send to AI using the same method as tutorial 2.1
const response = await genAI.models.generateContent({
model: "gemini-2.5-flash ",
contents: conversationPrompt,
});
const aiResponse = response.text;
// Add AI's response to history
addMessage("assistant", aiResponse || "");
return aiResponse || "";
}
This function handles the conversation flow: add user message, format all messages, get AI response, add AI response to history.
Step 6: Test the Conversation
async function testConversation() {
// Set up the AI's behavior first
addMessage(
"system",
"You are a helpful programming tutor. Keep your answers short and practical."
);
console.log("Starting conversation...\n");
// First message
const response1 = await chat("What is TypeScript?");
console.log("You: What is TypeScript?");
console.log("AI:", response1, "\n");
// Second message - AI remembers the context
const response2 = await chat("Show me a simple example");
console.log("You: Show me a simple example");
console.log("AI:", response2, "\n");
// Third message - still remembers
const response3 = await chat("What are its main benefits?");
console.log("You: What are its main benefits?");
console.log("AI:", response3);
}
testConversation();
Notice how we set up the system message first, then have our conversation. The AI will act like a programming tutor throughout all exchanges.
How It Works
Here's what happens in each conversation turn:
- Set system message → Tell AI how to behave
- User asks a question → Add to messages array
- Format all messages → Create one big prompt with history
- Send to AI → AI sees full context including system instructions
- AI responds → Add response to messages array
- Repeat → Each new exchange builds on previous ones
// After the conversation above, your messages array looks like:
[
{
role: "system",
content:
"You are a helpful programming tutor. Keep your answers short and practical.",
},
{ role: "user", content: "What is TypeScript?" },
{ role: "assistant", content: "TypeScript is..." },
{ role: "user", content: "Show me a simple example" },
{ role: "assistant", content: "Here is a TypeScript example..." },
{ role: "user", content: "What are its main benefits?" },
{ role: "assistant", content: "The main benefits are..." },
];
Understanding System Messages Better
Different System Message Examples
// For a coding tutor
addMessage(
"system",
"You are a helpful programming tutor. Keep answers short and include code examples."
);
// For a friendly assistant
addMessage(
"system",
"You are a friendly and enthusiastic assistant. Use simple language."
);
// For a formal helper
addMessage(
"system",
"You are a professional assistant. Provide detailed and accurate information."
);
When to Use System Messages
- Always start with one: Set the AI's personality from the beginning
- Keep it simple: Don't make the system message too complicated
- Be specific: Tell the AI exactly how you want it to behave
Simple Improvements
Viewing Conversation History
function showHistory() {
console.log("Conversation so far:");
messages.forEach((msg) => {
console.log(`${msg.role}: ${msg.content}`);
});
}
Clearing the Conversation
function clearConversation() {
messages.length = 0; // Empty the array
console.log("Conversation cleared!");
}
Common Mistakes to Avoid
Forgetting the system message: Always set up how you want the AI to behave.
Using wrong role for system message: System messages should use 'system' role, not 'user'.
Forgetting to add messages: If you don't add the user message or AI response to your array, the conversation loses context.
Not sending history: Always send the complete conversation history with each API call.
Mixing conversations: Don't use the same messages array for different conversations or users.
FAQ
Summary
Managing conversations is about keeping track of what was said before and setting clear instructions for the AI. Start with a system message to define the AI's behavior, then store each user message and AI response in an array. Send the entire history with each new message so the AI remembers context and maintains its personality. The key components are: system messages for AI behavior, user messages for your input, assistant messages for AI responses, and always including the full conversation history.
Complete Code
You can find the complete, runnable code for this tutorial on GitHub: https://github.com/avestalabs/academy/tree/main/2-core-llm-interactions/managing-conversations