Module 2 (Gemini) - Lesson 2b: System Prompt with Gemini
Shape model behavior using systemInstruction in Gemini.
Published: 1/15/2026
Lesson 2b: System Prompt with Google Gemini
System prompts define the AI's role, personality, and behavior. Learn how Gemini handles system prompts differently from OpenAI and Anthropic.
Key Differences from OpenAI and Anthropic
OpenAI: System prompt is part of the messages array
messages: [ { role: "system", content: "You are a helpful assistant" }, { role: "user", content: "Hello" } ]
Anthropic: System prompt is a separate top-level parameter
system: "You are a helpful assistant", messages: [ { role: "user", content: "Hello" } ]
Gemini: System prompt uses config.systemInstruction
contents: "Hello", config: { systemInstruction: "You are a helpful assistant" }
Code Example
Create src/gemini/basic-prompt-with-system.ts:
import { GoogleGenAI, ApiError } from "@google/genai"; import dotenv from "dotenv"; // Load environment variables dotenv.config(); // Create Gemini client const gemini = new GoogleGenAI({}); // Async function with proper return type async function basicPromptWithSystem(): Promise<void> { try { console.log("Testing Gemini connection..."); // Make API call with system instruction const response = await gemini.models.generateContent({ model: "gemini-3-flash-preview", contents: "Suggest a travel destination", config: { systemInstruction: "You are a helpful travel assistant.", }, }); console.log("Basic Prompt with System Success!"); console.log("Tokens used:"); console.dir(response.usageMetadata, { depth: null }); if (!response.text) { throw new Error("No content in response"); } console.log("AI Response:", response.text); } catch (error) { if (error instanceof ApiError) { console.log("API Error:", error.status, error.message); } else if (error instanceof Error) { console.log("Error:", error.message); } else { console.log("Unknown error occurred"); } } } // Run the test basicPromptWithSystem().catch((error) => { console.error("Error:", error); });
Run It
pnpm tsx src/gemini/basic-prompt-with-system.ts
System Prompt Best Practices
1. Be Clear and Specific
Bad:
config: { systemInstruction: "You help people" }
Good:
config: { systemInstruction: "You are a helpful travel assistant with expertise in European destinations. Provide detailed, practical travel advice." }
2. Define Personality and Tone
config: { systemInstruction: "You are a friendly, enthusiastic travel expert. Use a warm, conversational tone while providing accurate information." }
3. Set Constraints
config: { systemInstruction: "You are a travel assistant. Always include: 1) Destination details 2) Best time to visit 3) Budget estimate. Keep responses under 200 words." }
4. Specify Format
config: { systemInstruction: "You are a travel assistant. Format all responses with clear sections: Overview, Attractions, Practical Tips." }
Comparison: With vs Without System Prompt
Without System Prompt
const response = await gemini.models.generateContent({ model: "gemini-3-flash-preview", contents: "Suggest a travel destination" });
Response: Generic travel suggestion
With System Prompt
const response = await gemini.models.generateContent({ model: "gemini-3-flash-preview", contents: "Suggest a travel destination", config: { systemInstruction: "You are a budget travel expert specializing in off-the-beaten-path destinations." } });
Response: Budget-friendly, unique destination with cost-saving tips
Advanced System Prompts
Multi-Part System Prompts
config: { systemInstruction: `You are a professional travel assistant with the following guidelines: **Expertise:** - European destinations - Budget travel tips - Cultural experiences **Response Format:** 1. Destination name and location 2. Why visit (2-3 sentences) 3. Best time to visit 4. Estimated budget 5. Top 3 attractions **Tone:** Friendly, informative, and encouraging` }
Role-Based System Prompts
// Code reviewer config: { systemInstruction: "You are an experienced TypeScript developer. Review code for best practices, potential bugs, and performance issues." } // Creative writer config: { systemInstruction: "You are a creative writing coach. Provide constructive feedback on story structure, character development, and prose." } // Technical explainer config: { systemInstruction: "You are a patient teacher explaining complex technical concepts to beginners. Use analogies and simple language." }
System Prompt vs User Prompt
System Prompt (Persistent Role)
- Sets the AI's personality
- Defines expertise area
- Establishes response format
- Stays the same across conversation
User Prompt (Specific Request)
- What you want the AI to do
- Changes with each message
- Specific questions or tasks
Example Conversation Flow
// Persistent system (in config) config: { systemInstruction: "You are a travel assistant specializing in Europe" } // First user message contents: "Suggest a destination in France" // Second turn (multi-turn requires array of contents) contents: [ { role: "user", parts: [{ text: "Suggest a destination in France" }] }, { role: "model", parts: [{ text: "..." }] }, { role: "user", parts: [{ text: "What about Italy?" }] } ] // System instruction affects ALL responses with European expertise
Side-by-Side Comparison
OpenAI Approach
const response = await openai.chat.completions.create({ model: "gpt-5-nano", messages: [ { role: "system", content: "You are a travel assistant." }, { role: "user", content: "Suggest a destination" } ] });
Anthropic Approach
const response = await anthropic.messages.create({ model: "claude-haiku-4-5", max_tokens: 1000, system: "You are a travel assistant.", messages: [ { role: "user", content: "Suggest a destination" } ] });
Gemini Approach
const response = await gemini.models.generateContent({ model: "gemini-3-flash-preview", contents: "Suggest a destination", config: { systemInstruction: "You are a travel assistant." } });
Key Differences Table
| Feature | OpenAI | Anthropic | Gemini |
|---|---|---|---|
| Location | In messages array | Top-level system | config.systemInstruction |
| Role name | "system" | N/A (separate param) | N/A (separate config) |
| Format | Message object | String | String |
| Multiple system msgs | Yes (in array) | Single string | Single string |
Common Patterns
Customer Support
config: { systemInstruction: `You are a customer support agent for TechCorp. Guidelines: - Be polite and professional - If you don't know, say so - Offer to escalate complex issues - Always confirm the customer's problem before solving Product knowledge: - We sell software subscriptions - Refunds available within 30 days - Support hours: 9am-6pm EST` }
Code Assistant
config: { systemInstruction: `You are an expert TypeScript developer. When reviewing code: 1. Check for type safety 2. Look for potential bugs 3. Suggest performance improvements 4. Follow best practices When writing code: - Use TypeScript strict mode - Include proper error handling - Add JSDoc comments for public APIs - Prefer async/await over callbacks` }
Educational Tutor
config: { systemInstruction: `You are a patient math tutor for high school students. Teaching style: - Break problems into small steps - Ask guiding questions before giving answers - Use real-world examples - Celebrate progress and correct mistakes gently Never just give the answer - guide the student to discover it themselves.` }
Key Takeaways
- System prompt uses
config.systemInstructionin Gemini - Different from OpenAI (in messages) and Anthropic (top-level
system) - Use system prompts to define role, personality, and constraints
- System prompts persist across the entire conversation
- Be specific about tone, format, and expertise
Next Steps
Learn how to control response creativity with temperature!
Next: Lesson 2c - Temperature Control
Quick Reference
// Minimal system prompt example const response = await gemini.models.generateContent({ model: "gemini-3-flash-preview", contents: "Suggest a destination", config: { systemInstruction: "You are a helpful travel assistant." } });
Common Pitfalls
- Putting system prompt in
contentsinstead ofconfig.systemInstruction - Using
system(Anthropic style) instead ofsystemInstruction - Forgetting to wrap
systemInstructionin theconfigobject - Making system prompts too vague or generic