DEV Community

Cover image for Cách Chặn Việc Trông Trẻ Các AI Agent
Sebastian Petrus
Sebastian Petrus

Posted on • Originally published at apidog.com

Cách Chặn Việc Trông Trẻ Các AI Agent

TÓM TẮT

Bạn có thể ngừng "chăm sóc" các tác nhân AI bằng cách xây dựng ba lớp: rào chắn (guardrails), khả năng quan sát (observability), và các điểm kiểm tra (checkpoints). Thiết lập một lần, tác nhân có thể tự chạy hàng giờ mà không cần giám sát liên tục. Công cụ như Apidog giúp bạn định nghĩa hợp đồng API mà tác nhân không thể vi phạm, biến lớp API thành mạng lưới an toàn.

Hãy thử Apidog ngay hôm nay

Giới thiệu

Tuần trước, tôi chứng kiến một dev dành 4 giờ để giám sát một tác nhân AI vốn được kỳ vọng tiết kiệm thời gian. Cứ vài phút, anh ta lại phải sửa lỗi, khởi động lại. Kết quả: làm việc thủ công nhiều hơn tự code.

Đây là vấn đề "chăm sóc trẻ con" – lý do hàng đầu khiến tác nhân AI không phát huy hiệu quả. Công cụ tốt, mô hình mạnh, nhưng các nhóm không vượt qua nổi giai đoạn giám sát liên tục.

Nguyên nhân: Phần lớn setup tác nhân AI coi LLM như dev junior cần chỉ dẫn từng bước. Nhưng LLM giống thực tập sinh siêu tốc – đôi khi tự tin làm sai nếu không đặt ranh giới.

💡 Nếu bạn xây dựng API hoặc tác nhân AI gọi API, Apidog giúp xác định ranh giới rõ ràng. Chỉ định schema request/response, bạn tạo hợp đồng mà tác nhân không thể vi phạm – hiệu quả như đưa bản đồ thay vì để chúng tự do lang thang.

Xác định hợp đồng API mà tác nhân AI của bạn buộc phải tuân thủ.

Bạn sẽ nhận được:

  • Mô hình tư duy về quyền tự chủ tác nhân
  • Mẫu cụ thể cho rào chắn, quan sát, checkpoint
  • Đoạn mã dễ áp dụng
  • Checklist đánh giá tác nhân đã sẵn sàng tự chạy

Tại sao các tác nhân cần được giám sát liên tục

Các tác nhân AI thường thất bại theo cách có thể dự đoán. Hiểu rõ các chế độ lỗi giúp bạn chủ động phòng tránh.

Chế độ lỗi 1: Lạm dụng phạm vi (Scope creep)

Giao "thêm xác thực vào endpoint", tác nhân làm đúng. Nhưng rồi thêm rate limiting, refactor database, xóa file tưởng không dùng (nhưng lại cực kỳ quan trọng).

Tác nhân không biết điểm dừng nếu bạn không đặt ranh giới.

Chế độ lỗi 2: Trừu tượng hóa sai (Wrong abstractions)

Yêu cầu "cải thiện xử lý lỗi", tác nhân có thể spam try-catch, làm mã khó đọc, log lỗi không đồng nhất, không xử lý đúng trường hợp thực tế.

Chế độ lỗi 3: Lỗi tầng (Cascading failures)

Một lỗi nhỏ đầu chuỗi dẫn đến loạt quyết định sai về sau. Đến cuối, hệ thống hỏng, dev mất thời gian debug.

Chế độ lỗi 4: Cạn kiệt tài nguyên (Resource exhaustion)

Không kiểm soát, tác nhân có thể lặp vô hạn: retry API, tạo sub-agent không giới hạn, hoặc chạy đến khi cạn quota.

Khung quyền tự chủ: rào chắn, khả năng quan sát, checkpoint

Giải quyết bằng ba lớp – hãy hình dung như kim tự tháp:

  • Rào chắn (ngăn thất bại)
  • Quan sát (phát hiện thất bại)
  • Điểm kiểm tra (khôi phục sau thất bại)

Lớp 1: Rào chắn (Guardrails) – Ngăn ngừa

Rào chắn là các ràng buộc enforced qua code, không chỉ prompt.

Ràng buộc qua code:

# Không nên: Tin tác nhân tuân thủ hướng dẫn
agent.run("Only modify files in the src/ directory")

