Chi tiết tham số API mô hình lớn: Từ trường yêu cầu đến trường phản hồi
Lần đầu xem tài liệu về API chat completion, bạn thường bị choáng ngợp bởi chuỗi tham số dài. Thực tế, bạn có thể hình dung một lần gọi giống như việc đặt món tại nhà hàng: messages là nhật ký trao đổi với nhân viên, temperature là mức độ sáng tạo bạn muốn đầu bếp thể hiện, max_tokens là lượng món tối đa được phục vụ, và tools là cách cho phép đầu bếp gọi điện hỏi nhà bếp về nguyên liệu. Bài viết này sẽ giải thích chi tiết từng trường theo cách tiếp cận đó.
Cập nhật lúc
Điểm chính
- messages bao gồm bốn vai trò: system, user, assistant, tool. Mô hình không có bộ nhớ, bạn phải tự mang theo lịch sử.
- temperature kiểm soát tính ngẫu nhiên, top_p kiểm soát phạm vi ứng viên. Hai tham số này có tác dụng tương tự, thường chỉ cần điều chỉnh một trong hai.
- finish_reason quyết định cách bạn xử lý kết quả: stop là kết thúc bình thường, length là bị cắt ngắn, tool_calls là bạn cần thực hiện hàm.
- Trường usage là cơ sở đáng tin cậy nhất để tính phí và ngân sách, bạn nên đọc nó mỗi lần.
Một yêu cầu trông như thế nào
Địa chỉ endpoint là POST https://api.apidamoxing.com/v1/chat/completions, header xác thực là Authorization: Bearer <key>, thân yêu cầu là JSON, tương thích với format chat completion của OpenAI. Hãy xem một yêu cầu đầy đủ bao gồm các trường thường dùng:
curl https://api.apidamoxing.com/v1/chat/completions \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "uncensored",
"messages": [
{"role": "system", "content": "你是一位耐心的天文科普作者。"},
{"role": "user", "content": "为什么月亮总是同一面朝向地球?"}
],
"temperature": 0.7,
"top_p": 0.9,
"max_tokens": 400,
"stop": ["###"]
}'Lưu ý rằng model ở đây chỉ được điền là uncensored vì dịch vụ chỉ có một mô hình, không có tùy chọn khác. Bạn có thể xác nhận bằng GET /v1/models. Dưới đây là giải thích từng trường.
Sau khi đọc hết bài, bạn sẽ thấy các tham số này thực chất thuộc ba nhóm: quyết định "nói gì" (messages, tools), quyết định "nói như thế nào" (temperature, top_p), và quyết định "nói bao nhiêu, khi nào dừng" (max_tokens, stop, stream). Hãy nhớ cách phân loại này; khi gặp trường lạ, hãy xác định nhóm của nó để đoán công dụng.
messages: "Sổ ghi chép" của cuộc hội thoại này
messages là một mảng, mỗi phần tử có role và content. Hãy tưởng tượng nó là một cuốn biên bản cuộc họp được ghi chép từng trang. Mô hình đọc lại từ đầu mỗi lần rồi viết trang tiếp theo. Nó không nhớ những gì đã đọc trước đó, nên trong hội thoại nhiều lượt, bạn phải cung cấp đầy đủ lịch sử.
| role | Người viết | Mục đích |
|---|---|---|
| system | Bạn (nhà phát triển) | Thiết lập nhân vật, quy tắc, định dạng đầu ra, thường đặt ở đầu tiên |
| user | Người dùng cuối | Đặt câu hỏi hoặc đưa ra chỉ thị |
| assistant | Mô hình (hoặc lịch sử bạn tự bổ sung) | Câu trả lời trước đó, dùng cho ngữ cảnh nhiều lượt |
| tool | Chương trình của bạn | Kết quả thực thi gọi hàm, cần kèm tool_call_id |
Một mẹo phổ biến: muốn mô hình viết tiếp theo một giọng điệu nào đó, bạn tự tạo một tin nhắn assistant đưa vào lịch sử. Nhớ rằng tổng số token của prompt và đầu ra không được vượt quá 100,000 token; lịch sử càng dài càng tốn dung lượng.
Ví dụ cụ thể: bạn tạo trợ lý chăm sóc khách hàng với system prompt “chỉ trả lời câu hỏi về đơn hàng, tối đa ba câu”. Lượt 1 user hỏi về thời gian giao hàng, lượt 2 hỏi “vậy thì trả hàng thì sao”. Yêu cầu lượt 2 cần chứa tuần tự: system, user lượt 1, assistant lượt 1, user lượt 2. Thiếu bất kỳ tin nhắn nào, mô hình sẽ không biết “vậy thì” ám chỉ điều gì.
Tham số lấy mẫu: Điều chỉnh "không gian sáng tạo"
Khi tạo ra từng ký tự, mô hình sẽ gán điểm xác suất cho tất cả các ký tự ứng viên rồi thực hiện việc chọn ngẫu nhiên. Hai tham số dưới đây là các núm vặn để điều chỉnh quy tắc chọn này:
| Tham số | Phép loại suy | Cách hiểu | Giá trị thường dùng |
|---|---|---|---|
| temperature | Độ sáng tạo của mô hình | Giá trị càng thấp thì phản hồi càng bảo thủ và ổn định; giá trị càng cao thì càng phân tán và đa dạng | Từ 0 đến 1.2; với các tác vụ hỏi đáp, hãy dùng giá trị thấp; với sáng tạo nội dung, hãy dùng giá trị cao |
| top_p | Chỉ lấy mẫu từ các ứng viên hàng đầu | Chỉ lấy mẫu từ các ứng viên có tổng xác suất tích lũy đạt ngưỡng p | Từ 0.8 đến 1; giá trị mặc định thường đã đủ dùng |
Cả hai tham số này đều kiểm soát mức độ ngẫu nhiên, chỉ khác về góc độ. Việc điều chỉnh đồng thời cả hai khiến bạn khó xác định hiệu ứng đến từ tham số nào, vì vậy bạn nên chỉ thay đổi một tham số tại một thời điểm. Các trường lấy mẫu chuẩn này sẽ được truyền nguyên vẹn qua endpoint; API sẽ không tự ý sửa đổi chúng.
Một ví dụ số trực quan hơn: giả sử ba ký tự có khả năng xuất hiện tiếp theo cao nhất có xác suất lần lượt là 60%, 30% và 10%. Việc giảm temperature sẽ làm tăng ưu thế cho ký tự có xác suất 60%, khiến đầu ra giống như việc luôn chọn ký tự hàng đầu; việc tăng temperature sẽ làm giảm khoảng cách xác suất giữa các ký tự, khiến các ký tự ít phổ biến hơn dễ được chọn hơn. Với top_p = 0.9, chỉ hai ký tự đầu tiên (tổng xác suất đạt 90%) được giữ lại, ký tự thứ ba bị loại. Những con số này chỉ là giả định để minh họa nguyên lý, không phải là xác suất thực tế.
Kiểm soát độ dài và điểm dừng: max_tokens, stop, stream
| Tham số | Chức năng | Lưu ý quan trọng |
|---|---|---|
| max_tokens | Giới hạn số lượng token tối đa được tạo ra trong lần gọi này | Mặc định 2048, tối đa mỗi lần 32,000; nó và prompt cộng lại không được vượt quá 100,000 token |
| stop | Dừng lại khi gặp chuỗi ký tự chỉ định | Có thể truyền một mảng chuỗi, phù hợp để phân đoạn hoặc cắt ngắn các định dạng cố định |
| stream | Có trả về dữ liệu theo dạng luồng hay không | Khi đặt thành true, dữ liệu được đẩy theo từng khối qua SSE; cuối cùng sẽ tự động nối thêm một khối chứa thông tin usage. |
max_tokens giống như kích thước đĩa khi phục vụ món ăn. Đĩa nhỏ, món chưa hết đã bị thu lại, lúc này finish_reason sẽ là length. stop giống như mật hiệu đã hẹn trước, đầu bếp nghe thấy mật hiệu thì dừng lại. stream không thay đổi nội dung, chỉ thay đổi cách giao hàng: từ "làm xong tất cả rồi mới bưng ra" thành "làm xong một miếng thì bưng một miếng", người dùng cảm thấy phản hồi nhanh hơn.
Một cách sử dụng rất thực tế của stop: bạn yêu cầu mô hình xuất theo định dạng cố định "Câu hỏi: ... Câu trả lời: ...###", sau đó đặt ### làm giá trị của stop. Mô hình sẽ tự động dừng khi gặp ký tự phân cách này, giúp tiết kiệm token và tránh việc mô hình nói thêm những điều thừa thãi. Lưu ý rằng khi stop được kích hoạt, finish_reason cũng sẽ là stop; nếu bạn cần phân biệt, hãy tự kiểm tra nội dung.
tools và tool_choice: Cho phép mô hình "gọi điện" hỏi bạn
Mô hình không thể truy cập dữ liệu thời gian thực. Cách tiếp cận gọi hàm (function calling) là: bạn cung cấp cho mô hình danh sách các hàm có sẵn; khi cần, thay vì trả lời trực tiếp, mô hình sẽ trả về yêu cầu "Hãy gọi hàm X với các tham số Y". Chương trình của bạn sẽ thực thi hàm đó và trả kết quả lại cho mô hình, sau đó mô hình sẽ dựa vào đó để tổ chức câu trả lời. Định dạng tương thích với OpenAI.
| Tham số | Giá trị | Mô tả |
|---|---|---|
| tools | Mảng mô tả hàm | Mỗi mục bao gồm name, description và parameters ở định dạng JSON Schema |
| tool_choice | "auto" / "none" / tên hàm cụ thể | auto để mô hình tự quyết định; none vô hiệu hóa việc gọi hàm; tên hàm cụ thể sẽ bắt buộc mô hình gọi hàm đó |
import json
import os
from openai import OpenAI
client = OpenAI(base_url="https://api.apidamoxing.com/v1", api_key=os.environ["API_KEY"])
tools = [{
"type": "function",
"function": {
"name": "get_tide_time",
"description": "查询某港口今天的高潮时刻",
"parameters": {
"type": "object",
"properties": {"port": {"type": "string", "description": "港口名称"}},
"required": ["port"],
},
},
}]
messages = [{"role": "user", "content": "青岛今天几点涨潮?"}]
first = client.chat.completions.create(
model="uncensored", messages=messages, tools=tools, tool_choice="auto"
)
msg = first.choices[0].message
if msg.tool_calls:
call = msg.tool_calls[0]
args = json.loads(call.function.arguments)
result = {"port": args["port"], "high_tide": "14:20"} # 这里换成你自己的查询
messages.append(msg)
messages.append({"role": "tool", "tool_call_id": call.id, "content": json.dumps(result, ensure_ascii=False)})
final = client.chat.completions.create(model="uncensored", messages=messages, tools=tools)
print(final.choices[0].message.content)
else:
print(msg.content)Quy trình gồm hai bước: bước đầu tiên nhận được tool_calls, bước thứ hai thêm kết quả có role là tool vào rồi thực hiện yêu cầu. description càng cụ thể thì mô hình càng biết khi nào nên gọi. Tham số là chuỗi JSON, bắt buộc phải dùng json.loads để phân tích và xác thực, đừng tin tưởng trực tiếp.
Các trường phản hồi: Đọc "hóa đơn" trả về
Một phản hồi thành công thường có cấu trúc cố định như sau:
{
"id": "chatcmpl-xxxx",
"object": "chat.completion",
"model": "uncensored",
"choices": [
{
"index": 0,
"message": {"role": "assistant", "content": "因为潮汐锁定……"},
"finish_reason": "stop"
}
],
"usage": {"prompt_tokens": 38, "completion_tokens": 212, "total_tokens": 250}
}| Trường | Ý nghĩa |
|---|---|
| choices | Mảng kết quả, thường chỉ có một phần tử; nội dung nằm ở choices[0].message.content |
| finish_reason | Lý do kết thúc: stop là kết thúc bình thường; length là bị cắt ngắn do đạt max_tokens; tool_calls là mô hình yêu cầu gọi hàm |
| usage.prompt_tokens | Số token tiêu thụ cho đầu vào |
| usage.completion_tokens | Số token tiêu thụ cho đầu ra |
| usage.total_tokens | Tổng của hai giá trị trên |
Trong mã nguồn, bạn nên kiểm tra finish_reason trước: nếu là length thì thông báo cho người dùng rằng nội dung bị cắt ngắn hoặc tự động viết tiếp; nếu là tool_calls thì đi theo nhánh thực thi hàm. Vai trò của usage được trình bày chi tiết hơn về phương pháp tính toán chi phí trong token với việc tính phí.
Những sai lầm phổ biến nhất khi dùng tham số
- Coi max_tokens là giới hạn đầu vào. Tham số này chỉ kiểm soát đầu ra; đầu vào do bạn kiểm soát.
- Cho rằng mô hình ghi nhớ yêu cầu trước đó. Mỗi yêu cầu là độc lập; lịch sử hội thoại do bạn tự quản lý.
- Cho rằng nếu đặt temperature = 0 thì kết quả luôn giống hệt nhau. Kết quả sẽ ổn định hơn, nhưng không nên giả định rằng chúng giống nhau từng ký tự.
- Đọc trực tiếp choices[0].message trong chế độ stream. Trong các khối stream, trường dữ liệu là delta, bạn cần tự ghép nối chúng.
- Quên thêm tin nhắn assistant chứa tool_calls vào lịch sử sau khi gọi hàm, dẫn đến lỗi ở bước tiếp theo.
Ý nghĩa của mã lỗi và chiến lược thử lại có thể xem trong tài liệu. Để xem một ví dụ hoàn chỉnh kết nối các tham số này, hãy tham khảo bài viết xây dựng bot trò chuyện.
Câu hỏi thường gặp
Bạn có thể đặt đồng thời temperature và top_p không?
Có thể, nhưng khó tách biệt hiệu ứng của từng tham số. Trong hầu hết các trường hợp, bạn chỉ cần điều chỉnh temperature; chỉ khi cần kiểm soát chính xác phạm vi ứng viên mới nên điều chỉnh top_p.
Nên làm gì nếu finish_reason là length?
Điều này cho thấy đầu ra đã đạt giới hạn max_tokens và bị cắt ngắn. Bạn có thể tăng max_tokens (giới hạn tối đa là 32,000) hoặc yêu cầu mô hình tạo nội dung theo từng phần.
Định dạng của tools có giống với OpenAI không?
Đúng vậy, bạn sử dụng định dạng tools và tool_choice của OpenAI; trường tool_calls trong phản hồi cũng có cấu trúc tương tự.
Làm sao để lấy thông tin sử dụng trong phản hồi stream?
Khi bật stream, một khối dữ liệu chứa usage sẽ tự động được thêm vào cuối cùng. Bạn chỉ cần đọc khối đó là được, không cần thêm tham số nào khác.
Chỉ cần điền biểu mẫu để lấy khóa API
Tạo tài khoản, sao chép khóa API và sửa đổi Base URL. Việc cấu hình rất đơn giản.