Open-source release of MAESTRO, an agent orchestration platform that runs LLM-driven tasks through sandboxed tools, with a web UI. Apache-2.0. See README.md and docs/ (getting-started, configuration, architecture).
213 lines
9.1 KiB
Markdown
213 lines
9.1 KiB
Markdown
# ベンチマーク (`npm run bench`)
|
||
|
||
エージェントの **ツールコール能力 / 命令追従性 / 頭の良さ / チェックリスト使用 / 効率** を、1 つの統合タスクから多軸で計測するためのフレームワーク。
|
||
|
||
モデル変更・piece 改修・ツール追加などの前後で同じタスクを走らせ、品質回帰を検出する用途を想定している。
|
||
|
||
---
|
||
|
||
## 1. 前提
|
||
|
||
| 項目 | 必須 |
|
||
|------|------|
|
||
| `scripts/server.sh start`(またはそれ相当)でオーケストレータが起動していること | ✅ |
|
||
| `config.yaml` の `provider` が動作する LLM を指している(タスク実行 + judge の両方で使う) | ✅ |
|
||
| 初回のみ `npm run bench:fixtures` で `bench/fixtures/sales.xlsx` を生成 | ✅ |
|
||
|
||
ベンチランナーは外部ネットに依存しない。`fixtures/web/*` はランナー内蔵の **localhost HTTP サーバ** が配信する(起動時にランダムポートを取り、`{WEB_PORT}` トークンで prompt に注入)。
|
||
|
||
---
|
||
|
||
## 2. 使い方
|
||
|
||
```bash
|
||
# 全タスク
|
||
npm run bench
|
||
|
||
# 単一タスク
|
||
npm run bench -- --task=composite-mini-report
|
||
|
||
# 別ホスト/ポートのオーケストレータ向け
|
||
npm run bench -- --server=http://127.0.0.1:9876
|
||
|
||
# LLM judge を skip (axis D を 1.0 固定にして programmatic だけで採点)
|
||
BENCH_JUDGE=off npm run bench
|
||
|
||
# judge を別エンドポイント・別モデルにする
|
||
BENCH_JUDGE_ENDPOINT=https://api.example.com/v1 \
|
||
BENCH_JUDGE_MODEL=gpt-oss:20b \
|
||
npm run bench
|
||
```
|
||
|
||
実行が終わると `bench/results/<run_id>/` に書き出される(`run_id` は ISO タイムスタンプ)。
|
||
|
||
---
|
||
|
||
## 3. 出力の見方
|
||
|
||
```
|
||
bench/results/2026-05-01T03-22-11Z/
|
||
summary.md # ← ここを最初に見る
|
||
composite-mini-report/
|
||
result.json # 完全な採点 + raw データ
|
||
workspace/
|
||
logs/activity.log # エージェントが書いたログ
|
||
output/report.md # エージェントの成果物
|
||
```
|
||
|
||
`summary.md` の冒頭:
|
||
|
||
```
|
||
# Bench run @ 2026-05-01T03:22:11.000Z
|
||
|
||
**Overall: 73 / 100**
|
||
|
||
| Task | Status | Total | A | B | C | D |
|
||
| ---------------------- | ---------- | ----: | --: | --: | --: | --: |
|
||
| composite-mini-report | succeeded | 73 | 90% | 100%| 70% | 60% |
|
||
```
|
||
|
||
各タスクの詳細セクションでは axis ごとに ✓/✗ 内訳とツールコールの全シーケンスが折りたたみで見られる。
|
||
|
||
`result.json` は CI から機械可読に扱える形式。
|
||
|
||
---
|
||
|
||
## 4. 採点軸(重み 100 点満点)
|
||
|
||
| 軸 | 重み | 何を見るか | 判定 |
|
||
|----|----:|-----------|------|
|
||
| **A. Tools** | 30 | `must_use_tools` を呼んだか / `forbidden_tools` を避けたか / `forbidden_tool_for_ext` (例: Read 禁止 .xlsx) | プログラム |
|
||
| **B. Checklist** | 15 | `CreateChecklist` / `CheckItem×N` / `GetChecklist` の使用 | プログラム |
|
||
| **C. Instructions** | 30 | 出力ファイル名・1 行目固定・セクション順・行数・文字数・禁止パターンなど | プログラム |
|
||
| **D. Reasoning** | 25 | 内容の妥当性・統合の質・「次アクション」の具体性など | LLM judge ルーブリック |
|
||
| _補助: Efficiency_ | – | duration / prompt tokens(summary に数値表示のみ) | – |
|
||
|
||
`Total = A×30 + B×15 + C×30 + D×25` を 0..100 に正規化。
|
||
|
||
`completion_status: [succeeded, waiting_human, failed, aborted, cancelled]` で受理する終了状態を指定。デフォルトは `[succeeded]` のみ。**failure でも grader は走り部分スコアが出る**。
|
||
|
||
---
|
||
|
||
## 5. 既存タスク
|
||
|
||
### `composite-mini-report`
|
||
|
||
3 ソース(Excel / Web / Markdown)を統合してミニレポートを書かせるタスク。1 本で全軸が動く。
|
||
|
||
- 必須ツール: `ReadExcel` / `WebFetch` / `Read` / `Write` / `CreateChecklist` / `CheckItem` (≥3 回) / `GetChecklist`
|
||
- 禁止: `.xlsx` を `Read` で開く(バイナリ混入防止 — issue #189 と同じ罠)
|
||
- 出力 `output/report.md` に厳格な形式制約(1 行目固定、セクション順、各セクション 5 行以内、「次アクション」3 件 40 字以内、画像・HTML 禁止)
|
||
- judge ルーブリック: `factual_grounding` / `actions_quality` / `synthesis`
|
||
|
||
`bench/tasks/composite-mini-report.yaml` を参考実装としてそのまま使える。
|
||
|
||
---
|
||
|
||
## 6. タスクを追加する
|
||
|
||
`bench/tasks/*.yaml` を作るだけで自動的に拾われる。スキーマは `src/bench/types.ts` の `BenchTask` を参照。最小例:
|
||
|
||
```yaml
|
||
id: my-task
|
||
title: 短いタスク説明
|
||
piece_hint: chat # piece 名 (省略時は chat)
|
||
timeout_minutes: 5
|
||
|
||
fixtures: # 任意
|
||
- source: fixtures/data.txt # bench/ ルート相対
|
||
dest: input/data.txt # input/ に置けば attachments としてアップロード
|
||
- source: fixtures/web/page.html
|
||
dest: web/page.html # web/ に置けば fixture HTTP server が配信
|
||
|
||
prompt_tokens: # 任意。prompt 内の {KEY} を実行時に置換
|
||
CUSTOM_KEY: foo
|
||
prompt: |
|
||
http://127.0.0.1:{WEB_PORT}/page.html を読み、… {CUSTOM_KEY} …
|
||
|
||
expected:
|
||
must_use_tools: [WebFetch, Write]
|
||
forbidden_tools: [Bash]
|
||
forbidden_tool_for_ext:
|
||
Read: ['.xlsx']
|
||
must_produce_files: [output/answer.md]
|
||
completion_status: [succeeded]
|
||
|
||
checklist: # 任意。指定すると軸 B が有効化される
|
||
required_tools: [CreateChecklist, CheckItem, GetChecklist]
|
||
min_check_item_calls: 3
|
||
|
||
grading:
|
||
programmatic:
|
||
constraints:
|
||
- { type: file_first_line_equals, file: output/answer.md, line: '# Title' }
|
||
- { type: file_must_contain_in_order, file: output/answer.md, sections: ['## A', '## B'] }
|
||
- { type: file_section_max_lines, file: output/answer.md, section: A, max: 5 }
|
||
- { type: file_line_starts_with, file: output/answer.md, prefix: '-', min_lines: 3, section: B }
|
||
- { type: file_line_max_chars, file: output/answer.md, max: 40, section: B }
|
||
- { type: file_no_pattern, file: output/answer.md, pattern: '!\[' }
|
||
|
||
llm_judge: # 任意。指定しないと軸 D は 1.0 固定
|
||
rubrics:
|
||
- name: relevance
|
||
prompt: 出力が prompt の意図と整合しているか
|
||
max_score: 10
|
||
```
|
||
|
||
### プログラム制約の種類
|
||
|
||
| `type` | 意味 |
|
||
|--------|------|
|
||
| `file_first_line_equals` | ファイル 1 行目が完全一致するか |
|
||
| `file_must_contain_in_order` | 指定文字列が指定の順序で出現するか |
|
||
| `file_line_starts_with` | (任意セクション内で) 指定 prefix で始まる行が `min_lines` 以上あるか |
|
||
| `file_line_max_chars` | (任意セクション内で) 各行の文字数が `max` 以下か |
|
||
| `file_section_max_lines` | 指定セクションの非空行が `max` 以下か |
|
||
| `file_no_pattern` | 正規表現 (multiline) にマッチしないか |
|
||
|
||
`section` は `## ヘッダ` の `ヘッダ` 部分(`##` は付けない)。指定無しならファイル全体が対象。
|
||
|
||
---
|
||
|
||
## 7. 内部構造
|
||
|
||
```
|
||
bench/
|
||
fixtures/
|
||
tasks/
|
||
results/ # gitignored
|
||
src/bench/
|
||
types.ts # BenchTask / BenchResult / 制約スキーマ
|
||
fixture-server.ts # localhost HTTP fixture server
|
||
runner.ts # /api/local/tasks に投入 + ポーリング + ログ収集
|
||
grader.ts # 軸 A/B/C のプログラム採点
|
||
judge.ts # 軸 D の LLM judge 呼び出し + JSON parse
|
||
summary.ts # bench/results/<run_id>/summary.md 書き出し
|
||
grader.test.ts
|
||
scripts/
|
||
bench-run.ts # CLI エントリ (`npm run bench`)
|
||
build-bench-fixtures.ts # sales.xlsx 生成 (`npm run bench:fixtures`)
|
||
```
|
||
|
||
ベンチランナーは既存の `/api/local/tasks` API を使うだけで、orchestrator 内部とは疎結合になっている。新しい piece やツールを追加してもベンチ側は基本変更不要。
|
||
|
||
---
|
||
|
||
## 8. トラブルシューティング
|
||
|
||
| 症状 | 原因 / 対処 |
|
||
|------|-------------|
|
||
| `runner failed for ...: fetch failed` | `scripts/server.sh start` が立っていない、または `--server=` で指定したポートが違う |
|
||
| 全タスクで axis D が 0.0 | judge LLM のレスポンスが JSON parse 失敗。`bench/results/<run>/summary.md` の reasoning details を確認。OS の事情で短い応答しか返ってこないモデルなら `BENCH_JUDGE_MODEL` を別モデルに切り替える |
|
||
| タイムアウトで status が固まる | タスク YAML の `timeout_minutes` を伸ばす。プロバイダ側 `provider.timeoutMinutes` も併せて確認 |
|
||
| 同じタスクで毎回スコアが揺れる | LLM judge が確率的なため。programmatic 軸だけ見る・複数回平均を取る運用が無難 |
|
||
| `bench/results/` がコミットに乗ってしまった | `.gitignore` 済みだが、過去に追跡されていた場合は `git rm -r --cached bench/results` |
|
||
|
||
---
|
||
|
||
## 9. 参考: 関連 issue / 機能
|
||
|
||
- #156 — このベンチマーク自体
|
||
- #189 — `Read` で xlsx を開かない仕様(composite-mini-report の `forbidden_tool_for_ext` 罠と直結)
|
||
- #190 — preflight ログ表示の整理(activity.log を grader が読みやすいことの恩恵)
|