Mở đầu — vì sao bài này quan trọng
Hãy tưởng tượng bạn thuê được một trợ lý cực kỳ thông minh, đọc nhanh, viết giỏi, biết cả trăm ngôn ngữ. Nhưng có một vấn đề: người trợ lý này bị nhốt trong một căn phòng kín, không có điện thoại, không internet, không có quyền truy cập vào bất kỳ hệ thống nào của công ty bạn. Bạn hỏi "Hôm nay tỷ giá USD/VND là bao nhiêu?" — anh ta chỉ có thể đoán dựa trên trí nhớ cũ. Bạn nhờ "Gửi email xác nhận cho khách hàng đi" — anh ta viết ra một bức email hoàn hảo, nhưng không có cách nào bấm nút gửi.
Đó chính xác là giới hạn của một LLM (Large Language Model — mô hình ngôn ngữ lớn) khi đứng một mình. Bản thân model chỉ biết những gì có trong dữ liệu huấn luyện (thường đã cũ vài tháng đến vài năm), và nó hoàn toàn không thể hành động trong thế giới thực. Nó không tra được số dư tài khoản, không truy vấn được database, không đặt được lịch, không gọi được API thanh toán.
Tool use (còn gọi là function calling — gọi hàm) chính là chiếc "điện thoại" và "cánh cửa" cho người trợ lý thông minh đó. Nó cho phép LLM nói với hệ thống của bạn: "Tôi cần gọi hàm get_exchange_rate với tham số USD/VND", rồi bạn chạy hàm đó, trả kết quả về, và LLM dùng kết quả thật để trả lời. Đây là bước ngoặt biến chatbot "chỉ biết nói" thành AI agent biết làm việc thật — nền tảng cho hầu hết các sản phẩm AI nghiêm túc năm 2026.
Trong bài này, bạn sẽ hiểu cơ chế function calling hoạt động thế nào, cách viết định nghĩa công cụ (tool definition) đúng chuẩn, và cách áp dụng vào các bài toán kinh doanh thực tế của Việt Nam.
Khái niệm cốt lõi
Function calling thực chất là gì
Điểm dễ hiểu nhầm nhất: LLM không tự chạy code, không tự gọi API. Nó chỉ đề nghị gọi một hàm. Việc thực thi vẫn nằm hoàn toàn trong tay hệ thống của bạn.
Quy trình gồm bốn bước:
- Bạn khai báo công cụ. Bạn mô tả cho model biết nó có những hàm nào để dùng — tên hàm, hàm làm gì, cần tham số gì. Đây gọi là tool definition.
- Model quyết định gọi hàm. Khi người dùng hỏi điều gì đó cần dữ liệu/hành động bên ngoài, model không trả lời bằng văn bản thường, mà trả về một khối dữ liệu có cấu trúc kiểu: "hãy gọi hàm
get_order_statusvớiorder_id = 'DH2026-8842'". - Hệ thống của bạn thực thi. Code của bạn nhận đề nghị đó, thật sự chạy hàm — truy vấn database, gọi API giao hàng — và lấy kết quả.
- Model dùng kết quả để trả lời. Bạn đưa kết quả trở lại cho model, và nó diễn đạt thành câu trả lời tự nhiên cho người dùng: "Đơn DH2026-8842 đang được giao, dự kiến đến trong hôm nay."
Tool definition — trái tim của function calling
Một tool definition chuẩn (theo định dạng của các nhà cung cấp như Anthropic, OpenAI) thường có ba phần bằng JSON Schema:
- name: tên hàm, ví dụ
get_exchange_rate. - description: mô tả bằng ngôn ngữ tự nhiên — hàm này làm gì, khi nào nên dùng. Đây là phần quan trọng nhất vì model dựa vào đây để quyết định.
- input_schema / parameters: cấu trúc tham số đầu vào, mỗi tham số có kiểu dữ liệu, mô tả, và có bắt buộc hay không.
{
"name": "get_exchange_rate",
"description": "Lấy tỷ giá hối đoái hiện tại giữa hai loại tiền tệ. Dùng khi người dùng hỏi về giá quy đổi tiền tệ theo thời gian thực.",
"input_schema": {
"type": "object",
"properties": {
"from_currency": { "type": "string", "description": "Mã tiền tệ nguồn, ví dụ USD" },
"to_currency": { "type": "string", "description": "Mã tiền tệ đích, ví dụ VND" }
},
"required": ["from_currency", "to_currency"]
}
}
Chất lượng phần description quyết định 80% việc model có gọi đúng hàm, đúng lúc hay không. Description mơ hồ = model gọi lung tung hoặc bỏ sót.
Vì sao tool use "mở khóa" sức mạnh thật
Không có tool use, LLM chỉ giải quyết được các bài toán "trong đầu": viết, tóm tắt, dịch, phân loại văn bản. Có tool use, nó chạm được vào:
- Dữ liệu thời gian thực: tồn kho, giá vàng SJC hôm nay, số dư ví, trạng thái đơn hàng.
- Hành động có hậu quả: gửi email, tạo ticket, cập nhật CRM, đặt lịch, tạo hóa đơn.
- Phép tính chính xác: LLM tính toán số học rất tệ; đẩy sang một hàm
calculatorcho kết quả đáng tin. - Hệ thống nội bộ của doanh nghiệp: truy vấn kho dữ liệu riêng mà model chưa từng thấy khi huấn luyện.
Tình huống thực tế
Ví dụ 1 — Chatbot chăm sóc khách hàng của một sàn TMĐT
Một công ty thương mại điện tử giả định tên ShopViet (quy mô khoảng 50.000 đơn/tháng) triển khai chatbot trên fanpage. Trước đây chatbot chạy theo kịch bản cứng, khách hỏi "Đơn của tôi tới đâu rồi?" thì bot chỉ trả về link tra cứu, tỷ lệ khách bỏ ngang lên tới 60%.
Đội kỹ thuật khai báo cho LLM ba công cụ: get_order_status(order_id), get_shipping_estimate(order_id), và create_support_ticket(order_id, issue). Giờ khi khách nhắn "Đơn DH2026-8842 sao lâu quá vậy", model tự động gọi get_order_status('DH2026-8842'), hệ thống truy vấn database giao hàng, trả về "đang trung chuyển tại kho Bình Dương", và model diễn đạt: "Đơn của anh/chị đang ở kho Bình Dương, dự kiến giao trong 2 ngày tới. Anh/chị cần em hỗ trợ gì thêm không?"
Nếu khách bức xúc muốn khiếu nại, model gọi tiếp create_support_ticket. Sau 3 tháng, ShopViet giảm 45% số cuộc phải chuyển cho nhân viên thật.
Bài học rút ra: Sức mạnh không nằm ở việc bot "nói hay" mà ở việc nó chạm được vào dữ liệu đơn hàng thật. Một chatbot không có tool use mãi mãi chỉ là kịch bản trả lời chung chung.
Ví dụ 2 — Trợ lý tài chính nội bộ tại một fintech
Một startup fintech ở TP.HCM xây trợ lý nội bộ cho đội vận hành. Nhân viên hỏi bằng tiếng Việt tự nhiên: "Tổng giá trị giao dịch qua VietQR tuần trước là bao nhiêu, so với tuần trước nữa thế nào?"
LLM một mình chắc chắn không biết con số này. Nhưng với công cụ run_analytics_query(metric, period) được kết nối tới data warehouse, model tách câu hỏi thành hai lần gọi hàm: một cho tuần trước, một cho tuần trước nữa. Nó nhận về hai con số — ví dụ 4,2 tỷ và 3,7 tỷ — rồi tự tính chênh lệch và trả lời: "Tuần trước đạt 4,2 tỷ đồng, tăng 13,5% so với tuần trước nữa (3,7 tỷ)."
Điểm hay là phép tính phần trăm không do model "nhẩm" — vì LLM tính toán không đáng tin — mà đội kỹ thuật thêm cả một hàm calculator để model gọi khi cần độ chính xác tuyệt đối.
Bài học rút ra: Với dữ liệu số và tính toán, hãy để công cụ làm phần "sự thật và con số", model chỉ làm phần "hiểu câu hỏi và diễn đạt". Đừng bao giờ để model tự bịa số.
Ví dụ 3 — Đặt lịch tự động cho phòng khám
Một chuỗi phòng khám tại Hà Nội dùng LLM trực tổng đài Zalo. Bệnh nhân nhắn "Đặt giúp tôi lịch khám da liễu chiều thứ Sáu này". Model gọi check_availability(specialty='da liễu', date='2026-06-... ') để xem khung giờ trống, trả về 3 lựa chọn, khách chọn 15h30, rồi model gọi book_appointment(...) để chốt.
Điểm mấu chốt về an toàn: hàm đọc (check_availability) chạy tự động, nhưng hàm ghi có hậu quả (book_appointment) được thiết kế để hệ thống hiển thị bước xác nhận cuối cho khách bấm "Đồng ý" trước khi thực thi. Đây là nguyên tắc "human-in-the-loop" cho các hành động không thể hoàn tác.
Bài học rút ra: Phân biệt rõ công cụ chỉ-đọc và công cụ có-hậu-quả. Với nhóm sau, luôn cài một lớp xác nhận để tránh model hành động sai gây thiệt hại thật.
Hướng dẫn từng bước
Bước 1 — Liệt kê các "khoảng trống năng lực" của LLM. Ngồi lại và hỏi: trong bài toán của mình, chỗ nào model không thể tự biết (dữ liệu real-time, dữ liệu nội bộ) và chỗ nào cần hành động thật (gửi, tạo, cập nhật)? Mỗi khoảng trống đó là một công cụ tiềm năng.
Bước 2 — Thiết kế tool definition rõ ràng. Với mỗi công cụ, viết name ngắn gọn dạng động từ (get_, create_, search_), viết description nêu rõ hàm làm gì và khi nào dùng, khai báo đủ tham số với mô tả từng cái. Hãy viết description như thể bạn đang hướng dẫn một nhân viên mới chưa biết gì.
Bước 3 — Gửi công cụ kèm prompt. Khi gọi API, bạn đính kèm danh sách tool definitions cùng câu hỏi của người dùng. Nói rõ trong system prompt: "Khi cần dữ liệu thời gian thực, hãy dùng công cụ thay vì đoán."
Bước 4 — Bắt và thực thi lời gọi hàm. Model trả về một đối tượng báo hiệu muốn gọi hàm (thường có stop_reason là tool_use). Code của bạn đọc tên hàm và tham số, chạy hàm thật, lấy kết quả.
Bước 5 — Trả kết quả về cho model. Đưa kết quả (kèm mã định danh của lời gọi) ngược lại vào cuộc hội thoại. Model đọc kết quả và soạn câu trả lời cuối cùng cho người dùng — hoặc quyết định gọi tiếp một công cụ khác nếu chưa đủ.
Bước 6 — Xử lý lỗi và trường hợp biên. Nếu hàm lỗi (API sập, không tìm thấy đơn), hãy trả về thông báo lỗi có ý nghĩa cho model để nó xin lỗi khách lịch sự, thay vì để hệ thống crash.
Lỗi thường gặp & mẹo
Lỗi 1: Nghĩ rằng LLM tự chạy code. Không. Model chỉ đề nghị; bạn phải viết code thực thi. Nếu bạn không xử lý bước thực thi, không có gì xảy ra cả.
Lỗi 2: Description hời hợt. Viết description: "lấy dữ liệu" là công thức để model gọi sai. Càng cụ thể về khi nào dùng và khi nào KHÔNG dùng, model càng chính xác.
Lỗi 3: Nhồi quá nhiều công cụ. Đưa cho model 40 công cụ cùng lúc khiến nó bối rối, gọi nhầm và tốn token. Kinh nghiệm: giữ dưới khoảng 10–15 công cụ cho mỗi ngữ cảnh; nếu nhiều hơn, hãy nhóm lại hoặc chia theo tình huống.
Lỗi 4: Không kiểm soát hành động nguy hiểm. Để model tự động send_money hay delete_record mà không có lớp xác nhận là quả bom hẹn giờ. Luôn tách công cụ đọc và công cụ ghi, cài human-in-the-loop cho hành động không thể hoàn tác.
Lỗi 5: Tin tưởng tham số model điền vào một cách mù quáng. Model có thể "ảo giác" một order_id không tồn tại. Luôn validate tham số ở phía code trước khi thực thi.
Mẹo hay:
- Đặt tên hàm và tham số bằng tiếng Anh, mô tả có thể tiếng Việt — model hiểu tốt cả hai, nhưng tên kỹ thuật nhất quán tiếng Anh dễ bảo trì.
- Trả về kết quả công cụ ở dạng có cấu trúc (JSON), đừng trả về đoạn văn dài — model xử lý cấu trúc chính xác hơn.
- Thêm một hàm
calculatorchuyên cho mọi phép tính số học để tránh model tính sai. - Test riêng từng công cụ trước khi ghép: cho model vài câu hỏi mẫu, kiểm tra nó có gọi đúng hàm với đúng tham số không.
Bài tập thực hành
Bài 1 — Nhận diện nhu cầu công cụ. Chọn một quy trình trong công việc của bạn (ví dụ: tư vấn khách hàng, báo cáo bán hàng). Liệt kê 3–5 câu hỏi mà LLM không thể trả lời nếu chỉ dựa vào kiến thức có sẵn. Với mỗi câu, đặt tên công cụ tương ứng.
Bài 2 — Viết tool definition. Chọn một công cụ từ Bài 1 và viết đầy đủ định nghĩa JSON của nó: name, description (rõ khi nào dùng), và input_schema với ít nhất 2 tham số có mô tả. Tự chấm: một đồng nghiệp chưa biết gì có hiểu công cụ này làm gì chỉ qua description không?
Bài 3 — Phân loại rủi ro. Với danh sách công cụ bạn nghĩ ra, đánh dấu mỗi cái là "chỉ đọc" hay "có hậu quả". Với nhóm "có hậu quả", mô tả cơ chế xác nhận bạn sẽ cài để tránh hành động sai.
Bài 4 — Mô phỏng luồng gọi hàm. Viết ra bằng lời (không cần code) toàn bộ 4 bước cho một câu hỏi cụ thể: người dùng hỏi gì → model gọi hàm nào với tham số gì → hệ thống trả kết quả gì → model trả lời khách ra sao.
Tóm tắt
- Tool use / function calling cho phép LLM vượt qua hai giới hạn cốt tử: không biết dữ liệu thời gian thực và không thể hành động trong thế giới thực.
- Cơ chế gồm 4 bước: bạn khai báo công cụ → model đề nghị gọi → hệ thống của bạn thực thi → model dùng kết quả để trả lời. LLM không tự chạy code, nó chỉ điều phối.
- Tool definition là trái tim:
name,description(quan trọng nhất) vàinput_schema. Description rõ ràng quyết định model gọi đúng hay sai. - Áp dụng thực tế: tra trạng thái đơn hàng, truy vấn dữ liệu tài chính, đặt lịch tự động — tất cả đều chạm vào hệ thống thật của doanh nghiệp.
- Nguyên tắc an toàn: tách công cụ đọc và công cụ có hậu quả, cài human-in-the-loop cho hành động không thể hoàn tác, và luôn validate tham số model điền vào.
- Giữ số lượng công cụ vừa phải, đẩy phép tính sang hàm chuyên dụng, và test từng công cụ trước khi ghép.