Membuat AI Agent yang Bisa Membuka Website dan Mengisi Form

Membuat AI Agent yang Bisa Membuka Website dan Mengisi Form

Pendahuluan

Otomasi tugas web repetitif seperti mengisi formulir pendaftaran, login, atau data entry adalah salah satu use case paling praktis dari AI Agent. Tutorial ini membahas arsitektur dan implementasi AI Agent otonom yang mampu:
1. Menavigasi ke URL target.
2. Mengidentifikasi elemen form (input, select, button) menggunakan DOM.
3. Mengambil instruksi dari Large Language Model (LLM) untuk menentukan nilai input.
4. Mengeksekusi interaksi (klik, ketik, submit) secara programatik.

Arsitektur yang digunakan bersifat modular: Playwright sebagai browser automation engine, LLM API sebagai "otak" decision-making, dan Python sebagai orkestrator.

Prasyarat & Persiapan

Sebelum memulai, pastikan lingkungan pengembangan Anda memenuhi syarat berikut:

  1. Python 3.10+: Versi minimal untuk dukungan type hints modern.
  2. Node.js: Diperlukan oleh Playwright untuk menjalankan browser.
  3. API Key LLM: Anda memerlukan akses ke API LLM. Kami merekomendasikan penggunaan ChatGPT Plus atau Claude Pro untuk mendapatkan akses API dengan limit yang memadai. Jika Anda lebih memilih model multimodal untuk analisis screenshot, Gemini Advanced juga merupakan pilihan yang kuat.
  4. Paket Python:
  5. playwright: Untuk kontrol browser.
  6. openai atau anthropic: Client API LLM.
  7. pydantic: Untuk validasi struktur data.

Instalasi Dependensi

Jalankan perintah berikut di terminal:

# Buat virtual environment
python -m venv ai-agent-env
source ai-agent-env/bin/activate  # Linux/Mac
# ai-agent-env\Scripts\activate  # Windows

# Install paket
pip install playwright openai anthropic pydantic
playwright install chromium

Langkah Demi Langkah

Step 1: Inisialisasi Browser & Navigasi

Kita akan menggunakan Playwright untuk membuka browser headless. Mode headless diperlukan untuk eksekusi di server/VPS tanpa antarmuka grafis.

import asyncio
from playwright.async_api import async_playwright

async def init_browser():
    async with async_playwright() as p:
        browser = await p.chromium.launch(headless=True)
        context = await browser.new_context()
        page = await context.new_page()
        return browser, context, page

# Contoh penggunaan
# browser, context, page = await init_browser()
# await page.goto("https://example.com/register")

Step 2: Ekstraksi Struktur Form

Agent perlu memahami struktur halaman. Kita akan mengekstrak semua elemen interaktif dan metadata-nya.

async def extract_form_elements(page):
    """
    Mengekstrak elemen form dari halaman web.
    """
    elements = []

    # Cari semua input, select, dan button
    selectors = [
        "input[type='text']",
        "input[type='email']",
        "input[type='password']",
        "input[type='number']",
        "select",
        "button[type='submit']",
        "button"
    ]

    for selector in selectors:
        locators = await page.query_selector_all(selector)
        for loc in locators:
            tag = await loc.evaluate("el => el.tagName.toLowerCase()")
            name = await loc.get_attribute("name")
            id_attr = await loc.get_attribute("id")
            placeholder = await loc.get_attribute("placeholder")
            label = await loc.evaluate("""
                el => {
                    const labelEl = document.querySelector(`label[for='${el.id}']`);
                    return labelEl ? labelEl.innerText : '';
                }
            """)

            elements.append({
                "tag": tag,
                "name": name,
                "id": id_attr,
                "placeholder": placeholder,
                "label": label,
                "selector": f"#{id_attr}" if id_attr else f"[name='{name}']"
            })

    return elements

Step 3: Integrasi LLM untuk Decision Making

Ini adalah inti dari "AI Agent". Kita mengirim struktur form ke LLM dan meminta rekomendasi nilai.

import openai
from pydantic import BaseModel

class FormAction(BaseModel):
    selector: str
    action: str  # 'fill', 'click', 'select'
    value: str = None

def get_llm_recommendation(form_elements: list, task_description: str) -> list[FormAction]:
    """
    Mengirim struktur form ke LLM untuk mendapatkan instruksi pengisian.
    """
    client = openai.OpenAI(api_key="YOUR_OPENAI_API_KEY")

    prompt = f"""
    Kamu adalah AI Agent yang bertugas mengisi form web.

    Struktur Form yang tersedia:
    {form_elements}

    Tugas: {task_description}

    Kembalikan daftar aksi dalam format JSON array. 
    Setiap aksi harus memiliki: selector, action ('fill' atau 'click'), dan value (jika fill).
    Jika tidak ada aksi, kembalikan array kosong.
    """

    response = client.chat.completions.create(
        model="gpt-4o",
        messages=[
            {"role": "system", "content": "You are a helpful web automation assistant. Output only valid JSON."},
            {"role": "user", "content": prompt}
        ],
        response_format={"type": "json_object"}
    )

    import json
    data = json.loads(response.choices[0].message.content)
    return [FormAction(**item) for item in data.get("actions", [])]

