
Rất nhiều demo AI agent trông ổn cho tới lúc chạm production. Agent biết chọn tool, biết gọi API, biết tổng hợp câu trả lời. Nhưng khi traffic tăng lên hoặc tool bên dưới bắt đầu chậm, lỗi thật không đến từ prompt đẹp nữa. Nó đến từ những thứ rất quen với backend engineer: timeout, retry, duplicate side effect, race condition, partial failure và thiếu đường thoát sang con người.
Một agent có thể gọi search, rồi fetch, rồi send_email, rồi create_ticket. Nếu một bước ở giữa timeout, agent có retry không? Nếu retry thì có tạo ticket trùng không? Nếu tool trả kết quả stale hoặc schema đổi nhẹ, agent có loop vô hạn không? Nếu cần approval mà orchestration layer không chặn đúng chỗ, agent có thể vượt quyền không? Những failure mode này không phải vấn đề “AI thuần túy”. Chúng là bài toán reliability engineering trên một lớp execution mới.
Bài này đi theo góc nhìn technical dành cho team đang xây AI feature hoặc agent workflow thật: vì sao tool calling thường vỡ ở production, cách thiết kế execution contract cho từng tool, timeout budget theo chuỗi call, retry/idempotency/circuit breaker, human handoff, observability, và checklist release gate trước khi cho agent động vào hệ thống thật.
Tool calling không chỉ là function calling, mà là distributed system thu nhỏ
Về mặt giao diện, tool calling nhìn khá đơn giản:
- model quyết định gọi tool nào;
- orchestration layer validate input;
- tool chạy side effect hoặc đọc dữ liệu;
- kết quả trả lại model;
- model quyết định bước tiếp theo.
Nhưng ở production, mỗi vòng như vậy là một mini distributed workflow với nhiều boundary:
- model boundary;
- orchestrator boundary;
- internal API boundary;
- third-party SaaS boundary;
- permission boundary;
- human approval boundary.
Chỉ cần một boundary không có contract đủ rõ, agent sẽ bắt đầu hành xử khó đoán. Ví dụ:
- tool A trả kết quả thành công nhưng chậm 18 giây, khiến context vòng sau đã stale;
- tool B timeout sau khi đã tạo side effect ở downstream nhưng upstream không biết;
- model không hiểu lỗi tạm thời và chuyển sang gọi tool khác theo hướng sai;
- agent lặp lại cùng một tool call 5 lần vì phrasing lỗi vẫn giống nhau;
- tool schema thay đổi một field optional thành required và orchestration chỉ phát hiện ở runtime.
Đó là lý do nên nhìn tool calling như một pipeline thực thi có rủi ro tương đương job orchestration hoặc saga, chứ không phải chỉ là tính năng của model provider.
Execution contract cho mỗi tool phải rõ hơn mức “name + JSON schema”

Nhiều team dừng ở đây:
- tool name;
- description;
- input schema;
- output schema.
Thế là chưa đủ.
Một tool production-grade cần có execution contract ít nhất gồm các lớp sau:
1. Capability contract
Tool này được phép làm gì?
- chỉ đọc hay có side effect;
- có đụng dữ liệu nhạy cảm không;
- có gọi hệ thống ngoài không;
- có yêu cầu approval/human confirmation không;
- có giới hạn scope theo tenant/user/project không.
Ví dụ search_docs và send_invoice_email không thể được xử lý như nhau. Một cái là read-only, một cái là external side effect có hậu quả nghiệp vụ.
2. Latency contract
Tool thường hoàn thành trong bao lâu?
- p50, p95, p99 kỳ vọng;
- hard timeout của tool;
- soft timeout để agent chọn fallback;
- tool có streaming/progressive result không.
Nếu orchestrator không biết latency class của tool, nó sẽ không thể chia timeout budget hợp lý cho cả plan.
3. Side-effect contract
Tool có tạo side effect hay không? Nếu có, side effect đó có idempotent không?
-
create_ticketcó hỗ trợ idempotency key không; -
send_emailcó dedupe window không; -
refund_paymentcó double execution guard không; -
update_crm_contactlà patch hay replace.
Đây là chỗ rất nhiều agent chết vì retry mù.
4. Failure contract
Tool fail như thế nào?
- transient error;
- permanent validation error;
- auth error;
- rate limit;
- dependency unavailable;
- partial success.
Nếu tất cả lỗi đều bị ném lên thành một chuỗi kiểu Tool failed, model sẽ suy diễn sai. Orchestrator phải chuẩn hóa error class đủ tốt để policy layer quyết định retry, handoff hay stop.
5. Observability contract
Mỗi lần gọi tool cần log gì?
- trace/span id;
- agent run id;
- tool call id;
- idempotency key;
- actor/user context;
- approval state;
- downstream request id nếu có;
- latency, retry count, outcome class.
Nếu không có observability contract, incident review sau này chỉ còn log text rất khó nối chuỗi nguyên nhân.
Timeout budget: đừng để model và tool cùng tiêu sạch thời gian của nhau

