DEV Community

Cover image for Tại sao AI Agent gặp sự cố khi vận hành và cách kiểm tra từng loại lỗi
Sebastian Petrus
Sebastian Petrus

Posted on • Originally published at apidog.com

Tại sao AI Agent gặp sự cố khi vận hành và cách kiểm tra từng loại lỗi

Tác nhân của bạn có thể hoạt động tốt trong bản demo: đọc phiếu, gọi ba API và đăng bản tóm tắt. Nhưng sau khi triển khai, nó có thể gửi email trùng lặp, đốt ngân sách token vì vòng lặp thử lại, hoặc trả về payload mà giao diện không phân tích được. Khoảng cách giữa nguyên mẫu và tác nhân đáng tin cậy nằm ở các API mà tác nhân gọi: mọi yêu cầu HTTP đều có thể hết thời gian chờ, bị giới hạn tốc độ, trả về lỗi hoặc sai định dạng.

Dùng thử Apidog ngay hôm nay

Bạn không cần tin rằng mô hình luôn xử lý đúng. Thay vào đó, hãy chủ động kiểm thử các đường dẫn lỗi tại ranh giới API trước khi người dùng gặp chúng. Bài viết này tập trung vào năm chế độ lỗi phổ biến và cách kiểm thử từng chế độ bằng hợp đồng API, mock và assertion. Apidog hỗ trợ quản lý hợp đồng, mô phỏng phản hồi lỗi và xác thực dữ liệu trả về.

Tác nhân thất bại ở ranh giới API, không phải chỉ trong lời nhắc

Khi tác nhân hoạt động sai ở production, phản ứng thường thấy là sửa prompt. Điều này đôi khi hữu ích, nhưng nhiều lỗi thực tế xuất phát từ tích hợp:

  1. Mô hình chọn một công cụ.
  2. Ứng dụng chuyển lựa chọn đó thành yêu cầu HTTP.
  3. Dịch vụ bên ngoài trả phản hồi.
  4. Ứng dụng đưa kết quả về lại cho mô hình.

Trong bốn bước này, ba bước là bài toán tích hợp API thông thường. API có thể trả chậm, trả 429, trả 500, hết thời gian chờ hoặc trả JSON có cấu trúc khác dự kiến. Điểm khác biệt là tác nhân có thể suy luận và hành động tiếp trên dữ liệu lỗi, thay vì ném ra một exception rõ ràng.

Câu hỏi cần trả lời không phải là:

Mô hình có đủ thông minh không?

Mà là:

Tôi đã kiểm thử mọi cách mà các API của tác nhân có thể thất bại chưa?

Chế độ lỗi 1: Cuộc gọi công cụ lệch hợp đồng

Lỗi phổ biến nhất là tác nhân tạo một tool call không khớp với API đích:

  • Thiếu trường bắt buộc.
  • Dùng sai kiểu dữ liệu.
  • Gửi giá trị enum không hợp lệ.
  • Gọi đúng endpoint nhưng truyền tham số vô nghĩa.

Ví dụ, tác nhân đặt chỗ gọi POST /reservations với:

{
  "guests": "two"
}
Enter fullscreen mode Exit fullscreen mode

Trong khi API yêu cầu:

{
  "guests": 2
}
Enter fullscreen mode Exit fullscreen mode

API có thể trả 400. Tệ hơn, API có thể trả 200 nhưng nhúng lỗi trong body, khiến tác nhân tiếp tục như thể thao tác đã thành công.

Cách kiểm thử

Định nghĩa schema cho từng công cụ mà tác nhân được phép gọi. Sau đó xác thực request trước khi gửi hoặc trong bài kiểm thử tích hợp.

Ví dụ schema JSON cho công cụ tạo đặt chỗ:

{
  "type": "object",
  "required": ["guests", "date"],
  "properties": {
    "guests": {
      "type": "integer",
      "minimum": 1
    },
    "date": {
      "type": "string",
      "format": "date"
    }
  },
  "additionalProperties": false
}
Enter fullscreen mode Exit fullscreen mode

