<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>Evaluation on Tarragon</title><link>https://tarrragon.github.io/blog/tags/evaluation/</link><description>Recent content in Evaluation on Tarragon</description><generator>Hugo -- gohugo.io</generator><language>zh-TW</language><copyright>Tarragon (CC BY 4.0)</copyright><lastBuildDate>Thu, 14 May 2026 00:00:00 +0000</lastBuildDate><atom:link href="https://tarrragon.github.io/blog/tags/evaluation/index.xml" rel="self" type="application/rss+xml"/><item><title>Capability Spectrum</title><link>https://tarrragon.github.io/blog/llm/knowledge-cards/capability-spectrum/</link><pubDate>Thu, 14 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/llm/knowledge-cards/capability-spectrum/</guid><description>&lt;p>Capability spectrum（能力光譜）的核心概念是「&lt;strong>LLM 能力通常是連續程度，不是支援 / 不支援的二元開關&lt;/strong>」。同樣宣稱支援 function calling、reasoning、coding、structured output 的模型，可能在簡單案例都成功，但在長 context、多工具、巢狀 schema、模糊需求或反例情境下出現巨大差距。&lt;/p>
&lt;h2 id="概念位置">概念位置&lt;/h2>
&lt;p>能力光譜是評估與選型用語，用來替代 binary checklist。它把能力拆成範圍、穩定性、成本與失敗模式：模型能做什麼、在多寬的分佈上穩定、錯的時候怎麼錯、需要多少 prompt / validator / retry 才可用。&lt;/p>





&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-text" data-lang="text">&lt;span class="line">&lt;span class="ln">1&lt;/span>&lt;span class="cl">宣稱支援 → happy path 可用
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">2&lt;/span>&lt;span class="cl">基礎可用 → 常見變體可用
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">3&lt;/span>&lt;span class="cl">生產可用 → edge cases、錯誤路徑、壓力情境仍可控&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="可觀察訊號與例子">可觀察訊號與例子&lt;/h2>
&lt;p>Function calling 的能力光譜可以用幾個訊號量化：單工具成功率、多工具選擇成功率、schema 合法率、參數語意正確率、錯誤時是否追問。某模型能輸出合法 JSON，不代表它能選對工具；能選對工具，也不代表它能填對 nested argument。&lt;/p>
&lt;p>能力光譜的常見陷阱是把 demo 成功當成生產穩定。Demo 通常測 happy path，生產會遇到拼字錯、缺欄位、權限不足、工具 timeout、prompt injection、schema 演化與多語言輸入；這些才決定能力落在哪個位置。&lt;/p>
&lt;h2 id="設計責任">設計責任&lt;/h2>
&lt;p>做模型選型或應用設計時，把「有沒有」改成「到什麼程度可用」。判準要包含成功率、覆蓋範圍、錯誤成本、監控訊號與回退路徑。下一步路由是：能力來自訓練資料時讀 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/training-example-coverage/" data-link-title="Training Example Coverage" data-link-desc="訓練資料中的任務範例是否覆蓋足夠情境，決定模型在 function calling、格式輸出與邊界案例上的穩定性">Training Example Coverage&lt;/a>；能力需要推論階段兜底時讀 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/sampling-constraint/" data-link-title="Sampling Constraint" data-link-desc="推論時限制下一個 token 候選集合的控制手段，用來把模型生成導向合法格式或特定選項">Sampling Constraint&lt;/a>。&lt;/p></description><content:encoded><![CDATA[<p>Capability spectrum（能力光譜）的核心概念是「<strong>LLM 能力通常是連續程度，不是支援 / 不支援的二元開關</strong>」。同樣宣稱支援 function calling、reasoning、coding、structured output 的模型，可能在簡單案例都成功，但在長 context、多工具、巢狀 schema、模糊需求或反例情境下出現巨大差距。</p>
<h2 id="概念位置">概念位置</h2>
<p>能力光譜是評估與選型用語，用來替代 binary checklist。它把能力拆成範圍、穩定性、成本與失敗模式：模型能做什麼、在多寬的分佈上穩定、錯的時候怎麼錯、需要多少 prompt / validator / retry 才可用。</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="ln">1</span><span class="cl">宣稱支援 → happy path 可用
</span></span><span class="line"><span class="ln">2</span><span class="cl">基礎可用 → 常見變體可用
</span></span><span class="line"><span class="ln">3</span><span class="cl">生產可用 → edge cases、錯誤路徑、壓力情境仍可控</span></span></code></pre></div><h2 id="可觀察訊號與例子">可觀察訊號與例子</h2>
<p>Function calling 的能力光譜可以用幾個訊號量化：單工具成功率、多工具選擇成功率、schema 合法率、參數語意正確率、錯誤時是否追問。某模型能輸出合法 JSON，不代表它能選對工具；能選對工具，也不代表它能填對 nested argument。</p>
<p>能力光譜的常見陷阱是把 demo 成功當成生產穩定。Demo 通常測 happy path，生產會遇到拼字錯、缺欄位、權限不足、工具 timeout、prompt injection、schema 演化與多語言輸入；這些才決定能力落在哪個位置。</p>
<h2 id="設計責任">設計責任</h2>
<p>做模型選型或應用設計時，把「有沒有」改成「到什麼程度可用」。判準要包含成功率、覆蓋範圍、錯誤成本、監控訊號與回退路徑。下一步路由是：能力來自訓練資料時讀 <a href="/blog/llm/knowledge-cards/training-example-coverage/" data-link-title="Training Example Coverage" data-link-desc="訓練資料中的任務範例是否覆蓋足夠情境，決定模型在 function calling、格式輸出與邊界案例上的穩定性">Training Example Coverage</a>；能力需要推論階段兜底時讀 <a href="/blog/llm/knowledge-cards/sampling-constraint/" data-link-title="Sampling Constraint" data-link-desc="推論時限制下一個 token 候選集合的控制手段，用來把模型生成導向合法格式或特定選項">Sampling Constraint</a>。</p>
]]></content:encoded></item><item><title>Frozen baseline</title><link>https://tarrragon.github.io/blog/llm/knowledge-cards/frozen-baseline/</link><pubDate>Thu, 14 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/llm/knowledge-cards/frozen-baseline/</guid><description>&lt;p>Frozen baseline 的核心概念是「&lt;strong>把某個特定 prompt + 特定 model 跑 production 一段時間後 freeze、每次新版本都跟它比、定期 refresh 並標明時點&lt;/strong>」。Eval 系統的標準作法、讓行為漂移可見、避免「永遠跟上一版比、長期累積漂移看不見」的常見失敗。&lt;/p>
&lt;h2 id="概念位置">概念位置&lt;/h2>
&lt;p>跟其他 eval 概念對照：&lt;/p>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>概念&lt;/th>
 &lt;th>角色&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>Eval set&lt;/td>
 &lt;td>測試 input 的集合&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Frozen baseline&lt;/td>
 &lt;td>固定的「對照組」prompt + model 版本&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Regression set&lt;/td>
 &lt;td>Failed case 進來、防止改 prompt 又壞同樣 case&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Production trace&lt;/td>
 &lt;td>實際 traffic、抽樣補進 eval set / baseline&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;p>工作流：&lt;/p>





&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-text" data-lang="text">&lt;span class="line">&lt;span class="ln">1&lt;/span>&lt;span class="cl">Day 1：定義 eval set + 初始 prompt + model
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">2&lt;/span>&lt;span class="cl"> ↓ 跑 production 一段時間（如 2 週）
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">3&lt;/span>&lt;span class="cl">Day 14：把當下 prompt + model freeze 成 baseline-v1
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">4&lt;/span>&lt;span class="cl"> ↓
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">5&lt;/span>&lt;span class="cl">新版本 prompt / model 都跟 baseline-v1 比
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">6&lt;/span>&lt;span class="cl"> ↓ 定期（如每季）refresh
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">7&lt;/span>&lt;span class="cl">Day 90：baseline-v2、標明 refresh 時點&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="設計責任">設計責任&lt;/h2>
&lt;p>讀 eval / production AI 文章看到「frozen baseline」「baseline drift」「regression set」就是這個機制。實作判讀：&lt;/p>
&lt;ol>
&lt;li>&lt;strong>為什麼必要&lt;/strong>：每次 A/B 都跟「最新版本」比、長期累積漂移完全不可見、「整體變好了沒」無從回答。Frozen baseline 是漂移的錨點。&lt;/li>
&lt;li>&lt;strong>何時 freeze&lt;/strong>：production 跑穩、user 滿意度可接受時 freeze。太早 freeze 鎖到不夠好的版本、太晚 freeze 鎖不到。&lt;/li>
&lt;li>&lt;strong>何時 refresh&lt;/strong>：定期（每季 / 每半年）、或當 baseline 明顯 obsolete（如 model 升級、產品大改版）。Refresh 後標明時點、舊版本仍可保留當歷史對照。&lt;/li>
&lt;li>&lt;strong>跟 frozen baseline 一起的還有&lt;/strong>：regression set（failed case 永遠進、防 fix 一個壞一個）、production trace 抽樣補進 eval set（讓 eval set 不脫節）。&lt;/li>
&lt;li>&lt;strong>失敗模式&lt;/strong>：baseline 跟 production 分佈差太遠（baseline 用 lab case、production 是 wild input）、跑出來分數沒參考價值。緩解：baseline 的 eval set 用 production trace 抽樣建。&lt;/li>
&lt;/ol>
&lt;p>完整 eval 系統設計見 &lt;a href="https://tarrragon.github.io/blog/llm/04-applications/eval-design-framework/" data-link-title="4.13 Eval 設計座標系：三軸、八象限、何時測什麼" data-link-desc="Eval 設計三軸（objective↔subjective / component↔end-to-end / quantitative↔qualitative）、八象限的對應 eval 工具、軸選錯的訊號、跟 benchmarking / LLM-as-judge / tracing 的關係">4.13 Eval 設計座標系&lt;/a>。&lt;/p></description><content:encoded><![CDATA[<p>Frozen baseline 的核心概念是「<strong>把某個特定 prompt + 特定 model 跑 production 一段時間後 freeze、每次新版本都跟它比、定期 refresh 並標明時點</strong>」。Eval 系統的標準作法、讓行為漂移可見、避免「永遠跟上一版比、長期累積漂移看不見」的常見失敗。</p>
<h2 id="概念位置">概念位置</h2>
<p>跟其他 eval 概念對照：</p>
<table>
  <thead>
      <tr>
          <th>概念</th>
          <th>角色</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Eval set</td>
          <td>測試 input 的集合</td>
      </tr>
      <tr>
          <td>Frozen baseline</td>
          <td>固定的「對照組」prompt + model 版本</td>
      </tr>
      <tr>
          <td>Regression set</td>
          <td>Failed case 進來、防止改 prompt 又壞同樣 case</td>
      </tr>
      <tr>
          <td>Production trace</td>
          <td>實際 traffic、抽樣補進 eval set / baseline</td>
      </tr>
  </tbody>
</table>
<p>工作流：</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="ln">1</span><span class="cl">Day 1：定義 eval set + 初始 prompt + model
</span></span><span class="line"><span class="ln">2</span><span class="cl">   ↓ 跑 production 一段時間（如 2 週）
</span></span><span class="line"><span class="ln">3</span><span class="cl">Day 14：把當下 prompt + model freeze 成 baseline-v1
</span></span><span class="line"><span class="ln">4</span><span class="cl">   ↓
</span></span><span class="line"><span class="ln">5</span><span class="cl">新版本 prompt / model 都跟 baseline-v1 比
</span></span><span class="line"><span class="ln">6</span><span class="cl">   ↓ 定期（如每季）refresh
</span></span><span class="line"><span class="ln">7</span><span class="cl">Day 90：baseline-v2、標明 refresh 時點</span></span></code></pre></div><h2 id="設計責任">設計責任</h2>
<p>讀 eval / production AI 文章看到「frozen baseline」「baseline drift」「regression set」就是這個機制。實作判讀：</p>
<ol>
<li><strong>為什麼必要</strong>：每次 A/B 都跟「最新版本」比、長期累積漂移完全不可見、「整體變好了沒」無從回答。Frozen baseline 是漂移的錨點。</li>
<li><strong>何時 freeze</strong>：production 跑穩、user 滿意度可接受時 freeze。太早 freeze 鎖到不夠好的版本、太晚 freeze 鎖不到。</li>
<li><strong>何時 refresh</strong>：定期（每季 / 每半年）、或當 baseline 明顯 obsolete（如 model 升級、產品大改版）。Refresh 後標明時點、舊版本仍可保留當歷史對照。</li>
<li><strong>跟 frozen baseline 一起的還有</strong>：regression set（failed case 永遠進、防 fix 一個壞一個）、production trace 抽樣補進 eval set（讓 eval set 不脫節）。</li>
<li><strong>失敗模式</strong>：baseline 跟 production 分佈差太遠（baseline 用 lab case、production 是 wild input）、跑出來分數沒參考價值。緩解：baseline 的 eval set 用 production trace 抽樣建。</li>
</ol>
<p>完整 eval 系統設計見 <a href="/blog/llm/04-applications/eval-design-framework/" data-link-title="4.13 Eval 設計座標系：三軸、八象限、何時測什麼" data-link-desc="Eval 設計三軸（objective↔subjective / component↔end-to-end / quantitative↔qualitative）、八象限的對應 eval 工具、軸選錯的訊號、跟 benchmarking / LLM-as-judge / tracing 的關係">4.13 Eval 設計座標系</a>。</p>
]]></content:encoded></item><item><title>Instruction Following</title><link>https://tarrragon.github.io/blog/llm/knowledge-cards/instruction-following/</link><pubDate>Thu, 14 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/llm/knowledge-cards/instruction-following/</guid><description>&lt;p>Instruction following 的核心概念是「&lt;strong>模型能否遵守使用者或系統給定的任務約束&lt;/strong>」。它關注模型是否照格式輸出、是否留在任務範圍、是否遵守長度與禁止事項，跟 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/instruction-tuned/" data-link-title="Instruction-Tuned Model" data-link-desc="經過指令微調的模型：會跟著 prompt 走、回答使用者問題">instruction-tuned model&lt;/a> 這種訓練後模型類型相關，但不是同一件事。&lt;/p>
&lt;h2 id="概念位置">概念位置&lt;/h2>
&lt;p>&lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/instruction-tuned/" data-link-title="Instruction-Tuned Model" data-link-desc="經過指令微調的模型：會跟著 prompt 走、回答使用者問題">Instruction-tuned model&lt;/a> 是訓練狀態，instruction following 是行為表現。模型可能經過 SFT，仍在細格式、邊界條件或多約束任務上失敗；也可能在簡單指令上表現穩定，但遇到衝突指令或長 prompt 漏掉限制。&lt;/p>
&lt;h2 id="可觀察訊號與例子">可觀察訊號與例子&lt;/h2>
&lt;p>測試訊號包含：是否輸出指定 JSON、是否只回答要求的欄位、是否避免多餘解釋、是否在資料不足時說不知道、是否遵守「不要呼叫工具」或「只讀不寫」。本地小模型常在簡單問答可用，但在多條格式限制同時存在時掉分。&lt;/p>
&lt;h2 id="設計責任">設計責任&lt;/h2>
&lt;p>評估 instruction following 時要做 coverage 測試：格式、長度、拒答、資料不足、衝突指令、跨語言指令都要看。失敗時優先用更清楚的 prompt、few-shot、structured output 或 validator 兜底；長期穩定需求才考慮 fine-tune。&lt;/p></description><content:encoded><![CDATA[<p>Instruction following 的核心概念是「<strong>模型能否遵守使用者或系統給定的任務約束</strong>」。它關注模型是否照格式輸出、是否留在任務範圍、是否遵守長度與禁止事項，跟 <a href="/blog/llm/knowledge-cards/instruction-tuned/" data-link-title="Instruction-Tuned Model" data-link-desc="經過指令微調的模型：會跟著 prompt 走、回答使用者問題">instruction-tuned model</a> 這種訓練後模型類型相關，但不是同一件事。</p>
<h2 id="概念位置">概念位置</h2>
<p><a href="/blog/llm/knowledge-cards/instruction-tuned/" data-link-title="Instruction-Tuned Model" data-link-desc="經過指令微調的模型：會跟著 prompt 走、回答使用者問題">Instruction-tuned model</a> 是訓練狀態，instruction following 是行為表現。模型可能經過 SFT，仍在細格式、邊界條件或多約束任務上失敗；也可能在簡單指令上表現穩定，但遇到衝突指令或長 prompt 漏掉限制。</p>
<h2 id="可觀察訊號與例子">可觀察訊號與例子</h2>
<p>測試訊號包含：是否輸出指定 JSON、是否只回答要求的欄位、是否避免多餘解釋、是否在資料不足時說不知道、是否遵守「不要呼叫工具」或「只讀不寫」。本地小模型常在簡單問答可用，但在多條格式限制同時存在時掉分。</p>
<h2 id="設計責任">設計責任</h2>
<p>評估 instruction following 時要做 coverage 測試：格式、長度、拒答、資料不足、衝突指令、跨語言指令都要看。失敗時優先用更清楚的 prompt、few-shot、structured output 或 validator 兜底；長期穩定需求才考慮 fine-tune。</p>
]]></content:encoded></item><item><title>Training Example Coverage</title><link>https://tarrragon.github.io/blog/llm/knowledge-cards/training-example-coverage/</link><pubDate>Thu, 14 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/llm/knowledge-cards/training-example-coverage/</guid><description>&lt;p>Training example coverage（訓練範例覆蓋度）的核心概念是「&lt;strong>模型在訓練時看過的任務情境是否足以支撐部署時遇到的變化&lt;/strong>」。LLM 的能力宣稱常寫成支援某功能，但實際穩定性取決於範例是否覆蓋工具數量、參數形狀、語言變體、錯誤情境與 edge cases。&lt;/p>
&lt;h2 id="概念位置">概念位置&lt;/h2>
&lt;p>Coverage 是訓練資料分佈的問題，常在 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/sft/" data-link-title="SFT（Supervised Fine-Tuning）" data-link-desc="在 base model 上用「指令-回答」對資料微調、讓模型會跟著指令走">SFT&lt;/a>、偏好資料、tool-use data、domain fine-tune 裡出現。它跟 prompt 範例不同：few-shot 範例只存在於當次 context，training examples 會透過訓練更新模型權重，影響模型「自然」傾向怎麼回答。&lt;/p>





&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-text" data-lang="text">&lt;span class="line">&lt;span class="ln">1&lt;/span>&lt;span class="cl">訓練資料有覆蓋 → 模型自然輸出穩定
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">2&lt;/span>&lt;span class="cl">訓練資料缺口大 → 靠 prompt / structured output / validator 兜底&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="可觀察訊號與例子">可觀察訊號與例子&lt;/h2>
&lt;p>Function calling 的 coverage 可從四個面向判讀：該呼叫時是否呼叫、工具選擇是否正確、參數型別是否正確、巢狀 schema 與多工具情境是否穩定。小模型常在單一工具 + 平坦 schema 表現可用，但一進到多工具、optional field、nested object、跨語言 query 就明顯掉分，這通常是 coverage 不足而不是單純 parser 問題。&lt;/p>
&lt;p>Coverage 的陷阱是只看 happy path。訓練範例如果只有成功呼叫工具，模型會傾向每次都呼叫；如果缺少「資訊不足時先追問」「使用者要求超出權限時拒絕」「工具錯誤時重試或回退」這類範例，部署後會在安全與可靠性邊界失敗。&lt;/p>
&lt;h2 id="設計責任">設計責任&lt;/h2>
&lt;p>評估模型能力時，把支援功能改問成覆蓋範圍：支援哪些 tool schema 複雜度、哪些語言、哪些錯誤路徑、哪些反例。下一步路由是用 eval set 補齊代表性情境；如果 coverage 無法補在模型訓練層，就用 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/structured-output/" data-link-title="Structured Output" data-link-desc="讓 LLM 輸出可被 parser 穩定消費的推論階段設計：JSON mode、schema-guided decoding、grammar 約束都屬於這一層">structured output&lt;/a>、validator、retry 與 fallback 降低失敗成本。&lt;/p></description><content:encoded><![CDATA[<p>Training example coverage（訓練範例覆蓋度）的核心概念是「<strong>模型在訓練時看過的任務情境是否足以支撐部署時遇到的變化</strong>」。LLM 的能力宣稱常寫成支援某功能，但實際穩定性取決於範例是否覆蓋工具數量、參數形狀、語言變體、錯誤情境與 edge cases。</p>
<h2 id="概念位置">概念位置</h2>
<p>Coverage 是訓練資料分佈的問題，常在 <a href="/blog/llm/knowledge-cards/sft/" data-link-title="SFT（Supervised Fine-Tuning）" data-link-desc="在 base model 上用「指令-回答」對資料微調、讓模型會跟著指令走">SFT</a>、偏好資料、tool-use data、domain fine-tune 裡出現。它跟 prompt 範例不同：few-shot 範例只存在於當次 context，training examples 會透過訓練更新模型權重，影響模型「自然」傾向怎麼回答。</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="ln">1</span><span class="cl">訓練資料有覆蓋 → 模型自然輸出穩定
</span></span><span class="line"><span class="ln">2</span><span class="cl">訓練資料缺口大 → 靠 prompt / structured output / validator 兜底</span></span></code></pre></div><h2 id="可觀察訊號與例子">可觀察訊號與例子</h2>
<p>Function calling 的 coverage 可從四個面向判讀：該呼叫時是否呼叫、工具選擇是否正確、參數型別是否正確、巢狀 schema 與多工具情境是否穩定。小模型常在單一工具 + 平坦 schema 表現可用，但一進到多工具、optional field、nested object、跨語言 query 就明顯掉分，這通常是 coverage 不足而不是單純 parser 問題。</p>
<p>Coverage 的陷阱是只看 happy path。訓練範例如果只有成功呼叫工具，模型會傾向每次都呼叫；如果缺少「資訊不足時先追問」「使用者要求超出權限時拒絕」「工具錯誤時重試或回退」這類範例，部署後會在安全與可靠性邊界失敗。</p>
<h2 id="設計責任">設計責任</h2>
<p>評估模型能力時，把支援功能改問成覆蓋範圍：支援哪些 tool schema 複雜度、哪些語言、哪些錯誤路徑、哪些反例。下一步路由是用 eval set 補齊代表性情境；如果 coverage 無法補在模型訓練層，就用 <a href="/blog/llm/knowledge-cards/structured-output/" data-link-title="Structured Output" data-link-desc="讓 LLM 輸出可被 parser 穩定消費的推論階段設計：JSON mode、schema-guided decoding、grammar 約束都屬於這一層">structured output</a>、validator、retry 與 fallback 降低失敗成本。</p>
]]></content:encoded></item><item><title>LLM Benchmarks（MMLU / HumanEval / SWE-bench 等）</title><link>https://tarrragon.github.io/blog/llm/knowledge-cards/llm-benchmarks/</link><pubDate>Tue, 12 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/llm/knowledge-cards/llm-benchmarks/</guid><description>&lt;p>LLM benchmarks 的核心概念是「&lt;strong>用標準化任務集合衡量 LLM 各維度能力的評估工具&lt;/strong>」。不同 benchmark 衡量不同維度（知識、reasoning、code、對話、math 等）、選錯 benchmark 看模型會誤判。本卡列主流 benchmark 跟它們的覆蓋面、失效情境。&lt;/p>
&lt;h2 id="概念位置">概念位置&lt;/h2>
&lt;p>主流 LLM benchmark 一覽：&lt;/p>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>Benchmark&lt;/th>
 &lt;th>衡量維度&lt;/th>
 &lt;th>任務形式&lt;/th>
 &lt;th>失效情境&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>&lt;strong>MMLU&lt;/strong>&lt;/td>
 &lt;td>通用知識（57 學科多選題）&lt;/td>
 &lt;td>4 選 1 選擇題&lt;/td>
 &lt;td>訓練資料污染（題目可能在 pretrain corpus）&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>GSM8K&lt;/strong>&lt;/td>
 &lt;td>小學數學 word problem&lt;/td>
 &lt;td>文字 + 數字、需 reasoning&lt;/td>
 &lt;td>飽和（前沿模型 95%+）&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>MATH&lt;/strong>&lt;/td>
 &lt;td>高中 / 競賽數學&lt;/td>
 &lt;td>自由作答&lt;/td>
 &lt;td>訓練污染、reasoning model 表現遠超 instruct&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>HumanEval&lt;/strong>&lt;/td>
 &lt;td>Python function 補完&lt;/td>
 &lt;td>寫一個 function 通過 unit test&lt;/td>
 &lt;td>飽和、僅覆蓋初級 coding&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>MBPP&lt;/strong>&lt;/td>
 &lt;td>Python coding 任務&lt;/td>
 &lt;td>同上、規模較大&lt;/td>
 &lt;td>同 HumanEval&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/swe-bench/" data-link-title="SWE-bench" data-link-desc="用真實 GitHub issue 量化 LLM coding 能力的 benchmark">&lt;strong>SWE-bench&lt;/strong>&lt;/a>&lt;/td>
 &lt;td>真實 GitHub issue 修復&lt;/td>
 &lt;td>給 repo + issue、生 patch、跑 test&lt;/td>
 &lt;td>仍是 LLM 主要 coding 差距、不易飽和&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>MT-Bench&lt;/strong>&lt;/td>
 &lt;td>多輪對話品質&lt;/td>
 &lt;td>80 題 prompt、LLM-as-judge 評分&lt;/td>
 &lt;td>LLM-as-judge bias、judge 模型本身能力影響評分&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Chatbot Arena&lt;/strong>&lt;/td>
 &lt;td>開放對話偏好（眾人投票）&lt;/td>
 &lt;td>A/B 對戰、Elo 排名&lt;/td>
 &lt;td>文化偏好、prompt 設計影響&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>HELM&lt;/strong>&lt;/td>
 &lt;td>多 dimension comprehensive&lt;/td>
 &lt;td>22 scenarios × 多 metrics&lt;/td>
 &lt;td>計算昂貴、不易追蹤每代新模型&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>AlpacaEval&lt;/strong>&lt;/td>
 &lt;td>指令跟隨能力&lt;/td>
 &lt;td>LLM-as-judge 對比 GPT-4&lt;/td>
 &lt;td>Judge bias、易被「verbose」攻擊&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>RULER&lt;/strong>&lt;/td>
 &lt;td>Long context 真實任務&lt;/td>
 &lt;td>Multi-needle、aggregation、reasoning&lt;/td>
 &lt;td>較新、覆蓋仍在演化&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;blockquote>
