๐Ÿš€ ุงู„ุชูˆุณุน ุงู„ูƒุงู…ู„: ู…ู† ุงู„ููƒุฑุฉ ุฅู„ู‰ ู†ุธุงู… Agent Production-Ready

๐Ÿ“Š 2 ู…ุดุงู‡ุฏุฉ

Agent Production-Ready

ุณุฃุนุทูŠูƒ ุงู„ุขู† ุงู„ุตูˆุฑุฉ ุงู„ูƒุงู…ู„ุฉ ุจูƒู„ ุงู„ุชูุงุตูŠู„ ุงู„ู…ุนู…ุงุฑูŠุฉุŒ ู…ุน ุงู„ูƒูˆุฏ ุงู„ุฃุณุงุณูŠ ู„ูƒู„ ู…ูƒูˆู‘ู†ุŒ ุญุชู‰ ุชูƒูˆู† ุฌุงู‡ุฒู‹ุง ู„ุจู†ุงุก ุงู„ู†ุธุงู… ูƒุงู…ู„ู‹ุง.


๐Ÿ—๏ธ ุงู„ู…ุนู…ุงุฑูŠุฉ ุงู„ุนุงู…ุฉ ู„ู„ู†ุธุงู…

text

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚                    WordPress Admin UI                        โ”‚
โ”‚         (React Dashboard + REST API + WebSocket)             โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
                       โ”‚
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ–ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚                   Agent Orchestrator                         โ”‚
โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”    โ”‚
โ”‚  โ”‚ Planner  โ”‚โ†’ โ”‚Research  โ”‚โ†’ โ”‚ Writer   โ”‚โ†’ โ”‚ Critic   โ”‚    โ”‚
โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜    โ”‚
โ”‚         โ†“            โ†“             โ†“             โ†“          โ”‚
โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”        โ”‚
โ”‚  โ”‚           Message Bus (MySQL/Redis)             โ”‚        โ”‚
โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜        โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
                       โ”‚
     โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
     โ–ผ                 โ–ผ                 โ–ผ
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”      โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”      โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚ Memory  โ”‚      โ”‚Knowledge โ”‚      โ”‚  Tools    โ”‚
โ”‚ Qdrant  โ”‚      โ”‚  Graph   โ”‚      โ”‚  Registry โ”‚
โ”‚+MySQL   โ”‚      โ”‚  MySQL   โ”‚      โ”‚           โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜      โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜      โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
                       โ”‚
                       โ–ผ
              โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
              โ”‚ Verification    โ”‚
              โ”‚     Loop        โ”‚
              โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
                       โ”‚
                       โ–ผ
              โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
              โ”‚  LLM Providers  โ”‚
              โ”‚ OpenAI / Claude โ”‚
              โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

๐Ÿ”ง ุงู„ู…ูƒูˆู‘ู† 1: Core Agent + LLM Client (ุงู„ุฃุณุงุณ)

ู‡ูŠูƒู„ ุงู„ู…ุฌู„ุฏุงุช

text

wp-content/plugins/zezo-ai-agents/
โ”œโ”€โ”€ zezo-ai-agents.php
โ”œโ”€โ”€ composer.json
โ”œโ”€โ”€ src/
โ”‚   โ”œโ”€โ”€ Core/
โ”‚   โ”‚   โ”œโ”€โ”€ Agent.php
โ”‚   โ”‚   โ”œโ”€โ”€ AgentRegistry.php
โ”‚   โ”‚   โ”œโ”€โ”€ Orchestrator.php
โ”‚   โ”‚   โ””โ”€โ”€ MessageBus.php
โ”‚   โ”œโ”€โ”€ LLM/
โ”‚   โ”‚   โ”œโ”€โ”€ LLMClient.php
โ”‚   โ”‚   โ”œโ”€โ”€ OpenAIProvider.php
โ”‚   โ”‚   โ”œโ”€โ”€ ClaudeProvider.php
โ”‚   โ”‚   โ””โ”€โ”€ EmbeddingClient.php
โ”‚   โ”œโ”€โ”€ Tools/
โ”‚   โ”‚   โ”œโ”€โ”€ ToolInterface.php
โ”‚   โ”‚   โ”œโ”€โ”€ ToolRegistry.php
โ”‚   โ”‚   โ””โ”€โ”€ Tools/
โ”‚   โ”‚       โ”œโ”€โ”€ WpQueryTool.php
โ”‚   โ”‚       โ”œโ”€โ”€ SqlQueryTool.php
โ”‚   โ”‚       โ””โ”€โ”€ HttpTool.php
โ”‚   โ”œโ”€โ”€ Verification/
โ”‚   โ”‚   โ””โ”€โ”€ VerificationLoop.php
โ”‚   โ”œโ”€โ”€ Memory/
โ”‚   โ”‚   โ”œโ”€โ”€ MemoryStore.php
โ”‚   โ”‚   โ””โ”€โ”€ VectorClient.php
โ”‚   โ”œโ”€โ”€ Graph/
โ”‚   โ”‚   โ””โ”€โ”€ KnowledgeGraph.php
โ”‚   โ””โ”€โ”€ Admin/
โ”‚       โ”œโ”€โ”€ Dashboard.php
โ”‚       โ””โ”€โ”€ RestApi.php

composer.json

json

{
  "name": "zezo/ai-agents",
  "require": {
    "php": ">=8.1",
    "guzzlehttp/guzzle": "^7.8",
    "openai-php/client": "^0.8",
    "anthropic-ai/sdk": "^0.2"
  },
  "autoload": {
    "psr-4": { "Zezo\\AI\\": "src/" }
  }
}

src/LLM/LLMClient.php

php

<?php
namespace Zezo\AI\LLM;

interface LLMClient {
    public function chat(array $messages, array $options = []): array;
    public function embed(string $text): array;
    public function name(): string;
}

