Product Management
Đăng nhập
ESC

Nhập từ khóa để tìm kiếm

↑↓ Di chuyển
Enter Mở
ESC Đóng

Bài 6 — Độ tin cậy: timeout, retry, idempotency và xử lý lỗi legacy

Đã đọc 0/11 mục · còn khoảng 4 phút
Cách chúng tôi ghi nhận

Một mục được tính là đã đọc khi nó nằm giữa màn hình đủ lâu so với độ dài của nó (bảng và sơ đồ tính một nửa), bạn vẫn đang cuộn hoặc bấm phím, và bạn đã thấy tới cuối mục. Lướt nhanh hoặc để tab mở không được tính. Chúng tôi chỉ lưu thời gian đọc từng mục — không lưu gì khác.

Hệ thống legacy sẽ trục trặc: API treo, DB timeout, RPA gặp popup lạ, mạng nội bộ chập chờn. Một agent production phải giả định thất bại là bình thường và xử lý gọn gàng. Bài này xây lớp độ tin cậy quanh mọi tool.

Timeout: không chờ vô hạn

Mọi lời gọi ra hệ thống ngoài phải có timeout. Một API legacy treo mà không timeout sẽ làm cả agent đứng, kéo theo hàng loạt yêu cầu khác nghẽn.

r = requests.post(url, data=payload, timeout=8)   # luon dat timeout

Đặt timeout theo bản chất: đọc nhanh 3–5s, thao tác nặng 15–30s. Thà báo lỗi sớm còn hơn treo mãi.

Retry có kỷ luật: chỉ retry lỗi tạm thời

Retry đúng chỗ, sai chỗ là thảm họa:

  • Nên retry: lỗi mạng, timeout, HTTP 503/429 (tạm thời).
  • Không retry: HTTP 400/401/403 (input sai, sai quyền) — retry chỉ lặp lại lỗi.
Dùng exponential backoff (chờ tăng dần) để không dội bom hệ thống đang yếu:

import time
def with_retry(fn, max_try=3):
    for i in range(max_try):
        try:
            return fn()
        except (Timeout, ConnectionError) as e:   # chi loi tam thoi
            if i == max_try - 1:
                raise
            time.sleep(2 ** i)                      # 1s, 2s, 4s

Idempotency: retry không được tạo trùng

Đây là điểm chết người. Giả sử agent gọi tao_don, API tạo đơn thành công nhưng phản hồi bị mất do timeout. Agent retry → tạo đơn thứ hai. Khách bị tính tiền hai lần.

Giải pháp: mỗi hành động ghi mang một idempotency key (mã duy nhất). Hệ thống đích (hoặc bảng staging) nếu thấy key đã tồn tại thì trả về kết quả cũ, không tạo mới.

import uuid
key = f"order-{ma_don}-{uuid.uuid4().hex[:8]}"
# gui key nay kem request; retry dung DUNG key do
# -> he thong dich: neu key da co, tra ket qua cu

Với bảng staging, đặt UNIQUE constraint trên cột key: INSERT trùng sẽ bị chặn ở tầng DB.

Circuit breaker: ngắt mạch khi hệ thống sập

Nếu ERP đang sập, đừng để agent thử đi thử lại làm mọi thứ tệ hơn. Circuit breaker: sau N lỗi liên tiếp, "mở mạch" — tạm ngừng gọi trong X phút, trả lỗi thân thiện ngay, rồi thử lại sau.

Trả lỗi cho agent hiểu

Wrapper nên trả mã lỗi có nghĩa, không ném stacktrace thô cho LLM:

{"ok": false, "code": "ERP_TIMEOUT",
 "message": "He thong tam thoi ban, thu lai sau"}

Agent đọc code để quyết định: xin lỗi khách, chuyển người, hay thử lại.

Checklist độ tin cậy cho mỗi tool

  • [ ] Có timeout hợp lý.
  • [ ] Retry chỉ cho lỗi tạm thời, có backoff.
  • [ ] Hành động ghi có idempotency key.
  • [ ] Bảng staging có UNIQUE constraint.
  • [ ] Trả mã lỗi có cấu trúc, không stacktrace thô.
  • [ ] Có circuit breaker cho hệ thống hay sập.
  • [ ] Có fallback khi hệ thống chết (chuyển người/hàng đợi).

Sai lầm thường gặp

  • Không timeout → agent treo theo hệ thống.
  • Retry mọi loại lỗi kể cả 400/401 → lặp lỗi vô ích, khóa tài khoản.
  • Retry hành động ghi không idempotent → tạo đơn trùng, tính tiền đôi.
  • Retry dồn dập không backoff → dội sập hệ thống vốn đã yếu.
  • Ném stacktrace cho LLM → agent hiểu sai, trả lời lung tung.

Fallback: khi hệ thống chết hẳn, agent làm gì

Retry và circuit breaker giúp chịu lỗi tạm thời, nhưng sẽ có lúc hệ thống đích chết hẳn trong nhiều giờ. Agent không được "treo" khách ở đó. Hãy thiết kế đường lui rõ ràng: với thao tác đọc, trả lời trung thực "hệ thống đang bảo trì, mình sẽ cập nhật sau" thay vì bịa số liệu. Với thao tác ghi, đẩy yêu cầu vào một hàng đợi bền (durable queue) để xử lý lại khi hệ thống sống lại, hoặc chuyển cho nhân viên xử lý tay. Nguyên tắc là: thà chậm và đúng, còn hơn trả lời sai vì hệ thống đang sập.

Phân biệt lỗi tạm thời và lỗi nghiệp vụ

Một điểm hay bị nhầm: không phải mọi phản hồi "thất bại" đều đáng retry. Nếu ERP trả về "khách hàng không đủ hạn mức công nợ", đó là một kết quả nghiệp vụ hợp lệ, không phải lỗi hạ tầng — retry sẽ chỉ nhận lại đúng câu trả lời đó. Wrapper nên tách rõ hai nhóm: lỗi hạ tầng (timeout, mất kết nối) thì retry; còn kết quả nghiệp vụ (từ chối, không tìm thấy) thì trả về cho agent để nó phản hồi khách phù hợp. Nhầm lẫn hai nhóm này khiến agent vừa tốn thời gian vừa gây khó chịu cho khách.

Tổng kết

Độ tin cậy là thứ phân biệt demo với production. Đặt timeout, retry có kỷ luật với backoff, gắn idempotency key cho mọi hành động ghi, thêm circuit breaker, phân biệt lỗi hạ tầng với kết quả nghiệp vụ, và luôn có đường lui khi hệ thống chết. Giả định legacy sẽ hỏng — và chuẩn bị để agent hỏng một cách an toàn.

Học xong bài này rồi? Tạo tài khoản miễn phí để lưu lại — lần sau vào là biết ngay đang dở ở đâu, và học hết khóa thì có chứng chỉ. Lưu tiến độ của tôi