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.
- Step 1ReadStart with AI feature design before touching tools.
- Step 2BuildBuild toward: Connect a model API behind a practical interface.
- Step 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.
Connect intelligence as a bounded external capability.
Handle provider calls, errors, and secrets server-side.
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.
Build
Produce the artifact
Complete the lab and keep the result visible: Connect a model API behind a practical interface.
Record
Save review evidence
Capture what changed, what broke, and how AI feature design became clearer through the work.
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.
Ecosystem references
Platform and company logos are ecosystem references only: no affiliation, endorsement, interview access, hiring preference, salary outcome, or placement guarantee.
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.
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.
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
Skill signal
AI feature design is the market word. The lesson makes it visible through a small working artifact.
Proof artifact
The inspectable artifact is: Connect a model API behind a practical interface.
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.
Public
Written lesson stays open
Read the prepare and review material for lesson 16 on the public site before buying anything.
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.
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:
┌─────────────────────┐ ┌──────────────────────┐ ┌──────────────────────┐
│ 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:
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
| Term | Simple Meaning |
|---|---|
| Bounded feature | An AI call wrapped by your code at both ends — clear inputs, validated outputs |
| System prompt | The first message that sets the model's persona and constraints |
| Context | The dynamic data your code injects into the prompt (score, level, etc.) |
| Streaming | Returning the response token-by-token as it's generated (typewriter effect) |
| Fallback | What the user sees when the AI call fails — a default message, a heuristic, anything graceful |
| Rate limit | A cap on how often a single user (or your app) can call the model API |
| Idempotent prompt | A 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:
- 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.
- Added a backend route
POST /api/commentarythat takes a game event payload and calls Gemini:javascriptapp.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.`
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.
- 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.
- 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.)
- 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.
- 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. - 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:
- 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.")
- 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.