Integrating an LLM into Laravel with an AI SDK
You can call an LLM from Laravel by hand with Http, but an SDK handles multi-provider, tool calling, structured output, streaming and retries for you. Here is how the Laravel AI ecosystem works in 2026.
Calling a language model from Laravel is a POST request, and for a one-off you can write it with the Http client. Once you need structured output, tool calling, streaming to the browser, retries, and the ability to swap providers, an SDK earns its place. This guide covers the Laravel AI ecosystem in 2026 and how to use each capability, with Prism as the concrete example.
The 2026 landscape
- ✓Prism (prism-php/prism): provider-agnostic, one API across Anthropic, OpenAI, Mistral, Ollama and others. Text, structured output, tools, streaming, embeddings.
- ✓Official provider SDKs: the vendor packages when you want provider-specific features and are not planning to switch.
- ✓Laravel MCP: exposes your application as tools an MCP client (including an LLM agent) can call, the other direction from calling a model.
Text generation
The basic call: pick a provider and model, set a system prompt, send the user prompt. Keep the model choice in config so you can change it without touching code.
use Prism\Prism\Prism;
$response = Prism::text()
->using('anthropic', config('services.llm.model')) // e.g. claude-sonnet-5
->withSystemPrompt('You are a concise support assistant.')
->withPrompt($question)
->asText();
return $response->text;Structured output
When you need data, not prose, describe a schema and get back a typed array that has already been validated against it. This is the right tool for extraction (pull fields out of an email), classification (route a ticket), and any case where the next step is code, not a human reading text.
use Prism\Prism\Schema\{ObjectSchema, StringSchema, EnumSchema};
$schema = new ObjectSchema('ticket', 'A triaged support ticket', [
new StringSchema('summary', 'One sentence summary'),
new EnumSchema('category', 'The team it belongs to', ['billing', 'technical', 'account']),
new EnumSchema('priority', 'Urgency', ['low', 'medium', 'high']),
], ['summary', 'category', 'priority']);
$response = Prism::structured()
->using('anthropic', config('services.llm.model'))
->withSchema($schema)
->withPrompt($emailBody)
->asStructured();
$ticket = $response->structured; // ['summary' => ..., 'category' => ..., 'priority' => ...]Tool calling, kept safe
A tool lets the model call a function in your code: look up an order, check stock. The SDK handles the round trip, but you stay on the proposing side only. The model returns a tool name and arguments; your closure validates them against the current user's permissions and your business rules, then runs or refuses. The model never touches the database directly.
use Prism\Prism\Tool;
$orderStatus = Tool::as('order_status')
->for('Get the status of an order for the current user')
->withStringParameter('order_id', 'The order reference')
->using(function (string $orderId) use ($user) {
$order = $user->orders()->find($orderId); // scoped to the user
return $order ? "Status: {$order->status}" : 'Order not found';
});
$response = Prism::text()
->using('anthropic', config('services.llm.model'))
->withTools([$orderStatus])
->withMaxSteps(3)
->withPrompt($question)
->asText();Streaming to the browser
A generation call takes seconds; stream the tokens so the interface responds immediately. The SDK exposes the response as an iterable; wrap it in a Laravel streamed response over Server-Sent Events and consume it with EventSource on the front end.
return response()->stream(function () use ($question) {
$stream = Prism::text()
->using('anthropic', config('services.llm.model'))
->withPrompt($question)
->asStream();
foreach ($stream as $chunk) {
echo 'data: ' . json_encode(['text' => $chunk->text]) . "\n\n";
ob_flush();
flush();
}
}, 200, ['Content-Type' => 'text/event-stream', 'X-Accel-Buffering' => 'no']);Embeddings and pgvector
The same SDK generates embeddings, which you store in a pgvector column next to your relational data for a lightweight RAG setup, no separate vector database. Embed your documents at ingestion, embed the question at query time, and run a similarity search in SQL.
SDK abstraction or provider SDK directly?
| Need | By hand (Http) | Provider SDK | Prism (abstraction) |
|---|---|---|---|
| A single, simple call | Fine | Overkill | Fine |
| Structured output, tools, streaming | You build the plumbing | Yes, provider-shaped | Yes, uniform |
| Swap or compare providers | Rewrite each call | Rewrite each call | Change one string |
| A provider-specific feature (prompt caching, batch) | Manual | First-class | May lag behind |
Cost, caching, rate limiting, fallback
- ✓Cache answers to frequent or identical prompts so the same question is not paid for twice.
- ✓Rate-limit per user and per API key, and return a clear 429.
- ✓Track tokens and cost per feature, attributed to a user or tenant.
- ✓Have a non-AI fallback (a help page, a form) for when the provider times out or errors.
FAQ
- Do I need a package to use AI in Laravel?
- Not for a single simple call, which is just an Http request. You want an SDK once you need structured output, tool calling, streaming, retries, or the ability to swap providers without rewriting each call. Prism gives you one API across providers; a provider SDK gives you provider-specific features.
- Prism or the provider SDK?
- Use Prism when you value a uniform API and the ability to change or compare providers by editing one string. Use the provider SDK when you depend on provider-specific features such as prompt caching or the batch API, or when you have committed to one provider and want first-class support for it.
- How do I get structured JSON output from an LLM in Laravel?
- Describe the shape you want as a schema and use the SDK's structured mode. It constrains the model and validates the response against the schema, so you get back a typed array rather than parsing free text. It is the right approach for extraction and classification.
- How do I do tool calling cleanly?
- Define each tool as a closure that takes the model's arguments, validates them against the current user's permissions and your business rules, and then runs or refuses. The model proposes the call; your code decides. Never let the model reach the database directly, and scope every tool to the authenticated user server-side.
- How do I manage LLM costs in a Laravel app?
- Keep the model in config so you can move to a cheaper one per route. Cache frequent prompts, trim the system prompt and any retrieved context, rate-limit per user, and log tokens and cost per feature so a spike is visible before it is a surprise on the invoice.
An AI SDK does not add intelligence; it removes plumbing. It gives you one shape for text, structured output, tools, streaming and embeddings across providers, so the interesting work, the prompt, the context, the tool boundaries, is where your effort goes.
Need help with this topic? AI & RAG Integration
Discover this service →