# AI Agents


## Ringkasan

**AI Agent** adalah bot percakapan otomatis yang ditenagai model bahasa besar (LLM). Saat diaktifkan untuk kanal atau divisi tertentu, AI Agent akan membalas pesan masuk secara otomatis — tanpa menunggu agent manusia — menggunakan konteks dari knowledge base yang dikonfigurasi.

AI Agent di OmniStream mendukung tiga provider LLM:

- **OpenAI** — GPT-4o, GPT-4o Mini, GPT-4.1, GPT-4.1 Mini, GPT-4.1 Nano
- **Anthropic** — Claude Sonnet 4, Claude Haiku 4
- **Google** — Gemini 2.5 Flash, Gemini 2.5 Pro

:::info
**Hak akses:** Membuat, mengonfigurasi, dan menghapus AI Agent memerlukan izin `settings.manage` — hanya tersedia untuk **admin**. Supervisor dan agent dapat melihat daftar agent tetapi tidak dapat mengubah konfigurasi.
:::

## Cara kerja

```
Pesan masuk (WhatsApp / Instagram / Email)
          ↓
Sistem menyimpan pesan dan memicu AI Agent
          ↓
Jika ada assignment yang cocok (channel / division):
  1. Cek saldo AI token (billing) — jika kosong → handoff
  2. Cek daily_token_limit — jika tercapai → handoff
  3. Cek max_conversation_turns — jika tercapai → handoff
  4. Bangun konteks: system_prompt + ringkasan + 10 pesan terakhir + RAG
  5. Panggil LLM (OpenAI / Anthropic / Gemini sesuai model)
  6. Catat pemakaian token dan kurangi saldo
  7. Evaluasi handoff rules → jika terpicu, serahkan ke agen manusia
  8. Simpan balasan dan kirimkan ke pelanggan
  9. Setiap 10 pesan → buat ringkasan otomatis (context windowing)
```

RAG (Retrieval-Augmented Generation) aktif jika knowledge sources sudah diproses — vektor disimpan di Qdrant dan di-query setiap kali ada pesan masuk.

## Prasyarat

Sebelum AI Agent dapat beroperasi:

1. **API key LLM dikonfigurasi** di server oleh administrator — pastikan telah menghubungi administrator untuk mengaktifkan provider yang diinginkan (OpenAI, Anthropic, atau Google Gemini).
2. **Saldo AI token tersedia** — AI Agent menggunakan sistem billing berbasis token. Saldo diukur dalam IDR dan dikurangi per panggilan LLM. Isi saldo di halaman **Billing → AI Balance** sebelum mengaktifkan agent.
3. **Percakapan sudah ada** — AI Agent hanya membalas percakapan yang masuk melalui kanal yang di-assign. Percakapan baru yang tidak ter-assign ke divisi manapun tidak akan dijangkau.

:::warning
Jika saldo AI token habis, sistem akan langsung trigger handoff ke agen manusia dan berhenti membalas. Pantau saldo secara berkala di **Billing → AI Balance**.
:::

## Membuat AI Agent

1. Buka menu **AI Agents** (`/ai-agents`).
2. Klik **Create Agent**.
3. Isi form:
   - **Name** — nama unik untuk agent ini (wajib).
   - **Model** — pilih model LLM dari daftar.
4. Klik **Create**. Frontend langsung mengarahkan ke halaman konfigurasi agent.

## Konfigurasi agent (tab General)

Setelah agent dibuat, halaman detail memiliki tujuh tab. Tab **General** adalah titik konfigurasi utama.

### Field konfigurasi utama