src/LLM/OpenAIProvider.php

php

<?php
namespace Zezo\AI\LLM;

use GuzzleHttp\Client;

class OpenAIProvider implements LLMClient {
    private Client $http;
    private string $apiKey;
    private string $model;
    private string $embedModel;

    public function __construct(string $apiKey, string $model = 'gpt-4o', string $embedModel = 'text-embedding-3-large') {
        $this->apiKey = $apiKey;
        $this->model = $model;
        $this->embedModel = $embedModel;
        $this->http = new Client(['base_uri' => 'https://api.openai.com/v1/', 'timeout' => 120]);
    }

    public function chat(array $messages, array $options = []): array {
        $payload = [
            'model' => $this->model,
            'messages' => $messages,
            'temperature' => $options['temperature'] ?? 0.3,
        ];
        if (!empty($options['tools'])) {
            $payload['tools'] = $options['tools'];
            $payload['tool_choice'] = $options['tool_choice'] ?? 'auto';
        }
        if (!empty($options['response_format'])) {
            $payload['response_format'] = $options['response_format'];
        }

        $res = $this->http->post('chat/completions', [
            'headers' => [
                'Authorization' => "Bearer {$this->apiKey}",
                'Content-Type' => 'application/json',
            ],
            'json' => $payload,
        ]);

        $body = json_decode($res->getBody()->getContents(), true);
        return [
            'content' => $body['choices'][0]['message']['content'] ?? '',
            'tool_calls' => $body['choices'][0]['message']['tool_calls'] ?? [],
            'usage' => $body['usage'] ?? [],
            'raw' => $body,
        ];
    }

    public function embed(string $text): array {
        $res = $this->http->post('embeddings', [
            'headers' => ['Authorization' => "Bearer {$this->apiKey}"],
            'json' => ['model' => $this->embedModel, 'input' => $text],
        ]);
        $body = json_decode($res->getBody()->getContents(), true);
        return $body['data'][0]['embedding'] ?? [];
    }

    public function name(): string { return 'openai:' . $this->model; }
}

src/LLM/ClaudeProvider.php

php

<?php
namespace Zezo\AI\LLM;

use GuzzleHttp\Client;

class ClaudeProvider implements LLMClient {
    private Client $http;
    private string $apiKey;
    private string $model;

    public function __construct(string $apiKey, string $model = 'claude-sonnet-4-5') {
        $this->apiKey = $apiKey;
        $this->model = $model;
        $this->http = new Client(['base_uri' => 'https://api.anthropic.com/v1/', 'timeout' => 120]);
    }

    public function chat(array $messages, array $options = []): array {
        // ุงูุตู„ system ุนู† ุจุงู‚ูŠ ุงู„ุฑุณุงุฆู„
        $system = '';
        $filtered = [];
        foreach ($messages as $m) {
            if ($m['role'] === 'system') $system .= $m['content'] . "\n";
            else $filtered[] = $m;
        }

        $payload = [
            'model' => $this->model,
            'max_tokens' => $options['max_tokens'] ?? 4096,
            'system' => trim($system),
            'messages' => $filtered,
        ];
        if (!empty($options['tools'])) {
            $payload['tools'] = $this->convertTools($options['tools']);
        }

        $res = $this->http->post('messages', [
            'headers' => [
                'x-api-key' => $this->apiKey,
                'anthropic-version' => '2023-06-01',
                'Content-Type' => 'application/json',
            ],
            'json' => $payload,
        ]);

        $body = json_decode($res->getBody()->getContents(), true);
        $content = '';
        $toolCalls = [];
        foreach ($body['content'] ?? [] as $block) {
            if ($block['type'] === 'text') $content .= $block['text'];
            if ($block['type'] === 'tool_use') $toolCalls[] = $block;
        }
        return [
            'content' => $content,
            'tool_calls' => $toolCalls,
            'usage' => $body['usage'] ?? [],
            'raw' => $body,
        ];
    }

    public function embed(string $text): array {
        // Claude ู„ุง ูŠูˆูุฑ embeddings โ†’ ุงุณุชุฎุฏู… Voyage AI ุฃูˆ OpenAI
        return (new OpenAIProvider(get_option('zezo_openai_key')))->embed($text);
    }

    private function convertTools(array $tools): array {
        return array_map(fn($t) => [
            'name' => $t['function']['name'],
            'description' => $t['function']['description'],
            'input_schema' => $t['function']['parameters'],
        ], $tools);
    }

    public function name(): string { return 'claude:' . $this->model; }
}

src/Core/Agent.php โ€” ู‚ู„ุจ ุงู„ู†ุธุงู…

php

<?php
namespace Zezo\AI\Core;

use Zezo\AI\LLM\LLMClient;
use Zezo\AI\Tools\ToolRegistry;
use Zezo\AI\Memory\MemoryStore;
use Zezo\AI\Verification\VerificationLoop;

class Agent {
    private string $id;
    private string $role;
    private string $systemPrompt;
    private LLMClient $llm;
    private ToolRegistry $tools;
    private MemoryStore $memory;
    private VerificationLoop $verifier;
    private int $maxIterations = 8;

    public function __construct(
        string $id,
        string $role,
        string $systemPrompt,
        LLMClient $llm,
        ToolRegistry $tools,
        MemoryStore $memory,
        VerificationLoop $verifier
    ) {
        $this->id = $id;
        $this->role = $role;
        $this->systemPrompt = $systemPrompt;
        $this->llm = $llm;
        $this->tools = $tools;
        $this->memory = $memory;
        $this->verifier = $verifier;
    }

