In this final chapter, we'll step back and review the complete Study Buddy architecture, understand how all pieces fit together, and explore ideas for extending the system.
Branch:
workshop/chapter-05-completegit checkout workshop/chapter-05-complete
| Chapter | Key AI SDK Concept | React Parallel |
|---|---|---|
| 0 | useChat / streamText |
useState + useEffect for async data |
| 1 | Tools with Zod schemas | Custom hooks with typed props |
| 2 | Tool-as-agent pattern | HOCs that fetch their own data |
| 3 | Multi-agent orchestration | React Router for user intent |
| 4 | Artifacts with persistence | Controlled components with form state |
-
"The AI SDK is React-friendly by design"
- Same mental models: hooks, components, state
- Streaming = Suspense for AI responses
- Tools/agents = just functions with extra metadata
-
"Start simple, add complexity as needed"
- Chapter 0 β 5 is a natural progression
- Don't start with 10 agents; start with 1
- Artifacts are optional until you need persistence
-
"The orchestrator is your routing layer"
- Good descriptions = good routing
- Test with edge cases ("What's the weather in a fictional city?")
- The AI is smarter than you think at understanding intent
- Show a complete flow: learn β quiz β study plan β check progress
- Demonstrate version history on artifacts
- Show the database (Mongo Express) to prove persistence
- AI SDK Documentation - Official docs
- Vercel AI Templates - More examples
- This workshop repo - Reference code
- "Can I use this with OpenAI/GPT-4?" - Yes! Just change the provider
- "How do I add authentication?" - It's already built in (NextAuth)
- "What about rate limiting?" - Already implemented (see
lib/ai/entitlements.ts) - "How do I deploy this?" - Standard Vercel/Next.js deployment
By the end of this chapter, you'll understand:
- The complete data flow from user input to AI response
- How orchestration, agents, and artifacts work together
- Best practices for production deployments
- Ideas for extending the system
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β User Interface β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β β Chat Panel ββ
β β βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β β β User: "Quiz me on JavaScript closures" βββ
β β β βββ
β β β AI: I've created a quiz for you! [Artifact opens β] βββ
β β βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β β β
β βββββββββββββββββββββββββββββββββββΌβββββββββββββββββββββββββββββββββββββ
β β Artifact Panel ββ
β β βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β β β Quiz: JavaScript Closures βββ
β β β βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ βββ
β β β β Q1: What is a closure? β βββ
β β β β β A) A function with access to outer scope β βββ
β β β β β B) A JavaScript class β βββ
β β β β β C) A loop construct β βββ
β β β β β D) A data type β βββ
β β β βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ βββ
β β βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
Let's trace a complete request through the system:
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β 1. USER INPUT β
β User types: "Quiz me on JavaScript closures" β
β β useChat hook captures input β
β β POST request to /api/chat β
βββββββββββββββββββββββββββββββββββββββ¬ββββββββββββββββββββββββββββββββββββ
β
β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β 2. API ROUTE β
β /app/(chat)/api/chat/route.ts β
β β Authenticates user (session) β
β β Creates dataStream for streaming β
β β Calls streamText with orchestrator model β
βββββββββββββββββββββββββββββββββββββββ¬ββββββββββββββββββββββββββββββββββββ
β
β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β 3. ORCHESTRATOR (Claude Haiku) β
β Analyzes user intent β
β Reads tool descriptions: β
β - tutor: "explain", "teach me" β
β - quizMaster: "quiz me", "test me" β MATCHES! β
β - planner: "study plan", "roadmap" β
β β Decides to call quizMaster tool β
βββββββββββββββββββββββββββββββββββββββ¬ββββββββββββββββββββββββββββββββββββ
β
β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β 4. QUIZ MASTER AGENT β
β lib/ai/agents/quiz-master.ts β
β β Writes artifact metadata to dataStream: β
β data-id: "abc-123" β
β data-title: "Quiz: JavaScript Closures" β
β data-kind: "flashcard" β
β data-clear: null β
β β Calls generateObject to create quiz questions β
β β Streams content: data-flashcardDelta: "{...quiz JSON...}" β
β β Signals completion: data-finish: null β
β β Saves to database β
β β Returns AgentResult β
βββββββββββββββββββββββββββββββββββββββ¬ββββββββββββββββββββββββββββββββββββ
β
β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β 5. DATA STREAM HANDLER (Client) β
β components/data-stream-handler.tsx β
β β Receives streamed data parts β
β β data-id β Sets artifact ID β
β β data-kind β Finds flashcardArtifact definition β
β β data-flashcardDelta β Calls onStreamPart handler β
β β Updates useArtifact global state β
β β data-finish β Sets status to "idle" β
βββββββββββββββββββββββββββββββββββββββ¬ββββββββββββββββββββββββββββββββββββ
β
β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β 6. ARTIFACT VIEWER β
β artifacts/flashcard/client.tsx β
β β FlashcardViewer component renders β
β β Parses JSON content β
β β Displays interactive quiz UI β
β β Handles user clicks on answers β
β β Shows explanations and tracks score β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
ai-chatbot/
βββ app/
β βββ (chat)/
β βββ api/
β βββ chat/
β βββ route.ts # Orchestrator + all agents
β
βββ lib/
β βββ ai/
β β βββ providers.ts # AI model configuration
β β βββ prompts.ts # System prompts
β β βββ tools/
β β β βββ get-weather.ts # Weather tool
β β βββ agents/
β β βββ index.ts # Barrel export for all agents
β β βββ types.ts # Agent type definitions
β β βββ tutor.ts # Tutor agent (text response)
β β βββ quiz-master.ts # Quiz Master agent (flashcard artifact)
β β βββ planner.ts # Planner agent (study-plan artifact)
β β βββ analyst.ts # Analyst agent (text response)
β βββ db/
β β βββ queries.ts # Database operations
β β βββ types.ts # MongoDB types
β βββ types.ts # Custom data stream types
β
βββ artifacts/
β βββ flashcard/
β β βββ server.ts # FlashcardData type
β β βββ client.tsx # Flashcard artifact + viewer
β βββ study-plan/
β β βββ server.ts # StudyPlanData type
β β βββ client.tsx # Study plan artifact + viewer
β βββ text/ # Built-in text artifact
β βββ code/ # Built-in code artifact
β βββ sheet/ # Built-in spreadsheet artifact
β
βββ components/
β βββ artifact.tsx # Artifact panel + registry
β βββ data-stream-handler.tsx # Processes streaming data
β
βββ hooks/
βββ use-artifact.ts # Global artifact state
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β ORCHESTRATOR β
β (Main Claude Model) β
β β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β β System Prompt: ββ
β β - You have specialized agents available ββ
β β - tutor: for explanations ββ
β β - quizMaster: for quizzes (creates flashcard artifact) ββ
β β - planner: for study plans (creates study-plan artifact) ββ
β β - analyst: for summarizing and analyzing content ββ
β β - Match user intent to the right agent ββ
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β β
β Available Tools: β
β ββββββββββββββ ββββββββββββββ ββββββββββββββ ββββββββββββββ ββββββββββ β
β β tutor β β quizMaster β β planner β β analyst β βweather β β
β β β β β β β β β β β β
β β generateTextβ βcreates β βcreates β βgenerateTextβ β Simple β β
β β β text β βartifact β βartifact β ββ text β β tool β β
β ββββββββββββββ ββββββββββββββ ββββββββββββββ ββββββββββββββ ββββββββββ β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
Why wrap agents as tools?
| Aspect | Benefit |
|---|---|
| Routing | Orchestrator uses natural language understanding to pick the right agent |
| Parameters | Zod schemas ensure agents receive valid, typed input |
| Isolation | Each agent has its own prompt and model configuration |
| Composability | Agents can be added/removed without changing core logic |
| Observability | Tool calls are logged and traceable |
// lib/types.ts
export type CustomUIDataTypes = {
// Artifact content (each kind has its own delta type)
textDelta: string;
imageDelta: string;
codeDelta: string;
sheetDelta: string;
flashcardDelta: string; // Quiz questions JSON
studyPlanDelta: string; // Study plan JSON
// Other data types
suggestion: Suggestion; // Document suggestions
appendMessage: string; // Append to message
// Artifact metadata
id: string; // Unique document ID
title: string; // Display title
kind: ArtifactKind; // Artifact type (typed enum)
// Control signals
clear: null; // Clear previous content
finish: null; // Signal completion
error: string; // Error signaling from agents
// Analytics
usage: AppUsage; // Token usage data (enriched with costs)
};Always return graceful errors from agents:
execute: async ({ topic }): Promise<AgentResult> => {
try {
// Agent logic...
return { agentName: "tutor", success: true, summary: text };
} catch (error) {
console.error(`[Tutor] Error:`, error);
return {
agentName: "tutor",
success: false,
summary: "I had trouble with that request. Please try again.",
data: { error: String(error) },
};
}
}The app already includes rate limiting:
// lib/ai/entitlements.ts
- Guest users: 20 messages/day
- Regular users: 100 messages/dayEach agent call uses tokens. Consider:
- Using smaller models for simple agents
- Caching common responses
- Monitoring usage with the built-in TokenLens integration
Ensure proper indexes for document queries:
// Important indexes for document retrieval
db.documents.createIndex({ id: 1, createdAt: -1 })
db.documents.createIndex({ userId: 1, createdAt: -1 })export const createCodeReviewerAgent = ({ session, dataStream }: CreateAgentProps) =>
tool({
description: "Review code for best practices, bugs, and improvements.",
inputSchema: z.object({
code: z.string().describe("The code to review"),
language: z.string().describe("Programming language of the code"),
focusAreas: z
.array(z.string())
.optional()
.describe("Specific areas to focus on (security, performance, etc.)"),
}),
execute: async ({ code, language, focusAreas }): Promise<AgentResult> => {
// Generate code review with generateText...
return {
agentName: "code-reviewer",
success: true,
summary: reviewText,
data: { language, focusAreas },
};
},
});An agent that can search the web and summarize findings:
export const createResearcherAgent = ({ session, dataStream }: CreateAgentProps) =>
tool({
description: "Research a topic and provide summarized findings.",
inputSchema: z.object({
query: z.string().describe("The topic or question to research"),
depth: z
.enum(["quick", "thorough"])
.default("quick")
.describe("How deep to research"),
}),
execute: async ({ query, depth }): Promise<AgentResult> => {
// Fetch from APIs, summarize with generateText...
return {
agentName: "researcher",
success: true,
summary: researchFindings,
data: { query, depth },
};
},
});Store and retrieve conversation context:
// Track what topics the user has learned
const userProgress = await getUserProgress(session.user.id);
// Pass to agents for personalized responses
execute: async ({ topic }) => {
const previousTopics = userProgress.completedTopics;
// Adjust explanation based on what they already know
}Let agents call each other:
// After explaining a topic, tutor suggests a quiz
return {
agentName: "tutor",
success: true,
summary: explanation,
suggestNext: {
agent: "quizMaster",
params: { topic }
}
};Create an artifact that shows learning progress:
// artifacts/progress/client.tsx
export const progressArtifact = new Artifact<"progress", ProgressMetadata>({
kind: "progress",
description: "Track learning progress across topics.",
content: ({ content }) => <ProgressDashboard data={content} />,
});| Chapter | What You Learned |
|---|---|
| 0 | Basic chat architecture, streaming, AI SDK fundamentals |
| 1 | Tools, Zod schemas, weather example, tool rendering |
| 2 | Tool-as-agent pattern, tutor agent, generateText |
| 3 | Multi-agent orchestration, quiz master, planner, generateObject |
| 4 | Custom artifacts, data streaming, interactive viewers |
| 5 | Complete architecture, production considerations, extensions |
- Orchestration is Key: The main model decides which agent to use based on intent
- Agents are Tools: The tool-as-agent pattern provides structure and type safety
- Artifacts are Powerful: Interactive documents enhance the chat experience
- Streaming is Essential: Real-time updates create a responsive feel
- Structure Enables Scale: Clean separation makes adding new agents easy
You now have a fully functional Study Buddy with:
- A tutor that explains concepts
- A quiz master that tests knowledge
- A planner that creates study schedules
- Interactive artifacts for quizzes and study plans
Take this foundation and make it your own! Add new agents, create custom artifacts, and build the learning assistant of your dreams.
Happy coding!