| Field | Default | Keterangan |
|---|---|---|
| **Agent Name** | (nama saat buat) | Label agent di daftar |
| **System Prompt** | `""` | Instruksi kepribadian dan peran AI; maks 15.000 karakter |
| **Welcome Message** | `null` | Pesan sambutan saat AI memulai percakapan baru; maks 2.000 karakter |
| **Agent Transfer Conditions** | `""` | Deskripsi kondisi untuk transfer ke agen manusia (digunakan sebagai panduan — handoff rules di tab terpisah yang menjalankan logikanya) |
| **AI Model** | `gpt-4o-mini` | Provider dan versi model LLM |
| **Stop AI after Handoff** | `true` | Nonaktifkan AI setelah percakapan diserahkan ke manusia |

### Additional Settings (expandable)

| Field | Default | Keterangan |
|---|---|---|
| **Temperature** | `0.7` | Kreativitas respons (0 = deterministik, 2 = sangat kreatif) |
| **Max Tokens** | `1024` | Batas panjang tiap respons AI (per panggilan) |
| **Daily Token Limit** | `null` (tanpa batas) | Batas total token yang dipakai agent per hari; jika tercapai, handoff otomatis |
| **Max Conversation Turns** | `null` (tanpa batas) | Batas jumlah giliran dalam satu percakapan; jika tercapai, handoff otomatis |

Klik **Save AI Settings** untuk menyimpan perubahan.

### Test Chat (panel kanan)

Panel **Test Chat** (hanya muncul di layar lebar) memungkinkan admin menguji respons agent secara langsung dari browser tanpa percakapan nyata. Riwayat test tidak disimpan ke database percakapan. Panggilan test tetap mengurangi saldo token.

## Tab Assignments

**Assignment** menentukan kanal atau divisi mana yang akan dijangkau agent ini. Tanpa assignment, agent tidak akan pernah aktif di percakapan manapun.

| Field | Keterangan |
|---|---|
| **Channel** | Salah satu: `whatsapp`, `instagram`, `email`, `messenger`. Kosongkan untuk semua kanal |
| **Division** | Pilih divisi target; kosongkan untuk semua divisi |
| **Priority** | Angka integer — assignment dengan priority lebih tinggi dipilih lebih dulu |

Assignment yang sama (kombinasi channel + division) tidak dapat diduplikasi. Jika ada konflik, backend mengembalikan error validasi.

Matching dilakukan dengan logika: channel+division spesifik diprioritaskan di atas yang lebih umum.

## Tab Knowledge Sources

Knowledge source memungkinkan AI menjawab pertanyaan berdasarkan konten yang telah di-index. Ada lima sub-tipe:

| Sub-tipe | Keterangan |
|---|---|
| **Text** | Teks bebas yang langsung diketik; bisa memiliki beberapa entri bernama |
| **Website** | URL yang akan di-crawl dan di-chunk (maks ~300 link per domain) |
| **File** | Upload file PDF (format lain belum didukung) |
| **Q&A** | Pasangan pertanyaan–jawaban terstruktur |
| **Product** | Katalog produk dengan nama, deskripsi, harga, berat, thumbnail, dan gambar |

Setelah source ditambahkan, statusnya menjadi `pending` → `processing` → `ready` (atau `failed`). Hanya source dengan status `ready` yang aktif di-query saat RAG berlangsung. Gunakan tombol **Reprocess** jika indexing gagal.

:::tip
Untuk knowledge tipe **Text**, klik **Save Knowledge** secara eksplisit setelah mengedit konten — perubahan teks tidak tersimpan otomatis.
:::

## Tab Handoff Rules

Handoff rule mendefinisikan kondisi untuk menyerahkan percakapan ke agen manusia. Enam tipe rule tersedia:

| Tipe | Cara kerja |
|---|---|
| `keyword` | Handoff jika pesan pelanggan mengandung kata kunci tertentu (konfigurasi: `{"keywords": ["refund", "batal"]}`) |
| `message_count` | Handoff setelah N pesan dalam percakapan (konfigurasi: `{"threshold": 20}`) |
| `explicit_request` | Handoff jika pelanggan meminta berbicara dengan manusia — frasa bahasa Indonesia dan Inggris dikenali otomatis (mis. "bicara dengan agen", "talk to human") |
| `sentiment` | Dikenali oleh konfigurasi; evaluasi aktif di processor |
| `location` | Dikenali oleh konfigurasi; evaluasi aktif di processor |
| `topic` | Dikenali oleh konfigurasi; evaluasi aktif di processor |