    /**
     * ุชุดุบูŠู„ ุงู„ูˆูƒูŠู„ ุนู„ู‰ ู‡ุฏู ู…ุนูŠู† ู…ุน ุญู„ู‚ุฉ Tool-Calling
     */
    public function run(string $goal, array $context = []): array {
        $messages = [
            ['role' => 'system', 'content' => $this->systemPrompt],
        ];

        // ุงุณุชุฑุฌุงุน ุฐุงูƒุฑุฉ ุฐุงุช ุตู„ุฉ
        $memories = $this->memory->search($goal, 5);
        if ($memories) {
            $messages[] = ['role' => 'system', 'content' => "Relevant memories:\n" . implode("\n", $memories)];
        }
        if ($context) {
            $messages[] = ['role' => 'system', 'content' => "Context:\n" . json_encode($context, JSON_UNESCAPED_UNICODE)];
        }
        $messages[] = ['role' => 'user', 'content' => $goal];

        $trace = [];
        for ($i = 0; $i < $this->maxIterations; $i++) {
            $response = $this->llm->chat($messages, [
                'tools' => $this->tools->asOpenAISchema(),
                'temperature' => 0.2,
            ]);

            $trace[] = ['step' => $i, 'type' => 'llm_response', 'content' => $response['content']];

            // ู„ุง ูŠูˆุฌุฏ tool calls โ†’ ุฅุฌุงุจุฉ ู†ู‡ุงุฆูŠุฉ
            if (empty($response['tool_calls'])) {
                $final = $response['content'];

                // ุชุญู‚ู‚
                $verification = $this->verifier->verify($final, $goal, $context);
                if (!$verification['passed']) {
                    $messages[] = ['role' => 'assistant', 'content' => $final];
                    $messages[] = ['role' => 'user', 'content' =>
                        "ุงู„ุชุญู‚ู‚ ูุดู„: {$verification['reason']}\nุฃุนุฏ ุงู„ู…ุญุงูˆู„ุฉ ู…ุน ุชุตุญูŠุญ ุงู„ู…ุดูƒู„ุฉ."];
                    continue;
                }

                // ุญูุธ ููŠ ุงู„ุฐุงูƒุฑุฉ
                $this->memory->store([
                    'agent' => $this->id,
                    'goal' => $goal,
                    'result' => $final,
                ]);

                return ['success' => true, 'output' => $final, 'trace' => $trace];
            }

            // ู†ูู‘ุฐ ุงู„ุฃุฏูˆุงุช
            $messages[] = ['role' => 'assistant', 'content' => $response['content'] ?? null, 'tool_calls' => $response['tool_calls']];

            foreach ($response['tool_calls'] as $call) {
                $name = $call['function']['name'] ?? $call['name'];
                $args = json_decode($call['function']['arguments'] ?? json_encode($call['input'] ?? []), true);
                $result = $this->tools->execute($name, $args);
                $trace[] = ['step' => $i, 'type' => 'tool_call', 'tool' => $name, 'args' => $args, 'result' => $result];

                $messages[] = [
                    'role' => 'tool',
                    'tool_call_id' => $call['id'] ?? null,
                    'content' => is_string($result) ? $result : json_encode($result, JSON_UNESCAPED_UNICODE),
                ];
            }
        }

        return ['success' => false, 'output' => null, 'reason' => 'max_iterations', 'trace' => $trace];
    }
}

๐Ÿ”ง ุงู„ู…ูƒูˆู‘ู† 2: Verification Loop ุงู„ูƒุงู…ู„

php

<?php
namespace Zezo\AI\Verification;

class VerificationLoop {
    private array $rules = [];

    public function addRule(callable $rule, string $name): self {
        $this->rules[$name] = $rule;
        return $this;
    }

    public function verify(string $output, string $goal, array $context = []): array {
        foreach ($this->rules as $name => $rule) {
            try {
                $result = $rule($output, $goal, $context);
                if ($result !== true) {
                    return ['passed' => false, 'reason' => "[$name] " . (is_string($result) ? $result : 'failed')];
                }
            } catch (\Throwable $e) {
                return ['passed' => false, 'reason' => "[$name] exception: " . $e->getMessage()];
            }
        }
        return ['passed' => true, 'reason' => 'ok'];
    }

    // ---- Rules ุฌุงู‡ุฒุฉ ----

    public static function schemaRule(array $schema): callable {
        return function ($output) use ($schema) {
            $data = json_decode($output, true);
            if (json_last_error() !== JSON_ERROR_NONE) return 'ู„ูŠุณ JSON ุตุงู„ุญู‹ุง';
            foreach ($schema['required'] ?? [] as $key) {
                if (!array_key_exists($key, $data)) return "ุงู„ุญู‚ู„ ุงู„ู…ุทู„ูˆุจ ู…ูู‚ูˆุฏ: $key";
            }
            return true;
        };
    }

    public static function lengthRule(int $min, int $max): callable {
        return fn($output) => (mb_strlen($output) >= $min && mb_strlen($output) <= $max)
            ? true : "ุงู„ุทูˆู„ ูŠุฌุจ ุฃู† ูŠูƒูˆู† ุจูŠู† $min ูˆ $max";
    }

    public static function dbFactRule(callable $lookup): callable {
        return function ($output) use ($lookup) {
            $facts = $lookup(); // ู…ุตููˆูุฉ ุญู‚ุงุฆู‚ ู…ู† DB
            foreach ($facts as $fact) {
                if (!str_contains($output, (string)$fact)) {
                    return "ุงู„ุญู‚ูŠู‚ุฉ ุบูŠุฑ ู…ูˆุฌูˆุฏุฉ ููŠ ุงู„ุฅุฌุงุจุฉ: $fact";
                }
            }
            return true;
        };
    }

