Day 25 我們先把 final experiment 的設計固定下來。
當時沒有急著跑模型,原因是:
沒有固定實驗設計,就沒有可信的比較結果。
這一篇才正式開始執行實驗。
不過 Day 26 仍然先不下結論。
這次要做的是:
照 Day 25 的 experiment plan 執行各組設定,蒐集 eval run,並判斷哪些 run 可以進入 Day 27 分析。
Day 26 是資料蒐集日,分析留到下一篇。
執行內容包括:
json_strict prompt。json_strict + retry。執行期間先不做:
範圍收斂在一件事:
把實驗資料乾淨地跑出來。
在執行 Gemini 實驗前,先確認幾件事。
如果沒有設定 Gemini API key,會看到:
ValueError: GEMINI_API_KEY is not set
可以在同一個 terminal 裡設定:
export GEMINI_API_KEY="你的 Gemini API key"
如果只是要驗證本機流程,可以改用:
LLM_PROVIDER=fake
這次 final experiment 要觀察真實 LLM,因此主要使用 Gemini。
Day 25 已經決定:
所有實驗組使用同一份 evals/cases.json。
執行前不要新增、刪除或修改 test cases。
如果中途改了 dataset,前面已經跑出的結果就不適合拿來比較。
為了降低短時間連續請求造成 Gemini 429,每組 Gemini run 都加上:
EVAL_DELAY_SECONDS=10
這不是正式的 rate limit 解法。
但對 MVP 階段來說,可以降低實驗過程被 429 干擾的機率。
Day 25 設計了幾組實驗。
先執行四組 Gemini run:
| experiment id | provider | prompt version | retry |
|---|---|---|---|
gemini_baseline_no_retry |
gemini | baseline | off |
gemini_json_strict_no_retry |
gemini | json_strict | off |
gemini_baseline_retry |
gemini | baseline | on |
gemini_json_strict_retry |
gemini | json_strict | on |
這四組可以回答幾個基本問題:
baseline 表現如何?
json_strict prompt 是否改善 JSON output?
retry 能不能救回 format_error?
prompt 已經改善後,retry 是否還有額外價值?
第一組先建立 baseline。
執行:
EVAL_DELAY_SECONDS=10 \
RETRY_ENABLED=0 \
PROMPT_VERSION=baseline \
LLM_PROVIDER=gemini \
python3 -m evals.runner
這一組代表:
原始 prompt
不做 retry 補救
使用 Gemini 真實回覆
本次執行結果:
Run ID: eval_run_20260924_184555
Provider: gemini
Prompt version: baseline
Retry enabled: False
Total cases: 15
Passed: 10
Failed: 5
Total latency: 88262.05 ms
Total LLM calls: 15
Total tokens: 264
Estimated cost: 0.00000000
這一組是後面比較的基準。
Day 27 會拿其他設定和它比較。
第二組測試 prompt 改善。
執行:
EVAL_DELAY_SECONDS=10 \
RETRY_ENABLED=0 \
PROMPT_VERSION=json_strict \
LLM_PROVIDER=gemini \
python3 -m evals.runner
這一組代表:
改用更嚴格的 JSON prompt
不做 retry 補救
觀察 prompt 本身是否有效
本次執行結果:
Run ID: eval_run_20260924_185011
Provider: gemini
Prompt version: json_strict
Retry enabled: False
Total cases: 15
Passed: 13
Failed: 2
Total latency: 80131.38 ms
Total LLM calls: 15
Total tokens: 140
Estimated cost: 0.00000000
這一組可以和 baseline 直接比較:
同樣不開 retry
只改 prompt version
這樣比較比較乾淨。
第三組測試 retry。
執行:
EVAL_DELAY_SECONDS=10 \
RETRY_ENABLED=1 \
PROMPT_VERSION=baseline \
LLM_PROVIDER=gemini \
python3 -m evals.runner
這一組代表:
維持 baseline prompt
遇到 JSON format_error 時 retry 一次
觀察 retry 能救回多少失敗
本次執行結果:
Run ID: eval_run_20260924_185518
Provider: gemini
Prompt version: baseline
Retry enabled: True
Total cases: 15
Passed: 11
Failed: 4
Total latency: 105118.41 ms
Total LLM calls: 18
Total tokens: 463
Estimated cost: 0.00000000
這裡可以先記下一個現象:
Total LLM calls 從 15 變成 18。
這表示有 3 個 case 觸發 retry。
這裡先記錄現象,完整解讀留到 Day 27。
第四組測試 prompt + retry。
執行:
EVAL_DELAY_SECONDS=10 \
RETRY_ENABLED=1 \
PROMPT_VERSION=json_strict \
LLM_PROVIDER=gemini \
python3 -m evals.runner
這一組代表:
使用 json_strict prompt
同時允許 JSON format_error retry
觀察 prompt 改善後 retry 是否仍有發生
本次執行結果:
Run ID: eval_run_20260924_185945
Provider: gemini
Prompt version: json_strict
Retry enabled: True
Total cases: 15
Passed: 12
Failed: 3
Total latency: 79742.16 ms
Total LLM calls: 15
Total tokens: 133
Estimated cost: 0.00000000
這裡也先記下一個現象:
雖然 RETRY_ENABLED=1,但 Total LLM calls 仍然是 15。
這次沒有 case 觸發 retry;至少在這次 run 裡,json_strict 已經讓 JSON 題目一次通過。
接著把這四組結果記錄下來。
這裡先用 Markdown 手動整理。
新增 evals/final_experiment_runs.md:
# Final Experiment Runs
| experiment id | run id | provider | prompt version | retry | passed | failed | llm calls | total latency ms | usable | note |
|---|---|---|---|---:|---:|---:|---:|---:|---|---|
| gemini_baseline_no_retry | eval_run_20260924_184555 | gemini | baseline | 0 | 10 | 5 | 15 | 88262.05 | yes | baseline |
| gemini_json_strict_no_retry | eval_run_20260924_185011 | gemini | json_strict | 0 | 13 | 2 | 15 | 80131.38 | yes | prompt-only improvement |
| gemini_baseline_retry | eval_run_20260924_185518 | gemini | baseline | 1 | 11 | 4 | 18 | 105118.41 | yes | retry triggered on JSON cases |
| gemini_json_strict_retry | eval_run_20260924_185945 | gemini | json_strict | 1 | 12 | 3 | 15 | 79742.16 | yes | retry enabled but not triggered |
這個檔案不是給程式讀的。
它是給人看的實驗紀錄。
有了它,Day 27 分析時就不需要在 data/eval_runs/ 裡猜哪幾份 JSON 才是 final experiment。
Day 25 有定義一個 run 是否可以進入 final comparison 的條件。
接著逐項檢查。
| 條件 | 檢查結果 |
|---|---|
| total cases 相同 | 四組都是 15 |
| provider 正確 | 四組都是 gemini |
| prompt version 正確 | baseline / json_strict 符合設定 |
| retry_enabled 正確 | off / on 符合設定 |
| 沒有大量 429 | 這四組結果沒有看到 429 |
| eval runner 成功跑完 | 四組都有完整 summary |
所以這四組 run 都可以標記為:
usable for Day 27 analysis
這一步只要確認:
我們已經有一組乾淨、完整、可比較的實驗資料。
雖然 Day 27 才會正式分析,但 Day 26 可以先整理成一張總表。
| experiment | passed | failed | success rate | LLM calls | total latency |
|---|---|---|---|---|---|
| baseline / no retry | 10 | 5 | 66.7% | 15 | 88262.05 ms |
| json_strict / no retry | 13 | 2 | 86.7% | 15 | 80131.38 ms |
| baseline / retry | 11 | 4 | 73.3% | 18 | 105118.41 ms |
| json_strict / retry | 12 | 3 | 80.0% | 15 | 79742.16 ms |
這張表先只做資料整理。
暫時不要急著說:
哪一組最好
因為正式分析還要看:
json_strict + retry 為什麼沒有比 json_strict 更高。這些都留到 Day 27。
有一個欄位值得先確認:
Total LLM calls
如果總共有 15 個 cases,而且沒有 retry,理論上:
Total LLM calls = 15
這在三組實驗中成立:
| experiment | LLM calls |
|---|---|
| baseline / no retry | 15 |
| json_strict / no retry | 15 |
| json_strict / retry | 15 |
但 baseline / retry 是:
Total LLM calls = 18
這表示 retry 真的有發生,而且發生了 3 次。
這和 JSON 題目數量一致。
也就是:
case_013
case_014
case_015
這三題在 baseline 下容易產生 JSON format error。
retry 開啟後,系統多送一次修正 prompt。
這也驗證了 Day 19 和 Day 23 的設計:
retry 可以被觸發
retry 次數可以被記錄
retry 對 LLM call count 有影響
這次四組結果的 estimated cost 都是:
0.00000000
這不是成本真的為 0。
而是 Day 23 的 cost estimation 使用環境變數:
INPUT_COST_PER_1K_TOKENS
OUTPUT_COST_PER_1K_TOKENS
如果沒有設定,預設就是 0。
如果想讓 estimated cost 顯示非 0,可以執行時加上:
INPUT_COST_PER_1K_TOKENS=0.0001 \
OUTPUT_COST_PER_1K_TOKENS=0.0004 \
EVAL_DELAY_SECONDS=10 \
RETRY_ENABLED=0 \
PROMPT_VERSION=baseline \
LLM_PROVIDER=gemini \
python3 -m evals.runner
不過要注意:
這些價格只是示範,不代表 Gemini 實際價格。
Day 26 不處理精準帳單,只確認成本欄位能否統一記錄。
四組實驗跑完後,可以啟動 Day 24 的 dashboard:
streamlit run failure_dashboard_app.py
Dashboard 可以用來確認:
如果 dashboard 裡有很多舊 run,要注意不要直接把所有 run 都當成 final experiment。
真正要送進 Day 27 分析的是這四組:
eval_run_20260924_184555
eval_run_20260924_185011
eval_run_20260924_185518
eval_run_20260924_185945
依照 Day 25 的實驗設計,四組 Gemini final runs 都已完成。
完成內容包含:
evals/final_experiment_runs.md 作為實驗紀錄。這次先不選出勝負,得到的是:
我們已經有一組固定 dataset、固定條件、可比較的 eval run。
Day 27 可以據此回到幾個工程問題:
哪個改善真的有效?
它多花了多少成本與延遲?
剩下的失敗是 Agent 問題,還是 evaluator 問題?
Day 27 會正式分析這四組結果。
我們會比較:
最後會整理出一個比較務實的結論:
在目前這組 eval dataset 上,哪一種改善最值得保留?