在前幾篇文章中,我們已經學會如何呼叫 OpenAI API,並透過提示工程來控制回應的角色與風格。不過在實際應用中,不同情境往往需要截然不同的回答方式:有時候我們希望模型輸出嚴謹且結構明確的內容,有時候則希望它能展現更多創意,提供多樣化的想法。
這樣的差異並不是僅靠提示詞就能完全掌控,而是與生成機率的取樣策略息息相關。在 OpenAI API 中,負責調整這部分的核心參數主要有兩個:temperature
與 top_p
。今天我們就要深入解析這兩個設定,並透過程式實驗觀察它們對模型輸出的實際影響。
要理解怎麼控制回應風格,可以先用一個簡單的比喻來認識語言模型的運作方式:大語言模型其實就像是在玩「文字接龍」遊戲。
它的核心原理是這樣的:模型會根據你給的輸入文字,去計算「下一個最合理的詞」應該是什麼,然後把這個詞接上去。接著,它再用更新後的內容繼續計算下一個詞,並不斷重複這個動作,最後就組合出一整段文字。
舉個例子,如果你輸入:
JavaScript 是一種用來開發
模型可能會評估接下來最合理的詞是「網頁」、「前端」、「應用程式」等等,並依照機率大小來決定要選哪一個。假設它選了「網頁」,那接下來的輸入就變成:
JavaScript 是一種用來開發網頁
接著它再繼續判斷下一個詞可能是「應用程式」、「互動效果」或「前端功能」,然後選出其中一個。如此循環,直到模型認為回答完成為止。
這個過程看起來好像模型真的「理解」了你在說什麼,但事實上它並不具備真正的語意理解能力,而是根據訓練時學到的龐大語言統計資料,去預測在這樣的語境中,什麼詞最可能出現。
語言模型的運作雖然像「文字接龍」,每次都在預測下一個最合理的詞,但這並不代表它每次都必須挑選機率最高的那個詞。
如果模型永遠都挑機率最高的詞,那麼輸出的內容會非常穩定、安全,幾乎每次都能得到一樣的答案。這樣的特性在需要精準回覆時非常有用。但缺點是,回答容易變得制式、重複,缺乏新鮮感。
相反地,如果允許模型偶爾選擇一些機率不是最高,但仍合理的詞,那麼輸出就會更有變化,有時甚至會帶來意料之外的創意火花。不過這樣也伴隨風險,可能回答更容易出錯、跑題,甚至產生無意義的片段。
這就是為什麼我們需要能夠控制「隨機性」。它其實就是在穩定性與創造力之間拉一條平衡線。不同的應用場景,需要不同的設定,才能讓模型輸出符合我們的期待。
既然隨機性會影響回答的風格,我們就需要一個方法來控制它,讓模型能在穩定性和創造力之間找到合適的平衡點。
OpenAI API 提供了兩個關鍵參數:
temperature
:決定模型在選詞時的「自由度」。數值低時,模型傾向選擇最保險的答案,輸出穩定一致;數值高時,它會更大膽嘗試,內容可能更有創意,也更難以預測。top_p
:限制模型只從「前幾個最有可能的選項」中挑字。數值小時,模型幾乎只會從常見答案中挑選;數值大時,它能探索更廣的可能性。接下來我們會分別看看這兩個參數的作用,並透過程式範例觀察它們如何改變模型的回應風格。
temperature
:控制模型的創造力OpenAI 的 temperature 是最常用來調整回應創造力與多樣性的參數。它會影響模型在「預測下一個詞」時,究竟要保守選擇最安全的答案,還是大膽嘗試一些機率較低的選項。
數值範圍通常落在 0 ~ 2
,而在 OpenAI API 裡,預設值是 1
。
temperature = 0
:完全保守。模型只會挑選最有把握的詞,輸出非常穩定,但內容容易重複,看起來比較「制式化」。temperature = 1
:適度隨機。模型會依照機率分布進行抽樣,既能保持合理性,又帶有自然的多樣性。這是最常用的設定。temperature > 1
:高創意模式。模型更傾向冒險,會選擇一些平常不會出現的詞彙,輸出更具想像力,但同時也更容易跑題或產生雜訊。舉個例子,假設我們問模型:
請用一句話介紹 AI 是什麼?
不同 temperature
設定下,模型可能會給出這樣的回答:
temperature = 0
AI 是人工智慧的縮寫,用來模擬人類智能的技術。
temperature = 1
AI 是一種讓電腦能思考、判斷並學習的技術。
temperature = 1.5
AI 是讓機器解鎖想像力、模仿人腦直覺與夢境的未來工具。
可以發現:temperature
越低,回應越嚴謹可控;temperature
越高,回應越多樣奔放,但也更不可預測。
top_p
:限制模型的選詞範圍OpenAI 的 top_p 是另一個用來控制模型隨機性的參數,也被稱為 核心取樣(Nucleus Sampling)。它的作用是:只允許模型從「機率總和達到某個門檻」的候選詞中挑選下一個詞,而不是從所有詞彙中自由選擇。
數值範圍在 0 ~ 1
之間,代表「選詞時允許的累積機率上限」:
top_p = 1
:等於不設限,模型可以從所有詞彙中選擇。top_p = 0.9
:模型只會考慮「累積機率前 90%」的詞,排除掉最不可能的那部分。top_p = 0.1
:只保留極少數的高機率詞,輸出會變得非常保守、缺乏變化。來看一個例子。假設在某個情境下,模型預測下一個詞的機率分布如下:
詞 | 機率 | 累積機率 |
---|---|---|
網頁 | 35% | 35% |
應用程式 | 25% | 60% |
工具 | 15% | 75% |
科技 | 10% | 85% |
宇宙 | 5% | 90% |
其他(合計) | 10% | 100% |
不同的 top_p
設定會影響模型的候選範圍:
top_p = 1
:不限範圍,所有詞都可能被選中。top_p = 0.9
:取到累積機率 ≥ 90% 的最小集合為 {網頁, 應用程式, 工具, 科技, 宇宙}
。top_p = 0.75
:前三個詞剛好湊到 75%,所以只會挑選 {網頁, 應用程式, 工具}
。top_p = 0.5
:前兩個詞(35%+25%=60% ≥ 50%)就已達標,因此只考慮 {網頁, 應用程式}
。由此可見,top_p
的本質是控制「候選答案池的大小」:值越大,範圍越廣,回答更有可能出現意料之外的詞;值越小,輸出則更可控、更安全。
temperature
vs. top_p
:有什麼不同?雖然 temperature
和 top_p
都能影響模型的「隨機性」,但它們調控的角度完全不同:
temperature
:調整的是「整體分布的形狀」。數值低會讓分布變得尖銳,機率最高的詞幾乎必定被選中;數值高則會把分布攤平,讓低機率詞也有機會被挑選。top_p
:限制的是「候選詞的範圍」。它不會改變分布本身,而是劃一條界線,只保留累積機率達到某個比例的詞,其他候選詞一律排除。換句話說,temperature
像是在調整「抽籤池裡的權重分布」,決定熱門選項是不是要壓得很重,還是大家機會差不多。top_p
則像是在決定「抽籤池的大小」,是要只放前幾個熱門選項,還是把冷門選項也丟進去。
項目 | temperature | top_p |
---|---|---|
控制方式 | 改變「每個詞的機率分布形狀」 | 限制「可選詞的總機率範圍」 |
運作邏輯 | 每個詞都可能出現,只是機率高低不同 | 只從總機率最前面的詞彙中選擇 |
使用直覺 | 控制回答的 保守或創新程度 | 控制回答的 可靠性與合理詞彙範圍 |
不同的應用場景,對回應的要求並不相同,因此調整的策略也會有所差異:
需要高度可控、格式固定的回答
適合用在程式碼生成、數學計算或資料轉換這類任務。建議直接將 temperature
設為 0
(或接近 0),確保輸出穩定一致,不會因隨機性造成格式錯誤。
需要多樣但仍合理的回答
適合用在一般對話、客服回覆或內容建議等情境。此時可以透過調整 top_p
(常見範圍 0.7 ~ 0.9),讓回答保持一定的多樣性,同時避免出現過於離譜的內容。
需要創意發散或腦力激盪
適合用在廣告文案、故事生成、腦力激盪這類需要靈感的場合。可以將 temperature
提高到 1.0 ~ 1.2,甚至搭配較大的 top_p
,讓模型更敢冒險,產生新奇但可能不可預測的輸出。
Note:OpenAI 官方建議大部分情況下 只調整其中一個參數 就好。若同時大幅修改
temperature
與top_p
,兩者效果可能互相疊加,導致模型行為過於混亂,難以掌控。
理解了 temperature
和 top_p
的差異之後,我們就能更靈活地根據應用情境調整模型的回答風格。
接下來要做的事,就是在我們之前實作的 CLI Chatbot 上加上這兩個參數,讓使用者在啟動程式時,就能透過命令列選項直接控制模型的「創造力」與「回應範圍」。
我們將使用 yargs 這個 CLI 參數解析套件,新增兩個選項:
--temperature
(或 -t
):控制模型的創造力。--top-p
(或 --tp
):限制模型的選詞範圍。以下是修改後的 src/index.ts
:
// src/index.ts
import 'dotenv/config';
import readline from 'readline';
import yargs, { Arguments } from 'yargs';
import { hideBin } from 'yargs/helpers';
import { OpenAI } from 'openai';
import { roles } from './prompts';
interface Argv {
role: keyof typeof roles;
temperature: number;
top_p: number;
}
const argv = yargs(hideBin(process.argv))
.option('role', {
alias: 'r',
type: 'string',
choices: Object.keys(roles) as (keyof typeof roles)[],
default: 'default',
description: '指定助理角色',
})
.option('temperature', {
alias: 't',
type: 'number',
description: '控制模型的創造力 (0 ~ 2)',
default: 1,
})
.option('top_p', {
alias: 'tp',
type: 'number',
description: '限制模型的選詞範圍 (0 ~ 1)',
default: 1,
})
.help()
.parseSync();
async function main(argv: Arguments<Argv>) {
const openai = new OpenAI();
const messages = [...roles[argv.role]];
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout,
});
console.log('GPT Chatbot 已啟動,輸入訊息開始對話(按 Ctrl+C 離開)。\n');
rl.setPrompt('> ');
rl.prompt();
rl.on('line', async (input) => {
messages.push({ role: 'user', content: input });
try {
const stream = await openai.chat.completions.create({
model: 'gpt-4o-mini',
stream: true,
temperature: argv.temperature,
top_p: argv.top_p,
messages,
});
let reply = '';
process.stdout.write('\n');
for await (const chunk of stream) {
const content = chunk.choices[0]?.delta?.content || '';
process.stdout.write(content);
reply += content;
}
process.stdout.write('\n\n');
messages.push({ role: 'assistant', content: reply });
} catch (err) {
console.error(err);
}
rl.prompt();
});
}
main(argv);
完成修改後,就可以在命令列啟動聊天機器人,並嘗試不同參數組合。
預設參數(temperature = 1
、top_p = 1
):
npm run dev
模型會在穩定與多樣性之間取得平衡。
提高創意(temperature = 1.5
):
npm run dev -- --temperature 1.5
回應更自由、具想像力,但也更容易出現意料之外的答案。
限制選詞範圍(top_p = 0.5
):
npm run dev -- --top-p 0.5
只保留前半數高機率的候選詞,回應更集中、更保守。
透過以上測試,你會發現:同樣的問題,在不同參數下,AI 的回應長度、語氣、選詞甚至結論都可能不同。這種「可調控的隨機性」正是生成式 AI 的特色之一。
今天我們探討了如何透過 temperature
與 top_p
調整 AI 的「隨機性」,進而控制回應的穩定性與創造力:
temperature
:決定選詞的保守或奔放程度,低值輸出嚴謹穩定,高值輸出多樣且具創意。top_p
:限制候選詞的總機率範圍,值越小輸出越保守,值越大回答更有變化。temperature
改變「分布形狀」,top_p
控制「候選池大小」。temperature
,強調創意可拉高 temperature
,而想控制回答的保守程度或多樣性則可調整 top_p
。掌握這兩個設定,可以幫助我們在「可靠答案」與「創意靈感」之間找到合適平衡,讓 AI 更符合不同場景需求。