    public static function selfConsistencyRule(callable $askLLM, int $samples = 3): callable {
        return function ($output, $goal) use ($askLLM, $samples) {
            $answers = [$output];
            for ($i = 1; $i < $samples; $i++) {
                $answers[] = $askLLM($goal);
            }
            $normalized = array_map(fn($a) => md5(strtolower(trim($a))), $answers);
            $unique = count(array_unique($normalized));
            return $unique === 1 ? true : "ุงู„ุฅุฌุงุจุงุช ุบูŠุฑ ู…ุชุณู‚ุฉ ($unique/$samples ู…ุฎุชู„ูุฉ)";
        };
    }
}

๐Ÿ”ง ุงู„ู…ูƒูˆู‘ู† 3: Multi-Agent System + Message Bus

src/Core/MessageBus.php

php

<?php
namespace Zezo\AI\Core;

class MessageBus {
    private string $table;

    public function __construct() {
        global $wpdb;
        $this->table = $wpdb->prefix . 'agent_messages';
        $this->ensureTable();
    }

    private function ensureTable(): void {
        global $wpdb;
        $charset = $wpdb->get_charset_collate();
        $sql = "CREATE TABLE IF NOT EXISTS {$this->table} (
            id BIGINT AUTO_INCREMENT PRIMARY KEY,
            task_id VARCHAR(64),
            from_agent VARCHAR(64),
            to_agent VARCHAR(64),
            type VARCHAR(32),
            payload LONGTEXT,
            created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
            INDEX(task_id), INDEX(to_agent)
        ) $charset;";
        require_once ABSPATH . 'wp-admin/includes/upgrade.php';
        dbDelta($sql);
    }

    public function send(string $taskId, string $from, string $to, string $type, array $payload): void {
        global $wpdb;
        $wpdb->insert($this->table, [
            'task_id' => $taskId,
            'from_agent' => $from,
            'to_agent' => $to,
            'type' => $type,
            'payload' => wp_json_encode($payload),
        ]);
    }

    public function receive(string $taskId, string $agent): array {
        global $wpdb;
        $rows = $wpdb->get_results($wpdb->prepare(
            "SELECT * FROM {$this->table} WHERE task_id=%s AND to_agent=%s ORDER BY id ASC",
            $taskId, $agent
        ), ARRAY_A);
        return array_map(fn($r) => [
            'from' => $r['from_agent'],
            'type' => $r['type'],
            'payload' => json_decode($r['payload'], true),
        ], $rows);
    }
}

src/Core/Orchestrator.php

php

<?php
namespace Zezo\AI\Core;

class Orchestrator {
    private array $agents = [];
    private MessageBus $bus;

    public function __construct(MessageBus $bus) {
        $this->bus = $bus;
    }

    public function register(string $id, Agent $agent): self {
        $this->agents[$id] = $agent;
        return $this;
    }

    /**
     * Pipeline ุฎุทูŠ: Planner โ†’ Researcher โ†’ Writer โ†’ Critic โ†’ Executor
     */
    public function runPipeline(string $goal): array {
        $taskId = wp_generate_uuid4();
        $results = [];
        $context = ['goal' => $goal];

        // 1. Planner
        $plan = $this->agents['planner']->run("ุถุน ุฎุทุฉ ุชู†ููŠุฐูŠุฉ ู…ูุตู„ุฉ ู„ู„ู‡ุฏู: $goal");
        $results['planner'] = $plan;
        $context['plan'] = $plan['output'];

        // 2. Researcher
        $research = $this->agents['researcher']->run("ุงุฌู…ุน ุงู„ู…ุนู„ูˆู…ุงุช ุงู„ู„ุงุฒู…ุฉ ุญุณุจ ุงู„ุฎุทุฉ:\n{$plan['output']}", $context);
        $results['researcher'] = $research;
        $context['research'] = $research['output'];

        // 3. Writer
        $draft = $this->agents['writer']->run("ุงูƒุชุจ ุงู„ู…ุญุชูˆู‰ ุงู„ู†ู‡ุงุฆูŠ ุจู†ุงุกู‹ ุนู„ู‰ ุงู„ุจุญุซ:\n{$research['output']}", $context);
        $results['writer'] = $draft;
        $context['draft'] = $draft['output'];

        // 4. Critic (loop ุญุชู‰ ุงู„ุฑุถุง)
        $maxRounds = 3;
        for ($i = 0; $i < $maxRounds; $i++) {
            $critique = $this->agents['critic']->run("ุงู†ุชู‚ุฏ ุงู„ู…ุณูˆุฏุฉ ุงู„ุชุงู„ูŠุฉ ุจุนู…ู‚:\n{$draft['output']}", $context);
            $results['critic_round_' . $i] = $critique;

            if (str_contains(strtolower($critique['output']), 'ู…ู‚ุจูˆู„') ||
                str_contains(strtolower($critique['output']), 'approved')) {
                break;
            }
            $draft = $this->agents['writer']->run(
                "ุญุณู‘ู† ุงู„ู…ุณูˆุฏุฉ ุญุณุจ ุงู„ู…ู„ุงุญุธุงุช:\n{$critique['output']}\n\nุงู„ู…ุณูˆุฏุฉ:\n{$draft['output']}",
                $context
            );
            $results['writer_revision_' . $i] = $draft;
        }

        // 5. Executor (ูŠู†ุดุฑ ู…ุซู„ู‹ุง)
        $execution = $this->agents['executor']->run(
            "ู†ูู‘ุฐ ุงู„ู…ู‡ู…ุฉ ุงู„ู†ู‡ุงุฆูŠุฉ (ุงู†ุดุฑ ุงู„ู…ุญุชูˆู‰ ูƒู…ุณูˆุฏุฉ ููŠ WordPress):\n{$draft['output']}",
            $context
        );
        $results['executor'] = $execution;

        return ['task_id' => $taskId, 'results' => $results, 'final' => $execution];
    }
}

๐Ÿ”ง ุงู„ู…ูƒูˆู‘ู† 4: Memory Store + Vector Search

src/Memory/VectorClient.php (Qdrant)

php

<?php
namespace Zezo\AI\Memory;

