Loop Panggilan Agent AI Kustom dan Skema Pengendalian Biaya Token Setelah Fase Demo

Computing/Software19 min read

TuBrief Editorial Written with AI assistance from the source video. The video is the authority. Source video: "Build vs Buy" semakin bergeser ke arah "build" · Maximilian Schwarzmüller

Mengambil framework dan membuat AI agent menggunakan data internal perusahaan biasanya berjalan lancar hingga tahap prototipe. Masalah sebenarnya baru dimulai saat kode ini diimplementasikan ke lingkungan production. Agent yang tadinya bekerja dengan baik di dalam layar tiba-tiba terjebak dalam satu input tak terduga, melakukan panggilan berulang tanpa henti, dan menghasilkan tagihan API hingga puluhan juta rupiah dalam kurun waktu akhir pekan.

Sebagian besar gangguan yang terjadi di lapangan bukan disebabkan oleh keterbatasan model LLM itu sendiri, melainkan karena kegagalan manajemen status (state management) dan ketiadaan kontrol eksternal. Kita harus mengakhiri situasi di mana kita membuat tool kustom atas perintah manajemen, tetapi malah menghabiskan seharian hanya untuk melakukan debugging pada hallucination agent yang muncul tiba-tiba serta mengurus tagihan token yang membengkak alih-alih fokus pada pekerjaan utama.


Tiga Rintangan di Lingkungan Production

Setelah keluar dari lingkungan demo, agent akan membentur tiga dinding besar: operasional black box, loop non-deterministik, dan risiko kebocoran data.

Jika input dan output dari setiap tahap proses penalaran (Chain-of-Thought), panggilan tool eksternal (Tool Call), dan pencarian basis data vektor tidak tercatat dalam log, kita tidak akan bisa menemukan penyebabnya saat terjadi masalah. Hanya untuk melacak di mana prompt mengalami kekacauan saja bisa menghabiskan waktu seharian penuh.

Yang lebih serius adalah infinite loop. Agent dengan arsitektur ReAct (Reasoning + Acting) akan terus mengirimkan permintaan yang sama secara berulang jika hasil eksekusi tool bersifat ambigu.

`
┌─────────────────────────────────────────────────────────────────────────┐
│ ReAct Architecture Loop │
│ │
│ ┌────────────┐ User Query ┌────────────┐ Tool Call Request │
│ │ User │ ──────────────> │ Main LLM │ ────────────────────┐ │
│ └────────────┘ └────────────┘ │ │
│ ▲ ▼ │
│ │ Observation ┌──────┐ │
│ │ (Ambiguous/Failed) │ Tool │ │
│ └─────────────────────── │ A │ │
│ └──────┘ │
│ * Problem: When Observation fails, LLM retries Tool A endlessly. │
└─────────────────────────────────────────────────────────────────────────┘

`

Begitu agent gagal keluar dari kondisi berhenti dan terus-menerus memanggil API dengan argumen yang sama, anggaran token bulanan bisa habis hanya dalam beberapa menit. Kegagalan berantai di mana agent utama dan sub-agent saling memanggil dan melakukan retry menyumbang lebih dari 30% dari total penyebab gangguan sistem secara keseluruhan.

Ketika riwayat percakapan terus menumpuk dan context window menjadi penuh, kinerja model itu sendiri akan menurun. Di samping itu, prompt yang di-hardcode sebagai string di dalam kode Python membuat kita harus mem-build ulang dan mendistribusikan ulang seluruh sistem hanya untuk mengedit satu frasa sederhana.


Sistem Observabilitas untuk Memutus Infinite Loop dan Lonjakan Biaya

Kita harus memisahkan solusi debugging lokal dengan tool observabilitas production untuk menentukan poin pengumpulan log. Pada tahap pengembangan, kita menggunakan Arize Phoenix berbasis OpenTelemetry untuk memeriksa kualitas embedding RAG dan panggilan tool. Pada lingkungan production, kita menghubungkan Langfuse yang menggunakan ClickHouse sebagai backend untuk memantau trace log dan konsumsi token secara real-time.