Một agent run hiếm khi chỉ có một bước. Nó có thể gồm:
- lập kế hoạch sơ bộ;
- gọi search;
- gọi fetch detail;
- gọi database read;
- gọi CRM write;
- xin approval;
- tạo artifact cuối.
Nếu mỗi bước đều được “cho thoải mái 30 giây”, tổng runtime sẽ phình ra rất nhanh. Tệ hơn, timeout không đồng bộ giữa các lớp tạo ra trạng thái nửa sống nửa chết:
- model timeout trước nhưng tool vẫn chạy nền;
- orchestrator timeout sau khi downstream đã commit;
- HTTP client timeout ngắn hơn queue visibility timeout;
- approval wait không tách khỏi compute budget.
Cách tốt hơn là quản lý timeout budget theo cây thực thi.
Ví dụ với một run mục tiêu 45 giây:
- planning + first response: 5 giây;
- read-only tool fan-out: 12 giây;
- synthesis: 6 giây;
- side-effect tool: 8 giây;
- retry reserve: 6 giây;
- observability/cleanup margin: 3 giây;
- hard stop: 5 giây.
Điểm quan trọng không phải con số cố định, mà là nguyên tắc:
- global deadline cho toàn run;
- step deadline cho từng tool class;
- cancellation propagation xuống đúng downstream;
- approval wait là trạng thái riêng, không ăn hết compute budget.
Nếu không tách approval wait, agent sẽ trông như “timeout ngẫu nhiên” chỉ vì người dùng chưa bấm duyệt.
Retry cho AI agent phải theo policy, không theo cảm hứng của model
Model rất hay “thử lại” khi thấy lỗi. Điều này hữu ích với read-only tool, nhưng cực nguy hiểm với side-effect tool.
Nên retry khi nào?
Phù hợp cho retry tự động:
- network timeout ngắn hạn;
- 429 có
Retry-Afterrõ; - 503 từ dependency tạm thời;
- optimistic concurrency conflict có thể đọc lại rồi thử lại.
Không nên retry mù:
- validation error do input sai;
- permission denied;
- duplicate request có side effect chưa xác minh;
- downstream trả ambiguous result sau khi có khả năng đã commit.
Policy retry nên nằm ở orchestration layer
Đừng để model tự quyết I will try again rồi gọi lại y hệt. Hãy để orchestration layer map từng lỗi vào policy:
-
TRANSIENT_NETWORK→ retry tối đa 2 lần, exponential backoff + jitter; -
RATE_LIMITED→ chờ theoRetry-After, nếu vượt budget thì handoff; -
VALIDATION_FAILED→ không retry, yêu cầu model sửa tham số hoặc hỏi lại user; -
SIDE_EFFECT_AMBIGUOUS→ khóa retry tự động, chuyển sang reconciliation/human review.
Lợi ích là hành vi trở nên deterministic hơn và audit được.
Idempotency là tuyến phòng thủ quan trọng nhất cho side effect

Nếu agent được phép tạo ticket, gửi email, tạo invoice, đổi trạng thái workflow hoặc gọi bất kỳ API ghi nào, idempotency key gần như là bắt buộc.
Khi retry xảy ra, câu hỏi không phải “có chạy lại không?” mà là “cùng một intent có tạo ra cùng một kết quả không?”.
Một số pattern hữu ích:
1. Intent-scoped idempotency key
Sinh key theo một intent business ổn định, ví dụ:
tenant_id + user_id + action_type + normalized_target + time_bucket
Hoặc tốt hơn, gắn vào agent_run_id + tool_call_id nhưng vẫn có lớp business dedupe nếu run bị resume hoặc replay.
2. Write-ahead execution record
Trước khi gọi downstream side effect, ghi một execution record nội bộ:
- tool call id;
- idempotency key;
- payload digest;
- attempt count;
- current state: pending / committed / failed / unknown;
- downstream correlation id nếu có.
Nếu process crash giữa chừng, system còn cách reconcile thay vì gọi lại trong mù mờ.
3. Ambiguous commit handling
Tình huống khó nhất là downstream timeout sau khi có thể đã commit. Ví dụ create_ticket trả timeout nhưng ticket thật đã tạo. Lúc này không được retry ngay nếu không có idempotency guarantee. Phải:
- query lại downstream theo idempotency key hoặc correlation id;
- nếu xác nhận đã tạo thì mark committed;
- nếu không xác nhận được, chuyển human review hoặc queue reconciliation job.
Đây là pattern backend cũ nhưng đặc biệt quan trọng với agent, vì model thường có xu hướng “thử lại cho chắc”.
Circuit breaker và degradation path giúp agent không loop vô ích
Khi một tool hoặc dependency bắt đầu lỗi hàng loạt, agent rất dễ rơi vào loop:
- gọi tool;
- lỗi;
- model diễn giải là thiếu dữ liệu;
- gọi lại hoặc thử tool gần giống;
- lại lỗi;
- token tăng, latency tăng, user càng khó chịu.
Circuit breaker nên nằm ở orchestration layer hoặc tool gateway, không nằm trong prompt.
Một circuit breaker tối thiểu nên biết:
- failure rate theo cửa sổ thời gian;
- latency spike;
- số lần timeout liên tiếp;
- error class dominant;
- half-open recovery probe.
Khi breaker mở, agent cần degradation path rõ ràng:
- với read-only tool: fallback sang cache, stale data có nhãn, hoặc trả lời trung thực là nguồn hiện unavailable;
- với write tool: chặn side effect mới và yêu cầu human takeover;
- với multi-step workflow: cắt short-circuit cả branch đó thay vì để model tiếp tục đoán mò.
Human handoff không phải thất bại, mà là control point

Một agent production nghiêm túc phải biết lúc nào nên nhường người.
Các ngưỡng handoff thường hợp lý:
- side effect có giá trị cao hoặc rủi ro pháp lý;
- ambiguity sau commit;
- confidence thấp nhưng impact cao;
- tool chain fail quá số bước cho phép;
- permission boundary chưa đủ rõ;
- prompt/user intent mâu thuẫn với policy.
Human handoff tốt không chỉ là “xin lỗi, tôi không làm được”. Nó phải kèm:
- agent đã làm gì;
- tool call nào thành công/thất bại;
- dữ liệu nào đã xác minh;
- hành động nào chưa thực hiện;
- đề xuất bước tiếp theo cho người vận hành.
Nói cách khác, handoff là một stateful transfer, không phải reset cuộc hội thoại về số 0.
Approval gate nên là policy engine, không phải câu chữ mềm trong prompt
Một anti-pattern phổ biến là dựa vào prompt kiểu: “chỉ gửi email khi user xác nhận”. Khi run phức tạp, câu chữ đó không đủ làm enforcement.
Approval gate production nên có ít nhất 3 lớp:
- Tool classification: tool nào cần approval, tool nào read-only;
- Runtime interception: trước khi side-effect tool chạy, execution bị chặn ở policy layer;
- Resumable state: sau khi user duyệt, run tiếp tục từ đúng điểm bị chặn thay vì bắt model plan lại từ đầu.
Nếu không có resumable state, agent sau approval có thể re-plan khác đi và gây hành vi không mong muốn.
Một approval event nên lưu:
- requested action;
- normalized payload preview;
- risk classification;
- requester/approver identity;
- expiry time;
- approved/rejected reason;
- link với run id và tool call id.
Điều này cực quan trọng cho audit trail, nhất là trong B2B workflow hoặc tác vụ đụng CRM, email, support, tài chính.
Observability cho agent nên theo trace, không chỉ theo transcript
Nhiều hệ agent hiện mới log tốt phần chat transcript, nhưng phần thực thi tool lại rời rạc. Đến lúc incident xảy ra, team biết agent “nói gì” nhưng không biết tool nào thật sự gây sự cố.
Một trace tốt cho agent run nên có cây span kiểu:
agent.run
Trên mỗi span nên có attributes:
- tool name;
- normalized input hash;
- output size/class;
- retry count;
- idempotency key;
- timeout budget consumed;
- policy decision;
- downstream request id;
- tenant/user context đã được sanitize.
Nếu làm tốt, team có thể trả lời các câu hỏi rất thực tế:
- tool nào hay timeout nhất;
- lỗi nào khiến handoff tăng mạnh;
- branch plan nào dẫn tới nhiều duplicate side effect;
- approval stage trung bình chờ bao lâu;
- model/provider nào sinh ra plan lãng phí tool call.
Testing strategy: đừng chỉ test model output, hãy test execution behavior
Bài học từ backend và distributed system vẫn giữ nguyên: test output đẹp không đảm bảo runtime an toàn.
Với agent dùng tool, nên có ít nhất 4 lớp test.
1. Schema/contract test cho tool interface
- input schema có backward-compatible không;
- output parser có chịu được field mới/field thiếu ở mức cho phép không;
- error envelope có giữ được class ổn định không.
2. Policy test
- tool side effect có bị chặn khi thiếu approval không;
- lỗi
VALIDATION_FAILEDcó không retry không; - lỗi
RATE_LIMITEDcó obeyRetry-Afterkhông; - breaker mở thì agent có dừng branch đó không.
3. Replay/simulation test
Dùng trace cũ để replay các tình huống:
- timeout giữa chừng;
- downstream commit mơ hồ;
- duplicate message;
- provider schema drift;
- approval đến muộn.
Đây là nơi rất nhiều incident lộ ra trước khi lên production thật.
4. Canaries và shadow runs
Với workflow rủi ro cao, có thể cho agent chạy shadow:
- lập plan thật;
- chạy read-only tools hoặc mock side-effect;
- so kết quả với human operator hoặc workflow cũ;
- chỉ bật side effect thật khi đã đủ tín hiệu an toàn.
Những anti-pattern làm AI agent trông thông minh nhưng vận hành rất nguy hiểm
“Một error string cho mọi lỗi”
Nếu mọi failure đều thành tool failed, model sẽ ứng biến sai và orchestrator không policy được.
“Retry trong prompt”
Prompt có thể hướng dẫn model thử lại nhẹ nhàng, nhưng retry thật phải ở execution policy có guard rail rõ.
“Approval bằng hội thoại, không có state machine”
User nói “ok” trong chat không đủ nếu hệ thống không bind được approval đó với action cụ thể nào.
“Không có idempotency cho tool write”
Đây là công thức tạo incident kiểu gửi mail trùng, tạo ticket trùng, cập nhật CRM sai hàng loạt.
“Transcript là audit log”
Transcript hữu ích cho UX, nhưng audit cần structured event riêng cho action, approval, retry, outcome.
“Để model tự quyết fallback”
Fallback khi dependency lỗi là policy hạ tầng. Đừng để model tự bịa nguồn dữ liệu thay thế khi tool chính fail.
Một kiến trúc tham chiếu đủ thực dụng cho team backend
Một stack khá lành mạnh cho agent production thường có các lớp:
- Planner / model layer
- Tool gateway
- Policy engine
- Execution journal
- Observability
- Human ops surface
Điểm đáng chú ý là reliability không nằm trong model layer một mình. Nó là hệ thống phụ trợ quanh model.
Checklist release gate trước khi cho agent gọi tool production
Trước khi cho agent động vào dữ liệu hoặc hệ thống thật, nên tự kiểm tra ít nhất các câu hỏi sau:
- Mỗi tool đã được phân loại read-only hay side-effect chưa?
- Side-effect tool đã có idempotency key và execution journal chưa?
- Error class đã đủ để orchestration quyết định retry/stop/handoff chưa?
- Timeout budget có global deadline và per-step deadline chưa?
- Approval gate có intercept ở runtime, không chỉ ở prompt, chưa?
- Handoff có kèm state/context để người vận hành tiếp quản không?
- Breaker và degradation path đã định nghĩa cho dependency chậm/lỗi chưa?
- Trace có nối được từ agent run tới downstream request id chưa?
- Có replay test cho ambiguous commit, rate limit, timeout chain chưa?
- Có canary hoặc shadow phase trước khi mở side-effect thật chưa?
Nếu còn thiếu quá nửa các mục này, agent có thể demo ổn nhưng chưa nên được trao quyền thực thi đáng kể.
Kết luận
AI agent đáng tin trong production không đến từ prompt dài hơn hay model mạnh hơn một bậc. Nó đến từ việc team áp dụng những nguyên tắc quen thuộc của backend engineering vào lớp orchestration mới: execution contract, timeout budget, retry policy, idempotency, approval gate, observability và human handoff.
Nói ngắn gọn: khi agent bắt đầu gọi tool, bạn không còn xây “chatbot”. Bạn đang xây một hệ thống phân tán có model ở giữa. Nếu không đối xử với nó bằng kỷ luật production tương xứng, những lỗi rất cũ của backend sẽ quay lại trong vỏ bọc rất mới.
---
SEO package
- Primary keyword: AI agent tool calling reliability
- Secondary keywords: tool calling production, AI agent reliability engineering, function calling idempotency, AI agent timeout retry, human handoff AI agent, agent orchestration reliability
- Meta title: Tool Calling Reliability cho AI Agent: timeout, idempotency và handoff
- Meta description: Thiết kế độ tin cậy cho AI agent dùng tool trong production: timeout budget, idempotency key, retry policy, circuit breaker, approval gate, human handoff và observability thực chiến.
- Canonical: https://softwareengineer.vn/ai-agent-tool-calling-reliability-production/
- Category slugs: ai-engineering, ai-agent, backend-engineering, code-quality
Internal link plan
Links đi ra từ bài này - **LLM Structured Outputs với JSON Schema** → `https://softwareengineer.vn/llm-structured-outputs-json-schema-production/` - Anchor gợi ý: `LLM Structured Outputs với JSON Schema` - Lý do: nối contract ở output layer với contract ở execution layer. - **Idempotency là gì?** → `https://softwareengineer.vn/api-idempotency-la-gi/` - Anchor gợi ý: `idempotency cho API write` - Lý do: nền tảng chống duplicate side effect. - **Contract Testing cho Microservices** → `https://softwareengineer.vn/contract-testing-microservices-production/` - Anchor gợi ý: `contract testing giữa các service` - Lý do: mở rộng khái niệm contract sang tool boundary. - **Rate Limiting trong Distributed System** → `https://softwareengineer.vn/rate-limiting-distributed-system-token-bucket/` - Anchor gợi ý: `rate limit và Retry-After` - Lý do: policy cho dependency overload. - **Incident Postmortem** → `https://softwareengineer.vn/incident-postmortem-production-engineering/` - Anchor gợi ý: `incident postmortem` - Lý do: hậu kiểm khi agent gây sự cố thật. - **Backpressure và Load Shedding trong Backend** → `https://softwareengineer.vn/backend-backpressure-load-shedding/` - Anchor gợi ý: `load shedding cho workflow quá tải` - Lý do: liên hệ degradation path và resource protection.
Gợi ý links đi vào bài này từ bài khác - Từ `/llm-structured-outputs-json-schema-production/` thêm anchor: `độ tin cậy khi LLM bắt đầu gọi tool thật` - Từ `/api-idempotency-la-gi/` thêm anchor: `idempotency cho AI agent gọi API ghi dữ liệu` - Từ `/contract-testing-microservices-production/` thêm anchor: `execution contract cho tool của AI agent` - Từ `/rate-limiting-distributed-system-token-bucket/` thêm anchor: `retry policy cho agent dùng tool`
Image plan
Featured image - **Intent:** Process - **Suggested filename:** `agent-tool-calling-reliability-overview.jpg` - **Placement:** ảnh cover đầu bài - **Visual spec:** Sơ đồ pipeline gồm `User` → `Agent Planner` → `Policy/Approval Gate` → `Tool Gateway` → `Internal API / External SaaS`, có các nhãn timeout, retry, idempotency và human handoff ở các điểm quyết định. Phong cách technical editorial, nền tối, không logo vendor, không robot minh họa. - **Alt text:** Sơ đồ độ tin cậy cho AI agent gọi tool qua policy gate timeout retry và human handoff
In-content image 1 - **Intent:** Comparison - **Suggested filename:** `read-only-vs-side-effect-tools.jpg` - **Placement:** sau section `Execution contract cho mỗi tool` - **Visual spec:** Bảng so sánh hai cột `Read-only tool` và `Side-effect tool`, hàng gồm retry policy, idempotency, approval, observability, failure handling. - **Alt text:** So sánh read only tool và side effect tool trong AI agent production
In-content image 2 - **Intent:** Process - **Suggested filename:** `agent-timeout-budget-tree.jpg` - **Placement:** sau section `Timeout budget` - **Visual spec:** Cây thời gian từ global deadline tách ra planning, read tools, write tool, retry reserve và approval wait, nhấn mạnh budget consumption theo từng nhánh. - **Alt text:** Cây timeout budget cho AI agent run với nhiều bước tool calling
In-content image 3 - **Intent:** Checklist - **Suggested filename:** `agent-side-effect-idempotency-flow.jpg` - **Placement:** sau section `Idempotency là tuyến phòng thủ` - **Visual spec:** Flow side-effect gồm execution journal, idempotency key, downstream correlation id, ambiguous commit, reconciliation và human review. - **Alt text:** Luồng idempotency cho side effect tool của AI agent để tránh thực thi trùng
In-content image 4 - **Intent:** Outcome - **Suggested filename:** `agent-approval-handoff-control-plane.jpg` - **Placement:** gần section `Human handoff` và `Approval gate` - **Visual spec:** Control plane view với approval queue, rejected/approved states, resumable run và human takeover branch. - **Alt text:** Control plane cho approval gate và human handoff trong AI agent production
Source-backed references / records
- OpenAI Function Calling / Tools docs
- Anthropic Tool Use docs
- Model Context Protocol specification
- OpenTelemetry Traces concepts
- Google SRE book / handling overload concepts