Bài kiểm thử nên thất bại rõ ràng nếu tác nhân tạo request sai:

expect(toolCall.arguments).toMatchSchema(reservationSchema);
Enter fullscreen mode Exit fullscreen mode

Đọc thêm về kiểm thử các cuộc gọi công cụ của tác nhân AIkiểm thử các tác nhân gọi API của bạn.

Việc cần làm

  1. Liệt kê toàn bộ tool mà tác nhân có thể gọi.
  2. Viết hoặc nhập schema OpenAPI/JSON Schema cho từng endpoint.
  3. Tải hợp đồng vào Apidog.
  4. Chạy các tool call thực tế của tác nhân qua validation.
  5. Chặn triển khai nếu request vi phạm hợp đồng.

Chế độ lỗi 2: Lỗi upstream và giới hạn tốc độ

Mọi dependency bên ngoài đều có thể trả về:

  • 429 Too Many Requests
  • 500 Internal Server Error
  • Kết nối bị ngắt
  • Hết thời gian chờ
  • Phản hồi chậm bất thường

Một tác nhân tốt cần retry có kiểm soát. Một tác nhân kém có thể bỏ cuộc ngay ở lỗi đầu tiên, hoặc retry quá mạnh đến mức tự tạo thêm 429 và làm cạn ngân sách token. Các mẫu phục hồi lỗi tác nhân là chủ đề phổ biến trong cộng đồng SDK vì đây là lỗi production rất thường gặp.

Cách kiểm thử

Không thể kiểm thử error recovery bằng API luôn khỏe mạnh. Hãy mock dependency và lập trình một chuỗi phản hồi lỗi:

  1. Trả 429 kèm Retry-After.
  2. Trả 500.
  3. Trả phản hồi thành công.
  4. Kiểm tra số lần gọi, thời gian chờ và kết quả cuối cùng.

Ví dụ pseudo-code:

mockServer
  .onPost("/payments")
  .reply(429, { error: "rate_limited" }, { "Retry-After": "2" })
  .onPost("/payments")
  .reply(500, { error: "upstream_failure" })
  .onPost("/payments")
  .reply(200, { status: "paid", paymentId: "pay_123" });
Enter fullscreen mode Exit fullscreen mode

Sau đó kiểm tra:

expect(retryCount).toBeLessThanOrEqual(3);
expect(totalDelayMs).toBeGreaterThanOrEqual(2000);
expect(result.status).toBe("paid");
Enter fullscreen mode Exit fullscreen mode

Các câu hỏi cần trả lời trong bài kiểm thử:

  • Tác nhân có tôn trọng header Retry-After không?
  • Retry có exponential backoff và jitter không?
  • Có giới hạn số lần retry không?
  • Có dừng đúng cách khi upstream tiếp tục lỗi không?
  • Có circuit breaker để tránh tiếp tục gọi một dịch vụ đang ngừng hoạt động không?
  • Thao tác retry có an toàn để lặp lại không?

Với thao tác tạo đơn hàng, gửi email hoặc thanh toán, hãy dùng khóa bất biến để retry không gây gửi trùng hoặc tính phí trùng.

Xem thêm hướng dẫn về phản hồi vượt quá giới hạn tốc độphục hồi lỗi tác nhân AI.

Chế độ lỗi 3: Đầu ra không xác định

Ngay cả khi đặt temperature bằng 0, đầu ra mô hình vẫn có thể thay đổi giữa các lần chạy. Seed và temperature không luôn đủ để tái tạo kết quả; phần cứng, batching và thay đổi phía nhà cung cấp đều tạo ra biến động. Vấn đề này được thảo luận trong chuỗi vLLM.

