Langsung ke konten
KamusNgoding
Terapan Ai-agent 5 menit baca

Membangun AI Agent Layanan Pelanggan dengan Python: Tutorial Step-by-Step

#python #ai agent #applied #chatbot #project

Membangun AI Agent Layanan Pelanggan dengan Python: Tutorial Step-by-Step

Pendahuluan

Bayangkan kamu sedang membangun aplikasi e-commerce seperti Tokopedia atau Shopee — ada ribuan pelanggan yang bertanya setiap hari soal status pesanan, kebijakan pengembalian, atau stok produk. Melayani semua pertanyaan itu secara manual tentu tidak skalabel. Di sinilah AI Agent layanan pelanggan hadir sebagai solusi.

Berbeda dengan chatbot biasa yang hanya mencocokkan kata kunci, AI Agent mampu:

  • Memahami konteks percakapan secara mendalam
  • Memanggil tools eksternal (cek database, kirim email, cari informasi)
  • Membuat keputusan multi-langkah secara mandiri
  • Menangani alur percakapan yang kompleks

Dalam tutorial ini, kita akan membangun AI Agent layanan pelanggan yang bisa menjawab pertanyaan produk, mengecek status pesanan, dan mengeskalasi tiket ke tim manusia — semuanya menggunakan Python dan OpenAI API. Jika kamu belum familiar dengan konsep dasar prompt engineering, ada baiknya membaca Tutorial Menulis Prompt Efektif untuk Pemula terlebih dahulu sebelum melanjutkan.


Konsep Dasar

Arsitektur AI Agent Layanan Pelanggan

Sebuah AI Agent layanan pelanggan terdiri dari beberapa komponen utama:

User Message → Agent Core (LLM) → Tool Selection → Tool Execution → Response
                     ↑                                      ↓
               Memory/Context ←————————————————— Tool Result

Komponen kunci:

  1. LLM Core — Model bahasa (GPT-4, Claude) yang menjadi “otak” agent
  2. Tools/Functions — Aksi yang bisa dilakukan agent (cek order, FAQ lookup, eskalasi)
  3. Memory — Riwayat percakapan agar agent memahami konteks
  4. System Prompt — Instruksi kepribadian dan batasan agent

Pola ReAct untuk Customer Service

Agent kita menggunakan pola Reason + Act: agent berpikir terlebih dahulu sebelum mengambil aksi. Misalnya:

User: "Pesanan saya #12345 belum sampai"

Agent thinks: "Pelanggan ingin tahu status pesanan → perlu panggil tool check_order_status"
Agent acts: check_order_status(order_id="12345")
Agent responds: "Pesanan #12345 sedang dalam proses pengiriman, estimasi tiba besok."

Contoh Kode

Setup Project

Pertama, install dependensi yang dibutuhkan:

pip install openai python-dotenv

Buat file .env:

OPENAI_API_KEY=sk-your-api-key-here

Struktur file project kita:

customer-service-agent/
├── .env
├── tools.py
├── tool_schemas.py
├── agent.py
└── main.py

Definisi Tools

Tools adalah fungsi Python yang bisa dipanggil oleh agent. Kita buat tiga tools utama:

# tools.py
import json
from datetime import datetime, timedelta
import random

# Simulasi database pesanan
ORDER_DATABASE = {
    "12345": {"status": "Dalam Pengiriman", "estimasi": "Besok", "produk": "Laptop Gaming X"},
    "67890": {"status": "Selesai", "estimasi": None, "produk": "Mouse Wireless Y"},
    "11111": {"status": "Diproses", "estimasi": "3 hari lagi", "produk": "Keyboard Mechanical Z"},
}

# Simulasi FAQ database
FAQ_DATABASE = {
    "pengembalian": "Produk dapat dikembalikan dalam 7 hari sejak diterima dengan kondisi original.",
    "garansi": "Semua produk elektronik mendapat garansi resmi 1 tahun dari produsen.",
    "pembayaran": "Kami menerima transfer bank, kartu kredit, QRIS, dan dompet digital.",
    "pengiriman": "Pengiriman tersedia ke seluruh Indonesia dengan JNE, Sicepat, dan Anteraja.",
}

def check_order_status(order_id: str) -> str:
    """Mengecek status pesanan berdasarkan ID"""
    order = ORDER_DATABASE.get(order_id)
    if not order:
        return json.dumps({
            "success": False,
            "message": f"Pesanan dengan ID {order_id} tidak ditemukan."
        })

    result = {
        "success": True,
        "order_id": order_id,
        "produk": order["produk"],
        "status": order["status"],
        "estimasi_tiba": order["estimasi"] or "Sudah selesai"
    }
    return json.dumps(result, ensure_ascii=False)


