DEV Community

Cover image for Practical Prompt Engineering with Google Gemini and Node.js
Praveen Sripati
Praveen Sripati

Posted on • Edited on

Practical Prompt Engineering with Google Gemini and Node.js

Welcome back, developers! If you’ve just come from my previous post on As a Developer, Struggling with AI Prompts? Master AI Prompt Engineering Now, you’ve got the foundational knowledge down. You understand why clear instructions, context, and iterative refinement are crucial for getting desired responses from AI.

Now, it’s time to get our hands dirty. This post is your practical guide, a “codebook” filled with specific Node.js examples demonstrating how to apply those prompt engineering principles using the Google Gemini API. We’ll set up our environment and then dive into various techniques, showing you exactly how to craft effective prompts and integrate AI responses into your applications.

Let’s build!

Getting Started: Gemini & Node.js Setup

First things first, you’ll need a Google Cloud Project with the Gemini API enabled and an API key.

  1. Enable the Gemini API: Head over to the Google AI Studio or the Google Cloud Console. Follow the steps to create an API key for the Gemini API.

  2. Install the SDK: Open your terminal and run:

npm install @google/generative-ai dotenv
Enter fullscreen mode Exit fullscreen mode
  • @google/generative-ai: This is the official Google Gemini Node.js SDK.

  • dotenv: A handy package to securely load your API key from a .env file.

3. Create a .env file: In the root of your project, create a file named .env and add your API key like so:

API_KEY=YOUR_GEMINI_API_KEY
Enter fullscreen mode Exit fullscreen mode

Remember: Never commit your API keys directly into your source code!

4. Your Base Node.js Code: Create a file (e.g., gemini-codebook.js) and paste the following setup. This callGeminiApi function will be our wrapper for all the examples that follow.

// gemini-codebook.js
require('dotenv').config(); // Load environment variables

const { GoogleGenerativeAI } = require('@google/generative-ai');

const API_KEY = process.env.API_KEY;

if (!API_KEY) {
    console.error("API_KEY not found in .env file. Please create a .env file with API_KEY=YOUR_GEMINI_API_KEY");
    process.exit(1);
}

const genAI = new GoogleGenerativeAI(API_KEY);
const model = genAI.getGenerativeModel({ model: "gemini-pro" }); // Using gemini-pro for text tasks

/**
 * Calls the Google Gemini API with a given prompt and optional model parameters.
 * @param {string} prompt The text prompt to send to the AI.
 * @param {object} modelParams Optional parameters for the AI model (e.g., temperature, maxOutputTokens).
 * @returns {Promise<string>} The text response from the Gemini API.
 */
async function callGeminiApi(prompt, modelParams = {}) {
    try {
        const generationConfig = {
            temperature: modelParams.temperature || 0.7, // Default temperature
            maxOutputTokens: modelParams.maxOutputTokens || 2048, // Default max tokens
            // Add other parameters like topP, topK if needed here
        };

        console.log("\n--- Gemini API Call ---");
        console.log(`Prompt sent:\n'${prompt}'`);
        console.log(`Model Parameters: ${JSON.stringify(generationConfig)}`);

        const result = await model.generateContent(prompt, generationConfig);
        const response = await result.response;
        const text = response.text();

        console.log(`\nGemini Response:\n${text}`);
        return text;

    } catch (error) {
        console.error("Error calling Gemini API:", error);
        // Log more details if available, like error.response.candidates
        return `Error: ${error.message}`;
    }
}
Enter fullscreen mode Exit fullscreen mode

Now, let’s explore individual prompt engineering techniques with runnable Node.js code snippets. You can add each of these async function blocks to your gemini-codebook.js file and then call them one by one in your main execution flow.

1. Clear and Specific Instructions:

Context: When I need to distill a large chunk of information into a digestible format, I ensure my prompt is incredibly direct about the desired output. This prevents the AI from giving me a lengthy essay when I just need the highlights.

async function exampleClearSpecificInstructions() {
    console.log("\n## 1. Clear and Specific Instructions (Summarization)");
    const longArticle = `Artificial intelligence (AI) has rapidly advanced in recent years, transforming various industries and aspects of daily life. From sophisticated natural language processing models that can generate human-like text to advanced computer vision systems capable of recognizing objects and faces, AI's capabilities continue to expand. However, along with its immense potential, AI also presents significant challenges, including ethical considerations, job displacement, and the need for robust regulatory frameworks. The future of AI hinges on addressing these concerns while harnessing its power for societal benefit.`;
    const promptSummary = `Summarize the following text about AI advancements in exactly 3 concise bullet points.
Text: "${longArticle}"
`;
    await callGeminiApi(promptSummary);
}

// To run this specific example, uncomment the line below:
// exampleClearSpecificInstructions();
Enter fullscreen mode Exit fullscreen mode

2. Defining Output Format:

Context: In development, receiving structured data is paramount. If the AI’s response isn’t consistently formatted, it breaks my application. I explicitly ask for JSON so I can easily parse it into a JavaScript object.