&lt;p>&lt;strong>事實查核註&lt;/strong>：各 benchmark 的飽和狀態、前沿模型 score 持續變動、上述為 2026/5 主流觀察。引用前以 &lt;a href="https://paperswithcode.com/">Papers with Code&lt;/a> 或 &lt;a href="https://huggingface.co/spaces/HuggingFaceH4/open_llm_leaderboard">HuggingFace Open LLM Leaderboard&lt;/a> 當前狀態為準。&lt;/p>&lt;/blockquote>
&lt;h2 id="benchmark-的常見陷阱">Benchmark 的常見陷阱&lt;/h2>
&lt;ol>
&lt;li>&lt;strong>訓練資料污染（Contamination）&lt;/strong>：benchmark 題目本身在 pretrain corpus 出現過、模型「記得」答案、看似強實際是 memorization&lt;/li>
&lt;li>&lt;strong>飽和（Saturation）&lt;/strong>：前沿模型 score 接近上限、無法區分模型品質差距（HumanEval 80%→95% 看似進步、實際 5% 多半是 lucky 而非實質提升）&lt;/li>
&lt;li>&lt;strong>LLM-as-judge bias&lt;/strong>：用 LLM（如 GPT-4）評其他 LLM、judge 的偏好（如「冗長 = 好」）會 bias 評分&lt;/li>
&lt;li>&lt;strong>Single-task overfitting&lt;/strong>：模型廠商針對 benchmark 特別 fine-tune、benchmark 高分但通用能力沒提升&lt;/li>
&lt;li>&lt;strong>Prompt sensitivity&lt;/strong>：同個 benchmark 用不同 prompt format、score 差幾個百分點&lt;/li>
&lt;/ol>
&lt;h2 id="設計責任">設計責任&lt;/h2>
&lt;p>讀 model card / paper 看到 benchmark 數字、判讀框架：&lt;/p>
&lt;ol>
&lt;li>&lt;strong>看 multiple benchmarks、不只一個&lt;/strong>：如挑 coding 模型、看 HumanEval + MBPP + SWE-bench、不只看 HumanEval&lt;/li>
&lt;li>&lt;strong>跟自己任務對齊的 benchmark 才重要&lt;/strong>：你做 RAG 應用、看 retrieval benchmark；你做 chat、看 MT-Bench / Arena&lt;/li>
&lt;li>&lt;strong>看「相對」、不只看「絕對」&lt;/strong>：「Model A 在 MMLU 比 Model B 高 2%」可能 noise；「A 比 B 高 10%」更可信&lt;/li>
&lt;li>&lt;strong>In-house benchmark 是最後檢驗&lt;/strong>：自己的真實工作流案例 &amp;gt; 任何公開 benchmark&lt;/li>
&lt;/ol></description><content:encoded><![CDATA[<p>LLM benchmarks 的核心概念是「<strong>用標準化任務集合衡量 LLM 各維度能力的評估工具</strong>」。不同 benchmark 衡量不同維度（知識、reasoning、code、對話、math 等）、選錯 benchmark 看模型會誤判。本卡列主流 benchmark 跟它們的覆蓋面、失效情境。</p>
<h2 id="概念位置">概念位置</h2>
<p>主流 LLM benchmark 一覽：</p>
<table>
  <thead>
      <tr>
          <th>Benchmark</th>
          <th>衡量維度</th>
          <th>任務形式</th>
          <th>失效情境</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><strong>MMLU</strong></td>
          <td>通用知識（57 學科多選題）</td>
          <td>4 選 1 選擇題</td>
          <td>訓練資料污染（題目可能在 pretrain corpus）</td>
      </tr>
      <tr>
          <td><strong>GSM8K</strong></td>
          <td>小學數學 word problem</td>
          <td>文字 + 數字、需 reasoning</td>
          <td>飽和（前沿模型 95%+）</td>
      </tr>
      <tr>
          <td><strong>MATH</strong></td>
          <td>高中 / 競賽數學</td>
          <td>自由作答</td>
          <td>訓練污染、reasoning model 表現遠超 instruct</td>
      </tr>
      <tr>
          <td><strong>HumanEval</strong></td>
          <td>Python function 補完</td>
          <td>寫一個 function 通過 unit test</td>
          <td>飽和、僅覆蓋初級 coding</td>
      </tr>
      <tr>
          <td><strong>MBPP</strong></td>
          <td>Python coding 任務</td>
          <td>同上、規模較大</td>
          <td>同 HumanEval</td>
      </tr>
      <tr>
          <td><a href="/blog/llm/knowledge-cards/swe-bench/" data-link-title="SWE-bench" data-link-desc="用真實 GitHub issue 量化 LLM coding 能力的 benchmark"><strong>SWE-bench</strong></a></td>
          <td>真實 GitHub issue 修復</td>
          <td>給 repo + issue、生 patch、跑 test</td>
          <td>仍是 LLM 主要 coding 差距、不易飽和</td>
      </tr>
      <tr>
          <td><strong>MT-Bench</strong></td>
          <td>多輪對話品質</td>
          <td>80 題 prompt、LLM-as-judge 評分</td>
          <td>LLM-as-judge bias、judge 模型本身能力影響評分</td>
      </tr>
      <tr>
          <td><strong>Chatbot Arena</strong></td>
          <td>開放對話偏好（眾人投票）</td>
          <td>A/B 對戰、Elo 排名</td>
          <td>文化偏好、prompt 設計影響</td>
      </tr>
      <tr>
          <td><strong>HELM</strong></td>
          <td>多 dimension comprehensive</td>
          <td>22 scenarios × 多 metrics</td>
          <td>計算昂貴、不易追蹤每代新模型</td>
      </tr>
      <tr>
          <td><strong>AlpacaEval</strong></td>
          <td>指令跟隨能力</td>
          <td>LLM-as-judge 對比 GPT-4</td>
          <td>Judge bias、易被「verbose」攻擊</td>
      </tr>
      <tr>
          <td><strong>RULER</strong></td>
          <td>Long context 真實任務</td>
          <td>Multi-needle、aggregation、reasoning</td>
          <td>較新、覆蓋仍在演化</td>
      </tr>
  </tbody>
</table>
<blockquote>
<p><strong>事實查核註</strong>：各 benchmark 的飽和狀態、前沿模型 score 持續變動、上述為 2026/5 主流觀察。引用前以 <a href="https://paperswithcode.com/">Papers with Code</a> 或 <a href="https://huggingface.co/spaces/HuggingFaceH4/open_llm_leaderboard">HuggingFace Open LLM Leaderboard</a> 當前狀態為準。</p></blockquote>
<h2 id="benchmark-的常見陷阱">Benchmark 的常見陷阱</h2>
<ol>
<li><strong>訓練資料污染（Contamination）</strong>：benchmark 題目本身在 pretrain corpus 出現過、模型「記得」答案、看似強實際是 memorization</li>
<li><strong>飽和（Saturation）</strong>：前沿模型 score 接近上限、無法區分模型品質差距（HumanEval 80%→95% 看似進步、實際 5% 多半是 lucky 而非實質提升）</li>
<li><strong>LLM-as-judge bias</strong>：用 LLM（如 GPT-4）評其他 LLM、judge 的偏好（如「冗長 = 好」）會 bias 評分</li>
<li><strong>Single-task overfitting</strong>：模型廠商針對 benchmark 特別 fine-tune、benchmark 高分但通用能力沒提升</li>
<li><strong>Prompt sensitivity</strong>：同個 benchmark 用不同 prompt format、score 差幾個百分點</li>
</ol>
<h2 id="設計責任">設計責任</h2>
<p>讀 model card / paper 看到 benchmark 數字、判讀框架：</p>
<ol>
<li><strong>看 multiple benchmarks、不只一個</strong>：如挑 coding 模型、看 HumanEval + MBPP + SWE-bench、不只看 HumanEval</li>
<li><strong>跟自己任務對齊的 benchmark 才重要</strong>：你做 RAG 應用、看 retrieval benchmark；你做 chat、看 MT-Bench / Arena</li>
<li><strong>看「相對」、不只看「絕對」</strong>：「Model A 在 MMLU 比 Model B 高 2%」可能 noise；「A 比 B 高 10%」更可信</li>
<li><strong>In-house benchmark 是最後檢驗</strong>：自己的真實工作流案例 &gt; 任何公開 benchmark</li>
</ol>
]]></content:encoded></item><item><title>LLM-as-Judge</title><link>https://tarrragon.github.io/blog/llm/knowledge-cards/llm-as-judge/</link><pubDate>Tue, 12 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/llm/knowledge-cards/llm-as-judge/</guid><description>&lt;p>LLM-as-Judge 的核心概念是「&lt;strong>用一個 LLM（judge）對另一個 LLM（test subject）的輸出做品質評估&lt;/strong>」。給 judge 一個 rubric（評分標準）跟 (input, output) pair、judge 輸出分數或 pairwise 偏好。是 production LLM eval 的主流方法（500-5000× 比 human eval 便宜、80%+ 跟人類同意度）、但有 bias 要處理（position / verbosity / self-preference）。&lt;/p>
&lt;h2 id="概念位置">概念位置&lt;/h2>
&lt;p>跟其他 eval 路徑的對比：&lt;/p>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>Eval 路徑&lt;/th>
 &lt;th>成本&lt;/th>
 &lt;th>速度&lt;/th>
 &lt;th>適合&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>Standard &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/llm-benchmarks/" data-link-title="LLM Benchmarks（MMLU / HumanEval / SWE-bench 等）" data-link-desc="LLM 能力評估的標準 benchmark 集合：MMLU / HumanEval / MBPP / SWE-bench / MT-Bench 等的覆蓋範圍與失效情境">benchmark&lt;/a>（MMLU / SWE-bench 等）&lt;/td>
 &lt;td>中&lt;/td>
 &lt;td>慢（一次 run 數小時）&lt;/td>
 &lt;td>通用能力比較&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Human eval&lt;/td>
 &lt;td>極高（每筆 $1-10）&lt;/td>
 &lt;td>慢&lt;/td>
 &lt;td>黃金標準、final QA&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>LLM-as-Judge（本卡）&lt;/strong>&lt;/td>
 &lt;td>低（每筆 $0.001-0.01）&lt;/td>
 &lt;td>快&lt;/td>
 &lt;td>Production loop eval、自己應用 in-house&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Rule-based / regex&lt;/td>
 &lt;td>極低&lt;/td>
 &lt;td>即時&lt;/td>
 &lt;td>明確 binary（如格式對不對）&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;p>主要 use case：&lt;/p>
&lt;ol>
&lt;li>&lt;strong>In-house benchmark&lt;/strong>：自己工作流的真實案例、自寫 rubric、judge 評&lt;/li>
&lt;li>&lt;strong>Production trace eval&lt;/strong>：用 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/llm-tracing/" data-link-title="LLM Tracing" data-link-desc="把 LLM 應用的每次 LLM call / tool call / memory op 編成結構化 span、用 OpenTelemetry GenAI semantic conventions 標準化">LLM tracing&lt;/a> 蒐集的 production trace、定期 judge 跑、抓品質回歸&lt;/li>
&lt;li>&lt;strong>A/B test&lt;/strong>：兩個 prompt / model 變體、judge 做 pairwise 比較&lt;/li>
&lt;li>&lt;strong>Synthetic data quality&lt;/strong>：用大模型生 fine-tune 資料、judge 過濾低品質&lt;/li>
&lt;/ol>
&lt;h2 id="設計責任">設計責任&lt;/h2>
&lt;p>讀 eval framework / production AI app 看到「LLM as judge」「pairwise eval」「LLM evaluator」就是這 framing。寫 code 場景的判讀：&lt;/p>
&lt;ol>
&lt;li>&lt;strong>Judge 模型選擇&lt;/strong>：強模型當 judge（GPT-5 / Claude 4 / Gemini 旗艦）、reasoning model 更穩；judge 跟被測同家可能有 self-preference bias&lt;/li>
&lt;li>&lt;strong>三大 bias 緩解&lt;/strong>：
&lt;ul>
&lt;li>&lt;strong>Position bias&lt;/strong>：A/B pairwise 換位置跑 2 次取一致 vote&lt;/li>
&lt;li>&lt;strong>Verbosity bias&lt;/strong>：rubric 加「冗長不加分」明確指示、或長度 normalize&lt;/li>
&lt;li>&lt;strong>Self-preference bias&lt;/strong>：用 3 個不同 judge model 取多數&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>&lt;strong>跟 &lt;a href="https://tarrragon.github.io/blog/llm/04-applications/llm-as-judge/" data-link-title="4.21 LLM-as-Judge 評估方法" data-link-desc="LLM 評估 LLM 的 production eval 方法：rubric design、pairwise / direct scoring、三大 bias 緩解、跟 trace 串接的閉環、calibration">4.21 LLM-as-judge 章節&lt;/a> 的關係&lt;/strong>：本卡是定義、章節是工程實務（rubric design、bias 緩解、calibration、trace 串接）&lt;/li>
&lt;li>&lt;strong>不是萬靈丹&lt;/strong>：高 stake 任務（醫療、法律、安全）仍需 human eval；judge 的天花板 = judge 模型本身的能力&lt;/li>
&lt;/ol></description><content:encoded><![CDATA[<p>LLM-as-Judge 的核心概念是「<strong>用一個 LLM（judge）對另一個 LLM（test subject）的輸出做品質評估</strong>」。給 judge 一個 rubric（評分標準）跟 (input, output) pair、judge 輸出分數或 pairwise 偏好。是 production LLM eval 的主流方法（500-5000× 比 human eval 便宜、80%+ 跟人類同意度）、但有 bias 要處理（position / verbosity / self-preference）。</p>
<h2 id="概念位置">概念位置</h2>
<p>跟其他 eval 路徑的對比：</p>
<table>
  <thead>
      <tr>
          <th>Eval 路徑</th>
          <th>成本</th>
          <th>速度</th>
          <th>適合</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Standard <a href="/blog/llm/knowledge-cards/llm-benchmarks/" data-link-title="LLM Benchmarks（MMLU / HumanEval / SWE-bench 等）" data-link-desc="LLM 能力評估的標準 benchmark 集合：MMLU / HumanEval / MBPP / SWE-bench / MT-Bench 等的覆蓋範圍與失效情境">benchmark</a>（MMLU / SWE-bench 等）</td>
          <td>中</td>
          <td>慢（一次 run 數小時）</td>
          <td>通用能力比較</td>
      </tr>
      <tr>
          <td>Human eval</td>
          <td>極高（每筆 $1-10）</td>
          <td>慢</td>
          <td>黃金標準、final QA</td>
      </tr>
      <tr>
          <td><strong>LLM-as-Judge（本卡）</strong></td>
          <td>低（每筆 $0.001-0.01）</td>
          <td>快</td>
          <td>Production loop eval、自己應用 in-house</td>
      </tr>
      <tr>
          <td>Rule-based / regex</td>
          <td>極低</td>
          <td>即時</td>
          <td>明確 binary（如格式對不對）</td>
      </tr>
  </tbody>
</table>
<p>主要 use case：</p>
<ol>
<li><strong>In-house benchmark</strong>：自己工作流的真實案例、自寫 rubric、judge 評</li>
<li><strong>Production trace eval</strong>：用 <a href="/blog/llm/knowledge-cards/llm-tracing/" data-link-title="LLM Tracing" data-link-desc="把 LLM 應用的每次 LLM call / tool call / memory op 編成結構化 span、用 OpenTelemetry GenAI semantic conventions 標準化">LLM tracing</a> 蒐集的 production trace、定期 judge 跑、抓品質回歸</li>
<li><strong>A/B test</strong>：兩個 prompt / model 變體、judge 做 pairwise 比較</li>
<li><strong>Synthetic data quality</strong>：用大模型生 fine-tune 資料、judge 過濾低品質</li>
</ol>
<h2 id="設計責任">設計責任</h2>
<p>讀 eval framework / production AI app 看到「LLM as judge」「pairwise eval」「LLM evaluator」就是這 framing。寫 code 場景的判讀：</p>
<ol>
<li><strong>Judge 模型選擇</strong>：強模型當 judge（GPT-5 / Claude 4 / Gemini 旗艦）、reasoning model 更穩；judge 跟被測同家可能有 self-preference bias</li>
<li><strong>三大 bias 緩解</strong>：
<ul>
<li><strong>Position bias</strong>：A/B pairwise 換位置跑 2 次取一致 vote</li>
<li><strong>Verbosity bias</strong>：rubric 加「冗長不加分」明確指示、或長度 normalize</li>
<li><strong>Self-preference bias</strong>：用 3 個不同 judge model 取多數</li>
</ul>
</li>
<li><strong>跟 <a href="/blog/llm/04-applications/llm-as-judge/" data-link-title="4.21 LLM-as-Judge 評估方法" data-link-desc="LLM 評估 LLM 的 production eval 方法：rubric design、pairwise / direct scoring、三大 bias 緩解、跟 trace 串接的閉環、calibration">4.21 LLM-as-judge 章節</a> 的關係</strong>：本卡是定義、章節是工程實務（rubric design、bias 緩解、calibration、trace 串接）</li>
<li><strong>不是萬靈丹</strong>：高 stake 任務（醫療、法律、安全）仍需 human eval；judge 的天花板 = judge 模型本身的能力</li>
</ol>
]]></content:encoded></item><item><title>Lost in the Middle</title><link>https://tarrragon.github.io/blog/llm/knowledge-cards/lost-in-the-middle/</link><pubDate>Tue, 12 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/llm/knowledge-cards/lost-in-the-middle/</guid><description>&lt;p>Lost in the middle（中段遺失、Liu et al., 2023）的核心概念是「&lt;strong>LLM 對 long context 中段內容的 attention / recall 顯著低於開頭與結尾&lt;/strong>」。實測：把答案放在 10K context 的開頭或結尾、模型 recall 準確率 80%+；放在中段 4000-6000 token 位置、recall 掉到 50% 甚至更低。是 long context 使用上最常見的失敗模式。&lt;/p>
&lt;h2 id="概念位置">概念位置&lt;/h2>
&lt;p>Long context 的 effective context 跟 claimed context 落差來自三個現象：&lt;/p>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>現象&lt;/th>
 &lt;th>描述&lt;/th>
 &lt;th>嚴重度&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>Lost in the middle&lt;/td>
 &lt;td>中段內容 attention 顯著低、recall 掉&lt;/td>
 &lt;td>普遍、最頻繁&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Context degradation&lt;/td>
 &lt;td>接近 context 上限時、整體品質緩降&lt;/td>
 &lt;td>接近上限才明顯&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Needle in haystack&lt;/td>
 &lt;td>抓單一事實的能力（vs lost-in-the-middle 抓整段邏輯）&lt;/td>
 &lt;td>兩條軸、不完全重疊&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>





&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-text" data-lang="text">&lt;span class="line">&lt;span class="ln"> 1&lt;/span>&lt;span class="cl">Recall accuracy vs 答案位置（典型 10K context）：
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 2&lt;/span>&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 3&lt;/span>&lt;span class="cl">100% |█ █
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 4&lt;/span>&lt;span class="cl"> |██ ██
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 5&lt;/span>&lt;span class="cl"> 80% |███ ███
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 6&lt;/span>&lt;span class="cl"> |███ ███
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 7&lt;/span>&lt;span class="cl"> 60% |███ ____ ███
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 8&lt;/span>&lt;span class="cl"> |███ ___/ \___ ███
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 9&lt;/span>&lt;span class="cl"> 40% |███ _/ \_ ███
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">10&lt;/span>&lt;span class="cl"> |█████─/ \───── ███
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">11&lt;/span>&lt;span class="cl"> |
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">12&lt;/span>&lt;span class="cl"> 0 2K 4K 6K 8K 10K
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">13&lt;/span>&lt;span class="cl"> 開頭 結尾&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>成因：&lt;/p>
&lt;ol>
&lt;li>&lt;strong>Attention weight 分佈不均勻&lt;/strong>：訓練資料中、句首 / 段首通常含關鍵資訊、模型學會偏重句首；長 context 的中段在訓練資料中相對稀疏、attention 沒學好&lt;/li>
&lt;li>&lt;strong>Positional encoding 設計&lt;/strong>：RoPE / ALiBi 等對長距離 attention 的衰減模式、中段 token 跟 query 距離通常較大、attention 弱&lt;/li>
&lt;li>&lt;strong>訓練 context 長度的影響&lt;/strong>：模型若訓練在 8K context、推論時用 128K（用 RoPE scaling 延伸）、中段表現比訓練範圍內差更多&lt;/li>
&lt;/ol>
&lt;h2 id="設計責任">設計責任&lt;/h2>
&lt;p>讀 long-context paper / benchmark 看到「lost-in-the-middle」「U-shape recall」就是這現象。寫 code 場景的判讀：&lt;/p>
&lt;ol>
&lt;li>&lt;strong>把關鍵資訊放開頭或結尾&lt;/strong>：system prompt 在開頭、最新指示在結尾（剛好是模型 attention 最強的兩處）&lt;/li>
&lt;li>&lt;strong>長 context 不是「塞越多越好」&lt;/strong>：超過 effective context（典型 8-16K）後、邊際效用急降&lt;/li>
&lt;li>&lt;strong>RAG 比 long context 仍有價值&lt;/strong>：把相關片段 retrieve 出來放 prompt 開頭、比把整份文件塞進 100K context 效果更穩定&lt;/li>
&lt;li>&lt;strong>驗證自己模型的 effective context&lt;/strong>：用 needle-in-haystack 或自製測試、看模型在 8K / 16K / 32K 表現掉到哪&lt;/li>
&lt;li>&lt;strong>Reasoning model 的 thinking trace 不會遇到這事故嗎？&lt;/strong> — 仍會遇到、但 reasoning 過程會主動重新引用前文、部分緩解；不過 thinking trace 本身會擠壓 context budget、可能反而觸發 degradation&lt;/li>
&lt;/ol></description><content:encoded><![CDATA[<p>Lost in the middle（中段遺失、Liu et al., 2023）的核心概念是「<strong>LLM 對 long context 中段內容的 attention / recall 顯著低於開頭與結尾</strong>」。實測：把答案放在 10K context 的開頭或結尾、模型 recall 準確率 80%+；放在中段 4000-6000 token 位置、recall 掉到 50% 甚至更低。是 long context 使用上最常見的失敗模式。</p>
<h2 id="概念位置">概念位置</h2>
<p>Long context 的 effective context 跟 claimed context 落差來自三個現象：</p>
<table>
  <thead>
      <tr>
          <th>現象</th>
          <th>描述</th>
          <th>嚴重度</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Lost in the middle</td>
          <td>中段內容 attention 顯著低、recall 掉</td>
          <td>普遍、最頻繁</td>
      </tr>
      <tr>
          <td>Context degradation</td>
          <td>接近 context 上限時、整體品質緩降</td>
          <td>接近上限才明顯</td>
      </tr>
      <tr>
          <td>Needle in haystack</td>
          <td>抓單一事實的能力（vs lost-in-the-middle 抓整段邏輯）</td>
          <td>兩條軸、不完全重疊</td>
      </tr>
  </tbody>
</table>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="ln"> 1</span><span class="cl">Recall accuracy vs 答案位置（典型 10K context）：
</span></span><span class="line"><span class="ln"> 2</span><span class="cl">
</span></span><span class="line"><span class="ln"> 3</span><span class="cl">100% |█                                       █
</span></span><span class="line"><span class="ln"> 4</span><span class="cl">     |██                                     ██
</span></span><span class="line"><span class="ln"> 5</span><span class="cl"> 80% |███                                   ███
</span></span><span class="line"><span class="ln"> 6</span><span class="cl">     |███                                   ███
</span></span><span class="line"><span class="ln"> 7</span><span class="cl"> 60% |███          ____                     ███
</span></span><span class="line"><span class="ln"> 8</span><span class="cl">     |███      ___/    \___                 ███
</span></span><span class="line"><span class="ln"> 9</span><span class="cl"> 40% |███    _/            \_               ███
</span></span><span class="line"><span class="ln">10</span><span class="cl">     |█████─/                \─────         ███
</span></span><span class="line"><span class="ln">11</span><span class="cl">     |
</span></span><span class="line"><span class="ln">12</span><span class="cl">       0      2K     4K     6K     8K    10K
</span></span><span class="line"><span class="ln">13</span><span class="cl">       開頭                              結尾</span></span></code></pre></div><p>成因：</p>
<ol>
<li><strong>Attention weight 分佈不均勻</strong>：訓練資料中、句首 / 段首通常含關鍵資訊、模型學會偏重句首；長 context 的中段在訓練資料中相對稀疏、attention 沒學好</li>
<li><strong>Positional encoding 設計</strong>：RoPE / ALiBi 等對長距離 attention 的衰減模式、中段 token 跟 query 距離通常較大、attention 弱</li>
<li><strong>訓練 context 長度的影響</strong>：模型若訓練在 8K context、推論時用 128K（用 RoPE scaling 延伸）、中段表現比訓練範圍內差更多</li>
</ol>
<h2 id="設計責任">設計責任</h2>
<p>讀 long-context paper / benchmark 看到「lost-in-the-middle」「U-shape recall」就是這現象。寫 code 場景的判讀：</p>
<ol>
<li><strong>把關鍵資訊放開頭或結尾</strong>：system prompt 在開頭、最新指示在結尾（剛好是模型 attention 最強的兩處）</li>
<li><strong>長 context 不是「塞越多越好」</strong>：超過 effective context（典型 8-16K）後、邊際效用急降</li>
<li><strong>RAG 比 long context 仍有價值</strong>：把相關片段 retrieve 出來放 prompt 開頭、比把整份文件塞進 100K context 效果更穩定</li>
<li><strong>驗證自己模型的 effective context</strong>：用 needle-in-haystack 或自製測試、看模型在 8K / 16K / 32K 表現掉到哪</li>
<li><strong>Reasoning model 的 thinking trace 不會遇到這事故嗎？</strong> — 仍會遇到、但 reasoning 過程會主動重新引用前文、部分緩解；不過 thinking trace 本身會擠壓 context budget、可能反而觸發 degradation</li>
</ol>
]]></content:encoded></item><item><title>MTEB</title><link>https://tarrragon.github.io/blog/llm/knowledge-cards/mteb-benchmark/</link><pubDate>Tue, 12 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/llm/knowledge-cards/mteb-benchmark/</guid><description>&lt;p>MTEB（Massive Text Embedding Benchmark、Muennighoff et al., 2022）的核心概念是「&lt;strong>評估 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/embedding-model/" data-link-title="Embedding Model" data-link-desc="把文字轉成向量的模型：用於 codebase 索引與語意搜尋">embedding model&lt;/a> 跨多種任務通用能力的標準 benchmark&lt;/strong>」。覆蓋 8 大類任務（classification、clustering、pair classification、reranking、retrieval、STS、summarization、bitext mining）、56 個 dataset、112 種語言。是現在挑選 embedding model 最常用的 leaderboard。&lt;/p>
&lt;h2 id="概念位置">概念位置&lt;/h2>
&lt;p>MTEB 的 8 大任務類別：&lt;/p>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>類別&lt;/th>
 &lt;th>任務本質&lt;/th>
 &lt;th>衡量&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>Classification&lt;/td>
 &lt;td>用 embedding 做下游分類（如情感分析）&lt;/td>
 &lt;td>分類 accuracy&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Clustering&lt;/td>
 &lt;td>把相似 doc 聚到一起&lt;/td>
 &lt;td>V-measure、NMI&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Pair classification&lt;/td>
 &lt;td>判斷兩段文字「相關 / 不相關」&lt;/td>
 &lt;td>F1、AP&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Reranking&lt;/strong>&lt;/td>
 &lt;td>對 retrieval 結果用 embedding 重新排序&lt;/td>
 &lt;td>mAP、MRR&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Retrieval&lt;/strong>&lt;/td>
 &lt;td>給 query、從大量 corpus 找相關 doc&lt;/td>
 &lt;td>nDCG@10、&lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/retrieval-recall/" data-link-title="Retrieval Recall" data-link-desc="衡量 RAG 檢索是否把應該命中的文件或 chunk 放進 top-k 結果，是 component-level eval 的核心指標">Recall@k&lt;/a>&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>STS（Semantic Textual Similarity）&lt;/td>
 &lt;td>預測句對相似度（連續分數）&lt;/td>
 &lt;td>Spearman correlation&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Summarization&lt;/td>
 &lt;td>embedding-based summary quality&lt;/td>
 &lt;td>Correlation with human rating&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Bitext mining&lt;/td>
 &lt;td>跨語言找翻譯對&lt;/td>
 &lt;td>F1&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;p>&lt;strong>對寫 code / RAG 場景最相關&lt;/strong>：Retrieval、Reranking 兩類（粗體）。其他類別反映通用能力、但不直接影響 RAG 應用品質。&lt;/p>
&lt;p>主流 embedding model 在 MTEB Retrieval 的代表性能（2026/5 估計、會持續變動）：&lt;/p>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>模型&lt;/th>
 &lt;th>模型大小&lt;/th>
 &lt;th>MTEB Retrieval avg&lt;/th>
 &lt;th>適合場景&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>BAAI/bge-large-en-v1.5&lt;/td>
 &lt;td>~335M&lt;/td>
 &lt;td>~55&lt;/td>
 &lt;td>開源通用、英文 retrieval 主力&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>nomic-embed-text-v1.5&lt;/td>
 &lt;td>~137M&lt;/td>
 &lt;td>~52&lt;/td>
 &lt;td>開源、小巧、Ollama 內建&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>jina-embeddings-v3&lt;/td>
 &lt;td>~570M&lt;/td>
 &lt;td>~58&lt;/td>
 &lt;td>開源、多語、code 友善&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>mxbai-embed-large-v1&lt;/td>
 &lt;td>~335M&lt;/td>
 &lt;td>~55&lt;/td>
 &lt;td>開源通用&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>OpenAI text-embedding-3-large&lt;/td>
 &lt;td>API only&lt;/td>
 &lt;td>~64&lt;/td>
 &lt;td>雲端旗艦&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>voyage-3&lt;/td>
 &lt;td>API only&lt;/td>
 &lt;td>~62&lt;/td>
 &lt;td>雲端、Anthropic 推薦&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;blockquote>
&lt;p>&lt;strong>事實查核註&lt;/strong>：MTEB 數字依模型版本、評估配置變動、上述為 2026/5 大致排名、引用前以 &lt;a href="https://huggingface.co/spaces/mteb/leaderboard">MTEB Leaderboard&lt;/a> 當前狀態為準。&lt;/p>&lt;/blockquote>
&lt;h2 id="設計責任">設計責任&lt;/h2>
&lt;p>讀 embedding model 比較看到「MTEB score」就是這 benchmark。寫 code / RAG 場景的判讀：&lt;/p>
&lt;ol>
&lt;li>&lt;strong>看 Retrieval 子分數、不是 overall&lt;/strong>：MTEB overall 含 8 類、跟 RAG 場景關係最大的是 Retrieval 子分；通用 retrieval 分數高、reranking 分數高、就值得試&lt;/li>
&lt;li>&lt;strong>跟自己 domain 對齊&lt;/strong>：MTEB 多為通用語料、自己 domain（如 code、medical、legal）可能跟 MTEB 落差大；in-domain benchmark 比 MTEB 更重要&lt;/li>
&lt;li>&lt;strong>大小 / 速度 / 品質 trade-off&lt;/strong>：bge-large（335M）vs nomic-embed（137M）、後者跑得快、適合本地 RAG；前者品質略高、適合雲端或 latency 不敏感場景&lt;/li>
&lt;li>&lt;strong>MTEB 高分不代表「適合你」&lt;/strong>：高分模型可能是 instruction-tuned embedding（query 需要加特定前綴）、用法跟簡單模型不同、要看 model card&lt;/li>
&lt;/ol></description><content:encoded><![CDATA[<p>MTEB（Massive Text Embedding Benchmark、Muennighoff et al., 2022）的核心概念是「<strong>評估 <a href="/blog/llm/knowledge-cards/embedding-model/" data-link-title="Embedding Model" data-link-desc="把文字轉成向量的模型：用於 codebase 索引與語意搜尋">embedding model</a> 跨多種任務通用能力的標準 benchmark</strong>」。覆蓋 8 大類任務（classification、clustering、pair classification、reranking、retrieval、STS、summarization、bitext mining）、56 個 dataset、112 種語言。是現在挑選 embedding model 最常用的 leaderboard。</p>
<h2 id="概念位置">概念位置</h2>
<p>MTEB 的 8 大任務類別：</p>
<table>
  <thead>
      <tr>
          <th>類別</th>
          <th>任務本質</th>
          <th>衡量</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Classification</td>
          <td>用 embedding 做下游分類（如情感分析）</td>
          <td>分類 accuracy</td>
      </tr>
      <tr>
          <td>Clustering</td>
          <td>把相似 doc 聚到一起</td>
          <td>V-measure、NMI</td>
      </tr>
      <tr>
          <td>Pair classification</td>
          <td>判斷兩段文字「相關 / 不相關」</td>
          <td>F1、AP</td>
      </tr>
      <tr>
          <td><strong>Reranking</strong></td>
          <td>對 retrieval 結果用 embedding 重新排序</td>
          <td>mAP、MRR</td>
      </tr>
      <tr>
          <td><strong>Retrieval</strong></td>
          <td>給 query、從大量 corpus 找相關 doc</td>
          <td>nDCG@10、<a href="/blog/llm/knowledge-cards/retrieval-recall/" data-link-title="Retrieval Recall" data-link-desc="衡量 RAG 檢索是否把應該命中的文件或 chunk 放進 top-k 結果，是 component-level eval 的核心指標">Recall@k</a></td>
      </tr>
      <tr>
          <td>STS（Semantic Textual Similarity）</td>
          <td>預測句對相似度（連續分數）</td>
          <td>Spearman correlation</td>
      </tr>
      <tr>
          <td>Summarization</td>
          <td>embedding-based summary quality</td>
          <td>Correlation with human rating</td>
      </tr>
      <tr>
          <td>Bitext mining</td>
          <td>跨語言找翻譯對</td>
          <td>F1</td>
      </tr>
  </tbody>
</table>
<p><strong>對寫 code / RAG 場景最相關</strong>：Retrieval、Reranking 兩類（粗體）。其他類別反映通用能力、但不直接影響 RAG 應用品質。</p>
<p>主流 embedding model 在 MTEB Retrieval 的代表性能（2026/5 估計、會持續變動）：</p>
<table>
  <thead>
      <tr>
          <th>模型</th>
          <th>模型大小</th>
          <th>MTEB Retrieval avg</th>
          <th>適合場景</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>BAAI/bge-large-en-v1.5</td>
          <td>~335M</td>
          <td>~55</td>
          <td>開源通用、英文 retrieval 主力</td>
      </tr>
      <tr>
          <td>nomic-embed-text-v1.5</td>
          <td>~137M</td>
          <td>~52</td>
          <td>開源、小巧、Ollama 內建</td>
      </tr>
      <tr>
          <td>jina-embeddings-v3</td>
          <td>~570M</td>
          <td>~58</td>
          <td>開源、多語、code 友善</td>
      </tr>
      <tr>
          <td>mxbai-embed-large-v1</td>
          <td>~335M</td>
          <td>~55</td>
          <td>開源通用</td>
      </tr>
      <tr>
          <td>OpenAI text-embedding-3-large</td>
          <td>API only</td>
          <td>~64</td>
          <td>雲端旗艦</td>
      </tr>
      <tr>
          <td>voyage-3</td>
          <td>API only</td>
          <td>~62</td>
          <td>雲端、Anthropic 推薦</td>
      </tr>
  </tbody>
</table>
<blockquote>
<p><strong>事實查核註</strong>：MTEB 數字依模型版本、評估配置變動、上述為 2026/5 大致排名、引用前以 <a href="https://huggingface.co/spaces/mteb/leaderboard">MTEB Leaderboard</a> 當前狀態為準。</p></blockquote>
<h2 id="設計責任">設計責任</h2>
<p>讀 embedding model 比較看到「MTEB score」就是這 benchmark。寫 code / RAG 場景的判讀：</p>
<ol>
<li><strong>看 Retrieval 子分數、不是 overall</strong>：MTEB overall 含 8 類、跟 RAG 場景關係最大的是 Retrieval 子分；通用 retrieval 分數高、reranking 分數高、就值得試</li>
<li><strong>跟自己 domain 對齊</strong>：MTEB 多為通用語料、自己 domain（如 code、medical、legal）可能跟 MTEB 落差大；in-domain benchmark 比 MTEB 更重要</li>
<li><strong>大小 / 速度 / 品質 trade-off</strong>：bge-large（335M）vs nomic-embed（137M）、後者跑得快、適合本地 RAG；前者品質略高、適合雲端或 latency 不敏感場景</li>
<li><strong>MTEB 高分不代表「適合你」</strong>：高分模型可能是 instruction-tuned embedding（query 需要加特定前綴）、用法跟簡單模型不同、要看 model card</li>
</ol>
]]></content:encoded></item><item><title>Needle in a Haystack</title><link>https://tarrragon.github.io/blog/llm/knowledge-cards/needle-in-haystack/</link><pubDate>Tue, 12 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/llm/knowledge-cards/needle-in-haystack/</guid><description>&lt;p>Needle in a Haystack（NIH、大海撈針、Greg Kamradt 2023）的核心概念是「&lt;strong>把一個明確事實（needle）插入長度可變的 context（haystack）的不同位置、測試 LLM 能否在問問題時準確 recall 該事實&lt;/strong>」。是評估 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/context-window/" data-link-title="Context Window" data-link-desc="模型一次能處理的最大 token 數量：prompt 加生成的總和上限">long context&lt;/a> 模型實用性的標準 benchmark 之一、跟 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/lost-in-the-middle/" data-link-title="Lost in the Middle" data-link-desc="LLM 對 long context 中段內容的 attention / recall 顯著低於開頭與結尾的現象">lost-in-the-middle&lt;/a> 對應但側重不同。&lt;/p>
&lt;h2 id="概念位置">概念位置&lt;/h2>
&lt;p>NIH 測試的典型流程：&lt;/p>





