ABCsteps lesson path

Adding AI to Your App

Use an AI API as a product capability, with clear inputs, outputs, error handling, and cost awareness. Build one artifact, keep one review trail, and make the work easy to inspect later.

Lesson
16
Time
45 min
Access
public lesson

Learning objective

Add AI as a bounded product feature with clear behavior.

Lab outcome

Connect a model API behind a practical interface.

Module milestone

Polish the product and add one AI-assisted capability with documentation.

Lesson proof workflow

Read, build, then review the evidence.

  1. OpenAI hero workflow iconStep 1ReadStart with AI feature design before touching tools.
  2. Node.js hero workflow iconStep 2BuildBuild toward: Connect a model API behind a practical interface.
  3. JSON hero workflow iconStep 3ReviewReview the evidence using Structured output.

Toolchain

AI belongs behind a clear product boundary with failures and costs handled.

These are the practical surfaces used in this lesson. Learn the habit first, then connect it to the wider engineering ecosystem.

OpenAI iconOpenAIModel API

Connect intelligence as a bounded external capability.

Node.js iconNode.jsBackend guardrail

Handle provider calls, errors, and secrets server-side.

JSON iconJSONStructured output

Shape prompts and responses into usable product data.

Proof of work

Leave one inspectable trail from this lesson.

The useful output is not a passive note. It is a small artifact another person can inspect: a working file, a command result, a commit, a screenshot, a README note, or a demo link.

Lesson lab: Connect a model API behind a practical interface.

Tool and platform logos are ecosystem references only: no affiliation, endorsement, interview access, hiring promise, salary promise, or placement guarantee.

OpenAI proof icon

Build

Produce the artifact

Complete the lab and keep the result visible: Connect a model API behind a practical interface.

Node.js proof icon

Record

Save review evidence

Capture what changed, what broke, and how AI feature design became clearer through the work.

JSON proof icon

Explain

Write the vocabulary

Use your own words for Provider errors and Structured output; this is what makes the lesson inspectable later.

Skills companies recognize

Translate the lesson into inspectable work language.

This lesson turns one small lab into the language a learner can use in a README, demo note, or technical conversation. The point is not to collect logos; the point is to explain work clearly enough that another engineer can inspect it.

Where this skill appears

Applied AI teams value bounded features that handle errors, cost, and user expectations honestly.

Applied AI productsBackend guardrailsCustomer-facing automation

Ecosystem references

GitHub skill ecosystem logoMicrosoft skill ecosystem logoGoogle Cloud skill ecosystem logoAWS skill ecosystem logoOpenAI skill ecosystem logoCloudflare skill ecosystem logoGoogle skill ecosystem logo

Platform and company logos are ecosystem references only: no affiliation, endorsement, interview access, hiring preference, salary outcome, or placement guarantee.

OpenAI skill proof icon

README line

Name the artifact

Lab proof: Connect a model API behind a practical interface. Connect it to AI feature design so the result reads like work, not a passive note.

Node.js skill proof icon

Review line

Explain the stack

Use OpenAI, Node.js, JSON to explain Provider errors and what changed between the first attempt and the inspected result.

JSON skill proof icon

Conversation line

Answer with evidence

If a team asks about Structured output, use this proof line: Show the AI feature boundary, fallback behavior, cost note, and structured output contract.

Proof translation

OpenAI proof translation icon

Skill signal

AI feature design is the market word. The lesson makes it visible through a small working artifact.

Node.js proof translation icon

Proof artifact

The inspectable artifact is: Connect a model API behind a practical interface.

JSON proof translation icon

Interview answer

Use Provider errors and Structured output to explain what changed, what failed, and how you verified it.

Paid guidance

Read publicly. Upgrade when guidance will help you finish.

This lesson remains part of the public written syllabus. Paid help is online-only and human-led: video walkthroughs as they roll out, live class context, WhatsApp Q&A, and project review around the same work.

No account wall, automated checkout, or placement promise is introduced here. Enrollment stays human-led by WhatsApp or call, and the useful proof remains the learner's own artifact.

OpenAI paid guidance icon

Public

Written lesson stays open

Read the prepare and review material for lesson 16 on the public site before buying anything.

Node.js paid guidance icon

Recorded

Recorded and live guidance clarify the work

Paid guidance can add founder-led video walkthroughs as they roll out and live online class context; the teaching explains the work, but does not replace the written lesson.

JSON paid guidance icon

Human

Questions use real context

When stuck, useful guidance starts from the route, error, screenshot, repo fragment, and the lab artifact: Connect a model API behind a practical interface.

Phase 1 · Briefing

Lesson briefing

Before You Study (5 mins)

Lesson focus: Module C made you a full-stack engineer. Module D makes you an AI product engineer. The distinction matters: AI as a chat-with-LLM novelty is one thing; AI as a bounded product feature — with clear inputs, predictable outputs, error handling, cost awareness, and a graceful failure path — is the engineering discipline that separates real products from demos. Today, your Snake game gets its first real AI feature: an in-game commentator that reacts to events with personality. By the end, you will have shipped AI in a way that respects the four constraints every production AI feature has to respect: latency, cost, reliability, and behavior bounds.