async function exampleDefiningOutputFormat() {
    console.log("\n## 2. Defining Output Format (JSON Example)");
    const promptJson = `
Generate a JSON object for a hypothetical user profile.
The object should have the following keys: 'username' (string), 'id' (number), 'email' (string), and 'is_active' (boolean).
Example Data: Username 'dev_master', ID 12345, Email 'dev@example.com', Active status true.
`;
    const jsonResponse = await callGeminiApi(promptJson);
    try {
        const parsedJson = JSON.parse(jsonResponse);
        console.log("\nParsed JSON:", parsedJson);
        console.log(`Username: ${parsedJson.username}, ID: ${parsedJson.id}`);
    } catch (e) {
        console.error("Failed to parse JSON response:", e);
    }
}

// To run this specific example, uncomment the line below:
// exampleDefiningOutputFormat();
Enter fullscreen mode Exit fullscreen mode

3. Few-Shot Prompting:

Context: When I need code or highly specific text output, simply asking isn’t always enough. I provide an example of the desired format — in this case, a JSDoc-commented function — to guide the AI to match that exact style. I also use a lower temperature here to reduce creativity and increase adherence to the pattern.

async function exampleFewShotPrompting() {
    console.log("\n## 3. Few-Shot Prompting (Code Generation Style)");
    const promptFewShotCode = `
Generate a simple JavaScript function for calculating the area of a rectangle.
Here's an example of how you should format the function:

// Example function for calculating circle area
/**
 * Calculates the area of a circle.
 * @param {number} radius The radius of the circle.
 * @returns {number} The area of the circle.
 */
function calculateCircleArea(radius) {
  return Math.PI * radius * radius;
}

// Now, generate the function for rectangle area:
`;
    await callGeminiApi(promptFewShotCode, { temperature: 0.3 }); // Lower temp for more predictable code
}

// To run this specific example, uncomment the line below:
// exampleFewShotPrompting();
Enter fullscreen mode Exit fullscreen mode

4. Role-Playing / Persona:

Context: I often need explanations tailored for different audiences. By assigning a persona (e.g., “senior DevOps engineer”), I instruct the AI to adopt a specific tone and knowledge level, ensuring the explanation is appropriate and easy for the target audience to understand.

async function exampleRolePlayingPersona() {
    console.log("\n## 4. Role-Playing / Persona (Technical Explainer)");
    const promptPersona = `
You are a senior DevOps engineer explaining Docker containers to a junior developer.
Explain what Docker is and why it's useful for deploying applications, using simple, clear language.
`;
    await callGeminiApi(promptPersona);
}

// To run this specific example, uncomment the line below:
// exampleRolePlayingPersona();
Enter fullscreen mode Exit fullscreen mode

5. Chain-of-Thought (CoT) Prompting

Context: For complex problems, especially those involving logic or calculations, I don’t just want the answer; I want to see the reasoning. Asking the AI to “show your step-by-step calculations and reasoning” improves the accuracy of the final result and helps me debug if the answer is off.

async function exampleChainOfThought() {
    console.log("\n## 5. Chain-of-Thought (CoT) Prompting (Problem Solving)");
    const promptCoT = `
A train leaves station A at 10:00 AM traveling at 60 km/h.
Another train leaves station B at 11:00 AM traveling at 80 km/h towards station A.
The distance between station A and station B is 400 km.
At what time will the two trains meet? Show your step-by-step calculations and reasoning clearly.
`;
    await callGeminiApi(promptCoT);
}

// To run this specific example, uncomment the line below:
// exampleChainOfThought();
Enter fullscreen mode Exit fullscreen mode

6. Using Delimiters for Clarity

Context: When my prompts become lengthy, containing instructions, input data, and formatting requirements, they can get messy. Using clear delimiters like XML-like tags helps the AI distinguish between different parts of the prompt, ensuring it understands exactly what to do with each section.

async function exampleDelimitersForClarity() {
    console.log("\n## 6. Using Delimiters for Clarity (Multi-part Request)");
    const rawData = `Product: Laptop, Price: 1200, Category: Electronics, Stock: 50
Product: Keyboard, Price: 75, Category: Peripherals, Stock: 200
Product: Mouse, Price: 30, Category: Peripherals, Stock: 300`;

    const promptDelimited = `
<instructions>
Process the provided product data.
For each product, extract its name, price, and stock.
Then, generate a short summary for products with stock less than 100.
</instructions>

<data>
${rawData}
</data>

<output_format>
List the low-stock products in markdown bullet points, formatted as "Product Name (Stock: X)".
</output_format>
`;
    await callGeminiApi(promptDelimited);
}

// To run this specific example, uncomment the line below:
// exampleDelimitersForClarity();
Enter fullscreen mode Exit fullscreen mode

Next Steps: Integrate and Iterate!

You’ve now got a practical set of examples for applying prompt engineering principles with the Google Gemini API in Node.js. The key from here is integration and iteration.

  • Integrate: Think about where AI can enhance your existing applications. Can it summarize user feedback, generate product descriptions, or provide real-time code suggestions?

  • Iterate: As you use these prompts in real-world scenarios, you’ll inevitably find room for improvement. Continue to test, evaluate, and refine your prompts based on the AI’s responses and your application’s needs.

Prompt engineering is an evolving skill, and the more you practice, the more intuitive it becomes. Go forth and build amazing things with AI!

Want to see a random mix of weekend projects, half-baked ideas, and the occasional useful bit of code? Feel free to follow me on Twitter!
Follow @x

Top comments (0)