What is an Agent?
An agent is an autonomous AI entity that:
- Receives instructions through prompts
- Uses tools to interact with systems
- Maintains context across interactions
- Delegates to specialized agents via handoffs
- Produces streaming or structured output
import { agent } from '@deepagents/agent';
import { openai } from '@ai-sdk/openai';
const assistant = agent({
name: 'assistant',
model: openai('gpt-4o'),
prompt: 'You are a helpful assistant.',
});
Agent Configuration
The agent() function accepts a configuration object:
interface CreateAgent<Output, CIn, COut> {
// Required
name: string; // Unique agent identifier
model: LanguageModel; // AI SDK language model
prompt: Instruction<CIn>; // String, array, or function
// Optional
tools?: ToolSet; // Available tools
handoffs?: Agent[]; // Agents to delegate to
handoffDescription?: string; // Description for handoff tool
output?: z.Schema<Output>; // Structured output schema
toolChoice?: ToolChoice; // 'auto' | 'required' | 'none'
temperature?: number; // Model temperature
prepareHandoff?: PrepareHandoffFn; // Pre-handoff hook
prepareEnd?: PrepareEndFn; // Post-execution hook
}
Name
The agent’s unique identifier used in handoff tools and logging:
const agent1 = agent({ name: 'researcher', /* ... */ });
const agent2 = agent({ name: 'writer', /* ... */ });
// Creates tools: transfer_to_researcher, transfer_to_writer
Model
Any Vercel AI SDK compatible model:
import { openai } from '@ai-sdk/openai';
import { anthropic } from '@ai-sdk/anthropic';
import { google } from '@ai-sdk/google';
import { groq } from '@ai-sdk/groq';
const agent1 = agent({ model: openai('gpt-4o'), /* ... */ });
const agent2 = agent({ model: anthropic('claude-sonnet-4-20250514'), /* ... */ });
const agent3 = agent({ model: google('gemini-1.5-pro'), /* ... */ });
const agent4 = agent({ model: groq('llama-3.3-70b-versatile'), /* ... */ });
Prompt (Instructions)
Agents can receive instructions in multiple formats:
const agent = agent({
name: 'assistant',
model: openai('gpt-4o'),
prompt: 'You are a helpful assistant.',
});
const agent = agent({
name: 'assistant',
model: openai('gpt-4o'),
prompt: [
'You are a helpful assistant.',
'Always be concise.',
'Cite sources when possible.',
],
});
const agent = agent<unknown, { userId: string }>({
name: 'assistant',
model: openai('gpt-4o'),
prompt: (ctx) => `You are helping user ${ctx?.userId}.`,
});
import { instructions } from '@deepagents/agent';
const agent = agent({
name: 'assistant',
model: openai('gpt-4o'),
prompt: instructions({
purpose: [
'You coordinate research and writing tasks',
],
routine: [
'Analyze the user request',
'Delegate to specialists as needed',
'Synthesize results',
],
}),
});
The instructions() helper creates structured prompts optimized for agent coordination.
Agent Lifecycle
Understanding the agent execution flow:
Initialization
Agent is created with configuration. Tools and handoffs are registered.
Execution Start
execute(), generate(), or swarm() is called with a message and context.
Prompt Assembly
The prompt is evaluated (if function) and combined with system instructions.
Model Invocation
The LLM is called with messages, tools, and configuration.
Tool Execution
If the model calls tools, they execute and results are fed back.
Handoff (Optional)
If a transfer tool is called, control moves to the target agent.
Response Streaming
Text chunks and tool calls are streamed to the caller.
Completion
Final response is assembled and context is updated.
Design Patterns
Single-Purpose Agents
Create agents with focused responsibilities:
const summarizer = agent({
name: 'summarizer',
model: openai('gpt-4o'),
prompt: 'Summarize text concisely, preserving key information.',
});
const translator = agent({
name: 'translator',
model: openai('gpt-4o'),
prompt: 'Translate text accurately while preserving tone.',
});
const validator = agent({
name: 'validator',
model: openai('gpt-4o'),
prompt: 'Validate data against provided schemas.',
});
Coordinator Pattern
A single coordinator delegates to specialists:
const researcher = agent({
name: 'researcher',
model: openai('gpt-4o'),
prompt: 'Research topics thoroughly.',
handoffDescription: 'Research facts and gather information',
});
const analyst = agent({
name: 'analyst',
model: openai('gpt-4o'),
prompt: 'Analyze data and draw insights.',
handoffDescription: 'Perform data analysis',
});
const writer = agent({
name: 'writer',
model: openai('gpt-4o'),
prompt: 'Write clear, engaging content.',
handoffDescription: 'Create written content',
});
const coordinator = agent({
name: 'coordinator',
model: openai('gpt-4o'),
prompt: instructions({
purpose: ['Coordinate task completion using specialists'],
routine: [
'Understand the user request',
'Break down into subtasks',
'Delegate to appropriate specialists',
'Synthesize results',
],
}),
handoffs: [researcher, analyst, writer],
});
Pipeline Pattern
Sequential processing through multiple agents:
interface PipelineContext {
originalText: string;
summary?: string;
translation?: string;
}
const summarizer = agent<unknown, PipelineContext>({
name: 'summarizer',
model: openai('gpt-4o'),
prompt: 'Summarize the text concisely.',
});
const translator = agent<unknown, PipelineContext>({
name: 'translator',
model: openai('gpt-4o'),
prompt: (ctx) => `Translate this summary to Spanish: ${ctx?.summary}`,
});
// Execute pipeline
const ctx: PipelineContext = { originalText: '...' };
const summary = await generate(summarizer, ctx.originalText, ctx);
ctx.summary = await summary.text;
const translation = await generate(translator, ctx.summary, ctx);
ctx.translation = await translation.text;
Validation Pattern
Use structured output for validation:
const validator = agent({
name: 'validator',
model: openai('gpt-4o'),
prompt: 'Extract and validate contact information.',
output: z.object({
name: z.string(),
email: z.string().email(),
phone: z.string().regex(/^\+?[1-9]\d{1,14}$/),
valid: z.boolean(),
errors: z.array(z.string()),
}),
});
const result = await generate(
validator,
'Contact: John Doe, [email protected], +1234567890',
{}
);
console.log(result.output);
// {
// name: 'John Doe',
// email: '[email protected]',
// phone: '+1234567890',
// valid: true,
// errors: []
// }
Type Safety
Agents support full TypeScript inference:
interface UserContext {
userId: string;
permissions: string[];
}
interface AdminContext extends UserContext {
adminLevel: number;
}
const userAgent = agent<unknown, UserContext>({
name: 'user_agent',
model: openai('gpt-4o'),
prompt: (ctx) => {
// ctx is typed as UserContext | undefined
return `User ${ctx?.userId} with permissions: ${ctx?.permissions.join(', ')}`;
},
});
const adminAgent = agent<unknown, AdminContext>({
name: 'admin_agent',
model: openai('gpt-4o'),
prompt: (ctx) => {
// ctx is typed as AdminContext | undefined
return `Admin level ${ctx?.adminLevel}`;
},
});
Best Practices
Single Responsibility
Each agent should have one clear purpose
Clear Names
Use descriptive names like researcher, code_reviewer
Explicit Prompts
Provide detailed, specific instructions
Type Contexts
Define TypeScript interfaces for context
Minimal Handoffs
Avoid deep handoff chains (>3 levels)
Tool Documentation
Write clear tool descriptions and parameters
Anti-Patterns
Avoid these common mistakes:
- God Agents - Single agent with too many responsibilities
- Circular Handoffs - Agents that can delegate to each other
- Vague Prompts - Instructions that don’t specify behavior
- Missing Context Types - Relying on
any or untyped contexts
- Tool Overload - Giving an agent too many tools (>10)
Next Steps
Tools
Learn about tool integration
Handoffs
Master agent delegation
Context
Understand context management
Streaming
Implement streaming responses