Ở bài 2 bạn có các hàm gọi API. Bài này bạn dạy LLM tự quyết định gọi hàm nào và với tham số gì — đây chính là trái tim của một agent. Cơ chế này gọi là tool calling (hay function calling).
Tool calling hoạt động thế nào
Bạn mô tả các hàm cho model dưới dạng JSON schema. Khi người dùng nhắn, model không tự bịa dữ liệu mà trả về một yêu cầu: "hãy gọi hàm create_event với các tham số này". Code của bạn thực thi hàm thật, đưa kết quả lại cho model, model diễn giải thành câu trả lời cho người dùng.
NL của user → model → {tool: create_event, args: {...}}
→ bạn chạy hàm thật → kết quả JSON
→ model → câu trả lời tự nhiên
Các bước khai báo một tool
- Viết mô tả rõ ràng, ngắn gọn cho từng hàm — model dựa vào mô tả này để chọn đúng.
- Khai báo tham số kèm kiểu và trường bắt buộc.
- Trong
description, nói rõ khi nào dùng — vd "dùng khi người dùng muốn xem lịch". - Đăng ký danh sách tools vào lời gọi model.
- Viết bộ điều phối (dispatcher) ánh xạ tên tool → hàm Python thật.
tools = [{
"type": "function",
"function": {
"name": "list_events_today",
"description": "Liệt kê các sự kiện trong lịch hôm nay. Dùng khi người dùng hỏi về lịch/cuộc họp hôm nay.",
"parameters": {"type": "object", "properties": {}}
}
}, {
"type": "function",
"function": {
"name": "add_task",
"description": "Thêm một task mới. Dùng khi người dùng muốn ghi việc cần làm.",
"parameters": {
"type": "object",
"properties": {
"content": {"type": "string", "description": "Nội dung task"},
"due": {"type": "string", "description": "Hạn dạng YYYY-MM-DD, có thể rỗng"}
},
"required": ["content"]
}
}
}]
Vòng lặp điều phối tool
import json
from openai import OpenAI
client = OpenAI()
REGISTRY = {"list_events_today": list_events_today, "add_task": add_task}
def run(user_msg):
msgs = [{"role": "user", "content": user_msg}]
resp = client.chat.completions.create(
model="gpt-4o", messages=msgs, tools=tools)
m = resp.choices[0].message
if m.tool_calls:
msgs.append(m)
for call in m.tool_calls:
fn = REGISTRY[call.function.name]
args = json.loads(call.function.arguments)
result = fn(**args)
msgs.append({"role": "tool", "tool_call_id": call.id,
"content": json.dumps(result, default=str)})
resp = client.chat.completions.create(
model="gpt-4o", messages=msgs, tools=tools)
return resp.choices[0].message.content
Ví dụ cụ thể
Người dùng: "Nhắc tôi gọi cho kế toán, hạn thứ Sáu này." Model sẽ tự chọn add_task với content="Gọi cho kế toán" và due="2026-07-03" (nó tự suy ra ngày thứ Sáu từ ngày hiện tại nếu bạn nhét ngày hôm nay vào system prompt — xem bài 6).
Khung tư duy: mô tả tool là "hợp đồng"
Model không đọc code của bạn, nó chỉ đọc description. Một mô tả tồi ("làm việc với task") khiến model chọn sai hoặc bịa tham số. Mô tả tốt trả lời được: hàm này làm gì, khi nào nên gọi, mỗi tham số nghĩa là gì.
Sai lầm thường gặp
- Mô tả tool mơ hồ. Model chọn nhầm tool hoặc không gọi. Hãy viết mô tả như đang hướng dẫn một nhân viên mới.
- Quên vòng lặp thứ hai. Sau khi chạy hàm, phải gửi kết quả lại cho model lần nữa để nó diễn giải; nếu không, người dùng chỉ nhận được JSON thô.
- Tin model đã kiểm tra dữ liệu. Luôn validate
args(vd định dạng ngày) trước khi gọi API thật. - Nhồi 20 tool cùng lúc. Quá nhiều tool làm model rối; giữ 4-6 tool cốt lõi cho bản đầu.
- Không xử lý khi tool ném lỗi. Bọc
try/except, trả lỗi thân thiện lại cho model để nó xin lỗi/hỏi lại thay vì crash.