Membuat AI Agent dengan Memory dan Database

Membuat AI Agent dengan Memory dan Database

Pendahuluan

AI Agent adalah entitas yang dapat berinteraksi secara natural dengan pengguna, menyimpan konteks percakapan, dan mengambil data dari sumber eksternal. Dalam tutorial ini, Anda akan membangun AI Agent yang:
- Menggunakan ChatGPT Plus (atau alternatif LLM) untuk generasi teks.
- Menyimpan memori percakapan di Redis sebagai store in‑memory.
- Menyimpan data historis dan log di PostgreSQL.
- Menyediakan API REST sederhana untuk interaksi.

Arsitektur singkat:

Client  ──►  API Gateway  ──►  Agent Service
                                   │
                                   ├─►  Redis (Memory)
                                   └─►  PostgreSQL (Database)

Prasyarat & Persiapan

Item Kebutuhan Referensi
Python 3.10+ Interpreter https://www.python.org/downloads/
pip Package manager python -m ensurepip
PostgreSQL 15 Database https://www.postgresql.org/download/
Redis 7 In‑memory store https://redis.io/download
OpenAI API Key LLM https://platform.openai.com/account/api-keys
.env Konfigurasi pip install python-dotenv
Docker (opsional) Containerization https://www.docker.com/get-started

Tip: Untuk produksi, gunakan Vault atau AWS Secrets Manager untuk menyimpan kredensial.

Langkah Demi Langkah

1. Inisialisasi Proyek

mkdir ai-agent && cd ai-agent
python -m venv venv
source venv/bin/activate
pip install fastapi uvicorn[standard] python-dotenv openai redis psycopg2-binary

2. Konfigurasi Environment

Buat file .env:

OPENAI_API_KEY=sk-xxxxxxxxxxxxxxxxxxxxxxxx
REDIS_URL=redis://localhost:6379/0
POSTGRES_URL=postgresql://postgres:password@localhost:5432/ai_agent

3. Buat Skema Database

-- db_setup.sql
CREATE TABLE conversations (
    id SERIAL PRIMARY KEY,
    user_id TEXT NOT NULL,
    created_at TIMESTAMP DEFAULT NOW()
);

CREATE TABLE messages (
    id SERIAL PRIMARY KEY,
    conv_id INTEGER REFERENCES conversations(id),
    role TEXT NOT NULL,
    content TEXT NOT NULL,
    created_at TIMESTAMP DEFAULT NOW()
);
psql -U postgres -f db_setup.sql

4. Kode Agent Service

app/main.py

import os
import json
from datetime import datetime
from fastapi import FastAPI, HTTPException
from pydantic import BaseModel
import openai
import redis
import psycopg2
from dotenv import load_dotenv

load_dotenv()

app = FastAPI()
openai.api_key = os.getenv("OPENAI_API_KEY")

r = redis.Redis.from_url(os.getenv("REDIS_URL"))
conn = psycopg2.connect(os.getenv("POSTGRES_URL"))
cur = conn.cursor()

class Message(BaseModel):
    role: str
    content: str

class ConversationRequest(BaseModel):
    user_id: str
    messages: list[Message]

def store_message(conv_id: int, role: str, content: str):
    cur.execute(
        "INSERT INTO messages (conv_id, role, content) VALUES (%s, %s, %s)",
        (conv_id, role, content)
    )
    conn.commit()

def get_memory(user_id: str):
    key = f"mem:{user_id}"
    return r.get(key)

def set_memory(user_id: str, data: str):
    key = f"mem:{user_id}"
    r.set(key, data, ex=3600)  # 1 hour TTL

@app.post("/chat")
def chat(req: ConversationRequest):
    # 1. Create conversation if new
    cur.execute(
        "SELECT id FROM conversations WHERE user_id = %s ORDER BY created_at DESC LIMIT 1",
        (req.user_id,)
    )
    row = cur.fetchone()
    if row:
        conv_id = row[0]
    else:
        cur.execute(
            "INSERT INTO conversations (user_id) VALUES (%s) RETURNING id",
            (req.user_id,)
        )
        conv_id = cur.fetchone()[0]
        conn.commit()

    # 2. Store incoming messages
    for msg in req.messages:
        store_message(conv_id, msg.role, msg.content)

    # 3. Retrieve memory
    memory = get_memory(req.user_id) or ""

    # 4. Build prompt
    prompt = f"{memory}\nUser: {req.messages[-1].content}\nAI:"

    # 5. Call LLM
    response = openai.ChatCompletion.create(
        model="gpt-4o-mini",
        messages=[{"role": "system", "content": "You are a helpful assistant."},
                  {"role": "user", "content": prompt}]
    )
    ai_text = response.choices[0].message.content.strip()

    # 6. Store AI response
    store_message(conv_id, "assistant", ai_text)

    # 7. Update memory (simple sliding window)
    new_memory = f"{memory}\nUser: {req.messages[-1].content}\nAI: {ai_text}"
    set_memory(req.user_id, new_memory)

    return {"response": ai_text}

5. Jalankan Server

uvicorn app.main:app --reload

6. Uji dengan curl

curl -X POST http://localhost:8000/chat \
  -H "Content-Type: application/json" \
  -d '{
        "user_id": "alice",
        "messages": [
          {"role": "user", "content": "Apa kabar?"}
        ]
      }'

Tips Optimasi & Keamanan

Praktik Penjelasan
Gunakan Environment Variables Hindari hard‑coding kredensial.
Rate Limiting Terapkan middleware FastAPI SlowAPI untuk mencegah abuse.
TLS Deploy di behind HTTPS (Let’s Encrypt).
Connection Pooling Gunakan psycopg2.pool.SimpleConnectionPool.
Cache Expiry TTL Redis 1‑2 jam cukup untuk memori percakapan.
Audit Log Simpan log request di PostgreSQL untuk compliance.
Model Selection Gunakan gpt-4o-mini untuk biaya rendah, upgrade bila perlu.

Sumber Daya Tambahan
- Notion AI: Gunakan https://tools.jartekindo.com/tool/notion-ai/ untuk menulis dokumentasi otomatis.
- Midjourney: Jika ingin menambahkan gambar ke respons, gunakan https://tools.jartekindo.com/tool/midjourney/.

Troubleshooting Error Umum

Error Penyebab Solusi
openai.error.AuthenticationError API key tidak valid Periksa .env dan pastikan key aktif.
redis.exceptions.ConnectionError Redis tidak berjalan Pastikan redis-server aktif atau gunakan Docker.
psycopg2.OperationalError Koneksi DB gagal Cek POSTGRES_URL, user/password, dan port.
uvicorn.error.ServerError Port sudah digunakan Gunakan --port 8080 atau matikan proses lain.
JSONDecodeError Body request tidak valid Pastikan format JSON sesuai schema.

Kesimpulan

Anda kini memiliki AI Agent yang:
- Menggunakan LLM (ChatGPT Plus) untuk generasi teks.
- Menyimpan memori percakapan di Redis.
- Menyimpan data historis di PostgreSQL.
- Menyediakan endpoint REST sederhana.

Dengan arsitektur ini, Anda dapat memperluas ke fitur seperti integrasi API eksternal, analisis data, atau deployment ke cloud provider. Selamat mencoba!

🏷️ Topik Terkait: