Một LLM không nối tools thì chỉ biết "nói". Tools (còn gọi function calling) là các hàm thật cho phép agent đọc và thay đổi thế giới: query database, gọi API, đọc file, gửi tin nhắn. Đây là bộ phận biến agent từ "biết" thành "làm".
Cơ chế function calling hoạt động thế nào?
Bạn không đưa code hàm cho LLM. Bạn đưa cho nó một bản mô tả (schema) gồm: tên hàm, mô tả, và tham số. LLM đọc schema, quyết định gọi hàm nào với tham số gì, rồi trả về JSON ý định gọi. Code của bạn thực thi hàm và đưa kết quả lại cho LLM.
LLM ─(trả JSON)→ { "tool": "get_weather", "args": {"city": "Hà Nội"} }
Code ─(thực thi)→ gọi API thời tiết thật → "28°C"
Code ─(đưa lại)→ LLM đọc "28°C" → soạn câu trả lời
Điểm mấu chốt: LLM chỉ đề nghị, code của bạn mới thực thi. Đây là nơi bạn đặt kiểm soát an toàn.
Khai báo một tool (ví dụ)
tools = [{
"name": "get_weather",
"description": "Lấy nhiệt độ hiện tại của một thành phố. "
"Dùng khi user hỏi thời tiết.",
"parameters": {
"type": "object",
"properties": {
"city": {"type": "string", "description": "Tên thành phố"}
},
"required": ["city"]
}
}]
Phần description cực kỳ quan trọng: nó là cách duy nhất LLM biết tool làm gì và khi nào dùng. Viết description mơ hồ = agent chọn sai tool.
Các bước thiết kế một tool tốt
- Một tool = một việc rõ ràng. Đừng gộp
manage_calendar(action=...)làm mọi thứ; táchcreate_event,delete_event. - Đặt tên động từ + danh từ:
send_email,search_docs. LLM đoán ý định qua tên. - Mô tả cả mục đích lẫn khi nào dùng trong
description. - Khai báo tham số chặt: kiểu dữ liệu, bắt buộc/tùy chọn, enum nếu giới hạn giá trị.
- Trả về kết quả gọn, có cấu trúc: agent phải đọc được. Trả cả lỗi dạng text rõ nghĩa để agent tự sửa.
- Đặt kiểm soát trong code hàm, không tin LLM: validate tham số, giới hạn quyền (chỉ đọc email của chính user).
Khung phân loại tool
| Loại | Rủi ro | Ví dụ | Cần xác nhận? |
|---|---|---|---|
| Read-only | Thấp | search, get_calendar | Không |
| Ghi/sửa | Trung bình | create_event | Nên |
| Không đảo ngược | Cao | delete_db, send_money | Bắt buộc |
Xử lý lỗi để agent tự sửa
Đừng để hàm ném exception làm sập agent. Hãy trả lỗi thành text để LLM đọc và thử lại:
def get_weather(city):
if not city:
return "Lỗi: thiếu tên thành phố. Hãy hỏi user."
...
Agent đọc "Lỗi: thiếu tên thành phố" và sẽ hỏi lại user — đó là hành vi self-correction.
Checklist một tool sẵn sàng
- [ ] Tên là động từ + danh từ, rõ nghĩa.
- [ ] Description nêu mục đích + khi nào dùng.
- [ ] Tham số có kiểu,
required, enum khi cần. - [ ] Validate tham số bên trong code.
- [ ] Trả lỗi dạng text để agent tự sửa.
- [ ] Tool rủi ro cao có cơ chế xác nhận.
Sai lầm thường gặp
- Description sơ sài: "xử lý lịch" — LLM không biết dùng khi nào, chọn sai.
- Tool quá to, nhiều nhánh: khó cho LLM chọn đúng tham số; hãy tách nhỏ.
- Tin LLM validate hộ: LLM có thể gửi tham số bậy. Luôn validate trong code.
- Ném exception thay vì trả lỗi text: agent sập thay vì tự sửa.
- Cho tool quyền quá rộng:
run_sql(query)cho phép cảDROP TABLE. Giới hạn tool chỉ làm đúng việc cần.