Nếu bài kiểm thử khẳng định chuỗi kết quả chính xác, test sẽ dễ flaky. Và test flaky thường bị bỏ qua, khiến chúng trở nên kém giá trị hơn cả việc không có test.

Cách kiểm thử

Khẳng định về cấu trúc và ý nghĩa thay vì văn bản chính xác.

Thay vì:

expect(answer).toBe("Tổng đơn hàng là 120.000 VNĐ");
Enter fullscreen mode Exit fullscreen mode

Hãy kiểm tra schema và miền giá trị:

expect(response).toMatchObject({
  total: expect.any(Number),
  currency: "VND"
});

expect(response.total).toBeGreaterThanOrEqual(0);
expect(response.total).toBeLessThanOrEqual(cart.total);
Enter fullscreen mode Exit fullscreen mode

Với tool call, kiểm tra endpoint, kiểu hành động và tham số quan trọng:

expect(toolCall.name).toBe("create_refund");
expect(toolCall.arguments.orderId).toBe(orderId);
expect(toolCall.arguments.amount).toBeLessThanOrEqual(orderTotal);
Enter fullscreen mode Exit fullscreen mode

Các assertion nên bao gồm:

  • JSON hợp lệ theo schema.
  • Có đủ khóa bắt buộc.
  • Không xuất hiện trường bị cấm.
  • Giá trị số nằm trong phạm vi hợp lý.
  • Tool call đúng tên, đúng mục tiêu và đúng tham số.
  • Tác nhân không thực hiện hành động vượt phạm vi.

Đọc thêm về kiểm thử các tác nhân AI không xác định, những nguyên nhân gây ra các bài kiểm thử không ổn địnhcách bộ nhớ tác nhân hoạt động.

Chế độ lỗi 4: Chi phí vượt tầm kiểm soát

Tác nhân chạy theo vòng lặp, và mỗi vòng lặp tiêu tốn token, thời gian và API quota. Một tác nhân kẹt trong retry có thể thực hiện hàng nghìn cuộc gọi chỉ trong một đêm.

Chi phí cũng là vấn đề độ tin cậy:

  • Retry quá nhiều làm tăng độ trễ.
  • Context quá lớn làm phản hồi khó dự đoán.
  • Tool call dư thừa tăng xác suất lỗi.
  • Vòng lặp không kiểm soát có thể làm cạn ngân sách.

Cách kiểm thử

Theo dõi số cuộc gọi và token trong từng kịch bản kiểm thử.

expect(metrics.toolCalls).toBeLessThanOrEqual(8);
expect(metrics.totalTokens).toBeLessThanOrEqual(12_000);
expect(metrics.elapsedMs).toBeLessThan(30_000);
Enter fullscreen mode Exit fullscreen mode

Đặt giới hạn ở runtime:

const limits = {
  maxToolCalls: 8,
  maxRetriesPerTool: 3,
  maxTokens: 12_000,
  timeoutMs: 30_000
};
Enter fullscreen mode Exit fullscreen mode

Khi bất kỳ giới hạn nào bị vượt, tác nhân phải dừng và trả về trạng thái có thể xử lý:

{
  "status": "budget_exceeded",
  "message": "Tác vụ đã dừng vì vượt giới hạn số lần gọi công cụ."
}
Enter fullscreen mode Exit fullscreen mode

Khi chạy test phục hồi lỗi với mock, luôn assert cả kết quả và số lượng request. Một tác nhân cuối cùng trả về thành công nhưng phải gọi API 40 lần vẫn là một sự cố chi phí đang chờ xảy ra.

Xem hướng dẫn về giảm chi phí token tác nhân.

Chế độ lỗi 5: Thiếu hàng rào bảo vệ

Lỗi nguy hiểm nhất xảy ra khi tác nhân làm đúng điều được yêu cầu nhưng hành động đó không nên được thực hiện tự động. Ví dụ:

  • Gửi email cho khách hàng hoặc quản lý.
  • Xóa dữ liệu.
  • Hủy đơn hàng.
  • Hoàn tiền.
  • Tạo giao dịch hoặc đặt hàng.

