You've used AI to classify and summarize text. Now, get even more precise with Structured Extraction. This pulls specific pieces of information from unstructured text and places them exactly where needed in your app.
Use generateObject with a detailed Zod schema to extract appointment details from natural language input and display them using a v0-prototyped UI.
Project Setup
Continuing with the same codebase from AI SDK Dev Setup. For this section, you'll find the classification example files in the
app/(4-extraction)/directory.
Imagine typing "Lunch with Sarah next Tuesday at noon at Cafe Central" and having it automatically create a perfect calendar event with all the details filled in. Apps like Fantastical pioneered this kind of natural language processing - it seems like magic, but that's structured extraction in action!

Manually parsing that input is a nightmare. Regex breaks easily, and complex parsing logic is brittle. But for an LLM? It's a natural fit. Models continue to improve giving better results at a lower cost.
Let's get your environment ready.
pnpm run dev).http://localhost:3000/extraction.You'll see a simple UI: an input field to type appointment details and an empty calendar card below it (this is our CalendarAppointment component, built with Vercel v0. We'll explore this AI-powered UI generator in the next lesson).

actions.ts)Like before, you will use a Server Action to handle the AI call.
schemas.ts: In app/(4-extraction)/extraction/, create the file schemas.ts.typescript
typescript
Why nullable() instead of optional()?
In our experience, explicitly requiring a field but allowing null (z.string().nullable()) often yields more reliable results from LLMs than making the field entirely optional (z.string().optional()). It forces the model to consider the field and consciously decide if the information is present or not.
actions.ts: In app/(4-extraction)/extraction/, create the file actions.ts.typescript
typescript
No you'll make the form work.
Open app/(4-extraction)/extraction/page.tsx. The basic UI is already set up.
Add the necessary imports and state at the top of the file (after the existing imports):
typescript
typescript
Find the line with <CalendarAppointment appointment={null} /> and replace it with:
typescript
The complete page.tsx file should look like this:
typescript
Let's test it! Go to http://localhost:3000/extraction.
Enter: Meeting with Guillermo Rauch about Next Conf Keynote Practice tomorrow at 2pm at Vercel HQ
Click "Extract Appointment".

The initial results might be okay, but not perfect (e.g., title includes names, date is wrong, time format is basic).
.describe() - The Key!The initial results might work, but they could be imperfect (e.g., title includes names, date might be wrong, time format is basic).
Let's improve our extraction using .describe() in our Zod schema. Update your schemas.ts:
typescript
Key refinements:
Save schemas.ts, refresh the browser, and test again with the same input. The extraction should now be much more accurate!

💡 Handling Relative Dates and Time Formats
Struggling with date parsing or time format inconsistencies? Try asking an AI assistant:
text
nullable() for potentially missing fields..describe() is essential for specifying formats, providing context (like today's date), and defining default logic.You've seen how structured data unlocks practical features like calendar extraction and form filling. Now, take a quick (optional) detour to explore Vercel v0, the tool that was used to prototype the CalendarAppointment UI in this example. You'll get hands-on experience generating UI components directly from prompts, accelerating your frontend development for AI features.
Mark this chapter as finished to continue
Mark this chapter as finished to continue