What you should have ready:

  • Module C complete — your full-stack system from Lesson 15 working
  • Your Gemini API key from Lesson 11 (or any provider's key)
  • Your backend/ Express server running with the LLM proxy endpoint from Lesson 12
  • About 60 minutes
  • A specific game event you want commentary on (game over, new high score, eating food)

The Concept

A bounded AI feature is a piece of an application where an LLM call is one step in a larger flow that your application controls. The model is the engine; your code is the chassis, the steering, the brakes, and the dashboard. Most production AI features look like this:

text
   ┌─────────────────────┐    ┌──────────────────────┐    ┌──────────────────────┐
   │  1. Trigger          │    │  2. Build prompt     │    │  3. Call model API   │
   │  (game event,        │ ─▶ │  (system + context   │ ─▶ │  (timeout, retry,    │
   │   user click, ...)   │    │   + user input)      │    │   cost ceiling)      │
   └─────────────────────┘    └──────────────────────┘    └──────────────────────┘
                                                                       │
                                                                       ▼
   ┌─────────────────────┐    ┌──────────────────────┐    ┌──────────────────────┐
   │  6. Render to UI     │    │  5. Parse / validate │    │  4. Receive response │
   │  (with fallback if   │ ◀─ │  (guard against bad  │ ◀─ │  (handle 4xx, 5xx,   │
   │   anything failed)   │    │   model output)      │    │   timeouts)          │
   └─────────────────────┘    └──────────────────────┘    └──────────────────────┘

Steps 1, 2, 5, and 6 are your code. Step 3 is the model provider. Step 4 is the network. The thing that distinguishes a real AI feature from a demo is that you handle every failure mode in steps 3 and 4, and never hand the user a broken experience because the model API was slow or down.

The four constraints every production AI feature respects:

  • Latency: A model call takes 0.5–5 seconds depending on the model and the prompt size. That's an eternity in UX terms. Either you stream the response (typewriter effect), make it async ("we'll email you the result"), or design the feature so the wait is acceptable (a loading spinner with a clear message).
  • Cost: Every API call costs money. Even at fractions of a paisa per call, a viral feature can cost ₹10,000 a day. You set per-user rate limits, you cache deterministic prompts, you choose the cheapest model that works.
  • Reliability: Model APIs go down, return 429 (rate-limited), return 500 (server error), or simply timeout. Your feature must degrade gracefully — show a default message, retry with backoff, or fall back to a simpler heuristic.
  • Behavior bounds: Models can produce wildly off-target output. You set a system prompt that constrains tone, length, and content. You parse the response and reject anything that doesn't fit. You never trust the model with anything destructive (like database writes) without validation in between.

The pattern you'll use today — and for the rest of your career — is system prompt + context + user input → constrained output:

text
System prompt: "You are a brief, encouraging game commentator.
                Output exactly one sentence. No emojis."

Context:       Player named 'Divyanshu' just died on level 5
                with score 1230. Their previous high was 1100.

User input:    (empty — this is an internal AI feature, not a chat)

Expected:      "Divyanshu, that's a new high score — 1230 beats your
                previous best by 130 points. Take a breath; level 6 is harder."

The system prompt is the most underrated tool in AI engineering. It's where you encode the persona, the format, the constraints, the things to never say. Treat it as production code, version-control it, iterate on it like you would any other critical algorithm.

Key principle: the user never directly types into the model. Your code constructs every prompt. This is what makes the feature "bounded" — the user provides game state, your code wraps that state in your prompt template, and the model only ever sees prompts you authored. (Truly user-driven prompts, like a chatbot, require a different set of defenses against prompt injection — a topic for Lesson 17 and beyond.)

Quick Concepts

TermSimple Meaning
Bounded featureAn AI call wrapped by your code at both ends — clear inputs, validated outputs
System promptThe first message that sets the model's persona and constraints
ContextThe dynamic data your code injects into the prompt (score, level, etc.)
StreamingReturning the response token-by-token as it's generated (typewriter effect)
FallbackWhat the user sees when the AI call fails — a default message, a heuristic, anything graceful
Rate limitA cap on how often a single user (or your app) can call the model API
Idempotent promptA prompt that, given identical inputs, produces (mostly) identical output — cacheable

What We Will Build

By the end of this lesson, you will have done these specific things:

  1. Designed the AI commentator feature on paper first. Decided which game events trigger commentary (game over, new high score, milestone like 1000 points), what tone, what length. Two minutes of design saves an hour of debugging.
  2. Added a backend route POST /api/commentary that takes a game event payload and calls Gemini:
    javascript
    app.post('/api/commentary', async (req, res) => {
      const { event, score, previousBest, playerName } = req.body
      // Validate inputs
      if (!['game_over', 'new_high_score', 'milestone'].includes(event)) {
        return res.status(400).json({ error: 'invalid event' })
      }
    
      const systemPrompt = `You are a brief, encouraging game commentator for a Snake game.
    

Output exactly one sentence under 25 words. Be specific to the event. No emojis.`

text
  const userPrompt = `Event: ${event}. Player: ${playerName}. Score: ${score}.${
    previousBest ? ` Previous best: ${previousBest}.` : ''
  } Comment.`

  try {
    const response = await fetch(
      `https://generativelanguage.googleapis.com/v1beta/models/gemini-2.0-flash:generateContent?key=${process.env.GEMINI_API_KEY}`,
      {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({
          contents: [{ parts: [{ text: systemPrompt + '\n\n' + userPrompt }] }],
          generationConfig: { temperature: 0.7, maxOutputTokens: 80 }
        }),
        signal: AbortSignal.timeout(5000)             // 5 second hard cap
      }
    )

    if (!response.ok) {
      throw new Error(`Model API ${response.status}`)
    }

    const data = await response.json()
    const text = data.candidates?.[0]?.content?.parts?.[0]?.text?.trim()

    if (!text || text.length > 200) {
      throw new Error('Bad model output')
    }

    res.json({ text })
  } catch (err) {
    console.error('Commentary failed:', err)
    // FALLBACK — never leave the user with a broken UI
    const fallbacks = {
      game_over:       'Good run. Try again — you have the moves.',
      new_high_score:  'New best — keep climbing.',
      milestone:       'Strong progress. The board is yours.'
    }
    res.json({ text: fallbacks[event] || 'Nice work.', fallback: true })
  }
})
```

3. Wired the frontend to call this endpoint on game-over, on new-high-score, and on milestones. Showed the response in a small banner that appears for 4 seconds.

  1. Tested every failure path on purpose:
    • Disconnected your machine from the internet — confirmed the fallback message appears.
    • Set process.env.GEMINI_API_KEY = 'invalid' temporarily — confirmed the fallback appears.
    • Added a await new Promise(r => setTimeout(r, 6000)) before the model call — confirmed the 5-second timeout fires and the fallback shows.
  2. Added a per-user rate limit so a malicious player can't mash the game-over screen and burn your quota. The simplest approach: store last-call timestamps in memory, reject if the same IP called within 3 seconds. (Production would use Redis; in-memory is fine for now.)
  3. Inspected the cost in your provider's dashboard. Played 20 games. Counted tokens used. Computed cost per 1,000 game-overs at current pricing. Wrote it down somewhere — knowing the cost of every feature is part of being an AI product engineer.
  4. Made the feature toggleable via config.json (Lesson 08 paying back): "aiCommentary": true. When false, the frontend skips the call entirely. The most senior thing about this: you can ship the feature, watch costs, and turn it off remotely without redeploying.
  5. Documented the feature in a one-paragraph note at the top of server.js:
    javascript
    /**
     * AI Commentary feature
     * Trigger: game-over, new-high-score, milestone events
     * Cost: ~₹0.001 per call at Gemini Flash pricing (Apr 2026)
     * Latency: typical 1-2s, 5s hard timeout
     * Fallback: hardcoded message strings — never broken UI
     * Rate limit: 1 call per IP per 3 seconds
     */
    

Step 8 is what separates "I added AI" from "I shipped AI as an engineer." Documentation of cost, latency, fallback, and rate limit is what your future-self (and your future team) will rely on when this code reaches week 2 of production.

Think About

Before studying, consider:

  1. Your AI commentary works perfectly when you write it on a Tuesday afternoon. On Friday at 11pm, the model API has a regional outage. What happens to your user's experience? (If you didn't write the fallback, the answer is "the game freezes or shows a JavaScript error." If you wrote it, the answer is "they see a hardcoded message and don't know anything was wrong.")
  2. Imagine 10,000 players play your game tonight, hitting game-over an average of 5 times each. That's 50,000 model calls. At ~₹0.001 per call, that's ₹50 in API costs. At a different model's pricing, it might be ₹500 or ₹5,000. Which model and which prompt size you chose matters; it scales with users. When does this stop being an academic question?

By the End

After this lesson, you'll:

  • Have an AI commentary feature reacting to specific game events
  • Have a system prompt that bounds the model's persona, format, and length
  • Have a 5-second timeout so a slow model call doesn't hang your UI
  • Have a fallback message for every event so a failed AI call never breaks the user experience
  • Have a per-user rate limit guarding your API quota
  • Know the cost-per-call and have it documented
  • Have made the feature toggleable via config so you can ship-and-watch
  • Have shipped your first production-grade AI feature

The wand is now in your hand. The discipline is using it lightly. 🤖

Next lesson · 17

Prompting for Useful Engineering Output

Learn how to give AI systems enough context, constraints, and verification steps to produce usable engineering help.

OpenAI next lesson iconGitHub Copilot next lesson iconVS Code next lesson icon