Setiap rule memiliki opsi:
- **Target Division** — divisi yang menerima percakapan saat handoff. Kosong = tidak di-route ke divisi tertentu.
- **Stop AI after Handoff** — default `true`; AI berhenti membalas setelah handoff.

:::note
Rule tipe `keyword`, `message_count`, dan `explicit_request` sudah diimplementasikan penuh di `ai-agent/src/processor.rs`. Tipe `sentiment`, `location`, dan `topic` tersimpan di database dan tersedia untuk dikonfigurasi, tetapi evaluasinya dalam processor belum aktif (menunggu implementasi).
:::

## Tab Orchestration

Orchestration memungkinkan satu agent **parent** mendelegasikan percakapan ke agent **child** berdasarkan kondisi tertentu. Gunakan ini jika organisasi memiliki beberapa spesialisasi (mis. agent umum → agent produk → agent billing).

| Field | Keterangan |
|---|---|
| **Target Agent** | Agent tujuan (dipilih dari daftar agent lain yang ada) |
| **Condition Prompt** | Deskripsi kondisi dalam bahasa natural (mis. "Pertanyaan tentang harga atau pembelian") |
| **Priority** | Urutan evaluasi rule; lebih tinggi = dievaluasi lebih dulu |

Orchestration rules disimpan di tabel `ai_orchestration_rules` dengan relasi `parent_agent_id → target_agent_id`.

## Tab Evaluations

Tab Evaluations menampilkan daftar koreksi yang pernah dibuat supervisor atau admin terhadap respons AI. Setiap entri menyimpan respons asli, respons yang dikoreksi, dan pesan konteks yang relevan.

Untuk membuat evaluasi baru, gunakan endpoint `POST /api/ai/evaluate` dengan menyertakan `conversation_id`, `message_id`, `original_response`, dan `corrected_response`.

## Tab Usage

Menampilkan pemakaian token harian untuk agent ini: prompt tokens, completion tokens, total tokens, estimasi biaya (USD), dan jumlah request. Data diambil dari tabel `ai_usage_logs` yang diisi setiap kali agent memanggil LLM.

Filter tanggal tersedia via parameter `from` dan `to` di endpoint `GET /api/ai-agents/{id}/usage`.

## Mengaktifkan / menonaktifkan agent

Dari halaman daftar `/ai-agents`, klik tombol **Active / Inactive** di baris agent untuk toggle status tanpa masuk ke halaman konfigurasi. Agent yang `is_active = false` tidak akan dipilih oleh sistem assignment meskipun ada assignment yang cocok.

## Saldo AI Token

Setiap panggilan LLM mengurangi saldo tenant dalam IDR. Deduction dihitung berdasarkan tabel harga yang dikonfigurasi di control plane (`ai_pricing_config`) dengan markup dan nilai tukar. Jika saldo mencapai nol, semua percakapan yang dijangkau agent tersebut akan otomatis di-handoff ke agen manusia.

Isi saldo di **Billing → AI Balance** (`/billing/ai-balance`). Minimal top-up Rp 10.000.

## Endpoint (tag **AI Agents**)

