Sebelum memulai praktik, pastikan Anda telah memahami konsep dasar pada materi kelas AI Agent & PHP di infokoding.

BAB 7

Membuat Memory Percakapan

Implementasi memory percakapan pada AI Agent: menyimpan riwayat chat menggunakan Session PHP dan MySQL, memahami batas Context Window, dan cara mengirim history ke OpenAI API.

Terakhir diperbarui:

TL;DR (Ringkasan Cepat)

  • Session PHP cocok untuk memory jangka pendek dalam satu browser session.
  • Database MySQL diperlukan untuk menyimpan riwayat chat jangka panjang antar session.
  • Context Window adalah batas maksimum token yang dapat diproses AI dalam satu request.
  • Selalu kirim riwayat percakapan yang relevan agar AI memiliki konteks yang cukup.

Menyimpan Riwayat Chat dengan Session

Untuk prototype cepat, PHP Session adalah pilihan yang mudah dan cepat diimplementasikan:

<?php

class SessionMemory
{
    private string $sessionKey;

    public function __construct(string $sessionKey = 'chat_history')
    {
        $this->sessionKey = $sessionKey;
        if (session_status() === PHP_SESSION_NONE) {
            session_start();
        }
    }

    public function add(string $role, string $content): void
    {
        if (!isset($_SESSION[$this->sessionKey])) {
            $_SESSION[$this->sessionKey] = [];
        }
        $_SESSION[$this->sessionKey][] = [
            'role'    => $role,
            'content' => $content,
        ];
    }

    public function getAll(): array
    {
        return $_SESSION[$this->sessionKey] ?? [];
    }

    public function clear(): void
    {
        $_SESSION[$this->sessionKey] = [];
    }

    public function getLastN(int $n): array
    {
        $history = $this->getAll();
        return array_slice($history, -$n);
    }
}

Menyimpan Riwayat Chat ke Database MySQL

Untuk aplikasi production, gunakan database agar riwayat persisten antar session:

-- Migration: Tabel chat_sessions
CREATE TABLE IF NOT EXISTS chat_sessions (
    id          BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
    session_id  VARCHAR(128) NOT NULL,
    user_id     BIGINT UNSIGNED NULL,
    created_at  DATETIME DEFAULT CURRENT_TIMESTAMP,
    updated_at  DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
    INDEX idx_session_id (session_id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

-- Migration: Tabel chat_messages
CREATE TABLE IF NOT EXISTS chat_messages (
    id          BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
    session_id  VARCHAR(128) NOT NULL,
    role        ENUM('system','user','assistant','tool') NOT NULL,
    content     LONGTEXT NOT NULL,
    tool_name   VARCHAR(100) NULL,
    token_count INT NULL,
    created_at  DATETIME DEFAULT CURRENT_TIMESTAMP,
    INDEX idx_session_id (session_id),
    INDEX idx_created_at (created_at)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
<?php

class DatabaseMemory
{
    private PDO $pdo;
    private string $sessionId;

    public function __construct(PDO $pdo, string $sessionId)
    {
        $this->pdo       = $pdo;
        $this->sessionId = $sessionId;
    }

    public function add(string $role, string $content, ?string $toolName = null): void
    {
        $stmt = $this->pdo->prepare(
            'INSERT INTO chat_messages (session_id, role, content, tool_name) VALUES (?, ?, ?, ?)'
        );
        $stmt->execute([$this->sessionId, $role, $content, $toolName]);
    }

    public function getAll(int $limit = 50): array
    {
        $stmt = $this->pdo->prepare(
            'SELECT role, content FROM chat_messages
             WHERE session_id = ?
             ORDER BY created_at ASC
             LIMIT ?'
        );
        $stmt->execute([$this->sessionId, $limit]);
        return $stmt->fetchAll(PDO::FETCH_ASSOC);
    }
}

Memahami Context Window

Context Window adalah batas maksimum jumlah token (kata/karakter) yang dapat diproses oleh AI dalam satu request. Setiap model memiliki batas yang berbeda:

  • gpt-4o-mini: ~128.000 token context window
  • gpt-4o: ~128.000 token context window
  • gpt-3.5-turbo: ~16.000 token context window

Jika riwayat percakapan melebihi batas ini, Anda perlu menerapkan strategi truncation:

// Strategi: Selalu sertakan system prompt + N pesan terakhir
public function buildContextMessages(array $history, string $systemPrompt, int $maxMessages = 20): array
{
    $messages = [['role' => 'system', 'content' => $systemPrompt]];
    $recentHistory = array_slice($history, -$maxMessages);
    return array_merge($messages, $recentHistory);
}

Poin Kunci Bab 7

Memory yang baik adalah perbedaan antara AI yang "pelupa" dan AI yang benar-benar terasa cerdas. Selalu desain sistem memory dari awal — jauh lebih mudah daripada menambahkannya belakangan.