ローカルLLM AdapterをBFCLとTerminal-Benchで評価する計画
Posted:
先に私の評価結果
- 2026年時点でNvidia 3060 12GBメモリモデルで検証
- 現状のローカルLLMは日本語はかなりのものを返すようになった( 1bit LLMでも割と正しいものを返す )
- ただし tool search , tool use の機能の正確さはまだ良くない( 結構な頻度で失敗する )
- ローカルLLMへの期待としては 1bit LLM かつ tool search 機能を最初から学習したモデルが待たれる
ローカルLLM AdapterをBFCLとTerminal-Benchで評価する計画
ローカル LLM の評価では、model 単体の一般能力と、adapter を含む tool calling 経路の品質を混ぜない方がよい。
今回測りたいのは、Hermes 3 Llama 3.1 8B の総合知能ではなく、Hermes adapter が Codex CLI 互換の tool call をどれだけ安定して成立させるか。
そのため、評価対象を次の 3 層に分ける。
| 層 | 評価したいもの |
|---|---|
| adapter-native | parser、tool routing、warning filter、output relay、suppression |
| proxy / CLI | OpenAI-compatible proxy、Responses 変換、Codex CLI JSONL |
| terminal task | terminal agent としての最終タスク達成 |
BFCLとTerminal-Benchの位置づけ
BFCL は function calling の評価に近い。adapter の tool schema 変換、arguments、tool name、malformed recovery を見るには相性がよい。
Terminal-Bench は terminal 環境で agent が作業を完了できるかを見る。これは adapter だけでなく、CLI wrapper、sandbox、Docker、task workspace、model の推論力まで含む統合評価になる。
したがって、次のように使い分ける。
| Benchmark | 使い方 |
|---|---|
| adapter JSONL canary | 改修ごとの高速 regression |
| BFCL-lite | tool/function calling の失敗分類 |
| official BFCL canary | official harness へ接続できるかの確認 |
| Terminal-Bench private task | read-only terminal task の縦断確認 |
| official Terminal-Bench subset | 統合評価。write task は別 policy が必要 |
official score をいきなり目標にしない。まずは失敗分類と改修前後差分を見る。
Canary-First
最初から広い coverage を狙うと、benchmark harness の不具合、Docker image、Python version、proxy catalog、task workspace、adapter bug が一緒に出て原因が見えにくい。
最初は低カバー率でも、Phase 0 から Phase 6 まで薄く通す。
flowchart TD
P0[Phase 0: service health / smoke] --> P1[Phase 1: adapter-native JSONL]
P1 --> P2[Phase 2: BFCL-lite]
P2 --> P3[Phase 3: official BFCL canary]
P3 --> P4[Phase 4: Terminal-Bench private task]
P4 --> P5[Phase 5: custom agent wrapper]
P5 --> P6[Phase 6: official Terminal-Bench subset]
目的は score ではなく、配線と観測点を作ることだ。
評価観点
pass rate だけでは足りない。少なくとも次を分けて記録する。
| 観点 | 見る内容 |
|---|---|
| tool selection | 必要な時だけ正しい tool を選ぶか |
| argument precision | path、flag、URL、selector を壊さないか |
| no-tool precision | 実行不要や説明依頼で tool を呼ばないか |
| suppression | non-read-only command を実行しないか |
| output relay | stdout/stderr/exit code/行 selector を正しく返すか |
| parser robustness | duplicate、malformed、missing name を補正できるか |
| side effect oracle | 実ファイルや状態に副作用がないか |
| latency / loop | 同じ tool call を繰り返さないか |
特に read-only router では、positive case と negative case の両方が必要になる。
Read-Onlyテストの分類
read-only 境界内でも、かなりの coverage を作れる。
| 分類 | 例 |
|---|---|
| basic command | pwd, date, cat, ls |
| search | bounded な rg |
| system status | status-only な service 確認 |
| bounded log | 件数制限付き log read |
| output selector | 最初の行、最後の行、stderr、exit code |
| local docs search | docs / content の file 一覧検索 |
| internal web | fetch_url, search_web |
| no-run | command 例の説明、実行しない指示 |
| destructive negative | rm, touch, chmod, redirect などを実行しない |
| parser-only | malformed tool call、duplicate response |
| pruning | 低頻度 tool を明示時だけ見せる |
| context | 長い履歴や長い tool result でも intent を保持する |
read-only のままでも、tool calling adapter の品質はかなり測れる。
Codex CLI JSONL canaryの内訳
Codex CLI 経由の JSONL canary は、model が賢いかどうかだけを見るものではない。 実際には、Codex CLI、proxy、adapter/router、sandbox、tool result relay、final answer のすべてを通す統合テストである。
私の canary では、command_execution の有無、final answer、timeout、side effect を機械判定する。
case は大きく次に分けている。
| 分類 | 代表 case |
|---|---|
| basic read-only command | pwd, pwd -P, date, ls, rg, cat |
| system status read-only | systemctl is-active, is-enabled, is-failed, status, show, list-units |
| bounded log read-only | journalctl -n 1, journalctl -n5 |
| internal routing | local docs search intent、fetch_url |
| destructive negative | rm, touch, chmod, mv, systemctl restart, apt install, git clean, terraform apply |
| shell composition negative | redirect、pipe、logical and/or、backtick、heredoc |
| unbounded / unsafe read negative | unbounded journalctl, journalctl --rotate, rg --pre, cat /dev/urandom |
| no-run precision | 「実行しないでください」に対して tool を呼ばない |
重要なのは、positive read-only だけでは足りないという点だ。
pwd や systemctl is-active が通っても、rm や git clean が sandbox で失敗しているだけなら、router としては不十分である。
危険 command は、実行してから失敗するのではなく、model/backend に投げる前に deterministic に suppress する方がよい。
特に cat /dev/urandom のような case は、read-only に見えても評価 harness を壊しうる。
実行に流れると、無限 stream や巨大 output により Codex CLI 側の RSS、swap、tool-result context が急増する。
そのため、negative canary には process timeout だけでなく、output cap、RSS guard、stream command の事前拒否が必要になる。
2026-06-16 に Google 公式 Gemma 4 12B QAT Q4_0 GGUF、ctx=131072、ngl=40 で 37 case を流した。
最初は go-llm-proxy の backend が raw llama-server に直結しており、deterministic router を bypass していた。
この状態では 16 pass / 21 fail になり、失敗は negative suppression と internal routing に集中した。
これは model の一般性能というより、routing 配線の問題として扱うべきである。
go-llm-proxy -> codex-local-router -> llama-server に戻した後は、同じ 37 case が 37/37 pass した。
この再実行では case ごとに pswpin/pswpout 差分も記録し、全 case で swap-in / swap-out は 0MiB だった。
GPU memory も約 9.2GiB used / 2.7GiB free で安定し、NVIDIA Xid や OOM は出なかった。
さらに同条件の rerun でも 37/37 pass した。 この rerun では最大 child RSS は約 165MiB、swap-in / swap-out は合計 0MiB、GPU memory は監視範囲で約 9.27-9.38GiB used だった。 ad hoc な direct prompt は safety router により早期 suppress されることがあるため、tool-call 回帰の判定は期待出力、sandbox、side effect、RSS、swap 差分を固定した JSONL canary で見る。
local LLM を Codex CLI backend にするなら、次の順序で固めるのがよい。
- 明示 read-only command は bounded allowlist で通す。
- destructive、unbounded、shell composition、stream command は deterministic に suppress する。
- local docs search や fetch_url は model に tool selection させず、router 側で intent を拾う。
- その上で、model が final answer を短く正確に返せるかを見る。
Expected Failureを分ける
Terminal-Bench の official task には file 作成や編集を要求するものが多い。read-only router のままなら、write task は失敗して正しい。
ここを混ぜると、adapter の失敗なのか policy の拒否なのか分からなくなる。
分類は次のようにする。
| 結果 | 意味 |
|---|---|
| pass | 想定通り通った |
| fail | adapter / proxy / model / harness の不具合 |
| expected failure | policy 上できない task |
| blocked | 外部依存や未実装で評価不能 |
| partial | 一部配線は通ったが score としては未完成 |
write task の score を上げるなら、read-only router を広げるのではなく、別 profile と別 policy を作る方がよい。
Regressionの優先順位
実装を変えるたびに、まず adapter-native の JSONL canary を回す。これは速く、model や network に依存しない parser-only case も混ぜられる。
次に Codex CLI 経由の JSONL を見る。ここでは command_execution の有無、final answer、timeout、side effect を確認する。
最後に benchmark harness を回す。
adapter-native JSONL
-> Codex CLI JSONL
-> BFCL-lite
-> Terminal-Bench private tasks
-> official benchmark canary
この順にすると、失敗時の原因層が切り分けやすい。
品質改善バックログ
tool calling adapter の改善は、次の優先度で進めると効果が出やすい。
- no-run precision
- malformed / duplicate fixture
- suppression reason の構造化
- internal web tool の multi-step 評価
- loss-aware context compression
- external research helper と keyring 依存の分離
- low-frequency tool pruning coverage
- output-only selector の拡張
- Codex CLI harness の side effect oracle
- private read-only Terminal-Bench task の追加
- BFCL と proxy catalog の整理
- read-only allowlist の将来拡張設計
- systemd / deployment 運用の整理
- local docs semantic search router
このリストで重要なのは、read-only 境界を広げずに品質を上げる項目を先に進めることだ。
評価の結論
BFCL と Terminal-Bench を使う方向は妥当に思う。 ただし、目的は official leaderboard score ではなく、ローカル LLM adapter の失敗分類と回帰検知に置く。 小型 local model の tool use では、モデル本体の改善よりも、adapter の
- routing
- tool pruning
- output relay
- context compression の方が効く場面が多いと感じる(LLMの出力品質が低いとも感じる) 評価もそれに合わせて、まず adapter が制御できる領域を厚く測る。その上で、Terminal-Bench のような統合評価に進むのがよさそう