
Chặn Agent AI Đốt Tiền API: Circuit Breaker Và Kill Switch
Agent chạy vòng lặp không kiểm soát có thể đốt sạch quota API trong vài phút. Ba lớp chặn cần có: đếm cứng, dò vòng lặp và kill switch ngân sách.
Bạn để một agent chạy qua đêm để dọn dữ liệu. Sáng hôm sau log đầy những dòng giống hệt nhau, cùng một endpoint bị gọi lặp lại, và hạn mức API của cả team đã cạn trước khi ai kịp mở máy. Bài này chỉ ra ba lớp chặn cụ thể — bộ đếm cứng, bộ dò vòng lặp bằng hash payload, và công tắc ngắt theo ngân sách — để lần sau sự cố dừng lại ở một session thay vì cả hoá đơn tháng.
Vòng lặp ReAct không chặn hỏng ở chỗ nào
Agent tự động chạy trong tool-use loop hỏng theo kiểu khó đoán. Tác giả bài Bulletproofing AI Agents mô tả: "When an LLM encounters an unexpected schema, a transient network error, or an ambiguous prompt, it often enters a hallucinated retry storm." Model không crash. Nó chỉ thử lại, mỗi lần một biến thể tham số hơi khác.
Khác biệt so với web app thường nằm ở chỗ ai chặn bạn lại. Vẫn theo bài viết đó, một app bình thường gặp rate limit hoặc trả 500; còn "an unconstrained ReAct loop executes external API calls continuously, burning tokens, exhausting upstream quotas, and running up massive cloud bills in minutes". Câu chốt đáng dán lên tường: "Cloud providers do not issue refunds for self-inflicted API usage."
Anti-pattern mà bài viết chỉ ra rất quen mặt — vòng while not task_complete gọi thẳng external_api.call(...) rồi cập nhật state từ kết quả. Nếu model không parse được response để chuyển trạng thái, vòng lặp không có điểm dừng nào cả.
Ba lớp chặn nằm ngoài code của agent
Nguyên tắc kiến trúc trong bài rất rõ: "never allow direct API calls from agent code. Route every external request through an isolated API Safety Wrapper". Agent chỉ được nói muốn gọi gì; phần quyết định có gọi hay không thuộc về code bạn kiểm soát.
1. Bộ đếm cứng theo session
Lớp đầu tiên là "Deterministic Request Firewall: A hard cap on execution count per task session (Time-To-Live counter)". Đây là thứ rẻ nhất và nên có trước tiên: một biến đếm, một ngưỡng, một exception. Nó không cần thông minh — nó chỉ cần tồn tại trước khi agent lên production.
2. Hash payload để bắt vòng lặp dao động
Bộ đếm cứng chặn được thảm hoạ nhưng không phát hiện được sớm. Lớp thứ hai làm việc đó: "Sliding-Window Loop Detector: Hashing outgoing request payloads to catch repetitive or oscillating tool invocations." Điểm hay là nó bắt cả kiểu dao động A→B→A→B, thứ mà bộ đếm coi là bốn lệnh gọi hợp lệ.
3. Công tắc ngắt theo tiền
Lớp cuối là "Financial Kill Switch: A pre-flight budget validator that cuts credentials immediately if projected cost exceeds session limits". Chữ pre-flight quan trọng: kiểm tra trước khi gọi, không phải cộng dồn sau khi gọi. Và hành động khi vượt ngưỡng là thu hồi credential, không chỉ log cảnh báo.
Kết quả kỳ vọng, theo đúng lời bài viết: "even if an agent hallucinates or crashes, the blast radius is strictly confined to a single session budget."
Wrapper tối thiểu trông như thế nào
Đoạn dưới là bản rút gọn từ ví dụ minh hoạ trong bài — dùng để thấy hình dạng của ba lớp, không phải code copy thẳng vào production:
class APISafetyWrapper:
def __init__(self, client, max_calls=50, budget_limit=5.0):
self.client, self.max_calls, self.budget_limit = client, max_calls, budget_limit
self.history, self.total_cost = [], 0.0
def execute(self, endpoint, payload, estimated_cost=0.02):
sig = hashlib.md5(f"{endpoint}:{sorted(payload.items())}".encode()).hexdigest()
if len(self.history) >= self.max_calls:
raise RuntimeError("Circuit Breaker: Hard limit reached.")
if self.history[-3:].count(sig) >= 2:
raise RuntimeError("Loop Detected: Repeating payload.")
if (self.total_cost + estimated_cost) > self.budget_limit:
self.client.revoke_credentials()
raise PermissionError("Budget Exceeded: Financial kill-switch triggered.")
self.history.append(sig)
self.total_cost += estimated_cost
return self.client.call(endpoint, payload)
Ba con số trong ví dụ (max_calls=50, budget_limit=5.0, cửa sổ 3 lệnh gần nhất) là giá trị mặc định của bài viết, không phải chuẩn ngành. Hãy đặt lại theo workflow của bạn: một agent tóm tắt ticket cần vài lệnh gọi, một agent refactor repo cần vài chục.
Timeout mới là chỗ agent làm hỏng dữ liệu
Chặn tiền chỉ là một nửa. Nửa còn lại là ai quyết định "lệnh gọi vừa rồi thành công hay thất bại". Một bài khác về kiến trúc agent nêu đúng tình huống nguy hiểm: nếu LLM tự giữ state, "it might hallucinate a successful charge, or worse, hallucinate a failure and retry the action, double-charging the customer".
Cách xử lý được đề xuất là tách hẳn phần suy luận khỏi máy trạng thái. Khi một lệnh gọi timeout, "the outer loop does not blindly ask the LLM what to do. The outer loop pauses the agent, runs an out-of-band verification (e.g., checking the Stripe ledger), updates the exact deterministic outcome (success or failed), and only then hands the state back to the LLM."
Nói gọn theo bài đó: hãy coi LLM như một hàm biến đổi thuần Context → Intent, còn "your deterministic harness must handle the rest".
Phần còn lại của harness
Một checklist production cho agent liệt kê những thứ không hào nhoáng nhưng quyết định việc bạn có ngủ được hay không. Ba dòng liên quan trực tiếp đến bài này:
- Giới hạn số bước nằm trong harness. Checklist ghi thẳng: "Agents loop, so put step limits in the harness."
- Mọi tool call phải idempotent và workflow phải resume được. "Durable execution engines and checkpointing mean a crashed 40-step run resumes at step 31 instead of restarting. Every tool call should be idempotent too, so retries don't double-charge anyone."
- Đo tiền ở nhiều tầng. "Cost limits at every level: per chat, per user, per tenant, per SaaS account. One buggy retry loop without budgets is how cloud bills become front-page news internally."
Cùng checklist đó khuyên chọn một lớp tracing rồi gắn bó với nó — Langfuse, LangSmith hoặc OpenTelemetry — vì khi workflow chạy sai trong production, trace là ranh giới giữa debug được và nhìn vào hộp đen.
Câu tổng kết của tác giả đáng để đưa vào review kiến trúc: "The harness (schemas, limits, retries, locks, secrets) is the product. The model is a component inside it."
Làm gì trong tuần này
Mở agent tốn tiền nhất đang chạy và trả lời ba câu. Một: nếu response không parse được, vòng lặp dừng ở lệnh gọi thứ mấy? Hai: nếu cùng một payload được gửi ba lần liên tiếp, có gì phát hiện không? Ba: khi chi phí session vượt ngưỡng, hệ thống thu hồi credential hay chỉ ghi log?
Nếu câu trả lời nào là "không có gì", đó chính là lớp cần viết trước — và mỗi lớp trong ba lớp trên chỉ mất vài chục dòng code, ít hơn nhiều so với một đêm chạy loạn.
Không spam, hủy đăng ký bất kỳ lúc nào.


