打造專屬 ChatGPT(一):Chat Completions API 基礎參數解析 (20260601更新)
A. 前言:為什麼要理解 Chat Completions API 參數?
如果你想自己打造一個類似 ChatGPT 的應用,OpenAI 的 Chat Completions API 是最常被拿來入門的介面之一。
它的核心概念其實很簡單:我們把一組對話訊息傳給模型,模型根據這些訊息產生下一則回覆。這組訊息通常會包含使用者輸入、系統或開發者指令、歷史對話,以及工具呼叫的結果。模型回傳的內容則通常會是一則 assistant message,也就是 AI 助理的回答。
但當我們真的要把它做成一個產品,就不會只需要 model 和 messages 這兩個基本參數而已。
例如:
- 你希望模型回答穩定一點,還是有創意一點?
- 你希望模型輸出一般文字,還是固定格式的 JSON?
- 你希望模型可以呼叫外部工具,例如查資料庫、查天氣、查訂單狀態嗎?
- 你希望使用者看到文字一段一段串流出現,而不是等整段回答完成才顯示嗎?
- 你希望記錄每次請求的 metadata,方便日後分析、追蹤或除錯嗎?
- 你希望限制回答長度、控制成本,或取得 token 使用量嗎?
這些需求都會對應到不同的 API 參數,例如 temperature、top_p、max_completion_tokens、response_format、tools、tool_choice、stream、store、metadata、logprobs 等等。
也就是說,Chat Completions API 不是只有「送出 prompt,拿回答案」這麼簡單。它更像是一個可以控制模型行為的介面。你設定的每個參數,都會影響模型如何理解上下文、如何產生回答、如何輸出格式、如何呼叫工具,以及這次請求如何被記錄和追蹤。
理解這些參數的目的,不是要每次請求都把所有參數填滿。相反地,真正重要的是知道:
- 哪些參數是必要的?
- 哪些參數是一般應用最常用的?
- 哪些參數只適合進階情境?
- 哪些參數已經屬於相容性或 legacy 用法?
- 哪些參數會影響成本、延遲、穩定性與可維護性?
這篇文章會用開發者實作的角度,整理 Chat Completions API 的常用與進階參數,並補充每個參數適合的使用情境。目標不是逐字翻譯官方文件,而是建立一張比較容易理解的參數地圖,讓你在打造自己的 ChatGPT、客服機器人、AI 助理、資料抽取工具或 Tool Calling Agent 時,可以更清楚知道每個參數控制的是哪一層行為。
B. 最小可用範例:發出第一個 Chat Completion 請求
在正式介紹所有參數之前,我們先從最小可用範例開始。
雖然 OpenAI 官方 Quickstart 目前較常以 Responses API 作為新專案的入門範例,但 Chat Completions API 仍然保留在 API Reference 中,並且仍可透過 POST /chat/completions 建立對話回覆。這篇文章聚焦在 Chat Completions API,因此以下範例會使用 client.chat.completions.create(…)。
Chat Completions API 最基本需要兩個核心參數:
- model:指定要使用哪一個模型。
- messages:提供一組對話訊息,讓模型根據上下文產生回覆。
如果使用 Python,可以先安裝 OpenAI 官方 SDK:
pip install openai
接著設定 API key。實務上不建議把 API key 直接寫死在程式碼裡,比較好的方式是使用環境變數:
export OPENAI_API_KEY="你的 API key"
如果是在 Windows PowerShell,可以使用:
$env:OPENAI_API_KEY="你的 API key"
接著就可以建立第一個 Chat Completion 請求:
from openai import OpenAI
client = OpenAI()
completion = client.chat.completions.create(
model="gpt-5.5",
messages=[
{
"role": "user",
"content": "請用一句話解釋 Chat Completions API 是什麼。"
}
],
)
print(completion.choices[0].message.content)
這段程式做了幾件事。
首先,OpenAI() 會建立一個 API client。預設情況下,它會從環境變數 OPENAI_API_KEY 讀取 API key,所以我們不需要在程式碼中直接放入金鑰。
接著,client.chat.completions.create(…) 會發出一個 Chat Completions API 請求。其中 model 指定這次要使用的模型,messages 則是一個陣列,用來描述目前的對話內容。
在這個最小範例中,我們只傳入一則 user message:
messages=[
{
"role": "user",
"content": "請用一句話解釋 Chat Completions API 是什麼。"
}
]
role 代表這則訊息的角色,content 則是訊息內容。這裡的 role 是 user,表示這是使用者對模型提出的問題。模型收到這組 messages 之後,會產生一則 assistant 回覆。
回傳結果會放在 completion 物件中。一般最常讀取的欄位是:
completion.choices[0].message.content
其中:
- choices 是模型產生的候選回覆列表。
- choices[0] 代表第一個候選回覆。
- message 是模型產生的 assistant message。
- content 是 assistant message 的文字內容。
如果執行成功,輸出可能會類似:
Chat Completions API 是一個讓開發者把對話訊息傳給模型,並取得 AI 回覆的介面。
這就是一個最基本的 Chat Completions API 請求。
不過,實務上我們通常不會只傳一則 user message。為了讓模型更符合應用需求,通常會加入應用程式層級的指令,例如要求模型使用繁體中文、限制回答格式,或指定它扮演某種角色。
在較新的模型中,如果要提供開發者層級的指令,建議優先使用 developer message。你仍然可能在舊範例或相容情境中看到 system message,但對 o1 與更新模型而言,官方文件已說明 developer messages 取代先前的 system messages。
例如:
from openai import OpenAI
client = OpenAI()
completion = client.chat.completions.create(
model="gpt-5.5",
messages=[
{
"role": "developer",
"content": "你是一位熟悉 Python 與 API 設計的技術寫作者,請使用繁體中文回答。"
},
{
"role": "user",
"content": "請用一句話解釋 Chat Completions API 是什麼。"
}
],
)
print(completion.choices[0].message.content)
在這個版本中,developer message 用來提供開發者層級的指令,告訴模型應該遵守什麼規則、使用什麼語言、採用什麼風格,或用什麼方式回答。user message 則是使用者實際提出的問題。
可以把它想成:
- developer message:應用程式希望模型遵守的規則。
- user message:使用者這次真正輸入的內容。
- assistant message:模型產生的回覆。
這也是 Chat Completions API 最重要的心智模型:你不是只傳一段 prompt,而是傳一組有角色、有順序的 messages。模型會根據這些 messages 產生下一則 assistant message。
另外,這裡的範例先使用最單純的純文字 content。實際上,Chat Completions API 的 message content 也可以依照角色與模型支援,使用 content parts 來表示更複雜的輸入,例如文字、圖片或其他多模態內容。這部分會在後面的多模態段落再介紹。
在後面的段落中,我們會從這個最小範例出發,逐步拆解 model、messages、生成控制、輸出格式、工具呼叫、串流回應與回傳物件等參數。
C. Chat Completions API 的基本結構
在看完最小可用範例之後,我們先把 Chat Completions API 的整體結構整理清楚。
Chat Completions API 可以先用一句話理解:
你把一組 messages 傳給模型,模型根據這組對話內容產生下一則 assistant message。
從 API 的角度來看,它主要可以拆成四個部分:
- endpoint:請求送到哪裡。
- request body:這次請求要帶哪些參數。
- response object:非串流模式下,API 一次回傳的完整結果。
- streaming chunk:串流模式下,API 分段回傳的片段資料。
C.1 endpoint:請求送到哪裡
Chat Completions API 的建立請求使用:
POST /v1/chat/completions
如果使用 OpenAI Python SDK,通常不需要自己手動組 HTTP request,而是透過:
client.chat.completions.create(...)
來建立一個 Chat Completion。
例如:
from openai import OpenAI
client = OpenAI()
completion = client.chat.completions.create(
model="gpt-5.5",
messages=[
{
"role": "user",
"content": "請用一句話解釋 Chat Completions API。"
}
],
)
這段 SDK 寫法背後對應的就是建立一個 Chat Completion 請求。
C.2 request body:這次請求要帶哪些參數
Chat Completions API 的 request body 是一個 JSON 物件,用來描述這次請求的模型、對話內容,以及各種控制模型輸出的設定。
最小可用的 request body 大致會長這樣:
{
"model": "gpt-5.5",
"messages": [
{
"role": "user",
"content": "請用一句話解釋 Chat Completions API。"
}
]
}
其中最核心的兩個欄位是:
- model:指定要使用的模型。
- messages:指定目前的對話內容。
除此之外,實務上常見的 request body 還會加入其他參數,例如:
{
"model": "gpt-5.5",
"messages": [
{
"role": "developer",
"content": "你是一位技術寫作者,請使用繁體中文回答。"
},
{
"role": "user",
"content": "請用一句話解釋 Chat Completions API。"
}
],
"temperature": 0.7,
"max_completion_tokens": 300,
"stream": false
}
在這個例子中:
- developer message 用來設定應用程式層級的指令。
- user message 是使用者實際提出的問題。
- temperature 控制輸出的隨機程度。
- max_completion_tokens 控制模型最多可以產生多少 token。
- stream 控制是否使用串流回應。
後面的段落會依照不同用途,逐一拆解這些參數。
C.3 response object:非串流模式下的完整回傳結果
當 stream 沒有啟用,或設定為 false 時,API 會等模型產生完整結果後,一次回傳一個 Chat Completion object。
簡化後的回傳結構大致會像這樣:
{
"id": "chatcmpl_xxx",
"object": "chat.completion",
"created": 1710000000,
"model": "gpt-5.5",
"choices": [
{
"index": 0,
"message": {
"role": "assistant",
"content": "Chat Completions API 是一個讓開發者把對話訊息傳給模型,並取得 AI 回覆的介面。"
},
"finish_reason": "stop"
}
],
"usage": {
"prompt_tokens": 20,
"completion_tokens": 30,
"total_tokens": 50
}
}
一般開發時,最常讀取的是:
completion.choices[0].message.content
這個欄位代表第一個候選回覆中的 assistant 文字內容。
可以把 response object 想成「這次模型完成回答後的完整紀錄」。它不只包含回答文字,也包含:
- 這次請求的 id
- 使用的 model
- 模型產生的 choices
- 結束原因 finish_reason
- token 使用量 usage
其中 usage 對產品開發很重要,因為它可以用來追蹤成本、分析請求量,或估算不同功能的 token 消耗。
C.4 streaming chunk:串流模式下的分段回傳
如果把 stream 設定為 true,API 不會等整段回答完成後才一次回傳,而是會把模型產生的內容分成多個 chunk 逐步送回來。
Python SDK 範例:
from openai import OpenAI
client = OpenAI()
stream = client.chat.completions.create(
model="gpt-5.5",
messages=[
{
"role": "user",
"content": "請用三句話介紹 Chat Completions API。"
}
],
stream=True,
)
for chunk in stream:
if chunk.choices and chunk.choices[0].delta.content:
print(chunk.choices[0].delta.content, end="")
串流模式下,每次收到的不是完整的 Chat Completion object,而是 Chat Completion Chunk object。
簡化後的 chunk 可能長這樣:
{
"id": "chatcmpl_xxx",
"object": "chat.completion.chunk",
"created": 1710000000,
"model": "gpt-5.5",
"choices": [
{
"index": 0,
"delta": {
"content": "Chat"
},
"finish_reason": null
}
]
}
下一個 chunk 可能會接著回傳:
{
"id": "chatcmpl_xxx",
"object": "chat.completion.chunk",
"created": 1710000000,
"model": "gpt-5.5",
"choices": [
{
"index": 0,
"delta": {
"content": " Completions"
},
"finish_reason": null
}
]
}
直到最後一個 chunk,finish_reason 才會出現,例如:
{
"id": "chatcmpl_xxx",
"object": "chat.completion.chunk",
"created": 1710000000,
"model": "gpt-5.5",
"choices": [
{
"index": 0,
"delta": {},
"finish_reason": "stop"
}
]
}
也就是說,非串流模式下,我們通常讀:
completion.choices[0].message.content
串流模式下,我們則通常逐步讀:
chunk.choices[0].delta.content
這兩者的差異很重要:
- message:代表完整 assistant message。
- delta:代表這次 chunk 新增的片段內容。
如果你正在做聊天 UI,通常會使用串流模式,讓使用者看到文字一段一段出現,體驗會更接近 ChatGPT。
如果你是在做批次資料處理、背景任務或結構化資料抽取,則不一定需要串流,一次拿完整 response object 會更容易處理。
C.5 用一張表整理基本結構
| 結構 | 說明 | 常見位置 |
|---|---|---|
| endpoint | API 請求位置 | POST /v1/chat/completions |
| request body | 請求參數 | model、messages、temperature、tools、stream |
| response object | 非串流模式的完整回傳結果 | completion.choices[0].message.content |
| streaming chunk | 串流模式的片段回傳結果 | chunk.choices[0].delta.content |
理解這四個結構之後,後面看每個參數會清楚很多。
model 和 messages 決定模型要根據什麼內容回答;temperature、top_p、max_completion_tokens 會影響模型如何生成內容;response_format 會影響輸出格式;tools 和 tool_choice 會影響模型是否能呼叫外部工具;stream 則會改變回傳資料的形式。
接下來,我們就可以先從最核心的 messages 開始看起。
D. messages:對話的核心
在 Chat Completions API 裡,messages 是最核心的參數。
很多人剛開始使用 LLM API 時,會把它想成「送出一段 prompt,拿回一段回答」。但在 Chat Completions API 裡,比較精準的理解方式是:
你不是只傳一段 prompt,而是傳一組有角色、有順序的對話訊息。
這組對話訊息就是 messages。
最簡單的 messages 可能只有一則 user message:
[
{
"role": "user",
"content": "請用一句話解釋 Chat Completions API 是什麼。"
}
]
模型收到這組 messages 之後,會根據目前的對話內容,產生下一則 assistant message。
如果把它放進 Python SDK,會像這樣:
completion = client.chat.completions.create(
model="gpt-5.5",
messages=[
{
"role": "user",
"content": "請用一句話解釋 Chat Completions API 是什麼。"
}
],
)
這裡的重點是:messages 是一個陣列,陣列中的每一個物件都是一則訊息。每則訊息至少會有 role,並依照角色不同,帶有 content 或其他欄位。
D.1 messages 的順序很重要
messages 不是單純的資料集合,而是一段有順序的對話紀錄。
模型會按照陣列順序理解上下文。越前面的訊息越像前文,越後面的訊息越接近目前要回答的問題。
例如:
[
{
"role": "developer",
"content": "請使用繁體中文回答,並保持回答簡潔。"
},
{
"role": "user",
"content": "什麼是 Chat Completions API?"
}
]
這裡模型會先看到 developer message,知道應該用繁體中文、回答要簡潔,接著再看到 user message,知道使用者真正想問的是什麼。
如果是多輪對話,messages 會包含過去的使用者問題與 assistant 回答:
[
{
"role": "developer",
"content": "請使用繁體中文回答,並保持回答簡潔。"
},
{
"role": "user",
"content": "什麼是 Chat Completions API?"
},
{
"role": "assistant",
"content": "Chat Completions API 是一個讓開發者傳入對話訊息,並取得模型回覆的 API。"
},
{
"role": "user",
"content": "那它和一般 prompt 有什麼不同?"
}
]
在這個例子裡,最後一則 user message 才是這次真正要回答的問題,但前面的訊息會提供上下文。模型會知道使用者問的「它」指的是 Chat Completions API。
D.2 developer message:開發者層級的指令
developer message 用來放應用程式希望模型遵守的規則。
例如:
{
"role": "developer",
"content": "你是一位熟悉 Python 與 API 設計的技術寫作者。請使用繁體中文回答,並優先提供可執行的範例。"
}
developer message 常見用途包括:
- 指定回答語言。
- 指定模型扮演的角色。
- 指定回答格式。
- 指定語氣與風格。
- 指定安全、合規或產品規則。
- 指定工具使用原則。
例如你正在做一個客服機器人,可以在 developer message 中放入:
{
"role": "developer",
"content": "你是 TallyTrip 的客服助理。請使用繁體中文回答。若使用者詢問帳務、付款或個人資料問題,請提醒使用者前往官方客服管道確認。"
}
這樣每次請求都可以讓模型知道它不是一般聊天機器人,而是某個產品中的 AI 助理。
在較新的模型中,若要放開發者層級的指令,建議優先使用 developer message。你仍然可能在舊文章、舊 SDK 範例或相容性情境中看到 system message,但對 o1 與更新模型而言,官方文件已說明 developer messages 取代先前的 system messages。(OpenAI Developer Community)
D.3 system message:舊範例中常見的系統指令
system message 過去常用來放高層級指令,例如:
{
"role": "system",
"content": "You are a helpful assistant."
}
在許多早期 Chat Completions API 教學裡,你會看到這種寫法:
completion = client.chat.completions.create(
model="gpt-4o-mini",
messages=[
{
"role": "system",
"content": "你是一位專業的技術寫作者,請使用繁體中文回答。"
},
{
"role": "user",
"content": "請解釋 API rate limit 是什麼。"
}
],
)
這種寫法在很多舊專案中仍然看得到。不過如果你正在寫新的範例,並且使用較新的模型,建議優先示範 developer message,讓文章和目前 API 文件的用語保持一致。
簡單來說:
| role | 建議用法 |
|---|---|
| developer | 新範例優先使用,用來放應用程式層級的規則與指令 |
| system | 舊範例、舊模型或相容性情境中仍可能看到 |
| user | 使用者輸入 |
| assistant | 模型過去產生的回答 |
| tool | 外部工具執行後回傳給模型的結果 |
| function | legacy 用法,通常不建議新專案使用 |
D.4 user message:使用者輸入
user message 代表使用者實際輸入的內容。
例如:
{
"role": "user",
"content": "請幫我把這段英文翻成繁體中文。"
}
或:
{
"role": "user",
"content": "請根據以下訂單資料,整理成客服回覆。"
}
在大多數應用中,user message 會來自前端表單、聊天輸入框、API request,或其他使用者提交的內容。
如果是一般聊天機器人,每次使用者送出新訊息時,你通常會把它加入 messages 陣列的最後面:
messages.append({
"role": "user",
"content": user_input
})
接著再把整組 messages 傳給 Chat Completions API。
D.5 assistant message:模型的回答與對話歷史
assistant message 代表模型產生過的回答。
在 API 回傳結果中,模型產生的內容通常會出現在:
completion.choices[0].message
其中 message.role 通常會是 assistant,message.content 則是模型回覆的文字內容。
例如:
{
"role": "assistant",
"content": "Chat Completions API 是一個讓開發者傳入對話訊息,並取得模型回覆的 API。"
}
如果你要做多輪對話,必須自己保存對話歷史。Chat Completions API 不會自動記住上一輪對話;每次請求都需要你把需要的上下文放進 messages 裡。
典型流程會像這樣:
messages = [
{
"role": "developer",
"content": "請使用繁體中文回答,並保持回答簡潔。"
}
]
# 第一輪使用者輸入
messages.append({
"role": "user",
"content": "什麼是 Chat Completions API?"
})
completion = client.chat.completions.create(
model="gpt-5.5",
messages=messages,
)
assistant_message = completion.choices[0].message
# 把 assistant 回覆存回 messages
messages.append({
"role": "assistant",
"content": assistant_message.content
})
# 第二輪使用者輸入
messages.append({
"role": "user",
"content": "那它和 Responses API 有什麼不同?"
})
completion = client.chat.completions.create(
model="gpt-5.5",
messages=messages,
)
這也是很多人剛開始串接 API 時容易誤解的地方:模型不是靠 API 自動記憶對話,而是靠你每次把必要的對話歷史重新傳給它。
D.6 tool message:工具執行結果
當你使用 Tool Calling 時,模型可能不會直接回答使用者,而是先要求呼叫某個工具。
例如你提供了一個 get_weather 工具,使用者問:
台北今天會下雨嗎?
模型可能會回傳一個 assistant message,其中包含 tool_calls,表示它想呼叫某個工具來取得天氣資料。
簡化後可能像這樣:
{
"role": "assistant",
"content": null,
"tool_calls": [
{
"id": "call_abc123",
"type": "function",
"function": {
"name": "get_weather",
"arguments": "{\"city\":\"Taipei\"}"
}
}
]
}
這時候你的程式要做三件事:
- 讀取模型要求呼叫的工具名稱與參數。
- 在你的後端實際執行這個工具。
- 把工具執行結果用 tool message 回傳給模型。
tool message 會像這樣:
{
"role": "tool",
"tool_call_id": "call_abc123",
"content": "{\"city\":\"Taipei\",\"forecast\":\"今天下午有短暫陣雨機率。\"}"
}
其中 tool_call_id 必須對應到前面 assistant message 裡的 tool call id,讓模型知道這是哪一次工具呼叫的結果。
接著你再把更新後的 messages 傳回 API,讓模型根據工具結果產生最後回答。
完整概念大致是:
[
{
"role": "developer",
"content": "你是天氣助理,請根據工具結果回答。"
},
{
"role": "user",
"content": "台北今天會下雨嗎?"
},
{
"role": "assistant",
"content": null,
"tool_calls": [
{
"id": "call_abc123",
"type": "function",
"function": {
"name": "get_weather",
"arguments": "{\"city\":\"Taipei\"}"
}
}
]
},
{
"role": "tool",
"tool_call_id": "call_abc123",
"content": "{\"city\":\"Taipei\",\"forecast\":\"今天下午有短暫陣雨機率。\"}"
}
]
模型看到 tool message 後,才會根據工具回傳的資料整理成自然語言回答。
Tool Calling 的細節會在後面的 tools、tool_choice 與 parallel_tool_calls 段落再完整說明。這裡只需要先理解:tool message 不是使用者輸入,也不是模型一般回答,而是你的程式把外部工具執行結果回填給模型的訊息。
D.7 function message:legacy 用法
早期 Chat Completions API 使用 functions、function_call 和 function role 來處理函式呼叫。後來這套用法被 tools、tool_choice 和 tool role 取代。OpenAI API 社群與相關文件長期都將 functions 視為 deprecated,新的工具呼叫流程應優先使用 tools。(OpenAI Developer Community)
你可能會在舊範例中看到這種 message:
{
"role": "function",
"name": "get_weather",
"content": "{\"city\":\"Taipei\",\"forecast\":\"今天下午有短暫陣雨機率。\"}"
}
如果你是在維護舊專案,可能仍然需要理解這種寫法。但如果你正在寫新文章或新程式,建議把它放在 legacy 段落即可,不要把它當成主要推薦用法。
簡單來說:
| 舊用法 | 新用法 |
|---|---|
| functions | tools |
| function_call | tool_choice |
| function role | tool role |
| function result | tool message with tool_call_id |
D.8 content:訊息內容不一定只有字串
在最簡單的範例中,content 通常是一段字串:
{
"role": "user",
"content": "請用一句話解釋 Chat Completions API。"
}
但在較新的模型與多模態情境中,content 也可以是 content parts,也就是由多個內容片段組成的陣列。
例如,純文字 content part 可以寫成:
{
"role": "user",
"content": [
{
"type": "text",
"text": "請描述這張圖片。"
}
]
}
如果模型支援圖片輸入,也可能會搭配 image content part。實際可用的 content part 類型會依照模型與 API 文件而有所不同,所以在實作多模態輸入時,應該以你使用的模型支援範圍為準。
在這篇文章中,前面的最小範例先使用字串形式,因為它最容易理解,也足以涵蓋純文字聊天的基本用法。後面的多模態段落再另外整理 content parts 的寫法。
D.9 多輪對話需要自己管理上下文
最後要特別強調一點:Chat Completions API 本身不會替你保存對話狀態。
每次呼叫 API 時,模型只會看到你這次傳入的 messages。如果你希望模型記得前幾輪對話,就必須由你的應用程式保存歷史訊息,並在下一次請求時重新送出必要上下文。
例如:
conversation = [
{
"role": "developer",
"content": "請使用繁體中文回答,並保持簡潔。"
}
]
def ask(user_input: str) -> str:
conversation.append({
"role": "user",
"content": user_input
})
completion = client.chat.completions.create(
model="gpt-5.5",
messages=conversation,
)
answer = completion.choices[0].message.content
conversation.append({
"role": "assistant",
"content": answer
})
return answer
這段程式會把每次使用者輸入與模型回答都存進 conversation,下一次呼叫 API 時再一起送出。這樣模型才有辦法根據前文回答。
不過在實務產品中,不建議無限制地把所有歷史對話都塞進 messages。原因有三個:
- token 會變多,成本會上升。
- context 太長,延遲會增加。
- 過舊或不重要的訊息可能干擾模型回答。
常見做法是只保留最近幾輪對話,或將較早的對話摘要成一段 summary,再放回 messages 中。這樣可以在上下文完整性、成本與延遲之間取得平衡。
D.10 messages 小結
整理一下,messages 是 Chat Completions API 的核心,因為它決定模型看見什麼上下文。
常見 role 可以這樣理解:
| role | 用途 |
|---|---|
| developer | 應用程式層級的規則與指令,新範例建議優先使用 |
| system | 舊範例常見的高層級指令,部分相容情境仍會看到 |
| user | 使用者輸入 |
| assistant | 模型產生的回答,或包含 tool calls 的訊息 |
| tool | 外部工具執行後回填給模型的結果 |
| function | legacy 工具呼叫結果,不建議新專案優先使用 |
理解 messages 之後,後面介紹其他參數會更容易。因為無論是 temperature、response_format、tools、stream 還是 metadata,本質上都是在控制模型如何根據這組 messages 產生回覆。
E. 基本必要參數
在 Chat Completions API 裡,最基本、最核心的請求參數是:
- model
- messages
如果只想發出一個最小可用請求,通常只需要先理解這兩個參數。
前面已經看過一個最小範例:
from openai import OpenAI
client = OpenAI()
completion = client.chat.completions.create(
model="gpt-5.5",
messages=[
{
"role": "user",
"content": "請用一句話解釋 Chat Completions API 是什麼。"
}
],
)
print(completion.choices[0].message.content)
在這段程式中,model 決定這次要使用哪一個模型,messages 則決定模型這次要根據什麼上下文產生回答。
可以先把它們理解成:
| 參數 | 作用 |
|---|---|
| model | 決定使用哪一個模型來產生回覆 |
| messages | 決定模型看見哪些對話內容與指令 |
其他參數,例如 temperature、response_format、tools、stream、metadata,都是在這個基礎上進一步控制模型行為或回傳方式。
E.1 model:指定要使用的模型
model 用來指定這次請求要使用哪一個模型。
例如:
completion = client.chat.completions.create(
model="gpt-5.5",
messages=[
{
"role": "user",
"content": "請介紹 Chat Completions API。"
}
],
)
這裡的:
model="gpt-5.5"
表示這次請求會交給 gpt-5.5 這個模型處理。
不同模型通常會在以下面向有所差異:
- 推理能力
- 回答品質
- 速度
- 價格
- context window 大小
- 是否支援多模態輸入
- 是否支援音訊輸出
- 是否支援特定工具或進階功能
因此,選擇 model 不只是選一個名稱,而是在品質、速度、成本與功能之間做取捨。
如果你正在做一般聊天機器人,可能會優先考慮成本與速度;如果你正在做複雜推理、程式碼分析、長文件理解,則可能需要選擇能力更強、context window 更大的模型。
實務上,我通常會用這個方式思考:
| 使用情境 | 選型考量 |
|---|---|
| 一般客服或 FAQ | 成本、速度、穩定性 |
| 技術問答或程式碼分析 | 推理能力、程式碼能力、上下文長度 |
| 長文件摘要 | context window、摘要品質 |
| 結構化資料抽取 | JSON / structured output 穩定性 |
| Tool Calling Agent | 工具呼叫能力、參數生成穩定性 |
| 即時聊天 UI | 延遲、串流體驗、成本 |
文章範例中可以使用當前官方文件或官方 Quickstart 常見的模型名稱,但實務專案中,建議你仍然要依照最新的 Models 文件、價格表與專案需求來選擇模型。模型名稱、價格與支援能力會隨時間更新,因此文章中的模型名稱應該視為範例,而不是永遠固定的建議。
E.2 不要把 model 寫死在太多地方
在正式專案中,不建議把模型名稱散落在很多支程式裡。
例如不太建議這樣:
completion = client.chat.completions.create(
model="gpt-5.5",
messages=messages,
)
然後在另一個檔案又寫一次:
completion = client.chat.completions.create(
model="gpt-5.5",
messages=messages,
)
這樣做的問題是,未來如果要更換模型,需要到處搜尋與修改,容易漏掉。
比較好的方式是把模型名稱集中管理,例如:
CHAT_MODEL = "gpt-5.5"
completion = client.chat.completions.create(
model=CHAT_MODEL,
messages=messages,
)
或放在環境變數中:
export OPENAI_CHAT_MODEL="gpt-5.5"
Python 端再讀取:
import os
from openai import OpenAI
client = OpenAI()
CHAT_MODEL = os.getenv("OPENAI_CHAT_MODEL", "gpt-5.5")
completion = client.chat.completions.create(
model=CHAT_MODEL,
messages=[
{
"role": "user",
"content": "請用一句話解釋 Chat Completions API。"
}
],
)
這樣做有幾個好處:
- 開發環境與正式環境可以使用不同模型。
- A/B testing 時比較容易切換模型。
- 未來模型升級時,不需要大規模修改程式碼。
- 成本控管會更容易。
如果你的產品有多種 AI 功能,也可以針對不同任務設定不同模型:
CHAT_MODEL = os.getenv("OPENAI_CHAT_MODEL", "gpt-5.5")
SUMMARY_MODEL = os.getenv("OPENAI_SUMMARY_MODEL", "gpt-5.5")
EXTRACTION_MODEL = os.getenv("OPENAI_EXTRACTION_MODEL", "gpt-5.5")
這樣就可以讓聊天、摘要、資料抽取等功能各自調整模型,而不是全部綁在同一個設定上。
E.3 messages:指定模型看到的對話內容
messages 是一組對話訊息,用來告訴模型目前的上下文。
最簡單的 messages 只有一則 user message:
messages=[
{
"role": "user",
"content": "請用一句話解釋 Chat Completions API 是什麼。"
}
]
這代表使用者問了一個問題,模型要根據這則訊息產生下一則 assistant 回覆。
如果要加入應用程式層級的規則,可以加入 developer message:
messages=[
{
"role": "developer",
"content": "你是一位熟悉 Python 與 API 設計的技術寫作者,請使用繁體中文回答。"
},
{
"role": "user",
"content": "請用一句話解釋 Chat Completions API 是什麼。"
}
]
這裡的 developer message 會先告訴模型應該遵守什麼規則,接著 user message 才是使用者真正提出的問題。
前一段已經詳細介紹過 messages 的各種 role,這裡只需要記住一個重點:
messages 決定模型看見什麼;模型只能根據你這次傳入的 messages 產生回答。
也就是說,如果你沒有把某段上下文放進 messages,模型就不會在這次請求中看到它。
E.4 messages 通常由你的應用程式動態組出來
在實務產品中,messages 通常不是手寫死的,而是由你的應用程式根據使用者輸入、歷史對話、產品規則與外部資料組出來。
例如一個簡單的聊天功能可能會這樣寫:
from openai import OpenAI
client = OpenAI()
def ask(user_input: str) -> str:
messages = [
{
"role": "developer",
"content": "你是一位客服助理,請使用繁體中文回答,並保持簡潔。"
},
{
"role": "user",
"content": user_input
}
]
completion = client.chat.completions.create(
model="gpt-5.5",
messages=messages,
)
return completion.choices[0].message.content
這個版本每次請求都會建立一組新的 messages,其中:
- developer message 是固定的產品規則。
- user message 是這次使用者輸入的內容。
如果要支援多輪對話,就需要把歷史對話也放進 messages:
conversation = [
{
"role": "developer",
"content": "你是一位客服助理,請使用繁體中文回答,並保持簡潔。"
}
]
def ask(user_input: str) -> str:
conversation.append({
"role": "user",
"content": user_input
})
completion = client.chat.completions.create(
model="gpt-5.5",
messages=conversation,
)
answer = completion.choices[0].message.content
conversation.append({
"role": "assistant",
"content": answer
})
return answer
這樣下一次呼叫 API 時,模型才會看到前幾輪對話。
不過,這個範例只是為了說明概念。在正式產品中,通常還需要考慮:
- 對話歷史要存在哪裡。
- 要保留最近幾輪對話。
- 是否要摘要舊對話。
- 是否要過濾敏感資訊。
- 是否要限制 token 數量。
- 是否要分使用者、分 session 管理對話。
E.5 model 與 messages 的關係
model 和 messages 是 Chat Completions API 裡最核心的兩個參數,但它們控制的是不同層面。
可以這樣理解:
| 參數 | 控制層面 | 問題 |
|---|---|---|
| model | 模型能力 | 要讓哪個模型回答? |
| messages | 上下文內容 | 要讓模型根據什麼回答? |
同樣的 messages,換不同模型,可能會得到不同品質、不同速度、不同成本的結果。
同樣的 model,換不同 messages,也會產生完全不同的回答。
例如:
completion = client.chat.completions.create(
model="gpt-5.5",
messages=[
{
"role": "user",
"content": "請介紹 Python。"
}
],
)
和:
completion = client.chat.completions.create(
model="gpt-5.5",
messages=[
{
"role": "developer",
"content": "請用適合初學者的方式回答,並使用繁體中文。"
},
{
"role": "user",
"content": "請介紹 Python。"
}
],
)
雖然使用的是同一個模型,但第二個請求加入了 developer message,因此模型會更清楚知道回答語言與目標讀者。
再例如:
completion = client.chat.completions.create(
model="gpt-5.5",
messages=[
{
"role": "developer",
"content": "請用資深後端工程師的角度回答。"
},
{
"role": "user",
"content": "請介紹 Python。"
}
],
)
這次模型會更偏向從工程實務、語言特性、後端開發場景來介紹 Python。
所以在設計 AI 應用時,不要只關心「要用哪個模型」,也要同時設計「要給模型什麼 messages」。
E.6 基本必要參數小結
整理一下,Chat Completions API 最基本的請求,就是指定 model 與 messages。
最小形式如下:
completion = client.chat.completions.create(
model="gpt-5.5",
messages=[
{
"role": "user",
"content": "請用一句話解釋 Chat Completions API。"
}
],
)
如果要讓模型更符合你的應用需求,通常會加入 developer message:
completion = client.chat.completions.create(
model="gpt-5.5",
messages=[
{
"role": "developer",
"content": "請使用繁體中文回答,並保持簡潔。"
},
{
"role": "user",
"content": "請用一句話解釋 Chat Completions API。"
}
],
)
在實務上:
- model 決定模型能力、成本、速度與功能支援。
- messages 決定模型看到的上下文、規則與使用者輸入。
- 多輪對話需要由你的應用程式自行保存並重新傳入 messages。
- 模型名稱建議集中管理,不要散落在程式各處。
- 文章範例中的模型名稱只是示範,正式專案應依照最新模型文件與產品需求選擇。
理解 model 與 messages 之後,接下來就可以進一步看控制生成結果的參數,例如 temperature、top_p、max_completion_tokens、presence_penalty 與 frequency_penalty。
F. 控制生成結果的參數
前面介紹的 model 和 messages,決定了「讓哪個模型根據什麼上下文回答」。
接下來這一組參數,則是用來控制模型「怎麼生成回答」。
常見的生成控制參數包括:
- temperature
- top_p
- n
- stop
- max_completion_tokens
- presence_penalty
- frequency_penalty
- logit_bias
這些參數會影響模型輸出的隨機程度、長度、重複程度、停止條件,以及特定 token 出現的機率。
不過要先提醒一點:不是每個模型都支援完全相同的參數。有些最新 reasoning models 可能不支援部分傳統生成控制參數,或只支援預設值。因此實務上應該以你實際使用的模型文件為準。這篇文章會先從 Chat Completions API 的一般參數角度說明它們的用途。
F.1 temperature:控制輸出的隨機程度
temperature 用來控制模型輸出的隨機程度。
型別:
number or null
範圍:
0 到 2
一般來說:
- temperature 越低,輸出越穩定、越集中、越可預期。
- temperature 越高,輸出越發散、越有變化、越有創意。
例如:
completion = client.chat.completions.create(
model="gpt-5.5",
messages=[
{
"role": "user",
"content": "幫我想 5 個旅遊分帳 App 的標語。"
}
],
temperature=0.9,
)
如果你正在做創意型任務,例如文案、命名、標語、腦力激盪,可以使用較高的 temperature,讓模型產生更多變化。
如果你正在做比較要求穩定的任務,例如客服回答、資料整理、格式化輸出,則可以使用較低的 temperature。
常見設定可以這樣理解:
| 使用情境 | 建議 temperature |
|---|---|
| 結構化資料抽取 | 0 到 0.3 |
| 客服、FAQ、技術說明 | 0.2 到 0.7 |
| 一般聊天 | 0.7 到 1 |
| 創意寫作、命名、標語 | 0.8 到 1.2 |
範例:穩定回答
completion = client.chat.completions.create(
model="gpt-5.5",
messages=[
{
"role": "developer",
"content": "請用簡潔、穩定、可預期的方式回答。"
},
{
"role": "user",
"content": "請解釋什麼是 API rate limit。"
}
],
temperature=0.2,
)
範例:創意發想
completion = client.chat.completions.create(
model="gpt-5.5",
messages=[
{
"role": "user",
"content": "請幫 TallyTrip 想 10 個產品標語。"
}
],
temperature=1.0,
)
實務建議:
如果你不知道該怎麼設定,通常可以先使用預設值,等真的遇到「回答太死板」或「回答太發散」時再調整。
F.2 top_p:用 nucleus sampling 控制候選 token 範圍
top_p 是另一種控制隨機性的方式,也稱為 nucleus sampling。
型別:
number or null
範圍:
0 到 1
它的概念是:模型在產生下一個 token 時,不一定要考慮所有可能 token,而是只考慮累積機率達到 top_p 的那一群候選 token。
例如:
completion = client.chat.completions.create(
model="gpt-5.5",
messages=[
{
"role": "user",
"content": "請幫我寫一段產品介紹。"
}
],
top_p=0.9,
)
如果 top_p=0.1,代表模型只會從機率最高、累積機率約前 10% 的 token 中取樣,因此輸出會更保守。
如果 top_p 接近 1,代表模型會考慮更多候選 token,輸出會更有變化。
可以這樣理解:
| top_p | 效果 |
|---|---|
| 接近 0 | 非常保守,只考慮最高機率候選 |
| 0.5 | 較集中 |
| 0.9 | 較自然、有變化 |
| 1 | 預設範圍,候選 token 最完整 |
官方通常建議:temperature 和 top_p 擇一調整即可,不建議同時大幅調整兩者。
原因是這兩個參數都會影響隨機性。如果你同時調整,很難判斷輸出變化到底是由哪個參數造成。
實務建議:
- 一般情況:優先調整 temperature。
- 需要更精細控制候選 token 範圍時:再考慮調整 top_p。
- 不熟悉時:保留 top_p 預設值。
F.3 n:一次產生幾個候選回答
n 用來指定每個輸入要產生幾個 chat completion choices。
型別:
number or null
範圍:
最小 1
例如:
completion = client.chat.completions.create(
model="gpt-5.5",
messages=[
{
"role": "user",
"content": "幫我想 3 個部落格文章標題。"
}
],
n=3,
)
這樣 API 會回傳 3 個候選結果,你可以用:
for choice in completion.choices:
print(choice.message.content)
逐一讀取。
不過實務上,n 要小心使用。因為產生多個 choices 時,費用會依照所有產生的 tokens 計算,而不是只算你最後選用的那一個。
例如 n=3,代表模型會產生 3 份回答,生成 token 數量與成本通常也會跟著增加。
實務建議:
- 一般聊天 UI:保持 n=1。
- 需要產生多個候選文案:可以考慮 n=3 或更多。
- 想控制成本:盡量維持 n=1。
- 如果只是想要多個點子,也可以讓模型在單一回答裡列出多個選項,而不是使用 n。
例如比起這樣:
completion = client.chat.completions.create(
model="gpt-5.5",
messages=messages,
n=5,
)
很多時候可以改成:
completion = client.chat.completions.create(
model="gpt-5.5",
messages=[
{
"role": "user",
"content": "請幫我列出 5 個候選標題。"
}
],
)
這樣通常更容易控制成本,也更容易處理回傳結果。
F.4 stop:指定停止生成的字串
stop 用來指定模型遇到某些字串時停止生成。
型別:
string、array of strings 或 null
最多可以設定 4 組 stop sequences。
例如:
completion = client.chat.completions.create(
model="gpt-5.5",
messages=[
{
"role": "user",
"content": "請輸出一段簡短說明,結尾遇到 END 就停止。"
}
],
stop=["END"],
)
當模型生成內容時,如果遇到 END,就會停止繼續生成,而且回傳內容通常不會包含這個 stop sequence。
stop 常見用途包括:
- 限制模型不要繼續輸出後續段落。
- 處理自訂格式的分隔符。
- 避免模型生成下一個不該出現的區塊。
- 模擬舊式 prompt completion 的停止條件。
例如你希望模型只輸出第一段,不要繼續產生下一個角色對話,可以設定:
completion = client.chat.completions.create(
model="gpt-5.5",
messages=[
{
"role": "user",
"content": "請產生客服回覆,遇到「使用者:」就停止。"
}
],
stop=["使用者:"],
)
不過在 Chat Completions API 裡,很多時候你不一定需要 stop。因為 messages 本身已經用角色結構區分了 user、assistant、tool 等訊息,不像傳統 completion API 那樣需要大量依賴停止字串來切斷輸出。
另外要注意:部分最新 reasoning models 不支援 stop,所以如果你使用的是這類模型,應該先確認模型是否支援。
實務建議:
- 一般聊天:通常不需要設定 stop。
- 自訂文字格式:可以使用 stop。
- 結構化輸出:優先考慮 response_format 或 JSON Schema,而不是依賴 stop。
- 使用 reasoning models:先確認是否支援 stop。
F.5 max_completion_tokens:限制模型最多生成多少 token
max_completion_tokens 用來設定模型最多可以產生多少 completion tokens。
型別:
number or null
它是生成長度與成本控制中很重要的參數。
例如:
completion = client.chat.completions.create(
model="gpt-5.5",
messages=[
{
"role": "user",
"content": "請用 300 字介紹 Chat Completions API。"
}
],
max_completion_tokens=500,
)
這裡的 max_completion_tokens=500,表示模型最多可以產生 500 個 completion tokens。
要注意的是,max_completion_tokens 是 token 數,不是中文字數、英文字數或句數。Token 可以粗略理解成模型處理文字的基本單位,但它不等於一個字,也不等於一個單詞。
另外,對於支援 reasoning tokens 的模型,max_completion_tokens 的上限也可能包含 visible output tokens 和 reasoning tokens。也就是說,你設定的上限不一定全部都會變成使用者看得到的文字。
舊版參數 max_tokens 現在已經不建議新專案使用,應優先改用 max_completion_tokens。
實務建議:
- 一般短回答:可以設定 200 到 500。
- 長摘要或文章草稿:可以設定更高。
- 結構化資料抽取:設定足夠容納 JSON 的長度。
- 成本敏感功能:務必設定合理上限。
- 新專案:使用 max_completion_tokens,不要再優先使用 max_tokens。
範例:限制客服回答不要太長
completion = client.chat.completions.create(
model="gpt-5.5",
messages=[
{
"role": "developer",
"content": "你是客服助理,請用簡潔方式回答。"
},
{
"role": "user",
"content": "請問我可以如何重設密碼?"
}
],
max_completion_tokens=200,
)
範例:讓模型產生較完整的文章段落
completion = client.chat.completions.create(
model="gpt-5.5",
messages=[
{
"role": "user",
"content": "請寫一段 500 字左右的文章前言,主題是旅遊分帳工具。"
}
],
max_completion_tokens=900,
)
F.6 presence_penalty:降低已出現主題再次出現的機率
presence_penalty 用來根據某個 token 是否已經出現在目前生成內容中,調整模型再次使用它的機率。
型別:
number or null
範圍:
-2.0 到 2.0
正值會讓模型比較傾向談到新的主題或新的詞彙;負值則會讓模型比較不排斥回到已經出現過的內容。
可以簡單理解成:
presence_penalty 比較像是在問:「這個 token 有沒有出現過?」
例如:
completion = client.chat.completions.create(
model="gpt-5.5",
messages=[
{
"role": "user",
"content": "請幫我列出 10 個旅遊 App 的功能點子。"
}
],
presence_penalty=0.6,
)
這樣模型比較可能避免一直圍繞同一個功能打轉,而是提出較多不同方向的點子。
常見用途:
- 腦力激盪。
- 產生多樣化候選項目。
- 避免回答一直繞著同一個主題。
- 鼓勵模型探索新的面向。
實務建議:
| 使用情境 | presence_penalty |
|---|---|
| 穩定問答 | 0 |
| 一般創意發想 | 0.3 到 0.8 |
| 強烈鼓勵多樣性 | 0.8 以上 |
| 希望模型維持同一主題 | 不建議調高 |
不要把 presence_penalty 當成「防止重複字句」的唯一工具。它主要影響的是模型是否傾向引入新主題,而不是單純處理同一句話重複很多次。
F.7 frequency_penalty:降低重複用詞的機率
frequency_penalty 用來根據某個 token 已經出現的頻率,調整模型再次使用它的機率。
型別:
number or null
範圍:
-2.0 到 2.0
正值會降低模型重複使用相同 token 的機率,尤其是已經出現多次的 token。
可以簡單理解成:
frequency_penalty 比較像是在問:「這個 token 已經出現幾次了?」
例如:
completion = client.chat.completions.create(
model="gpt-5.5",
messages=[
{
"role": "user",
"content": "請寫一段產品介紹,不要一直重複產品名稱。"
}
],
frequency_penalty=0.5,
)
這樣可以降低模型在回答中反覆使用同一個詞或同一句話的機率。
presence_penalty 和 frequency_penalty 的差異可以這樣理解:
| 參數 | 判斷方式 | 主要效果 |
|---|---|---|
| presence_penalty | 是否出現過 | 鼓勵談新主題 |
| frequency_penalty | 出現幾次 | 降低重複用詞 |
實務建議:
| 使用情境 | frequency_penalty |
|---|---|
| 一般聊天 | 0 |
| 文章寫作 | 0.2 到 0.6 |
| 避免重複口號或產品名 | 0.4 到 0.8 |
| 需要保留固定術語 | 不宜設太高 |
如果你的輸出需要反覆使用同一個專有名詞,例如產品名稱、API 名稱、欄位名稱,就不要把 frequency_penalty 設得太高。否則模型可能會為了避免重複而改用不精確的代稱,反而讓文章變得不清楚。
F.8 logit_bias:調整特定 token 出現機率
logit_bias 是比較進階的生成控制參數。
它可以針對特定 token ID 調整出現機率。值的範圍通常是:
-100 到 100
概念上:
- 正值:提高該 token 出現機率。
- 負值:降低該 token 出現機率。
- 接近 -100:幾乎禁止該 token。
- 接近 100:強烈鼓勵該 token。
範例形式大致會像這樣:
completion = client.chat.completions.create(
model="gpt-5.5",
messages=[
{
"role": "user",
"content": "請輸出 yes 或 no。"
}
],
logit_bias={
"1234": 5,
"5678": -5
},
)
這裡的 “1234” 和 “5678” 是 token ID,不是普通字串。
這也是 logit_bias 比較不好使用的地方:你必須先知道目標文字對應到哪些 token ID,而且同一個文字在不同 tokenizer、不同前後空白或不同語言環境下,可能會被切成不同 token。
常見用途:
- 降低某些詞出現機率。
- 強化特定答案選項。
- 避免模型輸出某些格式字元。
- 做非常細緻的輸出控制。
不過在大多數產品情境中,logit_bias 不是第一優先選項。
如果你只是想讓模型不要提到某些內容,通常可以先用:
- developer message 明確規範。
- response_format 限制輸出格式。
- 後處理過濾輸出。
- 安全與合規檢查。
只有在你真的需要 token 層級控制時,再考慮使用 logit_bias。
實務建議:
- 一般聊天機器人:通常不用。
- 結構化分類任務:可以考慮,但要小心 token ID。
- 嚴格禁止特定 token:可以使用負 bias,但仍不應把它當成唯一安全機制。
- 不熟悉 tokenizer 時:先不要用。
F.9 生成控制參數的實務組合
實務上,我通常不會一次調整所有生成控制參數,而是根據任務類型選擇少數幾個。
一般客服或 FAQ
completion = client.chat.completions.create(
model="gpt-5.5",
messages=messages,
temperature=0.3,
max_completion_tokens=300,
)
特點:
- 回答要穩定。
- 不需要太多創意。
- 長度要可控。
創意文案或標語發想
completion = client.chat.completions.create(
model="gpt-5.5",
messages=messages,
temperature=1.0,
presence_penalty=0.5,
max_completion_tokens=800,
)
特點:
- 允許比較多變化。
- 鼓勵不同方向。
- 適合產生多個候選點子。
結構化資料抽取
completion = client.chat.completions.create(
model="gpt-5.5",
messages=messages,
temperature=0,
max_completion_tokens=1000,
)
特點:
- 要求穩定。
- 不需要創意。
- 通常會搭配 response_format 或 JSON Schema。
長文摘要
completion = client.chat.completions.create(
model="gpt-5.5",
messages=messages,
temperature=0.4,
max_completion_tokens=1200,
)
特點:
- 需要一定自然度。
- 但不能太發散。
- 需要設定足夠的輸出上限。
F.10 生成控制參數小結
整理一下:
| 參數 | 用途 | 常見建議 |
|---|---|---|
| temperature | 控制隨機程度 | 一般優先調這個 |
| top_p | 控制候選 token 範圍 | 通常不要和 temperature 同時大幅調整 |
| n | 產生多個候選回答 | 成本會增加,預設保持 1 |
| stop | 遇到指定字串停止生成 | 一般聊天少用,格式控制可用 |
| max_completion_tokens | 限制最多生成 token 數 | 控制成本與長度的重要參數 |
| presence_penalty | 鼓勵模型談新主題 | 適合點子發想 |
| frequency_penalty | 降低重複用詞 | 適合文章寫作或避免重複 |
| logit_bias | 調整特定 token 機率 | 進階用法,一般產品少用 |
如果你是第一次設計 Chat Completions API 請求,我建議先從這三個參數開始:
completion = client.chat.completions.create(
model="gpt-5.5",
messages=messages,
temperature=0.7,
max_completion_tokens=500,
)
也就是:
- 先選好 model
- 組好 messages
- 設定合理的 temperature
- 設定合理的 max_completion_tokens
等產品需求更明確後,再逐步調整 top_p、presence_penalty、frequency_penalty 或其他進階參數。
接下來,我們會介紹控制輸出格式的參數,也就是 response_format。這會影響模型回傳的是一般文字、JSON object,還是符合 JSON Schema 的結構化資料。
結語:先理解基礎參數,再進入產品級功能
到這裡,我們已經把 Chat Completions API 的基礎結構整理完了。
這一篇主要聚焦在幾個最核心的概念:
- model 決定要使用哪一個模型。
- messages 決定模型看見哪些對話內容與指令。
- developer、user、assistant、tool 等 role 讓對話結構更清楚。
- temperature、top_p、max_completion_tokens 等參數則用來控制生成結果的穩定性、發散程度與輸出長度。
如果只是要建立一個基本的 AI 對話功能,理解這些參數就已經足夠開始實作。你可以從最小可用範例出發,逐步加入 developer message、多輪對話記錄,以及適合任務的生成控制參數。
不過,當你想把 Chat Completions API 做成更完整的產品時,通常還會遇到更多需求:
- 讓模型輸出可以被程式穩定解析的 JSON。
- 使用 JSON Schema 限制模型回傳格式。
- 讓模型在需要時呼叫後端工具或內部 API。
- 讓聊天 UI 像 ChatGPT 一樣即時串流顯示文字。
- 處理圖片、音訊或檔案等多模態輸入。
這些就不是單純調整 temperature 或 messages 就能完成的事情,而會用到 response_format、tools、tool_choice、stream、content parts 等更進階的參數。
下一篇會接著介紹:
打造專屬 ChatGPT(二):結構化輸出、Tool Calling 與 Streaming
我們會從 response_format 開始,看如何讓模型輸出 JSON 或符合 JSON Schema 的結構化資料;接著介紹 Tool Calling,讓模型可以決定何時呼叫你的後端函式;最後再整理 Streaming 串流回應,讓聊天介面可以即時顯示模型輸出。
第一篇是在建立 Chat Completions API 的基礎心智模型,第二篇就會進一步把它推向更接近正式產品的使用方式。