dart_agent_core Evals:面向 Dart 和 Flutter 的 Agent 評估
Demystifying evals for AI agents Anthropic 的 Claude 工程團隊在這篇文章裡,把 Agent 評估拆成一組清楚的工程概念:task、trial、grader、transcript、outcome、evaluation harness、agent harness 和 evaluation suite。我們在 dart_agent_core 裡做 eval 子系統時,基本沿用了這套 Claude-style 的思路,只是把它做成 Dart 和 Flutter 團隊可以直接使用的 API。
我們想解決的問題很具體:做 Flutter Agent 時,也應該能像 Claude 團隊評估 Claude Code 那樣追問結果。Agent 是真的完成了任務,還是只是聲稱完成了?一次 prompt 調整到底提高了能力,還是犧牲了穩定性?一次模型升級有沒有減少 tool call、增加成本,或者讓某一類任務悄悄退化?
為什麼 eval 應該在 Dart Agent stack 裡
許多 Agent 評估工具預設跑在 Python 或 TypeScript 服務端。對後端 Agent 來說這很自然,但對 mobile-first 產品並不合適。Memex 的 Agent 跑在 Flutter app 內部,復用產品裡的 Dart tools,並且會修改本地檔案和本地 app state。如果把評估搬到外部框架,我們就得重建一套脫離真實執行環境的 agent harness。
package:dart_agent_core/eval.dart 的作用,是讓 evaluation harness 就放在 agent harness 旁邊執行。生產環境裡使用的 StatefulAgent、Tool、AgentController、LLMClient 和本地服務,都可以直接進入 eval。這對應 Claude 原文裡一個很重要的判斷:評估「一個 Agent」時,評估對象不是單獨的模型,而是模型和 scaffold 共同組成的系統。
把 Claude 的詞彙落到 dart_agent_core
- Task 對應
EvalTask. - Trial 對應
Trial. - Grader 對應
CodeGrader,ModelGrader, andHumanGrader. - Transcript 對應
Transcript. - Outcome 對應
Outcome. - Evaluation harness 對應
EvalRunner. - Agent harness 對應
AgentHarnessFactoryandAgentHarnessSession. - Evaluation suite 對應
EvalSuite.
如何跑第一個 dart_agent_core eval
- 建立 EvalTask,寫清楚輸入、metadata 和成功標準。
- 實作 EvalEnvironment,為每個 trial 準備獨立的 workspace 或 app state。
- 實作 AgentHarnessFactory,讓 eval 啟動真實的 Dart Agent。
- 依照要驗證的內容,選擇 CodeGrader、ModelGrader 或 HumanGrader。
- 用 EvalRunner 跑 EvalSuite,比較 pass@k、pass^k、成本、延遲和 trace。
final task = EvalTask(
id: 'create_sleep_note',
input: 'Create a sleep note from this journal entry.',
successCriteria: ['A note exists', 'The note is filed under Health'],
graders: [SleepNoteOutcomeGrader()],
);
final suite = EvalSuite(
id: 'pkm_agent_smoke',
tasks: [task],
trialCount: 3,
);
final report = await EvalRunner(
environment: PkmEvalEnvironment(workspaceDir),
harnessFactory: const PkmAgentHarnessFactory(),
).runSuite(runName: 'pkm_agent_smoke', suite: suite);先看 outcome,需要時再看 transcript
Claude 原文反覆強調:Agent 說了什麼,和 trial 結束後世界實際變成什麼,不是一回事。dart_agent_core 也保留這條邊界。驗證最終狀態時看 Outcome;驗證過程約束時,再看 Transcript。
三類 grader,而不是一個萬能分數
- Code-based grader 適合檢查確定性的狀態、schema、file diff 和 tool call。
- Model-based grader 適合用 LLM-as-judge rubric 評估主觀品質。
- Human grader 用來校準和複核模型判斷;LLM judge 不能無條件自證正確。
Capability suite 與 regression suite
Capability eval 關心 Agent 是否至少能解決某一類任務;regression eval 關心一個已經穩定的行為是否還能每次可靠完成。這個差異會直接反映在 EvalSuite、pass@k 和 pass^k 裡。
非確定性:pass@k 與 pass^k
pass@k 回答的是「k 次嘗試裡是否至少成功一次」,pass^k 回答的是「k 次嘗試是否全部成功」。前者適合能力探索,後者更接近使用者真正感受到的可靠性。
Record、replay、trace、inspect
為了降低 CI 成本和噪音,RecordingLLMClient 會保存真實模型的請求與回應;ReplayLLMClient 則在 CI 裡重放這些記錄,遇到 cache miss 就失敗。trace 可以寫成 JSONL、導出到 Langfuse,也可以用 transcript CLI 檢查。
Suite health 與 judge calibration
Claude 文章提醒我們:eval suite 會飽和、會漂移,也可能在不知不覺中測錯東西。SuiteHealthAnalyzer 用來發現 graduation candidate、broken task,以及 suite 是否還在提供有效斜率。JudgeCalibrator 則把 LLM judge 和人工 golden set 做對比,報告 Spearman、Pearson 和 MAE。
這給 Flutter Agent 團隊帶來什麼
這套設計明確對標 Anthropic 的 Claude eval 文章。我們沒有重新發明一套術語,而是把 Claude 原文裡的 task、trial、grader、transcript、outcome、evaluation harness、agent harness 和 evaluation suite 落成 Dart API,並補上 Flutter 團隊需要的本地 workspace、controller transcript、record/replay、JSON suite、Langfuse export、suite health 和 judge calibration。
dart_agent_core 已經發布在 pub.dev,eval guide 在 dart_agent_core repository。概念源頭可以讀 Anthropic 的 Claude agent eval guide。
pub.dev · dart_agent_core repository · Claude agent eval guide