Kokil Thapa - Professional Web Developer in Nepal
Freelancer Web Developer in Nepal with 15+ Years of Experience

Kokil Thapa is an experienced full-stack web developer focused on building fast, secure, and scalable web applications. He helps businesses and individuals create SEO-friendly, user-focused digital platforms designed for long-term growth.

Build Your First AI Agent (Tool Use)

By Kokil Thapa | Last reviewed: August 2026

If you want to build your first AI agent (tool use) that actually performs tasks rather than just generating text, you need to treat the Large Language Model (LLM) as a reasoning engine connected to deterministic code, not a magic black box. In my experience building automated workflows for legal-tech portals and eCommerce systems, the difference between a chatbot and an agent is the ability to reliably execute functions like checking database records or processing payments via structured APIs. This guide walks through implementing this architecture using PHP 8.4 and Laravel 12, focusing on the practical integration patterns I use daily for building robust REST APIs and backend automation.

How Do You Architect Tool Use When You Build Your First AI Agent?

When you set out to build your first AI agent (tool use), the most critical architectural decision is maintaining strict separation between the probabilistic reasoning of the LLM and the deterministic execution of your application code. A common mistake I see in early implementations is treating the LLM's output as executable code or trusting it to format data without validation. In production environments, whether for a Nepal-based law firm portal or a global SaaS platform, the LLM should only be responsible for intent classification and parameter extraction.

The architecture follows a cyclic "ReAct" (Reasoning + Acting) pattern. The user provides input, which goes to the LLM along with a list of available tools defined as JSON schemas. If the LLM determines a tool is needed, it returns a structured request (not free text). Your Laravel application intercepts this, validates the parameters against your own business rules, executes the actual PHP function, and feeds the raw result back into the conversation context. Only then does the LLM generate the final human-readable response.

User InputNatural LanguageLLM ReasoningIntent + Params(Structured JSON)NO Direct ExecutionPHP ExecutorValidated LogicTool Result
The safe ReAct architecture for tool use: the LLM reasons, but your PHP application controls all execution and validation.

This separation is non-negotiable for any system handling sensitive data. On legal-tech projects like Court Marriage In Nepal or Mijar Law Associates, where accuracy directly impacts client outcomes, we never let the model guess case numbers or dates. The tool definition acts as a contract; the PHP executor enforces it. If the LLM hallucinates a parameter that doesn't match your schema or business logic, your application rejects the call before any side effects occur, returning an error message to the LLM so it can self-correct or ask the user for clarification.

How Do You Define Reliable Tool Schemas for LLM Function Calling?

The quality of your agent depends entirely on how clearly you define your tools. When you build your first AI agent (tool use), think of tool definitions as API documentation written specifically for a non-human consumer. Vague descriptions lead to hallucinated parameters and failed executions. In Laravel 12 with PHP 8.4, I recommend defining these schemas as dedicated Value Objects or configuration arrays rather than inline strings, making them testable and reusable.

A robust tool definition must include three elements: a precise name using snake_case or camelCase (consistent with your codebase), a description that explains when to use the tool (not just what it does), and strict parameter typing with enums where possible. For example, if you are building a booking agent for a travel site like Adventure Third Pole Trek, do not define a generic "book_trip" tool. Instead, define "check_trek_availability" and "create_trek_booking" as separate tools with explicit constraints.

<?php
// app/Ai/Tools/CheckTrekAvailability.php

namespace App\Ai\Tools;

class CheckTrekAvailability
{
    public static function definition(): array
    {
        return [
            'type' => 'function',
            'function' => [
                'name' => 'check_trek_availability',
                'description' => 'Checks real-time slot availability for specific trekking packages. Use this BEFORE attempting to book. Returns available dates and remaining spots.',
                'parameters' => [
                    'type' => 'object',
                    'properties' => [
                        'trek_id' => [
                            'type' => 'integer',
                            'description' => 'The unique numeric ID of the trek package from the database.',
                        ],
                        'start_date' => [
                            'type' => 'string',
                            'format' => 'date',
                            'description' => 'Preferred start date in YYYY-MM-DD format. Must be at least 14 days in future.',
                        ],
                        'group_size' => [
                            'type' => 'integer',
                            'minimum' => 1,
                            'maximum' => 15,
                            'description' => 'Number of people in the booking party.',
                        ],
                    ],
                    'required' => ['trek_id', 'start_date', 'group_size'],
                ],
            ],
        ];
    }
}