Tác nhân không nên được phép chuyển trực tiếp từ quyết định của mô hình sang hành động có tác dụng phụ.

Cách triển khai hàng rào bảo vệ

Dùng ít nhất ba lớp bảo vệ:

  1. Allowlist hành động: chỉ các action được duyệt mới có thể chạy tự động.
  2. Phê duyệt của con người: yêu cầu xác nhận trước các thao tác phá hủy hoặc không thể đảo ngược.
  3. Chế độ dry-run: mô tả hành động dự kiến nhưng không thực thi.

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

const policy = {
  autoApproved: ["get_order", "search_customer", "draft_email"],
  requiresApproval: ["send_email", "delete_record", "create_refund"],
  blocked: ["transfer_funds"]
};
Enter fullscreen mode Exit fullscreen mode

Trước khi gọi tool:

function authorizeTool(toolName: string) {
  if (policy.blocked.includes(toolName)) {
    throw new Error(`Tool bị chặn: ${toolName}`);
  }

  if (policy.requiresApproval.includes(toolName)) {
    return { requiresHumanApproval: true };
  }

  return { allowed: true };
}
Enter fullscreen mode Exit fullscreen mode

Cách kiểm thử hàng rào bảo vệ

Mock endpoint có tác dụng phụ, chạy tác nhân và xác nhận rằng request không được gửi trước khi có phê duyệt.

expect(mockServer.requests("/send-email")).toHaveLength(0);
expect(agentResult.status).toBe("awaiting_approval");
Enter fullscreen mode Exit fullscreen mode

Sau khi mô phỏng phê duyệt:

expect(mockServer.requests("/send-email")).toHaveLength(1);
Enter fullscreen mode Exit fullscreen mode

Dùng OWASP Top 10 cho các ứng dụng mô hình ngôn ngữ lớn làm checklist bảo mật, đồng thời tham khảo hướng dẫn về hàng rào bảo vệ tác nhân AI.

Cách cấu trúc một bài kiểm thử tác nhân

Bạn có thể tái sử dụng cùng một cấu trúc cho cả năm chế độ lỗi.

1. Nắm bắt hợp đồng công cụ

Lưu schema cho mọi API mà tác nhân gọi:

  • Request body.
  • Query parameters.
  • Headers bắt buộc.
  • Response schema.
  • Mã lỗi dự kiến.

2. Mô phỏng dependency

Mock từng API để kiểm soát:

  • Mã trạng thái.
  • Độ trễ.
  • Timeout.
  • Header như Retry-After.
  • JSON sai định dạng.
  • Dữ liệu thiếu trường.
  • Tác dụng phụ.

3. Chạy kịch bản xấu

Đừng chỉ test happy path. Tạo các kịch bản như:

429 -> 500 -> 200
timeout -> timeout -> fallback
200 với JSON thiếu trường bắt buộc
tool call sai kiểu dữ liệu
yêu cầu xóa dữ liệu khi chưa có phê duyệt
Enter fullscreen mode Exit fullscreen mode

4. Khẳng định hành vi

Kiểm tra cả request và phản ứng của tác nhân:

expect(request.body).toMatchSchema(toolSchema);
expect(metrics.toolCalls).toBeLessThanOrEqual(8);
expect(agentResult.status).not.toBe("looping");
expect(agentResult.requiresApproval).toBe(true);
Enter fullscreen mode Exit fullscreen mode

Bắt đầu với một công cụ, hoàn thiện test harness, rồi mở rộng sang công cụ tiếp theo.

Danh sách kiểm tra độ tin cậy của tác nhân

