Product Management
Đăng nhập
ESC

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

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

Bài 5 — Parallel Tool Calls: gọi nhiều tool cùng lúc

Đã đọc 0/8 mục · còn khoảng 3 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.

Khi một yêu cầu cần dữ liệu từ nhiều nguồn ĐỘC LẬP, gọi tuần tự là lãng phí. Model hiện đại có thể đề nghị nhiều tool call trong CÙNG một lượt trả lời, và bạn thực thi chúng song song để giảm độ trễ đáng kể.

Khi nào parallel, khi nào sequential

  • Parallel (song song): các tool KHÔNG phụ thuộc dữ liệu của nhau. Ví dụ: lấy thời tiết Hà Nội + thời tiết Đà Nẵng + tỉ giá USD. Ba việc độc lập → chạy cùng lúc.
  • Sequential (tuần tự): output tool A là input tool B. Ví dụ: find_user_id(email) rồi get_orders(user_id). Bắt buộc chờ.
Quy tắc: song song khi độc lập, tuần tự khi phụ thuộc.

Cách hoạt động

Trong một lượt, model trả về một MẢNG các tool call, mỗi cái có id riêng:

{
  "tool_calls": [
    { "id": "call_1", "name": "get_weather", "args": { "city": "Hanoi" } },
    { "id": "call_2", "name": "get_weather", "args": { "city": "Danang" } },
    { "id": "call_3", "name": "get_fx_rate", "args": { "pair": "USD/VND" } }
  ]
}

Bạn thực thi cả ba song song rồi trả kết quả về, mỗi kết quả gắn đúng id:

import asyncio

async def run_tools(tool_calls):
    tasks = [execute(tc) for tc in tool_calls]  # không await từng cái
    results = await asyncio.gather(*tasks)      # chạy song song
    return [
        {"tool_call_id": tc["id"], "output": r}
        for tc, r in zip(tool_calls, results)
    ]

Các bước triển khai

  • Bật parallel tool calls (nhiều API mặc định bật; kiểm tra tham số như parallel_tool_calls).
  • Nhận mảng tool call từ response, đừng giả định chỉ có một.
  • Thực thi song song bằng async/await, thread pool, hoặc goroutine.
  • Gắn đúng tool_call_id cho mỗi kết quả — đây là chỗ dễ sai nhất.
  • Gộp toàn bộ kết quả trả về model trong một lượt để model tổng hợp.
  • Xử lý lỗi từng phần: nếu call_2 fail, vẫn trả call_1 và call_3, kèm thông báo lỗi cho call_2.

Khi nào NÊN tắt parallel

  • Khi các tool có tác dụng phụ dễ xung đột (cùng ghi vào một bản ghi).
  • Khi bạn cần model suy luận từng bước rõ ràng (một số flow reasoning muốn tuần tự).

Khung tư duy: fan-out / fan-in

Parallel tool call là mô hình fan-out (phát tán nhiều việc) rồi fan-in (gom kết quả). Hãy đảm bảo bước fan-in chờ ĐỦ tất cả rồi mới trả về, và xử lý được trường hợp một nhánh chậm/lỗi.

Checklist parallel an toàn

  • [ ] Đã xác định các tool thực sự độc lập?
  • [ ] Code xử lý được MẢNG tool call, không chỉ một?
  • [ ] Mỗi kết quả gắn đúng tool_call_id?
  • [ ] Có timeout cho từng call để một call chậm không treo cả lượt?
  • [ ] Lỗi một nhánh không làm sập toàn bộ?
  • [ ] Kết quả trả về model trong cùng một lượt?

Sai lầm thường gặp

  • Gắn nhầm tool_call_id. Trả kết quả thời tiết Đà Nẵng vào id của Hà Nội khiến model tổng hợp sai hoàn toàn — và rất khó debug.
  • Song song hóa các tool phụ thuộc nhau. Chạy get_orders trước khi có user_id sẽ lỗi hoặc dùng giá trị rác.
  • Await tuần tự dù đã nhận song song. Nhận 3 call nhưng await từng cái một → mất hết lợi ích tốc độ.
  • Một call lỗi làm rơi cả lượt. Nên cô lập lỗi từng nhánh, trả phần thành công + báo phần lỗi.
  • Không timeout. Một tool treo khiến cả agent đứng hình.
Song song giúp agent nhanh. Bài 6 sẽ ghép các tool phụ thuộc thành CHUỖI phức tạp — nơi output cái này là input cái kia.

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