# Nên: Áp ràng buộc qua code
import os
from pathlib import Path

ALLOWED_DIRECTORIES = {"src", "tests", "docs"}

def validate_file_path(path: str) -> bool:
    abs_path = Path(path).resolve()
    return any(
        str(abs_path).startswith(str(Path(d).resolve()))
        for d in ALLOWED_DIRECTORIES
    )

def agent_write_file(path: str, content: str):
    if not validate_file_path(path):
        raise ValueError(f"Không thể ghi vào {path}: ngoài các thư mục được phép")
    with open(path, 'w') as f:
        f.write(content)
Enter fullscreen mode Exit fullscreen mode

Ràng buộc schema API:

Áp dụng schema để chặn request sai định dạng – Apidog giúp định nghĩa contract, tác nhân không gửi được dữ liệu sai.

// apidog-schema.ts
export const CreateUserSchema = {
  type: 'object',
  required: ['email', 'name'],
  properties: {
    email: { type: 'string', format: 'email' },
    name: { type: 'string', minLength: 1, maxLength: 100 },
    role: { type: 'string', enum: ['user', 'admin', 'guest'] }
  },
  additionalProperties: false
}

// Tác nhân phải xác thực trước khi gọi API
function validateRequest(schema: object, data: unknown): void {
  const valid = ajv.validate(schema, data)
  if (!valid) {
    throw new Error(`Yêu cầu không hợp lệ: ${JSON.stringify(ajv.errors)}`)
  }
}
Enter fullscreen mode Exit fullscreen mode

Ràng buộc ngân sách:

import time
from dataclasses import dataclass

@dataclass
class AgentBudget:
    max_steps: int = 50
    max_tokens: int = 100000
    max_time_seconds: int = 600  # 10 phút
    max_api_calls: int = 100

class BudgetEnforcer:
    def __init__(self, budget: AgentBudget):
        self.budget = budget
        self.start_time = time.time()
        self.steps = 0
        self.tokens_used = 0
        self.api_calls = 0

    def check(self) -> bool:
        elapsed = time.time() - self.start_time
        if self.steps >= self.budget.max_steps:
            raise RuntimeError(f"Đã đạt giới hạn bước: {self.steps}")
        if self.tokens_used >= self.budget.max_tokens:
            raise RuntimeError(f"Đã đạt giới hạn token: {self.tokens_used}")
        if elapsed >= self.budget.max_time_seconds:
            raise RuntimeError(f"Đã đạt giới hạn thời gian: {elapsed:.0f}s")
        if self.api_calls >= self.budget.max_api_calls:
            raise RuntimeError(f"Đã đạt giới hạn lệnh gọi API: {self.api_calls}")
        return True

    def record_step(self, tokens: int, api_calls: int = 0):
        self.steps += 1
        self.tokens_used += tokens
        self.api_calls += api_calls
        self.check()
Enter fullscreen mode Exit fullscreen mode

Lớp 2: Khả năng quan sát (Observability) – Phát hiện

Cần biết tác nhân đang làm gì mà không xem từng bước.

Ghi nhật ký có cấu trúc:

import json
from datetime import datetime
from typing import Any

class AgentLogger:
    def __init__(self, log_file: str = "agent_trace.jsonl"):
        self.log_file = log_file
        self.entries = []

    def log(self, event: str, data: dict[str, Any] | None = None):
        entry = {
            "timestamp": datetime.utcnow().isoformat(),
            "event": event,
            "data": data or {}
        }
        self.entries.append(entry)
        with open(self.log_file, 'a') as f:
            f.write(json.dumps(entry) + '\n')

    def log_decision(self, decision: str, reasoning: str, confidence: float):
        self.log("decision", {
            "decision": decision,
            "reasoning": reasoning,
            "confidence": confidence
        })

    def log_action(self, action: str, params: dict, result: str):
        self.log("action", {
            "action": action,
            "params": params,
            "result": result[:200]
        })

    def log_error(self, error: str, context: dict):
        self.log("error", {
            "error": error,
            "context": context
        })

# Sử dụng
logger = AgentLogger()
logger.log_decision(
    decision="Add rate limiting to API",
    reasoning="Current endpoint has no protection against abuse",
    confidence=0.85
)
logger.log_action(
    action="write_file",
    params={"path": "src/middleware/rate-limit.ts"},
    result="Successfully wrote 45 lines"
)
Enter fullscreen mode Exit fullscreen mode

Bảng điều khiển chỉ số:

from collections import Counter
from dataclasses import dataclass, field

@dataclass
class AgentMetrics:
    actions_taken: Counter = field(default_factory=Counter)
    files_modified: list[str] = field(default_factory=list)
    api_calls: dict[str, int] = field(default_factory=dict)
    errors: list[str] = field(default_factory=list)
    decisions_by_confidence: dict[str, int] = field(default_factory=lambda: {
        "high (>0.9)": 0,
        "medium (0.7-0.9)": 0,
        "low (<0.7)": 0
    })

    def record_action(self, action: str):
        self.actions_taken[action] += 1

    def record_file_modification(self, path: str):
        if path not in self.files_modified:
            self.files_modified.append(path)

    def record_api_call(self, endpoint: str):
        self.api_calls[endpoint] = self.api_calls.get(endpoint, 0) + 1

    def record_error(self, error: str):
        self.errors.append(error)

    def record_decision(self, confidence: float):
        if confidence > 0.9:
            self.decisions_by_confidence["high (>0.9)"] += 1
        elif confidence >= 0.7:
            self.decisions_by_confidence["medium (0.7-0.9)"] += 1
        else:
            self.decisions_by_confidence["low (<0.7)"] += 1

    def summary(self) -> str:
        return f"""
Tóm tắt chỉ số tác nhân
=====================
Hành động: {dict(self.actions_taken)}
Tệp đã sửa đổi: {len(self.files_modified)}
Lệnh gọi API: {self.api_calls}
Lỗi: {len(self.errors)}
Quyết định theo độ tin cậy: {self.decisions_by_confidence}
"""
Enter fullscreen mode Exit fullscreen mode

Lớp 3: Điểm kiểm tra (Checkpoint) – Khôi phục

Checkpoint là các điểm tạm dừng tự động, chờ xác minh từ người dùng. Giúp phát hiện lỗi sớm, không cần giám sát liên tục.

Điểm kiểm tra tự động:

from enum import Enum
from typing import Callable
from dataclasses import dataclass

class CheckpointTrigger(Enum):
    BEFORE_FILE_WRITE = "before_file_write"
    BEFORE_API_CALL = "before_api_call"
    BEFORE_GIT_COMMIT = "before_git_commit"
    BEFORE_DELETE = "before_delete"
    AFTER_N_STEPS = "after_n_steps"

@dataclass
class Checkpoint:
    trigger: CheckpointTrigger
    description: str
    data: dict
    requires_approval: bool = True

class CheckpointManager:
    def __init__(self, auto_approve: set[CheckpointTrigger] | None = None):
        self.auto_approve = auto_approve or set()
        self.pending: list[Checkpoint] = []

    def create_checkpoint(
        self, 
        trigger: CheckpointTrigger, 
        description: str, 
        data: dict
    ) -> bool:
        if trigger in self.auto_approve:
            return True
        checkpoint = Checkpoint(
            trigger=trigger,
            description=description,
            data=data
        )
        self.pending.append(checkpoint)
        return False

    def approve(self, checkpoint_id: int) -> None:
        if 0 <= checkpoint_id < len(self.pending):
            self.pending.pop(checkpoint_id)

    def reject(self, checkpoint_id: int) -> None:
        raise RuntimeError(f"Điểm kiểm tra bị từ chối: {self.pending[checkpoint_id]}")

# Sử dụng trong agent
checkpoints = CheckpointManager(
    auto_approve={CheckpointTrigger.BEFORE_FILE_WRITE}
)

if not checkpoints.create_checkpoint(
    trigger=CheckpointTrigger.BEFORE_DELETE,
    description="About to delete src/legacy/ directory",
    data={"path": "src/legacy/", "files": ["old_handler.ts", "deprecated.ts"]}
):
    agent.pause("Đang chờ phê duyệt để xóa tệp")
Enter fullscreen mode Exit fullscreen mode

Xây dựng tác nhân tự chủ với Apidog

Tác nhân AI gọi API, rủi ro lớn nhất là gửi request sai định dạng.

Apidog cho phép định nghĩa schema API chuẩn xác, tác nhân buộc phải tuân thủ.

Thiết lập hợp đồng API:

  1. Nhập/định nghĩa OpenAPI spec trong Apidog
  2. Sinh mã client có xác thực tích hợp
  3. Cung cấp cho tác nhân client đã xác thực thay vì HTTP thô
// Không nên – gọi API trực tiếp
const response = await fetch('/api/users', {
  method: 'POST',
  body: JSON.stringify(data)  // Không xác thực schema
})

// Nên – dùng client đã xác thực từ Apidog
import { UsersApi } from './generated/apidog-client'

const usersApi = new UsersApi()
const response = await usersApi.createUser({
  email: 'user@example.com',
  name: 'Test User',
  role: 'user' // Buộc là enum hợp lệ
})
Enter fullscreen mode Exit fullscreen mode

Điều này biến lớp API thành rào chắn – request sai bị từ chối trước khi gửi đi.

Tạo client API xác thực cho tác nhân AI của bạn.

Các mẫu đã kiểm chứng & sai lầm phổ biến

Mẫu 1: Quy trình phê duyệt hai lớp (Approval sandwich)

Cho thao tác rủi ro, yêu cầu phê duyệt TRƯỚC & SAU khi thực hiện.

def risky_operation(agent, operation):
    # Phê duyệt trước
    if not agent.checkpoint(f"About to: {operation.description}"):
        return "Cancelled by user"
    # Thực hiện thao tác
    result = operation.execute()
    # Phê duyệt sau
    if not agent.checkpoint(f"Verify result of: {operation.description}"):
        operation.rollback()
        return "Rolled back by user"
    return result
Enter fullscreen mode Exit fullscreen mode

Mẫu 2: Ngưỡng tin cậy (Confidence thresholds)

Đừng để tác nhân quyết định khi độ tin cậy thấp.

MIN_CONFIDENCE = 0.75

def agent_decide(options: list[dict]) -> dict:
    best = max(options, key=lambda x: x.get('confidence', 0))
    if best['confidence'] < MIN_CONFIDENCE:
        return {
            'action': 'escalate',
            'reason': f"Best option has confidence {best['confidence']:.2f} < {MIN_CONFIDENCE}",
            'options': options
        }
    return best
Enter fullscreen mode Exit fullscreen mode

Mẫu 3: Các hoạt động bất biến (Idempotent operations)

Thiết kế hành động có thể lặp lại, không side-effect.

import hashlib

def idempotent_write(path: str, content: str) -> bool:
    """Chỉ ghi nếu nội dung thay đổi."""
    content_hash = hashlib.sha256(content.encode()).hexdigest()
    existing_hash = None
    if os.path.exists(path):
        with open(path, 'r') as f:
            existing_hash = hashlib.sha256(f.read().encode()).hexdigest()
    if content_hash == existing_hash:
        logger.log_action("write_file", {"path": path}, "Đã bỏ qua - không có thay đổi")
        return False
    with open(path, 'w') as f:
        f.write(content)
    logger.log_action("write_file", {"path": path}, f"Đã ghi {len(content)} byte")
    return True
Enter fullscreen mode Exit fullscreen mode

Những sai lầm phổ biến cần tránh

  • Tin prompt là ràng buộc: "Đừng xóa file" trong prompt không đủ, permission filesystem mới là ràng buộc thật.
  • Không có kế hoạch khôi phục: Không dùng git hay backup, bạn sẽ phải xử lý lỗi không thể hoàn tác.
  • Bỏ qua điểm số tin cậy: LLM có thể xuất ra confidence – điểm thấp thì pause, hỏi người.
  • Giám sát quá mức: Theo dõi mọi bước = hệ thống thủ công chậm.
  • Chỉ định mục tiêu không rõ: Tác nhân cần biết điều kiện hoàn thành rõ ràng.

Các lựa chọn thay thế & so sánh

Cách tiếp cận Khả năng tự chủ Rủi ro Tốt nhất cho
Viết mã thủ công Không Thấp Công việc phức tạp, quan trọng
Lập trình cặp với AI Thấp Thấp Học tập, khám phá
Các tác nhân được giám sát Trung bình Trung bình Các nhiệm vụ định kỳ
Các tác nhân tự chủ có rào chắn Cao Được kiểm soát Các thao tác hàng loạt, di chuyển dữ liệu
Các tác nhân hoàn toàn tự chủ Rất cao Rất cao Các quy trình làm việc đáng tin cậy, đã được kiểm tra kỹ

Đa số nhóm nên hướng tới "tự chủ có rào chắn" – tiết kiệm 80% thời gian với 10% rủi ro.


Trường hợp sử dụng thực tế

Di chuyển codebase:

Một nhóm dùng tác nhân tự chủ di chuyển 200 endpoint từ REST sang GraphQL. Rào chắn ngăn đổi schema, checkpoint yêu cầu phê duyệt khi xóa endpoint cũ. Hoàn thành trong 3 ngày, không sự cố production.

Tạo tài liệu:

Tác nhân tự động tạo doc API từ code. Rào chắn chỉ cho phép đọc thư mục nhất định, checkpoint trước khi publish. Nhóm review doc mỗi tuần, không cần viết tay.

Độ bao phủ test:

Tác nhân phân tích code và viết test case còn thiếu. Ràng buộc ngân sách chặn spam test, ngưỡng tin cậy flag test không chắc cho người review. Coverage tăng từ 60% lên 85% sau 1 tháng.

Tóm tắt

Bạn đã biết:

  • Các lỗi phổ biến: lạm dụng phạm vi, trừu tượng hóa sai, lỗi tầng, cạn tài nguyên
  • Ba lớp xử lý: rào chắn (ngăn ngừa), quan sát (phát hiện), checkpoint (khôi phục)
  • Rào chắn là code, không phải prompt – enforce bằng chương trình
  • Quan sát = log & metrics có cấu trúc, không phải xem mọi bước
  • Checkpoint cho phép xác minh mà không phải giám sát liên tục
  • Schema API từ Apidog biến API thành rào chắn cứng

Bước tiếp theo:

  1. Xác định tác vụ AI lặp đi lặp lại nhất
  2. Xác định rào chắn: tác nhân không được phép làm gì?
  3. Thêm structured logging
  4. Tạo checkpoint cho thao tác rủi ro
  5. Để chạy 30 phút, kiểm tra log

Mục tiêu không phải loại bỏ con người khỏi vòng lặp, mà là đặt con người đúng vị trí: ra quyết định cấp cao thay vì sửa lỗi thủ công.

Xây dựng rào chắn API cho tác nhân AI của bạn – miễn phí.

Câu hỏi thường gặp

Khác biệt giữa tác nhân AI và trợ lý AI là gì?

Trợ lý chỉ phản hồi, chờ chỉ dẫn. Tác nhân nhận mục tiêu, tự chủ lên kế hoạch & thực thi đến khi checkpoint hoặc hoàn thành.

Làm sao biết tác nhân đã sẵn sàng tự chủ?

Chạy ở chế độ giám sát 10 phiên, đếm số lần bạn phải can thiệp. Nếu <2 lần/phiên, chỉ là clarifying chứ không lỗi, đã sẵn sàng. Nếu thường xuyên rollback, cần thêm rào chắn.

Rủi ro lớn nhất của tác nhân tự chủ?

Lỗi tầng mà tác nhân không nhận ra. Checkpoint giúp phá vỡ lỗi tầng bằng xác minh người.

Có thể dùng các mẫu này với mọi LLM?

Có. Guardrails, observability, checkpoint không phụ thuộc model. Áp dụng cho Claude, GPT-4, Gemini, v.v.

Quan sát làm chậm tác nhân nhiều không?

Không đáng kể. Log chỉ tốn vài micro giây. Chậm nhất là checkpoint phải chờ người.

Nếu tác nhân quyết sai ý tôi?

Đó là vai trò checkpoint. Khi không đồng ý, từ chối checkpoint – tác nhân rollback hoặc thử cách khác. Tốt hơn nữa: embed preference vào prompt cho tác nhân học dần.

Nên bắt đầu với tác nhân được giám sát hay tự chủ?

Luôn bắt đầu với giám sát. Checkpoint mọi hành động quan trọng, dần bỏ checkpoint với thao tác rủi ro thấp.

Apidog giúp gì cho tác nhân AI?

Apidog tạo API client xác thực từ schema. Tác nhân dùng client này, request sai sẽ bị từ chối trước khi đến backend – loại bỏ cả lớp lỗi liên quan dữ liệu sai hoặc giá trị không hợp lệ.

Top comments (0)