`
┌─────────────────────────────────────────────────────────────────────────┐
│ Semantic Caching & Routing Flow │
│ │
│ Client Query │
│ │ │
│ ▼ │
│ ┌───────────┐ Similarity >= 0.92? ┌─────────────────────────────┐ │
│ │ Redis Vector │ ─────────────────────────> │ Return Cached Response │ │
│ │ Cache │ (Cache Hit) │ (Latency -88%, Cost -86%) │ │
│ └───────────┘ └─────────────────────────────┘ │
│ │ │
│ │ (Cache Miss) │
│ ▼ │
│ ┌───────────┐ Execution & Save Cache ┌─────────────────────────────┐ │
│ │ External │ ────────────────────────> │ Store Result as Vector in │ │
│ │ LLM API │ │ Backend Database │ │
│ └───────────┘ └─────────────────────────────┘ │
└─────────────────────────────────────────────────────────────────────────┘

`

Biaya API yang timbul dari kueri berulang dipangkas menggunakan lapisan Semantic Caching.

Berdasarkan data analisis terhadap 60.000 kueri yang dirilis oleh AWS, menerapkan semantic cache dengan standar kemiripan kosinus (cosine similarity) berhasil menekan biaya inferensi LLM hingga 86% dan mengoptimalkan latensi respons sebesar 88%. Framework RouteLLM dari LMSYS juga berhasil menghemat biaya sebesar 85% dengan membagi permintaan ke model berbiaya tinggi atau berbiaya rendah berdasarkan tingkat kesulitan pertanyaan.

Semantic caching dibangun dengan urutan sebagai berikut:

  1. Menyiapkan Backend Redis Vector Search: Jalankan satu instance Redis yang akan mengubah prompt input menjadi vektor embedding dan menyimpannya.
  2. Penentuan Kemiripan dan Pengembalian Cache: Jika kemiripan kosinus antara vektor prompt baru dan vektor yang tersimpan sebelumnya bernilai 0,92 atau lebih tinggi, sistem akan langsung mengembalikan respons yang tersimpan tanpa memanggil LLM eksternal.
  3. Penyimpanan Cache Miss: Hanya saat tingkat kemiripan kurang dari 0,92, API eksternal akan dipanggil, dan respons yang diterima akan diperbarui ke dalam Redis.

Untuk menghentikan infinite loop secara mendasar, kita harus memasukkan pola circuit breaker yang memvalidasi status agent secara langsung ke dalam flow kontrol pipeline. Bergantung pada opsi retry bawaan yang disediakan oleh framework dapat menyebabkan exception pecah dan mematikan seluruh layanan. Cara yang aman adalah meng-hash nama tool dan nilai argumen menggunakan SHA-256 lalu memasukkannya ke dalam daftar; jika hash yang sama menumpuk 3 kali berturut-turut, paksa sistem untuk mengalihkan ke node lain.

`python
import hashlib
from typing import TypedDict, Annotated, List
from langchain_core.messages import BaseMessage
from langgraph.graph.message import add_messages

class AgentState(TypedDict):
messages: Annotated[List[BaseMessage], add_messages]
steps: int
tool_hashes: List[str]

def hash_tool_call(tool_name: str, tool_args: str) -> str:
raw_str = f"{tool_name}:{tool_args}"
return hashlib.sha256(raw_str.encode('utf-8')).hexdigest()

def agent_circuit_breaker_router(state: AgentState) -> str:
# 1. Jika total eksekusi melebihi 5 kali, beralih ke node jalur keluar yang ditentukan
if state["steps"] > 5:
return "fallback_graceful_node"

# 2. Jika Tool dan Argument yang sama dipanggil 3 kali berturut-turut, segera blokir
hashes = state.get("tool_hashes", [])
if len(hashes) >= 3 and hashes[-1] == hashes[-2] == hashes[-3]:
    return "fallback_graceful_node"
    
# 3. Periksa kata kunci penyelesaian normal
last_message = state["messages"][-1]
if "FINAL_ANSWER" in last_message.content:
    return "end"
    
return "continue_tools"

`

