Gọi hàm: so sánh Responses API và Chat Completions
So sánh ở cấp giao thức về định nghĩa hàm, ID lời gọi, kết quả, đối số truyền theo luồng, phân quyền, tính lũy đẳng và khả năng tương thích tuyến.

Responses và Chat Completions đều có thể yêu cầu ứng dụng chạy một hàm, nhưng biểu diễn vòng lặp công cụ khác nhau. Chat Completions định nghĩa hàm dưới tools[].function, trả về message.tool_calls và nhận kết quả bằng thông điệp role: "tool". Responses dùng định nghĩa hàm phẳng, mục đầu ra có kiểu function_call và function_call_output liên kết bằng call_id.
Mô hình không tự chạy hàm ứng dụng. Mã ứng dụng phải xác thực đối số, kiểm tra quyền của thao tác, thực thi chính xác, trả kết quả và ngăn tác dụng phụ lặp lại khi yêu cầu được thử lại.
Vòng lặp công cụ có bốn bước
1. Khai báo hàm được phép và lược đồ đối số
2. Nhận một hoặc nhiều lời gọi hàm do mô hình đề xuất
3. Xác thực, cấp quyền và thực thi từng lời gọi trong ứng dụng
4. Trả từng kết quả bằng ID tương quan của lời gọi
Chỉ sau bước bốn mô hình mới tạo câu trả lời dựa trên kết quả công cụ. Công cụ tiếp theo bắt đầu vòng mới với mã định danh lệnh gọi mới. Hướng dẫn OpenAI Function Calling cũng mô tả đây là trao đổi nhiều bước.
So sánh hợp đồng truyền tải
| Khía cạnh | Responses API | Chat Completions |
|---|---|---|
| Định nghĩa | Mục phẳng trong tools[] |
Trường dưới tools[].function |
| Lệnh gọi từ mô hình | Mục đầu ra function_call |
tool_calls[] trong thông điệp của trợ lý |
| Liên kết | call_id |
id, kết quả dùng tool_call_id |
| Tên | function_call.name |
tool_calls[].function.name |
| Đối số | Chuỗi JSON trong function_call.arguments |
Chuỗi JSON trong tool_calls[].function.arguments |
| Kết quả | function_call_output |
Thông điệp role: "tool" |
| Truyền phát | Sự kiện đối số có kiểu | Mảnh delta.tool_calls[] |
| Văn bản cuối | Mục đầu ra / hàm hỗ trợ SDK | choices[0].message.content |
Không liên kết các lệnh gọi theo vị trí trong mảng. Các lệnh gọi song song và mảnh dữ liệu có thể kết thúc theo thứ tự khác. Mã định danh lệnh gọi tường minh là khóa liên kết ổn định.
Định nghĩa lược đồ hàm nghiêm ngặt
{
"type": "object",
"properties": {
"order_id": {
"type": "string",
"pattern": "^ORDER-[0-9]{4}$"
}
},
"required": ["order_id"],
"additionalProperties": false
}
strict: true yêu cầu mô hình tuân thủ lược đồ, nhưng ứng dụng vẫn phải phân tích cú pháp và xác thực đối số. pattern cùng các từ khóa khác có thể khác theo nhà cung cấp; hãy dùng cùng bước kiểm tra tương thích như Structured Outputs.
Triển khai với Responses API
import OpenAI from "openai";
const client = new OpenAI({
apiKey: process.env.MODELFLARE_API_KEY,
baseURL: "https://modelflare.dev/v1",
});
const model = process.env.MODEL_ID;
if (!model) throw new Error("Bắt buộc phải có MODEL_ID");
const orders = new Map([
["ORDER-1001", { status: "in_transit", eta: "2026-08-06" }],
]);
const tools = [
{
type: "function",
name: "get_delivery_status",
description: "Trả về trạng thái giao hàng hiện tại của một đơn.",
parameters: {
type: "object",
properties: {
order_id: { type: "string", pattern: "^ORDER-[0-9]{4}$" },
},
required: ["order_id"],
additionalProperties: false,
},
strict: true,
},
];
function executeTool(name, rawArguments) {
if (name !== "get_delivery_status") {
throw new Error(`Công cụ không được phép: ${name}`);
}
const args = JSON.parse(rawArguments);
if (!/^ORDER-[0-9]{4}$/.test(args.order_id)) {
throw new Error("order_id không hợp lệ");
}
return orders.get(args.order_id) ?? { status: "not_found" };
}
const first = await client.responses.create({
model,
input: "Đơn ORDER-1001 đang ở đâu?",
tools,
parallel_tool_calls: false,
});
const calls = first.output.filter((item) => item.type === "function_call");
if (calls.length === 0) {
console.log(first.output_text);
process.exit(0);
}
const toolOutputs = calls.map((call) => ({
type: "function_call_output",
call_id: call.call_id,
output: JSON.stringify(executeTool(call.name, call.arguments)),
}));
const final = await client.responses.create({
model,
input: [...first.output, ...toolOutputs],
tools,
parallel_tool_calls: false,
});
console.log(final.output_text);
call.call_id phải khớp call_id của kết quả. Với trao đổi không lưu trạng thái, gửi lại mục đầu ra trước cùng kết quả. Không giả định mọi tuyến tương thích OpenAI đều lưu trạng thái phản hồi.
Triển khai với Chat Completions
import OpenAI from "openai";
const client = new OpenAI({
apiKey: process.env.MODELFLARE_API_KEY,
baseURL: "https://modelflare.dev/v1",
});
const model = process.env.MODEL_ID;
if (!model) throw new Error("Bắt buộc phải có MODEL_ID");
const orders = new Map([
["ORDER-1001", { status: "in_transit", eta: "2026-08-06" }],
]);
const tools = [
{
type: "function",
function: {
name: "get_delivery_status",
description: "Trả về trạng thái giao hàng hiện tại của một đơn.",
parameters: {
type: "object",
properties: {
order_id: { type: "string", pattern: "^ORDER-[0-9]{4}$" },
},
required: ["order_id"],
additionalProperties: false,
},
strict: true,
},
},
];
function executeTool(name, rawArguments) {
if (name !== "get_delivery_status") {
throw new Error(`Công cụ không được phép: ${name}`);
}
const args = JSON.parse(rawArguments);
if (!/^ORDER-[0-9]{4}$/.test(args.order_id)) {
throw new Error("order_id không hợp lệ");
}
return orders.get(args.order_id) ?? { status: "not_found" };
}
const messages = [
{ role: "user", content: "Đơn ORDER-1001 đang ở đâu?" },
];
const first = await client.chat.completions.create({
model,
messages,
tools,
parallel_tool_calls: false,
});
const assistant = first.choices[0].message;
const calls = assistant.tool_calls ?? [];
if (calls.length === 0) {
console.log(assistant.content);
process.exit(0);
}
messages.push(assistant);
for (const call of calls) {
const result = executeTool(call.function.name, call.function.arguments);
messages.push({
role: "tool",
tool_call_id: call.id,
content: JSON.stringify(result),
});
}
const final = await client.chat.completions.create({
model,
messages,
tools,
parallel_tool_calls: false,
});
console.log(final.choices[0].message.content);
Thông điệp của trợ lý chứa lệnh gọi phải được thêm trước kết quả công cụ. Thiếu thông điệp hoặc dùng tool_call_id không khớp sẽ tạo lịch sử hội thoại không hợp lệ.
Xem đối số truyền phát là các mảnh dữ liệu
{"order là JSON chưa hoàn tất, không phải JSON không hợp lệ. Duy trì bộ đệm theo từng lệnh gọi, nối từng phần tăng thêm, chờ đối số hoặc phản hồi hoàn tất, phân tích chuỗi đầy đủ một lần rồi xác thực và thực thi. Responses dùng sự kiện có kiểu; Chat Completions dùng choices[].delta.tool_calls[]. Không chạy hàm ở mảnh đầu tiên. Xem Hướng dẫn truyền phát AI API.
Thực thi công cụ an toàn và có tính lũy đẳng
- chỉ cho phép tên hàm đã đăng ký;
- giới hạn kích thước và xác thực lược đồ đầy đủ;
- kiểm tra quyền của người dùng hoặc khối lượng công việc đối với tài nguyên;
- tách công cụ chỉ đọc khỏi công cụ có tác dụng phụ;
- loại dữ liệu bí mật khỏi kết quả;
- đặt thời hạn và giới hạn số lần thử lại tới dịch vụ phụ thuộc;
- lưu tham chiếu thao tác an toàn.
Với tác dụng phụ, tạo khóa lũy đẳng từ yêu cầu ứng dụng ổn định và mã định danh lệnh gọi. Lưu bền vững kết quả trước khi trả về. Lần thử lại phải trả kết quả đã lưu thay vì hoàn tiền, gửi thông điệp, triển khai hoặc thay đổi cơ sở dữ liệu lần hai.
Tên hàm và đối số từ mô hình là dữ liệu đầu vào không đáng tin cậy. Lược đồ hợp lệ không cấp quyền và không thay thế ranh giới giao dịch.
Quyết định cách xử lý nhiều lệnh gọi
parallel_tool_calls: false giúp máy trạng thái dễ kiểm tra. Nếu bật chế độ song song, hãy liên kết bằng mã định danh lệnh gọi, giới hạn số lệnh gọi và mức đồng thời, xác định tác động của lỗi, trả một kết quả cho mỗi lệnh gọi và thực thi tuần tự các tác dụng phụ phụ thuộc thứ tự. Chế độ song song giảm độ trễ cho các thao tác đọc độc lập nhưng làm phức tạp việc phân quyền, thử lại và xử lý lỗi một phần.
Hiểu giới hạn tương thích Modelflare
Modelflare giữ định nghĩa hàm nghiêm ngặt và ánh xạ các dạng lệnh gọi được hỗ trợ giữa Responses và Chat Completions trên các tuyến OpenAI/Codex phù hợp. Phạm vi ánh xạ này cố ý hẹp hơn toàn bộ khả năng công cụ của Responses.
Hàm do ứng dụng định nghĩa có thể biểu diễn trong cả hai định dạng. Công cụ lưu trú do nhà cung cấp chạy, như tìm kiếm hoặc thực thi mã, không tương đương. Với các họ mô hình tương thích OpenAI khác, Chat Completions được chuyển tiếp nguyên trạng cho đến khi được xác minh; hợp đồng của nhà cung cấp quyết định khả năng hỗ trợ tools, strict, lệnh gọi song song, đối số truyền phát và tool_choice.
| Kiểm thử | Bằng chứng cần thiết |
|---|---|
| Lệnh gọi chỉ đọc | Tên, đối số, mã định danh lệnh gọi, liên kết kết quả, văn bản cuối |
| Đối số không hợp lệ | Lỗi rõ ràng, không thực thi |
| Hàm không xác định | Bị danh sách cho phép từ chối |
| Không cần công cụ | Văn bản bình thường, không có lệnh gọi bịa đặt |
| Truyền phát | Đối số hoàn chỉnh và mã định danh đúng |
| Yêu cầu lặp lại | Một tác dụng phụ hoặc kết quả đã lưu |
| Nhiều lệnh gọi | Liên kết không phụ thuộc thứ tự hoàn tất |
| Tuyến dự phòng | Cùng mô hình, giao thức, lược đồ và hợp đồng |
Dùng Định tuyến AI API đáng tin cậy để thay đổi tuyến một cách tường minh và Bảo mật khóa AI API để tách khối lượng công việc cùng quyền hạn.
Chọn định dạng theo hợp đồng ứng dụng
Dùng Responses khi cần các mục đầu ra có kiểu, mô hình sự kiện Responses, tiếp tục trạng thái hoặc khả năng đã xác minh. Dùng Chat Completions khi ứng dụng có lịch sử thông điệp ổn định và hợp đồng công cụ của nhà cung cấp đã được kiểm thử. Xem Responses API và Chat Completions.
Tiêu chuẩn ở cả hai định dạng giống nhau: danh sách công cụ cho phép rõ ràng, lược đồ đối số nghiêm ngặt, xác thực trong ứng dụng, phân quyền trước khi thực thi, liên kết bằng mã định danh lệnh gọi, tính lũy đẳng cho tác dụng phụ và kết quả đầy đủ cho mô hình. Các biện pháp kiểm soát này tạo độ tin cậy, không phải tên điểm cuối.