API 開發
動手建一條 prompt 評測管線:資料集、程式評分與模型評分
動手建一條 prompt 評測管線:資料集、程式評分與模型評分
上一篇談了為什麼 prompt 需要評測,這一篇就捲起袖子動手做,從零建出一條完整的評測管線:先產生測試資料集,再把管線本體跑起來,最後接上兩種評分器。
範例的目標 prompt 很具體:協助使用者完成 AWS 相關任務,輸出 Python 程式、JSON 設定檔或正規表達式,而且要乾淨輸出,不准夾帶多餘的說明、開頭或結尾。
你將學到什麼
五個步驟總覽
從草擬 prompt 到改版重跑,一條管線的完整循環。
用 Claude 產生資料集
prefill 加 stop sequence,讓測試資料自動生出來。
三個核心函式
run_prompt、run_test_case、run_eval 各管一件事。
兩種評分器
程式評分管格式語法,模型評分管內容品質。
一條評測管線的五個步驟
- 草擬 prompt:先有一版基準,簡單也沒關係。
- 建立評測資料集:收集一批有代表性的輸入。
- 逐筆丟給 Claude:把每筆輸入套進 prompt 模板送出。
- 交給評分器:對每個輸出打 1 到 10 分並取平均。
- 修改 prompt 再跑一輪:平均分數上升,才算真的進步。
組裝這條管線的方式很多,市面上也有各種開源與付費工具,但先徒手做一次小規模的,之後要換工具或擴大都容易得多。
建立資料集:請 Claude 代工
資料集是一個 JSON 陣列,每個物件帶一個 task 欄位描述要完成的任務。你可以手工建,也可以寫一個函式請 Claude 產生。因為只是產生測試資料,很適合改用速度較快的 Haiku 等級模型。
def generate_dataset():
prompt = """
Generate an evaluation dataset for a prompt evaluation.
The dataset will be used to evaluate prompts that generate
Python, JSON, or Regex specifically for AWS-related tasks.
Generate an array of JSON objects, each representing a task.
* Focus on tasks solvable with a single function, object, or regex
* Focus on tasks that do not require much code
Please generate 3 objects.
"""
messages = []
add_user_message(messages, prompt)
add_assistant_message(messages, "```json")
text = chat(messages, stop_sequences=["```"])
return json.loads(text)
收尾兩招是關鍵:用 assistant prefill 先幫 Claude 起頭一個程式碼區塊,再用 stop sequence 在區塊結束時停下來,回傳的內容就能直接用 json.loads 解析。產好的資料集存成 dataset.json,之後每一輪評測都重複使用同一份,分數才有可比性。
三個核心函式,把管線跑起來
def run_prompt(test_case):
prompt = f"""
Please solve the following task:
{test_case["task"]}
"""
messages = []
add_user_message(messages, prompt)
return chat(messages)
def run_test_case(test_case):
output = run_prompt(test_case)
score = 10 # TODO: real grading
return {"output": output, "test_case": test_case, "score": score}
def run_eval(dataset):
results = []
for test_case in dataset:
results.append(run_test_case(test_case))
return results
run_prompt 負責把測試案例塞進 prompt 模板送給 Claude;run_test_case 跑單一案例並打分;run_eval 走訪整個資料集收集結果。此刻分數還是寫死的 10 分,但整條管線已經能動了。
實際跑一次,你會拿到一個結構化的結果陣列,每個物件有三樣東西:output 是 Claude 的完整回應、test_case 是原始測試案例、score 是分數。因為我們還沒給任何格式指示,這時的輸出會相當囉嗦,前後夾著大段說明。這正是之後改 prompt 要解決的問題,也是評測要抓的東西。
老實說,你剛剛已經做完一條評測管線的主體,剩下的複雜度全在細節裡,尤其是評分。
評分器有三種
| 評分器 | 擅長評的東西 | 特性 |
|---|---|---|
| 程式評分器 | 輸出長度、關鍵字檢查、JSON 與 Python 與 regex 的語法驗證、可讀性分數 | 快、便宜、完全客觀 |
| 模型評分器 | 回答品質、遵循指示程度、完整性、有用性、安全性 | 彈性最大,但分數會有些浮動 |
| 人工評分器 | 整體品質、深度、簡潔度、相關性 | 最靈活,也最花時間 |
評分器的共同點只有一個:接收模型的輸出,回傳某種可用的訊號,通常是 1 到 10 的數字。程式評分器能實作任何你寫得出來的檢查;模型評分器是把輸出丟進另一次 API 呼叫請模型評估;人工評分最靈活,但又慢又累,適合抽查而不是全量。
打分之前要先訂標準。以這個代碼生成 prompt 為例,評估標準有三條:格式(只回 Python、JSON 或 regex,不准解釋)、語法有效(產出的程式碼要能解析)、正確回應任務。前兩條非黑即白,交給程式評分器;最後一條需要理解力,交給模型評分器。
模型評分:要分數,也要理由
def grade_by_model(test_case, output):
eval_prompt = """
You are an expert code reviewer. Evaluate this AI-generated solution.
Task: {task}
Solution: {solution}
Provide your evaluation as a structured JSON object with:
- "strengths": An array of 1-3 key strengths
- "weaknesses": An array of 1-3 key areas for improvement
- "reasoning": A concise explanation of your assessment
- "score": A number between 1-10
"""
messages = []
add_user_message(messages, eval_prompt)
add_assistant_message(messages, "```json")
eval_text = chat(messages, stop_sequences=["```"])
return json.loads(eval_text)
拿到分數後,把它接回 run_test_case,順便把 reasoning 一起存進結果;最後在 run_eval 裡用 statistics.mean 算出整體平均,你就有一個可以逐輪追蹤的客觀指標了。
模型評分的分數難免有些浮動,不會每次一模一樣,但作為衡量改進的基準線已經非常夠用:同一份資料集、同一個評分器,前後兩版 prompt 的平均分數就有比較意義。
程式評分與分數合併
def validate_json(text):
try:
json.loads(text.strip())
return 10
except json.JSONDecodeError:
return 0
def validate_python(text):
try:
ast.parse(text.strip())
return 10
except SyntaxError:
return 0
def validate_regex(text):
try:
re.compile(text.strip())
return 10
except re.error:
return 0
三個驗證函式的邏輯一模一樣:能成功解析就給 10 分,解析失敗就 0 分。
為了讓程式評分器知道該用哪個驗證器,資料集的每筆案例要多帶一個 format 欄位標明預期格式;同時把 prompt 的指示寫得更明確,例如「只回傳 Python、JSON 或 regex,不加任何註解或說明」,並可用 prefill 起頭一個程式碼區塊,引導 Claude 只吐純程式碼。
model_score = grade_by_model(test_case, output)["score"]
syntax_score = grade_syntax(output, test_case)
score = (model_score + syntax_score) / 2
最後把兩種分數合併,最簡單的做法是各占一半取平均;哪一邊比較重要,就依你的應用調整權重。要記住:分數本身沒有絕對的好壞,重點是你能不能靠改 prompt 把它推高。有了這條管線,prompt engineering 就從主觀猜測,變成可量測、可累積的工程。
延伸學習
ChatGPT 很強,但真正讓你下班的是 Google
六小時完整實錄。從「AI 很厲害,為什麼你還是每天加班」這個問題出發,把 Google Workspace 當成真正的工作平台重新設計一次流程 ── Sheets 的資料結構、Drive 與 Docs 的文件流、Gmail 與 Calendar 的通知系統,再用 Apps Script 讓它自己跑起來,最後收斂成一張屬於你自己的 AI 工作能力地圖。
NT$ 4,599
AI Native 工作法
四小時完整實錄。工作已經不是以前的工作了 ── 這門課拆解 AI Native 的四個核心能力,帶你把自己的工作做成一份可執行的 AI Native Blueprint,從「會用 AI 的人」變成「工作本身就長在 AI 上的人」。
NT$ 2,599