def get_faq_answer(topik: str) -> str:
    """Mengambil jawaban FAQ berdasarkan topik"""
    topik_lower = topik.lower()

    # Cari topik yang paling relevan
    for key, answer in FAQ_DATABASE.items():
        if key in topik_lower or topik_lower in key:
            return json.dumps({
                "success": True,
                "topik": key,
                "jawaban": answer
            }, ensure_ascii=False)

    return json.dumps({
        "success": False,
        "message": "Informasi tidak ditemukan. Akan dieskalasi ke tim support."
    })


def escalate_to_human(alasan: str, prioritas: str = "normal") -> str:
    """Mengeskalasi percakapan ke agen manusia"""
    ticket_id = f"TKT-{random.randint(10000, 99999)}"
    return json.dumps({
        "success": True,
        "ticket_id": ticket_id,
        "alasan": alasan,
        "prioritas": prioritas,
        "estimasi_respon": "2-4 jam kerja",
        "pesan": f"Tiket {ticket_id} telah dibuat dan tim kami akan menghubungi kamu segera."
    }, ensure_ascii=False)

Definisi Tool Schema untuk OpenAI

# tool_schemas.py

TOOLS = [
    {
        "type": "function",
        "function": {
            "name": "check_order_status",
            "description": "Mengecek status pesanan pelanggan berdasarkan nomor order ID",
            "parameters": {
                "type": "object",
                "properties": {
                    "order_id": {
                        "type": "string",
                        "description": "Nomor ID pesanan, contoh: 12345"
                    }
                },
                "required": ["order_id"]
            }
        }
    },
    {
        "type": "function",
        "function": {
            "name": "get_faq_answer",
            "description": "Mengambil jawaban untuk pertanyaan umum tentang kebijakan toko",
            "parameters": {
                "type": "object",
                "properties": {
                    "topik": {
                        "type": "string",
                        "description": "Topik pertanyaan, contoh: pengembalian, garansi, pembayaran, pengiriman"
                    }
                },
                "required": ["topik"]
            }
        }
    },
    {
        "type": "function",
        "function": {
            "name": "escalate_to_human",
            "description": "Mengeskalasi masalah yang tidak bisa diselesaikan AI ke agen manusia",
            "parameters": {
                "type": "object",
                "properties": {
                    "alasan": {
                        "type": "string",
                        "description": "Alasan eskalasi dan ringkasan masalah pelanggan"
                    },
                    "prioritas": {
                        "type": "string",
                        "enum": ["rendah", "normal", "tinggi", "urgent"],
                        "description": "Tingkat urgensi masalah"
                    }
                },
                "required": ["alasan"]
            }
        }
    }
]

Core Agent dengan Agentic Loop

Ini adalah inti dari sistem kita. Fungsi run_agent menjalankan agentic loop — agent terus berputar memanggil tools sampai menghasilkan respons final untuk pelanggan:

# agent.py
import json
import os
from openai import OpenAI
from dotenv import load_dotenv
from tool_schemas import TOOLS
from tools import check_order_status, get_faq_answer, escalate_to_human

load_dotenv()

client = OpenAI(api_key=os.getenv("OPENAI_API_KEY"))

SYSTEM_PROMPT = """Kamu adalah Kaka, asisten layanan pelanggan yang ramah dan profesional
untuk toko elektronik online KamusShop.

KEMAMPUANMU:
- Mengecek status pesanan pelanggan
- Menjawab pertanyaan seputar kebijakan toko (pengembalian, garansi, pembayaran, pengiriman)
- Mengeskalasi masalah kompleks ke tim manusia

PANDUAN PERILAKU:
1. Selalu sapa pelanggan dengan ramah dan gunakan bahasa Indonesia yang sopan
2. Jika pelanggan memberikan nomor pesanan, langsung cek statusnya
3. Untuk pertanyaan yang tidak bisa kamu jawab, eskalasi ke tim manusia
4. Jaga percakapan tetap fokus dan efisien
5. Akhiri setiap percakapan dengan tawaran bantuan lebih lanjut

JANGAN:
- Memberikan informasi yang tidak akurat
- Berjanji hal-hal di luar kewenanganmu
- Mendiskusikan topik di luar layanan pelanggan
"""

# Mapping nama fungsi ke fungsi Python
TOOL_FUNCTIONS = {
    "check_order_status": check_order_status,
    "get_faq_answer": get_faq_answer,
    "escalate_to_human": escalate_to_human,
}

