What is Invisible AI?
So far you've learned how to call an LLM programmatically and how to iterate on your prompt to perform different tasks (text extraction and summarization). Now let's move from basic scripts to features that create genuine value for users so you'll understand Invisible AI techniques - what they are, why users appreciate them, and how to build them with AI SDK + v0.
Let's set aside chatbots for a moment. Some of the most impactful AI features happen when users don't even realize it's there. Smart categorization. Instant summaries. Forms with intelligent assistance. These are the features we're building next.
Invisible AI is thoughtful enhancements that make your app easier to use.
Beyond Chatbots: Subtle Superpowers
Chatbots get much of the attention (we'll build one later!), but AI's real impact often comes from features users don't explicitly notice.
Invisible AI integrates helpful assistance and automation throughout your app and processes.
These features don't advertise themselves; they just work.
The goal is a seamless experience the user simply appreciates.
Further Reading: Ethics of Subtle AI
When AI is invisible, it raises important ethical considerations about transparency and user agency.
- The Ethics of Invisible AI ā Exploring transparency concerns when AI operates behind the scenes
- Transparent AI and User Trust ā Research on balancing seamless UX with appropriate transparency
- Designing Ethical AI Experiences ā Google's People + AI Research guidebook on ethical AI design patterns
Activation Energy: The Science Behind Great UX
You can think about UX as activation energy. Every form field, every click, every search = friction. It adds up over time sapping users of precious energy and attention.
Invisible AI done well actively reduces that friction. It automates repetitive tasks and makes complex flows feel intuitive. The needs of the user are anticipated without directly asking.
For product developers, this approach offers several benefits: less friction = more sign-ups, better conversion rates, fewer support tickets.
Advancing: From Basic Text to Structured Data
In the last lesson, you used generateText
for basic text generation. For most invisible AI features you'll be using generateObject
to generate structured data instead. This approach is powerful and allows you to turn prompts into data that your applications can use.
See the Difference
First, see these examples to understand text vs structured output:
Response will appear here
Schema:
z.object({ title: z.string(), date: z.string(), time: z.string().nullable(), location: z.string().nullable(), attendees: z.array(z.string()).nullable(), })
Object will appear here
Notice how the first returns plain text you'd need to parse, while the second gives you clean, typed JSON ready to use!
Build Your Own Comparison
Now let's build this ourselves. Your template already has starter files with imports and sample data ready.
Step 1: Implement Text Extraction
Open app/(2-invisible-ai)/test-structured.ts
. Inside the compareOutputs
function, replace the first TODO with a generateText
example:
// Replace the first TODO with this:
console.log('\n=== Using generateText (Plain Text) ===\n');
const { text } = await generateText({
model: 'openai/gpt-4.1',
prompt: `Extract all names from this text: ${namesText}`,
});
console.log('Raw text output:', text);
console.log('Output type:', typeof text);
console.log('Need to parse string to get individual names');
Step 2: Implement Structured Extraction
Now replace the second TODO with generateObject
:
// Replace the second TODO with this:
console.log('\n=== Using generateObject (Structured Data) ===\n');
const appointmentSchema = z.object({
title: z.string().describe('The meeting title or subject'),
date: z.string().describe('The date of the meeting'),
time: z.string().nullable().describe('The time of the event'),
location: z.string().nullable().describe('Where the event will take place'),
attendees: z.array(z.string()).nullable().describe('People attending'),
});
const { object } = await generateObject({
model: 'openai/gpt-4.1',
prompt: `Parse appointment details from: ${appointmentText}`,
schema: appointmentSchema,
});
console.log('Structured output:', JSON.stringify(object, null, 2));
console.log('Output type:', typeof object);
console.log('\nDirect property access:');
console.log('- Title:', object.title);
console.log('- Date:', object.date);
console.log('- Time:', object.time);
console.log('- Location:', object.location);
console.log('- Attendees:', object.attendees?.join(', '));
Step 3: Test Your Implementation
Run your script to see the difference:
pnpm invisible-ai:compare
You'll see:
- generateText returns: "Guillermo, Lee, Sarah" - just a string
- generateObject returns: A typed object with properties you can use directly!
Build Real Invisible AI Examples
Now let's create practical examples. Open app/(2-invisible-ai)/invisible-ai-demo.ts
. This file has two functions with TODOs for you to implement.
Step 1: Implement Smart Form Filling
In the smartFormFill
function, replace the TODOs:
// Replace the TODOs in smartFormFill with:
// Define the structure we want
const eventSchema = z.object({
eventTitle: z.string().describe('The title or purpose of the event'),
date: z.string().describe('The date of the event'),
time: z.string().nullable().describe('The time of the event'),
duration: z.string().nullable().describe('How long the event will last'),
location: z.string().nullable().describe('Where the event will take place'),
attendees: z.array(z.string()).nullable().describe('People attending'),
notes: z.string().nullable().describe('Additional notes or agenda items'),
});
// Extract structured data from natural language
const { object: eventDetails } = await generateObject({
model: 'openai/gpt-4.1',
prompt: `Extract calendar event details from: "${userInput}"`,
schema: eventSchema,
});
// Display as if it's a form being auto-filled
console.log('⨠AI automatically fills your form:\n');
console.log(`š
Event: ${eventDetails.eventTitle}`);
console.log(`š Date: ${eventDetails.date}`);
if (eventDetails.time) console.log(`ā° Time: ${eventDetails.time}`);
if (eventDetails.location) console.log(`š Location: ${eventDetails.location}`);
if (eventDetails.attendees) console.log(`š„ Attendees: ${eventDetails.attendees.join(', ')}`);
if (eventDetails.notes) console.log(`š Notes: ${eventDetails.notes}`);
console.log('\nā
Form ready to save - no manual input needed!');
Step 2: Implement Email Triage (Optional Challenge)
Try implementing the smartEmailTriage
function on your own! Use a similar pattern with generateObject
and a Zod schema for email categorization.
Test Your Work
Once you've implemented both scripts, run them to see Invisible AI in action:
# First, run your comparison to understand the difference
pnpm invisible-ai:compare
# Then see your practical examples
pnpm invisible-ai:demo
What You've Built
You've just implemented two key Invisible AI patterns:
- Text vs Structured Output - You saw how
generateObject
gives you typed, ready-to-use data instead of strings you need to parse - Smart Form Filling - Natural language input automatically populates form fields
- Email Triage (if you did the challenge) - Automatic categorization and prioritization
These patterns are the foundation for countless Invisible AI features!
You're Already Using Invisible AI. It's Everywhere.
Invisible AI is everywhere:
- Linear suggesting issue titles? AI.
- Figma search understanding "blue button"? AI.
- Gmail smart replies? AI.
- GitHub Copilot? AI.
- Analytics showing anomalies? AI.
These features don't scream "AI" - they just feel like good UX enhancing, but not interrupting, your workflows.
A Quick Review
- Invisible AI = subtle features that make your app easier to use
- Reduces UX friction (activation energy) and delights users
- Powered by
generateObject
+ Zod schemas for structured data generation
What apps do you use with hidden AI features? Identify 1-2 examples. How do they improve UX? How could you build something similar with the AI SDK?
Next Up: Building a Classification Engine
Ready to build something practical with Invisible AI? You'll start with auto-classification - a powerful feature that categorizes support tickets, content, or user messages automatically. It's an AI feature that is applicable in so many different applications. You'll build a system that takes unstructured user text, organizes it into clear categories using Zod schemas for type safety, and significantly improves support workflow efficiency.
Let's put generateObject
to work!