PHPackages                             llm-agents/agents - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Utility &amp; Helpers](/categories/utility)
4. /
5. llm-agents/agents

ActiveLibrary[Utility &amp; Helpers](/categories/utility)

llm-agents/agents
=================

LLM Agents PHP SDK - Autonomous Language Model Agents for PHP

1.7.0(1y ago)16715.1k—0.9%9[4 issues](https://github.com/llm-agents-php/agents/issues)[1 PRs](https://github.com/llm-agents-php/agents/pulls)9MITPHPPHP ^8.2

Since Aug 26Pushed 1y ago2 watchersCompare

[ Source](https://github.com/llm-agents-php/agents)[ Packagist](https://packagist.org/packages/llm-agents/agents)[ Docs](https://github.com/llm-agents-php)[ RSS](/packages/llm-agents-agents/feed)WikiDiscussions master Synced today

READMEChangelog (10)Dependencies (13)Versions (14)Used By (9)

 [   ![LLM Agents Logo](https://raw.githubusercontent.com/llm-agents-php/.github/master/assets/logo.png)  ](https://github.com/llm-agents-php)

LLM Agents PHP SDK
==================

[](#llm-agents-php-sdk)

LLM Agents is a PHP library for building and managing Language Model (LLM) based agents. It provides a framework for creating autonomous agents that can perform complex tasks, make decisions, and interact with various tools and APIs.

The library enables developers to integrate LLM capabilities into PHP applications efficiently, allowing for the creation of intelligent systems that can understand and respond to user inputs, process information, and carry out actions based on that processing.The library enables developers to integrate LLM capabilities into PHP applications efficiently.

> For a comprehensive explanation of LLM agents and their applications, you can read the article: A PHP dev's dream: [A PHP dev’s dream: An AI home that really gets you](https://butschster.medium.com/a-php-devs-dream-an-ai-home-that-really-gets-you-dd97ae2ca0b0)

[![PHP](https://camo.githubusercontent.com/b95d9b94a8433804e6206d971c087d3276cd1a63bbda3e266937b0199982efd6/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f7068702d762f6c6c6d2d6167656e74732f6167656e74732e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/llm-agents/agents)[![Latest Version on Packagist](https://camo.githubusercontent.com/be866891aaeb7e3bf89ca04d7f1be2f023270379cba3f7622fdd8f369dfa4251/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f6c6c6d2d6167656e74732f6167656e74732e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/llm-agents/agents)[![Total Downloads](https://camo.githubusercontent.com/ee4830952a562dfdf86beffb5633c79e34cafe10a6560fa696a2b846fcfa927e/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f64742f6c6c6d2d6167656e74732f6167656e74732e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/llm-agents/agents)

> For a complete example with sample agents and a CLI interface to interact with them, check out our sample application repository .
>
> This sample app demonstrates practical implementations and usage patterns of the LLM Agents library.

The package does not include any specific LLM implementation. Instead, it provides a framework for creating agents that can interact with any LLM service or API.

✨ Key Features
--------------

[](#-key-features)

- **🤖 Agent Creation:** Create and configure **LLM-based agents** in PHP with customizable behaviors.
- **🔧 Tool Integration:** Seamlessly integrate various tools and APIs for agent use in PHP applications.
- **🧠 Memory Management:** Support for agent memory, enabling information retention and recall across interactions.
- **💡 Prompt Management:** Efficient handling of prompts and instructions to guide agent behavior.
- **🔌 Extensible Architecture:** Easily add new agent types, tools, and capabilities to your PHP projects.
- **🤝 Multi-Agent Support:** Build systems with multiple interacting agents for complex problem-solving scenarios in PHP.

📀 Installation
--------------

[](#-installation)

You can install the LLM Agents package via Composer:

```
composer require llm-agents/agents
```

💻 Usage
-------

[](#-usage)

### → Creating an Agent

[](#-creating-an-agent)

To create an agent, you'll need to define its behavior, tools, and configuration. Here's a basic example:

```
use LLM\Agents\Agent\AgentAggregate;
use LLM\Agents\Agent\Agent;
use LLM\Agents\Solution\Model;
use LLM\Agents\Solution\ToolLink;
use LLM\Agents\Solution\MetadataType;
use LLM\Agents\Solution\SolutionMetadata;

class SiteStatusCheckerAgent extends AgentAggregate
{
    public const NAME = 'site_status_checker';

    public static function create(): self
    {
        $agent = new Agent(
            key: self::NAME,
            name: 'Site Status Checker',
            description: 'This agent checks the online status of websites.',
            instruction: 'You are a website status checking assistant. Your goal is to help users determine if a website is online. Use the provided tool to check site availability. Give clear, concise responses about a site\'s status.',
        );

        $aggregate = new self($agent);

        $aggregate->addMetadata(
            new SolutionMetadata(
                type: MetadataType::Memory,
                key: 'check_availability',
                content: 'Always check the site\'s availability using the provided tool.',
            ),
            new SolutionMetadata(
                type: MetadataType::Configuration,
                key: 'max_tokens',
                content: 500,
            )
        );

        $model = new Model(model: 'gpt-4o-mini');
        $aggregate->addAssociation($model);

        $aggregate->addAssociation(new ToolLink(name: CheckSiteAvailabilityTool::NAME));

        return $aggregate;
    }
}
```

### → Implementing a Tool

[](#-implementing-a-tool)

Now, let's implement the tool used by this agent:

```
use LLM\Agents\Tool\PhpTool;
use LLM\Agents\Tool\ToolLanguage;

class CheckSiteAvailabilityTool extends PhpTool
{
    public const NAME = 'check_site_availability';

    public function __construct()
    {
        parent::__construct(
            name: self::NAME,
            inputSchema: CheckSiteAvailabilityInput::class,
            description: 'This tool checks if a given URL is accessible and returns its HTTP status code and response time.',
        );
    }

    public function getLanguage(): ToolLanguage
    {
        return ToolLanguage::PHP;
    }

    public function execute(object $input): string
    {
        $ch = curl_init($input->url);
        curl_setopt_array($ch, [
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_HEADER => true,
            CURLOPT_NOBODY => true,
            CURLOPT_FOLLOWLOCATION => true,
            CURLOPT_MAXREDIRS => 10,
            CURLOPT_TIMEOUT => 30,
        ]);

        $startTime = microtime(true);
        $response = curl_exec($ch);
        $endTime = microtime(true);

        $statusCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
        $responseTime = round(($endTime - $startTime) * 1000, 2);

        curl_close($ch);

        $isOnline = $statusCode >= 200 && $statusCode < 400;

        return json_encode([
            'status_code' => $statusCode,
            'response_time_ms' => $responseTime,
            'is_online' => $isOnline,
        ]);
    }
}
```

And the input schema for the tool:

```
use Spiral\JsonSchemaGenerator\Attribute\Field;

class CheckSiteAvailabilityInput
{
    public function __construct(
        #[Field(title: 'URL', description: 'The full URL of the website to check')]
        public readonly string $url,
    ) {}
}
```

### → Linking Agents

[](#-linking-agents)

LLM Agents supports creating complex systems by linking multiple agents together. This allows you to build hierarchical or collaborative agent networks. Here's how you can link one agent to another:

#### Creating an Agent Link

[](#creating-an-agent-link)

To link one agent to another, you use the `AgentLink` class. Here's an example of how to modify our `SiteStatusCheckerAgent` to include a link to another agent:

```
use LLM\Agents\Solution\AgentLink;

class SiteStatusCheckerAgent extends AgentAggregate
{
    public const NAME = 'site_status_checker';

    public static function create(): self
    {
        // ... [previous agent setup code] ...

        // Link to another agent
        $aggregate->addAssociation(
            new AgentLink(
                name: 'network_diagnostics_agent',
                outputSchema: NetworkDiagnosticsOutput::class,
            ),
        );

        return $aggregate;
    }
}
```

In this example, we're linking a `network_diagnostics_agent`. The `outputSchema` parameter specifies the expected output format from the linked agent. The output schema is used to standardize the data format that should be returned by the linked agent.

#### Using a Linked Agent

[](#using-a-linked-agent)

We don't provide an implementation for the linked agent here, but you can use the linked agent in your agent's execution.

Here's an example of how you might call the linked agent:

```
use LLM\Agents\Tool\PhpTool;
use LLM\Agents\Agent\AgentExecutor;
use LLM\Agents\LLM\Prompt\Chat\ToolCallResultMessage;
use LLM\Agents\LLM\Response\ToolCalledResponse;
use LLM\Agents\Tool\ToolExecutor;
use LLM\Agents\Tool\ToolLanguage;

/**
 * @extends PhpTool
 */
final class AskAgentTool extends PhpTool
{
    public const NAME = 'ask_agent';

    public function __construct(
        private readonly AgentExecutor $executor,
        private readonly ToolExecutor $toolExecutor,
    ) {
        parent::__construct(
            name: self::NAME,
            inputSchema: AskAgentInput::class,
            description: 'Ask an agent with given name to execute a task.',
        );
    }

    public function getLanguage(): ToolLanguage
    {
        return ToolLanguage::PHP;
    }

    public function execute(object $input): string|\Stringable
    {
        $prompt = \sprintf(
            executor->execute(
            agent: MyAgent::NAME,
            prompt: $prompt,
        );

        return (string)$execution->result->content;
    }
}

// Usage
$agentRunner = new AgentRunner($executor);
$result = $agentRunner->run("Do something cool!");
echo $result;
```

This example demonstrates how to create a simple agent that can perform a specific task using a custom tool.

### → Agent Memory and Prompts

[](#-agent-memory-and-prompts)

Agents can use memory and predefined prompts to guide their behavior:

```
use LLM\Agents\Solution\SolutionMetadata;
use LLM\Agents\Solution\MetadataType;

// In your agent creation method:
$aggregate->addMetadata(
    new SolutionMetadata(
        type: MetadataType::Memory,
        key: 'user_preference',
        content: 'The user prefers concise answers.',
    ),

    new SolutionMetadata(
        type: MetadataType::Prompt,
        key: 'check_google',
        content: 'Check the status of google.com.',
    ),

    new SolutionMetadata(
        type: MetadataType::Prompt,
        key: 'check_yahoo',
        content: 'Check the status of yahoo.com.',
    ),

    //...
);
```

Executor Interceptors
---------------------

[](#executor-interceptors)

The package includes a powerful interceptor system for the executor. This allows developers to inject data into prompts, modify execution options, and handle LLM responses at various stages of the execution process. Here's a detailed look at each available interceptor:

```
use LLM\Agents\AgentExecutor\ExecutorInterface;
use LLM\Agents\AgentExecutor\ExecutorPipeline;
use LLM\Agents\AgentExecutor\Interceptor\GeneratePromptInterceptor;
use LLM\Agents\AgentExecutor\Interceptor\InjectModelInterceptor;
use LLM\Agents\AgentExecutor\Interceptor\InjectOptionsInterceptor;
use LLM\Agents\AgentExecutor\Interceptor\InjectResponseIntoPromptInterceptor;
use LLM\Agents\AgentExecutor\Interceptor\InjectToolsInterceptor;

$executor = new ExecutorPipeline(...);

$executor = $executor->withInterceptor(
    new GeneratePromptInterceptor(...),
    new InjectModelInterceptor(...),
    new InjectToolsInterceptor(...),
    new InjectOptionsInterceptor(...),
    new InjectResponseIntoPromptInterceptor(...),
);

$executor->execute(...);
```

### Available Interceptors

[](#available-interceptors)

1. **GeneratePromptInterceptor**

    - **Purpose**: Generates the initial prompt for the agent.
    - **Functionality**:
        - Uses the `AgentPromptGeneratorInterface` to create a comprehensive prompt.
        - Incorporates agent instructions, memory, and user input into the prompt.
    - **When to use**: Always include this interceptor to ensure proper prompt generation.
2. **InjectModelInterceptor**

    - **Purpose**: Injects the appropriate language model for the agent.
    - **Functionality**:
        - Retrieves the model associated with the agent.
        - Adds the model information to the execution options.
    - **When to use**: Include this interceptor when you want to ensure the correct model is used for each agent, especially in multi-agent systems.
3. **InjectToolsInterceptor**

    - **Purpose**: Adds the agent's tools to the execution options.
    - **Functionality**:
        - Retrieves all tools associated with the agent.
        - Converts tool schemas into a format understood by the LLM.
        - Adds tool information to the execution options.
    - **When to use**: Include this interceptor when your agent uses tools and you want them available during execution.
4. **InjectOptionsInterceptor**

    - **Purpose**: Incorporates additional configuration options for the agent.
    - **Functionality**:
        - Retrieves any custom configuration options defined for the agent.
        - Adds these options to the execution options.
    - **When to use**: Include this interceptor when you have agent-specific configuration that should be applied during execution.
5. **InjectResponseIntoPromptInterceptor**

    - **Purpose**: Adds the LLM's response back into the prompt for continuous conversation.
    - **Functionality**:
        - Takes the LLM's response from the previous execution.
        - Appends this response to the existing prompt.
    - **When to use**: Include this interceptor in conversational agents or when context from previous interactions is important.

### Creating Custom Interceptors

[](#creating-custom-interceptors)

You can create custom interceptors to add specialized behavior to your agent execution pipeline.

Here's an example of a custom interceptor that adds time-aware and user-specific context to the prompt:

```
use LLM\Agents\AgentExecutor\ExecutorInterceptorInterface;
use LLM\Agents\AgentExecutor\ExecutionInput;
use LLM\Agents\AgentExecutor\InterceptorHandler;
use LLM\Agents\Agent\Execution;
use LLM\Agents\LLM\Prompt\Chat\Prompt;
use LLM\Agents\LLM\Response\ChatResponse;
use Psr\Log\LoggerInterface;

class TokenCounterInterceptor implements ExecutorInterceptorInterface
{
    public function __construct(
        private TokenCounterInterface $tokenCounter,
        private LoggerInterface $logger,
    ) {}

    public function execute(ExecutionInput $input, InterceptorHandler $next): Execution
    {
        // Count tokens in the input prompt
        $promptTokens = $this->tokenCounter->count((string) $input->prompt);

        // Execute the next interceptor in the chain
        $execution = $next($input);

        // Count tokens in the response
        $responseTokens = 0;
        if ($execution->result instanceof ChatResponse) {
            $responseTokens = $this->tokenCounter->count((string) $execution->result->content);
        }

        // Log the token counts
        $this->logger->info('Token usage', [
            'prompt_tokens' => $promptTokens,
            'response_tokens' => $responseTokens,
            'total_tokens' => $promptTokens + $responseTokens,
        ]);

        return $execution;
    }
}
```

Then, you can add your custom interceptor to the executor:

```
use Psr\Log\LoggerInterface;

// Assume you have implementations of TokenCounterInterface and LoggerInterface
$tokenCounter = new MyTokenCounter();
$logger = new MyLogger();

$executor = $executor->withInterceptor(
    new TokenCounterInterceptor($tokenCounter, $logger),
);
```

This example demonstrates how to create a more complex and useful interceptor. The token counting interceptor can be valuable for monitoring API usage, optimizing prompt length, or ensuring you stay within token limits of your LLM provider.

**You can create various other types of interceptors to suit your specific needs, such as:**

- Caching interceptors to store and retrieve responses for identical prompts
- Rate limiting interceptors to control the frequency of API calls
- Error handling interceptors to gracefully manage and log exceptions
- Analytics interceptors to gather data on agent performance and usage patterns

Implementing Required Interfaces
--------------------------------

[](#implementing-required-interfaces)

To use the LLM Agents package, you'll need to implement the required interfaces in your project.

### → LLMInterface

[](#-llminterface)

It serves as a bridge between your application and LLM you're using, such as OpenAI, Claude, etc.

```
use LLM\Agents\LLM\ContextInterface;
use LLM\Agents\LLM\LLMInterface;
use LLM\Agents\LLM\OptionsInterface;
use LLM\Agents\LLM\Prompt\Chat\MessagePrompt;
use LLM\Agents\LLM\Prompt\Chat\PromptInterface as ChatPromptInterface;
use LLM\Agents\LLM\Prompt\PromptInterface;
use LLM\Agents\LLM\Prompt\Tool;
use LLM\Agents\LLM\Response\Response;
use OpenAI\Client;

final readonly class OpenAILLM implements LLMInterface
{
    public function __construct(
        private Client $client,
        private MessageMapper $messageMapper,
        private StreamResponseParser $streamParser,
    ) {}

    public function generate(
        ContextInterface $context,
        PromptInterface $prompt,
        OptionsInterface $options,
    ): Response {
        $request = $this->buildOptions($options);

        $messages = $prompt instanceof ChatPromptInterface
            ? $prompt->format()
            : [MessagePrompt::user($prompt)->toChatMessage()];

        $request['messages'] = array_map(
            fn($message) => $this->messageMapper->map($message),
            $messages
        );

        if ($options->has('tools')) {
            $request['tools'] = array_values(array_map(
                fn(Tool $tool): array => $this->messageMapper->map($tool),
                $options->get('tools')
            ));
        }

        $stream = $this->client->chat()->createStreamed($request);

        return $this->streamParser->parse($stream);
    }

    private function buildOptions(OptionsInterface $options): array
    {
        $defaultOptions = [
            'temperature' => 0.8,
            'max_tokens' => 120,
            'model' => null,
            // Add other default options as needed
        ];

        $result = array_intersect_key($options->getIterator()->getArrayCopy(), $defaultOptions);
        $result += array_diff_key($defaultOptions, $result);

        if (!isset($result['model'])) {
            throw new \InvalidArgumentException('Model is required');
        }

        return array_filter($result, fn($value) => $value !== null);
    }
}
```

Here is an example of `MessageMapper` that converts messages to the format required by the LLM API:

```
use LLM\Agents\LLM\Prompt\Chat\ChatMessage;
use LLM\Agents\LLM\Prompt\Chat\Role;
use LLM\Agents\LLM\Prompt\Chat\ToolCalledPrompt;
use LLM\Agents\LLM\Prompt\Chat\ToolCallResultMessage;
use LLM\Agents\LLM\Prompt\Tool;
use LLM\Agents\LLM\Response\ToolCall;

final readonly class MessageMapper
{
    public function map(object $message): array
    {
        if ($message instanceof ChatMessage) {
            return [
                'content' => $message->content,
                'role' => $message->role->value,
            ];
        }

        if ($message instanceof ToolCallResultMessage) {
            return [
                'content' => \is_array($message->content) ? \json_encode($message->content) : $message->content,
                'tool_call_id' => $message->id,
                'role' => $message->role->value,
            ];
        }

        if ($message instanceof ToolCalledPrompt) {
            return [
                'content' => null,
                'role' => Role::Assistant->value,
                'tool_calls' => \array_map(
                    static fn(ToolCall $tool): array => [
                        'id' => $tool->id,
                        'type' => 'function',
                        'function' => [
                            'name' => $tool->name,
                            'arguments' => $tool->arguments,
                        ],
                    ],
                    $message->tools,
                ),
            ];
        }

        if ($message instanceof Tool) {
            return [
                'type' => 'function',
                'function' => [
                    'name' => $message->name,
                    'description' => $message->description,
                    'parameters' => [
                            'type' => 'object',
                            'additionalProperties' => $message->additionalProperties,
                        ] + $message->parameters,
                    'strict' => $message->strict,
                ],
            ];
        }

        if ($message instanceof \JsonSerializable) {
            return $message->jsonSerialize();
        }

        throw new \InvalidArgumentException('Invalid message type');
    }
}
```

Prompt Generation
-----------------

[](#prompt-generation)

It plays a vital role in preparing the context and instructions for an agent before it processes a user's request. It ensures that the agent has all necessary information, including its own instructions, memory, associated agents, and any relevant session context.

- System message with the agent's instruction and important rules.
- System message with the agent's memory (experiences).
- System message about associated agents (if any).
- System message with session context (if provided).
- User message with the actual prompt.

You can customize the prompt generation logic to suit your specific requirements.

Instead of implementing the `AgentPromptGeneratorInterface` yourself, you can use the `llm-agents/prompt-generator`package as an implementation. This package provides a flexible and extensible system for generating chat prompts with all required system and user messages for LLM agents.

> **Note:** Read full documentation of the `llm-agents/prompt-generator`package [here](https://github.com/llm-agents-php/prompt-generator)

To use it, first install the package:

```
composer require llm-agents/prompt-generator
```

Then, set it up in your project. Here's an example using Spiral Framework:

```
use LLM\Agents\PromptGenerator\Interceptors\AgentMemoryInjector;
use LLM\Agents\PromptGenerator\Interceptors\InstructionGenerator;
use LLM\Agents\PromptGenerator\Interceptors\LinkedAgentsInjector;
use LLM\Agents\PromptGenerator\Interceptors\UserPromptInjector;
use LLM\Agents\PromptGenerator\PromptGeneratorPipeline;

class PromptGeneratorBootloader extends Bootloader
{
    public function defineSingletons(): array
    {
        return [
            PromptGeneratorPipeline::class => static function (
                LinkedAgentsInjector $linkedAgentsInjector,
            ): PromptGeneratorPipeline {
                $pipeline = new PromptGeneratorPipeline();

                return $pipeline->withInterceptor(
                    new InstructionGenerator(),
                    new AgentMemoryInjector(),
                    $linkedAgentsInjector,
                    new UserPromptInjector(),
                    // Add more interceptors as needed
                );
            },
        ];
    }
}
```

### → SchemaMapperInterface

[](#-schemamapperinterface)

This class is responsible for handling conversions between JSON schemas and PHP objects.

We provide a schema mapper package that you can use to implement the `SchemaMapperInterface` in your project. This package is a super handy JSON Schema Mapper for the LLM Agents project.

**To install the package:**

```
composer require llm-agents/json-schema-mapper
```

> **Note:** Read full documentation of the `llm-agents/json-schema-mapper`package [here](https://github.com/llm-agents-php/schema-mapper)

### → ContextFactoryInterface

[](#-contextfactoryinterface)

It provides a clean way to pass execution-specific data through the system without tightly coupling components or overly complicating method signatures.

```
use LLM\Agents\LLM\ContextFactoryInterface;
use LLM\Agents\LLM\ContextInterface;

final class ContextFactory implements ContextFactoryInterface
{
    public function create(): ContextInterface
    {
        return new class implements ContextInterface {
            // Implement any necessary methods or properties for your context
        };
    }
}
```

### → OptionsFactoryInterface

[](#-optionsfactoryinterface)

The options is a simple key-value store that allows you to store and retrieve configuration options that can be passed to LLM clients and other components. For example, you can pass a model name, max tokens, and other configuration options to an LLM client.

```
use LLM\Agents\LLM\OptionsFactoryInterface;
use LLM\Agents\LLM\OptionsInterface;

final class OptionsFactory implements OptionsFactoryInterface
{
    public function create(): OptionsInterface
    {
        return new class implements OptionsInterface {
            private array $options = [];

            public function has(string $option): bool
            {
                return isset($this->options[$option]);
            }

            public function get(string $option, mixed $default = null): mixed
            {
                return $this->options[$option] ?? $default;
            }

            public function with(string $option, mixed $value): static
            {
                $clone = clone $this;
                $clone->options[$option] = $value;
                return $clone;
            }

            public function getIterator(): \Traversable
            {
                return new \ArrayIterator($this->options);
            }
        };
    }
}
```

🏗️ Architecture
---------------

[](#️-architecture)

The LLM Agents package is built around several key components:

- **AgentInterface**: Defines the contract for all agents.
- **AgentAggregate**: Implements AgentInterface and aggregates an Agent instance with other Solution objects.
- **Agent**: Represents a single agent with its key, name, description, and instruction.
- **Solution**: Abstract base class for various components like Model and ToolLink.
- **AgentExecutor**: Responsible for executing agents and managing their interactions.
- **Tool**: Represents a capability that an agent can use to perform tasks.

For a visual representation of the architecture, refer to the class diagram in the documentation.

🎨 Class Diagram
---------------

[](#-class-diagram)

Here's a class diagram illustrating the key components of the LLM Agents PHP SDK:

 ```
classDiagram
    class AgentInterface {

        +getKey() string
        +getName() string
        +getDescription() string
        +getInstruction() string
        +getTools() array
        +getAgents() array
        +getModel() Model
        +getMemory() array
        +getPrompts() array
        +getConfiguration() array
    }

    class AgentAggregate {
        -agent: Agent
        -associations: array
        +addAssociation(Solution)
        +addMetadata(SolutionMetadata)
    }

    class Agent {
        +key: string
        +name: string
        +description: string
        +instruction: string
        +isActive: bool
    }

    class Solution {

        +name: string
        +type: SolutionType
        +description: string
        -metadata: array
        +addMetadata(SolutionMetadata)
        +getMetadata() array
    }

    class SolutionMetadata {
        +type: MetadataType
        +key: string
        +content: string|Stringable|int
    }

    class Model {
        +model: string
    }

    class ToolLink {
        +getName() string
    }

    class AgentLink {
        +getName() string
        +outputSchema: string
    }

    class ExecutorInterface {

        +execute(string, string|Stringable|Prompt, ContextInterface, OptionsInterface, PromptContextInterface) Execution
        +withInterceptor(ExecutorInterceptorInterface) self
    }

    class ToolInterface {

        +getName() string
        +getDescription() string
        +getInputSchema() string
        +getLanguage() ToolLanguage
        +execute(object) string|Stringable
    }

    AgentAggregate ..|> AgentInterface
    AgentAggregate o-- Agent
    AgentAggregate o-- Solution
    Agent --|> Solution
    Model --|> Solution
    ToolLink --|> Solution
    AgentLink --|> Solution
    ExecutorInterface --> AgentInterface
    ExecutorInterface --> ToolInterface
    Solution o-- SolutionMetadata
```

      Loading 🙌 Want to Contribute?
---------------------

[](#-want-to-contribute)

Thank you for considering contributing to the llm-agents-php community! We are open to all kinds of contributions. If you want to:

- 🤔 [Suggest a feature](https://github.com/llm-agents-php/agents/issues/new?assignees=&labels=type%3A+enhancement&projects=&template=2-feature-request.yml&title=%5BFeature%5D%3A+)
- 🐛 [Report an issue](https://github.com/llm-agents-php/agents/issues/new?assignees=&labels=type%3A+documentation%2Ctype%3A+maintenance&projects=&template=1-bug-report.yml&title=%5BBug%5D%3A+)
- 📖 [Improve documentation](https://github.com/llm-agents-php/agents/issues/new?assignees=&labels=type%3A+documentation%2Ctype%3A+maintenance&projects=&template=4-docs-bug-report.yml&title=%5BDocs%5D%3A+)
- 👨‍💻 Contribute to the code

You are more than welcome. Before contributing, kindly check our [contribution guidelines](.github/CONTRIBUTING.md).

[![Conventional Commits](https://camo.githubusercontent.com/1e023e4ca15719f3a1397c355e66638a51acf4e0a9118045265b03997dc416d0/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f436f6e76656e74696f6e616c253230436f6d6d6974732d312e302e302d79656c6c6f772e7376673f7374796c653d666f722d7468652d6261646765)](https://conventionalcommits.org)

⚖️ License
----------

[](#️-license)

LLM Agents is open-source software licensed under the [MIT license](https://opensource.org/licenses/MIT).

[![Licence](https://camo.githubusercontent.com/94400bb3f1a51ae26a99f2dd626719719f89dc37cbc7f9be8fe00a035b6fa673/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f6c6963656e73652f6c6c6d2d6167656e74732d7068702f6167656e74733f7374796c653d666f722d7468652d626164676526636f6c6f723d626c7565)](./LICENSE.md)

###  Health Score

44

—

FairBetter than 90% of packages

Maintenance40

Moderate activity, may be stable

Popularity43

Moderate usage in the ecosystem

Community23

Small or concentrated contributor base

Maturity60

Established project with proven stability

 Bus Factor1

Top contributor holds 68.8% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~2 days

Total

10

Last Release

655d ago

PHP version history (2 changes)1.0.0PHP ^8.3

1.2.0PHP ^8.2

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/773481?v=4)[Pavel Buchnev](/maintainers/butschster)[@butschster](https://github.com/butschster)

---

Top Contributors

[![butschster](https://avatars.githubusercontent.com/u/773481?v=4)](https://github.com/butschster "butschster (64 commits)")[![lotyp](https://avatars.githubusercontent.com/u/94047334?v=4)](https://github.com/lotyp "lotyp (28 commits)")[![ilyachase](https://avatars.githubusercontent.com/u/1961077?v=4)](https://github.com/ilyachase "ilyachase (1 commits)")

---

Tags

llmllm-agentsllm-tool-callphpphp8php83phpsymfonylaravelopenaiAgentclaudellmanthropicgenerative-aigenaigpt4langchainautophpclaude-ai

###  Code Quality

TestsPHPUnit

Static AnalysisPHPStan, Psalm, Rector

Type Coverage Yes

### Embed Badge

![Health badge](/badges/llm-agents-agents/health.svg)

```
[![Health](https://phpackages.com/badges/llm-agents-agents/health.svg)](https://phpackages.com/packages/llm-agents-agents)
```

###  Alternatives

[cognesy/instructor-php

The complete AI toolkit for PHP: unified LLM API, structured outputs, agents, and coding agent control

318123.0k1](/packages/cognesy-instructor-php)[mozex/anthropic-laravel

Laravel integration for the Anthropic API: facade, config publishing, install command, testing fakes, messages, streaming, tool use, thinking, and batches.

74331.3k1](/packages/mozex-anthropic-laravel)[rumenx/php-seo

AI-powered, framework-agnostic PHP package for automated SEO optimization. Intelligently generates meta tags, titles, descriptions, and alt texts using configurable AI providers or manual patterns.

124.5k](/packages/rumenx-php-seo)[mohamed-ashraf-elsaed/claude-agent-sdk-laravel

Anthropic Claude Agent SDK for PHP &amp; Laravel — build AI agents with tool use, sandboxing, MCP servers, subagents, hooks, and structured output via the Claude Code CLI

171.1k](/packages/mohamed-ashraf-elsaed-claude-agent-sdk-laravel)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