use GuzzleHttp\Client;

class VectorClient {
    private Client $http;
    private string $collection;

    public function __construct(string $endpoint, string $collection, string $apiKey = '') {
        $headers = ['Content-Type' => 'application/json'];
        if ($apiKey) $headers['api-key'] = $apiKey;
        $this->http = new Client(['base_uri' => rtrim($endpoint, '/') . '/', 'headers' => $headers, 'timeout' => 60]);
        $this->collection = $collection;
        $this->ensureCollection();
    }

    private function ensureCollection(): void {
        try {
            $this->http->get("collections/{$this->collection}");
        } catch (\Throwable $e) {
            $this->http->put("collections/{$this->collection}", [
                'json' => [
                    'vectors' => ['size' => 3072, 'distance' => 'Cosine'],
                ],
            ]);
        }
    }

    public function upsert(string $id, array $vector, array $payload): void {
        $this->http->put("collections/{$this->collection}/points", [
            'json' => ['points' => [['id' => $id, 'vector' => $vector, 'payload' => $payload]]],
        ]);
    }

    public function search(array $vector, int $top = 5): array {
        $res = $this->http->post("collections/{$this->collection}/points/search", [
            'json' => ['vector' => $vector, 'limit' => $top, 'with_payload' => true],
        ]);
        return json_decode($res->getBody()->getContents(), true)['result'] ?? [];
    }
}

src/Memory/MemoryStore.php

php

<?php
namespace Zezo\AI\Memory;

use Zezo\AI\LLM\LLMClient;

class MemoryStore {
    private LLMClient $embedder;
    private VectorClient $vector;
    private string $table;

    public function __construct(LLMClient $embedder, VectorClient $vector) {
        global $wpdb;
        $this->embedder = $embedder;
        $this->vector = $vector;
        $this->table = $wpdb->prefix . 'agent_memory';
        $this->ensureTable();
    }

    private function ensureTable(): void {
        global $wpdb;
        $charset = $wpdb->get_charset_collate();
        $sql = "CREATE TABLE IF NOT EXISTS {$this->table} (
            id BIGINT AUTO_INCREMENT PRIMARY KEY,
            agent_id VARCHAR(64),
            goal LONGTEXT,
            result LONGTEXT,
            vector_id VARCHAR(64),
            metadata JSON,
            created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
            INDEX(agent_id), INDEX(vector_id)
        ) $charset;";
        require_once ABSPATH . 'wp-admin/includes/upgrade.php';
        dbDelta($sql);
    }

    public function store(array $data): void {
        global $wpdb;
        $text = ($data['goal'] ?? '') . "\n" . ($data['result'] ?? '');
        $vector = $this->embedder->embed($text);
        $vectorId = wp_generate_uuid4();

        $this->vector->upsert($vectorId, $vector, [
            'agent' => $data['agent'] ?? 'unknown',
            'goal' => $data['goal'] ?? '',
            'result' => $data['result'] ?? '',
        ]);

        $wpdb->insert($this->table, [
            'agent_id' => $data['agent'] ?? '',
            'goal' => $data['goal'] ?? '',
            'result' => $data['result'] ?? '',
            'vector_id' => $vectorId,
            'metadata' => wp_json_encode($data['metadata'] ?? []),
        ]);
    }

    public function search(string $query, int $top = 5): array {
        $vector = $this->embedder->embed($query);
        $hits = $this->vector->search($vector, $top);
        return array_map(fn($h) => $h['payload']['result'] ?? '', $hits);
    }
}

๐Ÿ”ง ุงู„ู…ูƒูˆู‘ู† 5: Knowledge Graph ุนู„ู‰ MySQL

src/Graph/KnowledgeGraph.php

php

<?php
namespace Zezo\AI\Graph;

class KnowledgeGraph {
    private string $nodesTable;
    private string $edgesTable;

    public function __construct() {
        global $wpdb;
        $this->nodesTable = $wpdb->prefix . 'kg_nodes';
        $this->edgesTable = $wpdb->prefix . 'kg_edges';
        $this->ensureSchema();
    }

    private function ensureSchema(): void {
        global $wpdb;
        $charset = $wpdb->get_charset_collate();
        require_once ABSPATH . 'wp-admin/includes/upgrade.php';

        dbDelta("CREATE TABLE IF NOT EXISTS {$this->nodesTable} (
            id BIGINT AUTO_INCREMENT PRIMARY KEY,
            type VARCHAR(50),
            label VARCHAR(255),
            properties JSON,
            created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
            INDEX(type), INDEX(label(100))
        ) $charset;");

        dbDelta("CREATE TABLE IF NOT EXISTS {$this->edgesTable} (
            id BIGINT AUTO_INCREMENT PRIMARY KEY,
            source_id BIGINT,
            target_id BIGINT,
            relation VARCHAR(100),
            weight FLOAT DEFAULT 1.0,
            properties JSON,
            INDEX(source_id), INDEX(target_id), INDEX(relation)
        ) $charset;");
    }

    public function addNode(string $type, string $label, array $props = []): int {
        global $wpdb;
        $wpdb->insert($this->nodesTable, [
            'type' => $type,
            'label' => $label,
            'properties' => wp_json_encode($props),
        ]);
        return (int)$wpdb->insert_id;
    }

    public function addEdge(int $src, int $dst, string $relation, float $weight = 1.0, array $props = []): void {
        global $wpdb;
        $wpdb->insert($this->edgesTable, [
            'source_id' => $src,
            'target_id' => $dst,
            'relation' => $relation,
            'weight' => $weight,
            'properties' => wp_json_encode($props),
        ]);
    }

    /** ุงุฌู„ุจ ุฌูŠุฑุงู† ุนู‚ุฏุฉ */
    public function neighbors(int $nodeId, ?string $relation = null): array {
        global $wpdb;
        $sql = "SELECT n.*, e.relation, e.weight FROM {$this->edgesTable} e
                JOIN {$this->nodesTable} n ON n.id = e.target_id
                WHERE e.source_id = %d";
        $params = [$nodeId];
        if ($relation) { $sql .= " AND e.relation = %s"; $params[] = $relation; }
        return $wpdb->get_results($wpdb->prepare($sql, ...$params), ARRAY_A);
    }

    /** ุจุญุซ multi-hop ุจุณูŠุท (BFS) */
    public function traverse(int $startId, int $depth = 2): array {
        $visited = [$startId => true];
        $frontier = [$startId];
        $graph = ['nodes' => [], 'edges' => []];

        for ($d = 0; $d < $depth; $d++) {
            $next = [];
            foreach ($frontier as $nid) {
                foreach ($this->neighbors($nid) as $n) {
                    $graph['edges'][] = ['from' => $nid, 'to' => $n['id'], 'rel' => $n['relation']];
                    if (!isset($visited[$n['id']])) {
                        $visited[$n['id']] = true;
                        $graph['nodes'][] = $n;
                        $next[] = $n['id'];
                    }
                }
            }
            $frontier = $next;
        }
        return $graph;
    }

    /** ุจู†ุงุก KG ู…ู† ู…ู‚ุงู„ุงุช WordPress */
    public function buildFromPosts(int $limit = 100): int {
        $posts = get_posts(['numberposts' => $limit, 'post_status' => 'publish']);
        $count = 0;
        foreach ($posts as $post) {
            $postNode = $this->addNode('post', $post->post_title, [
                'wp_id' => $post->ID,
                'url' => get_permalink($post->ID),
            ]);
            $authorNode = $this->addNode('user', get_the_author_meta('display_name', $post->post_author), [
                'wp_id' => $post->post_author,
            ]);
            $this->addEdge($authorNode, $postNode, 'authored');

            foreach (wp_get_post_categories($post->ID) as $catId) {
                $cat = get_category($catId);
                if ($cat) {
                    $catNode = $this->addNode('category', $cat->name, ['wp_id' => $catId]);
                    $this->addEdge($postNode, $catNode, 'in_category');
                }
            }
            $count++;
        }
        return $count;
    }
}

๐Ÿ”ง ุงู„ู…ูƒูˆู‘ู† 6: Admin Dashboard ู…ุชู‚ุฏู…

src/Admin/RestApi.php

php

<?php
namespace Zezo\AI\Admin;

class RestApi {
    public function register(): void {
        add_action('rest_api_init', function () {
            register_rest_route('zezo-ai/v1', '/agents', [
                'methods' => 'GET',
                'callback' => [$this, 'listAgents'],
                'permission_callback' => fn() => current_user_can('manage_options'),
            ]);
            register_rest_route('zezo-ai/v1', '/run', [
                'methods' => 'POST',
                'callback' => [$this, 'runTask'],
                'permission_callback' => fn() => current_user_can('manage_options'),
            ]);
            register_rest_route('zezo-ai/v1', '/tasks/(?P<id>[\w-]+)', [
                'methods' => 'GET',
                'callback' => [$this, 'getTask'],
                'permission_callback' => fn() => current_user_can('manage_options'),
            ]);
        });
    }

    public function listAgents(): array {
        return [
            ['id' => 'planner', 'role' => 'Planner', 'status' => 'idle'],
            ['id' => 'researcher', 'role' => 'Researcher', 'status' => 'idle'],
            ['id' => 'writer', 'role' => 'Writer', 'status' => 'idle'],
            ['id' => 'critic', 'role' => 'Critic', 'status' => 'idle'],
            ['id' => 'executor', 'role' => 'Executor', 'status' => 'idle'],
        ];
    }

    public function runTask(\WP_REST_Request $req): array {
        $goal = sanitize_text_field($req->get_param('goal'));
        // ุดุบู‘ู„ ููŠ ุงู„ุฎู„ููŠุฉ ุนุจุฑ Action Scheduler ุฃูˆ cron
        as_enqueue_async_action('zezo_ai_run_pipeline', ['goal' => $goal], 'zezo-ai');
        return ['queued' => true, 'goal' => $goal];
    }

    public function getTask(\WP_REST_Request $req): array {
        global $wpdb;
        $taskId = $req['id'];
        $rows = $wpdb->get_results($wpdb->prepare(
            "SELECT * FROM {$wpdb->prefix}agent_messages WHERE task_id=%s ORDER BY id ASC", $taskId
        ), ARRAY_A);
        return ['task_id' => $taskId, 'messages' => $rows];
    }
}

src/Admin/Dashboard.php

php

<?php
namespace Zezo\AI\Admin;

class Dashboard {
    public function register(): void {
        add_action('admin_menu', function () {
            add_menu_page(
                'Zezo AI Agents', 'Zezo AI', 'manage_options',
                'zezo-ai', [$this, 'render'], 'dashicons-buddicons-buddypress-logo', 30
            );
        });
        add_action('admin_enqueue_scripts', function ($hook) {
            if ($hook !== 'toplevel_page_zezo-ai') return;
            wp_enqueue_script('zezo-ai-admin', plugins_url('assets/admin.js', __DIR__ . '/../../zezo-ai-agents.php'), ['wp-element'], '1.0', true);
            wp_localize_script('zezo-ai-admin', 'ZezoAI', [
                'rest' => rest_url('zezo-ai/v1'),
                'nonce' => wp_create_nonce('wp_rest'),
            ]);
        });
    }

    public function render(): void {
        echo '<div id="zezo-ai-root"></div>';
    }
}

assets/admin.js (React ู…ุตุบุฑ)

jsx

const { render, useState, useEffect } = wp.element;

