Tool gọi ra thế giới thật, nên nó sẽ hỏng: API timeout, mạng rớt, rate limit, dữ liệu thiếu. Agent xịn không phải là agent không bao giờ gặp lỗi, mà là agent phục hồi được từ lỗi. Bài này dạy chiến lược retry và cách để model tự sửa. Nguyên tắc bao trùm: một lỗi được xử lý tốt là một lỗi biến thành thông tin — hoặc để hệ thống retry, hoặc để model điều chỉnh, hoặc để người dùng biết chuyện gì xảy ra. Lỗi tệ nhất là lỗi bị nuốt im lặng.
Phân loại lỗi để xử lý đúng
Không phải lỗi nào cũng retry được. Phân loại trước:
- Lỗi tạm thời (transient) — timeout, 503, rate limit 429, mạng chập chờn. → Retry được với backoff.
- Lỗi đầu vào (client error) — tham số sai, 400, email không tồn tại. → Không retry; trả lỗi cho model để nó sửa tham số.
- Lỗi nghiệp vụ — "đơn hàng đã hủy, không thể cập nhật". → Không retry; đây là kết quả hợp lệ, để model diễn giải cho người dùng.
Retry với exponential backoff
Với lỗi transient, chờ tăng dần và có jitter để tránh dồn tải:
import time, random
def call_with_retry(fn, *args, max_tries=3):
for attempt in range(max_tries):
try:
return fn(*args)
except TransientError as e:
if attempt == max_tries - 1:
raise
wait = (2 ** attempt) + random.uniform(0, 0.5) # 1s, 2s, 4s + jitter
time.sleep(wait)
Để MODEL tự sửa: trả lỗi có cấu trúc
Đây là kỹ thuật mạnh nhất của tool-use. Với lỗi đầu vào, đừng crash — trả một message lỗi rõ ràng, gợi ý sửa về cho model. Model đọc và tự gọi lại đúng:
def dispatch(name, args):
try:
return {"ok": TOOLS[name]["fn"](**args)}
except ValidationError as e:
return {"error": "invalid_args",
"message": f"Tham số sai: {e}. Hãy kiểm tra và gọi lại.",
"retryable": False}
except TransientError:
return {"error": "temporary",
"message": "Dịch vụ tạm gián đoạn, đã thử lại nhưng thất bại."}
Ví dụ: model gọi get_weather(city="Danang") nhưng registry dùng "Da Nang". Bạn trả {"error": "Không tìm thấy 'Danang'. Các thành phố hợp lệ: Da Nang, Ha Noi"}. Model đọc, gọi lại get_weather(city="Da Nang") và thành công. Bạn vừa cho model khả năng tự sửa.
Khung tư duy: cây quyết định khi lỗi
Lỗi xảy ra
├─ Transient? → retry backoff (tối đa N lần) → vẫn lỗi? báo model "tạm gián đoạn"
├─ Sai tham số? → trả lỗi mô tả + gợi ý → để MODEL gọi lại
└─ Nghiệp vụ? → trả kết quả hợp lệ → để MODEL diễn giải
Chống retry vô hạn ở tầng agent
Ngoài retry trong từng tool, đặt ngân sách toàn cục: tối đa số lần gọi tool, hoặc theo dõi cùng một tool call lặp lại. Nếu model gọi get_weather("X") ba lần với cùng lỗi, dừng và trả lời người dùng — đừng để nó lặp mãi.
if call_signature in seen and seen[call_signature] >= 2:
return {"error": "Đã thử tool này nhiều lần không thành công, dừng lại."}
Checklist độ bền
- [ ] Phân loại lỗi: transient / input / business.
- [ ] Chỉ retry lỗi transient, có backoff + jitter.
- [ ] Lỗi input trả message gợi ý sửa cho model.
- [ ] Có timeout cho mọi lời gọi mạng.
- [ ] Có ngân sách tool call toàn cục + phát hiện lặp.
- [ ] Ghi log mọi lỗi kèm tham số (để debug sau).
Sai lầm thường gặp
- Retry mọi loại lỗi. Retry một lỗi 400 chỉ đốt tiền; nó sẽ không bao giờ thành công.
- Retry không backoff. Bắn lại ngay lập tức làm nặng thêm API đang quá tải, dễ bị ban.
- Nuốt lỗi im lặng.
except: passkhiến agent trả lời sai mà bạn không biết vì sao. - Không đặt timeout. Một API treo có thể khiến toàn bộ agent đứng vô thời hạn.
- Trả lỗi kỹ thuật thô cho model. Stack trace dài làm model rối; hãy tóm gọn thành message hành động được.
- Quên chống loop. Model kẹt trong vòng gọi-lỗi-gọi-lỗi sẽ cháy quota nếu không có trần.