&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-text" data-lang="text">&lt;span class="line">&lt;span class="ln"> 1&lt;/span>&lt;span class="cl">1. 準備 haystack：一份長文（如 Paul Graham essays、技術文件）
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 2&lt;/span>&lt;span class="cl">2. 在指定位置（如 50% 處）插入 needle：
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 3&lt;/span>&lt;span class="cl"> 「The best thing to do in San Francisco is eat a sandwich at Dolores Park.」
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 4&lt;/span>&lt;span class="cl">3. Prompt 模型：「What is the best thing to do in San Francisco?」
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 5&lt;/span>&lt;span class="cl">4. 看模型能否抓出 needle 內容
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 6&lt;/span>&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 7&lt;/span>&lt;span class="cl">Variables：
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 8&lt;/span>&lt;span class="cl">- Context 總長度（1K、4K、16K、64K、128K、1M）
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 9&lt;/span>&lt;span class="cl">- Needle 插入位置（0%、10%、25%、50%、75%、90%、100%）
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">10&lt;/span>&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">11&lt;/span>&lt;span class="cl">每個 (length, position) 組合測 N 次、得到 accuracy heatmap&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>跟 lost-in-the-middle 的對比：&lt;/p>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>維度&lt;/th>
 &lt;th>Lost in the middle&lt;/th>
 &lt;th>Needle in haystack&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>衡量的能力&lt;/td>
 &lt;td>對中段內容的整體 attention&lt;/td>
 &lt;td>抓單一事實的 recall&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>任務&lt;/td>
 &lt;td>抓整段邏輯、做推論&lt;/td>
 &lt;td>純 retrieve、不需推論&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>難度&lt;/td>
 &lt;td>高（需理解整段語意）&lt;/td>
 &lt;td>較低（明確 keyword 匹配）&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>模型表現&lt;/td>
 &lt;td>中段顯著差&lt;/td>
 &lt;td>通常各位置都接近 100%（強模型）&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>判讀意義&lt;/td>
 &lt;td>反映「實用 effective context」&lt;/td>
 &lt;td>反映「lower bound effective context」&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>





&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-text" data-lang="text">&lt;span class="line">&lt;span class="ln"> 1&lt;/span>&lt;span class="cl">典型 NIH heatmap（GPT-4 128K 之類）：
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 2&lt;/span>&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 3&lt;/span>&lt;span class="cl">100% |████ ████████████████████████████ ████
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 4&lt;/span>&lt;span class="cl"> 80% |████ ████████████████████████████ ████
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 5&lt;/span>&lt;span class="cl"> 60% |
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 6&lt;/span>&lt;span class="cl"> 40% |
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 7&lt;/span>&lt;span class="cl"> 20% |
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 8&lt;/span>&lt;span class="cl"> 0 +----+----+----+----+----+----+----+
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 9&lt;/span>&lt;span class="cl"> 0% 25% 50% 75% 100%（needle 位置）
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">10&lt;/span>&lt;span class="cl"> ↑ ↑
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">11&lt;/span>&lt;span class="cl"> 開頭強 結尾強
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">12&lt;/span>&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">13&lt;/span>&lt;span class="cl">NIH heatmap 通常全綠（強模型）、但實用任務（reasoning over long context）就會出現中段塌陷&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="設計責任">設計責任&lt;/h2>
&lt;p>讀 long context 模型 release notes 看到「needle in a haystack: 100%」「pass NIH up to 128K」等聲稱、要區分：&lt;/p></description><content:encoded><![CDATA[<p>Needle in a Haystack（NIH、大海撈針、Greg Kamradt 2023）的核心概念是「<strong>把一個明確事實（needle）插入長度可變的 context（haystack）的不同位置、測試 LLM 能否在問問題時準確 recall 該事實</strong>」。是評估 <a href="/blog/llm/knowledge-cards/context-window/" data-link-title="Context Window" data-link-desc="模型一次能處理的最大 token 數量：prompt 加生成的總和上限">long context</a> 模型實用性的標準 benchmark 之一、跟 <a href="/blog/llm/knowledge-cards/lost-in-the-middle/" data-link-title="Lost in the Middle" data-link-desc="LLM 對 long context 中段內容的 attention / recall 顯著低於開頭與結尾的現象">lost-in-the-middle</a> 對應但側重不同。</p>
<h2 id="概念位置">概念位置</h2>
<p>NIH 測試的典型流程：</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="ln"> 1</span><span class="cl">1. 準備 haystack：一份長文（如 Paul Graham essays、技術文件）
</span></span><span class="line"><span class="ln"> 2</span><span class="cl">2. 在指定位置（如 50% 處）插入 needle：
</span></span><span class="line"><span class="ln"> 3</span><span class="cl">   「The best thing to do in San Francisco is eat a sandwich at Dolores Park.」
</span></span><span class="line"><span class="ln"> 4</span><span class="cl">3. Prompt 模型：「What is the best thing to do in San Francisco?」
</span></span><span class="line"><span class="ln"> 5</span><span class="cl">4. 看模型能否抓出 needle 內容
</span></span><span class="line"><span class="ln"> 6</span><span class="cl">
</span></span><span class="line"><span class="ln"> 7</span><span class="cl">Variables：
</span></span><span class="line"><span class="ln"> 8</span><span class="cl">- Context 總長度（1K、4K、16K、64K、128K、1M）
</span></span><span class="line"><span class="ln"> 9</span><span class="cl">- Needle 插入位置（0%、10%、25%、50%、75%、90%、100%）
</span></span><span class="line"><span class="ln">10</span><span class="cl">
</span></span><span class="line"><span class="ln">11</span><span class="cl">每個 (length, position) 組合測 N 次、得到 accuracy heatmap</span></span></code></pre></div><p>跟 lost-in-the-middle 的對比：</p>
<table>
  <thead>
      <tr>
          <th>維度</th>
          <th>Lost in the middle</th>
          <th>Needle in haystack</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>衡量的能力</td>
          <td>對中段內容的整體 attention</td>
          <td>抓單一事實的 recall</td>
      </tr>
      <tr>
          <td>任務</td>
          <td>抓整段邏輯、做推論</td>
          <td>純 retrieve、不需推論</td>
      </tr>
      <tr>
          <td>難度</td>
          <td>高（需理解整段語意）</td>
          <td>較低（明確 keyword 匹配）</td>
      </tr>
      <tr>
          <td>模型表現</td>
          <td>中段顯著差</td>
          <td>通常各位置都接近 100%（強模型）</td>
      </tr>
      <tr>
          <td>判讀意義</td>
          <td>反映「實用 effective context」</td>
          <td>反映「lower bound effective context」</td>
      </tr>
  </tbody>
</table>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="ln"> 1</span><span class="cl">典型 NIH heatmap（GPT-4 128K 之類）：
</span></span><span class="line"><span class="ln"> 2</span><span class="cl">
</span></span><span class="line"><span class="ln"> 3</span><span class="cl">100% |████ ████████████████████████████ ████
</span></span><span class="line"><span class="ln"> 4</span><span class="cl"> 80% |████ ████████████████████████████ ████
</span></span><span class="line"><span class="ln"> 5</span><span class="cl"> 60% |
</span></span><span class="line"><span class="ln"> 6</span><span class="cl"> 40% |
</span></span><span class="line"><span class="ln"> 7</span><span class="cl"> 20% |
</span></span><span class="line"><span class="ln"> 8</span><span class="cl">   0 +----+----+----+----+----+----+----+
</span></span><span class="line"><span class="ln"> 9</span><span class="cl">     0%   25%   50%   75%   100%（needle 位置）
</span></span><span class="line"><span class="ln">10</span><span class="cl">     ↑                                  ↑
</span></span><span class="line"><span class="ln">11</span><span class="cl">     開頭強                             結尾強
</span></span><span class="line"><span class="ln">12</span><span class="cl">
</span></span><span class="line"><span class="ln">13</span><span class="cl">NIH heatmap 通常全綠（強模型）、但實用任務（reasoning over long context）就會出現中段塌陷</span></span></code></pre></div><h2 id="設計責任">設計責任</h2>
<p>讀 long context 模型 release notes 看到「needle in a haystack: 100%」「pass NIH up to 128K」等聲稱、要區分：</p>
<ol>
<li><strong>NIH 100% 不代表「能用 128K context」</strong>：NIH 只測單一事實 retrieve、實際 reasoning over long context 仍可能崩</li>
<li><strong>真實任務 benchmark</strong>：<a href="https://github.com/THUDM/LongBench">LongBench</a>、<a href="https://github.com/hsiehjackson/RULER">RULER</a> 等是更貼近實用的 long context evaluation、會暴露 lost-in-the-middle 等問題</li>
<li><strong>本地跑 long context 模型</strong>：先用 NIH 驗證 baseline、再用 RULER / 自己工作流 case 測 effective context</li>
<li><strong>判讀「我的模型實際能用幾 K」</strong>：NIH pass 的長度是上限、實用 effective context 通常是 NIH pass 長度的 1/2 到 1/4</li>
</ol>
]]></content:encoded></item><item><title>Perplexity</title><link>https://tarrragon.github.io/blog/llm/knowledge-cards/perplexity/</link><pubDate>Tue, 12 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/llm/knowledge-cards/perplexity/</guid><description>&lt;p>Perplexity（困惑度）的核心概念是「&lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/cross-entropy/" data-link-title="Cross-Entropy" data-link-desc="衡量「預測機率分佈」跟「真實分佈」距離的指標、LLM 預訓練的主要 loss">cross-entropy&lt;/a> 的指數形式」：&lt;code>perplexity = exp(cross-entropy)&lt;/code>。直覺意義是「模型在每個位置平均覺得下個 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/token/" data-link-title="Token" data-link-desc="LLM 處理文字時的最小單位：介於字元與單字之間">token&lt;/a> 有多少種候選」。perplexity = 1 表示模型完美預測；perplexity = vocab_size 表示模型純猜（vocab 上的 uniform 分佈）。&lt;/p>
&lt;h2 id="概念位置">概念位置&lt;/h2>
&lt;p>Perplexity 跟 cross-entropy 的關係：&lt;/p>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>指標&lt;/th>
 &lt;th>公式 / 定義&lt;/th>
 &lt;th>人類直覺&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>Cross-entropy&lt;/td>
 &lt;td>&lt;code>-mean(log p_true)&lt;/code>、底通常是 e&lt;/td>
 &lt;td>loss 數字、訓練拿來最佳化&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Perplexity&lt;/td>
 &lt;td>&lt;code>exp(cross-entropy)&lt;/code>&lt;/td>
 &lt;td>「平均看到幾種候選」、好讀&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;p>換算範例（base e）：&lt;/p>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>Cross-entropy&lt;/th>
 &lt;th>Perplexity&lt;/th>
 &lt;th>意義（極粗略直覺）&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>11&lt;/td>
 &lt;td>~60K&lt;/td>
 &lt;td>純隨機（vocab ≈ 128K 時）&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>5&lt;/td>
 &lt;td>~148&lt;/td>
 &lt;td>早期訓練&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>3&lt;/td>
 &lt;td>~20&lt;/td>
 &lt;td>中等訓練模型&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>2&lt;/td>
 &lt;td>~7.4&lt;/td>
 &lt;td>接近現代成熟 LLM 在文本上的表現&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>0&lt;/td>
 &lt;td>1&lt;/td>
 &lt;td>完美預測（不可能達到）&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;p>Perplexity 主要用於：&lt;/p>
&lt;ul>
&lt;li>&lt;strong>預訓練評估&lt;/strong>：在 held-out 語料上算 perplexity、衡量基礎建模能力。&lt;/li>
&lt;li>&lt;strong>量化品質衡量&lt;/strong>：fp16 vs Q4 vs Q3 模型的 perplexity 差異、看量化造成多少品質損失。&lt;/li>
&lt;li>&lt;strong>領域 benchmark&lt;/strong>：在特定領域語料（code、math、医學文獻）上算 perplexity、評估模型對該領域的熟悉度。&lt;/li>
&lt;/ul>
&lt;h2 id="設計責任">設計責任&lt;/h2>
&lt;p>Perplexity 是 base model 評估標準、但對 instruction-tuned / chat 模型用處有限（chat 模型輸出風格已偏離 raw text、perplexity 不一定降）。對寫 code 場景的判讀：看到 paper 報 perplexity 是評估 pretrain 品質的訊號、實際聊天 / coding 能力要看 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/swe-bench/" data-link-title="SWE-bench" data-link-desc="用真實 GitHub issue 量化 LLM coding 能力的 benchmark">SWE-bench&lt;/a>、MMLU、HumanEval 等任務式 benchmark。&lt;/p></description><content:encoded><![CDATA[<p>Perplexity（困惑度）的核心概念是「<a href="/blog/llm/knowledge-cards/cross-entropy/" data-link-title="Cross-Entropy" data-link-desc="衡量「預測機率分佈」跟「真實分佈」距離的指標、LLM 預訓練的主要 loss">cross-entropy</a> 的指數形式」：<code>perplexity = exp(cross-entropy)</code>。直覺意義是「模型在每個位置平均覺得下個 <a href="/blog/llm/knowledge-cards/token/" data-link-title="Token" data-link-desc="LLM 處理文字時的最小單位：介於字元與單字之間">token</a> 有多少種候選」。perplexity = 1 表示模型完美預測；perplexity = vocab_size 表示模型純猜（vocab 上的 uniform 分佈）。</p>
<h2 id="概念位置">概念位置</h2>
<p>Perplexity 跟 cross-entropy 的關係：</p>
<table>
  <thead>
      <tr>
          <th>指標</th>
          <th>公式 / 定義</th>
          <th>人類直覺</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Cross-entropy</td>
          <td><code>-mean(log p_true)</code>、底通常是 e</td>
          <td>loss 數字、訓練拿來最佳化</td>
      </tr>
      <tr>
          <td>Perplexity</td>
          <td><code>exp(cross-entropy)</code></td>
          <td>「平均看到幾種候選」、好讀</td>
      </tr>
  </tbody>
</table>
<p>換算範例（base e）：</p>
<table>
  <thead>
      <tr>
          <th>Cross-entropy</th>
          <th>Perplexity</th>
          <th>意義（極粗略直覺）</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>11</td>
          <td>~60K</td>
          <td>純隨機（vocab ≈ 128K 時）</td>
      </tr>
      <tr>
          <td>5</td>
          <td>~148</td>
          <td>早期訓練</td>
      </tr>
      <tr>
          <td>3</td>
          <td>~20</td>
          <td>中等訓練模型</td>
      </tr>
      <tr>
          <td>2</td>
          <td>~7.4</td>
          <td>接近現代成熟 LLM 在文本上的表現</td>
      </tr>
      <tr>
          <td>0</td>
          <td>1</td>
          <td>完美預測（不可能達到）</td>
      </tr>
  </tbody>
</table>
<p>Perplexity 主要用於：</p>
<ul>
<li><strong>預訓練評估</strong>：在 held-out 語料上算 perplexity、衡量基礎建模能力。</li>
<li><strong>量化品質衡量</strong>：fp16 vs Q4 vs Q3 模型的 perplexity 差異、看量化造成多少品質損失。</li>
<li><strong>領域 benchmark</strong>：在特定領域語料（code、math、医學文獻）上算 perplexity、評估模型對該領域的熟悉度。</li>
</ul>
<h2 id="設計責任">設計責任</h2>
<p>Perplexity 是 base model 評估標準、但對 instruction-tuned / chat 模型用處有限（chat 模型輸出風格已偏離 raw text、perplexity 不一定降）。對寫 code 場景的判讀：看到 paper 報 perplexity 是評估 pretrain 品質的訊號、實際聊天 / coding 能力要看 <a href="/blog/llm/knowledge-cards/swe-bench/" data-link-title="SWE-bench" data-link-desc="用真實 GitHub issue 量化 LLM coding 能力的 benchmark">SWE-bench</a>、MMLU、HumanEval 等任務式 benchmark。</p>
]]></content:encoded></item><item><title>Hands-on：用本地 LLM 跑 judge harness（最小可行版）</title><link>https://tarrragon.github.io/blog/llm/01-local-llm-services/hands-on/local-llm-judge-harness/</link><pubDate>Tue, 12 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/llm/01-local-llm-services/hands-on/local-llm-judge-harness/</guid><description>&lt;p>&lt;a href="https://tarrragon.github.io/blog/llm/04-applications/llm-as-judge/" data-link-title="4.21 LLM-as-Judge 評估方法" data-link-desc="LLM 評估 LLM 的 production eval 方法：rubric design、pairwise / direct scoring、三大 bias 緩解、跟 trace 串接的閉環、calibration">4.21 LLM-as-judge&lt;/a> 寫的是原理。本篇用 Ollama / LM Studio 在本地跑一個最小可行的 judge harness、對自己工作流的真實案例做 systematic eval。隱私敏感場景特別合用 — eval 資料（user query、agent output、可能含 PII）不需要送雲端。&lt;/p>
&lt;p>本篇 framing 是「&lt;strong>真的能跑、不只跑 demo&lt;/strong>」、所以包含：硬體預算估算、judge model 選型、bias 緩解、calibration 流程、跟 production trace 串接的延伸；術語對應 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/llm-as-judge/" data-link-title="LLM-as-Judge" data-link-desc="用 LLM 評估另一個 LLM 的輸出品質、production eval 的主流方法、500-5000× 成本降但有 bias 要處理">LLM-as-Judge&lt;/a> 與 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/llm-tracing/" data-link-title="LLM Tracing" data-link-desc="把 LLM 應用的每次 LLM call / tool call / memory op 編成結構化 span、用 OpenTelemetry GenAI semantic conventions 標準化">LLM Tracing&lt;/a>。&lt;/p>
&lt;blockquote>
&lt;p>&lt;strong>驗證日期&lt;/strong>：2026-05-12
&lt;strong>環境&lt;/strong>：M4 Max 64GB / 或 24GB+ VRAM PC + Ollama
&lt;strong>Judge model&lt;/strong>：DeepSeek-R1-Distill-Qwen-32B 或 QwQ-32B（reasoning model 當 judge 更穩）&lt;/p>&lt;/blockquote>
&lt;h2 id="為什麼用本地-llm-當-judge">為什麼用本地 LLM 當 judge&lt;/h2>
&lt;p>跟雲端 judge（GPT-5 / Claude 4）對比：&lt;/p>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>維度&lt;/th>
 &lt;th>本地 judge&lt;/th>
 &lt;th>雲端 judge&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>Cost&lt;/td>
 &lt;td>0（電費）&lt;/td>
 &lt;td>$0.001-0.01 per item&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>隱私&lt;/td>
 &lt;td>完全本地、eval 資料不出機器&lt;/td>
 &lt;td>送雲端、依政策&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Latency&lt;/td>
 &lt;td>視硬體、reasoning model 30B 約 30-60s&lt;/td>
 &lt;td>API call 5-30s&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>品質上限&lt;/td>
 &lt;td>本地 30B reasoning 接近 2024 雲端中段&lt;/td>
 &lt;td>雲端旗艦上限高&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>大量 batch&lt;/td>
 &lt;td>慢但 zero cost&lt;/td>
 &lt;td>快但 cost 累積&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;p>判讀：&lt;/p>