Terlepas dari status output non-deterministik LLM, router ini memvalidasi pernyataan kondisi di lingkungan eksekusi Python, sehingga secara fisik mencegah masuknya agent ke dalam loop akibat ilusi atau hallucination.


Pemisahan Versi Prompt dan Otomatisasi CI/CD

Membiarkan prompt terisolasi di dalam kode dapat menyebabkan kegagalan regresi (Regression Failure), di mana fitur yang sebelumnya berjalan lancar menjadi tidak berfungsi setelah dilakukan modifikasi model. Prompt harus dikeluarkan dari kode Python dan dikelola sebagai file YAML independen.

`yaml
name: "agent_reasoning"
version: "1.2.0"
model: "gpt-4o"
temperature: 0.1
messages:

  • role: "system"
    content: |
    Anda adalah agent penganalisis database internal perusahaan.
    Anda harus menjawab sesuai dengan skema JSON yang ditentukan, dan jika informasi kurang, buatlah pertanyaan tambahan.
  • role: "user"
    content: "{{ user_input }}"

`

Prompt yang telah dipisahkan ini digabungkan dengan DeepEval (framework evaluasi open-source) dan Pytest untuk diuji secara otomatis di dalam pipeline CI/CD. Metrik G-Eval ditetapkan sebagai tolok ukur untuk memverifikasi nilai respons model sebelum proses deployment.

`python
import pytest
from deepeval import assert_test
from deepeval.metrics import GEval, TaskCompletionMetric
from deepeval.test_case import LLMTestCase, SingleTurnParams

1. Definisi kriteria evaluasi

correctness_metric = GEval(
name="Akurasi dan Kepatuhan Skema",
criteria="Apakah respons LLM menjawab pertanyaan dengan akurat dan mematuhi format JSON yang diminta secara sempurna?",
evaluation_params=[SingleTurnParams.ACTUAL_OUTPUT, SingleTurnParams.EXPECTED_OUTPUT],
threshold=0.7
)

2. Pengujian regresi berbasis Pytest

@pytest.mark.parametrize(
"user_input, expected_output",
[
("Rangkum data penjualan Q1 tahun 2024.", "Total penjualan Q1 adalah 5 miliar KRW."),
("Beri tahu saya peraturan perhitungan pesangon.", "Pesangon adalah rata-upah 30 hari atau lebih untuk setiap 1 tahun masa kerja.")
]
)
def test_agent_regression(user_input, expected_output):
actual_output = run_in_house_agent(user_input)

test_case = LLMTestCase(
    input=user_input,
    actual_output=actual_output,
    expected_output=expected_output
)

# Batalkan build jika skor tidak mencapai ambang batas yang ditetapkan
assert_test(test_case, [correctness_metric, TaskCompletionMetric(threshold=0.8)])

`

Sistem evaluasi diintegrasikan melalui tiga tahap:

  1. Pembuatan Dataset Evaluasi: Buat himpunan pertanyaan domain utama beserta jawaban benarnya, lalu tentukan batas skor kelulusan (Threshold).
  2. Penggabungan Workflow GitHub Actions: Konfigurasikan action agar perintah deepeval test run berjalan secara otomatis saat membuat PR setelah modifikasi kode.
  3. Penerapan Shadow Testing: Sebelum digabungkan ke main branch, salin dan kirim permintaan traffic nyata secara asinkron untuk membandingkan kualitas respons dan latensi dengan versi sebelumnya sebelum melakukan deployment akhir.

`yaml
name: AI Agent Evaluation Gate

on:
pull_request:
branches: [ main ]

jobs:
eval-gate:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.11'
- name: Install Dependencies
run: |
pip install poetry
poetry install
- name: Run DeepEval Suite
env:
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
run: |
poetry run deepeval test run tests/test_evals.py

`


Penerapan Masking dan Kontrol Hak Akses

Untuk mencegah kebocoran data internal perusahaan, diperlukan guardrail yang melakukan de-identifikasi Informasi Identitas Pribadi (PII) sebelum permintaan API keluar ke eksternal. Dengan memasang mesin Microsoft Presidio pada gateway, sistem akan menyamarkan nomor identitas (RRN), email, nomor telepon, dan ID karyawan secara otomatis.

`python
from presidio_analyzer import AnalyzerEngine, PatternRecognizer
from presidio_anonymizer import AnonymizerEngine
from presidio_anonymizer.entities import OperatorConfig

1. Pendaftaran Analyzer Engine dan Aturan ID Karyawan

analyzer = AnalyzerEngine()
employee_id_recognizer = PatternRecognizer(
supported_entity="EMPLOYEE_ID",
regex="EMP-[0-9]{6}",
score=0.95
)
analyzer.registry.add_recognizer(employee_id_recognizer)

2. Inisialisasi Anonymizer Engine

anonymizer = AnonymizerEngine()

def sanitize_user_prompt(raw_prompt: str) -> str:
results = analyzer.analyze(
text=raw_prompt,
entities=["PERSON", "PHONE_NUMBER", "EMAIL_ADDRESS", "EMPLOYEE_ID"],
language="en"
)

anonymized_result = anonymizer.anonymize(
    text=raw_prompt,
    analyzer_results=results,
    operators={
        "DEFAULT": OperatorConfig("replace", {"new_value": "<REDACTED>"}),
        "EMPLOYEE_ID": OperatorConfig("mask", {"chars_to_mask": 6, "masking_char": "*", "from_end": True})
    }
)
return anonymized_result.text

`

Saat menghubungkan pencarian RAG, kita juga harus memastikan bahwa hanya dokumen yang sesuai dengan tingkat hak akses pengguna yang ditarik. Basis data vektor seperti Qdrant atau Pinecone menangani pemisahan hak akses menggunakan penyaringan metadata (Metadata Filtering) saat melakukan pencarian kemiripan.

`python
from qdrant_client import QdrantClient
from qdrant_client.http import models

client = QdrantClient(host="localhost", port=6333)

def search_documents_with_rbac(query_vector: list, user_department: str, user_clearance_level: int):
search_result = client.search(
collection_name="enterprise_knowledge_base",
query_vector=query_vector,
query_filter=models.Filter(
must=[
models.FieldCondition(
key="department",
match=models.MatchValue(value=user_department)
),
models.FieldCondition(
key="security_level",
range=models.Range(lte=user_clearance_level)
)
]
),
limit=5
)
return search_result

`

Pencegahan prompt injection pada dasarnya dilakukan dengan memisahkan secara total kanal system prompt dan kanal input pengguna. Tugas berisiko tinggi seperti memodifikasi database atau memanggil API eksternal harus melalui prosedur persetujuan manual oleh manusia (Human-in-the-Loop) atau dibatasi izin eksekusinya di dalam sandbox terisolasi agar tetap aman.


Lifecycle Infrastruktur dan Memastikan Konsistensi Secara Bertahap

Jika ingin menggantikan modul SaaS dan terus mengoperasikannya sebagai sistem internal perusahaan, diperlukan rutinitas pemeriksaan secara berkala.