Step 4: Eksekusi Aksi

Melakukan interaksi dengan elemen berdasarkan rekomendasi LLM.

async def execute_actions(page, actions: list[FormAction]):
    for action in actions:
        try:
            locator = page.locator(action.selector)

            if action.action == "fill":
                await locator.fill(action.value)
                print(f"Filled {action.selector} with: {action.value}")

            elif action.action == "click":
                await locator.click()
                print(f"Clicked {action.selector}")

        except Exception as e:
            print(f"Error executing action on {action.selector}: {e}")

Step 5: Orkestrasi Utama (Main Loop)

Menggabungkan semua komponen menjadi satu alur kerja.

async def main():
    target_url = "https://example.com/contact"
    task = "Isi form kontak dengan nama 'Budi', email 'budi@example.com', dan pesan 'Halo, ini tes otomasi'."

    browser, context, page = await init_browser()

    try:
        # 1. Navigasi
        await page.goto(target_url, wait_until="networkidle")

        # 2. Ekstraksi
        elements = await extract_form_elements(page)
        print("Elements found:", elements)

        # 3. Decision (LLM)
        actions = get_llm_recommendation(elements, task)
        print("Recommended Actions:", actions)

        # 4. Eksekusi
        await execute_actions(page, actions)

        # 5. Verifikasi (Opsional)
        await page.wait_for_timeout(2000)
        screenshot_path = "screenshot_result.png"
        await page.screenshot(path=screenshot_path)
        print(f"Screenshot saved to {screenshot_path}")

    finally:
        await browser.close()

if __name__ == "__main__":
    asyncio.run(main())

Tips Optimasi & Keamanan

  1. Rate Limiting & Anti-Bot:
  2. Website modern sering menggunakan Cloudflare atau Akamai. Tambahkan user_agent yang realistis dan delay acak (await page.wait_for_timeout(random.randint(1000, 3000))) antara aksi untuk menghindari deteksi bot.
  3. Gunakan proxy residential jika target website memiliki proteksi IP yang ketat.

  4. Keamanan Data:

  5. Jangan pernah hardcode kredensial di dalam kode. Gunakan environment variables.
  6. Jika menggunakan Notion AI atau Jasper untuk menyiapkan template pesan, pastikan data sensitif tidak disimpan di log LLM.

  7. Error Handling:

  8. Selalu gunakan try-except di sekitar interaksi elemen. Elemen bisa berubah (ID/Class) sewaktu-waktu.
  9. Implementasi retry logic: jika elemen tidak ditemukan, tunggu 2 detik dan coba lagi.

  10. Monitoring:

  11. Simpan screenshot setiap langkah untuk debugging.
  12. Log setiap keputusan LLM beserta input-nya untuk audit trail.

Troubleshooting Error Umum

Error Penyebab Solusi
TimeoutError Elemen belum ter-render Tambahkan wait_until="domcontentloaded" atau networkidle. Gunakan page.wait_for_selector().
Element not found Selector salah atau elemen dinamis Gunakan page.locator() dengan strategi fallback (misal: cari by text jika by ID gagal).
LLM returns invalid JSON Prompt tidak jelas Perketat prompt system: "Output ONLY valid JSON. No markdown."
Browser crashes Memory leak Tutup browser dengan benar di finally block. Gunakan headless=True untuk mengurangi memori.

Kesimpulan

Membangun AI Agent untuk otomasi web adalah kombinasi antara web scraping (Playwright) dan NLP (LLM). Dengan arsitektur yang benar, Anda dapat mengotomasi tugas repetitif dengan tingkat akurasi tinggi.

Untuk pengembangan lebih lanjut, pertimbangkan:
- Menggunakan Multi-Agent System: Satu agent untuk navigasi, satu untuk validasi data.
- Integrasi dengan RAG (Retrieval-Augmented Generation): Jika form sangat kompleks, gunakan database vektor untuk menyimpan contoh pengisian sebelumnya.
- Deployment ke VPS: Jalankan script ini di server cloud untuk eksekusi 24/7. Anda dapat menggunakan layanan seperti DigitalOcean atau Vultr.

Jika Anda membutuhkan bantuan dalam menulis prompt LLM yang lebih efektif, Anda dapat memanfaatkan Perplexity Pro untuk riset best practices prompt engineering, atau Copy.ai untuk mengoptimalkan template pesan yang akan diisi oleh agent.

🏷️ Topik Terkait: