DEV Community

Cover image for Cách kiểm tra AI Agent gọi API của bạn mà không mất dữ liệu
Sebastian Petrus
Sebastian Petrus

Posted on • Originally published at apidog.com

Cách kiểm tra AI Agent gọi API của bạn mà không mất dữ liệu

Một tác nhân mã hóa AI chạy một script, thấy thành công, rồi một bảng database production biến mất. Bài phân tích trên Hacker News lan truyền với tiêu đề: “AI không xóa cơ sở dữ liệu của bạn, bạn đã làm điều đó.” Một thread khác trên r/ClaudeAI kể câu chuyện tương tự: tác nhân bị kẹt trong vòng lặp thanh toán và đốt hàng trăm đô token trước khi ai đó nhận ra. Bề mặt lỗi khác nhau, nhưng cùng một nguyên nhân: tác nhân được cấp quyền gọi API thật mà không có guardrail. Vấn đề không phải là mô hình “ngu”. Vấn đề là API không được kiểm thử đủ kỹ.

Dùng thử Apidog hôm nay

💡 Nếu bạn đang triển khai tác nhân tự động gọi API, hướng dẫn này dành cho bạn. Bạn sẽ học cách mock endpoint bên ngoài khi phát triển tác nhân, cô lập thao tác phá hoại, viết contract test cho schema công cụ, đặt ngân sách cho từng tác nhân, và diễn tập failure mode trước khi chúng xảy ra trong production. Bài viết dùng Apidog vì công cụ này hỗ trợ OpenAPI, mock server và scenario testing trong cùng một workflow.

TL;DR

Tác nhân AI gây sự cố production khi API phía sau thiếu cơ chế bảo vệ:

  • Không rate limit
  • Không idempotency
  • Cho phép hard delete trực tiếp
  • Schema công cụ lệch với OpenAPI
  • Không giới hạn ngân sách token/request/chi phí

Cách xử lý:

  1. Kiểm thử contract giữa tool schema của tác nhân và OpenAPI.
  2. Dùng mock server cho endpoint phá hoại.
  3. Bắt buộc idempotency key cho mọi write operation.
  4. Đặt budget limit cho từng tác nhân.
  5. Replay failure scenario trong CI.

Apidog có thể nhập OpenAPI, tạo mock server và chạy scenario test từ một project duy nhất.

Vì sao lỗi tác nhân thường là lỗi API

Trước đây, “kiểm thử tác nhân AI” thường chỉ là nhập prompt và đánh giá câu trả lời. Cách đó không còn đủ.

Tác nhân hiện nay gọi tool. Tool gọi API. API chạm vào database, payment processor, email provider hoặc hệ thống nội bộ. Một tool definition sai hoặc endpoint thiếu giới hạn không còn là lỗi nhỏ; đó là production incident.

Một số pattern phổ biến:

Prompt injection gọi nhầm endpoint nguy hiểm

Ví dụ: người dùng upload PDF có instruction ẩn. Tác nhân đọc file, rồi gọi:

POST /admin/users
Content-Type: application/json

{
  "delete_all": true
}
Enter fullscreen mode Exit fullscreen mode

Cách sửa không phải chỉ là “prompt cứng hơn”. API phải enforce authorization theo user context gốc. Nếu user không có quyền xóa toàn bộ user, tác nhân chạy thay user đó cũng không được quyền.

Tool schema lệch với OpenAPI

OpenAPI nói:

{
  "amount": {
    "type": "integer",
    "description": "Amount in cents"
  }
}
Enter fullscreen mode Exit fullscreen mode

Tool definition lại nói:

{
  "amount": {
    "type": "number",
    "description": "Amount in dollars"
  }
}
Enter fullscreen mode Exit fullscreen mode

Kết quả: hoàn tiền 19 cent thành 19 đô. Mô hình không sai; nó dùng schema bạn đưa. Lỗi nằm ở contract không được kiểm thử.

Retry loop không có rate limit

Tác nhân gọi email API, nhận lỗi tạm thời, rồi retry liên tục vì planner nghĩ task chưa hoàn tất. Sau vài phút, bạn có:

  • Hàng nghìn request
  • Email thật bị gửi
  • Chi phí tăng
  • Provider flag tài khoản

API phải có rate limit, budget limit và retry policy rõ ràng.

Thiếu idempotency gây double charge

Tác nhân gọi:

POST /payments
Enter fullscreen mode Exit fullscreen mode

Network timeout. Planner retry. Payment ban đầu thực ra đã thành công. Khách hàng bị tính phí hai lần.

Lớp tác nhân không thể biết request đầu thành công hay chưa. API phải hỗ trợ idempotency key.

4 guardrail bắt buộc cho tích hợp tác nhân-API

1. Contract test giữa tool schema và OpenAPI

OpenAPI nên là nguồn sự thật. Tool definition của tác nhân phải khớp với OpenAPI. Nếu lệch, CI phải fail.

Ví dụ Python đơn giản:

import json
from jsonschema import Draft202012Validator

def validate_tool_against_openapi(tool_def: dict, openapi_spec: dict) -> list[str]:
    """Return a list of mismatch errors, empty list = pass."""
    errors = []

    op = openapi_spec["paths"][tool_def["path"]][tool_def["method"].lower()]
    api_schema = op["requestBody"]["content"]["application/json"]["schema"]
    tool_schema = tool_def["input_schema"]

    api_props = set(api_schema.get("properties", {}).keys())
    tool_props = set(tool_schema.get("properties", {}).keys())

    for missing in api_props - tool_props:
        if missing in api_schema.get("required", []):
            errors.append(f"Tool missing required field: {missing}")

    for extra in tool_props - api_props:
        errors.append(f"Tool defines field not in API: {extra}")

    for prop, api_def in api_schema.get("properties", {}).items():
        if prop in tool_schema.get("properties", {}):
            tool_def_prop = tool_schema["properties"][prop]
            if api_def.get("type") != tool_def_prop.get("type"):
                errors.append(
                    f"Type mismatch on {prop}: API={api_def.get('type')} "
                    f"tool={tool_def_prop.get('type')}"
                )

    return errors
Enter fullscreen mode Exit fullscreen mode

Chạy script này trong CI trên mọi PR thay đổi:

  • openapi.yaml
  • Tool definition
  • Endpoint request schema
  • Agent capability config

Nếu errors không rỗng, fail build.

2. Mock/sandbox cho endpoint phá hoại

Mọi endpoint thay đổi state nên có môi trường test tương ứng:

Loại endpoint Môi trường dev nên dùng
GET Mock hoặc staging
POST Mock
PUT/PATCH Mock hoặc sandbox DB
DELETE Mock, soft delete trong staging
Payment/refund Sandbox provider

Vòng lặp phát triển tác nhân không nên gọi production.

Apidog có thể tạo mock từ OpenAPI, bao gồm response theo schema. Bạn trỏ base URL của tác nhân sang mock server, ví dụ:

AGENT_API_BASE_URL=https://mock.apidog.com/m1/your-project-id/
Enter fullscreen mode Exit fullscreen mode

Nếu tác nhân hiểu sai tài liệu và gọi DELETE /users/{id}, mock server sẽ ghi nhận request mà không đụng database thật.

Tham khảo thêm: phát triển hợp đồng trước.

3. Idempotency key và soft delete

Mọi write endpoint mà tác nhân có thể gọi nên yêu cầu Idempotency-Key.

Ví dụ Express middleware:

const idempotencyCache = new Map();

function idempotency(req, res, next) {
  const key = req.headers['idempotency-key'];

  if (!key) {
    return res.status(400).json({
      error: 'Missing Idempotency-Key header'
    });
  }

  if (idempotencyCache.has(key)) {
    const cached = idempotencyCache.get(key);
    return res.status(cached.status).json(cached.body);
  }

  const originalJson = res.json.bind(res);

  res.json = function (body) {
    idempotencyCache.set(key, {
      status: res.statusCode,
      body
    });

    setTimeout(() => {
      idempotencyCache.delete(key);
    }, 24 * 60 * 60 * 1000);

    return originalJson(body);
  };

  next();
}

app.post('/payments', idempotency, createPayment);
Enter fullscreen mode Exit fullscreen mode

Agent-side pattern:

import { randomUUID } from "crypto";

const operationId = randomUUID();

await fetch(`${API_BASE_URL}/payments`, {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    "Idempotency-Key": operationId
  },
  body: JSON.stringify({
    customer_id: "cus_123",
    amount: 1900
  })
});
Enter fullscreen mode Exit fullscreen mode

Khi retry cùng một logical operation, tác nhân dùng lại key cũ. API trả lại response đã cache thay vì tạo payment mới.

Với delete operation, mặc định nên là soft delete:

UPDATE users
SET deleted_at = NOW()
WHERE id = $1;
Enter fullscreen mode Exit fullscreen mode

Hard delete nên là endpoint riêng, yêu cầu human approval.

4. Budget limit cho từng tác nhân

Mỗi tác nhân cần ngân sách rõ ràng:

  • Token/session
  • API call/phút
  • Tổng chi phí/tác vụ
  • Tool call depth
  • Thời gian chạy tối đa

Ví dụ policy:

agent_budget:
  max_tokens_per_session: 50000
  max_api_calls_per_minute: 30
  max_cost_cents_per_task: 500
  max_tool_call_depth: 10
  max_runtime_seconds: 300
Enter fullscreen mode Exit fullscreen mode

Khi vượt giới hạn, API gateway nên trả:

HTTP/1.1 429 Too Many Requests
Retry-After: 60
X-Budget-Exceeded: max_api_calls_per_minute
Content-Type: application/json

{
  "error": "Agent budget exceeded",
  "limit": "max_api_calls_per_minute",
  "action": "escalate_to_human"
}
Enter fullscreen mode Exit fullscreen mode

Planner của tác nhân phải dừng, log lại và chuyển cho con người thay vì tiếp tục retry.

Kiểm thử lệnh gọi API của tác nhân bằng Apidog

Dưới đây là workflow thực tế để kiểm thử agent-API integration trong Apidog.

Bạn cần:

  • File OpenAPI 3.x
  • Danh sách tool definition của tác nhân
  • Bộ prompt hoặc scenario tác nhân thường chạy
  • Environment config cho mock/staging/production

Bước 1: Nhập OpenAPI

Trong Apidog:

  1. Tạo project mới.
  2. Import file OpenAPI 3.x.
  3. Kiểm tra các path, request body, response schema.
  4. Đánh dấu các endpoint có side effect: POST, PUT, PATCH, DELETE.

Nếu API chưa có OpenAPI, hãy tạo trước. Agent reliability phụ thuộc vào một source of truth chung cho cả developer, QA và tool schema.

Tham khảo: quy trình API design-first.

Bước 2: Tạo mock response cho endpoint phá hoại

Với từng endpoint thay đổi dữ liệu:

  1. Mở endpoint trong Apidog.
  2. Thêm mock response.
  3. Dùng schema thật nhưng dữ liệu test rõ ràng.
  4. Tránh dùng giá trị giống production.

Ví dụ response mock cho delete user:

{
  "id": "mock_user_1970_001",
  "status": "deleted",
  "deleted_at": "1970-01-01T00:00:00Z"
}
Enter fullscreen mode Exit fullscreen mode

Sau đó khởi động mock server và cấu hình tác nhân:

AGENT_API_BASE_URL=https://mock.apidog.com/m1/your-project-id/
Enter fullscreen mode Exit fullscreen mode

Bây giờ tác nhân có thể gọi DELETE /users/{id} trong dev mà không ảnh hưởng production.

Xem thêm: phát triển hợp đồng trước.

Bước 3: Viết scenario mô phỏng chuỗi tool call

Scenario trong Apidog nên phản ánh chuỗi tác nhân sẽ thực hiện.

Ví dụ tác nhân phân loại ticket:

  1. POST /auth/token để lấy bearer token.
  2. GET /tickets?status=open để lấy ticket đầu tiên.
  3. POST /tickets/{id}/triage để gán category.
  4. POST /notifications để gửi thông báo.
  5. Assert status code, schema và field quan trọng.