Notice the specificity in the description and parameter constraints. Adding minimum, maximum, and format hints helps modern LLMs constrain their output significantly. In practice, I have found that adding negative constraints in the description ("Do NOT use this for flight bookings") reduces misrouting by over 40% compared to positive-only descriptions. Always version your tool definitions alongside your API routes; changing a parameter name is a breaking change for the agent just as it is for a REST client.

How Do You Safely Execute Tools in Laravel Without Security Risks?

Security is where most experimental AI agents fail in production. When you build your first AI agent (tool use), you must assume the LLM will eventually produce malicious or nonsensical inputs. The execution layer must be a hardened boundary. Never evaluate LLM output as code. Never pass LLM-generated strings directly into SQL queries or shell commands without validation. Treat every tool call as untrusted user input, identical to handling a public form submission.

In Laravel, leverage Form Requests or custom validators even for internal AI tool calls. This creates a consistent validation layer that protects your business logic regardless of whether the request originates from a human user or an LLM. For a project like Nepal Gift Card, where agents might check balance or redeem codes, validating the gift card format and checking rate limits per session prevents abuse vectors that pure prompt engineering cannot stop.

  1. Parse and Validate: Decode the JSON tool call from the LLM response. Run it through a dedicated Validator or Form Request. If validation fails, return the error messages as the tool result so the LLM can retry.
  2. Authorize: Check permissions. Just because the LLM asked to delete a record doesn't mean the current user has that right. Apply Laravel Policies or Gate checks inside the tool executor.
  3. Execute Deterministically: Run the actual service method or repository query. Catch exceptions gracefully. Return structured data (arrays/objects), not formatted HTML or markdown strings.
  4. Sanitize Output: Before feeding results back to the LLM, strip sensitive fields (passwords, tokens, PII). The LLM only needs enough context to answer the user, not your entire database row.
  5. Log Everything: Record the original LLM request, validated parameters, execution result, and latency. This audit trail is essential for debugging agent behavior and improving prompts iteratively.
Raw LLM CallUNTRUSTEDSchema ValidateType + RangePolicy CheckAuth + Rate LimitExecuteSAFEFailure PathReturn Error to LLM → Retry or ClarifySuccess PathSanitized Result → LLM Context → User Response
Defense-in-depth pipeline: every AI tool call passes through schema validation, authorization, and sanitization before reaching business logic.

This defensive approach aligns with standard REST API security practices. The LLM is simply another API client with unusual latency characteristics. By reusing existing Laravel infrastructure for validation and authorization, you avoid creating a parallel security model that inevitably drifts from your main application's standards.

How Do You Handle Multi-Step Reasoning and Token Limits?

Real-world tasks rarely resolve in a single tool call. When you build your first AI agent (tool use) for complex domains like legal case management or multi-vendor eCommerce, you need to manage conversation state and token budgets carefully. Modern LLMs have large context windows, but stuffing them with full tool results wastes money and degrades reasoning quality. In production systems serving Nepali businesses where cost efficiency matters (Rs 5,000–15,000/month API budgets are common), intelligent context management is a feature, not an optimization.

Implement a summarization or truncation strategy for tool outputs. If a database query returns 500 records, never pass all of them to the LLM. Aggregate server-side first, or paginate and let the agent request subsequent pages explicitly. For long-running workflows, maintain a separate "working memory" store (Redis works well) that persists key facts across turns while discarding verbose intermediate steps. This keeps the active context window focused on current reasoning.

StrategyBest ForTrade-offLaravel Implementation
Full Context Pass-throughSmall datasets (<2K tokens)Simple but expensive at scaleDirect array serialization
Server-Side AggregationAnalytics, counts, summariesLoses granular detailEloquent aggregates / DB::raw
Paginated Tool ResultsLarge lists, search resultsRequires multi-turn coordinationCursor pagination + next_page_token
Semantic SummarizationDocument review, long historiesAdds latency + secondary LLM callQueue job + embedding cache
Working Memory StoreMulti-session workflowsComplexity in state managementRedis hash + TTL policies