function Dashboard() {
  const [agents, setAgents] = useState([]);
  const [goal, setGoal] = useState('');
  const [trace, setTrace] = useState(null);

  useEffect(() => {
    fetch(ZezoAI.rest + '/agents', { headers: { 'X-WP-Nonce': ZezoAI.nonce } })
      .then(r => r.json()).then(setAgents);
  }, []);

  const run = async () => {
    const res = await fetch(ZezoAI.rest + '/run', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json', 'X-WP-Nonce': ZezoAI.nonce },
      body: JSON.stringify({ goal })
    }).then(r => r.json());
    alert('ุชู… ุฌุฏูˆู„ุฉ ุงู„ู…ู‡ู…ุฉ: ' + res.goal);
  };

  return (
    <div className="wrap">
      <h1>Zezo AI Agents Dashboard</h1>
      <div style={{ display: 'flex', gap: 16, marginBottom: 24 }}>
        {agents.map(a => (
          <div key={a.id} style={{ padding: 16, border: '1px solid #ccc', borderRadius: 8, minWidth: 140 }}>
            <strong>{a.role}</strong><br />
            <span style={{ color: a.status === 'idle' ? 'green' : 'orange' }}>โ— {a.status}</span>
          </div>
        ))}
      </div>

      <h2>ุชุดุบูŠู„ ู…ู‡ู…ุฉ ุฌุฏูŠุฏุฉ</h2>
      <textarea value={goal} onChange={e => setGoal(e.target.value)}
        placeholder="ุงูƒุชุจ ุงู„ู‡ุฏู ู‡ู†ุง..." style={{ width: '100%', height: 100 }} />
      <button className="button button-primary" onClick={run}>Run Pipeline</button>
    </div>
  );
}

render(<Dashboard />, document.getElementById('zezo-ai-root'));

๐ŸŽฏ ุงู„ู…ู„ู ุงู„ุฑุฆูŠุณูŠ zezo-ai-agents.php

php

<?php
/**
 * Plugin Name: Zezo AI Agents
 * Description: Multi-Agent LLM System for WordPress with Verification, Memory, and KG
 * Version: 1.0.0
 * Author: You
 */

require __DIR__ . '/vendor/autoload.php';

use Zezo\AI\LLM\OpenAIProvider;
use Zezo\AI\LLM\ClaudeProvider;
use Zezo\AI\Core\Agent;
use Zezo\AI\Core\MessageBus;
use Zezo\AI\Core\Orchestrator;
use Zezo\AI\Tools\ToolRegistry;
use Zezo\AI\Memory\MemoryStore;
use Zezo\AI\Memory\VectorClient;
use Zezo\AI\Verification\VerificationLoop;
use Zezo\AI\Admin\Dashboard;
use Zezo\AI\Admin\RestApi;

add_action('plugins_loaded', function () {
    $openai = new OpenAIProvider(get_option('zezo_openai_key', ''));
    $claude = new ClaudeProvider(get_option('zezo_claude_key', ''));

    $tools = (new ToolRegistry())
        ->register('wp_query', new \Zezo\AI\Tools\Tools\WpQueryTool())
        ->register('sql_query', new \Zezo\AI\Tools\Tools\SqlQueryTool());

    $vector = new VectorClient(get_option('zezo_qdrant_url', 'http://localhost:6333'), 'wp_agent_memory');
    $memory = new MemoryStore($openai, $vector);

    $verifier = (new VerificationLoop())
        ->addRule(VerificationLoop::lengthRule(10, 20000), 'length');

    $makeAgent = fn($id, $role, $prompt, $llm) =>
        new Agent($id, $role, $prompt, $llm, $tools, $memory, $verifier);

    $bus = new MessageBus();
    $orchestrator = (new Orchestrator($bus))
        ->register('planner', $makeAgent('planner', 'Planner', 'ุฃู†ุช ู…ุฎุทุท ุฎุจูŠุฑ. ููƒูƒ ุงู„ุฃู‡ุฏุงู ู„ู…ู‡ุงู… ูุฑุนูŠุฉ.', $claude))
        ->register('researcher', $makeAgent('researcher', 'Researcher', 'ุฃู†ุช ุจุงุญุซ. ุงุณุชุฎุฏู… ุงู„ุฃุฏูˆุงุช ู„ุฌู…ุน ุงู„ุญู‚ุงุฆู‚.', $openai))
        ->register('writer', $makeAgent('writer', 'Writer', 'ุฃู†ุช ูƒุงุชุจ ู…ุญุชุฑู ุจุงู„ุนุฑุจูŠุฉ.', $claude))
        ->register('critic', $makeAgent('critic', 'Critic', 'ุฃู†ุช ู†ุงู‚ุฏ ุตุงุฑู…. ุงุฐูƒุฑ "ู…ู‚ุจูˆู„" ูู‚ุท ุนู†ุฏ ุงู„ุฌูˆุฏุฉ ุงู„ุนุงู„ูŠุฉ.', $openai))
        ->register('executor', $makeAgent('executor', 'Executor', 'ุฃู†ุช ู…ู†ูุฐ. ุงู†ุดุฑ ุงู„ู…ุญุชูˆู‰ ููŠ WordPress.', $openai));

    // Action Scheduler hook
    add_action('zezo_ai_run_pipeline', function ($goal) use ($orchestrator) {
        $orchestrator->runPipeline($goal);
    });

    (new Dashboard())->register();
    (new RestApi())->register();
});

๐Ÿ“Š ู…ู‚ุงุฑู†ุฉ ุณุฑูŠุนุฉ ุจูŠู† ุงู„ู…ุฒูˆู‘ุฏูŠู†