Ví dụ assertion cần có:

pm.test("triage returns assigned_to", function () {
  const json = pm.response.json();
  pm.expect(json.assigned_to).to.be.a("string");
});

pm.test("notification message is safe", function () {
  const json = pm.response.json();
  pm.expect(json.message).to.match(/^Ticket #[0-9]+ assigned to /);
});
Enter fullscreen mode Exit fullscreen mode

Nếu developer đổi schema ticket khiến regex fail, scenario sẽ báo lỗi trước khi tác nhân chạy trên production.

Tham khảo thêm: kiểm thử API cho kỹ sư QA.

Bước 4: Chạy scenario trong CI

Dùng Apidog CLI trong GitHub Actions, GitLab CI hoặc runner nội bộ.

Ví dụ command:

apidog run -t scenario-id --env test
Enter fullscreen mode Exit fullscreen mode

Ví dụ GitHub Actions:

name: Agent API Contract Tests

on:
  pull_request:
    paths:
      - "openapi.yaml"
      - "agents/**"
      - "tools/**"

jobs:
  test-agent-api:
    runs-on: ubuntu-latest

    steps:
      - uses: actions/checkout@v4

      - name: Install Apidog CLI
        run: npm install -g apidog-cli

      - name: Run Apidog scenario
        run: apidog run -t ${{ secrets.APIDOG_SCENARIO_ID }} --env test
Enter fullscreen mode Exit fullscreen mode

Mục tiêu: mọi thay đổi đến API hoặc tool definition đều phải replay scenario trước khi merge.

Bước 5: So sánh hành vi giữa hai model

Khi đổi model, đừng chỉ so sánh câu trả lời. Hãy so sánh tool call trace.

Quy trình:

  1. Chạy cùng prompt set với model A.
  2. Ghi lại request body, endpoint, header, thứ tự tool call.
  3. Chạy lại với model B.
  4. Diff trace.

Bạn có thể phát hiện sớm các thay đổi như:

  • Model B bỏ qua field bắt buộc.
  • Model B truyền priority khác.
  • Model B format ngày khác.
  • Model B gọi endpoint hai lần.
  • Model B retry dù response đã thành công.

Pattern này đặc biệt hữu ích khi đánh giá model mới, như trong bài tích hợp API GPT-5.5.

Kỹ thuật nâng cao

Đặt temperature = 0 khi test tool call

Bạn đang kiểm thử lớp tool/API, không kiểm thử tính sáng tạo. Hãy cố định:

temperature: 0
seed: 1234
Enter fullscreen mode Exit fullscreen mode

Điều này giúp test ổn định và diff dễ đọc hơn.

Snapshot tool call trace

Mỗi test run nên lưu:

{
  "tool": "create_refund",
  "method": "POST",
  "path": "/refunds",
  "arguments": {
    "payment_id": "pay_123",
    "amount": 1900
  }
}
Enter fullscreen mode Exit fullscreen mode

Sau đó so với baseline. Nếu tác nhân đột nhiên gọi thêm /users hoặc đổi amount, CI nên cảnh báo/fail.

Không cấp credential production trực tiếp cho tác nhân

Tác nhân chỉ nên dùng service account giới hạn scope.

Không nên:

DATABASE_URL=postgres://prod...
STRIPE_SECRET_KEY=sk_live_...
Enter fullscreen mode Exit fullscreen mode

Nên dùng:

  • Short-lived token
  • Proxy ký request
  • Read-only key mặc định
  • Write key chỉ dùng sau human approval

Tách read key và write key

Phần lớn tác vụ của tác nhân là đọc. Hãy cấp read-only token cho default flow.

permissions:
  tickets:read: true
  tickets:write: false
  payments:refund: false
Enter fullscreen mode Exit fullscreen mode

Write operation nên yêu cầu approval gate.

Dùng HTTP 423 cho thao tác cần xác nhận

Khi tác nhân gọi endpoint cần human approval, trả về:

HTTP/1.1 423 Locked
Content-Type: application/json

{
  "error": "Human confirmation required",
  "confirmation_url": "https://internal.example.com/approve/req_123"
}
Enter fullscreen mode Exit fullscreen mode

423 Locked rõ nghĩa hơn 403 Forbidden: tác nhân chưa được phép tiếp tục cho đến khi có xác nhận.

Fail closed khi schema drift

Nếu tool schema lệch OpenAPI:

  • Không warning.
  • Không log rồi bỏ qua.
  • Fail CI ngay.

Chi phí của một build fail thấp hơn nhiều so với production incident.

Lỗi phổ biến cần tránh

  • Hard-code mock URL trong prompt. Hãy dùng biến môi trường.
  • Bỏ qua idempotency cho endpoint “nhỏ” như gửi email.
  • Log toàn bộ request body chứa PII.
  • Cho tác nhân truy cập database trực tiếp.
  • Tin vào confidence score của model như tín hiệu an toàn.
  • Dùng production credential trong local agent run.
  • Không replay scenario khi đổi model.
  • Không giới hạn số lần retry.

Nếu hệ thống của bạn gồm nhiều service nội bộ, xem thêm các mẫu kiểm thử microservice.

Công cụ và lựa chọn thay thế

Phương pháp Thời gian thiết lập Ưu điểm Nhược điểm Phù hợp với
Unit test thủ công Thấp Kiểm soát hoàn toàn, không phụ thuộc vendor Dễ lệch khỏi API thật, tốn công bảo trì Dự án nhỏ
LangSmith / LangGraph eval Trung bình Replay trace tốt, có metric cho model Mạnh ở lớp agent, yếu hơn ở lớp API Nhóm AI tập trung vào eval
Postman + Postbot Trung bình Giao diện quen thuộc, nhiều template Mock server là tiện ích trả phí, scripting cũ Nhóm đã dùng Postman lâu
Apidog scenario + mock Trung bình OpenAPI-native, mock, scenario, CLI cho CI Nhận diện thương hiệu kém hơn Postman Nhóm muốn một workflow cho design, mock và test

Nếu bạn đã dùng LangSmith, hãy tiếp tục dùng cho prompt/model eval và thêm lớp API testing riêng. Nếu bạn đang tìm lựa chọn thay thế Postman, xem Apidog là một sự thay thế mạnh mẽ. Nếu bắt đầu mới, hãy chọn công cụ xử lý OpenAPI, mock và scenario test trong cùng một project.

Use case thực tế

Tác nhân cập nhật row trong production database

Một nhóm support xây tác nhân cập nhật trường tài khoản từ ticket. Trước khi deploy, họ:

  • Bắt mọi write endpoint yêu cầu idempotency key
  • Chạy 200 scenario replay trong Apidog trên sandbox DB
  • Assert enum cho subscription_status
  • Chặn hard delete

Replay phát hiện hai lần tác nhân cố set subscription_status thành string ngoài enum. Nhóm thêm validation và deploy an toàn.

Tác nhân gọi payment API

Một nhóm fintech xây refund agent với policy:

  • Tối đa 5 refund/session
  • Tối đa 50 USD/refund
  • Bắt buộc idempotency key
  • Contract test với OpenAPI trên mỗi PR

Họ chạy bộ kiểm thử hợp đồng và xử lý 12.000 refund trong 6 tháng mà không tạo phí trùng.

Tác nhân phân loại GitHub issue

Một nhóm platform xây triage bot lấy cảm hứng từ Clawsweeper. Họ:

  • Mock GitHub API trong Apidog
  • Chạy 50 scenario test
  • Bao phủ issue bị xóa, thiếu label, user data sai format
  • Sửa 3 lỗi trước khi launch

Bot hiện xử lý triage cho repository công khai có 5.000 issue mở.

Checklist triển khai nhanh

Dùng checklist này cho agent mới trước khi production:

[ ] OpenAPI là source of truth
[ ] Tool schema được sinh hoặc validate từ OpenAPI
[ ] Contract test chạy trong CI
[ ] Mock server cho mọi endpoint ghi
[ ] Không dùng production credential trong dev
[ ] Mọi write endpoint yêu cầu Idempotency-Key
[ ] Delete mặc định là soft delete
[ ] Hard delete yêu cầu human approval
[ ] Rate limit theo agent/session
[ ] Budget limit theo token/request/chi phí
[ ] Tool call trace được snapshot
[ ] Scenario replay chạy trên mỗi PR
[ ] Model upgrade có trace diff
[ ] Log đã redact PII
Enter fullscreen mode Exit fullscreen mode

Kết luận

Nếu chỉ nhớ một điều: tác nhân không phải là vấn đề chính. API mới là nơi sự cố bị chặn lại hoặc được phép xảy ra.

Năm việc nên làm ngay:

  1. Coi tool schema là contract và test trong CI.
  2. Mock endpoint phá hoại trong mọi vòng lặp phát triển tác nhân.
  3. Bắt buộc idempotency key cho mọi write operation.
  4. Đặt budget limit cho từng tác nhân.
  5. Replay scenario trên mọi PR chạm đến API hoặc tool definition.

Các incident AI-agent sẽ còn tiếp diễn. Nhóm phục hồi nhanh là nhóm đã có guardrail trước khi sự cố xảy ra. Tải Apidog và bắt đầu từ mock server; chỉ bước đó đã có thể giúp bạn tránh một đêm xử lý production incident. Để xem thêm góc nhìn QA, đọc các công cụ kiểm thử API cho kỹ sư QA. Để viết tool definition an toàn hơn cho tác nhân, xem cách viết tệp AGENTS.md.

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

Làm cách nào kiểm thử API call của tác nhân AI mà không tốn token?

Chạy tác nhân với mock server trong development. URL mock của Apidog trả response theo schema mà không gọi API thật. Đặt temperature về 0 và dùng prompt set cố định để test ổn định. Xem danh sách kiểm thử của kỹ sư QA.

Kiểm thử tác nhân khác gì kiểm thử API?

Kiểm thử tác nhân xác minh model có chọn đúng tool và truyền đúng argument không. Kiểm thử API xác minh endpoint có xử lý request đúng không. Bạn cần cả hai. Tác nhân đúng gọi API lỗi vẫn gây lỗi; tác nhân lỗi gọi API đúng vẫn có thể gây sự cố.

Có cần idempotency key trên mọi endpoint không?

Có, với mọi write endpoint. Read operation vốn idempotent. Write operation thì không, và tác nhân sẽ retry. Middleware idempotency là một lớp bảo vệ rẻ nhưng hiệu quả.

Làm sao ngăn prompt injection kích hoạt API call nguy hiểm?

Không dựa hoàn toàn vào prompt. API phải enforce authorization theo user context gốc. Nếu user không có quyền gọi /admin/delete-all-users, tác nhân chạy thay user đó cũng không được quyền gọi endpoint này.

Có thể dùng Apidog trực tiếp với Claude hoặc GPT không?

Bạn trỏ base URL trong tool configuration của tác nhân sang mock URL của Apidog khi test. Khi chuyển sang staging hoặc production, đổi biến môi trường cho base URL. Cách này giữ nguyên tool definition và chỉ thay môi trường chạy.

Budget limit nên đặt bao nhiêu?

Bắt đầu chặt rồi nới theo dữ liệu. Ví dụ:

  • 50.000 token/session
  • 30 API call/phút
  • 5 USD/task
  • 10 nested tool call

Theo dõi trong 2 tuần, tăng giới hạn nếu workflow hợp lệ thường xuyên chạm trần, giảm giới hạn nếu không bao giờ dùng tới.

Làm sao phát hiện schema drift giữa tool và API?

Chạy schema comparison trong CI trên mỗi PR. So sánh JSON schema của tool với request body schema trong OpenAPI cho cùng endpoint. Nếu lệch field, type hoặc required property, fail build. Đoạn Python ở phần trên có thể dùng làm điểm khởi đầu.

Top comments (0)