Vizra ADK

repository·master·Indexed 43 days ago

https://github.com/vizra-ai/vizra-adk

A Laravel-native development kit for building autonomous AI agents with reasoning, tool usage, and persistent memory. It integrates with the Laravel ecosystem via Eloquent, Artisan, and Service Providers, featuring a fluent executor API for asynchronous agent queuing, support for LLM and Media agents, and extensibility through the Laravel macro pattern.

Tokens
125.1K
Snippets
321
Records
405
Agent score
54%

What's inside Vizra ADK

  1. Core features of Vizra ADK

    master

    Vizra ADK provides several built-in capabilities for building production-ready AI agents:

    • Multi-LLM Support: Compatibility with OpenAI, Anthropic, and Google Gemini.
    • Tool System: Ability to grant agents custom capabilities via tools.
    • Smart Memory: Support for Vector memory and RAG (Retrieval-Augmented Generation) for conversational context.
    • Complex Workflows: Support for multi-step processes.
    • Quality Evaluations: Automated testing using the 'LLM-as-a-Judge' pattern.
    • Debug Tracing: Visibility into the agent's internal reasoning and thought process.
  2. Access Agent Memory within Tools

    master

    Every tool implemented via ToolInterface automatically receives the agent's memory as the third parameter in the execute method. This allows tools to read from and write to the agent's persistent memory, enabling personalized experiences and cross-session state management.

    Available Memory Methods

    • addFact(string $content, float $confidence): Store immutable facts.
    • addLearning(string $insight): Track insights discovered during interaction.
    • addPreference(string $value, string $key = 'general'): Store user preferences.
    • updateSummary(): Update the overall user profile summary.
    public function execute(
        array $arguments,
        AgentContext $context,
        AgentMemory $memory  // Automatically provided
    ): string {
        // Example: Storing a fact
        $memory->addFact("User prefers dark mode", 1.0);
        
        // Example: Storing a preference
        $memory->addPreference("dark", "ui_theme");
    
        return json_encode(['success' => true]);
    }
  3. Understand Vizra ADK Memory Types

    master

    Vizra ADK provides three distinct memory types to manage agent context:

    1. Session Memory: Maintains conversation history within a single session. It persists only for the lifetime of that session.
    2. User Memory: Stores information tied to a specific user. This is permanent and persists across multiple different sessions.
    3. Vector Memory: Used for semantic search and Retrieval Augmented Generation (RAG). This is permanent and allows agents to search through large datasets of unstructured information.
  4. Use lifecycle hooks to manage context flow

    master

    Implement lifecycle hooks to automatically inject context into prompts before an LLM call or to extract insights from the LLM response after it is generated.

    beforeLlmCall(array $inputMessages, AgentContext $context): array

    Use this hook to build a context summary (e.g., from current state) and inject it into the system message. This ensures the LLM is aware of the current session state before it generates a response.

    afterLlmResponse(Response|Generator $response, AgentContext $context): mixed

    Use this hook to parse the LLM's response and update the AgentContext. This is the ideal place to extract user preferences, update goals, or perform structured data extraction from the response text.

    // Example: Injecting context before LLM call
    public function beforeLlmCall(array $inputMessages, AgentContext $context): array
    {
        $cart = $context->getState('cart', []);
        $budget = $context->getState('budget');
        $preferences = $context->getState('preferences', []);
        $totalSpent = $context->getState('total_spent', 0);
    
        $contextSummary = $this->buildContextSummary($cart, $budget, $preferences, $totalSpent);
        
        // Inject into the first message (usually the system instruction)
        $inputMessages[0]['content'] = $this->instructions . "\n\n" . $contextSummary;
        
        return $inputMessages;
    }
    
    // Example: Extracting insights after LLM response
    public function afterLlmResponse(Response|Generator $response, AgentContext $context): mixed
    {
        $responseText = $response->getContent(); // Assuming response provides content
        
        $this->extractAndStorePreferences($responseText, $context);
        $this->updateShoppingGoals($responseText, $context);
        
        return $response;
    }
  5. What are Toolboxes?

    master

    Toolboxes are logical collections of related tools that allow for better organization and built-in authorization. They act as "tool bundles" that can be enabled or disabled based on user permissions, subscription tiers, or other runtime context.

    Key capabilities include:

    • Organized Tools: Grouping tools for cleaner agent definitions.
    • Built-in Authorization: Using Laravel Gates and Policies at both the toolbox and individual tool levels.
    • Dynamic Loading: Tools are loaded on-demand based on user context.
    • Runtime Flexibility: Adding or removing toolboxes at runtime based on application conditions.
  6. How SubAgents and delegation work

    master

    SubAgents allow you to build teams of specialized agents. A parent (manager) agent can delegate tasks to these specialists. When you define a $subAgents array on a BaseLlmAgent class, Vizra ADK automatically provides the DelegateToSubAgentTool, enabling the manager to route requests intelligently.

    Best Practices:

    • Provide a clear description property for each subAgent; the manager uses this description to decide which specialist is appropriate for a task.
    • Use specialized tools within subAgents to maintain separation of concerns.
    • Assign different LLM models to different agents (e.g., GPT-4 for the manager, GPT-3.5 for simple subAgents).
    class CustomerServiceManager extends BaseLlmAgent
    {
        protected string $name = 'customer_service_manager';
    
        protected string $instructions = "You are a customer service manager. Route technical questions to the technical support agent.";
    
        protected array $subAgents = [
            TechnicalSupportAgent::class,
            BillingSupportAgent::class,
        ];
    }
  7. Best Practices for Error Handling

    master

    To build resilient AI agents, follow these four best practices:

    1. Use Specific Exception Types: Avoid throwing generic \Exception. Instead, use AgentNotFoundException, AgentConfigurationException, or ToolExecutionException to provide clarity.
    2. Provide Meaningful Error Messages: Include context (e.g., which tool failed or which parameter was missing) in the exception message.
    3. Log Errors with Context: When catching exceptions, use logger()->error() and include relevant metadata like agent_name, session_id, or the exception object itself.
    4. Handle Errors at the Right Level: Let exceptions bubble up from low-level components (like Tools) to high-level components (like Controllers) where they can be converted into user-facing responses.
  8. Use LLM-as-a-Judge for quality evaluation

    master

    For complex qualitative checks, use LlmJudgeAssertion or LlmComparativeAssertion to leverage LLMs as evaluators.

    Basic Judge: Evaluates against a text-based criteria string. Detailed Rubric: Uses a multi-dimensional scoring system (e.g., Empathy, Accuracy) and a threshold to determine pass/fail. Comparative Judge: Compares the agent's response against a provided referenceResponse.

    // Basic Judge
    new LlmJudgeAssertion(
        criteria: 'The response should be helpful, accurate, and professional',
        model: 'gpt-4o'
    )
    
    // Detailed Rubric
    new LlmJudgeAssertion(
        criteria: "Evaluate on: 1. Empathy (0-3), 2. Accuracy (0-3). Total score must be > 4.",
        model: 'gpt-4o',
        threshold: 0.75
    )
    
    // Comparative Judge
    new LlmComparativeAssertion(
        referenceResponse: $idealResponse,
        criteria: 'Response should be as helpful as or better than the reference',
        model: 'gpt-4o'
    )
  9. How Sessions and Memory work together

    master

    Vizra distinguishes between short-term context and long-term knowledge:

    • Sessions act as short-term memory. They provide conversation history, preserve state across multiple interactions within a single conversation, and track messages between the agent and the user.
    • Memory acts as long-term knowledge retention. It enables agents to remember learnings, facts, and user preferences across different sessions and over time.

    Together, they allow agents to provide personalized experiences that improve as they learn from interactions.

  10. Handle Agent Completion via Events

    master

    When an agent completes its queued task, Vizra ADK emits a completion event. You can listen for these events to perform post-generation logic, such as updating a database record with the agent's result.

    // Event listener for completion
    Event::listen('agent.report_agent.completed', function ($data) {
        $sessionId = $data['session_id']; // e.g., 'report-123'
        $reportId = str_replace('report-', '', $sessionId);
    
        Report::find($reportId)->update([
            'status' => 'completed',
            'content' => $data['result'],
        ]);
    });
  11. Configure MCP server transport types

    master

    Vizra ADK supports two transport types for MCP servers:

    1. STDIO Transport (Default): Used for local MCP servers running as subprocesses. Ideal for filesystem access, local databases, and npm packages. Use the transport => 'stdio' key.
    2. HTTP Transport: Used for remote MCP servers via HTTP/SSE. Ideal for cloud services and microservices. Requires a url and optionally an api_key.
    // STDIO (Default)
    'filesystem' => [
        'transport' => 'stdio',
        'command' => 'npx',
        'args' => ['@modelcontextprotocol/server-filesystem'],
        'enabled' => true,
    ],
    
    // HTTP
    'github_remote' => [
        'transport' => 'http',
        'url' => 'https://mcp.example.com/api',
        'api_key' => env('MCP_API_KEY'),
        'enabled' => true,
    ],
  12. Authorize Toolboxes with Gates and Policies

    master

    Toolboxes support two primary authorization methods. If both are defined, the policy takes precedence.

    Toolbox-Level Gates

    Use the $gate property to specify a Laravel Gate name. If the gate fails, the entire toolbox is hidden.

    Toolbox-Level Policies

    Use the $policy property to specify a Laravel Policy class. You can also specify the $policyAbility to check (defaults to 'use').

    // Example using a Gate
    class AdminToolbox extends BaseToolbox
    {
        protected string $name = 'admin';
        protected ?string $gate = 'admin-access'; // Defined in AuthServiceProvider
        protected array $tools = [...];
    }
    
    // Example using a Policy
    class PremiumToolbox extends BaseToolbox
    {
        protected string $name = 'premium';
        protected ?string $policy = SubscriptionPolicy::class;
        protected ?string $policyAbility = 'accessPremiumFeatures';
        protected array $tools = [...];
    }