Trước khi đưa tác nhân lên production, kiểm tra các mục sau:

  • [ ] Mỗi tool call được xác thực theo schema.
  • [ ] Vi phạm hợp đồng làm test thất bại rõ ràng.
  • [ ] 429, 500 và timeout được mô phỏng.
  • [ ] Retry có backoff, giới hạn số lần thử và tôn trọng Retry-After.
  • [ ] Các thao tác retry có idempotency key nếu có tác dụng phụ.
  • [ ] Test khẳng định cấu trúc và ý nghĩa, không phụ thuộc vào chuỗi chính xác.
  • [ ] Token, số tool call và thời gian chạy được đo lường.
  • [ ] Có ngân sách tối đa cho từng tác vụ.
  • [ ] Hành động phá hủy cần allowlist hoặc phê duyệt của con người.
  • [ ] Guardrail được test bằng mock, không chỉ được giả định.

Hoàn thành danh sách này giúp bạn bao phủ các lỗi thường gặp nhất của tác nhân ở production.

Apidog phù hợp ở đâu — và không phù hợp ở đâu

Apidog không phải là framework tác nhân, model server hay nền tảng đánh giá mô hình. Nó không xây dựng hoặc chạy tác nhân thay bạn.

Vai trò của Apidog là quản lý lớp API mà tác nhân phụ thuộc vào:

  • Thiết kế và lưu trữ hợp đồng API cho tool.
  • Xác thực request mà tác nhân tạo ra.
  • Mock các dependency.
  • Lập trình phản hồi 429, 500, timeout hoặc body sai định dạng.
  • Assert schema, trường bắt buộc và phạm vi giá trị của response.

Đây là phần phù hợp nhất với kiểm thử tác nhân: kiểm thử API mà tác nhân gọi, mô phỏng lỗi mà nó phải xử lý và kiểm tra dữ liệu quay về. Xem thêm tổng quan về kiểm thử AI tác nhân.

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

Độ tin cậy của tác nhân là vấn đề mô hình hay vấn đề kỹ thuật?

Chủ yếu là vấn đề kỹ thuật. Lựa chọn mô hình quan trọng, nhưng các lỗi gây sự cố thường là tool call sai, rate limit không được xử lý, retry không kiểm soát và thiếu guardrail. Đây là các vấn đề tích hợp và kiểm thử có thể giải quyết mà không cần đổi mô hình.

Tôi có thể kiểm thử tác nhân mà không gọi API thật không?

Có, và nên làm vậy. Mock dependency để ép API trả lỗi, kiểm soát thời gian phản hồi và tránh tác dụng phụ thật. Đây là cách đáng tin cậy để test error recovery và guardrail.

Làm sao kiểm thử khi output thay đổi giữa các lần chạy?

Khẳng định về schema, cấu trúc, tool call và phạm vi giá trị thay vì chuỗi văn bản chính xác. Tham khảo hướng dẫn kiểm thử các tác nhân AI không xác định.

Tôi nên kiểm thử gì trước?

Bắt đầu với:

  1. Guardrail cho hành động phá hủy.
  2. Error recovery cho 429, 500 và timeout.

Hai nhóm này bảo vệ bạn trước các lỗi đắt giá nhất: tác nhân thực hiện hành động gây hại, hoặc lặp vô hạn và làm cạn ngân sách.

Bắt đầu với một chế độ lỗi

Không cần kiểm thử cả năm chế độ ngay lập tức. Chọn một lỗi đáng lo nhất — thường là guardrail hoặc error recovery — rồi mock nó trong tuần này.

Quy trình tối thiểu:

  1. Chọn một tool có tác dụng phụ hoặc dependency dễ lỗi.
  2. Tạo mock response 429, 500 hoặc timeout.
  3. Chạy tác nhân.
  4. Kiểm tra retry, số request, token và hành vi dừng.
  5. Thêm assertion để đảm bảo tác nhân không lặp hoặc thực hiện hành động trái phép.

Tải xuống Apidog để thiết kế hợp đồng, mô phỏng lỗi và xác thực các phản hồi mà tác nhân của bạn phụ thuộc vào.

Top comments (0)