MAX_ITERATIONS = 10  # Batas maksimal iterasi untuk mencegah infinite loop

def run_agent(user_message: str, conversation_history: list) -> tuple[str, list]:
    """
    Menjalankan agent untuk satu giliran percakapan.

    Args:
        user_message: Pesan dari pelanggan
        conversation_history: Riwayat percakapan sebelumnya

    Returns:
        tuple: (response_text, updated_history)
    """
    # Tambah pesan user ke history
    conversation_history.append({
        "role": "user",
        "content": user_message
    })

    messages = [{"role": "system", "content": SYSTEM_PROMPT}] + conversation_history

    iteration = 0

    # Agentic loop — agent terus berjalan sampai memberikan respons final
    while iteration < MAX_ITERATIONS:
        iteration += 1

        response = client.chat.completions.create(
            model="gpt-4o-mini",
            messages=messages,
            tools=TOOLS,
            tool_choice="auto",
            temperature=0.3  # Rendah untuk konsistensi customer service
        )

        message = response.choices[0].message

        # Jika tidak ada tool call, agent sudah punya respons final
        if not message.tool_calls:
            final_response = message.content
            conversation_history.append({
                "role": "assistant",
                "content": final_response
            })
            return final_response, conversation_history

        # Tambahkan respons agent (beserta tool calls) ke messages
        messages.append(message)

        # Proses semua tool calls dalam satu giliran
        for tool_call in message.tool_calls:
            function_name = tool_call.function.name
            function_args = json.loads(tool_call.function.arguments)

            print(f"  [Agent memanggil: {function_name}({function_args})]")

            # Eksekusi tool yang dipilih agent
            if function_name in TOOL_FUNCTIONS:
                tool_result = TOOL_FUNCTIONS[function_name](**function_args)
            else:
                tool_result = json.dumps({"error": f"Tool {function_name} tidak ditemukan"})

            # Tambahkan hasil tool ke messages agar agent bisa memprosesnya
            messages.append({
                "role": "tool",
                "tool_call_id": tool_call.id,
                "content": tool_result
            })

    # Jika mencapai batas iterasi, kembalikan pesan fallback
    fallback = "Maaf, terjadi kendala teknis saat memproses permintaan kamu. Tim kami akan segera menghubungi untuk membantu lebih lanjut."
    conversation_history.append({"role": "assistant", "content": fallback})
    return fallback, conversation_history

Interface Percakapan

# main.py
from agent import run_agent

def main():
    print("=" * 50)
    print("  KamusShop - Layanan Pelanggan AI")
    print("  Ketik 'keluar' untuk mengakhiri sesi")
    print("=" * 50)
    print()

    conversation_history = []

    # Sapaan pembuka
    print("Kaka: Halo! Selamat datang di KamusShop. Saya Kaka, asisten virtual kamu.")
    print("Kaka: Ada yang bisa saya bantu hari ini?\n")

    while True:
        user_input = input("Kamu: ").strip()

        if not user_input:
            continue

        if user_input.lower() in ["keluar", "exit", "quit"]:
            print("\nKaka: Terima kasih sudah menghubungi KamusShop. Sampai jumpa!")
            break

        print()
        response, conversation_history = run_agent(user_input, conversation_history)
        print(f"Kaka: {response}\n")

if __name__ == "__main__":
    main()

Contoh Output Interaksi

Jalankan agent dengan perintah python main.py, lalu coba beberapa skenario berikut:

Skenario 1 — Cek status pesanan:

==================================================
  KamusShop - Layanan Pelanggan AI
  Ketik 'keluar' untuk mengakhiri sesi
==================================================

Kaka: Halo! Selamat datang di KamusShop. Saya Kaka, asisten virtual kamu.
Kaka: Ada yang bisa saya bantu hari ini?

Kamu: Halo, pesanan saya 12345 belum sampai nih

  [Agent memanggil: check_order_status({'order_id': '12345'})]

Kaka: Halo! Saya sudah cek pesanan kamu ya.

Pesanan #12345 (Laptop Gaming X) saat ini sedang **Dalam Pengiriman**
dan diperkirakan tiba **besok**.

Jika besok pesanan belum tiba, jangan ragu untuk menghubungi kami lagi
dan saya akan bantu proses penyelidikannya. Ada yang bisa saya bantu lagi?

Skenario 2 — Pertanyaan kebijakan:

Kamu: Kalau mau retur gimana caranya?

  [Agent memanggil: get_faq_answer({'topik': 'pengembalian'})]

Kaka: Untuk pengembalian produk di KamusShop, berikut ketentuannya:

Produk dapat dikembalikan dalam **7 hari sejak diterima** dengan kondisi
original (tidak rusak, kelengkapan masih ada, kemasan masih baik).

Apakah ada pertanyaan lain yang bisa saya bantu?

Skenario 3 — Eskalasi ke manusia:

Kamu: Saya mau komplain, produk yang datang cacat dan sudah lewat 7 hari

  [Agent memanggil: escalate_to_human({'alasan': 'Pelanggan menerima produk cacat
  dan sudah melewati batas waktu pengembalian normal 7 hari', 'prioritas': 'tinggi'})]

Kaka: Saya sangat menyesal mendengar produk yang kamu terima dalam kondisi cacat.
Untuk kasus seperti ini, saya akan langsung eskalasi ke tim senior kami.

Tiket **TKT-47823** telah dibuat dengan prioritas **tinggi**. Tim kami akan
menghubungi kamu dalam **2-4 jam kerja** untuk menyelesaikan masalah ini.

Terima kasih atas kesabaranmu, dan kami pastikan masalah ini ditangani dengan baik.

Troubleshooting: Error yang Sering Muncul

openai.AuthenticationError: Incorrect API key

Penyebab: API key tidak terbaca dari environment variable, bisa karena file .env tidak ada, nama variabel salah, atau load_dotenv() dipanggil setelah os.getenv().

Solusi:

# Pastikan load_dotenv() dipanggil SEBELUM os.getenv()
from dotenv import load_dotenv
import os

load_dotenv()  # Harus dipanggil lebih dulu!

api_key = os.getenv("OPENAI_API_KEY")
if not api_key:
    raise ValueError("OPENAI_API_KEY tidak ditemukan. Periksa file .env kamu.")

print(f"API key loaded: {'Yes' if api_key else 'No'}")  # Debug check

Pastikan juga isi file .env tidak mengandung spasi di sekitar tanda =:

# Benar:
OPENAI_API_KEY=sk-proj-xxxxx

# Salah (ada spasi):
OPENAI_API_KEY = sk-proj-xxxxx

json.JSONDecodeError saat Parsing Tool Arguments

Penyebab: Model kadang menghasilkan JSON yang tidak valid untuk argumen tool, terutama pada input yang mengandung karakter khusus atau tanda kutip.

Solusi:

import json

def safe_parse_args(raw_args: str) -> dict:
    try:
        return json.loads(raw_args)
    except json.JSONDecodeError as e:
        print(f"Warning: Gagal parse tool args: {e}")
        print(f"Raw args: {raw_args}")
        # Fallback: kembalikan dict kosong agar agent bisa melanjutkan
        return {}

# Gunakan di dalam agentic loop:
for tool_call in message.tool_calls:
    function_args = safe_parse_args(tool_call.function.arguments)
    # ... lanjutkan eksekusi tool

Agent Masuk Infinite Loop (Tool Terus Dipanggil)

Penyebab: Jika tool selalu mengembalikan error atau respons ambigu, agent bisa terus memanggil tool tanpa menghasilkan respons akhir untuk pengguna.

Solusi:

Kita sudah menambahkan MAX_ITERATIONS = 10 di agent.py. Pastikan batas ini ada dan tampilkan log iterasi untuk debugging:

MAX_ITERATIONS = 10

while iteration < MAX_ITERATIONS:
    iteration += 1
    print(f"  [Iterasi {iteration}/{MAX_ITERATIONS}]")  # Untuk debugging

    response = client.chat.completions.create(...)
    message = response.choices[0].message

    if not message.tool_calls:
        break  # Respons final ditemukan, keluar dari loop

    # ... proses tool calls

# Tangani kasus batas iterasi terlampaui
if iteration >= MAX_ITERATIONS:
    print("Warning: Agent mencapai batas iterasi maksimal!")
    return "Maaf, terjadi kendala teknis. Tim kami akan menghubungi kamu.", conversation_history

RateLimitError: Rate limit reached

Penyebab: Terlalu banyak request dalam waktu singkat, umum terjadi saat testing agent dalam volume tinggi atau menggunakan tier API gratis.

Solusi:

import time
from openai import RateLimitError

def run_agent_with_retry(
    user_message: str,
    conversation_history: list,
    max_retries: int = 3
) -> tuple[str, list]:
    """Wrapper run_agent dengan exponential backoff untuk rate limit."""
    for attempt in range(max_retries):
        try:
            return run_agent(user_message, conversation_history)
        except RateLimitError as e:
            if attempt < max_retries - 1:
                wait_time = 2 ** attempt  # Exponential backoff: 1s, 2s, 4s
                print(f"Rate limit tercapai. Menunggu {wait_time} detik... (percobaan {attempt + 1}/{max_retries})")
                time.sleep(wait_time)
            else:
                print("Rate limit: semua percobaan gagal.")
                raise

KeyError saat Mengakses Tool Result

Penyebab: Fungsi tool mengembalikan JSON dengan struktur yang tidak sesuai ekspektasi, misalnya karena refactor atau perubahan schema response.

Solusi:

import json

def check_order_status_safe(order_id: str) -> str:
    """Versi defensif check_order_status dengan validasi output."""
    try:
        result = check_order_status(order_id)
        # Pastikan JSON valid sebelum dikembalikan ke agent
        parsed = json.loads(result)
        assert "success" in parsed  # Field wajib harus ada
        return result
    except (json.JSONDecodeError, AssertionError, Exception) as e:
        # Fallback response yang tetap valid
        return json.dumps({
            "success": False,
            "message": f"Gagal mengambil data pesanan: {str(e)}"
        })

Pertanyaan yang Sering Diajukan

Apa perbedaan AI Agent layanan pelanggan dengan chatbot biasa?

Chatbot konvensional bekerja berdasarkan aturan if-else atau pencocokan kata kunci yang statis. AI Agent, sebaliknya, menggunakan LLM sebagai “otak” yang bisa bernalar, memanggil tools secara dinamis, dan menangani percakapan multi-langkah yang kompleks tanpa perlu script yang ditulis manual untuk setiap skenario.

Bagaimana cara menambahkan tool baru ke agent?

Cukup dua langkah: (1) buat fungsi Python baru di tools.py dengan logika yang diinginkan, lalu (2) tambahkan schema JSON-nya ke list TOOLS di tool_schemas.py. Agent akan otomatis bisa menggunakan tool baru tersebut berdasarkan deskripsi yang kamu tulis di schema — tidak perlu mengubah kode agent.py sama sekali.

Apakah agent ini aman untuk dipakai di produksi?

Untuk produksi, kamu perlu menambahkan beberapa hal: autentikasi pelanggan sebelum mengakses data sensitif, validasi input yang ketat di setiap tool, logging percakapan untuk keperluan audit, serta guardrail untuk mencegah prompt injection. Implementasi di tutorial ini adalah titik awal yang solid, namun perlu diperkuat keamanannya sebelum menghadapi traffic nyata.

Bagaimana cara menyimpan riwayat percakapan agar persisten?

Pada tutorial ini, conversation_history disimpan di memori (RAM) dan hilang saat program ditutup. Untuk persistensi, simpan history ke database seperti SQLite atau Redis dengan session ID sebagai key. Setiap kali sesi dibuka, muat kembali history berdasarkan ID pengguna. Kamu juga bisa mempelajari Memahami Arsitektur LLM dan Cara Kerjanya untuk memahami bagaimana model bahasa memproses konteks percakapan.

Berapa biaya API yang dibutuhkan untuk agent ini?

Dengan model gpt-4o-mini, biaya per percakapan sangat terjangkau — sekitar $0.0001–$0.001 per sesi tergantung panjang percakapan. Untuk volume tinggi, pertimbangkan caching respons untuk pertanyaan yang sering berulang, batasi panjang conversation_history yang dikirim ke API, atau eksplorasi model open-source yang bisa di-deploy sendiri.


Kesimpulan

Kita telah berhasil membangun AI Agent layanan pelanggan yang fungsional dari nol menggunakan Python. Agent ini mampu mengecek status pesanan, menjawab FAQ, hingga mengeskalasi tiket ke tim manusia — semua dengan cara yang terasa natural bagi pelanggan, berkat agentic loop yang kita implementasikan di agent.py.

Kunci keberhasilan agent layanan pelanggan terletak pada tiga hal: tools yang dirancang dengan baik, system prompt yang jelas dan terarah, serta penanganan error yang robust. Dari sini, kamu bisa mengembangkannya lebih jauh: integrasikan dengan database nyata, tambahkan autentikasi pelanggan, atau hubungkan ke platform chat seperti WhatsApp Business API — jika kamu ingin membangun sistem seperti yang digunakan aplikasi super-app besar.

Selamat bereksperimen dan terus kembangkan project-mu! Jika ada pertanyaan atau kamu ingin mengeksplorasi topik AI lainnya, jangan ragu untuk menjelajahi artikel-artikel lain di KamusNgoding — kita belajar bersama, satu baris kode setiap harinya.

Artikel Terkait