Tác vụ thật hiếm khi cần một tool. "Đặt lịch họp với khách A tuần sau" cần: tra thông tin khách → xem lịch trống → tạo sự kiện → gửi mail. Bài này dạy cách điều phối nhiều tool: tuần tự, phụ thuộc, và song song.
Ba kiểu ghép tool
- Tuần tự phụ thuộc: kết quả tool A là đầu vào tool B.
get_customer→ dùng email →get_orders. - Song song độc lập: các tool không phụ thuộc nhau, chạy cùng lúc để nhanh hơn.
get_weather(HN)vàget_weather(SG)cùng lúc. - Điều kiện rẽ nhánh: gọi tool nào tùy kết quả trước đó. Nếu
check_stock= 0 thìnotify_restock, ngược lạicreate_order.
Model tự orchestrate qua vòng lặp
Điểm hay: bạn không phải code cứng thứ tự. Vòng lặp ở Bài 3 cho phép model tự chuỗi: nó gọi tool A, đọc kết quả, quyết định gọi tool B. Nhiệm vụ của bạn là cung cấp tool tốt và để model lập kế hoạch.
for _ in range(MAX_STEPS):
resp = model.chat(messages, tools=schemas)
if not resp.tool_calls:
return resp.content
for call in resp.tool_calls: # model có thể trả NHIỀU call
result = dispatch(call.name, call.args)
messages.append(tool_result_msg(call.id, result))
Chạy song song đúng cách
Khi model trả về nhiều tool call độc lập trong một lượt, chạy chúng song song rồi trả tất cả kết quả về:
import concurrent.futures as cf
calls = resp.tool_calls
with cf.ThreadPoolExecutor(max_workers=5) as ex:
futures = {ex.submit(dispatch, c.name, c.args): c for c in calls}
for fut in cf.as_completed(futures):
c = futures[fut]
messages.append(tool_result_msg(c.id, fut.result()))
Lưu ý: chỉ song song hóa các call độc lập. Nếu có phụ thuộc, model sẽ tự tách thành nhiều lượt — bạn không được ép song song những call nối tiếp.
Khung tư duy: vẽ đồ thị phụ thuộc
Trước khi thiết kế một agent multi-tool, phác đồ thị:
get_customer ──► get_orders ──► summarize
│
└──► get_loyalty (độc lập, song song được với get_orders)
Cạnh = phụ thuộc dữ liệu. Nhánh không có cạnh nối = song song hóa được. Đồ thị này giúp bạn biết đâu là điểm nghẽn và đâu tối ưu được tốc độ.
Quản lý ngân sách và trạng thái
Multi-tool dễ phình chi phí và context. Kiểm soát:
- Trần số bước toàn cục (đã có ở Bài 3) — quan trọng gấp bội khi chuỗi dài.
- Cắt gọn kết quả tool: nếu
get_orderstrả 500 dòng, tóm tắt/phân trang trước khi đưa vào context, tránh nổ token. - Giữ trạng thái tường minh: khi tác vụ dài, lưu tiến độ (đã tạo event chưa, đã gửi mail chưa) để retry không làm trùng.
- Idempotency cho write tool:
create_eventnên nhận khóa duy nhất để gọi lại hai lần không tạo hai sự kiện.
Ví dụ luồng đặt lịch
- Model gọi
get_customer(email)→ nhận{name, tz}. - Model gọi
list_free_slots(tz, next_week)→ nhận danh sách giờ trống. - Model đề xuất giờ, hỏi người dùng xác nhận (human-in-the-loop cho write).
- Sau xác nhận:
create_event(...)với idempotency key. send_email(...)thông báo. Xong.
Checklist orchestration
- [ ] Đã vẽ đồ thị phụ thuộc, biết đâu song song được.
- [ ] Call độc lập chạy song song; call phụ thuộc để model tách lượt.
- [ ] Có trần số bước cho chuỗi dài.
- [ ] Kết quả tool lớn được cắt gọn trước khi vào context.
- [ ] Write tool có idempotency key.
- [ ] Tác vụ dài lưu trạng thái để retry an toàn.
Sai lầm thường gặp
- Ép song song các call phụ thuộc nhau, khiến tool B chạy trước khi có kết quả tool A → dữ liệu rác.
- Code cứng thứ tự tool thay vì để model lập kế hoạch, làm agent cứng nhắc, khó mở rộng.
- Nhồi toàn bộ output tool vào context làm nổ token và tăng chi phí mỗi lượt.
- Write tool không idempotent: retry sau timeout tạo trùng đơn/sự kiện.
- Không có trần bước cho chuỗi dài: một nhánh lỗi khiến agent lặp và đốt quota.
- Quên human-in-the-loop ở bước write nhạy cảm trong chuỗi tự động.