DEV Community

Hristijan Stojanoski
Hristijan Stojanoski

Posted on

Your AI Agent Is Only as Smart as the Tools You Give It

I've been building with the Laravel AI SDK since it dropped, and one thing became clear fast: the agent itself is not the hard part. The tools are.

Let me explain what I mean.

What Are Tools in the Context of AI Agents?

If you've worked with any LLM API — OpenAI, Anthropic, Gemini — you know the model can generate text. But text alone doesn't get you far when you need the agent to actually do something in your application. It can't query your database. It can't check a user's permissions. It can't look up what media files are attached to a product. It can't tell you which translations are missing from your multilingual content.

Without a way to interact with your application's data, the agent is just a very expensive autocomplete.

That's where tools come in.

A tool is a PHP class that you hand to the agent. It has a schema (the parameters the AI can fill in) and a handle method (the code that runs when the AI decides to use it). The AI reads the schema, decides based on the user's natural language prompt whether to call the tool, fills in the parameters, and Laravel executes it. The result goes back to the AI so it can reason about what to do next.

Think of it this way: the agent is the bol is a PHP class that you hand to the agent. It has a schema (the parameters the AI can fill in) and a handle method (the code that runs when the AI decides to use it). The AI reads the schema, decides based on the user's natural language prompt whether to call the tool, fills in the parameters, and Laravel executes it. The result goes back to the AI so it can reason about what to do next.

Think of it this way: the agent is the brain, but tools are the hands. And a brain without hands can think all day long — it justrain, but tools are the hands. And a brain without hands can think all day long — it just can't get anything done.

Why I Started Building Custom Tools

I work with several Spatie packages across my Laravel projects — activity log, permissions, media library, tags, translatable, settings. These are staples in the Laravel ecosystem, and many of you probably use at least two or three of them. They solve real problems, they're well-maintained, and they have clean APIs that are a pleasure to work with.

When I started building AI agents for my applications, I hit a wall. The agent could answer general questions, sure. But the moment I asked "What permissions does the admin role have?" or "Show me all images attached to product 42" — it had nothing to work with. It didn't know my database schema. It didn't know about Spatie's models or how the data was structured. It was just guessing, and the guesses were confidently wrong.

So I started writing tools. One at a time. Each one focused on a single Spatie package.

The first was QueryPermissionsTool. I defined a schema with an action parameter (list roles, list permissions, get a user's access breakdown) and wired it up to Spatie Permission's models. Suddenly the agent could answer "Which roles can delete articles?" by actually querying the roles and permissions tables through the package's own API. Not hallucinating an answer — returning real data from the database.

That was the moment it clicked. The agent didn't get smarter — I just gave it the right hands.

What a Tool Looks Like in Practice

Here's the pattern. Every tool implements Laravel AI SDK's Tool contract with three methods:

description() — tells the AI what this tool does in plain English
schema() — defines the parameters the AI can pass (types, enums, constraints)
handle(Request $request) — executes the actual logic and returns a result

The beauty of this pattern is its simplicity. If you've ever written a Laravel controller action or an Artisan command, you already understand the mental model. Define what goes in, write the logic, return the result.

For example, QueryActivityLogTool lets the agent filter activity logs by causer, subject, date range, log name, and description. The schema defines all of these as optional string/integer parameters. In handle(), I build an Eloquent query using spatie/laravel-activitylog's Activity model, apply the filters conditionally with when(), and return JSON.

QueryTranslatableTool was another interesting one. It lets the agent inspect translations across locales — get all translations for a model, check which locales exist, and even find missing translations. When you're managing multilingual content, being able to ask "Which translations are missing for product 5?" and getting an actual answer from the database is a game-changer compared to manually clicking through admin panels.

The key insight: the AI decides which parameters to fill based on the user's prompt. If someone asks "What changed on order 42 today?", the model fills in subject_type, subject_id, and from. If they ask "Show me the last 5 auth logs", it fills log_name and limit. You define the possibilities — the AI makes the choices. You never call the tool yourself. You just register it on the agent and the framework handles the rest.

Why This Matters More Than You Think

Here's what I've learned building six of these tools:

  1. Tools make agents domain-aware. Without tools, your agent is a general-purpose chatbot that happens to live inside your Laravel app. With the right tools, it becomes an expert in your application's data. A permissions tool turns it into a security auditor. A media library tool turns it into an asset manager. A settings tool turns it into a configuration dashboard you can talk to. Same agent, different capabilities — all driven by which tools you register.

  2. The schema is your contract with the AI. The better you describe your parameters — clear descriptions, proper types, enums for fixed options — the more reliably the AI fills them in. A vague schema leads to vague tool calls. I spent more time refining schemas than writing the actual query logic. Good descriptions aren't just documentation — they're instructions to the AI about when and how to use the tool.

  3. Tools are composable. An agent with QueryPermissionsTool and QueryActivityLogTool registered together can answer compound questions like "What did admin users change in the payment log this week?" The AI chains tool calls on its own — it calls the permissions tool to understand the role, then the activity log tool to filter by those users. You don't orchestrate this. You don't write if-else chains or build a state machine. You just register the tools and the agent figures out the workflow.

  4. Read-only tools are the safe starting point. Every tool I built is read-only. The agent can query permissions but can't assign them. It can browse media but can't delete files. It can read settings but can't change them. This is intentional. You get enormous value from letting agents read your application state, with zero risk of unintended mutations. Start here. You can always add write tools later once you've built confidence in the agent's behavior and have proper guardrails in place.

  5. The tools outlast the models. AI models improve every few months. What doesn't change is your domain — your data, your packages, your business rules. The tools you build around that domain are the durable part. When the next model generation drops, your tools still work. They just work better.

The Bigger Picture

The Laravel AI SDK makes the plumbing invisible. You write a PHP class, define a schema, and the framework handles serializing it to the provider, parsing the response, creating the Request object, and calling your handle method. You don't think about JSON-RPC, function calling protocols, or provider differences between OpenAI and Anthropic. You think about your domain. That's what a good framework does — it lets you focus on the problem, not the infrastructure.

That's the real value here. Not the AI model — those will keep improving. The lasting value is in the tools you build around your specific data, your specific packages, your specific business logic. That's what makes your agent genuinely useful instead of generically clever. That's the difference between a demo and a product.

I packaged all of this into an open-source package called hristijans/spatie-agent-tools (https://github.com/hristijans/spatie-agent-tools) — drop-in tools for the Spatie packages most Laravel developers already use. Activity log, permissions, media library, tags, translatable, settings. Install it, register the tools you need, and your agent can query all of that through natural language.

https://github.com/hristijans/spatie-agent-tools

But more importantly, the pattern is what matters. Pick the package you use most, look at its public API, and write a tool for it. It takes an afternoon and completely changes what your agent can do.

The AI gives you the brain. Build it the right hands.

Top comments (0)