Learning Objectives
- 用 messages 串列組出一次請求,說明 system、user、assistant 三種角色的用途
- 從回應物件取出文字、結束原因與 token 用量
- 說明模型不記得上一次呼叫,並用程式維護對話記憶
- 說明對話變長時費用與上下文的問題,並裁剪對話紀錄
從聊天視窗到程式
在 ChatGPT 的視窗裡打字,背後是一個網頁程式把你的文字包成請求、送給模型、再把回答顯示出來。自己做 AI 應用時,這個程式由你來寫。
這一課學怎麼寫這段程式。學會之後,你可以把模型接進自己的網站、批次處理一千份文件,或讓它依照你的規則工作。
先說明這一軌的範例怎麼執行:右邊的程式和真實環境寫法相同,但不會真的呼叫模型。 我們事先用 gpt-5.6-luna 執行一次,把真實的回應錄下來(2026-11-03),你看到的回答、token 數都是當時的真實結果。所以你改了提示詞再跑,會看到「沒有預錄的回應」;想試自己寫的提示詞,第 5、9、13、18 課有登入後呼叫真實模型的實驗。
逐步看:第一次呼叫
請注意 messages 是一個普通的 Python 串列,每個元素是字典;還有回應物件裡有哪幾個你會用到的欄位。
三種角色
| 角色 | 誰說的 | 用途 |
|---|---|---|
system |
開發者 | 設定模型的角色、規則與回答格式 |
user |
使用者 | 這次的問題或要處理的資料 |
assistant |
模型 | 模型之前的回答;放進來才能接續對話 |
回應物件裡常用的欄位:
| 欄位 | 內容 |
|---|---|
response.choices[0].message.content |
回答的文字 |
response.choices[0].finish_reason |
為什麼停下來:stop 講完、length 被截斷、tool_calls 要呼叫工具 |
response.usage.prompt_tokens |
輸入用了多少 token |
response.usage.completion_tokens |
輸出用了多少 token |
常用參數: max_completion_tokens 限制輸出長度,temperature 控制隨機程度(第 4 課)。
參數要依模型查文件。例如我們實測 gpt-5.6-luna 時,舊參數 max_tokens 會回傳 400 錯誤,要改用 max_completion_tokens。各家模型支援的參數不同,換模型時要重新確認。
逐步看:模型不記得上一句
連續呼叫兩次:第一次告訴模型名字,第二次問它名字。先猜猜看第二次會回答什麼。
對話記憶是程式做出來的
每次 API 呼叫都是獨立的,模型不會記得你上一次送了什麼。聊天網站看起來有記憶,是因為它每次都把之前的對話一起送過去。
所以「記憶」就是一個串列:使用者說一句就加一筆,模型回一句也加一筆,下次全部送出。
逐步看:自己維護對話紀錄
問題和上一個範例相同。請看 history 怎麼變長,以及輸入的 token 數怎麼變。
對話越長,每一輪越貴
從上面的輸出可以看到,第二輪的輸入 token 比第一輪多。對話越長,每一輪都要重送全部內容,費用不是線性增加;而且模型能接收的長度也有上限(上下文長度,第 2 課)。
常見的處理方式:
- 只留最近幾則: 最簡單,但會忘記較早的內容。
- 摘要舊對話: 請模型把舊內容摘要成一段,放進 system 訊息;要多花一次呼叫,也可能漏掉細節。
- 需要時才檢索: 把舊對話存起來,用到時再找出相關的部分,做法和第 13 課的 RAG 相同。
裁剪時要注意:system 訊息通常要留著,否則模型會忘記規則。
實作:裁剪對話紀錄
完成 trim_history(history, keep):回傳新的串列,保留第一則 system 訊息,再加上最後 keep 則訊息。
這個練習的請求已經錄好:只要裁剪結果正確,就對得上錄音,模型會回應;裁剪錯了會看到「沒有預錄的回應」。
小測驗:Chat API
聊天機器人第二輪答得出第一輪提到的名字,原因是什麼?
finish_reason 是 length 代表什麼?
把對話裁剪成「只留最後幾則」時,為什麼通常要另外保留第一則 system 訊息?
金鑰應該放在哪裡?
重點整理
- 一次呼叫就是送出
messages串列、收到回應物件;常用choices[0].message.content、finish_reason、usage。 system設定規則,user是使用者的話,assistant是模型之前的回答。- 模型不記得上一次呼叫;對話記憶是程式每次把舊訊息一起送出,所以對話越長,每一輪越貴。
- 參數依模型而異,換模型要查文件、實際測試。
下一課: 回答要等全部生成才顯示太慢,而且網路會斷、回答會被截斷。下一課處理串流與錯誤。