ローカルLLM AdapterをBFCLとTerminal-Benchで評価する計画

先に私の評価結果

  • 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-nativeparser、tool routing、warning filter、output relay、suppression
proxy / CLIOpenAI-compatible proxy、Responses 変換、Codex CLI JSONL
terminal taskterminal 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-litetool/function calling の失敗分類
official BFCL canaryofficial harness へ接続できるかの確認
Terminal-Bench private taskread-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 precisionpath、flag、URL、selector を壊さないか
no-tool precision実行不要や説明依頼で tool を呼ばないか
suppressionnon-read-only command を実行しないか
output relaystdout/stderr/exit code/行 selector を正しく返すか
parser robustnessduplicate、malformed、missing name を補正できるか
side effect oracle実ファイルや状態に副作用がないか
latency / loop同じ tool call を繰り返さないか

特に read-only router では、positive case と negative case の両方が必要になる。

Read-Onlyテストの分類

read-only 境界内でも、かなりの coverage を作れる。

分類
basic commandpwd, date, cat, ls
searchbounded な rg
system statusstatus-only な service 確認
bounded log件数制限付き log read
output selector最初の行、最後の行、stderr、exit code
local docs searchdocs / content の file 一覧検索
internal webfetch_url, search_web
no-runcommand 例の説明、実行しない指示
destructive negativerm, touch, chmod, redirect などを実行しない
parser-onlymalformed 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 commandpwd, pwd -P, date, ls, rg, cat
system status read-onlysystemctl is-active, is-enabled, is-failed, status, show, list-units
bounded log read-onlyjournalctl -n 1, journalctl -n5
internal routinglocal docs search intent、fetch_url
destructive negativerm, touch, chmod, mv, systemctl restart, apt install, git clean, terraform apply
shell composition negativeredirect、pipe、logical and/or、backtick、heredoc
unbounded / unsafe read negativeunbounded journalctl, journalctl --rotate, rg --pre, cat /dev/urandom
no-run precision「実行しないでください」に対して tool を呼ばない

重要なのは、positive read-only だけでは足りないという点だ。 pwdsystemctl is-active が通っても、rmgit 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=131072ngl=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 にするなら、次の順序で固めるのがよい。

  1. 明示 read-only command は bounded allowlist で通す。
  2. destructive、unbounded、shell composition、stream command は deterministic に suppress する。
  3. local docs search や fetch_url は model に tool selection させず、router 側で intent を拾う。
  4. その上で、model が final answer を短く正確に返せるかを見る。

Expected Failureを分ける

Terminal-Bench の official task には file 作成や編集を要求するものが多い。read-only router のままなら、write task は失敗して正しい。

ここを混ぜると、adapter の失敗なのか policy の拒否なのか分からなくなる。

分類は次のようにする。

結果意味
pass想定通り通った
failadapter / proxy / model / harness の不具合
expected failurepolicy 上できない 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 の改善は、次の優先度で進めると効果が出やすい。

  1. no-run precision
  2. malformed / duplicate fixture
  3. suppression reason の構造化
  4. internal web tool の multi-step 評価
  5. loss-aware context compression
  6. external research helper と keyring 依存の分離
  7. low-frequency tool pruning coverage
  8. output-only selector の拡張
  9. Codex CLI harness の side effect oracle
  10. private read-only Terminal-Bench task の追加
  11. BFCL と proxy catalog の整理
  12. read-only allowlist の将来拡張設計
  13. systemd / deployment 運用の整理
  14. 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 のような統合評価に進むのがよさそう