Siklus Item Pemeriksaan Operasional Rincian Tugas
Setiap Hari Tingkat Error dan Konsumsi Token Periksa tingkat error HTTP 5xx dan konsumsi token per departemen di dashboard Langfuse
Setiap Hari Riwayat Pemblokiran Circuit Breaker Kumpulkan nama tool dan pola argumen pada sesi yang terputus akibat deteksi loop, lalu perbaiki
Setiap Minggu Ekstraksi Kueri Gagal Pencarian RAG Pilih permintaan dengan skor kemiripan di bawah 0,6 dan tambahkan ke himpunan jawaban benar untuk pengujian
Setiap Minggu Verifikasi Positif Palsu Masking PII Ambil sampel log pemrosesan Presidio untuk memverifikasi apakah ada masking yang terlewat
Setiap Bulan Pembaruan Kriteria Evaluasi CI/CD Sesuaikan test case otomatis untuk mencerminkan perubahan bisnis

Jika Anda sedang mempertimbangkan antara hosting model mandiri (berbasis vLLM) atau berlangganan API eksternal, cobalah hitung berdasarkan traffic harian.

Biaya sewa bulanan untuk instance AWS EC2 g5.2xlarge yang dilengkapi 1 GPU NVIDIA A10G adalah sekitar $880. Di sisi lain, tarif API GPT-4o berkisar di angka $2.50 per 1 juta token input dan $10.00 per 1 juta token output. Jika traffic harian berada di bawah 50 juta token, metode berlangganan API jauh lebih menguntungkan mengingat beban kerja enginir DevOps dan biaya tetap GPU. Baru ketika traffic harian melebihi 100 juta token atau saat isolasi jaringan internal secara mutlak diperlukan, beralih ke hosting mandiri berbasis vLLM menjadi pilihan yang tepat.

Untuk mengantisipasi gangguan pada model utama, buatlah struktur routing backup 4 tingkat (4-Tier).

`
┌─────────────────────────────────────────────────────────────────────────┐
│ 4-Tier Graceful Degradation Architecture │
│ │
│ [Tier 1] Primary High-Performance Model (e.g., GPT-4o) │
│ │ │
│ ▼ (API Failure / Timeout / Circuit Breaker) │
│ [Tier 2] Lightweight Routing Model (e.g., GPT-4o-mini / On-Prem vLLM) │
│ │ │
│ ▼ (Continuous Outage) │
│ [Tier 3] Deterministic Regex & SQL Rule Engine │
│ │ │
│ ▼ (Unrecoverable Error) │
│ [Tier 4] Static Error Message & Async Admin Ticket Generation │
└─────────────────────────────────────────────────────────────────────────┘

`


Urutan Stabilisasi Operasional

Pekerjaan menyempurnakan sistem agent kustom dilakukan dalam rentang waktu 90 hari.

Periode Target Penerapan Rincian Tugas Konkret
Hari ke-1~30 Visibilitas dan Perlindungan Data Menginstal mesin masking Presidio dan mengimplementasikan SDK logging Langfuse
Hari ke-31~60 Pemblokiran Loop dan Penghematan Biaya Menerapkan semantic caching Redis dan menghubungkan circuit breaker berbasis Python
Hari ke-61~90 Otomatisasi Verifikasi dan Kontrol Hak Akses Manajemen Git untuk prompt, integrasi CI/CD DeepEval, dan penerapan metadata RBAC Qdrant

Pada bulan pertama, bangun solusi observabilitas untuk mencegah kebocoran informasi pribadi dan memastikan semua permintaan tercatat dalam log. Pada bulan kedua, pasang caching prompt berulang dan router pemblokir loop untuk memangkas pengeluaran biaya yang tidak terduga. Pada bulan terakhir, setelah manajemen versi prompt dan sistem evaluasi pengujian otomatis selesai dibangun, Anda dapat mengoperasikan agent secara stabil tanpa perlu khawatir akan malfungsi setiap kali melakukan deployment.

Related Video

"Build vs Buy" semakin bergeser ke arah "build"

Maximilian Schwarzmüller10:07

More from the community

Comments

Log in to leave a comment.

No comments yet.