ุงู„ู…ูŠุฒุฉOpenAI GPT-4oClaude Sonnet 4.5
Tool callingโœ… ู…ู…ุชุงุฒโœ… ู…ู…ุชุงุฒ
Embeddingsโœ… ู…ุฏู…ุฌโŒ (ูŠุญุชุงุฌ Voyage/OpenAI)
JSON modeโœ… strictโœ… ุนุจุฑ tools
Context128K200K
ุงู„ุฃูุถู„ ููŠุงู„ุฃุฏูˆุงุช ูˆุงู„ู€ JSONุงู„ูƒุชุงุจุฉ ูˆุงู„ุชุญู„ูŠู„ ุงู„ุทูˆูŠู„

ุงู„ุชูˆุตูŠุฉ: ุงุณุชุฎุฏู… Claude ู„ู„ู€ Planner/Writer ูˆOpenAI ู„ู„ู€ Researcher/Executor (ู„ุฃู†ู‡ ูŠุญุชุงุฌ embeddings + JSON ุตุงุฑู…).


โš ๏ธ ู†ู‚ุงุท Production ู…ู‡ู…ุฉ

  1. Rate Limiting: ุฎุฒู‘ู† ุนุฏุฏ ุงู„ู€ tokens ููŠย wp_optionsย ูˆุฃูˆู‚ู ุนู†ุฏ ุงู„ุญุฏ.
  2. Cost Tracking: ุณุฌู‘ู„ย usageย ู…ู† ูƒู„ ุฑุฏ ููŠ ุฌุฏูˆู„ย wp_agent_costs.
  3. Async Execution: ุงุณุชุฎุฏู…ย Action Schedulerย (ูŠุฃุชูŠ ู…ุน WooCommerce) ุฃูˆย wp_schedule_single_event.
  4. Secrets: ู„ุง ุชุฎุฒู† API keys ููŠ DB ู†ุตู‹ุง ุตุฑูŠุญู‹ุง โ€” ุงุณุชุฎุฏู…ย wp-config.phpย constants.
  5. Kill Switch:ย wp_options.zezo_ai_enabledย = false ูŠูˆู‚ู ูƒู„ ุงู„ูˆูƒู„ุงุก.
  6. Logging: ุงุณุชุฎุฏู…ย error_logย ุฃูˆ Monolog ุฅู„ู‰ ู…ู„ู ููŠย wp-content/uploads/zezo-ai-logs/.

๐ŸŽฌ ุงู„ุฎุทูˆุฉ ุงู„ุชุงู„ูŠุฉ โ€” ุงุฎุชุฑ ูˆุงุญุฏู‹ุง:

ุฃ) ุฃุฑุณู„ ู„ูƒ ุงู„ู€ Plugin ูƒุงู…ู„ ุฌุงู‡ุฒ ู„ู„ุชู†ุฒูŠู„ุŸ

ุณุฃุฌู…ุน ูƒู„ ุงู„ู…ู„ูุงุช ููŠ ู‡ูŠูƒู„ ู†ู‡ุงุฆูŠ ู…ุน ุฎุทูˆุงุช ุงู„ุชุซุจูŠุช (composer install โ†’ activate โ†’ ุฅุนุฏุงุฏ ุงู„ู…ูุงุชูŠุญ).

ุจ) ู†ุจู†ูŠ ู…ูƒูˆู‘ู†ู‹ุง ูˆุงุญุฏู‹ุง ุจุนู…ู‚ ุฃูƒุจุฑุŸ

ู…ุซู„ู‹ุง:

  • Verification Loop ู…ุชู‚ุฏู…ย ู…ุน 8 ุฃู†ูˆุงุน ุชุญู‚ู‚ ู…ุฎุชู„ูุฉ
  • Memory Systemย ู…ุน hierarchical + episodic + semantic
  • Agent-to-Agent Protocolย ู…ุน negotiation ุจูŠู† ุงู„ูˆูƒู„ุงุก

ุฌ) ู†ุจู†ูŠ ุญุงู„ุฉ ุงุณุชุฎุฏุงู… ุญู‚ูŠู‚ูŠุฉุŸ

ู…ุซู„ู‹ุง:

  • ู…ุฏูŠุฑ ู…ุญุชูˆู‰ ุฐูƒูŠ: ูŠูƒุชุจ ูˆูŠุญุฑุฑ ูˆูŠู†ุดุฑ ู…ู‚ุงู„ุงุช WordPress ุชู„ู‚ุงุฆูŠู‹ุง
  • ู…ุณุงุนุฏ ุฏุนู… ุนู…ู„ุงุก: ูŠู‚ุฑุฃ ุชุฐุงูƒุฑ ูˆูŠุฑุฏ ูˆูŠุตุนู‘ุฏ
  • ู…ุญู„ู„ SEO: ูŠูุญุต ุงู„ู…ู‚ุงู„ุงุช ูˆูŠู‚ุชุฑุญ ุชุญุณูŠู†ุงุช ูˆูŠู†ูุฐู‡ุง

ู‚ู„ ู„ูŠ:

  1. ุฃูŠ ู…ุณุงุฑ ุชุฑูŠุฏ (ุฃ / ุจ / ุฌ)ุŸ
  2. ู…ุง ุฅุตุฏุงุฑ PHP ูˆ WordPress ู„ุฏูŠูƒุŸ
  3. ู‡ู„ ู„ุฏูŠูƒ ู…ูุงุชูŠุญ OpenAI/Claude ูˆ Qdrant ุฌุงู‡ุฒุฉุŸ

ูˆุณุฃูƒู…ู„ ู…ุนูƒ ููˆุฑู‹ุง ุฅู„ู‰ ุงู„ูƒูˆุฏ ุงู„ู†ู‡ุงุฆูŠ ุงู„ู‚ุงุจู„ ู„ู„ุชุดุบูŠู„. ๐Ÿ”ฅ

Scroll to Top

๐Ÿค– ู…ูˆุตู‰ ุจู‡ ู„ูƒ ุจู†ุงุกู‹ ุนู„ู‰ ุงู‡ุชู…ุงู…ุงุชูƒ