| Aksi | Endpoint |
|---|---|
| List agent | `GET /api/ai-agents` |
| Buat agent | `POST /api/ai-agents` |
| Detail agent | `GET /api/ai-agents/{id}` |
| Update agent | `PUT /api/ai-agents/{id}` |
| Hapus agent | `DELETE /api/ai-agents/{id}` |
| Toggle aktif | `PUT /api/ai-agents/{id}/toggle` |
| List assignments | `GET /api/ai-agents/{id}/assignments` |
| Buat assignment | `POST /api/ai-agents/{id}/assignments` |
| Update assignment | `PUT /api/ai-agents/{id}/assignments/{aid}` |
| Hapus assignment | `DELETE /api/ai-agents/{id}/assignments/{aid}` |
| List knowledge sources | `GET /api/ai-agents/{id}/knowledge` |
| Buat knowledge source | `POST /api/ai-agents/{id}/knowledge` |
| Hapus knowledge source | `DELETE /api/ai-agents/{id}/knowledge/{kid}` |
| Reprocess knowledge source | `POST /api/ai-agents/{id}/knowledge/{kid}/reprocess` |
| List Q&A | `GET /api/ai-agents/{id}/knowledge/{kid}/qna` |
| Buat Q&A | `POST /api/ai-agents/{id}/knowledge/{kid}/qna` |
| Hapus Q&A | `DELETE /api/ai-agents/{id}/knowledge/{kid}/qna/{qid}` |
| List produk | `GET /api/ai-agents/{id}/products` |
| Buat produk | `POST /api/ai-agents/{id}/products` |
| Update produk | `PUT /api/ai-agents/{id}/products/{pid}` |
| Hapus produk | `DELETE /api/ai-agents/{id}/products/{pid}` |
| Import produk (bulk) | `POST /api/ai-agents/{id}/products/import` |
| List handoff rules | `GET /api/ai-agents/{id}/handoff-rules` |
| Buat handoff rule | `POST /api/ai-agents/{id}/handoff-rules` |
| Update handoff rule | `PUT /api/ai-agents/{id}/handoff-rules/{hid}` |
| Hapus handoff rule | `DELETE /api/ai-agents/{id}/handoff-rules/{hid}` |
| List orchestration rules | `GET /api/ai-agents/{id}/orchestration` |
| Buat orchestration rule | `POST /api/ai-agents/{id}/orchestration` |
| Update orchestration rule | `PUT /api/ai-agents/{id}/orchestration/{rid}` |
| Hapus orchestration rule | `DELETE /api/ai-agents/{id}/orchestration/{rid}` |
| Usage harian (per agent) | `GET /api/ai-agents/{id}/usage` |
| Usage agregat (semua agent) | `GET /api/ai/usage/summary` |
| Test chat | `POST /api/ai/test-chat` |
| List evaluations | `GET /api/ai-agents/{id}/evaluations` |
| Buat evaluation | `POST /api/ai/evaluate` |
| Update evaluation | `PUT /api/ai/evaluate/{eid}` |
| Hapus evaluation | `DELETE /api/ai/evaluate/{eid}` |

Skema lengkap di [API Reference](/api).

## Praktik terbaik

- **Mulai dengan system prompt yang spesifik** — jelaskan peran, batasan topik, dan gaya bahasa. Prompt yang terlalu umum menghasilkan respons yang kurang relevan.
- **Gunakan `daily_token_limit`** untuk mengontrol pengeluaran per agent, terutama saat baru pertama mencoba.
- **Isi knowledge source sebelum mengaktifkan assignment** — agent tanpa knowledge source akan menjawab hanya dari system prompt, tanpa konteks bisnis.
- **Buat handoff rule `explicit_request` selalu ada** — pelanggan yang ingin berbicara dengan manusia harus bisa dilayani.
- **Pantau tab Usage** setelah peluncuran — spike token yang tidak wajar bisa menandakan prompt loop atau knowledge source yang menghasilkan konteks terlalu panjang.
- **Satu agent per use case utama** — jangan mencampur logika CS, sales, dan technical support dalam satu system prompt; gunakan orchestration rules untuk routing.

## Rute terkait

- [Manajemen Divisi](/panduan/admin/divisi) — divisi sebagai target assignment dan handoff
- [Kebijakan SLA](/panduan/admin/kebijakan-sla) — SLA tetap berlaku meski percakapan ditangani AI
- [Activity Logs](/panduan/admin/activity-logs) — semua perubahan konfigurasi AI Agent dicatat