&lt;ul>
&lt;li>&lt;strong>大量 production trace eval（千筆以上）+ 隱私敏感&lt;/strong> → 本地 judge&lt;/li>
&lt;li>&lt;strong>少量 high-stake eval（&amp;lt; 50 筆）&lt;/strong> → 雲端旗艦 judge&lt;/li>
&lt;li>&lt;strong>A/B test 快速 iterate&lt;/strong> → 雲端（latency 重要）&lt;/li>
&lt;/ul>
&lt;h2 id="硬體預算">硬體預算&lt;/h2>
&lt;p>Judge model 選擇看硬體：&lt;/p>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>硬體&lt;/th>
 &lt;th>適合 judge model&lt;/th>
 &lt;th>預期 latency / item&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>M4 Pro 24GB / 4090 16GB&lt;/td>
 &lt;td>Qwen2.5-32B Q4 或 DeepSeek-R1-Distill-14B&lt;/td>
 &lt;td>30-60s&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>M4 Pro 36GB&lt;/td>
 &lt;td>DeepSeek-R1-Distill-Qwen-32B Q4&lt;/td>
 &lt;td>60-120s&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>M4 Max 48-64GB / 5090 24GB&lt;/td>
 &lt;td>QwQ-32B 或 DeepSeek-R1-Distill-Qwen-32B Q6&lt;/td>
 &lt;td>60-180s（含 reasoning trace）&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>M4 Max 128GB / 多卡 PC&lt;/td>
 &lt;td>Llama 3.3 70B 或 Qwen3-72B&lt;/td>
 &lt;td>120-300s&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;p>注意：reasoning model 的 thinking trace 拉長 latency、跑大量 batch 要規劃時間（100 item × 60s = 100 min）。&lt;/p></description><content:encoded><![CDATA[<p><a href="/blog/llm/04-applications/llm-as-judge/" data-link-title="4.21 LLM-as-Judge 評估方法" data-link-desc="LLM 評估 LLM 的 production eval 方法：rubric design、pairwise / direct scoring、三大 bias 緩解、跟 trace 串接的閉環、calibration">4.21 LLM-as-judge</a> 寫的是原理。本篇用 Ollama / LM Studio 在本地跑一個最小可行的 judge harness、對自己工作流的真實案例做 systematic eval。隱私敏感場景特別合用 — eval 資料（user query、agent output、可能含 PII）不需要送雲端。</p>
<p>本篇 framing 是「<strong>真的能跑、不只跑 demo</strong>」、所以包含：硬體預算估算、judge model 選型、bias 緩解、calibration 流程、跟 production trace 串接的延伸；術語對應 <a href="/blog/llm/knowledge-cards/llm-as-judge/" data-link-title="LLM-as-Judge" data-link-desc="用 LLM 評估另一個 LLM 的輸出品質、production eval 的主流方法、500-5000× 成本降但有 bias 要處理">LLM-as-Judge</a> 與 <a href="/blog/llm/knowledge-cards/llm-tracing/" data-link-title="LLM Tracing" data-link-desc="把 LLM 應用的每次 LLM call / tool call / memory op 編成結構化 span、用 OpenTelemetry GenAI semantic conventions 標準化">LLM Tracing</a>。</p>
<blockquote>
<p><strong>驗證日期</strong>：2026-05-12
<strong>環境</strong>：M4 Max 64GB / 或 24GB+ VRAM PC + Ollama
<strong>Judge model</strong>：DeepSeek-R1-Distill-Qwen-32B 或 QwQ-32B（reasoning model 當 judge 更穩）</p></blockquote>
<h2 id="為什麼用本地-llm-當-judge">為什麼用本地 LLM 當 judge</h2>
<p>跟雲端 judge（GPT-5 / Claude 4）對比：</p>
<table>
  <thead>
      <tr>
          <th>維度</th>
          <th>本地 judge</th>
          <th>雲端 judge</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Cost</td>
          <td>0（電費）</td>
          <td>$0.001-0.01 per item</td>
      </tr>
      <tr>
          <td>隱私</td>
          <td>完全本地、eval 資料不出機器</td>
          <td>送雲端、依政策</td>
      </tr>
      <tr>
          <td>Latency</td>
          <td>視硬體、reasoning model 30B 約 30-60s</td>
          <td>API call 5-30s</td>
      </tr>
      <tr>
          <td>品質上限</td>
          <td>本地 30B reasoning 接近 2024 雲端中段</td>
          <td>雲端旗艦上限高</td>
      </tr>
      <tr>
          <td>大量 batch</td>
          <td>慢但 zero cost</td>
          <td>快但 cost 累積</td>
      </tr>
  </tbody>
</table>
<p>判讀：</p>
<ul>
<li><strong>大量 production trace eval（千筆以上）+ 隱私敏感</strong> → 本地 judge</li>
<li><strong>少量 high-stake eval（&lt; 50 筆）</strong> → 雲端旗艦 judge</li>
<li><strong>A/B test 快速 iterate</strong> → 雲端（latency 重要）</li>
</ul>
<h2 id="硬體預算">硬體預算</h2>
<p>Judge model 選擇看硬體：</p>
<table>
  <thead>
      <tr>
          <th>硬體</th>
          <th>適合 judge model</th>
          <th>預期 latency / item</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>M4 Pro 24GB / 4090 16GB</td>
          <td>Qwen2.5-32B Q4 或 DeepSeek-R1-Distill-14B</td>
          <td>30-60s</td>
      </tr>
      <tr>
          <td>M4 Pro 36GB</td>
          <td>DeepSeek-R1-Distill-Qwen-32B Q4</td>
          <td>60-120s</td>
      </tr>
      <tr>
          <td>M4 Max 48-64GB / 5090 24GB</td>
          <td>QwQ-32B 或 DeepSeek-R1-Distill-Qwen-32B Q6</td>
          <td>60-180s（含 reasoning trace）</td>
      </tr>
      <tr>
          <td>M4 Max 128GB / 多卡 PC</td>
          <td>Llama 3.3 70B 或 Qwen3-72B</td>
          <td>120-300s</td>
      </tr>
  </tbody>
</table>
<p>注意：reasoning model 的 thinking trace 拉長 latency、跑大量 batch 要規劃時間（100 item × 60s = 100 min）。</p>
<p><strong>何時不適合用本地 judge</strong>：</p>
<ol>
<li><strong>硬體低於 M4 Pro 24GB / 4090 16GB</strong>（如 M1/M2 16GB、無獨立 GPU PC）：跑 32B reasoning model 太緊、強行跑會 swap、latency 爆 5-10×。改用 14B instruct model（如 Qwen2.5-14B Q4）作 judge、或直接走雲端 judge</li>
<li><strong>Batch × latency &gt; 你可接受的等待時間</strong>：100 item × 60s/item = 100 min；500 item × 120s = 17 hr。預估超過 4 hr 時改雲端 batch API</li>
<li><strong>eval 任務太 nuanced</strong>：細粒度倫理 / 法律 / 高 stake 判讀、本地 32B distill 能力不夠、用雲端旗艦 judge 或人工 review</li>
<li><strong>calibration 階段</strong>：第一次跑、要快速 iterate rubric、雲端 judge latency 短（5-30s）更適合 iterate</li>
</ol>
<h2 id="整體流程">整體流程</h2>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="ln">1</span><span class="cl">1. 蒐集 eval dataset    → JSONL：每行一個 (input, output) 待評
</span></span><span class="line"><span class="ln">2</span><span class="cl">2. 設計 rubric         → 評分維度、scale、明確 anti-pattern
</span></span><span class="line"><span class="ln">3</span><span class="cl">3. 寫 judge prompt     → 4 段式（task / input-output / rubric / format）
</span></span><span class="line"><span class="ln">4</span><span class="cl">4. 跑 harness          → 對每筆 input call judge、parse JSON output
</span></span><span class="line"><span class="ln">5</span><span class="cl">5. Aggregate 結果      → 算平均分數、找 outlier、看 reasoning
</span></span><span class="line"><span class="ln">6</span><span class="cl">6. Calibration（可選）  → 跟 human eval 比對、調 rubric
</span></span><span class="line"><span class="ln">7</span><span class="cl">7. 跟 production trace 串接 → 定期跑 production sample</span></span></code></pre></div><h2 id="step-1蒐集-eval-dataset">Step 1：蒐集 eval dataset</h2>
<p>JSONL format（每行一筆）：</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-json" data-lang="json"><span class="line"><span class="ln">1</span><span class="cl"><span class="p">{</span><span class="nt">&#34;id&#34;</span><span class="p">:</span> <span class="s2">&#34;001&#34;</span><span class="p">,</span> <span class="nt">&#34;input&#34;</span><span class="p">:</span> <span class="s2">&#34;用 Python 寫 fibonacci function&#34;</span><span class="p">,</span> <span class="nt">&#34;output&#34;</span><span class="p">:</span> <span class="s2">&#34;def fib(n):\n    if n &lt;= 1:\n        return n\n    return fib(n-1) + fib(n-2)&#34;</span><span class="p">}</span>
</span></span><span class="line"><span class="ln">2</span><span class="cl"><span class="p">{</span><span class="nt">&#34;id&#34;</span><span class="p">:</span> <span class="s2">&#34;002&#34;</span><span class="p">,</span> <span class="nt">&#34;input&#34;</span><span class="p">:</span> <span class="s2">&#34;解釋這段 code 在做什麼：[code]&#34;</span><span class="p">,</span> <span class="nt">&#34;output&#34;</span><span class="p">:</span> <span class="s2">&#34;這段 code 實作了 ...&#34;</span><span class="p">}</span>
</span></span><span class="line"><span class="ln">3</span><span class="cl"><span class="p">{</span><span class="nt">&#34;id&#34;</span><span class="p">:</span> <span class="s2">&#34;003&#34;</span><span class="p">,</span> <span class="nt">&#34;input&#34;</span><span class="p">:</span> <span class="s2">&#34;[bug 描述]&#34;</span><span class="p">,</span> <span class="nt">&#34;output&#34;</span><span class="p">:</span> <span class="s2">&#34;[suggested fix]&#34;</span><span class="p">}</span></span></span></code></pre></div><p>來源：</p>
<ul>
<li>過往 Continue.dev / Cursor 跟 LLM 的對話 log</li>
<li>Production agent 的 trace（手動 export 或 LangSmith / Phoenix dump）</li>
<li>自己 hand-craft 30-100 個典型 case</li>
</ul>
<p>放在 <code>data/eval.jsonl</code>。</p>
<h2 id="step-2設計-rubric">Step 2：設計 rubric</h2>
<p>依任務類型設計、coding 任務的範例 rubric：</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="ln"> 1</span><span class="cl">評分維度：
</span></span><span class="line"><span class="ln"> 2</span><span class="cl">1. Correctness（程式碼能否運作、邏輯是否正確）：1-5
</span></span><span class="line"><span class="ln"> 3</span><span class="cl">2. Style（是否符合 codebase convention、習慣命名）：1-5
</span></span><span class="line"><span class="ln"> 4</span><span class="cl">3. Completeness（是否完整解決 user request）：1-5
</span></span><span class="line"><span class="ln"> 5</span><span class="cl">
</span></span><span class="line"><span class="ln"> 6</span><span class="cl">評分規則：
</span></span><span class="line"><span class="ln"> 7</span><span class="cl">- 5：完美無瑕、可直接 merge
</span></span><span class="line"><span class="ln"> 8</span><span class="cl">- 4：小修可用、整體正確
</span></span><span class="line"><span class="ln"> 9</span><span class="cl">- 3：方向正確、需 substantial 修改
</span></span><span class="line"><span class="ln">10</span><span class="cl">- 2：部分對、主要邏輯有錯
</span></span><span class="line"><span class="ln">11</span><span class="cl">- 1：完全錯、誤導使用者
</span></span><span class="line"><span class="ln">12</span><span class="cl">
</span></span><span class="line"><span class="ln">13</span><span class="cl">明確不加分（緩解 verbosity bias）：
</span></span><span class="line"><span class="ln">14</span><span class="cl">- 冗長 / verbose（同樣正確的短答 = 長答）
</span></span><span class="line"><span class="ln">15</span><span class="cl">- 道歉 / 開場白
</span></span><span class="line"><span class="ln">16</span><span class="cl">- 「我希望這有幫助」這類禮貌話
</span></span><span class="line"><span class="ln">17</span><span class="cl">- 過多 markdown 修飾（不加分）</span></span></code></pre></div><h2 id="step-3judge-prompt-模板">Step 3：Judge prompt 模板</h2>
<p>寫成 file <code>prompts/judge.txt</code>：</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="ln"> 1</span><span class="cl">你是 LLM 輸出品質評估員、要評估 coding assistant 對使用者請求的回答品質。
</span></span><span class="line"><span class="ln"> 2</span><span class="cl">重要：請保持公正、忽略風格偏好、聚焦在實質品質。
</span></span><span class="line"><span class="ln"> 3</span><span class="cl">
</span></span><span class="line"><span class="ln"> 4</span><span class="cl">User request:
</span></span><span class="line"><span class="ln"> 5</span><span class="cl">{input}
</span></span><span class="line"><span class="ln"> 6</span><span class="cl">
</span></span><span class="line"><span class="ln"> 7</span><span class="cl">Assistant response:
</span></span><span class="line"><span class="ln"> 8</span><span class="cl">{output}
</span></span><span class="line"><span class="ln"> 9</span><span class="cl">
</span></span><span class="line"><span class="ln">10</span><span class="cl">評分維度（每維 1-5、加總用 overall）：
</span></span><span class="line"><span class="ln">11</span><span class="cl">
</span></span><span class="line"><span class="ln">12</span><span class="cl">1. Correctness：程式碼能否運作、邏輯正確
</span></span><span class="line"><span class="ln">13</span><span class="cl">   5: 完美無瑕
</span></span><span class="line"><span class="ln">14</span><span class="cl">   4: 小修可用
</span></span><span class="line"><span class="ln">15</span><span class="cl">   3: 方向正確、需 substantial 修改
</span></span><span class="line"><span class="ln">16</span><span class="cl">   2: 部分對、主要邏輯有錯
</span></span><span class="line"><span class="ln">17</span><span class="cl">   1: 完全錯
</span></span><span class="line"><span class="ln">18</span><span class="cl">
</span></span><span class="line"><span class="ln">19</span><span class="cl">2. Style：符合 codebase convention
</span></span><span class="line"><span class="ln">20</span><span class="cl">   1-5 同 scale
</span></span><span class="line"><span class="ln">21</span><span class="cl">
</span></span><span class="line"><span class="ln">22</span><span class="cl">3. Completeness：完整解決 user request
</span></span><span class="line"><span class="ln">23</span><span class="cl">   1-5 同 scale
</span></span><span class="line"><span class="ln">24</span><span class="cl">
</span></span><span class="line"><span class="ln">25</span><span class="cl">明確不加分項：
</span></span><span class="line"><span class="ln">26</span><span class="cl">- 冗長 / verbose（同樣正確的短答 = 長答）
</span></span><span class="line"><span class="ln">27</span><span class="cl">- 道歉 / 開場白
</span></span><span class="line"><span class="ln">28</span><span class="cl">- 「我希望這有幫助」這類禮貌話
</span></span><span class="line"><span class="ln">29</span><span class="cl">- 過多 markdown 修飾
</span></span><span class="line"><span class="ln">30</span><span class="cl">
</span></span><span class="line"><span class="ln">31</span><span class="cl">請依下列 JSON 輸出（不要加額外文字、不要 markdown code fence）：
</span></span><span class="line"><span class="ln">32</span><span class="cl">{
</span></span><span class="line"><span class="ln">33</span><span class="cl">  &#34;correctness&#34;: &lt;1-5&gt;,
</span></span><span class="line"><span class="ln">34</span><span class="cl">  &#34;style&#34;: &lt;1-5&gt;,
</span></span><span class="line"><span class="ln">35</span><span class="cl">  &#34;completeness&#34;: &lt;1-5&gt;,
</span></span><span class="line"><span class="ln">36</span><span class="cl">  &#34;reasoning&#34;: &#34;&lt;簡短解釋、&lt; 100 字&gt;&#34;,
</span></span><span class="line"><span class="ln">37</span><span class="cl">  &#34;overall&#34;: &lt;1-5&gt;
</span></span><span class="line"><span class="ln">38</span><span class="cl">}</span></span></code></pre></div><h2 id="step-4跑-harness">Step 4：跑 harness</h2>
<p>Python 最小可行版：</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="ln"> 1</span><span class="cl"><span class="c1"># judge_harness.py</span>
</span></span><span class="line"><span class="ln"> 2</span><span class="cl"><span class="kn">import</span> <span class="nn">json</span>
</span></span><span class="line"><span class="ln"> 3</span><span class="cl"><span class="kn">import</span> <span class="nn">requests</span>
</span></span><span class="line"><span class="ln"> 4</span><span class="cl"><span class="kn">from</span> <span class="nn">pathlib</span> <span class="kn">import</span> <span class="n">Path</span>
</span></span><span class="line"><span class="ln"> 5</span><span class="cl">
</span></span><span class="line"><span class="ln"> 6</span><span class="cl"><span class="n">JUDGE_MODEL</span> <span class="o">=</span> <span class="s2">&#34;deepseek-r1:32b&#34;</span>  <span class="c1"># 或 qwq:32b</span>
</span></span><span class="line"><span class="ln"> 7</span><span class="cl"><span class="n">OLLAMA_URL</span> <span class="o">=</span> <span class="s2">&#34;http://localhost:11434/v1/chat/completions&#34;</span>
</span></span><span class="line"><span class="ln"> 8</span><span class="cl">
</span></span><span class="line"><span class="ln"> 9</span><span class="cl"><span class="k">def</span> <span class="nf">load_dataset</span><span class="p">(</span><span class="n">path</span><span class="p">):</span>
</span></span><span class="line"><span class="ln">10</span><span class="cl">    <span class="s2">&#34;&#34;&#34;Load JSONL eval dataset.&#34;&#34;&#34;</span>
</span></span><span class="line"><span class="ln">11</span><span class="cl">    <span class="k">with</span> <span class="nb">open</span><span class="p">(</span><span class="n">path</span><span class="p">)</span> <span class="k">as</span> <span class="n">f</span><span class="p">:</span>
</span></span><span class="line"><span class="ln">12</span><span class="cl">        <span class="k">return</span> <span class="p">[</span><span class="n">json</span><span class="o">.</span><span class="n">loads</span><span class="p">(</span><span class="n">line</span><span class="p">)</span> <span class="k">for</span> <span class="n">line</span> <span class="ow">in</span> <span class="n">f</span> <span class="k">if</span> <span class="n">line</span><span class="o">.</span><span class="n">strip</span><span class="p">()]</span>
</span></span><span class="line"><span class="ln">13</span><span class="cl">
</span></span><span class="line"><span class="ln">14</span><span class="cl"><span class="k">def</span> <span class="nf">load_prompt_template</span><span class="p">(</span><span class="n">path</span><span class="p">):</span>
</span></span><span class="line"><span class="ln">15</span><span class="cl">    <span class="k">return</span> <span class="n">Path</span><span class="p">(</span><span class="n">path</span><span class="p">)</span><span class="o">.</span><span class="n">read_text</span><span class="p">()</span>
</span></span><span class="line"><span class="ln">16</span><span class="cl">
</span></span><span class="line"><span class="ln">17</span><span class="cl"><span class="k">def</span> <span class="nf">call_judge</span><span class="p">(</span><span class="n">prompt</span><span class="p">):</span>
</span></span><span class="line"><span class="ln">18</span><span class="cl">    <span class="s2">&#34;&#34;&#34;Call Ollama judge model、回 raw response text.&#34;&#34;&#34;</span>
</span></span><span class="line"><span class="ln">19</span><span class="cl">    <span class="n">resp</span> <span class="o">=</span> <span class="n">requests</span><span class="o">.</span><span class="n">post</span><span class="p">(</span><span class="n">OLLAMA_URL</span><span class="p">,</span> <span class="n">json</span><span class="o">=</span><span class="p">{</span>
</span></span><span class="line"><span class="ln">20</span><span class="cl">        <span class="s2">&#34;model&#34;</span><span class="p">:</span> <span class="n">JUDGE_MODEL</span><span class="p">,</span>
</span></span><span class="line"><span class="ln">21</span><span class="cl">        <span class="s2">&#34;messages&#34;</span><span class="p">:</span> <span class="p">[{</span><span class="s2">&#34;role&#34;</span><span class="p">:</span> <span class="s2">&#34;user&#34;</span><span class="p">,</span> <span class="s2">&#34;content&#34;</span><span class="p">:</span> <span class="n">prompt</span><span class="p">}],</span>
</span></span><span class="line"><span class="ln">22</span><span class="cl">        <span class="s2">&#34;temperature&#34;</span><span class="p">:</span> <span class="mf">0.1</span><span class="p">,</span>  <span class="c1"># judge 用低 temperature 穩定</span>
</span></span><span class="line"><span class="ln">23</span><span class="cl">        <span class="s2">&#34;stream&#34;</span><span class="p">:</span> <span class="kc">False</span><span class="p">,</span>
</span></span><span class="line"><span class="ln">24</span><span class="cl">    <span class="p">},</span> <span class="n">timeout</span><span class="o">=</span><span class="mi">600</span><span class="p">)</span>
</span></span><span class="line"><span class="ln">25</span><span class="cl">    <span class="k">return</span> <span class="n">resp</span><span class="o">.</span><span class="n">json</span><span class="p">()[</span><span class="s2">&#34;choices&#34;</span><span class="p">][</span><span class="mi">0</span><span class="p">][</span><span class="s2">&#34;message&#34;</span><span class="p">][</span><span class="s2">&#34;content&#34;</span><span class="p">]</span>
</span></span><span class="line"><span class="ln">26</span><span class="cl">
</span></span><span class="line"><span class="ln">27</span><span class="cl"><span class="k">def</span> <span class="nf">parse_judge_output</span><span class="p">(</span><span class="n">text</span><span class="p">):</span>
</span></span><span class="line"><span class="ln">28</span><span class="cl">    <span class="s2">&#34;&#34;&#34;Parse judge 回的 JSON、容錯處理（reasoning model 可能加 &lt;think&gt; 標記）。&#34;&#34;&#34;</span>
</span></span><span class="line"><span class="ln">29</span><span class="cl">    <span class="c1"># 跳過 reasoning trace</span>
</span></span><span class="line"><span class="ln">30</span><span class="cl">    <span class="k">if</span> <span class="s2">&#34;&lt;/think&gt;&#34;</span> <span class="ow">in</span> <span class="n">text</span><span class="p">:</span>
</span></span><span class="line"><span class="ln">31</span><span class="cl">        <span class="n">text</span> <span class="o">=</span> <span class="n">text</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s2">&#34;&lt;/think&gt;&#34;</span><span class="p">)[</span><span class="o">-</span><span class="mi">1</span><span class="p">]</span>
</span></span><span class="line"><span class="ln">32</span><span class="cl">
</span></span><span class="line"><span class="ln">33</span><span class="cl">    <span class="c1"># 找 JSON 區塊</span>
</span></span><span class="line"><span class="ln">34</span><span class="cl">    <span class="n">start</span> <span class="o">=</span> <span class="n">text</span><span class="o">.</span><span class="n">find</span><span class="p">(</span><span class="s2">&#34;{&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="ln">35</span><span class="cl">    <span class="n">end</span> <span class="o">=</span> <span class="n">text</span><span class="o">.</span><span class="n">rfind</span><span class="p">(</span><span class="s2">&#34;}&#34;</span><span class="p">)</span> <span class="o">+</span> <span class="mi">1</span>
</span></span><span class="line"><span class="ln">36</span><span class="cl">    <span class="k">if</span> <span class="n">start</span> <span class="o">==</span> <span class="o">-</span><span class="mi">1</span> <span class="ow">or</span> <span class="n">end</span> <span class="o">==</span> <span class="mi">0</span><span class="p">:</span>
</span></span><span class="line"><span class="ln">37</span><span class="cl">        <span class="k">return</span> <span class="kc">None</span>
</span></span><span class="line"><span class="ln">38</span><span class="cl">    <span class="k">try</span><span class="p">:</span>
</span></span><span class="line"><span class="ln">39</span><span class="cl">        <span class="k">return</span> <span class="n">json</span><span class="o">.</span><span class="n">loads</span><span class="p">(</span><span class="n">text</span><span class="p">[</span><span class="n">start</span><span class="p">:</span><span class="n">end</span><span class="p">])</span>
</span></span><span class="line"><span class="ln">40</span><span class="cl">    <span class="k">except</span> <span class="n">json</span><span class="o">.</span><span class="n">JSONDecodeError</span><span class="p">:</span>
</span></span><span class="line"><span class="ln">41</span><span class="cl">        <span class="k">return</span> <span class="kc">None</span>
</span></span><span class="line"><span class="ln">42</span><span class="cl">
</span></span><span class="line"><span class="ln">43</span><span class="cl"><span class="k">def</span> <span class="nf">run_harness</span><span class="p">(</span><span class="n">dataset_path</span><span class="p">,</span> <span class="n">prompt_template_path</span><span class="p">,</span> <span class="n">output_path</span><span class="p">):</span>
</span></span><span class="line"><span class="ln">44</span><span class="cl">    <span class="n">dataset</span> <span class="o">=</span> <span class="n">load_dataset</span><span class="p">(</span><span class="n">dataset_path</span><span class="p">)</span>
</span></span><span class="line"><span class="ln">45</span><span class="cl">    <span class="n">template</span> <span class="o">=</span> <span class="n">load_prompt_template</span><span class="p">(</span><span class="n">prompt_template_path</span><span class="p">)</span>
</span></span><span class="line"><span class="ln">46</span><span class="cl">
</span></span><span class="line"><span class="ln">47</span><span class="cl">    <span class="n">results</span> <span class="o">=</span> <span class="p">[]</span>
</span></span><span class="line"><span class="ln">48</span><span class="cl">    <span class="k">for</span> <span class="n">i</span><span class="p">,</span> <span class="n">item</span> <span class="ow">in</span> <span class="nb">enumerate</span><span class="p">(</span><span class="n">dataset</span><span class="p">):</span>
</span></span><span class="line"><span class="ln">49</span><span class="cl">        <span class="n">prompt</span> <span class="o">=</span> <span class="n">template</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="nb">input</span><span class="o">=</span><span class="n">item</span><span class="p">[</span><span class="s2">&#34;input&#34;</span><span class="p">],</span> <span class="n">output</span><span class="o">=</span><span class="n">item</span><span class="p">[</span><span class="s2">&#34;output&#34;</span><span class="p">])</span>
</span></span><span class="line"><span class="ln">50</span><span class="cl">        <span class="n">raw</span> <span class="o">=</span> <span class="n">call_judge</span><span class="p">(</span><span class="n">prompt</span><span class="p">)</span>
</span></span><span class="line"><span class="ln">51</span><span class="cl">        <span class="n">parsed</span> <span class="o">=</span> <span class="n">parse_judge_output</span><span class="p">(</span><span class="n">raw</span><span class="p">)</span>
</span></span><span class="line"><span class="ln">52</span><span class="cl">
</span></span><span class="line"><span class="ln">53</span><span class="cl">        <span class="n">result</span> <span class="o">=</span> <span class="p">{</span>
</span></span><span class="line"><span class="ln">54</span><span class="cl">            <span class="s2">&#34;id&#34;</span><span class="p">:</span> <span class="n">item</span><span class="p">[</span><span class="s2">&#34;id&#34;</span><span class="p">],</span>
</span></span><span class="line"><span class="ln">55</span><span class="cl">            <span class="s2">&#34;scores&#34;</span><span class="p">:</span> <span class="n">parsed</span><span class="p">,</span>
</span></span><span class="line"><span class="ln">56</span><span class="cl">            <span class="s2">&#34;raw_judge_output&#34;</span><span class="p">:</span> <span class="n">raw</span><span class="p">[:</span><span class="mi">500</span><span class="p">],</span>  <span class="c1"># 保留前 500 字便於 debug</span>
</span></span><span class="line"><span class="ln">57</span><span class="cl">        <span class="p">}</span>
</span></span><span class="line"><span class="ln">58</span><span class="cl">        <span class="n">results</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">result</span><span class="p">)</span>
</span></span><span class="line"><span class="ln">59</span><span class="cl">        <span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s2">&#34;[</span><span class="si">{</span><span class="n">i</span><span class="o">+</span><span class="mi">1</span><span class="si">}</span><span class="s2">/</span><span class="si">{</span><span class="nb">len</span><span class="p">(</span><span class="n">dataset</span><span class="p">)</span><span class="si">}</span><span class="s2">] id=</span><span class="si">{</span><span class="n">item</span><span class="p">[</span><span class="s1">&#39;id&#39;</span><span class="p">]</span><span class="si">}</span><span class="s2"> overall=</span><span class="si">{</span><span class="n">parsed</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s1">&#39;overall&#39;</span><span class="p">)</span> <span class="k">if</span> <span class="n">parsed</span> <span class="k">else</span> <span class="s1">&#39;FAIL&#39;</span><span class="si">}</span><span class="s2">&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="ln">60</span><span class="cl">
</span></span><span class="line"><span class="ln">61</span><span class="cl">    <span class="c1"># 寫出 JSONL</span>
</span></span><span class="line"><span class="ln">62</span><span class="cl">    <span class="k">with</span> <span class="nb">open</span><span class="p">(</span><span class="n">output_path</span><span class="p">,</span> <span class="s2">&#34;w&#34;</span><span class="p">)</span> <span class="k">as</span> <span class="n">f</span><span class="p">:</span>
</span></span><span class="line"><span class="ln">63</span><span class="cl">        <span class="k">for</span> <span class="n">r</span> <span class="ow">in</span> <span class="n">results</span><span class="p">:</span>
</span></span><span class="line"><span class="ln">64</span><span class="cl">            <span class="n">f</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="n">json</span><span class="o">.</span><span class="n">dumps</span><span class="p">(</span><span class="n">r</span><span class="p">)</span> <span class="o">+</span> <span class="s2">&#34;</span><span class="se">\n</span><span class="s2">&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="ln">65</span><span class="cl">
</span></span><span class="line"><span class="ln">66</span><span class="cl">    <span class="c1"># Aggregate</span>
</span></span><span class="line"><span class="ln">67</span><span class="cl">    <span class="n">valid</span> <span class="o">=</span> <span class="p">[</span><span class="n">r</span> <span class="k">for</span> <span class="n">r</span> <span class="ow">in</span> <span class="n">results</span> <span class="k">if</span> <span class="n">r</span><span class="p">[</span><span class="s2">&#34;scores&#34;</span><span class="p">]]</span>
</span></span><span class="line"><span class="ln">68</span><span class="cl">    <span class="k">if</span> <span class="n">valid</span><span class="p">:</span>
</span></span><span class="line"><span class="ln">69</span><span class="cl">        <span class="n">avg</span> <span class="o">=</span> <span class="nb">sum</span><span class="p">(</span><span class="n">r</span><span class="p">[</span><span class="s2">&#34;scores&#34;</span><span class="p">][</span><span class="s2">&#34;overall&#34;</span><span class="p">]</span> <span class="k">for</span> <span class="n">r</span> <span class="ow">in</span> <span class="n">valid</span><span class="p">)</span> <span class="o">/</span> <span class="nb">len</span><span class="p">(</span><span class="n">valid</span><span class="p">)</span>
</span></span><span class="line"><span class="ln">70</span><span class="cl">        <span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s2">&#34;</span><span class="se">\n</span><span class="s2">Aggregate: </span><span class="si">{</span><span class="nb">len</span><span class="p">(</span><span class="n">valid</span><span class="p">)</span><span class="si">}</span><span class="s2">/</span><span class="si">{</span><span class="nb">len</span><span class="p">(</span><span class="n">results</span><span class="p">)</span><span class="si">}</span><span class="s2"> valid、avg overall = </span><span class="si">{</span><span class="n">avg</span><span class="si">:</span><span class="s2">.2f</span><span class="si">}</span><span class="s2">&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="ln">71</span><span class="cl">
</span></span><span class="line"><span class="ln">72</span><span class="cl"><span class="k">if</span> <span class="vm">__name__</span> <span class="o">==</span> <span class="s2">&#34;__main__&#34;</span><span class="p">:</span>
</span></span><span class="line"><span class="ln">73</span><span class="cl">    <span class="n">run_harness</span><span class="p">(</span><span class="s2">&#34;data/eval.jsonl&#34;</span><span class="p">,</span> <span class="s2">&#34;prompts/judge.txt&#34;</span><span class="p">,</span> <span class="s2">&#34;results/eval.jsonl&#34;</span><span class="p">)</span></span></span></code></pre></div><p>跑：</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl"><span class="c1"># 先確認 judge model 已 pull</span>
</span></span><span class="line"><span class="ln">2</span><span class="cl">ollama pull deepseek-r1:32b
</span></span><span class="line"><span class="ln">3</span><span class="cl">
</span></span><span class="line"><span class="ln">4</span><span class="cl"><span class="c1"># 跑 harness</span>
</span></span><span class="line"><span class="ln">5</span><span class="cl">python judge_harness.py</span></span></code></pre></div><h2 id="step-5aggregate-跟看-outlier">Step 5：Aggregate 跟看 outlier</h2>
<p>跑完後 results/eval.jsonl 含每筆評分跟 reasoning。看哪些是 outlier：</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl"><span class="c1"># 找 overall &lt; 3 的 case（低分、值得 review）</span>
</span></span><span class="line"><span class="ln">2</span><span class="cl">jq <span class="s1">&#39;select(.scores.overall &lt; 3)&#39;</span> results/eval.jsonl
</span></span><span class="line"><span class="ln">3</span><span class="cl">
</span></span><span class="line"><span class="ln">4</span><span class="cl"><span class="c1"># 看 reasoning 找系統性問題</span>
</span></span><span class="line"><span class="ln">5</span><span class="cl">jq <span class="s1">&#39;.scores.reasoning&#39;</span> results/eval.jsonl <span class="p">|</span> sort -u</span></span></code></pre></div><p>判讀：</p>
<ul>
<li><strong>多數 score 4-5、少數 1-2</strong>：整體品質好、focus 在低分 case 找 fix</li>
<li><strong>多數 score 2-3</strong>：系統性問題、改 prompt / model / agent design</li>
<li><strong>分數分佈兩極（很多 5 很多 1）</strong>：可能是 task difficulty 分群、stratified analysis</li>
</ul>
<h2 id="step-6calibration可選但推薦">Step 6：Calibration（可選但推薦）</h2>
<p>跟 human eval 比對、確認 judge 對齊：</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="ln">1</span><span class="cl">1. 從 dataset 抽 30 個（覆蓋 difficulty / score 分佈）
</span></span><span class="line"><span class="ln">2</span><span class="cl">2. 自己 human eval（依同樣 rubric）
</span></span><span class="line"><span class="ln">3</span><span class="cl">3. 對比 judge 跟 human 的 overall score
</span></span><span class="line"><span class="ln">4</span><span class="cl">4. 算 Spearman correlation
</span></span><span class="line"><span class="ln">5</span><span class="cl">   - &gt; 0.7：judge 對齊夠好、可信
</span></span><span class="line"><span class="ln">6</span><span class="cl">   - 0.5-0.7：部分問題、改 rubric
</span></span><span class="line"><span class="ln">7</span><span class="cl">   - &lt; 0.5：judge 不可信、換 model 或重寫 rubric</span></span></code></pre></div><p>低 correlation 的常見原因：</p>
<ul>
<li>Rubric 太 vague、judge 自由發揮</li>
<li>Judge model 能力不夠（換更強 judge）</li>
<li>Verbosity / position bias 沒緩解</li>
<li>Eval task 跟 judge 訓練分佈差距大</li>
</ul>
<h2 id="step-7跟-production-trace-串接延伸">Step 7：跟 production trace 串接（延伸）</h2>
<p>把 <a href="/blog/llm/04-applications/llm-tracing-and-observability/" data-link-title="4.20 LLM tracing 與 observability" data-link-desc="OpenTelemetry GenAI semantic conventions、結構化 span 設計、cost / latency 監控、failure debug 流程、跟 LLM-as-judge eval 的串接">4.20 LLM tracing</a> 蒐集的 production trace export 成 JSONL、定期跑 judge：</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl"><span class="c1"># 假設用 Langfuse self-host</span>
</span></span><span class="line"><span class="ln">2</span><span class="cl">langfuse <span class="nb">export</span> --filter <span class="s2">&#34;user_feedback=negative&#34;</span> --output traces.jsonl
</span></span><span class="line"><span class="ln">3</span><span class="cl">
</span></span><span class="line"><span class="ln">4</span><span class="cl"><span class="c1"># 轉成 eval format</span>
</span></span><span class="line"><span class="ln">5</span><span class="cl">python convert_trace_to_eval.py traces.jsonl &gt; data/eval-from-prod.jsonl
</span></span><span class="line"><span class="ln">6</span><span class="cl">
</span></span><span class="line"><span class="ln">7</span><span class="cl"><span class="c1"># 跑 judge</span>
</span></span><span class="line"><span class="ln">8</span><span class="cl">python judge_harness.py</span></span></code></pre></div><p>這是 production quality engineering 閉環的本地版本、隱私敏感場景的 cost-free alternative。</p>
<h2 id="失敗模式">失敗模式</h2>
<ol>
<li><strong>Judge 不輸出合法 JSON</strong>：reasoning model 可能在 <code>&lt;think&gt;...&lt;/think&gt;</code> 後仍加 markdown / 解釋</li>
</ol>
<p><strong>緩解</strong>：parse 時跳 <code>&lt;think&gt;</code> 段、容錯處理、或開 <a href="/blog/llm/knowledge-cards/constrained-decoding/" data-link-title="Constrained Decoding" data-link-desc="推論時用 grammar 強制 LLM 輸出符合特定格式（JSON / regex / CFG）的 sampling 機制、把不合法 token 的機率歸零">constrained decoding</a>（llama.cpp grammar）</p>
<ol start="2">
<li><strong>Latency 太長、batch 跑不完</strong>：reasoning model 32B 每 item 60-120s、100 item 要 2 小時</li>
</ol>
<p><strong>緩解</strong>：用較小 judge model（如 Qwen2.5-32B instruct、非 reasoning）、或拆 batch 並行</p>
<ol start="3">
<li><strong>Judge bias 沒緩解</strong>：本地 judge 跟雲端 judge 都會有 verbosity / position bias</li>
</ol>
<p><strong>緩解</strong>：rubric 寫明、pairwise 換位置跑 2 次</p>
<ol start="4">
<li><strong>本地 judge 能力上限</strong>：30B distill 對 nuanced case 判讀不如雲端旗艦</li>
</ol>
<p><strong>緩解</strong>：critical case 加 spot human review、或混用本地（量大）+ 雲端（精選 sample）</p>
<h2 id="跟其他章節的關係">跟其他章節的關係</h2>
<ul>
<li>原理層的 LLM-as-judge 設計見 <a href="/blog/llm/04-applications/llm-as-judge/" data-link-title="4.21 LLM-as-Judge 評估方法" data-link-desc="LLM 評估 LLM 的 production eval 方法：rubric design、pairwise / direct scoring、三大 bias 緩解、跟 trace 串接的閉環、calibration">4.21</a></li>
<li>Production trace 串接見 <a href="/blog/llm/04-applications/llm-tracing-and-observability/" data-link-title="4.20 LLM tracing 與 observability" data-link-desc="OpenTelemetry GenAI semantic conventions、結構化 span 設計、cost / latency 監控、failure debug 流程、跟 LLM-as-judge eval 的串接">4.20 tracing</a></li>
<li>Reasoning model 選型見 <a href="/blog/llm/03-theoretical-foundations/reasoning-models/" data-link-title="3.8 Reasoning models：test-time compute paradigm" data-link-desc="Chain-of-thought 從 prompting 技巧演化成訓練 paradigm、reasoning model 的內部運作、本地可跑的選項與適用任務">3.8</a></li>
<li>隱私 / 跨雲端邊界判讀見 <a href="/blog/llm/06-security/cross-cloud-local-data-boundary/" data-link-title="6.4 跨雲端 / 本地的資料邊界" data-link-desc="個人 dev 場景下混用雲端 LLM 跟本地 LLM 時的 prompt 洩漏點：Continue.dev 多 provider 設定、隱私資料流、按敏感度分流的判讀">6.4</a></li>
<li>Benchmark 跟 in-house eval 的層次見 <a href="/blog/llm/04-applications/benchmarking-and-evaluation/" data-link-title="4.14 Benchmarking 與評估方法論" data-link-desc="判讀 model card benchmark 數字、做自己工作流的 in-house benchmark、量測本地推論速度的完整方法論">4.14</a></li>
</ul>
]]></content:encoded></item><item><title>4.12 Embedding model 內部：訓練、選型、in-domain fine-tune</title><link>https://tarrragon.github.io/blog/llm/04-applications/embedding-model-internals/</link><pubDate>Tue, 12 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/llm/04-applications/embedding-model-internals/</guid><description>&lt;p>&lt;a href="https://tarrragon.github.io/blog/llm/04-applications/rag-principles/" data-link-title="4.1 RAG 原理：retrieval &amp;#43; augmentation 模式" data-link-desc="為什麼模型需要外掛知識、語意相似 vs 字面相似、chunking 的本質取捨、retrieval 失敗的根本原因">RAG&lt;/a> 章節定義了 retrieval + augmentation 的二段式結構、但 retrieval 階段背後的 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/embedding-model/" data-link-title="Embedding Model" data-link-desc="把文字轉成向量的模型：用於 codebase 索引與語意搜尋">embedding model&lt;/a> 怎麼運作、怎麼選、什麼時候該換、什麼時候該自己 fine-tune、這些決策直接影響 RAG 品質。本章把 embedding model 的訓練機制、評估方法、實務選型展開。&lt;/p>
&lt;h2 id="本章目標">本章目標&lt;/h2>
&lt;p>讀完本章後、你應該能：&lt;/p>
&lt;ol>
&lt;li>解釋 embedding model 跟 base LLM 的訓練差異。&lt;/li>
&lt;li>看到 MTEB / BEIR 分數時、知道對自己場景的意義。&lt;/li>
&lt;li>對自己 domain 選對 embedding model（通用 vs code vs multilingual）。&lt;/li>
&lt;li>判斷「需要 fine-tune 自己的 embedding model」的時機跟方法。&lt;/li>
&lt;/ol>
&lt;h2 id="embedding-model-vs-llm-的訓練差異">Embedding model vs LLM 的訓練差異&lt;/h2>
&lt;p>兩者底層架構可能類似（都用 Transformer）、但訓練 objective 完全不同：&lt;/p>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>維度&lt;/th>
 &lt;th>LLM（如 Llama / Gemma instruct）&lt;/th>
 &lt;th>Embedding model（如 bge-large、jina-v3）&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>訓練 objective&lt;/td>
 &lt;td>Next-token prediction + RLHF&lt;/td>
 &lt;td>&lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/contrastive-learning/" data-link-title="Contrastive Learning" data-link-desc="用「相關 vs 不相關」成對 / 三元組樣本訓練 embedding 的方法、現代 embedding model 的核心訓練 paradigm">Contrastive learning&lt;/a>&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>輸出形式&lt;/td>
 &lt;td>一連串 token&lt;/td>
 &lt;td>一個固定維度的向量（如 768、1024）&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>訓練資料&lt;/td>
 &lt;td>Trillion-token 通用文字&lt;/td>
 &lt;td>億級的 (query, doc) 正向對&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>用法&lt;/td>
 &lt;td>Prompt → response&lt;/td>
 &lt;td>Text → vector&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Pretrained 起點&lt;/td>
 &lt;td>從 scratch 或繼承 base&lt;/td>
 &lt;td>通常從 base LLM 抽 hidden state 開始&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;p>關鍵理解：&lt;strong>不能拿任意 LLM 的最後 hidden state 當 embedding&lt;/strong> — LLM hidden state 是為「預測下一個 token」優化、不為「相似度比較」優化。要再經過 contrastive learning fine-tune 才能當 embedding model 用。&lt;/p>
&lt;p>Embedding model 的典型訓練 pipeline：&lt;/p>





&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-text" data-lang="text">&lt;span class="line">&lt;span class="ln"> 1&lt;/span>&lt;span class="cl">Stage 1: 從 base model 開始（如 BERT、RoBERTa、Mistral、Llama）
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 2&lt;/span>&lt;span class="cl"> ↓
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 3&lt;/span>&lt;span class="cl">Stage 2: Contrastive pre-training
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 4&lt;/span>&lt;span class="cl"> 用大量 weak supervised pair（如 Reddit title-body、StackExchange QA）
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 5&lt;/span>&lt;span class="cl"> InfoNCE loss、batch size 大、hard negative mining
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 6&lt;/span>&lt;span class="cl"> ↓
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 7&lt;/span>&lt;span class="cl">Stage 3: Supervised fine-tune
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 8&lt;/span>&lt;span class="cl"> 用標註好的 (query, relevant_doc) pair
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 9&lt;/span>&lt;span class="cl"> 來源如 MSMARCO、Natural Questions
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">10&lt;/span>&lt;span class="cl"> ↓
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">11&lt;/span>&lt;span class="cl">Stage 4（可選）: Task-specific instruction tuning
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">12&lt;/span>&lt;span class="cl"> 讓模型懂「task description」、可針對不同 retrieval 任務切換
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">13&lt;/span>&lt;span class="cl"> 代表：bge-large、e5-mistral-7b-instruct&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Stage 4 的「instruction-tuned embedding」是 2024 後流行的設計：query 前加「Represent this sentence for retrieving relevant passages:」這類前綴、embedding model 學會依任務調整向量。&lt;/p></description><content:encoded><![CDATA[<p><a href="/blog/llm/04-applications/rag-principles/" data-link-title="4.1 RAG 原理：retrieval &#43; augmentation 模式" data-link-desc="為什麼模型需要外掛知識、語意相似 vs 字面相似、chunking 的本質取捨、retrieval 失敗的根本原因">RAG</a> 章節定義了 retrieval + augmentation 的二段式結構、但 retrieval 階段背後的 <a href="/blog/llm/knowledge-cards/embedding-model/" data-link-title="Embedding Model" data-link-desc="把文字轉成向量的模型：用於 codebase 索引與語意搜尋">embedding model</a> 怎麼運作、怎麼選、什麼時候該換、什麼時候該自己 fine-tune、這些決策直接影響 RAG 品質。本章把 embedding model 的訓練機制、評估方法、實務選型展開。</p>
<h2 id="本章目標">本章目標</h2>
<p>讀完本章後、你應該能：</p>
<ol>
<li>解釋 embedding model 跟 base LLM 的訓練差異。</li>
<li>看到 MTEB / BEIR 分數時、知道對自己場景的意義。</li>
<li>對自己 domain 選對 embedding model（通用 vs code vs multilingual）。</li>
<li>判斷「需要 fine-tune 自己的 embedding model」的時機跟方法。</li>
</ol>
<h2 id="embedding-model-vs-llm-的訓練差異">Embedding model vs LLM 的訓練差異</h2>
<p>兩者底層架構可能類似（都用 Transformer）、但訓練 objective 完全不同：</p>
<table>
  <thead>
      <tr>
          <th>維度</th>
          <th>LLM（如 Llama / Gemma instruct）</th>
          <th>Embedding model（如 bge-large、jina-v3）</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>訓練 objective</td>
          <td>Next-token prediction + RLHF</td>
          <td><a href="/blog/llm/knowledge-cards/contrastive-learning/" data-link-title="Contrastive Learning" data-link-desc="用「相關 vs 不相關」成對 / 三元組樣本訓練 embedding 的方法、現代 embedding model 的核心訓練 paradigm">Contrastive learning</a></td>
      </tr>
      <tr>
          <td>輸出形式</td>
          <td>一連串 token</td>
          <td>一個固定維度的向量（如 768、1024）</td>
      </tr>
      <tr>
          <td>訓練資料</td>
          <td>Trillion-token 通用文字</td>
          <td>億級的 (query, doc) 正向對</td>
      </tr>
      <tr>
          <td>用法</td>
          <td>Prompt → response</td>
          <td>Text → vector</td>
      </tr>
      <tr>
          <td>Pretrained 起點</td>
          <td>從 scratch 或繼承 base</td>
          <td>通常從 base LLM 抽 hidden state 開始</td>
      </tr>
  </tbody>
</table>
<p>關鍵理解：<strong>不能拿任意 LLM 的最後 hidden state 當 embedding</strong> — LLM hidden state 是為「預測下一個 token」優化、不為「相似度比較」優化。要再經過 contrastive learning fine-tune 才能當 embedding model 用。</p>
<p>Embedding model 的典型訓練 pipeline：</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="ln"> 1</span><span class="cl">Stage 1: 從 base model 開始（如 BERT、RoBERTa、Mistral、Llama）
</span></span><span class="line"><span class="ln"> 2</span><span class="cl">   ↓
</span></span><span class="line"><span class="ln"> 3</span><span class="cl">Stage 2: Contrastive pre-training
</span></span><span class="line"><span class="ln"> 4</span><span class="cl">   用大量 weak supervised pair（如 Reddit title-body、StackExchange QA）
</span></span><span class="line"><span class="ln"> 5</span><span class="cl">   InfoNCE loss、batch size 大、hard negative mining
</span></span><span class="line"><span class="ln"> 6</span><span class="cl">   ↓
</span></span><span class="line"><span class="ln"> 7</span><span class="cl">Stage 3: Supervised fine-tune
</span></span><span class="line"><span class="ln"> 8</span><span class="cl">   用標註好的 (query, relevant_doc) pair
</span></span><span class="line"><span class="ln"> 9</span><span class="cl">   來源如 MSMARCO、Natural Questions
</span></span><span class="line"><span class="ln">10</span><span class="cl">   ↓
</span></span><span class="line"><span class="ln">11</span><span class="cl">Stage 4（可選）: Task-specific instruction tuning
</span></span><span class="line"><span class="ln">12</span><span class="cl">   讓模型懂「task description」、可針對不同 retrieval 任務切換
</span></span><span class="line"><span class="ln">13</span><span class="cl">   代表：bge-large、e5-mistral-7b-instruct</span></span></code></pre></div><p>Stage 4 的「instruction-tuned embedding」是 2024 後流行的設計：query 前加「Represent this sentence for retrieving relevant passages:」這類前綴、embedding model 學會依任務調整向量。</p>
<h2 id="選型維度">選型維度</h2>
<p>主流 embedding model 的選型維度：</p>
<h3 id="1-domain-相符">1. Domain 相符</h3>
<table>
  <thead>
      <tr>
          <th>Domain</th>
          <th>推薦模型</th>
          <th>為什麼</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>通用英文</td>
          <td>bge-large-en-v1.5、mxbai-embed-large-v1</td>
          <td>通用 corpus、MTEB Retrieval 高分</td>
      </tr>
      <tr>
          <td>通用多語</td>
          <td>jina-embeddings-v3、bge-m3、multilingual-e5</td>
          <td>多語 pretrain、中日韓阿等支援</td>
      </tr>
      <tr>
          <td>Code（讀 / 寫 code）</td>
          <td>jina-embeddings-v2-base-code、voyage-code-3</td>
          <td>code corpus 訓練、語意（函式名、註解）+ syntax 結合</td>
      </tr>
      <tr>
          <td>中文</td>
          <td>bge-large-zh、Conan-embedding</td>
          <td>中文 corpus 為主</td>
      </tr>
      <tr>
          <td>跨語言（中英混合）</td>
          <td>jina-embeddings-v3、multilingual-e5</td>
          <td>跨語言對齊訓練、中英 query 找對方語言 doc</td>
      </tr>
  </tbody>
</table>
<h3 id="2-大小模型大小--向量維度">2. 大小（模型大小 / 向量維度）</h3>
<table>
  <thead>
      <tr>
          <th>Tier</th>
          <th>模型大小</th>
          <th>向量維度</th>
          <th>Latency / 記憶體</th>
          <th>適合場景</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>小（&lt; 200M）</td>
          <td>nomic-embed (137M)、all-MiniLM (23M)</td>
          <td>384-768</td>
          <td>快、本機 CPU 可跑</td>
          <td>本地 RAG、簡單 retrieval</td>
      </tr>
      <tr>
          <td>中（200-500M）</td>
          <td>bge-large (335M)、mxbai-embed-large</td>
          <td>1024</td>
          <td>中、需要 GPU 或 fast CPU</td>
          <td>主力 RAG、品質敏感場景</td>
      </tr>
      <tr>
          <td>大（500M-7B）</td>
          <td>e5-mistral-7b、Linq-Embed-Mistral</td>
          <td>4096</td>
          <td>慢、需要 GPU</td>
          <td>高品質、雲端、Reranking 場景</td>
      </tr>
      <tr>
          <td>雲端 API</td>
          <td>OpenAI text-embedding-3、voyage-3</td>
          <td>1024-3072</td>
          <td>網路 latency + API 成本</td>
          <td>雲端 RAG、高 QPS</td>
      </tr>
  </tbody>
</table>
<h3 id="3-context-window-上限">3. Context window 上限</h3>
<p>不同 embedding model 對單次 embed 的 token 上限不同：</p>
<table>
  <thead>
      <tr>
          <th>模型</th>
          <th>Context limit</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>早期 sentence-transformers</td>
          <td>256-512 tokens</td>
      </tr>
      <tr>
          <td>bge-large / mxbai-embed</td>
          <td>512 tokens</td>
      </tr>
      <tr>
          <td>nomic-embed-text-v1.5</td>
          <td>8192 tokens</td>
      </tr>
      <tr>
          <td>jina-embeddings-v3</td>
          <td>8192 tokens</td>
      </tr>
      <tr>
          <td>voyage-3</td>
          <td>32K tokens</td>
      </tr>
  </tbody>
</table>
<blockquote>
<p><strong>事實查核註</strong>：本節所列具體型號（bge-large-en-v1.5、jina-embeddings-v3、nomic-embed-text-v1.5、voyage-3 等）、向量維度、context limit、訓練資料 domain、MTEB / BEIR 排名 — 都是 2026/5 主流版本的估計、各模型升級節奏快、引用前以 <a href="https://huggingface.co/spaces/mteb/leaderboard">MTEB Leaderboard</a> 跟對應 model card 當前狀態為準。</p></blockquote>
<p>選擇影響 chunking 策略（見 <a href="/blog/llm/04-applications/rag-principles/" data-link-title="4.1 RAG 原理：retrieval &#43; augmentation 模式" data-link-desc="為什麼模型需要外掛知識、語意相似 vs 字面相似、chunking 的本質取捨、retrieval 失敗的根本原因">4.1 RAG</a> 的 chunking 段）：短 context embedding 要切細、長 context embedding 可保留更完整段落、但內部 attention 對長段中段仍可能 lost-in-the-middle。</p>
<h3 id="4-cosine-similarity-設計">4. Cosine similarity 設計</h3>
<p>部分 embedding model 訓練時就 L2-normalized、用 cosine = dot product；部分沒 normalize、要自己處理：</p>
<table>
  <thead>
      <tr>
          <th>Model</th>
          <th>Normalize 預設</th>
          <th>推薦 distance metric</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>bge-large、mxbai-embed</td>
          <td>已 L2-normalize</td>
          <td>Dot product（高效、結果同 cosine）</td>
      </tr>
      <tr>
          <td>nomic-embed-text</td>
          <td>已 L2-normalize</td>
          <td>Dot product</td>
      </tr>
      <tr>
          <td>OpenAI ada-002 / 3</td>
          <td>已 L2-normalize</td>
          <td>Dot product</td>
      </tr>
      <tr>
          <td>自訓練 / 早期模型</td>
          <td>未 normalize</td>
          <td>Cosine similarity</td>
      </tr>
  </tbody>
</table>
<blockquote>
<p>詳細見 <a href="/blog/llm/knowledge-cards/vector-norm/" data-link-title="Vector Norm" data-link-desc="衡量向量大小的純量值、L1 / L2 / L∞ 各有用途、cosine similarity 的基礎">vector-norm</a> 跟 <a href="/blog/llm/knowledge-cards/dot-product/" data-link-title="Dot Product" data-link-desc="兩個向量對應位置相乘再加總、attention score 跟相似度判讀的基礎">dot-product</a> 卡片。</p></blockquote>
<h2 id="評估mteb-跟自己-domain-的對齊">評估：MTEB 跟自己 domain 的對齊</h2>
<p><a href="/blog/llm/knowledge-cards/mteb-benchmark/" data-link-title="MTEB" data-link-desc="Massive Text Embedding Benchmark：8 大類 56 任務、評估 embedding model 跨任務通用能力的標準">MTEB</a> 是現在挑選 embedding model 最常用的 leaderboard、但要正確讀：</p>
<ol>
<li><strong>看 Retrieval 子分數、不是 Overall</strong>：MTEB 含 8 大類、跟 RAG 最直接相關的是 Retrieval 跟 Reranking</li>
<li><strong>跟自己 domain 對齊</strong>：MTEB 通用 corpus、自己 domain 可能跟 MTEB 落差大</li>
<li><strong>In-domain benchmark 才是 final test</strong>：用自己工作流的真實 query 跟 expected doc、自建小型評估集（如 100-200 對）、看候選 embedding model 的 hit rate / nDCG</li>
</ol>
<p>In-domain 評估的最小可行流程：</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="ln">1</span><span class="cl"><span class="c1"># 偽代碼</span>
</span></span><span class="line"><span class="ln">2</span><span class="cl"><span class="mf">1.</span> <span class="n">蒐集</span> <span class="mi">50</span><span class="o">-</span><span class="mi">100</span> <span class="n">個</span> <span class="n">query</span> <span class="o">+</span> <span class="n">expected_doc</span><span class="err">（</span><span class="n">已知答案的對</span><span class="err">）</span>
</span></span><span class="line"><span class="ln">3</span><span class="cl"><span class="mf">2.</span> <span class="n">對</span> <span class="n">candidate</span> <span class="n">embedding</span> <span class="n">models</span> <span class="n">各跑</span><span class="err">：</span>
</span></span><span class="line"><span class="ln">4</span><span class="cl">   <span class="o">-</span> <span class="n">embed</span> <span class="n">所有</span> <span class="n">doc</span><span class="err">（</span><span class="n">含</span> <span class="n">expected</span> <span class="n">跟</span> <span class="n">distractor</span><span class="err">、</span><span class="o">~</span><span class="mi">1000</span> <span class="n">個</span> <span class="n">distractor</span><span class="err">）</span>
</span></span><span class="line"><span class="ln">5</span><span class="cl">   <span class="o">-</span> <span class="n">embed</span> <span class="n">每個</span> <span class="n">query</span>
</span></span><span class="line"><span class="ln">6</span><span class="cl">   <span class="o">-</span> <span class="n">算</span> <span class="n">query</span><span class="o">-</span><span class="n">doc</span> <span class="n">similarity</span><span class="err">、</span><span class="n">看</span> <span class="n">expected</span> <span class="n">是否在</span> <span class="n">top</span><span class="o">-</span><span class="mi">5</span> <span class="o">/</span> <span class="n">top</span><span class="o">-</span><span class="mi">10</span>
</span></span><span class="line"><span class="ln">7</span><span class="cl"><span class="mf">3.</span> <span class="n">比較</span> <span class="n">candidate</span> <span class="n">的</span> <span class="n">hit_rate</span><span class="o">@</span><span class="mi">5</span> <span class="o">/</span> <span class="n">hit_rate</span><span class="o">@</span><span class="mi">10</span></span></span></code></pre></div><p>跑完這個再決定用哪個 embedding model、比看 MTEB leaderboard 可靠很多。</p>
<h2 id="實務選型的-constraint-優先序">實務選型的 constraint 優先序</h2>
<p>上面四個維度（domain / 大小 / context / cosine 設計）跟 MTEB 評估是「品質軸」— 哪個 embedding model 最能解你的 retrieval 問題。但實際選型時，品質軸之前通常有一組<strong>工程 constraint 先砍掉大量選項</strong>，剩下的候選才進品質比較。</p>
<p>常見的工程 constraint 依砍選項力度排序：</p>
<ol>
<li><strong>Runtime 可用性</strong>：推論伺服器支援哪些模型？Ollama 目前原生支援 <code>nomic-embed-text</code>、<code>mxbai-embed-large</code>、<code>snowflake-arctic-embed</code> 等，但不支援所有 Hugging Face 模型。用 cloud API（OpenAI / Cohere / Voyage）則受 vendor 綁定跟成本約束。這一條通常砍掉最多選項。</li>
<li><strong>體積 / 記憶體預算</strong>：個人機器常駐 embedding model 跟 chat model 共用記憶體。137M 的 <code>nomic-embed-text</code> 跟 7B 的 <code>e5-mistral</code> 在記憶體佔用上差一個數量級。</li>
<li><strong>已有驗證基線</strong>：團隊或前期 demo 已用某個模型跑過、retrieval 品質已確認可用。換模型要重建 index + 重新驗證，成本不只是 MTEB 分數比較。</li>
<li><strong>向量維度的 storage 成本</strong>：維度影響 index 大小（n × d × 4 bytes）跟 brute-force search 延遲。768 維 vs 1024 維在小規模無感，但 100K+ chunks 時差異開始有意義。詳見 <a href="/blog/llm/04-applications/vector-storage-engineering/" data-link-title="4.22 RAG storage 工程：從 pickle 到 vector database 的選型判讀" data-link-desc="RAG storage backend 選型：規模到哪個階段該從 in-memory 升級到 vector DB、dependency chain 如何收窄選項">4.22 RAG storage 工程</a>。</li>
</ol>
<p>實務流程是：先用 constraint 1-3 收窄到 2-3 個候選，再跑 in-domain benchmark（上段的 hit rate 流程）做最終決定。直接從 MTEB leaderboard 挑最高分的模型、到實際場景才發現 runtime 不支援或體積太大，是常見的繞路。</p>
<h2 id="何時該-fine-tune-自己的-embedding-model">何時該 fine-tune 自己的 embedding model</h2>
<p>通常<strong>不該</strong> fine-tune embedding model — 用現成的 bge-large、jina-v3 已經很好。但下列情境值得評估：</p>
<ol>
<li>
<p><strong>Domain 跟通用 corpus 差距大</strong>：</p>
<ul>
<li>醫療 / 法律 / 金融的專業術語、通用 embedding model 對「同義詞」「同概念不同表述」recall 差</li>
<li>In-domain term frequency 跟通用 corpus 差距大（如「IRA」在金融 vs 政治語境）</li>
</ul>
</li>
<li>
<p><strong>In-domain benchmark hit rate 顯著低於通用 benchmark</strong>：</p>
<ul>
<li>用 MTEB 高分模型、in-domain hit rate@5 仍 &lt; 60%</li>
<li>換多個候選 embedding model、所有都類似低分</li>
</ul>
</li>
<li>
<p><strong>有足夠 in-domain (query, doc) 對</strong>：</p>
<ul>
<li>Fine-tune 需要至少數千對、最好 1-10 萬對</li>
<li>對少於 1000 對的場景、fine-tune 收益通常低於數據增強 / 提升 retrieval pipeline</li>
</ul>
</li>
</ol>
<p>Fine-tune 流程（詳細）：</p>
<h3 id="step-1蒐集-in-domain-training-data">Step 1：蒐集 in-domain training data</h3>
<p>三種主流形態：</p>
<table>
  <thead>
      <tr>
          <th>Format</th>
          <th>結構</th>
          <th>蒐集難度</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Positive pair</td>
          <td>(query, relevant_doc)</td>
          <td>容易（從 click log、QA pair）</td>
      </tr>
      <tr>
          <td>Triplet</td>
          <td>(anchor, positive, negative)</td>
          <td>中（要明確 negative）</td>
      </tr>
      <tr>
          <td>Score / label</td>
          <td>(query, doc, relevance_score)</td>
          <td>難（要人工標）</td>
      </tr>
  </tbody>
</table>
<p>實務多從 positive pair 開始（InfoNCE loss 在 batch 內自動取其他樣本當 negative）、品質提升再進 triplet（hard negative mining）。</p>
<h3 id="step-2選-base-model">Step 2：選 base model</h3>
<p>選擇看資料量跟硬體：</p>
<table>
  <thead>
      <tr>
          <th>起始 base model</th>
          <th>適合資料量</th>
          <th>適合硬體</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>sentence-transformers MiniLM</td>
          <td>1K - 50K 對</td>
          <td>一般 CPU / 小 GPU</td>
      </tr>
      <tr>
          <td>BGE-base / bge-small</td>
          <td>10K - 100K 對</td>
          <td>16GB+ GPU</td>
      </tr>
      <tr>
          <td>BGE-large / jina-v3 / mxbai</td>
          <td>50K+ 對</td>
          <td>24GB+ GPU</td>
      </tr>
      <tr>
          <td>E5-Mistral-7B-instruct</td>
          <td>100K+ 對</td>
          <td>多卡 / A100</td>
      </tr>
  </tbody>
</table>
<p>選擇原則：base model 在 generic benchmark 越強、fine-tune 後上限越高、但訓練成本越高。</p>
<h3 id="step-3loss-選擇">Step 3：Loss 選擇</h3>
<table>
  <thead>
      <tr>
          <th>Loss</th>
          <th>機制</th>
          <th>適合</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>MultipleNegativesRankingLoss</td>
          <td>InfoNCE 變體、batch 內其他樣本當 negative</td>
          <td>Positive pair only、大 batch</td>
      </tr>
      <tr>
          <td>Triplet loss</td>
          <td>直接比 (anchor, positive, negative) 距離</td>
          <td>有明確 triplet、傳統選擇</td>
      </tr>
      <tr>
          <td>Cosine similarity loss</td>
          <td>預測相似度標籤</td>
          <td>Score / label data</td>
      </tr>
      <tr>
          <td>Contrastive tension loss</td>
          <td>對比學習變體、效果好</td>
          <td>大規模 fine-tune</td>
      </tr>
  </tbody>
</table>
<p>實務 default：MultipleNegativesRankingLoss + batch size 64-128（越大 negatives 越多、品質越高）。</p>
<h3 id="step-4hard-negative-mining">Step 4：Hard negative mining</h3>
<p>純隨機 negative（batch 內其他樣本）容易、但 hard negative（看似相關但實際無關）才能 push 模型品質：</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="ln">1</span><span class="cl">1. 用初版 fine-tuned model 對每個 query 跑 retrieve top-50
</span></span><span class="line"><span class="ln">2</span><span class="cl">2. 對每個 query 的 top-50：
</span></span><span class="line"><span class="ln">3</span><span class="cl">   - 真正 relevant doc（known positive）→ skip
</span></span><span class="line"><span class="ln">4</span><span class="cl">   - 其他 → 候選 hard negative
</span></span><span class="line"><span class="ln">5</span><span class="cl">3. 篩 hard negatives（LLM-as-judge 或人工確認真的「看似相關但不對」）
</span></span><span class="line"><span class="ln">6</span><span class="cl">4. 用 (query, positive, hard_negative) 重訓
</span></span><span class="line"><span class="ln">7</span><span class="cl">5. Iterate 2-3 輪</span></span></code></pre></div><p>Hard negative 是 embedding fine-tune 品質的關鍵差距 — 沒做的 fine-tune 通常 plateau 早、做了的可超越通用 model。</p>
<h3 id="step-5lora-fine-tune-而非-full-fine-tune">Step 5：LoRA fine-tune 而非 full fine-tune</h3>
<p>跟 LLM fine-tune 一樣、embedding model fine-tune 也用 <a href="/blog/llm/knowledge-cards/lora/" data-link-title="LoRA" data-link-desc="Low-Rank Adaptation：凍住原模型權重、只訓兩個小矩陣的 parameter-efficient fine-tuning">LoRA</a>：</p>
<table>
  <thead>
      <tr>
          <th>方式</th>
          <th>訓練成本</th>
          <th>通用能力保留</th>
          <th>推論方式</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Full fine-tune</td>
          <td>高</td>
          <td>易 <a href="/blog/llm/knowledge-cards/catastrophic-forgetting/" data-link-title="Catastrophic Forgetting" data-link-desc="Fine-tune 模型時、新訓練資料覆蓋掉原本學到的能力的現象、LoRA / 資料 mixing 是主要緩解">catastrophic forgetting</a></td>
          <td>部署新權重</td>
      </tr>
      <tr>
          <td>LoRA fine-tune</td>
          <td>低</td>
          <td>保留好</td>
          <td>載入 base + adapter</td>
      </tr>
  </tbody>
</table>
<p>主流 framework：sentence-transformers + PEFT、Hugging Face Transformers + LoRA library。</p>
<h3 id="step-6evaluate">Step 6：Evaluate</h3>
<p>不只看 training loss、要實測：</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="ln">1</span><span class="cl">1. Build in-domain test set（held-out、跟 training 完全分開）
</span></span><span class="line"><span class="ln">2</span><span class="cl">2. 算 [hit_rate@K](/llm/knowledge-cards/retrieval-recall/)（query 的 expected doc 是否在 top-K retrieval result）
</span></span><span class="line"><span class="ln">3</span><span class="cl">3. 跟「base model 未 fine-tune」對比：
</span></span><span class="line"><span class="ln">4</span><span class="cl">   - Fine-tune 後 hit_rate@5 提升 ≥ 10 percentage point → 成功
</span></span><span class="line"><span class="ln">5</span><span class="cl">   - 提升 &lt; 5pp → fine-tune 沒效益、不如優化 retrieval pipeline
</span></span><span class="line"><span class="ln">6</span><span class="cl">4. 確認沒崩通用能力：在 MTEB 跑、看主流 retrieval 任務沒大降</span></span></code></pre></div><h3 id="失敗模式">失敗模式</h3>
<table>
  <thead>
      <tr>
          <th>失敗</th>
          <th>緩解</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>資料太少（&lt; 1000 對）、模型沒學到</td>
          <td>數據增強（用 LLM 生 synthetic pair）、改用 prompt + RAG</td>
      </tr>
      <tr>
          <td>訓練 loss 降但 hit_rate 沒升</td>
          <td>Hard negative 不夠、要重 mine</td>
      </tr>
      <tr>
          <td>In-domain 提升但通用能力崩</td>
          <td>加 mixed dataset（80% domain + 20% MTEB）</td>
      </tr>
      <tr>
          <td>Embedding dim 不能改</td>
          <td>Base model 已固定 dim、自己訓 from scratch 才能改</td>
      </tr>
      <tr>
          <td>部署時跟 base model 衝突</td>
          <td>LoRA adapter merge 進 base 後部署、或同時 serve 兩版</td>
      </tr>
  </tbody>
</table>
<h2 id="跟-llm-的整合retrieval-pipeline">跟 LLM 的整合：retrieval pipeline</h2>
<p>完整 RAG pipeline 裡 embedding model 的位置：</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="ln"> 1</span><span class="cl">[Ingestion 階段（離線）]
</span></span><span class="line"><span class="ln"> 2</span><span class="cl">  Documents
</span></span><span class="line"><span class="ln"> 3</span><span class="cl">    ↓ chunking
</span></span><span class="line"><span class="ln"> 4</span><span class="cl">  Chunks
</span></span><span class="line"><span class="ln"> 5</span><span class="cl">    ↓ embedding model
</span></span><span class="line"><span class="ln"> 6</span><span class="cl">  Chunk vectors → 存進 vector DB
</span></span><span class="line"><span class="ln"> 7</span><span class="cl">
</span></span><span class="line"><span class="ln"> 8</span><span class="cl">[Query 階段（線上）]
</span></span><span class="line"><span class="ln"> 9</span><span class="cl">  User query
</span></span><span class="line"><span class="ln">10</span><span class="cl">    ↓ embedding model
</span></span><span class="line"><span class="ln">11</span><span class="cl">  Query vector
</span></span><span class="line"><span class="ln">12</span><span class="cl">    ↓ vector DB ANN search
</span></span><span class="line"><span class="ln">13</span><span class="cl">  Top-K chunks
</span></span><span class="line"><span class="ln">14</span><span class="cl">    ↓ (optional) reranking
</span></span><span class="line"><span class="ln">15</span><span class="cl">  Top-N chunks
</span></span><span class="line"><span class="ln">16</span><span class="cl">    ↓ augment LLM prompt
</span></span><span class="line"><span class="ln">17</span><span class="cl">  LLM response</span></span></code></pre></div><p>關鍵設計決策：</p>
<ol>
<li><strong>Embedding model 一致性</strong>：ingestion 跟 query 必須用同個 model（換 model = 整批 re-embed）；chunk vectors 存進 vector DB 之後的 index 結構、維度成本與生命週期見 <a href="/blog/llm/04-applications/vector-storage-engineering/" data-link-title="4.22 RAG storage 工程：從 pickle 到 vector database 的選型判讀" data-link-desc="RAG storage backend 選型：規模到哪個階段該從 in-memory 升級到 vector DB、dependency chain 如何收窄選項">4.22 RAG storage 工程</a></li>
<li><strong>Chunking 策略對齊 embedding context</strong>：見 <a href="/blog/llm/04-applications/rag-principles/" data-link-title="4.1 RAG 原理：retrieval &#43; augmentation 模式" data-link-desc="為什麼模型需要外掛知識、語意相似 vs 字面相似、chunking 的本質取捨、retrieval 失敗的根本原因">4.1 RAG chunking</a></li>
<li><strong>Reranking model 通常用 cross-encoder</strong>：embedding model 是 bi-encoder（query 跟 doc 分開 embed）、reranker 是 cross-encoder（query + doc 一起算）、品質更高但慢、適合在 top-50 → top-5 之間做 reranking</li>
<li><strong>Hybrid retrieval</strong>：BM25（字面）+ embedding（語意）混用、用 RRF（Reciprocal Rank Fusion）合併、是 production 常見配置</li>
</ol>
<h2 id="本地-vs-雲端-embedding">本地 vs 雲端 embedding</h2>
<table>
  <thead>
      <tr>
          <th>維度</th>
          <th>本地（如 nomic-embed）</th>
          <th>雲端（如 OpenAI text-embedding-3）</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>隱私</td>
          <td>完全本地、no exfil</td>
          <td>API 送 doc、依政策 log</td>
      </tr>
      <tr>
          <td>成本</td>
          <td>一次硬體 + 電費</td>
          <td>按 token 計費、長期可累積</td>
      </tr>
      <tr>
          <td>品質</td>
          <td>bge-large / jina-v3 已接近雲端旗艦</td>
          <td>略高（旗艦如 voyage-3 仍領先）</td>
      </tr>
      <tr>
          <td>Latency</td>
          <td>視硬體、本地 SSD 快</td>
          <td>網路 latency</td>
      </tr>
      <tr>
          <td>多語 / domain</td>
          <td>開源選擇多、可挑 domain-specific</td>
          <td>API 是通用、不一定最佳 domain match</td>
      </tr>
  </tbody>
</table>
<p>寫 code 場景的判讀：</p>
<ul>
<li><strong>codebase 內部 RAG（NDA / 機密 code）</strong>：本地 embedding 必選</li>
<li><strong>個人開源專案 RAG</strong>：本地 embedding 是合理 default、簡單、free</li>
<li><strong>公司內部 RAG（需高品質、量大）</strong>：評估 voyage-3 / OpenAI v3 vs 本地 bge-large</li>
<li><strong>產品級 production RAG</strong>：通常雲端 API + 自己 fine-tune 的 embedding（最佳品質）</li>
</ul>
<h2 id="何時過時--何時不過時">何時過時 / 何時不過時</h2>
<p><strong>不會過時的部分</strong>：</p>
<ul>
<li>Contrastive learning 是 embedding model 的核心訓練 paradigm</li>
<li>MTEB 作為通用 embedding 評估的角色</li>
<li>「跟自己 domain 對齊」的 in-domain benchmark 必要性</li>
<li>Bi-encoder vs cross-encoder 的分工（retrieval vs reranking）</li>
<li>Hybrid retrieval（BM25 + embedding）的設計</li>
</ul>
<p><strong>會變的部分</strong>：</p>
<ul>
<li>具體 embedding model（bge → bge-v2 → &hellip;、jina-v3 → v4 → &hellip;）</li>
<li>MTEB leaderboard 排名（每月變）</li>
<li>Instruction-tuned embedding 的 prompt format（標準化中）</li>
<li>Embedding model 的 context window 上限（推升中）</li>
<li>Long-context embedding 的研究（如 ColBERT-style late interaction）</li>
</ul>
<h2 id="下一章">下一章</h2>
<p>沒 backend 的靜態場景（個人 blog / docs site）做 embedding 搜尋的 deployment 選擇見 <a href="/blog/llm/04-applications/static-and-serverless-rag-deployment/" data-link-title="4.16 靜態 / serverless RAG deployment：架構選擇與資安取捨" data-link-desc="沒 backend 的場景怎麼做 RAG：四種 deployment 方案、API key 暴露問題、CORS / abuse / 第三方信任、跟模組六的 routing">4.16 靜態 / serverless RAG deployment</a>。</p>
<p>下一章：<a href="/blog/llm/04-applications/eval-design-framework/" data-link-title="4.13 Eval 設計座標系：三軸、八象限、何時測什麼" data-link-desc="Eval 設計三軸（objective↔subjective / component↔end-to-end / quantitative↔qualitative）、八象限的對應 eval 工具、軸選錯的訊號、跟 benchmarking / LLM-as-judge / tracing 的關係">4.13 Eval 設計座標系</a>、看 eval 三軸八象限 meta 框架（先選軸再選工具）、再進 <a href="/blog/llm/04-applications/benchmarking-and-evaluation/" data-link-title="4.14 Benchmarking 與評估方法論" data-link-desc="判讀 model card benchmark 數字、做自己工作流的 in-house benchmark、量測本地推論速度的完整方法論">4.14 Benchmarking 與評估方法論</a> 看具體 benchmark 設計。</p>
]]></content:encoded></item><item><title>4.13 Eval 設計座標系：三軸、八象限、何時測什麼</title><link>https://tarrragon.github.io/blog/llm/04-applications/eval-design-framework/</link><pubDate>Thu, 14 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/llm/04-applications/eval-design-framework/</guid><description>&lt;p>LLM 應用的「怎麼測」問題大家都在問、但答案常常是「跑某個 benchmark」「找個 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/llm-as-judge/" data-link-title="LLM-as-Judge" data-link-desc="用 LLM 評估另一個 LLM 的輸出品質、production eval 的主流方法、500-5000× 成本降但有 bias 要處理">LLM judge&lt;/a>」這類&lt;strong>工具層&lt;/strong>回答。實務上工具是末端、設計重點是&lt;strong>先選測什麼軸、再選工具&lt;/strong>。軸選錯了、再好的工具也測不出有用訊號——用 subjective 工具測 objective 行為（例如用 LLM judge 看金額計算對不對）、或用 end-to-end 工具測 component bug（例如看 user satisfaction 但其實是 retrieval pipeline 在漏 chunk）、都是常見的軸誤選。&lt;/p>
&lt;p>本章寫 eval 設計的座標系：三個 binary 軸、八個象限、每個象限對應什麼工具、軸選錯的訊號怎麼識別。這層 framing 是 meta、不是具體 eval 方法——具體方法在 &lt;a href="https://tarrragon.github.io/blog/llm/04-applications/benchmarking-and-evaluation/" data-link-title="4.14 Benchmarking 與評估方法論" data-link-desc="判讀 model card benchmark 數字、做自己工作流的 in-house benchmark、量測本地推論速度的完整方法論">4.14 benchmarking&lt;/a> 跟 &lt;a href="https://tarrragon.github.io/blog/llm/04-applications/llm-as-judge/" data-link-title="4.21 LLM-as-Judge 評估方法" data-link-desc="LLM 評估 LLM 的 production eval 方法：rubric design、pairwise / direct scoring、三大 bias 緩解、跟 trace 串接的閉環、calibration">4.21 LLM-as-Judge&lt;/a>。&lt;/p>
&lt;h2 id="本章目標">本章目標&lt;/h2>
&lt;p>讀完本章後你能：&lt;/p>
&lt;ol>
&lt;li>把任何 eval 需求放到三軸座標、定位象限。&lt;/li>
&lt;li>對每個象限選對應的 eval 工具。&lt;/li>
&lt;li>識別軸誤選的訊號、避免「工具對、軸錯」的常見坑。&lt;/li>
&lt;li>規劃 eval 路線：初期該做哪幾個象限、規模化後再補哪些。&lt;/li>
&lt;li>把 eval 設計跟 &lt;a href="https://tarrragon.github.io/blog/llm/04-applications/benchmarking-and-evaluation/" data-link-title="4.14 Benchmarking 與評估方法論" data-link-desc="判讀 model card benchmark 數字、做自己工作流的 in-house benchmark、量測本地推論速度的完整方法論">4.14 benchmarking&lt;/a> / &lt;a href="https://tarrragon.github.io/blog/llm/04-applications/llm-tracing-and-observability/" data-link-title="4.20 LLM tracing 與 observability" data-link-desc="OpenTelemetry GenAI semantic conventions、結構化 span 設計、cost / latency 監控、failure debug 流程、跟 LLM-as-judge eval 的串接">4.20 tracing&lt;/a> / &lt;a href="https://tarrragon.github.io/blog/llm/04-applications/llm-as-judge/" data-link-title="4.21 LLM-as-Judge 評估方法" data-link-desc="LLM 評估 LLM 的 production eval 方法：rubric design、pairwise / direct scoring、三大 bias 緩解、跟 trace 串接的閉環、calibration">4.21 LLM-as-Judge&lt;/a> 串成完整 pipeline。&lt;/li>
&lt;/ol>
&lt;h2 id="三軸">三軸&lt;/h2>
&lt;p>Eval 設計的三個正交軸：&lt;/p>
&lt;h3 id="軸-1objective--subjective">軸 1：Objective ↔ Subjective&lt;/h3>
&lt;ul>
&lt;li>&lt;strong>Objective&lt;/strong>：有明確 ground truth、檢驗可以寫成 deterministic check（金額對不對、SQL 跑得通不通、JSON schema 合不合法）。&lt;/li>
&lt;li>&lt;strong>Subjective&lt;/strong>：沒有單一正確答案、需要評分或比較（語氣好不好、解釋清楚不清楚、推薦的 trip 合不合用戶）。&lt;/li>
&lt;/ul>
&lt;p>判讀訊號：「能不能用 Python 函數判定對錯」、能 → objective、不能 → subjective。&lt;/p>
&lt;h3 id="軸-2component--end-to-end">軸 2：Component ↔ End-to-End&lt;/h3>
&lt;ul>
&lt;li>&lt;strong>Component&lt;/strong>：測單一元件、孤立評估（retrieval 拿對 chunk 沒、tool call 參數對沒、prompt 抽出正確 entity 沒）。&lt;/li>
&lt;li>&lt;strong>End-to-End&lt;/strong>：測完整流程、user 視角結果（user 問題有沒有被解決、訂單有沒有完成、conversation 滿意度）。&lt;/li>
&lt;/ul>
&lt;p>判讀訊號：「失敗時你想知道是哪一段壞掉」→ component；「你只在乎最終體驗」→ end-to-end。&lt;/p>
&lt;h3 id="軸-3quantitative--qualitative">軸 3：Quantitative ↔ Qualitative&lt;/h3>
&lt;ul>
&lt;li>&lt;strong>Quantitative&lt;/strong>：產出數字（accuracy / latency / cost / pass rate）、可以追蹤、可以比較、可以 alert。&lt;/li>
&lt;li>&lt;strong>Qualitative&lt;/strong>：產出觀察（error pattern、user 抱怨、reviewer 註記）、無法直接 aggregate、但能引導 hypothesis。&lt;/li>
&lt;/ul>
&lt;p>判讀訊號：「結果能算平均嗎」→ quantitative；「結果是讀完才知道」→ qualitative。&lt;/p></description><content:encoded><![CDATA[<p>LLM 應用的「怎麼測」問題大家都在問、但答案常常是「跑某個 benchmark」「找個 <a href="/blog/llm/knowledge-cards/llm-as-judge/" data-link-title="LLM-as-Judge" data-link-desc="用 LLM 評估另一個 LLM 的輸出品質、production eval 的主流方法、500-5000× 成本降但有 bias 要處理">LLM judge</a>」這類<strong>工具層</strong>回答。實務上工具是末端、設計重點是<strong>先選測什麼軸、再選工具</strong>。軸選錯了、再好的工具也測不出有用訊號——用 subjective 工具測 objective 行為（例如用 LLM judge 看金額計算對不對）、或用 end-to-end 工具測 component bug（例如看 user satisfaction 但其實是 retrieval pipeline 在漏 chunk）、都是常見的軸誤選。</p>
<p>本章寫 eval 設計的座標系：三個 binary 軸、八個象限、每個象限對應什麼工具、軸選錯的訊號怎麼識別。這層 framing 是 meta、不是具體 eval 方法——具體方法在 <a href="/blog/llm/04-applications/benchmarking-and-evaluation/" data-link-title="4.14 Benchmarking 與評估方法論" data-link-desc="判讀 model card benchmark 數字、做自己工作流的 in-house benchmark、量測本地推論速度的完整方法論">4.14 benchmarking</a> 跟 <a href="/blog/llm/04-applications/llm-as-judge/" data-link-title="4.21 LLM-as-Judge 評估方法" data-link-desc="LLM 評估 LLM 的 production eval 方法：rubric design、pairwise / direct scoring、三大 bias 緩解、跟 trace 串接的閉環、calibration">4.21 LLM-as-Judge</a>。</p>
<h2 id="本章目標">本章目標</h2>
<p>讀完本章後你能：</p>
<ol>
<li>把任何 eval 需求放到三軸座標、定位象限。</li>
<li>對每個象限選對應的 eval 工具。</li>
<li>識別軸誤選的訊號、避免「工具對、軸錯」的常見坑。</li>
<li>規劃 eval 路線：初期該做哪幾個象限、規模化後再補哪些。</li>
<li>把 eval 設計跟 <a href="/blog/llm/04-applications/benchmarking-and-evaluation/" data-link-title="4.14 Benchmarking 與評估方法論" data-link-desc="判讀 model card benchmark 數字、做自己工作流的 in-house benchmark、量測本地推論速度的完整方法論">4.14 benchmarking</a> / <a href="/blog/llm/04-applications/llm-tracing-and-observability/" data-link-title="4.20 LLM tracing 與 observability" data-link-desc="OpenTelemetry GenAI semantic conventions、結構化 span 設計、cost / latency 監控、failure debug 流程、跟 LLM-as-judge eval 的串接">4.20 tracing</a> / <a href="/blog/llm/04-applications/llm-as-judge/" data-link-title="4.21 LLM-as-Judge 評估方法" data-link-desc="LLM 評估 LLM 的 production eval 方法：rubric design、pairwise / direct scoring、三大 bias 緩解、跟 trace 串接的閉環、calibration">4.21 LLM-as-Judge</a> 串成完整 pipeline。</li>
</ol>
<h2 id="三軸">三軸</h2>
<p>Eval 設計的三個正交軸：</p>
<h3 id="軸-1objective--subjective">軸 1：Objective ↔ Subjective</h3>
<ul>
<li><strong>Objective</strong>：有明確 ground truth、檢驗可以寫成 deterministic check（金額對不對、SQL 跑得通不通、JSON schema 合不合法）。</li>
<li><strong>Subjective</strong>：沒有單一正確答案、需要評分或比較（語氣好不好、解釋清楚不清楚、推薦的 trip 合不合用戶）。</li>
</ul>
<p>判讀訊號：「能不能用 Python 函數判定對錯」、能 → objective、不能 → subjective。</p>
<h3 id="軸-2component--end-to-end">軸 2：Component ↔ End-to-End</h3>
<ul>
<li><strong>Component</strong>：測單一元件、孤立評估（retrieval 拿對 chunk 沒、tool call 參數對沒、prompt 抽出正確 entity 沒）。</li>
<li><strong>End-to-End</strong>：測完整流程、user 視角結果（user 問題有沒有被解決、訂單有沒有完成、conversation 滿意度）。</li>
</ul>
<p>判讀訊號：「失敗時你想知道是哪一段壞掉」→ component；「你只在乎最終體驗」→ end-to-end。</p>
<h3 id="軸-3quantitative--qualitative">軸 3：Quantitative ↔ Qualitative</h3>
<ul>
<li><strong>Quantitative</strong>：產出數字（accuracy / latency / cost / pass rate）、可以追蹤、可以比較、可以 alert。</li>
<li><strong>Qualitative</strong>：產出觀察（error pattern、user 抱怨、reviewer 註記）、無法直接 aggregate、但能引導 hypothesis。</li>
</ul>
<p>判讀訊號：「結果能算平均嗎」→ quantitative；「結果是讀完才知道」→ qualitative。</p>
<h3 id="三軸的正交性">三軸的正交性</h3>
<p>這三軸是正交的、不是同義詞：</p>
<ul>
<li>「Objective + component + quantitative」典型是 unit test（function 返回對不對）。</li>
<li>「Subjective + end-to-end + qualitative」典型是 user 訪談（user 整體滿意度）。</li>
<li>中間象限存在多種混合、各有對應工具。</li>
</ul>
<h2 id="八象限">八象限</h2>
<p>3 個 binary 軸 = 8 象限。每個象限的常見對應工具：</p>
<table>
  <thead>
      <tr>
          <th>象限</th>
          <th>典型問題</th>
          <th>對應工具</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Objective + Component + Quantitative</td>
          <td>這個函數 / tool / RAG 元件對嗎</td>
          <td>Unit test、deterministic check、<a href="/blog/llm/knowledge-cards/retrieval-recall/" data-link-title="Retrieval Recall" data-link-desc="衡量 RAG 檢索是否把應該命中的文件或 chunk 放進 top-k 結果，是 component-level eval 的核心指標">retrieval recall@k</a></td>
      </tr>
      <tr>
          <td>Objective + Component + Qualitative</td>
          <td>這個元件失敗 pattern 是什麼</td>
          <td>Error log 分析、trace inspection</td>
      </tr>
      <tr>
          <td>Objective + End-to-end + Quantitative</td>
          <td>整套系統的 success rate / latency</td>
          <td>E2E test、success metric、latency p95</td>
      </tr>
      <tr>
          <td>Objective + End-to-end + Qualitative</td>
          <td>整套系統的 catastrophic 失敗 case 是什麼</td>
          <td>Production incident review、抽樣 trace 讀</td>
      </tr>
      <tr>
          <td>Subjective + Component + Quantitative</td>
          <td>這個 step 的輸出評分</td>
          <td>LLM-as-judge pairwise / rubric、human rating</td>
      </tr>
      <tr>
          <td>Subjective + Component + Qualitative</td>
          <td>這個 step 的 output 哪裡讓人不舒服</td>
          <td>Human review、error analysis with comments</td>
      </tr>
      <tr>
          <td>Subjective + End-to-end + Quantitative</td>
          <td>User 整體 NPS / 滿意度評分</td>
          <td>CSAT、thumbs up/down、appeal rate</td>
      </tr>
      <tr>
          <td>Subjective + End-to-end + Qualitative</td>
          <td>User 想要的是什麼、現在哪裡沒滿足</td>
          <td>User 訪談、開放問卷、social listening</td>
      </tr>
  </tbody>
</table>
<p>不是「八個都要做」、是「先看你的問題在哪個象限、用對應工具」。</p>
<p>兩個最容易誤判的象限展開：</p>
<p><strong>Subjective + Component + Quantitative</strong>（這個 step 輸出評分）：對應工具列「LLM-as-judge pairwise / rubric、human rating」、但 <strong>pairwise 是首選、不是 rubric</strong>——pairwise 比較讓 judge 的偏差更可控（兩個答案放在一起比、誰好誰差比較好判）、rubric 容易受 verbosity / position bias 影響。Rubric 留給「需要絕對分數而非相對排序」的場景（如要追蹤絕對品質漂移）。詳見 <a href="/blog/llm/04-applications/llm-as-judge/" data-link-title="4.21 LLM-as-Judge 評估方法" data-link-desc="LLM 評估 LLM 的 production eval 方法：rubric design、pairwise / direct scoring、三大 bias 緩解、跟 trace 串接的閉環、calibration">4.21 LLM-as-Judge</a> 的 bias 緩解段。</p>
<p><strong>Objective + Component + Quantitative</strong>（元件對嗎）：這象限最容易做、cost 也最低——deterministic check 配 component test、CI 跑、production trace 隨抽即驗。Production AI 系統若這象限沒覆蓋、bug 永遠靠 user 抱怨才發現、debug 跟 incident review 成本高。對應反例：把這象限的測試交給 LLM judge（見軸誤選一）。</p>
<h2 id="軸誤選的訊號">軸誤選的訊號</h2>
<p>軸選錯時、工具會給出「看起來合理但其實沒用」的訊號。三個常見軸誤選：</p>
<h3 id="誤選一用-subjective-工具測-objective-行為">誤選一：用 subjective 工具測 objective 行為</h3>
<p>例：訂單金額計算對不對、找 LLM judge 來看「這個金額合理嗎」。</p>
<ul>
<li><strong>問題</strong>：金額計算有 ground truth、應該 deterministic check（<code>assert order.total == expected</code>）。LLM judge 對「合理」的判斷有偏差、會放過明顯錯誤、會挑剔正確但不直觀的答案。</li>
<li><strong>訊號</strong>：你發現自己在寫「judge prompt」描述「什麼樣的金額是合理的」、但其實該行為有客觀標準。</li>
<li><strong>修正</strong>：把 judge prompt 翻成 deterministic check。</li>
</ul>
<h3 id="誤選二用-end-to-end-工具測-component-bug">誤選二：用 end-to-end 工具測 component bug</h3>
<p>例：整套系統 success rate 從 90% 掉到 80%、追了一週、結果是 retrieval 漏 chunk。</p>
<ul>
<li><strong>問題</strong>：E2E metric 告訴你「有問題」、不告訴你「在哪」。Component eval 缺失時、debug 從 trace 倒推、耗時。</li>
<li><strong>訊號</strong>：incident 後 root cause analysis 經常超過一天、查到的東西其實 component eval 該秒抓。</li>
<li><strong>修正</strong>：對 critical component（retrieval、tool 調用、parse 階段）加 component eval、production 持續跑。</li>
</ul>
<h3 id="誤選三用-quantitative-工具找-qualitative-訊號">誤選三：用 quantitative 工具找 qualitative 訊號</h3>
<p>例：user 滿意度從 4.2 掉到 4.0、團隊看數字盯一週、不知道發生什麼。</p>
<ul>
<li><strong>問題</strong>：Quantitative metric 只告訴你「有變化」、不告訴你「為什麼」。Qualitative 訊號（user 抱怨內容、抽樣 conversation）才能浮現 hypothesis。</li>
<li><strong>訊號</strong>：團隊看 dashboard 看了很久、卻沒人去讀 actual user feedback。</li>
<li><strong>修正</strong>：quantitative trigger（指標漂移）、qualitative 跟進（讀樣本、找 pattern）。</li>
</ul>
<h2 id="eval-演化路徑">Eval 演化路徑</h2>
<p>不同階段的 LLM 應用、該優先補哪些象限不同。</p>
<h3 id="階段-0mvp沒任何-eval">階段 0：MVP（沒任何 eval）</h3>
<p>問題：「能不能 demo 一下就好」、行為對不對全靠手測。</p>
<ul>
<li><strong>第一個該補的</strong>：Objective + End-to-end + Quantitative。最少跑 10 個 representative case、能看「跑得起來率」就好。</li>
<li><strong>不該太早做</strong>：subjective eval、需要 judge / human rating 的東西。MVP 階段先讓系統穩定運行。</li>
</ul>
<h3 id="階段-1有-user-在用">階段 1：有 user 在用</h3>
<p>問題：production 偶爾有 bug、user 偶爾抱怨、不知道哪些是 systematic、哪些是 random。</p>
<ul>
<li><strong>第二個該補的</strong>：Objective + End-to-end + Qualitative。讀 incident、讀抽樣 trace、找 pattern。</li>
<li><strong>第三個該補的</strong>：Objective + Component + Quantitative。對 critical component（retrieval / tool call / parse）加 component-level eval、production 跑。</li>
<li><strong>不該做</strong>：完整 subjective rubric。先把 objective 失敗修了再說。</li>
</ul>
<h3 id="階段-2要持續優化品質">階段 2：要持續優化品質</h3>
<p>問題：objective 部分已經穩、user 抱怨主要在 subjective 層（語氣、helpful 程度、推薦合不合用）。</p>
<ul>
<li><strong>第四個該補的</strong>：Subjective + Component + Quantitative。用 LLM-as-judge 給每個 step 評分、做 A/B test 比較 prompt 變動。</li>
<li><strong>第五個該補的</strong>：Subjective + End-to-end + Quantitative。CSAT、thumbs up/down、appeal rate。</li>
<li><strong>要做的</strong>：Subjective eval 跟 qualitative review 必須配合進行——quantitative 給出方向、qualitative 給出修法 hypothesis。</li>
</ul>
<h3 id="階段-3規模化跨團隊">階段 3：規模化、跨團隊</h3>
<p>問題：多個產品 / 團隊用同一套 LLM infra、eval 要 cross-cutting。</p>
<ul>
<li><strong>要做的</strong>：標準化 eval pipeline、把象限 1-7 都 cover、qualitative review 進入 ritual（每週 incident review、每月抽樣 trace 讀）。</li>
<li><strong>重點不是「全部都有」、而是「每個象限的 owner 清楚」</strong>。</li>
</ul>
<h2 id="eval-跟-trace-的閉環">Eval 跟 Trace 的閉環</h2>
<p>Eval 不是孤立的——它跟 <a href="/blog/llm/04-applications/llm-tracing-and-observability/" data-link-title="4.20 LLM tracing 與 observability" data-link-desc="OpenTelemetry GenAI semantic conventions、結構化 span 設計、cost / latency 監控、failure debug 流程、跟 LLM-as-judge eval 的串接">4.20 LLM tracing</a> 形成閉環：</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="ln"> 1</span><span class="cl">[Production traffic]
</span></span><span class="line"><span class="ln"> 2</span><span class="cl">       ↓
</span></span><span class="line"><span class="ln"> 3</span><span class="cl">   [LLM trace]  ← 每次 call / agent step / tool 都記錄
</span></span><span class="line"><span class="ln"> 4</span><span class="cl">       ↓
</span></span><span class="line"><span class="ln"> 5</span><span class="cl">   ├── 即時 monitoring（latency / cost / error rate）
</span></span><span class="line"><span class="ln"> 6</span><span class="cl">   ├── 抽樣進 eval set（人工標 + LLM judge）
</span></span><span class="line"><span class="ln"> 7</span><span class="cl">   └── failed case 進 regression set（防止改 prompt 又壞同樣 case）
</span></span><span class="line"><span class="ln"> 8</span><span class="cl">       ↓
</span></span><span class="line"><span class="ln"> 9</span><span class="cl">   [Eval pipeline]
</span></span><span class="line"><span class="ln">10</span><span class="cl">       ↓
</span></span><span class="line"><span class="ln">11</span><span class="cl">   ├── Component eval（單元件 accuracy）
</span></span><span class="line"><span class="ln">12</span><span class="cl">   ├── E2E eval（整套 success rate）
</span></span><span class="line"><span class="ln">13</span><span class="cl">   └── Subjective eval（judge / human rating）
</span></span><span class="line"><span class="ln">14</span><span class="cl">       ↓
</span></span><span class="line"><span class="ln">15</span><span class="cl">   [Insights]
</span></span><span class="line"><span class="ln">16</span><span class="cl">       ↓
</span></span><span class="line"><span class="ln">17</span><span class="cl">   ├── Quantitative：metric 漂移 alert
</span></span><span class="line"><span class="ln">18</span><span class="cl">   └── Qualitative：error pattern → hypothesis → 修 prompt / tool / RAG
</span></span><span class="line"><span class="ln">19</span><span class="cl">       ↓
</span></span><span class="line"><span class="ln">20</span><span class="cl">   [改動進 production]
</span></span><span class="line"><span class="ln">21</span><span class="cl">       ↓
</span></span><span class="line"><span class="ln">22</span><span class="cl">   [回到 production traffic、看 metric 收斂]</span></span></code></pre></div><p>Production trace 不只是 debug 工具、是 eval set 的活泉。Trace + eval 閉環的設計細節見 <a href="/blog/llm/04-applications/llm-tracing-and-observability/" data-link-title="4.20 LLM tracing 與 observability" data-link-desc="OpenTelemetry GenAI semantic conventions、結構化 span 設計、cost / latency 監控、failure debug 流程、跟 LLM-as-judge eval 的串接">4.20</a>。</p>
<h2 id="跟其他-eval-章節的分工">跟其他 Eval 章節的分工</h2>
<table>
  <thead>
      <tr>
          <th>章節</th>
          <th>焦點</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><a href="/blog/llm/04-applications/eval-design-framework/" data-link-title="4.13 Eval 設計座標系：三軸、八象限、何時測什麼" data-link-desc="Eval 設計三軸（objective↔subjective / component↔end-to-end / quantitative↔qualitative）、八象限的對應 eval 工具、軸選錯的訊號、跟 benchmarking / LLM-as-judge / tracing 的關係">4.13 本章</a></td>
          <td><strong>Meta</strong>：先選軸、再選工具的設計座標系</td>
      </tr>
      <tr>
          <td><a href="/blog/llm/04-applications/benchmarking-and-evaluation/" data-link-title="4.14 Benchmarking 與評估方法論" data-link-desc="判讀 model card benchmark 數字、做自己工作流的 in-house benchmark、量測本地推論速度的完整方法論">4.14 Benchmarking</a></td>
          <td>具體 benchmark 跟自家 eval set 的方法論</td>
      </tr>
      <tr>
          <td><a href="/blog/llm/04-applications/llm-tracing-and-observability/" data-link-title="4.20 LLM tracing 與 observability" data-link-desc="OpenTelemetry GenAI semantic conventions、結構化 span 設計、cost / latency 監控、failure debug 流程、跟 LLM-as-judge eval 的串接">4.20 LLM tracing</a></td>
          <td>Trace 怎麼接 eval、production observability</td>
      </tr>
      <tr>
          <td><a href="/blog/llm/04-applications/llm-as-judge/" data-link-title="4.21 LLM-as-Judge 評估方法" data-link-desc="LLM 評估 LLM 的 production eval 方法：rubric design、pairwise / direct scoring、三大 bias 緩解、跟 trace 串接的閉環、calibration">4.21 LLM-as-Judge</a></td>
          <td>Subjective eval 的核心工具、rubric / pairwise / bias 緩解</td>
      </tr>
  </tbody>
</table>
<p>讀法建議：先讀本章建立座標系、再依當前痛點往對應章節展開。Subjective eval 痛點 → 4.21；自家 benchmark 設計 → 4.14；production observability → 4.20。</p>
<h2 id="有效-eval-系統的四個設計條件">有效 eval 系統的四個設計條件</h2>
<p>Eval 系統要持續產生有用訊號、必須滿足四個條件。每個條件對應一個常見退化模式、可同時當 checklist 用。</p>
<h3 id="條件一judge-只用在-subjective-軸">條件一：Judge 只用在 subjective 軸</h3>
<p>LLM-as-judge 留給沒 ground truth 的 subjective 行為（語氣、helpful 程度、解釋清楚）、objective 行為（金額、JSON schema、API 參數）用 deterministic check。Judge 的 cost 比 deterministic check 高 1-2 個數量級、精度反而不如、明顯不划算。</p>
<p>對應反例：「全部 eval 都做成 LLM judge」——judge 被誤用在 objective 行為、cost 翻倍、精度反降。</p>
<h3 id="條件二每個-metric-有-ownerthresholdaction">條件二：每個 metric 有 owner、threshold、action</h3>
<p>每個 production metric 都要明確：誰負責看（owner）、什麼數字觸發 alert（threshold）、alert 後做什麼（action）。沒這三項的 metric 是 noise。</p>
<p>對應反例：dashboard 上 50 個 metric 圖、沒人定期看、bug 還是靠 user 抱怨才知道。</p>
<h3 id="條件三eval-set-跟-production-traffic-同步">條件三：Eval set 跟 production traffic 同步</h3>
<p>Production trace 持續抽樣補進 eval set、每季 review eval set 跟 traffic 分佈是否一致。</p>
<p>對應反例：eval set 是兩年前定的、production traffic 已經漂得很遠、eval 通過不代表 user 滿意。</p>
<h3 id="條件四保留-frozen-baseline">條件四：保留 frozen baseline</h3>
<p><a href="/blog/llm/knowledge-cards/frozen-baseline/" data-link-title="Frozen baseline" data-link-desc="Eval 系統中固定特定 prompt &#43; model 當長期對照、讓行為漂移可見的標準作法">Frozen baseline</a> 是把某個特定 prompt + 特定 model 跑 production 一段時間後 freeze 起來、每次新版本跟它比、定期 refresh 並標明時點。漂移看得見才能管理。</p>
<p>對應反例：每次 A/B 都跟「最新版本」比、長期累積漂移完全不可見、「整體變好了沒」無從回答。</p>
<h2 id="何時過時--何時不過時">何時過時 / 何時不過時</h2>
<p><strong>不會過時的部分</strong>：</p>
<ul>
<li>三軸座標（objective / component / quantitative 三個 binary 軸）。</li>
<li>八象限對應工具的結構分類。</li>
<li>三類軸誤選的識別訊號跟修正。</li>
<li>Eval 演化路徑（MVP → user → 優化 → 規模化）。</li>
<li>Eval / trace 閉環的設計。</li>
<li>有效 eval 系統的四個設計條件。</li>
</ul>
<p><strong>會變的部分</strong>：</p>
<ul>
<li>具體 eval framework（OpenAI Evals、Promptfoo、Braintrust、Langfuse 等會持續演化）。</li>
<li>LLM-as-judge 的具體 prompt 模板跟 bias 緩解技巧。</li>
<li>各 benchmark 的權威性（半年一換）。</li>
</ul>
<h2 id="下一章">下一章</h2>
<p>下一章：<a href="/blog/llm/04-applications/benchmarking-and-evaluation/" data-link-title="4.14 Benchmarking 與評估方法論" data-link-desc="判讀 model card benchmark 數字、做自己工作流的 in-house benchmark、量測本地推論速度的完整方法論">4.14 Benchmarking 與評估方法論</a>、把座標系落到具體 benchmark 設計。Subjective eval 的工具見 <a href="/blog/llm/04-applications/llm-as-judge/" data-link-title="4.21 LLM-as-Judge 評估方法" data-link-desc="LLM 評估 LLM 的 production eval 方法：rubric design、pairwise / direct scoring、三大 bias 緩解、跟 trace 串接的閉環、calibration">4.21 LLM-as-Judge</a>、production trace 怎麼接 eval 見 <a href="/blog/llm/04-applications/llm-tracing-and-observability/" data-link-title="4.20 LLM tracing 與 observability" data-link-desc="OpenTelemetry GenAI semantic conventions、結構化 span 設計、cost / latency 監控、failure debug 流程、跟 LLM-as-judge eval 的串接">4.20 LLM tracing</a>、跟 fuzzy engineering 典範的關係見 <a href="/blog/llm/00-foundations/deterministic-vs-fuzzy-engineering/" data-link-title="0.8 Deterministic vs Fuzzy Engineering：軟體設計典範的位移" data-link-desc="傳統 deterministic 軟體跟 fuzzy LLM 軟體在資料、邏輯、分解、實驗成本四個維度的根本差異、以及哪段該 deterministic、哪段該 fuzzy 的決策框架">0.8</a>（fuzzy 行為的測試本質就是 distribution metric）。</p>
]]></content:encoded></item><item><title>4.14 Benchmarking 與評估方法論</title><link>https://tarrragon.github.io/blog/llm/04-applications/benchmarking-and-evaluation/</link><pubDate>Tue, 12 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/llm/04-applications/benchmarking-and-evaluation/</guid><description>&lt;p>讀 model card 看到「MMLU 78.5」「HumanEval 82.3」「SWE-bench 12.6」等數字、要能判讀對自己場景的意義；自己跑本地 LLM、要能量化「tok/s、TTFT、實際品質」；想對比不同 model / 量化等級、要有可重現的 evaluation 方法。本章把「LLM 能力評估」跟「本地推論性能評估」兩條軸拆成可操作的方法論。&lt;/p>
&lt;p>本章是 eval 設計的&lt;strong>具體實作層&lt;/strong>——meta 層的 eval 軸選擇（先看軸再看工具的三軸座標）見 &lt;a href="https://tarrragon.github.io/blog/llm/04-applications/eval-design-framework/" data-link-title="4.13 Eval 設計座標系：三軸、八象限、何時測什麼" data-link-desc="Eval 設計三軸（objective↔subjective / component↔end-to-end / quantitative↔qualitative）、八象限的對應 eval 工具、軸選錯的訊號、跟 benchmarking / LLM-as-judge / tracing 的關係">4.13 Eval 設計座標系&lt;/a>、subjective eval 的核心工具見 &lt;a href="https://tarrragon.github.io/blog/llm/04-applications/llm-as-judge/" data-link-title="4.21 LLM-as-Judge 評估方法" data-link-desc="LLM 評估 LLM 的 production eval 方法：rubric design、pairwise / direct scoring、三大 bias 緩解、跟 trace 串接的閉環、calibration">4.21 LLM-as-Judge&lt;/a>。三章合起來才是 production AI app 的完整 eval pipeline。&lt;/p>
&lt;h2 id="本章目標">本章目標&lt;/h2>
&lt;p>讀完本章後、你應該能：&lt;/p>
&lt;ol>
&lt;li>看 model card benchmark 數字、判讀對自己場景的相關性。&lt;/li>
&lt;li>區分 capability benchmark（MMLU 等）跟 performance benchmark（tok/s 等）。&lt;/li>
&lt;li>跑 &lt;code>llama-bench&lt;/code> 量測自己硬體 + 模型的真實速度。&lt;/li>
&lt;li>設計 in-house benchmark 評估自己工作流的真實品質。&lt;/li>
&lt;li>看到 benchmark 異常數字時、知道可能的陷阱。&lt;/li>
&lt;/ol>
&lt;h2 id="capability-benchmarks衡量模型會什麼">Capability benchmarks：衡量模型「會什麼」&lt;/h2>
&lt;p>&lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/llm-benchmarks/" data-link-title="LLM Benchmarks（MMLU / HumanEval / SWE-bench 等）" data-link-desc="LLM 能力評估的標準 benchmark 集合：MMLU / HumanEval / MBPP / SWE-bench / MT-Bench 等的覆蓋範圍與失效情境">LLM benchmarks&lt;/a> 卡片列了主流 benchmark 的覆蓋面。本節展開對寫 code 場景最相關的幾個：&lt;/p>
&lt;h3 id="coding-benchmarks-的演化">Coding benchmarks 的演化&lt;/h3>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>Benchmark&lt;/th>
 &lt;th>任務性質&lt;/th>
 &lt;th>適合衡量&lt;/th>
 &lt;th>飽和狀態&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>HumanEval&lt;/td>
 &lt;td>寫一個 Python function 通過簡單 unit test&lt;/td>
 &lt;td>初級 coding 能力&lt;/td>
 &lt;td>飽和（90%+）&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>MBPP&lt;/td>
 &lt;td>同 HumanEval、規模較大&lt;/td>
 &lt;td>同上&lt;/td>
 &lt;td>飽和&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>HumanEval+&lt;/td>
 &lt;td>HumanEval + 更嚴格 test cases&lt;/td>
 &lt;td>排除 edge case 漏寫&lt;/td>
 &lt;td>部分飽和&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>BigCodeBench&lt;/td>
 &lt;td>真實 library use（pandas、numpy 等）&lt;/td>
 &lt;td>中級 coding&lt;/td>
 &lt;td>進行中&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>LiveCodeBench&lt;/td>
 &lt;td>LeetCode 風格 problems、定期更新避免污染&lt;/td>
 &lt;td>Algorithm + reasoning&lt;/td>
 &lt;td>進行中&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>SWE-bench&lt;/strong>&lt;/td>
 &lt;td>真實 GitHub issue 修復、要看懂 codebase&lt;/td>
 &lt;td>真實 coding agent 能力&lt;/td>
 &lt;td>仍有大空間（前沿 &amp;lt; 60%）&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>SWE-bench Verified&lt;/strong>&lt;/td>
 &lt;td>SWE-bench 的人工 verify 子集&lt;/td>
 &lt;td>同上、更可靠&lt;/td>
 &lt;td>同上&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;p>判讀建議：&lt;/p>
&lt;ol>
&lt;li>&lt;strong>看 SWE-bench、別只看 HumanEval&lt;/strong>：HumanEval 早飽和、無法區分前沿模型；SWE-bench 仍有大差距、可信度高&lt;/li>
&lt;li>&lt;strong>HumanEval 90% vs 95% 差異不大&lt;/strong>：飽和區間的 noise 大、判斷 coding 能力靠 SWE-bench / 真實任務測&lt;/li>
&lt;li>&lt;strong>LiveCodeBench 避免污染&lt;/strong>：定期出新題、模型訓練 cutoff 後的題目不在 pretrain corpus、更能反映真實能力&lt;/li>
&lt;/ol>
&lt;blockquote>
&lt;p>&lt;strong>事實查核註&lt;/strong>：本章所列 benchmark 飽和狀態（HumanEval 90%+、MMLU 85%+、GSM8K 90%+）、SOTA 數字（SWE-bench &amp;lt; 60%）、各模型在各 benchmark 的相對排名 — 都是 2026/5 估計、隨新模型推出快速變動、引用前以 &lt;a href="https://paperswithcode.com/">Papers with Code&lt;/a> 跟 &lt;a href="https://huggingface.co/spaces/HuggingFaceH4/open_llm_leaderboard">HuggingFace Open LLM Leaderboard&lt;/a> 當前狀態為準。&lt;/p></description><content:encoded><![CDATA[<p>讀 model card 看到「MMLU 78.5」「HumanEval 82.3」「SWE-bench 12.6」等數字、要能判讀對自己場景的意義；自己跑本地 LLM、要能量化「tok/s、TTFT、實際品質」；想對比不同 model / 量化等級、要有可重現的 evaluation 方法。本章把「LLM 能力評估」跟「本地推論性能評估」兩條軸拆成可操作的方法論。</p>
<p>本章是 eval 設計的<strong>具體實作層</strong>——meta 層的 eval 軸選擇（先看軸再看工具的三軸座標）見 <a href="/blog/llm/04-applications/eval-design-framework/" data-link-title="4.13 Eval 設計座標系：三軸、八象限、何時測什麼" data-link-desc="Eval 設計三軸（objective↔subjective / component↔end-to-end / quantitative↔qualitative）、八象限的對應 eval 工具、軸選錯的訊號、跟 benchmarking / LLM-as-judge / tracing 的關係">4.13 Eval 設計座標系</a>、subjective eval 的核心工具見 <a href="/blog/llm/04-applications/llm-as-judge/" data-link-title="4.21 LLM-as-Judge 評估方法" data-link-desc="LLM 評估 LLM 的 production eval 方法：rubric design、pairwise / direct scoring、三大 bias 緩解、跟 trace 串接的閉環、calibration">4.21 LLM-as-Judge</a>。三章合起來才是 production AI app 的完整 eval pipeline。</p>
<h2 id="本章目標">本章目標</h2>
<p>讀完本章後、你應該能：</p>
<ol>
<li>看 model card benchmark 數字、判讀對自己場景的相關性。</li>
<li>區分 capability benchmark（MMLU 等）跟 performance benchmark（tok/s 等）。</li>
<li>跑 <code>llama-bench</code> 量測自己硬體 + 模型的真實速度。</li>
<li>設計 in-house benchmark 評估自己工作流的真實品質。</li>
<li>看到 benchmark 異常數字時、知道可能的陷阱。</li>
</ol>
<h2 id="capability-benchmarks衡量模型會什麼">Capability benchmarks：衡量模型「會什麼」</h2>
<p><a href="/blog/llm/knowledge-cards/llm-benchmarks/" data-link-title="LLM Benchmarks（MMLU / HumanEval / SWE-bench 等）" data-link-desc="LLM 能力評估的標準 benchmark 集合：MMLU / HumanEval / MBPP / SWE-bench / MT-Bench 等的覆蓋範圍與失效情境">LLM benchmarks</a> 卡片列了主流 benchmark 的覆蓋面。本節展開對寫 code 場景最相關的幾個：</p>
<h3 id="coding-benchmarks-的演化">Coding benchmarks 的演化</h3>
<table>
  <thead>
      <tr>
          <th>Benchmark</th>
          <th>任務性質</th>
          <th>適合衡量</th>
          <th>飽和狀態</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>HumanEval</td>
          <td>寫一個 Python function 通過簡單 unit test</td>
          <td>初級 coding 能力</td>
          <td>飽和（90%+）</td>
      </tr>
      <tr>
          <td>MBPP</td>
          <td>同 HumanEval、規模較大</td>
          <td>同上</td>
          <td>飽和</td>
      </tr>
      <tr>
          <td>HumanEval+</td>
          <td>HumanEval + 更嚴格 test cases</td>
          <td>排除 edge case 漏寫</td>
          <td>部分飽和</td>
      </tr>
      <tr>
          <td>BigCodeBench</td>
          <td>真實 library use（pandas、numpy 等）</td>
          <td>中級 coding</td>
          <td>進行中</td>
      </tr>
      <tr>
          <td>LiveCodeBench</td>
          <td>LeetCode 風格 problems、定期更新避免污染</td>
          <td>Algorithm + reasoning</td>
          <td>進行中</td>
      </tr>
      <tr>
          <td><strong>SWE-bench</strong></td>
          <td>真實 GitHub issue 修復、要看懂 codebase</td>
          <td>真實 coding agent 能力</td>
          <td>仍有大空間（前沿 &lt; 60%）</td>
      </tr>
      <tr>
          <td><strong>SWE-bench Verified</strong></td>
          <td>SWE-bench 的人工 verify 子集</td>
          <td>同上、更可靠</td>
          <td>同上</td>
      </tr>
  </tbody>
</table>
<p>判讀建議：</p>
<ol>
<li><strong>看 SWE-bench、別只看 HumanEval</strong>：HumanEval 早飽和、無法區分前沿模型；SWE-bench 仍有大差距、可信度高</li>
<li><strong>HumanEval 90% vs 95% 差異不大</strong>：飽和區間的 noise 大、判斷 coding 能力靠 SWE-bench / 真實任務測</li>
<li><strong>LiveCodeBench 避免污染</strong>：定期出新題、模型訓練 cutoff 後的題目不在 pretrain corpus、更能反映真實能力</li>
</ol>
<blockquote>
<p><strong>事實查核註</strong>：本章所列 benchmark 飽和狀態（HumanEval 90%+、MMLU 85%+、GSM8K 90%+）、SOTA 數字（SWE-bench &lt; 60%）、各模型在各 benchmark 的相對排名 — 都是 2026/5 估計、隨新模型推出快速變動、引用前以 <a href="https://paperswithcode.com/">Papers with Code</a> 跟 <a href="https://huggingface.co/spaces/HuggingFaceH4/open_llm_leaderboard">HuggingFace Open LLM Leaderboard</a> 當前狀態為準。</p></blockquote>
<h3 id="reasoning-benchmarks">Reasoning benchmarks</h3>
<table>
  <thead>
      <tr>
          <th>Benchmark</th>
          <th>任務性質</th>
          <th>主要 audience</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>MMLU</td>
          <td>通用知識多選</td>
          <td>Pretrain 能力</td>
      </tr>
      <tr>
          <td>MMLU-Pro</td>
          <td>MMLU 更困難版本、5 → 10 選 1</td>
          <td>同上、區分前沿模型</td>
      </tr>
      <tr>
          <td>GSM8K</td>
          <td>小學數學 word problem</td>
          <td>早期 reasoning</td>
      </tr>
      <tr>
          <td>MATH</td>
          <td>高中 / 競賽數學</td>
          <td>中級 reasoning</td>
      </tr>
      <tr>
          <td>AIME / GPQA</td>
          <td>競賽數學 / graduate-level science</td>
          <td><a href="/blog/llm/03-theoretical-foundations/reasoning-models/" data-link-title="3.8 Reasoning models：test-time compute paradigm" data-link-desc="Chain-of-thought 從 prompting 技巧演化成訓練 paradigm、reasoning model 的內部運作、本地可跑的選項與適用任務">Reasoning models</a></td>
      </tr>
      <tr>
          <td>ARC-AGI</td>
          <td>視覺 reasoning puzzle</td>
          <td>General reasoning</td>
      </tr>
  </tbody>
</table>
<p>判讀：</p>
<ol>
<li><strong>Reasoning model 在 AIME / GPQA 顯著領先 instruct model</strong>：這正是 reasoning model 的優勢區</li>
<li><strong>MMLU 飽和</strong>：85%+ 後差別意義不大、改看 MMLU-Pro</li>
<li><strong>GSM8K 接近飽和</strong>：90%+、改看 MATH / AIME</li>
</ol>
<h3 id="long-context-benchmarks">Long context benchmarks</h3>
<table>
  <thead>
      <tr>
          <th>Benchmark</th>
          <th>任務性質</th>
          <th>衡量</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><a href="/blog/llm/knowledge-cards/needle-in-haystack/" data-link-title="Needle in a Haystack" data-link-desc="把一個事實藏在 long context 不同位置、測試 LLM 能否抓出來的 benchmark 方法">Needle in haystack</a></td>
          <td>抓單一事實</td>
          <td>Lower bound effective context</td>
      </tr>
      <tr>
          <td>RULER</td>
          <td>Multi-needle、aggregation、reasoning</td>
          <td>真實 long context 能力</td>
      </tr>
      <tr>
          <td>LongBench</td>
          <td>QA、summarization、code 等真實任務</td>
          <td>全方面 long context</td>
      </tr>
      <tr>
          <td>∞Bench</td>
          <td>100K+ context tasks</td>
          <td>極長 context</td>
      </tr>
  </tbody>
</table>
<p>判讀：聲稱「128K context」要配 RULER / LongBench 分數才知道實用、見 <a href="/blog/llm/04-applications/long-context-engineering/" data-link-title="4.11 Long context engineering" data-link-desc="128K / 1M context 模型怎麼用：claimed vs effective context、lost-in-the-middle、context 設計策略、Long context vs RAG 取捨">4.11 Long context engineering</a>。</p>
<h2 id="performance-benchmarks衡量跑多快">Performance benchmarks：衡量「跑多快」</h2>
<p>跟 capability 並列的另一條軸 — 推論速度：</p>
<table>
  <thead>
      <tr>
          <th>指標</th>
          <th>定義</th>
          <th>影響使用者體感</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><a href="/blog/llm/knowledge-cards/tokens-per-second/" data-link-title="Tokens Per Second" data-link-desc="LLM 每秒能生成幾個 token：生字速度的標準量化指標">Tokens per second</a></td>
          <td>生成速度（tok/s）</td>
          <td>連續輸出感受</td>
      </tr>
      <tr>
          <td><a href="/blog/llm/knowledge-cards/ttft/" data-link-title="TTFT" data-link-desc="Time To First Token：送出 prompt 到第一個 token 出現的等待時間">TTFT</a></td>
          <td>Time to first token</td>
          <td>「按下 enter 多久才看到字」</td>
      </tr>
      <tr>
          <td>Prefill speed</td>
          <td>Prompt 處理速度（tok/s）</td>
          <td>長 prompt 的等待時間</td>
      </tr>
      <tr>
          <td>Memory footprint</td>
          <td>推論記憶體佔用</td>
          <td>能不能塞進機器</td>
      </tr>
      <tr>
          <td>Energy consumption</td>
          <td>推論電力</td>
          <td>長期使用成本</td>
      </tr>
  </tbody>
</table>
<h3 id="llama-bench標準工具">llama-bench：標準工具</h3>
<p>llama.cpp 內建 benchmark 工具：</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln"> 1</span><span class="cl"><span class="c1"># 基本測試：純 generation 速度</span>
</span></span><span class="line"><span class="ln"> 2</span><span class="cl">llama-bench -m model.gguf -p <span class="m">512</span> -n <span class="m">128</span>
</span></span><span class="line"><span class="ln"> 3</span><span class="cl"><span class="c1"># -p 512：prompt 512 token（測 prefill）</span>
</span></span><span class="line"><span class="ln"> 4</span><span class="cl"><span class="c1"># -n 128：generate 128 token（測 decode）</span>
</span></span><span class="line"><span class="ln"> 5</span><span class="cl">
</span></span><span class="line"><span class="ln"> 6</span><span class="cl"><span class="c1"># 不同 context 長度的影響</span>
</span></span><span class="line"><span class="ln"> 7</span><span class="cl">llama-bench -m model.gguf -p 512,2048,8192 -n <span class="m">128</span>
</span></span><span class="line"><span class="ln"> 8</span><span class="cl">
</span></span><span class="line"><span class="ln"> 9</span><span class="cl"><span class="c1"># 開 flash attention</span>
</span></span><span class="line"><span class="ln">10</span><span class="cl">llama-bench -m model.gguf -p <span class="m">512</span> -n <span class="m">128</span> -fa <span class="m">1</span>
</span></span><span class="line"><span class="ln">11</span><span class="cl">
</span></span><span class="line"><span class="ln">12</span><span class="cl"><span class="c1"># Speculative decoding 對比</span>
</span></span><span class="line"><span class="ln">13</span><span class="cl">llama-bench -m target.gguf --draft-model drafter.gguf <span class="se">\
</span></span></span><span class="line"><span class="ln">14</span><span class="cl"><span class="se"></span>            -p <span class="m">512</span> -n <span class="m">128</span> --speculative-draft <span class="m">5</span></span></span></code></pre></div><p>輸出範例：</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="ln">1</span><span class="cl">| model                |       size |     params | backend    | ngl |   test |              t/s |
</span></span><span class="line"><span class="ln">2</span><span class="cl">| -------------------- | ---------: | ---------: | ---------- | --: | -----: | ---------------: |
</span></span><span class="line"><span class="ln">3</span><span class="cl">| gemma3 31B Q4_K - M  |  18.45 GiB |    31.21 B | Metal      |  99 |  pp512 |    324.21 ± 1.27 |
</span></span><span class="line"><span class="ln">4</span><span class="cl">| gemma3 31B Q4_K - M  |  18.45 GiB |    31.21 B | Metal      |  99 |  tg128 |     28.43 ± 0.31 |</span></span></code></pre></div><p>讀法：</p>
<ul>
<li><code>pp512</code>：prefill 512 token 的 throughput（tok/s）</li>
<li><code>tg128</code>：generate 128 token 的 throughput（tok/s、即 tok/s）</li>
<li><code>± 0.31</code>：多次跑的 std deviation、&lt; 5% 是穩定基線</li>
</ul>
<h3 id="推論成本-vs-品質的-trade-off-矩陣">推論成本 vs 品質的 trade-off 矩陣</h3>
<p>對自己機器跑 <code>llama-bench</code> 後、可以建一個矩陣：</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="ln">1</span><span class="cl">                     tok/s 高           tok/s 中           tok/s 低
</span></span><span class="line"><span class="ln">2</span><span class="cl">品質（HumanEval）
</span></span><span class="line"><span class="ln">3</span><span class="cl">     高              [Q4 7B coder]      [Q4 14B coder]    [Q4 30B reasoning]
</span></span><span class="line"><span class="ln">4</span><span class="cl">     中              [Q4 14B instruct]  [Q4 30B instruct]
</span></span><span class="line"><span class="ln">5</span><span class="cl">     低              [Q4 30B base]      [unused]          [unused]</span></span></code></pre></div><p>對應到實際選型：</p>
<ul>
<li>自動補完（高頻、低品質需求）：左上 tok/s 高的小模型</li>
<li>對話（中頻、中品質需求）：中段</li>
<li>複雜 reasoning（低頻、高品質需求）：右下大 reasoning model</li>
</ul>
<h2 id="in-house-benchmark自己工作流的真實評估">In-house benchmark：自己工作流的真實評估</h2>
<p>最重要的 benchmark 是「自己真實任務上的表現」、公開 benchmark 是粗略 filter。</p>
<h3 id="建立-in-house-benchmark-的步驟">建立 in-house benchmark 的步驟</h3>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="ln"> 1</span><span class="cl">1. 蒐集真實案例
</span></span><span class="line"><span class="ln"> 2</span><span class="cl">   - 從過往工作流挑 30-100 個有代表性的任務
</span></span><span class="line"><span class="ln"> 3</span><span class="cl">   - 含「容易任務」「中等任務」「困難任務」三類
</span></span><span class="line"><span class="ln"> 4</span><span class="cl">   - 每個任務記錄 (input prompt, expected output 或評分標準)
</span></span><span class="line"><span class="ln"> 5</span><span class="cl">
</span></span><span class="line"><span class="ln"> 6</span><span class="cl">2. 定義評分機制
</span></span><span class="line"><span class="ln"> 7</span><span class="cl">   - Objective（最理想）：unit test、exact match、能機械驗證
</span></span><span class="line"><span class="ln"> 8</span><span class="cl">   - Semi-objective：rubric 評分、人工或 LLM-as-judge
</span></span><span class="line"><span class="ln"> 9</span><span class="cl">   - Subjective（最後手段）：人工 A/B 偏好
</span></span><span class="line"><span class="ln">10</span><span class="cl">
</span></span><span class="line"><span class="ln">11</span><span class="cl">3. 跑 candidate models
</span></span><span class="line"><span class="ln">12</span><span class="cl">   - 對每個模型、每個任務都跑、記錄輸出
</span></span><span class="line"><span class="ln">13</span><span class="cl">   - 注意推論參數一致（temperature、top-p、max_tokens 一樣）
</span></span><span class="line"><span class="ln">14</span><span class="cl">   - 注意 prompt 一致（chat template、system prompt）
</span></span><span class="line"><span class="ln">15</span><span class="cl">
</span></span><span class="line"><span class="ln">16</span><span class="cl">4. 評分
</span></span><span class="line"><span class="ln">17</span><span class="cl">   - Objective：跑 test、算 pass rate
</span></span><span class="line"><span class="ln">18</span><span class="cl">   - Semi-objective：建 rubric、評分
</span></span><span class="line"><span class="ln">19</span><span class="cl">   - Subjective：人工 / LLM 評
</span></span><span class="line"><span class="ln">20</span><span class="cl">
</span></span><span class="line"><span class="ln">21</span><span class="cl">5. 看分佈、不只看平均
</span></span><span class="line"><span class="ln">22</span><span class="cl">   - 平均 80% 可能來自「20 題滿分 + 80 題 70%」或「100 題 80%」
</span></span><span class="line"><span class="ln">23</span><span class="cl">   - 看 std、看哪些任務崩、針對性 debug</span></span></code></pre></div><h3 id="llm-as-judge-的注意點">LLM-as-judge 的注意點</h3>
<p>用 LLM（如 GPT-4、Claude）評其他 LLM 是省人力的方法、但有 bias：</p>
<ol>
<li><strong>Verbosity bias</strong>：judge 傾向給「答得長」的高分、即使內容沒提升</li>
<li><strong>Position bias</strong>：A/B 比較時、judge 對 A、B 位置敏感、要做 swap 平均</li>
<li><strong>Self-preference bias</strong>：judge 模型偏好自己風格的答案</li>
<li><strong>Judge 能力上限</strong>：judge 模型本身不夠強、評不出兩個強模型的差距</li>
</ol>
<p>緩解：</p>
<ol>
<li><strong>用結構化 rubric</strong>：給 judge 明確評分標準、不只「哪個好」</li>
<li><strong>多 judge 取共識</strong>：用 2-3 個不同 judge model 各評、取一致 / 平均</li>
<li><strong>Critical task 仍要人工 review</strong>：高 stake 任務不能全靠 LLM-as-judge</li>
</ol>
<h2 id="常見陷阱跟反例">常見陷阱跟反例</h2>
<h3 id="陷阱-1訓練資料污染">陷阱 1：訓練資料污染</h3>
<p>模型在 benchmark 題目上「看似強」、實際是 memorization：</p>
<p>判讀訊號：</p>
<ul>
<li>benchmark cutoff date 之前的 dataset、新模型分數異常高</li>
<li>同模型在「同 dataset 變體（rephrase）」上分數顯著低</li>
</ul>
<p>緩解：用較新出題的 benchmark（如 LiveCodeBench 定期更新）。</p>
<h3 id="陷阱-2single-benchmark-過擬合">陷阱 2：Single benchmark 過擬合</h3>
<p>模型廠商針對特定 benchmark fine-tune、benchmark 高但通用能力沒提升：</p>
<p>判讀訊號：</p>
<ul>
<li>在 benchmark A 顯著領先、在 benchmark B（測類似能力）沒差</li>
<li>同模型實際使用後評價跟 benchmark 不符</li>
</ul>
<p>緩解：看多個 benchmark + in-house benchmark。</p>
<h3 id="陷阱-3prompt-sensitivity">陷阱 3：Prompt sensitivity</h3>
<p>同 benchmark 用不同 prompt 格式、score 差幾個百分點：</p>
<p>判讀訊號：</p>
<ul>
<li>model card 報的數字跟自己跑差很多</li>
<li>同模型不同 prompt template 結果差距大</li>
</ul>
<p>緩解：自己跑、用一致的 prompt template；report 時明確標 prompt 版本。</p>
<h3 id="陷阱-4sampling-設定不一致">陷阱 4：Sampling 設定不一致</h3>
<p>不同模型用不同 temperature / top-p、結果不可比：</p>
<p>判讀訊號：</p>
<ul>
<li>兩篇 paper 用同 benchmark 報不同數字、推論參數不同</li>
</ul>
<p>緩解：對 reproduction 用 temperature=0 + greedy decoding 確保一致。</p>
<h2 id="benchmark-之間的關係跟導讀路徑">Benchmark 之間的關係跟導讀路徑</h2>
<p>各 benchmark 在不同階段的角色：</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="ln"> 1</span><span class="cl">研究模型能力（paper 階段）：
</span></span><span class="line"><span class="ln"> 2</span><span class="cl">  HELM / MT-Bench / Chatbot Arena → 通用能力 baseline
</span></span><span class="line"><span class="ln"> 3</span><span class="cl">  MMLU / GSM8K / AIME            → reasoning 能力
</span></span><span class="line"><span class="ln"> 4</span><span class="cl">  HumanEval / SWE-bench           → coding 能力
</span></span><span class="line"><span class="ln"> 5</span><span class="cl">  RULER / LongBench               → long context
</span></span><span class="line"><span class="ln"> 6</span><span class="cl">
</span></span><span class="line"><span class="ln"> 7</span><span class="cl">挑選模型（user 階段）：
</span></span><span class="line"><span class="ln"> 8</span><span class="cl">  Open LLM Leaderboard            → 快速 filter
</span></span><span class="line"><span class="ln"> 9</span><span class="cl">  MTEB（若 RAG）                  → embedding model
</span></span><span class="line"><span class="ln">10</span><span class="cl">  In-house benchmark              → final 確認
</span></span><span class="line"><span class="ln">11</span><span class="cl">
</span></span><span class="line"><span class="ln">12</span><span class="cl">監控模型（production 階段）：
</span></span><span class="line"><span class="ln">13</span><span class="cl">  自己工作流 KPI                  → 真實品質
</span></span><span class="line"><span class="ln">14</span><span class="cl">  A/B test                       → 部署前的決策
</span></span><span class="line"><span class="ln">15</span><span class="cl">  User feedback                  → 持續迭代</span></span></code></pre></div><h2 id="何時過時--何時不過時">何時過時 / 何時不過時</h2>
<p><strong>不會過時的部分</strong>：</p>
<ul>
<li>Benchmark 跟自己任務對齊的必要性</li>
<li>訓練污染 / 飽和 / single-task overfit 的陷阱</li>
<li>LLM-as-judge bias 的存在</li>
<li>In-house benchmark 是最後 final test</li>
<li><code>llama-bench</code> 是量測本地推論的標準工具</li>
</ul>
<p><strong>會變的部分</strong>：</p>
<ul>
<li>各 benchmark 的飽和狀態跟前沿 score</li>
<li>主流 benchmark 的選擇（HumanEval → MBPP → SWE-bench → &hellip;）</li>
<li>LLM-as-judge model 的偏好（隨 judge model 更新而變）</li>
<li>新 benchmark 出現（特別是 reasoning / long-context 領域）</li>
</ul>
<h2 id="下一章">下一章</h2>
<p>下一章：<a href="/blog/llm/04-applications/vision-in-coding-workflow/" data-link-title="4.15 Vision in coding workflow：本地 VLM 怎麼接寫 code" data-link-desc="VLM 在 coding 工作流的 use cases、本地 VLM 選型、跟雲端 VLM 的分工、Continue.dev / Ollama 整合現狀">4.15 Vision in coding workflow</a>、把 vision 維度加進 coding 工作流的設計取捨。讀完 4.10、模組四覆蓋了 LLM 作為系統元件的設計取捨（RAG、tool use、agent、應用層協議、workflow、resource planning、long context、embedding、benchmarking、vision）、寫 code 場景需要的應用層概念完整、之後可進入 <a href="/blog/llm/05-discrete-gpu/" data-link-title="模組五：Windows / Linux &#43; 獨立 GPU" data-link-desc="消費級 PC（Windows / Linux &#43; NVIDIA / AMD 獨立 GPU）跑本地 LLM 的硬體判讀、MoE CPU 卸載、KV cache 量化與 llama.cpp 調參">模組五 PC 獨立 GPU</a> 或 <a href="/blog/llm/06-security/" data-link-title="模組六：本地 LLM 的安全與權限" data-link-desc="個人 dev 在自己機器上跑本地 LLM 的安全議題：模型供應鏈、推論伺服器綁定、tool use 副作用、prompt injection 在 IDE、跨雲端 / 本地資料邊界">模組六 安全</a>。</p>
]]></content:encoded></item><item><title>4.21 LLM-as-Judge 評估方法</title><link>https://tarrragon.github.io/blog/llm/04-applications/llm-as-judge/</link><pubDate>Tue, 12 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/llm/04-applications/llm-as-judge/</guid><description>&lt;p>&lt;a href="https://tarrragon.github.io/blog/llm/04-applications/benchmarking-and-evaluation/" data-link-title="4.14 Benchmarking 與評估方法論" data-link-desc="判讀 model card benchmark 數字、做自己工作流的 in-house benchmark、量測本地推論速度的完整方法論">4.14 benchmarking-and-evaluation&lt;/a> 寫了 capability benchmark（MMLU、SWE-bench 等）跟 in-house benchmark 概念。但「自己工作流的真實案例該怎麼系統性 eval」這個操作層、4.14 點到沒展開。本章補上 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/llm-as-judge/" data-link-title="LLM-as-Judge" data-link-desc="用 LLM 評估另一個 LLM 的輸出品質、production eval 的主流方法、500-5000× 成本降但有 bias 要處理">LLM-as-Judge&lt;/a> — production AI app 的事實標準 eval 方法、比 human eval 便宜 500-5000×、跟人類有 80%+ agreement、但要處理 bias。&lt;/p>
&lt;p>Judge 在 eval 系統中的定位：&lt;a href="https://tarrragon.github.io/blog/llm/04-applications/eval-design-framework/" data-link-title="4.13 Eval 設計座標系：三軸、八象限、何時測什麼" data-link-desc="Eval 設計三軸（objective↔subjective / component↔end-to-end / quantitative↔qualitative）、八象限的對應 eval 工具、軸選錯的訊號、跟 benchmarking / LLM-as-judge / tracing 的關係">4.13 Eval 設計座標系&lt;/a> 把 eval 分三軸八象限、判斷哪個象限該用什麼工具——judge 的位置是 subjective 軸（沒 ground truth 的行為）、不是 objective 軸（有 ground truth 用 deterministic check 更便宜更準）。讀本章前先看 4.13 的軸誤選段、避開「全部 eval 都做成 judge」的常見反模式。&lt;/p>
&lt;h2 id="本章目標">本章目標&lt;/h2>
&lt;p>讀完本章後、你應該能：&lt;/p>
&lt;ol>
&lt;li>區分 LLM-as-Judge、standard benchmark、human eval 三條 eval 路徑。&lt;/li>
&lt;li>設計可重現的 judge rubric（input / output / rubric / reasoning 四段）。&lt;/li>
&lt;li>用 pairwise vs direct scoring、知道何時用哪種。&lt;/li>
&lt;li>緩解三大 bias（position / verbosity / self-preference）。&lt;/li>
&lt;li>把 production &lt;a href="https://tarrragon.github.io/blog/llm/04-applications/llm-tracing-and-observability/" data-link-title="4.20 LLM tracing 與 observability" data-link-desc="OpenTelemetry GenAI semantic conventions、結構化 span 設計、cost / latency 監控、failure debug 流程、跟 LLM-as-judge eval 的串接">trace&lt;/a> 餵回 judge、形成自動 eval 閉環。&lt;/li>
&lt;/ol>
&lt;h2 id="為什麼需要-llm-as-judge">為什麼需要 LLM-as-Judge&lt;/h2>
&lt;p>&lt;a href="https://tarrragon.github.io/blog/llm/04-applications/benchmarking-and-evaluation/" data-link-title="4.14 Benchmarking 與評估方法論" data-link-desc="判讀 model card benchmark 數字、做自己工作流的 in-house benchmark、量測本地推論速度的完整方法論">4.14&lt;/a> 推「in-house benchmark 是 final test」、但操作層是個 gap：&lt;/p>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>Eval 痛點&lt;/th>
 &lt;th>LLM-as-Judge 解法&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>Standard benchmark 跟自己 use case 不符&lt;/td>
 &lt;td>Judge 用自己 case 跑、rubric 自定義&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Human eval 太貴 / 太慢&lt;/td>
 &lt;td>Judge 自動跑、$0.001-0.01 per item&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Production trace 量大、人工看不完&lt;/td>
 &lt;td>Judge 跑 100% production trace 都可行&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Rule-based eval 抓不到語意問題&lt;/td>
 &lt;td>Judge 能判斷「答案是否符合意圖、即使措辭不同」&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Iteration 需要快速 feedback&lt;/td>
 &lt;td>Judge 幾分鐘跑完 100 items、prompt 改完馬上重測&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;p>主要 use case（重複 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/llm-as-judge/" data-link-title="LLM-as-Judge" data-link-desc="用 LLM 評估另一個 LLM 的輸出品質、production eval 的主流方法、500-5000× 成本降但有 bias 要處理">LLM-as-Judge 卡片&lt;/a>）：in-house benchmark、production trace eval、A/B test、synthetic data quality。&lt;/p></description><content:encoded><![CDATA[<p><a href="/blog/llm/04-applications/benchmarking-and-evaluation/" data-link-title="4.14 Benchmarking 與評估方法論" data-link-desc="判讀 model card benchmark 數字、做自己工作流的 in-house benchmark、量測本地推論速度的完整方法論">4.14 benchmarking-and-evaluation</a> 寫了 capability benchmark（MMLU、SWE-bench 等）跟 in-house benchmark 概念。但「自己工作流的真實案例該怎麼系統性 eval」這個操作層、4.14 點到沒展開。本章補上 <a href="/blog/llm/knowledge-cards/llm-as-judge/" data-link-title="LLM-as-Judge" data-link-desc="用 LLM 評估另一個 LLM 的輸出品質、production eval 的主流方法、500-5000× 成本降但有 bias 要處理">LLM-as-Judge</a> — production AI app 的事實標準 eval 方法、比 human eval 便宜 500-5000×、跟人類有 80%+ agreement、但要處理 bias。</p>
<p>Judge 在 eval 系統中的定位：<a href="/blog/llm/04-applications/eval-design-framework/" data-link-title="4.13 Eval 設計座標系：三軸、八象限、何時測什麼" data-link-desc="Eval 設計三軸（objective↔subjective / component↔end-to-end / quantitative↔qualitative）、八象限的對應 eval 工具、軸選錯的訊號、跟 benchmarking / LLM-as-judge / tracing 的關係">4.13 Eval 設計座標系</a> 把 eval 分三軸八象限、判斷哪個象限該用什麼工具——judge 的位置是 subjective 軸（沒 ground truth 的行為）、不是 objective 軸（有 ground truth 用 deterministic check 更便宜更準）。讀本章前先看 4.13 的軸誤選段、避開「全部 eval 都做成 judge」的常見反模式。</p>
<h2 id="本章目標">本章目標</h2>
<p>讀完本章後、你應該能：</p>
<ol>
<li>區分 LLM-as-Judge、standard benchmark、human eval 三條 eval 路徑。</li>
<li>設計可重現的 judge rubric（input / output / rubric / reasoning 四段）。</li>
<li>用 pairwise vs direct scoring、知道何時用哪種。</li>
<li>緩解三大 bias（position / verbosity / self-preference）。</li>
<li>把 production <a href="/blog/llm/04-applications/llm-tracing-and-observability/" data-link-title="4.20 LLM tracing 與 observability" data-link-desc="OpenTelemetry GenAI semantic conventions、結構化 span 設計、cost / latency 監控、failure debug 流程、跟 LLM-as-judge eval 的串接">trace</a> 餵回 judge、形成自動 eval 閉環。</li>
</ol>
<h2 id="為什麼需要-llm-as-judge">為什麼需要 LLM-as-Judge</h2>
<p><a href="/blog/llm/04-applications/benchmarking-and-evaluation/" data-link-title="4.14 Benchmarking 與評估方法論" data-link-desc="判讀 model card benchmark 數字、做自己工作流的 in-house benchmark、量測本地推論速度的完整方法論">4.14</a> 推「in-house benchmark 是 final test」、但操作層是個 gap：</p>
<table>
  <thead>
      <tr>
          <th>Eval 痛點</th>
          <th>LLM-as-Judge 解法</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Standard benchmark 跟自己 use case 不符</td>
          <td>Judge 用自己 case 跑、rubric 自定義</td>
      </tr>
      <tr>
          <td>Human eval 太貴 / 太慢</td>
          <td>Judge 自動跑、$0.001-0.01 per item</td>
      </tr>
      <tr>
          <td>Production trace 量大、人工看不完</td>
          <td>Judge 跑 100% production trace 都可行</td>
      </tr>
      <tr>
          <td>Rule-based eval 抓不到語意問題</td>
          <td>Judge 能判斷「答案是否符合意圖、即使措辭不同」</td>
      </tr>
      <tr>
          <td>Iteration 需要快速 feedback</td>
          <td>Judge 幾分鐘跑完 100 items、prompt 改完馬上重測</td>
      </tr>
  </tbody>
</table>
<p>主要 use case（重複 <a href="/blog/llm/knowledge-cards/llm-as-judge/" data-link-title="LLM-as-Judge" data-link-desc="用 LLM 評估另一個 LLM 的輸出品質、production eval 的主流方法、500-5000× 成本降但有 bias 要處理">LLM-as-Judge 卡片</a>）：in-house benchmark、production trace eval、A/B test、synthetic data quality。</p>
<h2 id="judge-prompt-結構">Judge prompt 結構</h2>
<p>可重現的 judge 必須四段式：</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="ln"> 1</span><span class="cl">[Section 1: Task description]
</span></span><span class="line"><span class="ln"> 2</span><span class="cl">你是 LLM 輸出品質評估員。要評估 coding assistant 對使用者請求的回答品質。
</span></span><span class="line"><span class="ln"> 3</span><span class="cl">
</span></span><span class="line"><span class="ln"> 4</span><span class="cl">[Section 2: Input + Output to evaluate]
</span></span><span class="line"><span class="ln"> 5</span><span class="cl">User request: {input}
</span></span><span class="line"><span class="ln"> 6</span><span class="cl">Assistant response: {output}
</span></span><span class="line"><span class="ln"> 7</span><span class="cl">
</span></span><span class="line"><span class="ln"> 8</span><span class="cl">[Section 3: Rubric（評分標準）]
</span></span><span class="line"><span class="ln"> 9</span><span class="cl">評分維度：
</span></span><span class="line"><span class="ln">10</span><span class="cl">1. Correctness（程式碼能否運作、邏輯是否正確）：1-5
</span></span><span class="line"><span class="ln">11</span><span class="cl">2. Style（是否符合 codebase convention）：1-5
</span></span><span class="line"><span class="ln">12</span><span class="cl">3. Completeness（是否完整解決 user request）：1-5
</span></span><span class="line"><span class="ln">13</span><span class="cl">
</span></span><span class="line"><span class="ln">14</span><span class="cl">評分規則：
</span></span><span class="line"><span class="ln">15</span><span class="cl">- 5：完美無瑕、可直接 merge
</span></span><span class="line"><span class="ln">16</span><span class="cl">- 4：小修可用、整體正確
</span></span><span class="line"><span class="ln">17</span><span class="cl">- 3：方向正確、需 substantial 修改
</span></span><span class="line"><span class="ln">18</span><span class="cl">- 2：部分對、主要邏輯有錯
</span></span><span class="line"><span class="ln">19</span><span class="cl">- 1：完全錯、誤導使用者
</span></span><span class="line"><span class="ln">20</span><span class="cl">
</span></span><span class="line"><span class="ln">21</span><span class="cl">明確不加分：
</span></span><span class="line"><span class="ln">22</span><span class="cl">- 冗長 / verbose（同樣正確的短答 = 長答）
</span></span><span class="line"><span class="ln">23</span><span class="cl">- 道歉 / 開場白
</span></span><span class="line"><span class="ln">24</span><span class="cl">- 「我希望這有幫助」這類禮貌話
</span></span><span class="line"><span class="ln">25</span><span class="cl">
</span></span><span class="line"><span class="ln">26</span><span class="cl">[Section 4: Output format]
</span></span><span class="line"><span class="ln">27</span><span class="cl">請依下列 JSON 輸出：
</span></span><span class="line"><span class="ln">28</span><span class="cl">{
</span></span><span class="line"><span class="ln">29</span><span class="cl">  &#34;correctness&#34;: &lt;1-5&gt;,
</span></span><span class="line"><span class="ln">30</span><span class="cl">  &#34;style&#34;: &lt;1-5&gt;,
</span></span><span class="line"><span class="ln">31</span><span class="cl">  &#34;completeness&#34;: &lt;1-5&gt;,
</span></span><span class="line"><span class="ln">32</span><span class="cl">  &#34;reasoning&#34;: &#34;&lt;簡短解釋&gt;&#34;,
</span></span><span class="line"><span class="ln">33</span><span class="cl">  &#34;overall&#34;: &lt;1-5&gt;
</span></span><span class="line"><span class="ln">34</span><span class="cl">}</span></span></code></pre></div><p>關鍵設計原則：</p>
<ol>
<li><strong>Rubric 明確、可重現</strong>：用 1-5 scale + 每分明確定義、避免 judge 自由發揮</li>
<li><strong>明確列「不加分項」</strong>：vag rubric 容易讓 judge 加分長答 / 道歉 / 客套（verbosity bias）</li>
<li><strong>要求 reasoning</strong>：強迫 judge 寫評分理由、提升 calibration、後續可 debug</li>
<li><strong>Structured output</strong>：用 JSON / <a href="/blog/llm/04-applications/application-protocols/" data-link-title="4.6 應用層協議：function calling / structured output / MCP" data-link-desc="三個常被混為一談的概念：模型能力、sampling 約束、server 協議，三者的層級差異與組合方式">structured output</a> 強制格式、後續可程式化處理</li>
</ol>
<h2 id="pairwise-vs-direct-scoring">Pairwise vs Direct scoring</h2>
<p>兩種主流評分方式：</p>
<h3 id="direct-scoring直接打分">Direct scoring（直接打分）</h3>
<p>給一個 (input, output)、judge 給絕對分數（1-5、1-10）。</p>
<p>優點：簡單、可看「絕對品質」隨時間改變
缺點：分數 calibration 不穩（不同 batch 跑、judge 可能 baseline drift）</p>
<h3 id="pairwise-comparison兩兩比較">Pairwise comparison（兩兩比較）</h3>
<p>給一個 input + 兩個 output（A、B）、judge 選哪個比較好。</p>
<p>優點：相對比較比絕對打分穩、適合 A/B testing
缺點：需要兩個 candidates、結果是「A &gt; B」不是「A 多好」</p>
<p>實務組合：</p>
<table>
  <thead>
      <tr>
          <th>場景</th>
          <th>適合方式</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Production quality monitoring</td>
          <td>Direct scoring（每個 trace 一個分數）</td>
      </tr>
      <tr>
          <td>Prompt / model A/B test</td>
          <td>Pairwise（A 跟 B 比）</td>
      </tr>
      <tr>
          <td>Fine-tune 前後比較</td>
          <td>Pairwise</td>
      </tr>
      <tr>
          <td>Regression detection</td>
          <td>Direct（跟 baseline 比較）</td>
      </tr>
      <tr>
          <td>Synthetic data filtering</td>
          <td>Direct（保留 ≥ 4 分）</td>
      </tr>
  </tbody>
</table>
<h2 id="三大-bias-跟緩解">三大 Bias 跟緩解</h2>
<h3 id="1-position-bias位置偏見">1. Position bias（位置偏見）</h3>
<p>Pairwise 比較時、judge 對「先出現」的 candidate 有偏好（通常偏 A）。</p>
<p><strong>緩解</strong>：</p>
<ul>
<li>換位置跑 2 次（A-B 跟 B-A）</li>
<li>只 count 兩次都偏 A 的為「prefer A」、不一致為「tie」</li>
<li>標準 LLM-as-Judge framework（如 MT-Bench）內建這做法</li>
</ul>
<h3 id="2-verbosity-bias冗長偏見">2. Verbosity bias（冗長偏見）</h3>
<p>Judge 傾向給「長答」高分、即使內容沒比「短答」更好。</p>
<p><strong>緩解</strong>：</p>
<ul>
<li>Rubric 明確寫「冗長不加分」「同樣正確的短答 = 長答」</li>
<li>長度 normalize：分數 = raw_score / log(length)</li>
<li>用 length-controlled benchmark（如 length-controlled AlpacaEval）</li>
</ul>
<h3 id="3-self-preference-bias自家偏好">3. Self-preference bias（自家偏好）</h3>
<p>Judge 偏好自家風格的答案（GPT 當 judge、偏好 GPT-style 輸出；Claude 當 judge、偏好 Claude-style）。</p>
<p><strong>緩解</strong>：</p>
<ul>
<li>用 3 個不同 family 的 judge model（如 Claude + GPT + Gemini）取多數</li>
<li>避免 judge 跟 test subject 同 model</li>
<li>用 reasoning model 當 judge（多家 reasoning model 共識更穩）</li>
</ul>
<h3 id="補充-biasformat-bias">補充 bias：Format bias</h3>
<p>Judge 對「有 markdown / 有 code block / 有結構」的答案偏好、即使內容沒比「純文字」更好。</p>
<p><strong>緩解</strong>：rubric 明確寫「格式不加分、看內容」。</p>
<h2 id="calibration校準">Calibration（校準）</h2>
<p>Judge 不該光信、要 calibrate：</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="ln"> 1</span><span class="cl">1. 蒐集 100 個 (input, output) pair
</span></span><span class="line"><span class="ln"> 2</span><span class="cl">2. Human eval（你自己或可信 human）打 ground truth 分數
</span></span><span class="line"><span class="ln"> 3</span><span class="cl">3. Judge 跑同樣 100 個
</span></span><span class="line"><span class="ln"> 4</span><span class="cl">4. 算 agreement rate：
</span></span><span class="line"><span class="ln"> 5</span><span class="cl">   - Pairwise：judge 跟 human 同意比例（target &gt; 75%）
</span></span><span class="line"><span class="ln"> 6</span><span class="cl">   - Direct scoring：Spearman correlation（target &gt; 0.7）
</span></span><span class="line"><span class="ln"> 7</span><span class="cl">5. 若 agreement 低：
</span></span><span class="line"><span class="ln"> 8</span><span class="cl">   - 改 rubric（更明確）
</span></span><span class="line"><span class="ln"> 9</span><span class="cl">   - 換 judge model（更強）
</span></span><span class="line"><span class="ln">10</span><span class="cl">   - 改 prompt（few-shot example）
</span></span><span class="line"><span class="ln">11</span><span class="cl">6. Calibrate 後的 judge 才能跑 production</span></span></code></pre></div><p>Calibration 是「judge 評什麼」跟「人類評什麼」對齊的步驟、跳過會讓 production eval 失準。</p>
<h2 id="跟-420-llm-tracing-的閉環">跟 <a href="/blog/llm/04-applications/llm-tracing-and-observability/" data-link-title="4.20 LLM tracing 與 observability" data-link-desc="OpenTelemetry GenAI semantic conventions、結構化 span 設計、cost / latency 監控、failure debug 流程、跟 LLM-as-judge eval 的串接">4.20 LLM tracing</a> 的閉環</h2>
<p>Production trace + LLM-as-Judge 形成自動 eval pipeline：</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="ln"> 1</span><span class="cl">Production users
</span></span><span class="line"><span class="ln"> 2</span><span class="cl">   ↓ 產生 trace
</span></span><span class="line"><span class="ln"> 3</span><span class="cl">[LLM tracing 平台]（LangSmith / Phoenix / Langfuse / Braintrust）
</span></span><span class="line"><span class="ln"> 4</span><span class="cl">   ↓ filter：user thumbs-down、error、long latency 等 trace
</span></span><span class="line"><span class="ln"> 5</span><span class="cl">   ↓ sample 100 個 / day
</span></span><span class="line"><span class="ln"> 6</span><span class="cl">[LLM-as-Judge batch run]
</span></span><span class="line"><span class="ln"> 7</span><span class="cl">   ↓ rubric scoring
</span></span><span class="line"><span class="ln"> 8</span><span class="cl">[Dashboard]
</span></span><span class="line"><span class="ln"> 9</span><span class="cl">   - 哪類 query 品質下降
</span></span><span class="line"><span class="ln">10</span><span class="cl">   - 哪個 deployment version 品質差
</span></span><span class="line"><span class="ln">11</span><span class="cl">   - 哪個 user segment 體驗差
</span></span><span class="line"><span class="ln">12</span><span class="cl">   ↓
</span></span><span class="line"><span class="ln">13</span><span class="cl">觸發 alert / 改 prompt / 改 model / 回退
</span></span><span class="line"><span class="ln">14</span><span class="cl">   ↓ A/B test
</span></span><span class="line"><span class="ln">15</span><span class="cl">   ↓ Pairwise judge eval new vs old
</span></span><span class="line"><span class="ln">16</span><span class="cl">   ↓ Deploy 勝者</span></span></code></pre></div><p>這是 production LLM 應用 quality engineering 的標準閉環。</p>
<h2 id="judge-model-選型">Judge model 選型</h2>
<table>
  <thead>
      <tr>
          <th>Judge model 候選</th>
          <th>強項</th>
          <th>弱項</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Claude Sonnet / Opus</td>
          <td>reasoning 強、rubric 跟得緊</td>
          <td>Cost 中等</td>
      </tr>
      <tr>
          <td>GPT-5 / GPT-4o</td>
          <td>普及、tool-calling 強</td>
          <td>對自家 GPT 輸出有 self-preference</td>
      </tr>
      <tr>
          <td>Gemini Pro 2.5</td>
          <td>Long context 強、multi-modal</td>
          <td>rubric 跟得較鬆</td>
      </tr>
      <tr>
          <td>o1 / o3 / R1（reasoning model）</td>
          <td>推理能力強、判 nuanced case 穩</td>
          <td>Cost 高、latency 長</td>
      </tr>
      <tr>
          <td>本地 30B+ 模型（QwQ、DeepSeek-R1 distill）</td>
          <td>隱私強、cost 0</td>
          <td>能力上限低於雲端旗艦</td>
      </tr>
  </tbody>
</table>
<p>判讀：</p>
<ol>
<li><strong>大 stake / final QA</strong>：雲端旗艦 reasoning model</li>
<li><strong>大量 production trace eval</strong>：中等模型（GPT-4o / Sonnet）、cost / speed 平衡</li>
<li><strong>隱私敏感（user trace 不能送雲端）</strong>：本地 reasoning model（QwQ-32B / R1 distill）</li>
<li><strong>A/B test prompt 改進</strong>：用同個 judge 跑前後比對、保持 baseline</li>
</ol>
<h2 id="失敗模式">失敗模式</h2>
<ol>
<li><strong>Rubric 太 vague</strong>：judge 自由發揮、分數沒重複性</li>
</ol>
<p><strong>緩解</strong>：rubric 寫得像 unit test、每分有具體 criteria</p>
<ol start="2">
<li><strong>沒做 calibration</strong>：judge 跟 human agreement 沒驗、可能 systematically off</li>
</ol>
<p><strong>緩解</strong>：每次大改 rubric / 換 judge model 都重新 calibrate</p>
<ol start="3">
<li><strong>Sample 不代表 production</strong>：只 eval easy case、production 真實困難 case 沒覆蓋</li>
</ol>
<p><strong>緩解</strong>：用 stratified sampling（按 difficulty / user segment / feature 抽樣）</p>
<ol start="4">
<li><strong>Bias 沒緩解</strong>：position / verbosity / self-preference 直接 baked in</li>
</ol>
<p><strong>緩解</strong>：標準 framework（DeepEval / Inspect / Braintrust）內建 bias 緩解、用既有 framework 比 DIY 穩</p>
<ol start="5">
<li><strong>Judge cost 比預期高</strong>：production trace 全跑 judge、cost 爆</li>
</ol>
<p><strong>緩解</strong>：sample rate &lt; 10%、配合 <a href="/blog/llm/04-applications/llm-tracing-and-observability/" data-link-title="4.20 LLM tracing 與 observability" data-link-desc="OpenTelemetry GenAI semantic conventions、結構化 span 設計、cost / latency 監控、failure debug 流程、跟 LLM-as-judge eval 的串接">LLM tracing</a> 的 sampling</p>
<ol start="6">
<li><strong>Over-reliance on judge</strong>：忘記 judge 也會錯、把 judge 當絕對真理</li>
</ol>
<p><strong>緩解</strong>：高 stake 任務仍需 spot human review、judge 是 80% 解、不是 100%</p>
<h2 id="主流-framework">主流 framework</h2>
<table>
  <thead>
      <tr>
          <th>Framework</th>
          <th>特色</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>DeepEval</td>
          <td>OSS、Python、跟 pytest 整合</td>
      </tr>
      <tr>
          <td>Inspect（UK AI Safety）</td>
          <td>強 eval framework、reasoning model 友善</td>
      </tr>
      <tr>
          <td>Braintrust</td>
          <td>SaaS、eval + tracing 一體</td>
      </tr>
      <tr>
          <td>Langfuse evals</td>
          <td>OSS、跟 tracing 整合</td>
      </tr>
      <tr>
          <td>OpenAI evals</td>
          <td>OSS、Anthropic 也支援</td>
      </tr>
      <tr>
          <td>Patronus</td>
          <td>Production eval SaaS</td>
      </tr>
  </tbody>
</table>
<h2 id="何時不該用-llm-as-judge">何時不該用 LLM-as-Judge</h2>
<ol>
<li><strong>可機械驗證</strong>：unit test、exact match、output schema validation — 用 deterministic rule 比 judge 穩</li>
<li><strong>極小 dataset（&lt; 20 items）</strong>：直接 human eval、不必 judge</li>
<li><strong>判讀需要 domain expertise</strong>：醫療 / 法律 / 安全的 high-stake 判讀、judge 不該替代 expert</li>
<li><strong>Judge 能力 &lt; test subject</strong>：用 GPT-4o judge 評 o3 輸出、judge 看不懂 reasoning trace</li>
</ol>
<h2 id="何時過時--何時不過時">何時過時 / 何時不過時</h2>
<p><strong>不會過時的部分</strong>：</p>
<ul>
<li>LLM-as-Judge 作為 production eval 主流方法的地位</li>
<li>四段式 judge prompt 結構（task / input-output / rubric / format）</li>
<li>Pairwise vs direct scoring 的取捨</li>
<li>三大 bias 分類跟緩解方法</li>
<li>Production trace → judge → action 的閉環</li>
</ul>
<p><strong>會變的部分</strong>：</p>
<ul>
<li>主流 framework（DeepEval / Inspect / Braintrust 等）</li>
<li>各 judge model 的具體能力（每代強模型）</li>
<li>Bias 的具體量化（人類 agreement 數字會隨時間 / 任務變）</li>
<li>新興 bias 跟緩解方法</li>
</ul>
<h2 id="下一步">下一步</h2>
<p>下一步：模組四到此覆蓋從基礎（4.0 prompt 技術光譜 / 4.1-4.2 RAG / 4.3 tool / 4.4 agent / 4.5 HITL）、協議與編排（4.6 protocols / 4.7 workflow / 4.8 multi-agent）、production 細節（4.9-4.12 resource / artifact / long-context / embedding）、到 eval 跟 production observability 閉環（4.13 eval 框架 / 4.14 benchmarking / 4.17-4.21 harness / caching / memory / tracing / judge）的完整應用層地圖。Hands-on 端到端案例見 <a href="/blog/llm/04-applications/hands-on/" data-link-title="4.x Hands-on：端到端案例" data-link-desc="把模組四的所有原理串成具體 case study：從 task decomposition、workflow 設計、eval 設計到 iteration loop">hands-on 子分類</a>。可進入 <a href="/blog/llm/05-discrete-gpu/" data-link-title="模組五：Windows / Linux &#43; 獨立 GPU" data-link-desc="消費級 PC（Windows / Linux &#43; NVIDIA / AMD 獨立 GPU）跑本地 LLM 的硬體判讀、MoE CPU 卸載、KV cache 量化與 llama.cpp 調參">模組五</a> 看本地推論硬體、進入 <a href="/blog/llm/06-security/" data-link-title="模組六：本地 LLM 的安全與權限" data-link-desc="個人 dev 在自己機器上跑本地 LLM 的安全議題：模型供應鏈、推論伺服器綁定、tool use 副作用、prompt injection 在 IDE、跨雲端 / 本地資料邊界">模組六</a> 看安全議題（特別是 <a href="/blog/llm/06-security/owasp-llm-top10-mapping/" data-link-title="6.6 OWASP LLM Top 10 對照圖" data-link-desc="把模組六的本地 dev 視角安全章節對照到 OWASP LLM Top 10 2025、補出個人 dev 場景跟企業合規溝通的共同詞彙">6.6 OWASP LLM Top 10 對照</a>、把 production eval 的安全議題對應到企業合規詞彙）、或回 <a href="/blog/llm/04-applications/eval-design-framework/" data-link-title="4.13 Eval 設計座標系：三軸、八象限、何時測什麼" data-link-desc="Eval 設計三軸（objective↔subjective / component↔end-to-end / quantitative↔qualitative）、八象限的對應 eval 工具、軸選錯的訊號、跟 benchmarking / LLM-as-judge / tracing 的關係">4.13 Eval 設計座標系</a> 看 judge 在 meta eval 框架中的定位。</p>
]]></content:encoded></item></channel></rss>