大型模型 API 接口參數詳解:從請求欄位到回應欄位
第一次看聊天補全接口的文件,往往會被一長串參數嚇住。其實可以把一次呼叫想像成去餐廳點菜:messages 是你和服務員的對話記錄,temperature 是你要廚師發揮多少,max_tokens 是這道菜最多上多少量,tools 則是允許廚師向後廚打電話問食材。這篇按這個思路,一張表一張表地把每個欄位講透。
更新於
重點
- messages 由 system、user、assistant、tool 四種角色組成,模型沒有記憶,歷史要你自己帶。
- temperature 控制隨機性,top_p 控制候選範圍,兩者作用相近,通常只調其一。
- finish_reason 決定你該怎麼處理結果:stop 是正常結束,length 是被截斷,tool_calls 是要你去執行函式。
- usage 欄位是計費和預算的唯一可靠依據,每次都應該讀取。
一次請求長什麼樣
接口地址是 POST https://api.apidamoxing.com/v1/chat/completions,鑑權頭為 Authorization: Bearer <key>,請求體是 JSON,格式與 OpenAI 的聊天補全相容。先看一個把常用欄位都用上的完整請求:
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": ["###"]
}'注意這裡的 model 只能填 uncensored,因為服務只有一個模型,沒有可選項目。可以用 GET /v1/models 確認。下面按欄位逐個解釋。
讀完整篇你會發現,這些參數其實可以歸成三類:決定「說什麼」的(messages、tools),決定「怎麼說」的(temperature、top_p),決定「說多少、何時停」的(max_tokens、stop、stream)。記住這個分類,以後遇到陌生欄位,先判斷它屬於哪一類,大半就能猜出用途。
messages:這場對話的「記錄本」
messages 是一個陣列,每個元素有 role 和 content。想像它是一本逐頁記錄的會議紀要,模型每次都從頭讀一遍,然後寫下一頁。它自己不會記得上次讀過什麼,所以多輪對話時,歷史必須由你完整帶上。
| role | 誰寫的 | 用途 |
|---|---|---|
| system | 你(開發者) | 設定身份、規則、輸出格式,通常放在最前面 |
| user | 最終使用者 | 提問或指令 |
| assistant | 模型(或你補寫的歷史) | 之前的回答,用於多輪上下文 |
| tool | 你的程式 | 函式呼叫的執行結果,需帶 tool_call_id |
一個常見的技巧:想讓模型按某種口吻接著寫,可以自己構造一條 assistant 訊息放進歷史裡。要記住 prompt 和輸出合計不能超過 100,000 token,歷史越長越佔空間。
舉個具體的例子。你做了一個客服助手,system 寫「只回答與訂單有關的問題,回答不超過三句」。使用者第一輪問發貨時間,第二輪追問「那退貨呢」。第二輪請求裡,messages 要依次包含:system、第一轮的 user、第一輪模型的 assistant 回答、第二輪的 user。缺任何一條,模型都不知道「那」指的是什麼。
採樣參數:調「發揮空間」
模型生成每個字時,會先給所有候選字打機率分,再抽籤。下面兩個參數就是調整抽籤規則的旋鈕:
| 參數 | 類比 | 怎麼理解 | 常見取值 |
|---|---|---|---|
| temperature | 廚師的創意度 | 越低越保守、越穩定;越高越發散 | 0 到 1.2,問答類取低,創作取高 |
| top_p | 只在前幾名裡抽 | 只從累計機率達到 p 的候選裡抽籤 | 0.8 到 1,預設通常夠用 |
兩者都在管「隨機多少」,只是角度不同。同時調很難判斷效果來自哪個,所以建議一次只動一個。這些標準採樣欄位會原樣透傳,介面不會私自改寫。
再用一個直觀的數字例子:假設模型接下去最可能的三個字,機率分別是 60%、30%、10%。temperature 調低,會讓 60% 的那個更佔優勢,輸出更像每次都選第一名;調高則把三者拉近,冷門字更容易被抽中。top_p 取 0.9 的話,只保留累計到 90% 的前兩個字,第三個直接出局。這些數字僅為說明原理的假設,並非真實機率。
控制長度與停止:max_tokens、stop、stream
| 參數 | 作用 | 要點 |
|---|---|---|
| max_tokens | 限制本次最多生成多少 token | 預設 2048,單次最大 32,000;它與 prompt 合計不得超過 100,000 |
| stop | 遇到指定字串就停 | 可傳字串陣列,適合做分段、截斷固定格式 |
| stream | 是否串流返回 | 設為 true 後用 SSE 逐塊推送,最後自動追加一個帶 usage 的資料塊 |
max_tokens 就像一次上菜的盤子大小。盤子小了,菜沒上完就被端走,這時 finish_reason 會是 length。stop 則像預先約定的信號,廚師聽到信號就收手。stream 不改變內容,只改變交付方式:從「全部做好再端上來」變成「做好一口上一口」,使用者感覺回應更快。
stop 有個很實用的用法:你讓模型按「問題:……答案:……###」的固定格式輸出,再把 ### 設為 stop,生成到分隔符就自動停止,既省 token,也避免它後面多說廢話。注意 stop 命中時 finish_reason 同樣是 stop,如果你要區分,需要自己檢查內容。
tools 與 tool_choice:讓模型「打電話」問你
模型本身查不到即時資料。function calling 的做法是:你先告訴模型有哪些函式可用,模型判斷需要時,不直接回答,而是返回「請呼叫某函式,參數是……」,你的程式執行後把結果交回,模型再據此組織答案。格式與 OpenAI 一致。
| 參數 | 取值 | 說明 |
|---|---|---|
| tools | 函式描述陣列 | 每個含 name、description 和 JSON Schema 形式的 parameters |
| tool_choice | "auto" / "none" / 指定函式 | auto 由模型決定,none 禁止呼叫,指定函式則強制呼叫它 |
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)流程是兩輪:第一輪拿到 tool_calls,第二輪把 role 為 tool 的結果追加後再請求。description 寫得越具體,模型越知道什麼時候該調。參數是 JSON 字串,務必用 json.loads 解析並做校驗,別直接信任。
回應欄位:讀懂返回的「收據」
一次成功回應大致如下,欄位是固定的:
{
"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}
}| 欄位 | 含義 |
|---|---|
| choices | 結果陣列,通常只有一項,正文在 choices[0].message.content |
| finish_reason | 結束原因:stop 正常結束;length 觸達 max_tokens 被截斷;tool_calls 模型請求呼叫函式 |
| usage.prompt_tokens | 輸入消耗的 token |
| usage.completion_tokens | 輸出消耗的 token |
| usage.total_tokens | 兩者之和 |
程式碼裡應該先看 finish_reason:是 length 就提示使用者內容被截斷或者自動續寫;是 tool_calls 就走函式執行分支。usage 的作用在token 與計費那篇裡有更詳細的預算方法。
幾個最容易踩的參數誤區
- 把 max_tokens 當成「輸入上限」。它只管輸出,輸入由你控制。
- 以為模型記得上一次請求。每次請求都是獨立的,歷史自己帶。
- temperature 設 0 就以為每次結果完全相同。會更穩定,但不應當假設逐字一致。
- 串流模式下直接讀 choices[0].message。串流的塊裡欄位是 delta,要自己拼接。
- tool 呼叫後忘記追加 assistant 那條帶 tool_calls 的訊息,導致第二輪報錯。
常見問題
可以同時設置 temperature 和 top_p 嗎?
可以,但效果難以拆分判斷。多數場景只調 temperature 即可,需要精細控制候選範圍時再動 top_p。
finish_reason 為 length 時該怎麼辦?
說明輸出觸達 max_tokens 被截斷。可以調大 max_tokens,上限 32,000,或者讓模型分段生成。
tools 的格式和 OpenAI 一樣嗎?
是的,使用 OpenAI 格式的 tools 與 tool_choice,回應裡的 tool_calls 也是同樣的結構。
串流回應裡怎麼拿到用量?
開啟 stream 後,最後會自動追加一個包含 usage 的資料塊,讀取它即可,無需額外參數。
只需填寫表單即可獲取金鑰
創建帳戶,複製金鑰,修改 Base URL。配置就是這麼簡單。