Giới hạn kiến thức: Tại sao LLM của bạn cần một “cửa sổ”
Hãy tưởng tượng một LLM nguyên bản giống như một nhà nghiên cứu lỗi lạc bị nhốt trong một căn phòng không có internet. Họ sở hữu lượng kiến thức khổng lồ cho đến thời điểm dừng dữ liệu đào tạo (knowledge cutoff), nhưng lại hoàn toàn “mù tịt” về hiện tại. Nếu bạn hỏi GPT-4o hoặc Claude 3.5 Sonnet về lượng hàng tồn kho hiện tại của công ty bạn tại kho Singapore, nó có khả năng sẽ ảo giác (hallucinate) ra một con số đầy tự tin nhưng hoàn toàn sai lệch. Nó không hề nói dối; chỉ là nó không có công cụ để nhìn ra thế giới bên ngoài.
Các lập trình viên thường nhầm lẫn AI chỉ là một trình tạo văn bản đơn thuần. Trên thực tế, Function Calling (hoặc ‘Tool Use’) biến các mô hình này thành các Agent (tác tử) chủ động. Thay vì chỉ trò chuyện, mô hình sẽ quyết định khi nào cần “vươn ra ngoài” để kích hoạt một kịch bản backend, truy vấn cơ sở dữ liệu hoặc gọi một API bên thứ ba. Trong các môi trường thực tế của tôi, việc thêm một công cụ ‘search_order’ duy nhất đã giúp giảm tỷ lệ ảo giác hơn 70% cho các bot hỗ trợ khách hàng.
Logic cốt lõi: AI không trực tiếp chạy mã của bạn
Có một lầm tưởng phổ biến rằng mô hình AI thực thi mã Python hoặc các câu truy vấn SQL của bạn. Thực tế không phải vậy. Function Calling bản chất là một quá trình thương lượng có cấu trúc giữa ứng dụng của bạn và LLM. Về cơ bản, bạn đang đưa cho AI một “thực đơn” các khả năng.
Khi người dùng đặt câu hỏi, mô hình sẽ quét danh sách ‘tools’ của bạn để xem có công cụ nào phù hợp với ý định (intent) đó không. Nếu tìm thấy kết quả khớp, AI sẽ tạm dừng cuộc hội thoại và trả về một đối tượng JSON có cấu trúc. Đối tượng này chứa tên hàm cụ thể và các đối số (arguments) cần thiết. Sau đó, ứng dụng của bạn sẽ chạy mã đó cục bộ, lấy kết quả và gửi ngược lại cho AI. Chỉ khi đó, mô hình mới đưa ra câu trả lời cuối cùng. Đây là một sự bàn giao (hand-off), không phải là sự tiếp quản hoàn toàn.
Độ chính xác là then chốt: JSON Schema
Mô hình hoạt động hiệu quả hay không phụ thuộc hoàn toàn vào phần mô tả của bạn. Cả OpenAI và Claude đều sử dụng một biến thể JSON Schema để hiểu các hàm của bạn. Nếu bạn mô tả một tham số một cách mơ hồ, hãy chuẩn bị tinh thần nhận về những dữ liệu rác làm hỏng hệ thống backend của mình. Hãy thật chi tiết. Nếu một hàm yêu cầu `user_id`, hãy cho mô hình biết chính xác chuỗi đó trông như thế nào—ví dụ: ‘Một mã UUID gồm 10 chữ số bắt đầu bằng US-‘.
Vòng lặp triển khai: Định nghĩa, Phát hiện, Thực thi
Để xây dựng một Agent tin cậy, hãy tuân theo mô hình kiến trúc ba bước sau:
- Instruction (Chỉ dẫn): Gửi prompt của người dùng cùng với các định nghĩa công cụ của bạn tới API.
- Signal (Tín hiệu): Mô hình phát hiện nhu cầu sử dụng công cụ và trả về một yêu cầu ‘tool_call’ thay vì văn bản.
- Closing the Loop (Đóng vòng lặp): Mã của bạn thực thi logic, lấy dữ liệu và gửi yêu cầu thứ hai quay lại để AI có thể diễn giải các phát hiện đó.
Triển khai OpenAI Function Calling
OpenAI hiện đang dẫn đầu trong việc tích hợp công cụ. Chat Completions API của họ sử dụng một mảng tools để định nghĩa các khả năng. Dưới đây là một ví dụ thực tế để kiểm tra trạng thái đơn hàng theo thời gian thực.
import openai
import json
# 1. Định nghĩa công cụ với các mô tả chặt chẽ
tools = [
{
"type": "function",
"function": {
"name": "get_order_status",
"description": "Truy xuất trạng thái vận chuyển thời gian thực cho một mã đơn hàng cụ thể.",
"parameters": {
"type": "object",
"properties": {
"order_id": {
"type": "string",
"description": "Mã định danh đơn hàng duy nhất, định dạng như ORD-555."
}
},
"required": ["order_id"]
}
}
}
]
# 2. Yêu cầu ban đầu
response = openai.chat.completions.create(
model="gpt-4o",
messages=[{"role": "user", "content": "Đơn hàng ORD-999 của tôi đang ở đâu?"}],
tools=tools,
tool_choice="auto"
)
# 3. Xử lý ý định của AI
message = response.choices[0].message
if message.tool_calls:
for tool_call in message.tool_calls:
args = json.loads(tool_call.function.arguments)
# Giả lập gọi cơ sở dữ liệu: status = db.fetch(args['order_id'])
print(f"Mô hình đang yêu cầu: {tool_call.function.name} với {args}")
GPT-4o cực kỳ giỏi trong việc trích xuất các biến từ đầu vào không rõ ràng của con người. Ngay cả khi người dùng nói: ‘Kiểm tra nhanh giùm tôi đơn hàng ORD-999 với?’, mô hình vẫn ánh xạ chính xác chuỗi đó vào tham số order_id của bạn mà không gặp chút khó khăn nào.
Làm việc với Tool Use của Claude
Claude 3.5 Sonnet của Anthropic xử lý các công cụ với cấu trúc chặt chẽ và đáng tin cậy. Mặc dù logic vẫn tương tự, nhưng việc xử lý phản hồi yêu cầu bạn phải theo dõi ID công cụ một cách cẩn thận. Claude đặc biệt nổi tiếng with việc tuân thủ các chỉ dẫn phức tạp, nhiều bước chính xác hơn hầu hết các mô hình khác.
import anthropic
client = anthropic.Anthropic()
tools = [
{
"name": "get_weather",
"description": "Lấy thông tin thời tiết hiện tại cho một thành phố cụ thể.",
"input_schema": {
"type": "object",
"properties": {
"location": {"type": "string", "description": "Thành phố và bang/quốc gia"},
"unit": {"type": "string", "enum": ["celsius", "fahrenheit"]}
},
"required": ["location"]
}
}
]
response = client.messages.create(
model="claude-3-5-sonnet-20240620",
max_tokens=1024,
tools=tools,
messages=[{"role": "user", "content": "Nhiệt độ ở Tokyo là bao nhiêu?"}]
)
print(response.content)
Khi Claude kích hoạt một công cụ, stop_reason sẽ là tool_use. Sau đó, bạn phải trả về kết quả bằng một khối tool_result cụ thể. Việc theo dõi tường minh này giúp quá trình gỡ lỗi các chuỗi Agent phức tạp trở nên dễ dàng hơn nhiều vì mọi hành động đều được gắn with một ID duy nhất.
Hoàn thiện cho môi trường Production: Mẹo từ thực tế
Sau khi triển khai hàng tá các tích hợp như thế này, tôi nhận ra có ba quy tắc phân biệt một ứng dụng đồ chơi với một công cụ thực thụ. Đầu tiên, hãy xử lý lỗi một cách khéo léo (fail gracefully). Nếu API của bạn hết thời gian chờ (timeout), hãy chuyển lỗi đó lại cho AI. Một mô hình tốt có thể xin lỗi người dùng hoặc gợi ý một giải pháp thay thế thay vì chỉ dừng hoạt động đột ngột.
Thứ hai, ngữ cảnh là tất cả. Đừng chỉ đặt tên công cụ là ‘get_data’. Hãy gọi nó là ‘fetch_nyse_stock_prices_in_usd’. Metadata của bạn càng mang tính mô tả cao, AI càng ít có khả năng chọn sai công cụ. Đó là sự khác biệt giữa một phỏng đoán và một quyết định có tính toán.
Cuối cùng, đừng bao giờ bỏ qua bảo mật. Việc trao cho LLM khả năng xóa các bản ghi cơ sở dữ liệu hoặc chuyển tiền là rất nguy hiểm. Luôn triển khai bước xác nhận “Human-in-the-Loop” (con người tham gia vào quy trình) cho bất kỳ hành động nào có rủi ro cao. Bạn cung cấp bộ não, nhưng bạn cũng phải cung cấp cả dây xích.
Tổng kết: Xây dựng tương lai của các Agent
Function calling là nền tảng của sự chuyển dịch sang kỷ nguyên ‘Agentic’ trong AI. Bằng cách kết nối OpenAI và Claude vào hệ thống hiện có, bạn sẽ vượt xa những bong bóng chat đơn thuần để hướng tới những hệ thống thực sự làm việc trong môi trường Production. Hãy bắt đầu từ quy mô nhỏ. Kết nối một API nội bộ, quan sát cách mô hình tương tác với nó và mở rộng từ đó. Khả năng hành động chính là điều biến một chatbot thành một người đồng nghiệp giá trị.