For legal-tech portals handling document review, I typically combine server-side aggregation with paginated retrieval. The agent gets summary statistics immediately ("Found 47 matching cases, 12 from 2025") and can drill down only when necessary. This pattern mirrors how human lawyers actually work: scan first, investigate selectively. Aligning your agent's information access patterns with domain expert workflows improves both performance and user trust.

How Do You Test and Debug AI Agents Before Production Deployment?

Testing non-deterministic systems requires different strategies than traditional unit testing. When you build your first AI agent (tool use), you cannot assert exact string matches on LLM outputs. Instead, focus on testing the deterministic boundaries: tool schemas, validators, executors, and the orchestration logic between them. I treat the LLM itself as an external dependency to be mocked in unit tests, similar to mocking a payment gateway or SMS provider.

Create a comprehensive test suite covering three layers. First, unit test each tool executor with valid and invalid inputs to ensure validation and business logic work independently of the LLM. Second, integration test the orchestration layer using recorded LLM responses (golden files) to verify your parsing and state management handle expected formats correctly. Third, run periodic evaluation benchmarks against real LLM endpoints with curated test cases to detect regressions in model behavior or prompt effectiveness.

// tests/Unit/Ai/Tools/CheckTrekAvailabilityTest.php

public function test_rejects_past_dates(): void
{
    $executor = new CheckTrekAvailabilityExecutor();
    
    $result = $executor->execute([
        'trek_id' => 42,
        'start_date' => '2020-01-01', // Invalid: past date
        'group_size' => 4,
    ]);
    
    $this->assertArrayHasKey('error', $result);
    $this->assertStringContainsString('future date', $result['error']);
}

public function test_returns_structured_availability_on_valid_input(): void
{
    // Mock the TrekRepository to return predictable data
    $mockRepo = $this->createMock(TrekRepository::class);
    $mockRepo->method('getAvailability')->willReturn([
        'available_slots' => 8,
        'next_available_date' => '2026-09-15',
    ]);
    
    $executor = new CheckTrekAvailabilityExecutor($mockRepo);
    $result = $executor->execute([
        'trek_id' => 42,
        'start_date' => '2026-09-20',
        'group_size' => 4,
    ]);
    
    $this->assertArrayNotHasKey('error', $result);
    $this->assertEquals(8, $result['available_slots']);
}

For end-to-end evaluation, maintain a dataset of 50–100 representative user queries with expected tool calls and outcomes. Run these weekly against your staging environment. Track metrics like tool selection accuracy, parameter validity rate, and task completion success. These quantitative signals matter far more than subjective "it feels smarter" assessments. When working with clients in Nepal or globally, having concrete reliability metrics builds confidence during acceptance testing far better than demo theatrics.

Unit TestsTool ExecutorsValidators✓ DeterministicIntegration TestsOrchestration LogicGolden File Responses✓ Mocked LLMEval BenchmarksReal LLM EndpointCurated Test Cases⚠ Non-DeterministicKey Metrics to Track WeeklyTool Selection %Param Validity RateTask Completion %Avg Latency (ms)>95% target>98% target>90% target<3000ms target
Comprehensive testing pyramid for production AI agents: deterministic unit tests form the base, with non-deterministic evaluations monitored separately.

Debugging live agent issues requires observability beyond standard logging. Implement structured tracing that correlates user sessions with LLM API calls, tool executions, and intermediate reasoning states. Tools like Laravel Telescope or OpenTelemetry integrations help visualize these traces. When a user reports "the agent gave wrong availability," you need to replay the exact sequence of tool calls and responses to diagnose whether the failure was in the LLM's reasoning, your tool implementation, or stale underlying data.

Build Your First AI Agent (Tool Use) With Production Discipline

Building functional AI agents is no longer experimental; it is an engineering discipline requiring the same rigor as any other backend system. When you build your first AI agent (tool use), prioritize safety, testability, and cost control over novelty. Start with one or two well-defined tools solving genuine user problems rather than exposing your entire API surface. Validate relentlessly at every boundary. Measure everything. Whether you are automating legal intake forms in Kathmandu or building global SaaS features, the principles remain identical: the LLM reasons, your code executes, and your tests guarantee reliability.

