Effective prompts are crucial for getting high-quality results from language models. This guide covers best practices and tips for prompt engineering with AI SDK Core.
import { generateText } from 'ai';import { openai } from '@ai-sdk/openai';// Vagueconst { text } = await generateText({ model: openai('gpt-5'), prompt: 'Write about AI',});// Better: Specific and clearconst { text } = await generateText({ model: openai('gpt-5'), prompt: 'Write a 3-paragraph explanation of how transformer models work, suitable for software engineers with no ML background.',});
Set the model’s role and behavior with system messages:
const { text } = await generateText({ model: openai('gpt-5'), system: 'You are a professional technical writer. You write clear, concise documentation with code examples. Use simple language and avoid jargon.', prompt: 'Explain async/await in JavaScript',});
const { text } = await generateText({ model: openai('gpt-5'), prompt: `Summarize this article for a newsletter: Title: The Future of Web Development Article: ${articleContent} Keep the summary to 2-3 sentences and highlight key takeaways.`,});
Provide comprehensive tool and parameter descriptions:
import { tool } from 'ai';import { z } from 'zod';const queryDatabase = tool({ description: 'Query the user database to find users matching specific criteria. Returns user profiles including name, email, role, and registration date.', inputSchema: z.object({ role: z .enum(['admin', 'user', 'guest']) .optional() .describe('Filter by user role. Leave empty to include all roles.'), registeredAfter: z .string() .optional() .describe('ISO date string. Only return users registered after this date.'), limit: z .number() .max(100) .optional() .describe('Maximum number of users to return (max: 100, default: 10)'), }), execute: async ({ role, registeredAfter, limit = 10 }) => { /* ... */ },});
When tool dependencies exist, describe output in the tool description:
import { tool } from 'ai';import { z } from 'zod';const tools = { getUserId: tool({ description: 'Get the user ID for a given email address. Returns an object with a "userId" field containing the numeric user ID.', inputSchema: z.object({ email: z.string().email(), }), execute: async ({ email }) => ({ userId: 12345 }), }), getUserProfile: tool({ description: 'Get detailed user profile. Requires a numeric user ID (use getUserId tool first to get the ID from an email).', inputSchema: z.object({ userId: z.number().describe('The numeric user ID'), }), execute: async ({ userId }) => ({ /* ... */ }), }),};
import { generateText } from 'ai';import { openai } from '@ai-sdk/openai';const { text } = await generateText({ model: openai('gpt-5'), tools: { searchDatabase, updateRecord }, prompt: `You have access to database tools. Example usage: 1. To find a user: Use searchDatabase with {"query": "email@example.com"} 2. To update: Use updateRecord with {"id": 123, "fields": {"status": "active"}} Task: Find the user with email john@example.com and set their status to active.`,});
import { generateText, Output } from 'ai';import { openai } from '@ai-sdk/openai';import { z } from 'zod';const { output } = await generateText({ model: openai('gpt-5'), output: Output.object({ schema: z.object({ name: z.string().describe('The full name of the recipe'), servings: z.number().describe('Number of servings (typically 2-8)'), prepTime: z.number().describe('Preparation time in minutes'), ingredients: z.array( z.object({ name: z.string().describe('Ingredient name'), amount: z.string().describe('Amount in grams (g) or milliliters (ml)'), }) ).describe('List of all ingredients with precise amounts'), steps: z.array(z.string()).describe('Numbered cooking steps in order'), }), }), prompt: 'Generate a lasagna recipe for 4 people.',});
Use string schemas with transformations for dates:
import { generateText, Output } from 'ai';import { openai } from '@ai-sdk/openai';import { z } from 'zod';const { output } = await generateText({ model: openai('gpt-5'), output: Output.object({ schema: z.object({ events: z.array( z.object({ name: z.string(), date: z .string() .date() .describe('Date in YYYY-MM-DD format') .transform(value => new Date(value)), }) ), }), }), prompt: 'List 5 important events from the year 2000.',});// output.events[0].date is now a Date object
import { generateText } from 'ai';import { openai } from '@ai-sdk/openai';const result = await generateText({ model: openai('gpt-5'), prompt: 'Hello, world!', temperature: 0.7, topP: 0.9,});if (result.warnings && result.warnings.length > 0) { console.log('Warnings:', result.warnings); // Provider may not support both temperature and topP}
import { generateText } from 'ai';import { openai } from '@ai-sdk/openai';const result = await generateText({ model: openai('gpt-5'), prompt: 'Explain quantum computing',});// See exact request sent to OpenAIconsole.log(JSON.stringify(result.request.body, null, 2));
import { generateText } from 'ai';import { openai } from '@ai-sdk/openai';const { text } = await generateText({ model: openai('gpt-5'), prompt: `A store has 15 apples. They sell 8 apples and then receive a delivery of 12 more apples. How many apples do they have? Let's solve this step by step:`,});console.log(text);// "1. Start with 15 apples// 2. Sell 8: 15 - 8 = 7 apples// 3. Receive 12: 7 + 12 = 19 apples// Answer: 19 apples"
import { generateText } from 'ai';import { openai } from '@ai-sdk/openai';const { text } = await generateText({ model: openai('gpt-5'), system: `You are a senior software architect with 15 years of experience. You: - Prioritize maintainability and scalability - Consider security implications - Suggest modern, battle-tested solutions - Explain trade-offs clearly`, prompt: 'How should I structure authentication in a Node.js microservices application?',});
import { generateText } from 'ai';import { openai } from '@ai-sdk/openai';const { text } = await generateText({ model: openai('gpt-5'), prompt: `Write a product description for a wireless keyboard. Requirements: - Exactly 3 sentences - Mention at least 2 key features - Target audience: software developers - Tone: professional but friendly`,});