The Batteries-Included AI Toolkit
The Laravel AI SDK is a first-party toolkit for adding AI features to your applications. Using a helpdesk app as our playground, you’ll learn structured output, chat with memory, streaming, tool use, retrieval, and everything else you need to build AI features that are reliable, testable, and ready for production.
This is an incredibly powerful toolkit, and I can't wait to show you what you can build. Let's get going!

Progress
Series Info
- Episodes
- 13
- Run Time
- 3h 10m
- Difficulty
- Intermediate
- Last Updated
- Mar 23, 2026
- Version
- Latest
Series Episodes
- Episodes (13)
Structured Output as the Foundation
We’ll kick things off with a simple ticket triage flow: take a ticket subject and message, send them to an agent, and get back data we can use immediately. UsingHasStructuredOutputand a clear schema, we’ll capture priority, department, sentiment, tags, and a summary, then apply it straight back to the ticket.Logging AI Usage
With the first feature in place, it’s time to add real visibility into what the provider is doing. We’ll createAiRunandAiUsage, wire them into the triage flow, and record both the request and token usage details so debugging doesn’t become guesswork.Conversation Architecture & Context Management
Next, we’ll switch gears and build ticket-scoped chat so each ticket keeps its own context. We’ll add anai_conversation_idto tickets, create a conversationalTicketAssistantwithRemembersConversations, and expose it through aTicketChatControllerso we can start and continue conversations while still logging runs and saving messages.Demoing Our Chat Agent
Let’s put the chat experience in front of users. We’ll add a small Alpine panel to the ticket page, call our controller withfetch, and handle theCSRFtoken along the way. Once the request/response loop feels solid, we’ll be ready to make it feel even better with streaming.Streaming AI Responses to the UI
A chat that waits for the full response feels slow, so let’s instead stream it! We’ll add anoutput_textcolumn toai_runs, create a streaming route and controller, and usefetchwithtext/event-streamin Alpine so the reply shows up chunk by chunk.Giving AI the Ability to Use Tools
Now we’ll stop the assistant from guessing by giving it safe, bounded tools for real app data. We’ll generate a couple tool classes withArtisan, enforce strict schemas and authorization, and add guardrails likemax_stepsso it can fetch ticket facts and recent messages without going off the rails.Retrieval Augmented Generation with Your Database
Time to add retrieval. We’ll generate embeddings for a query, compare them to embeddings we store for documents, and return the best matches. Even onSQLite, we can get surprisingly far by storing vectors in a JSON field and using a smallVectorhelper to calculate cosine similarity.Retrieval from Files and External Sources
Next, we’ll move from self-managed embeddings to provider-managed vector stores so the workflow can scale. We’ll build an upload and Q&A flow with anUploadedDocumentmodel, aDocumentQaAssistantusing theFileSearchtool, and endpoints tostore,ask, anddestroydocuments while tracking provider IDs and metadata.Designing for Reliability and Failure
AI features are great until a provider is slow, down, or rate-limited. We’ll add resilience with provider failover, sensibletimeoutsettings, and a fallback to thequeue. To practice, we’ll build a product description agent that can run sync when it can and async when it must.Controlling Cost Before It Controls You
Token usage adds up fast, so we’ll put guardrails in place. We’ll correlateAI runswithAI usagesusing aninvocation_id, hook into events to record usage automatically, and addEnforceAiBudgetmiddleware to enforce a daily budget before costs get out of hand.Safety Layers and Guardrails
Before we ship anything, we need safety layers that we can trust. We’ll wire upInputSafetyMiddlewareandOutputSafetyMiddlewareto screen prompts and filter responses, and we’ll lock down tools likeWebSearchwith an allow list of approved domains.Testing AI Features Without Hitting the API
Tests that call real providers are slow, flaky, and expensive. We’ll keep everything local and deterministic withfake(), then add a safety net withpreventStrayPrompts()(and similar guards for embeddings, files, and stores) so the test suite fails fast if anything slips through.Exposing Your AI Features with MCP
Let’s expose one of our features to external agents, and do it safely. We’ll install Laravel MCP, spin up anMCPserver, and publish atriageTickettool with a simple inputschema. Finally, we’ll use the inspector to confirm everything responds exactly how we expect.