If you are planning to integrate AI agents into your Laravel application or need guidance on architecting safe tool-use patterns for your specific domain, reach out to discuss your project requirements. I regularly help teams move from AI prototypes to production systems that respect both technical constraints and business realities.

Frequently Asked Questions

Tool use allows an LLM to execute external code, query databases, or call APIs instead of generating text from training data alone. The model outputs structured function calls that your application executes server-side.

API costs for a functional prototype typically range Rs 3,000–8,000 (~USD 22–60) monthly depending on token volume. Development time for a senior engineer to integrate tools securely into Laravel usually takes 20–40 hours.

Prism by EchoLabs is currently the most mature option for Laravel 11 and 12. It provides native support for tool definitions, multiple providers like OpenAI and Anthropic, and integrates cleanly with Eloquent models and queued jobs.

Define tools as strict PHP classes with validated parameters rather than allowing arbitrary code execution. In my experience building legal-tech portals, I wrap database queries and API calls in dedicated tool classes with explicit input validation, rate limiting, and audit logging to prevent prompt injection attacks or unauthorized data access.

Yes, but function-calling reliability varies significantly compared to commercial APIs. Models like Llama 3.1 or Qwen2.5 support tool schemas, yet they often require extensive fine-tuning or few-shot prompting to match GPT-4o or Claude 3.5 Sonnet accuracy. For production client projects where reliability matters, I still recommend commercial APIs unless data residency mandates local inference.

Never expose raw API keys to the LLM context. Store credentials in environment variables and inject them only at the execution layer within your tool class. When integrating payment gateways like eSewa or Khalti for Nepal-based commerce agents, I use scoped tokens with minimal permissions and validate every response server-side before returning results to the model.

Implement strict schema validation and error handling in your tool executor. If the model generates invalid parameters, catch the exception and return a structured error message back to the agent so it can self-correct. On production systems I maintain, I log all failed tool invocations to monitor hallucination patterns and refine system prompts accordingly.

Use Laravel queues for any tool taking over two seconds. Synchronous execution blocks the HTTP request and risks timeout errors during complex operations like document processing or third-party API calls. Dispatch tool executions as jobs and stream intermediate status updates to the frontend using Server-Sent Events or WebSockets for better user experience.

Mock external services and LLM responses in your test suite rather than hitting live APIs. Create fixture files representing expected tool-call JSON structures and assert your tool classes parse them correctly. For integration tests, use recorded API responses to ensure deterministic behavior without incurring token costs or flaky network dependencies.

SQL injection through manipulated parameters is the primary concern. Always use parameterized queries or Eloquent ORM methods inside tool classes—never concatenate user-derived strings. Additionally, implement row-level authorization checks so agents cannot access records outside their permitted scope, especially critical in multi-tenant applications like lawyer directories or client portals.

Set max_tokens on completion requests and implement caching for repeated tool queries using Redis. Truncate large database result sets before returning them to the model. On client projects, I configure daily spend alerts and circuit breakers that disable agent functionality if costs exceed predefined thresholds in NPR or USD.

Limited options exist, but most lack robust tool-execution frameworks. Plugins like AI Engine provide basic chatbot features but struggle with secure, custom tool integration. For serious agent workflows requiring database access or business logic, I recommend building a separate Laravel microservice that WordPress communicates with via REST API rather than forcing everything into PHP-FPM.

Enable verbose logging of the full message history including system prompts, user inputs, and raw model responses. Compare actual tool calls against expected behavior using structured logs. In practice, incorrect tool selection usually stems from ambiguous descriptions or overlapping functionality between tools—refine naming conventions and add negative examples to your system prompt.

Each round-trip adds 1–3 seconds for API inference plus tool execution time. Multi-step reasoning chains can easily reach 10–15 seconds total. Optimize by parallelizing independent tool calls, pre-fetching common data, and using smaller models for simple routing decisions while reserving larger models for complex synthesis tasks.

If your workflow involves fewer than three distinct actions or doesn't require dynamic decision-making, traditional conditional logic is simpler and more reliable. Custom agents add complexity around testing, monitoring, and cost management. Reserve agent architectures for genuinely ambiguous problems where rule-based systems fail, such as natural-language document analysis or adaptive customer support triage.

Share this article

Quick Contact Options
Choose how you want to connect me: