Tool Calling
Cho phép mô hình đề xuất lời gọi công cụ để ứng dụng thực thi an toàn và gửi lại kết quả.
Tool Calling cho phép mô hình chọn một hoặc nhiều công cụ dựa trên hội thoại và tạo tham số có cấu trúc cho lời gọi. Mô hình không thay ứng dụng truy cập cơ sở dữ liệu, gọi dịch vụ nội bộ hay thực hiện thao tác ghi; chương trình của bạn luôn chịu trách nhiệm thực thi công cụ.
Cách này phù hợp để truy vấn đơn hàng, đọc thông tin thời tiết, truy xuất kho kiến thức, tính toán dữ liệu và thực hiện thao tác nghiệp vụ xác định sau khi được cấp quyền.
Không thực thi trực tiếp tham số do mô hình tạo
Tên và tham số công cụ đều là đầu ra của mô hình. Trước khi thực thi, phải phân tích JSON, kiểm tra tính hợp lệ theo Schema, kiểm tra quyền và danh sách cho phép nghiệp vụ. Các thao tác rủi ro cao như thanh toán, xóa và gửi tin nhắn còn cần xác nhận của người dùng và kiểm soát tính idempotent.
Chu trình gọi đầy đủ
1. Định nghĩa công cụ
Sử dụng tên rõ ràng, mô tả mục đích và JSON Schema để cho mô hình biết khi nào có thể gọi công cụ và tham số cần có cấu trúc nào.
2. Gửi yêu cầu đến mô hình
Gửi đầu vào của người dùng cùng định nghĩa công cụ. Mô hình có thể trả lời trực tiếp hoặc trả về không, một hay nhiều lời gọi công cụ.
3. Xác thực và thực thi
Tra cứu triển khai cục bộ theo tên công cụ, kiểm tra toàn bộ tham số và quyền của người gọi, rồi thực thi với thời gian chờ. Không cho mô hình tự chỉ định hàm, URL, SQL hay lệnh Shell tùy ý.
4. Gửi lại kết quả công cụ
Dùng ID lời gọi do giao thức trả về để liên kết kết quả thực thi với lời gọi gốc, rồi gửi yêu cầu đến mô hình lần nữa.
5. Đọc câu trả lời cuối cùng
Mô hình có thể tạo câu trả lời cho người dùng dựa trên kết quả công cụ hoặc đề xuất lời gọi mới. Ứng dụng cần đặt số vòng lặp tối đa và nhận diện điều kiện kết thúc.
Định nghĩa công cụ chỉ đọc
Công cụ sau chỉ truy vấn thời tiết, không ghi dữ liệu ra bên ngoài:
{
"type": "function",
"function": {
"name": "get_weather",
"description": "Truy vấn thời tiết hiện tại của thành phố được chỉ định",
"parameters": {
"type": "object",
"properties": {
"city": {
"type": "string",
"description": "Tên thành phố, ví dụ Thượng Hải"
},
"unit": {
"type": "string",
"enum": ["celsius", "fahrenheit"]
}
},
"required": ["city", "unit"],
"additionalProperties": false
}
}
}Mô tả công cụ cần nêu “làm gì” và “khi nào sử dụng”. Giữ tên tham số ổn định, giới hạn enum trong phạm vi cần thiết, và dùng required cùng additionalProperties để hạn chế đầu vào không cần thiết.
Hoàn thành một chu trình công cụ Chat
Ví dụ sau trình bày luồng chính đầy đủ: khai báo công cụ, đọc lời gọi, thực thi hàm cục bộ, gửi lại kết quả và đọc câu trả lời cuối cùng:
import json
from openai import OpenAI
client = OpenAI(
api_key="your-api-key",
base_url="https://api.agtcloud.cn/v1",
)
tools = [
{
"type": "function",
"function": {
"name": "get_weather",
"description": "Truy vấn thời tiết hiện tại của thành phố được chỉ định",
"parameters": {
"type": "object",
"properties": {
"city": {"type": "string"},
"unit": {
"type": "string",
"enum": ["celsius", "fahrenheit"],
},
},
"required": ["city", "unit"],
"additionalProperties": False,
},
},
}
]
def get_weather(city: str, unit: str) -> dict[str, str | int]:
if city != "Thượng Hải" or unit != "celsius":
raise ValueError("Ví dụ chỉ cho phép truy vấn nhiệt độ tại Thượng Hải theo độ Celsius")
return {"city": city, "unit": unit, "temperature": 25}
messages = [{"role": "user", "content": "Hiện tại ở Thượng Hải bao nhiêu độ?"}]
response = client.chat.completions.create(
model="MODEL_ID",
messages=messages,
tools=tools,
tool_choice="auto",
)
assistant_message = response.choices[0].message
messages.append(assistant_message)
for tool_call in assistant_message.tool_calls or []:
if tool_call.function.name != "get_weather":
raise ValueError("Mô hình yêu cầu một công cụ chưa đăng ký")
arguments = json.loads(tool_call.function.arguments)
result = get_weather(**arguments)
messages.append(
{
"role": "tool",
"tool_call_id": tool_call.id,
"content": json.dumps(result, ensure_ascii=False),
}
)
if assistant_message.tool_calls:
final_response = client.chat.completions.create(
model="MODEL_ID",
messages=messages,
tools=tools,
)
print(final_response.choices[0].message.content)
else:
print(assistant_message.content)Ứng dụng thực tế cần dùng thư viện kiểm tra tính hợp lệ theo JSON Schema để kiểm tra arguments, đồng thời thiết lập quyền, thời gian chờ, loại lỗi và nhật ký kiểm toán riêng cho công cụ.
Cách các giao thức biểu diễn lời gọi công cụ
| Giao thức | Định nghĩa công cụ | Lời gọi của mô hình | Gửi lại kết quả công cụ |
|---|---|---|---|
| Chat Completions | tools[].function | trong Assistant Message tool_calls | role: tool và tool_call_id |
| Responses | Function Tool trong tools | function_call Output Item | function_call_output và call_id |
| Anthropic Messages | tools và input_schema | tool_use Content Block | tool_result Content Block |
| Gemini | functionDeclarations | trong Part functionCall | trong Part functionResponse |
Không trộn tên trường và cấu trúc lồng nhau giữa các giao thức. Xem cấu trúc đầy đủ trong Reference của Chat Completions, Responses, Anthropic Messages và Gemini Generate Content.
Nhiều lời gọi và Streaming
- Không giả định mỗi lần chỉ gọi được một công cụ; kiểm tra tính hợp lệ, thực thi và gửi kết quả riêng theo ID lời gọi.
- Chỉ thực thi song song các lời gọi chỉ đọc độc lập với nhau và được nghiệp vụ cho phép.
- Tham số theo luồng có thể bị chia thành nhiều phần tăng dần; phải ghép đầy đủ trước khi phân tích JSON.
- Sau khi nhận kết quả công cụ, mô hình vẫn có thể đề xuất vòng gọi tiếp theo; ứng dụng cần giới hạn số vòng và tổng thời gian chờ.
- Khi thử lại cùng một thao tác ghi, dùng khóa idempotency của nghiệp vụ để tránh trừ tiền, gửi dữ liệu hoặc tạo tài nguyên lặp lại.
Xử lý thất bại
Khi công cụ thực thi thất bại, không tạo kết quả thành công giả. Có thể gửi lại loại lỗi đã che thông tin nhạy cảm, như tham số không hợp lệ, thiếu quyền hoặc dịch vụ thượng nguồn tạm thời không khả dụng, để mô hình giải thích cho người dùng hoặc chọn phương án thay thế được phép.
Không gửi trực tiếp cho mô hình hoặc người dùng các thông tin sau: stack trace nội bộ, cấu trúc cơ sở dữ liệu, token truy cập, địa chỉ mạng riêng và phản hồi bên thứ ba chưa được che thông tin nhạy cảm.
Kiểm tra trước khi đưa vào production
- Chỉ chọn công cụ từ registry hoặc danh sách cho phép.
- Tham số được kiểm tra tính hợp lệ theo Schema và quy tắc nghiệp vụ trước khi thực thi.
- Mỗi công cụ có kiểm soát quyền, thời gian chờ, kích thước kết quả tối đa và xử lý lỗi.
- Thao tác ghi rủi ro cao có xác nhận của người dùng, hỗ trợ idempotency và kiểm toán.
- Chu trình gọi có số vòng tối đa, không để mô hình tiếp tục vô hạn.
- Chỉ thực thi tham số công cụ theo luồng sau khi nhận đầy đủ.
Để ghép tham số công cụ trong khi nhận dữ liệu, xem Streaming; để câu trả lời cuối cùng tuân theo JSON Schema, xem Structured Output.