Anthropic published a very popular blog, Building Effective Agents, a research post describing the most useful patterns for building production AI systems. The patterns are practical, proven, and widely adopted.
The good news: you can build every one of those patterns in Laravel today, with very little code, using the Laravel AI SDK.
All the examples in this post use just the agent() helper function, a single line to spin up an agent. That alone is enough to show how powerful these patterns can be. But the Laravel AI SDK doesn't stop there. You can bring your own dedicated agent classes, attach tools, configure models, add middleware, and build workflows as complex as production demands.
Install the Laravel AI SDK via Composer: composer require laravel/ai.
What Is a Multi-Agent Workflow?
A single LLM call works great for simple tasks. But for complex work, such as reviewing code, generating polished emails, or routing support tickets, you want multiple agents working together, each focused on a specific task.
Multi-agent workflows let you do multiple things:
- Break a task into ordered steps.
- Run independent steps in parallel.
- Route inputs to the right specialist.
- Evaluate and refine outputs in a loop.
The Five Patterns (and How You Can Use Them with the Laravel AI SDK)
1. Prompt Chaining
One agent's output becomes the next agent's input.
Think of it as an assembly line. Each step does one thing well and hands the result forward. This is the simplest and most common pattern.
Example: Cold Email Generator
Let’s think of a simple workflow: Draft → review quality → improve if needed.
With the Laravel AI SDK, the three agents are orchestrated through a Pipeline . Each step receives the full payload and passes it forward, enriched:
1$result = Pipeline::send(['company' => $company, 'role' => $role, 'email' => '', 'review' => []])2 ->through([3 fn ($payload, $next) => $next([...$payload, 'email' => $this->draftAgent($payload)]),4 fn ($payload, $next) => $next([...$payload, 'review' => $this->reviewAgent($payload)]),5 fn ($payload, $next) => $next($this->improveAgent($payload)),6 ])7 ->thenReturn();
Each pipeline step is backed by a dedicated agent:
1use function Laravel\Ai\{agent}; 2 3// Agent 1: Draft 4private function draftAgent(array $payload): string 5{ 6 return agent(instructions: 'Expert B2B copywriter. Write a concise, personalised cold email.') 7 ->prompt("Draft a cold email targeting the {$payload['role']} at {$payload['company']}.") 8 ->text; 9}10 11// Agent 2: Review (structured output)12private function reviewAgent(array $payload): mixed13{14 return agent(15 instructions: 'Cold email quality analyst. Be strict.',16 schema: fn (JsonSchema $schema) => [17 'hasPersonalisation' => $schema->boolean()->required(),18 'toneScore' => $schema->integer()->min(1)->max(10)->required(),19 'callToActionStrength' => $schema->integer()->min(1)->max(10)->required(),20 ],21 )->prompt($payload['email']);22}23 24// Agent 3: Improve only if scores fall short25private function improveAgent(array $payload): array26{27 $review = $payload['review'];28 29 if ($review['hasPersonalisation'] && $review['toneScore'] >= 7 && $review['callToActionStrength'] >= 7) {30 return $payload;31 }32 33 return [34 ...$payload,35 'email' => agent(instructions: 'Expert B2B copywriter.')36 ->prompt("Rewrite with better personalisation and a stronger CTA:\n{$payload['email']}")37 ->text,38 ];39}
✅ When to use it: This works for tasks with a clear sequence: generate, validate, refine, format. Each step should do one job well.
2. Routing
Classify the input first, then send it to the right agent.
Instead of a single agent handling everything, a classifier examines the input and selects the best specialist. Different query types get different instructions. Different complexity levels get different models.
Example: Customer Support
Workflow: Classify → pick the right instructions → choose a cheap or capable model based on complexity.
1use function Laravel\Ai\{agent}; 2 3$classification = agent( 4 instructions: 'Classify customer support queries.', 5 schema: fn (JsonSchema $schema) => [ 6 'type' => $schema->string()->required(), // general | refund | technical 7 'complexity' => $schema->string()->required(), // simple | complex 8 ], 9)->prompt("Classify: {$query}");10 11$instructions = match ($classification['type']) {12 'refund' => 'Customer service agent specialising in refund requests...',13 'technical' => 'Technical support specialist with deep product knowledge...',14 default => 'Friendly customer service agent...',15};16 17$agent = match ($classification['complexity']) {18 'complex' => new AdvancedSupportAgent($instructions),19 default => new StandardSupportAgent($instructions), // #[UseCheapestModel]20};21 22return $agent->prompt($query)->text;
#[UseCheapestModel] Attribute can be added to StandardSupportAgent for making simple queries run fast and cheaply. Complex queries go to the full model. The classifier decides which is which.
✅ When to use it: This is ideal when inputs vary widely in type or complexity and a single prompt can't handle all cases well.
3. Parallelization
Run independent agents at the same time.
When steps don't depend on each other, there's no reason to run them one by one. Laravel's Concurrency::run() is PHP's equivalent of Promise.all() . You can kick off all agents at once, and collect the results when they're done.
Example: Code Review
Workflow: Three specialist agents review code simultaneously. A fourth synthesizes their findings.
1use function Laravel\Ai\{agent}; 2 3[$security, $performance, $maintainability] = Concurrency::run([ 4 fn () => (new SecurityReviewAgent)->prompt($code), 5 fn () => (new PerformanceReviewAgent)->prompt($code), 6 fn () => (new MaintainabilityReviewAgent)->prompt($code), 7]); 8 9$summary = agent(instructions: 'Technical lead synthesising code reviews.')10 ->prompt("Summarise:\n" . json_encode([11 ['type' => 'security', 'review' => $security->text],12 ['type' => 'performance', 'review' => $performance->text],13 ['type' => 'maintainability', 'review' => $maintainability->text],14 ]))->text;
Three agents review in parallel. The summary agent only runs after all three are done, giving it the full picture.
✅ When to use it: Multiple independent analyses of the same input, or when you need several specialists to each look at the same problem.
4. Orchestrator-Workers
One agent coordinates; worker agents do the work.
The orchestrator understands the full task and decides what needs to be done. Workers are specialists—they only handle their specific job. The orchestrator calls them automatically as tools, in whatever order makes sense.
Example: Feature Implementation
Orchestrator agent receives a feature request, then automatically calls worker agents to create, modify, or delete files.
1use function Laravel\Ai\{agent}; 2 3$response = agent( 4 instructions: 'You are a senior software architect. Analyze feature requests and use the available tools to implement each required file change.', 5 tools: [ 6 new CreateFileAgentTool, 7 new ModifyFileAgentTool, 8 new DeleteFileAgentTool, 9 ],10)->prompt("Implement this feature: {$featureRequest}");
Each tool is itself an agent() — a sub-agent with its own focused instructions:
1use function Laravel\Ai\{agent}; 2 3class CreateFileAgentTool implements Tool 4{ 5 public function description(): Stringable|string 6 { 7 return 'Creates a new file with the appropriate code following best practices.'; 8 } 9 10 public function schema(JsonSchema $schema): array11 {12 return [13 'filePath' => $schema->string()->required(),14 'purpose' => $schema->string()->required(),15 ];16 }17 18 public function handle(Request $request): Stringable|string19 {20 return agent(21 instructions: 'You are an expert at implementing new files following best practices.',22 )->prompt("Create {$request['filePath']} to support: {$request['purpose']}")->text;23 }24}
You don't hardcode which files to change or what order to process them. The orchestrator figures that out from the feature request.
✅ When to use it: Complex tasks where the required steps aren't known upfront — the model needs to plan and delegate dynamically.
5. Evaluator-Optimizer
The pattern is generate → evaluate → improve, in a loop.
Sometimes one pass isn't enough. The evaluator-optimizer pattern runs output through a quality check and keeps refining until it meets the bar or hits the iteration limit.
Example: Content Writer
Workflow: Write a paragraph → score it → rewrite if not approved → repeat up to three times.
1use function Laravel\Ai\{agent}; 2 3$content = agent(instructions: 'You are a clear and concise writer.') 4 ->prompt("Write a short paragraph about: {$topic}")->text; 5 6$iterations = 0; 7 8while ($iterations < 3) { 9 $evaluation = agent(10 instructions: 'You are a writing quality evaluator.',11 schema: fn (JsonSchema $schema) => [12 'score' => $schema->integer()->min(1)->max(10)->required(),13 'approved' => $schema->boolean()->required(),14 'issues' => $schema->array()->items($schema->string())->required(),15 ],16 )->prompt("Rate this paragraph (approved if score >= 8): {$content}");17 18 if ($evaluation['approved']) {19 break;20 }21 22 $issues = implode(', ', $evaluation['issues']);23 $content = agent(instructions: 'You are a clear and concise writer.')24 ->prompt("Rewrite fixing these issues: {$issues} {$content}")->text;25 26 $iterations++;27}
The evaluator uses structured output to return a score, an approval flag, and a list of specific issues. The writer only retries if approved is false , and it knows exactly what to fix.
✅ When to use it: When you have clear quality criteria and the output benefits from iterative refinement: translations, writing, code generation.
Laravel AI SDK Simplifies Multi-Agent Work
Anthropic's research identified these patterns because they consistently work in production. What's striking is how little code they take in Laravel using the Laravel AI SDK.
| Pattern | Use when |
|---|---|
| Prompt Chaining | Fixed sequence of steps |
| Routing | Inputs vary in type or complexity |
| Parallelization | Independent tasks can run simultaneously |
| Orchestrator-Workers | Dynamic planning and delegation |
| Evaluator-Optimizer | Quality bar requires iteration |
Start simple. A single agent() call handles most tasks. Reach for these patterns only when the task genuinely needs them, and when you do, you'll find they're straightforward to implement.
You can install the Laravel AI SDK via Composer. Just run composer require laravel/ai.
To learn more about other Laravel AI tools, like Laravel Boost and MCP, check out this blog post.