agent-evaluation
AIエージェント向けの包括的な評価システムの設計と実装ができます。コーディングエージェント、会話型エージェント、リサーチエージェント、コンピュータ操作エージェントなど、各種エージェントの評価構築時に活用してください。採点方法の種類、ベンチマーク、8段階のロードマップ、本番環境への統合まで対応します。
description の原文を見る
Design and implement comprehensive evaluation systems for AI agents. Use when building evals for coding agents, conversational agents, research agents, or computer-use agents. Covers grader types, benchmarks, 8-step roadmap, and production integration.
SKILL.md 本文
Agent Evaluation (AI Agent Evals)
Anthropicの「Demystifying evals for AI agents」に基づいています
このスキルを使う場合
- AIエージェントの評価システムを設計する
- コーディング、会話型、またはリサーチエージェント用のベンチマークを構築する
- グレーダー(コードベース、モデルベース、ヒューマン)を作成する
- AI システムの本番環境での監視を実装する
- 自動化評価を含むCI/CDパイプラインをセットアップする
- エージェントのパフォーマンス問題をデバッグする
- 時間経過に伴うエージェントの改善を測定する
主要概念
Eval の進化: 単一ターン → マルチターン → エージェント型
| 種類 | ターン数 | 状態 | グレーディング | 複雑度 |
|---|---|---|---|---|
| 単一ターン | 1 | なし | シンプル | 低 |
| マルチターン | N | 会話 | ターンごと | 中 |
| エージェント型 | N | ワールド + 履歴 | 結果 | 高 |
7 つの主要用語
| 用語 | 定義 |
|---|---|
| Task(タスク) | 単一のテストケース(プロンプト + 期待される結果) |
| Trial(トライアル) | タスクに対するエージェントの 1 回の実行 |
| Grader(グレーダー) | スコアリング関数(コード/モデル/ヒューマン) |
| Transcript(トランスクリプト) | エージェントのアクションの完全な記録 |
| Outcome(結果) | グレーディング用の最終状態 |
| Harness(ハーネス) | Eval を実行するインフラストラクチャ |
| Suite(スイート) | 関連するタスクのコレクション |
手順
Step 1: グレーダーの種類を理解する
コードベースのグレーダー(コーディングエージェント向けに推奨)
- 長所: 高速、客観的、再現可能
- 短所: 明確な成功基準が必要
- 最適な用途: コーディングエージェント、構造化された出力
# 例: コードベースのグレーダー
def grade_task(outcome: dict) -> float:
"""テスト合格でコーディングタスクをグレーディング"""
tests_passed = outcome.get("tests_passed", 0)
total_tests = outcome.get("total_tests", 1)
return tests_passed / total_tests
# SWE-bench スタイルのグレーダー
def grade_swe_bench(repo_path: str, test_spec: dict) -> bool:
"""テストを実行し、パッチが問題を解決しているか確認"""
result = subprocess.run(
["pytest", test_spec["test_file"]],
cwd=repo_path,
capture_output=True
)
return result.returncode == 0
モデルベースのグレーダー(LLM-as-Judge)
- 長所: 柔軟性、ニュアンスに対応
- 短所: キャリブレーション が必要、矛盾する可能性がある
- 最適な用途: 会話型エージェント、オープンエンドなタスク
# 例: カスタマーサポートエージェント用の LLM ルーブリック
rubric:
dimensions:
- name: empathy
weight: 0.3
scale: 1-5
criteria: |
5: 感情を認め、温かい言葉遣いを使用
3: 丁寧だが個人的でない
1: 冷淡または軽視的
- name: resolution
weight: 0.5
scale: 1-5
criteria: |
5: 問題を完全に解決
3: 部分的な解決
1: 解決なし
- name: efficiency
weight: 0.2
scale: 1-5
criteria: |
5: 最小限のターンで解決
3: 妥当なターン数
1: 過度なやり取り
ヒューマングレーダー
- 長所: 最高の精度、エッジケースを捕捉
- 短所: 高額、遅い、スケーラブルでない
- 最適な用途: 最終的な検証、曖昧なケース
Step 2: エージェントの種類別に戦略を選択する
2.1 コーディングエージェント
ベンチマーク:
- SWE-bench Verified: 実際の GitHub 問題(40% → 80% 以上達成可能)
- Terminal-Bench: 複雑なターミナルタスク
- あなたのコードベースを使用したカスタムテストスイート
グレーディング戦略:
def grade_coding_agent(task: dict, outcome: dict) -> dict:
return {
"tests_passed": run_test_suite(outcome["code"]),
"lint_score": run_linter(outcome["code"]),
"builds": check_build(outcome["code"]),
"matches_spec": compare_to_reference(task["spec"], outcome["code"])
}
主要メトリクス:
- テスト合格率
- ビルド成功
- Lint/スタイル準拠
- diff サイズ(小さいほど良い)
2.2 会話型エージェント
ベンチマーク:
- τ2-Bench: マルチドメイン会話
- カスタムドメイン固有スイート
グレーディング戦略(多次元):
success_criteria:
- empathy_score: >= 4.0
- resolution_rate: >= 0.9
- avg_turns: <= 5
- escalation_rate: <= 0.1
主要メトリクス:
- タスク解決率
- 顧客満足度プロキシ
- ターン効率
- エスカレーション率
2.3 リサーチエージェント
グレーディングの側面:
- Grounding(接地性): クレームがソースで裏付けられている
- Coverage(カバレッジ): すべての側面に対応している
- Source Quality(ソース品質): 信頼できるソースが使用されている
def grade_research_agent(task: dict, outcome: dict) -> dict:
return {
"grounding": check_citations(outcome["report"]),
"coverage": check_topic_coverage(task["topics"], outcome["report"]),
"source_quality": score_sources(outcome["sources"]),
"factual_accuracy": verify_claims(outcome["claims"])
}
2.4 コンピュータ操作エージェント
ベンチマーク:
- WebArena: ウェブナビゲーションタスク
- OSWorld: デスクトップ環境タスク
グレーディング戦略:
def grade_computer_use(task: dict, outcome: dict) -> dict:
return {
"ui_state": verify_ui_state(outcome["screenshot"]),
"db_state": verify_database(task["expected_db_state"]),
"file_state": verify_files(task["expected_files"]),
"success": all_conditions_met(task, outcome)
}
Step 3: 8 ステップのロードマップに従う
Step 0: 早期開始(20~50 タスク)
# 初期 eval スイート構造を作成
mkdir -p evals/{tasks,results,graders}
# 代表的なタスクで開始
# - 一般的なユースケース(60%)
# - エッジケース(20%)
# - 失敗モード(20%)
Step 1: 手動テストを変換
# 既存の QA テストを eval タスクに変換
def convert_qa_to_eval(qa_case: dict) -> dict:
return {
"id": qa_case["id"],
"prompt": qa_case["input"],
"expected_outcome": qa_case["expected"],
"grader": "code" if qa_case["has_tests"] else "model",
"tags": qa_case.get("tags", [])
}
Step 2: 明確性と参照ソリューションを確保
# 良いタスク定義
task:
id: "api-design-001"
prompt: |
以下を含むユーザー管理用の REST API を設計してください:
- CRUD オペレーション
- JWT によるAuthentication
- レート制限
reference_solution: "./solutions/api-design-001/"
success_criteria:
- "すべてのエンドポイントがドキュメント化されている"
- "Auth ミドルウェアが存在する"
- "レート制限設定が存在する"
Step 3: ポジティブケース/ネガティブケースのバランスを取る
# eval スイートのバランスを確保
suite_composition = {
"positive_cases": 0.5, # 成功すべき
"negative_cases": 0.3, # 適切に失敗すべき
"edge_cases": 0.2 # 境界条件
}
Step 4: 環境を分離
# コーディング eval 用の Docker ベースの分離
eval_environment:
type: docker
image: "eval-sandbox:latest"
timeout: 300s
resources:
memory: "4g"
cpu: "2"
network: isolated
cleanup: always
Step 5: パスではなく結果に焦点を当てる
# 良い例: 結果重視のグレーダー
def grade_outcome(expected: dict, actual: dict) -> float:
return compare_final_states(expected, actual)
# 悪い例: パス重視のグレーダー(脆弱性が高い)
def grade_path(expected_steps: list, actual_steps: list) -> float:
return step_by_step_match(expected_steps, actual_steps)
Step 6: トランスクリプトを常に読む
# デバッグ用のトランスクリプト分析
def analyze_transcript(transcript: list) -> dict:
return {
"total_steps": len(transcript),
"tool_usage": count_tool_calls(transcript),
"errors": extract_errors(transcript),
"decision_points": find_decision_points(transcript),
"recovery_attempts": find_recovery_patterns(transcript)
}
Step 7: Eval の飽和状態を監視
# eval がもはや有用でないかどうかを検出
def check_saturation(results: list, window: int = 10) -> dict:
recent = results[-window:]
return {
"pass_rate": sum(r["passed"] for r in recent) / len(recent),
"variance": calculate_variance(recent),
"is_saturated": all(r["passed"] for r in recent),
"recommendation": "Add harder tasks" if saturated else "Continue"
}
Step 8: 長期的なメンテナンス
# Eval スイートメンテナンスチェックリスト
maintenance:
weekly:
- 失敗した eval をレビューし、偽陰性がないか確認
- 不安定なテストを確認
monthly:
- 本番環境の問題から新しいエッジケースを追加
- 飽和した eval を廃止
- 参照ソリューションを更新
quarterly:
- 完全なベンチマークのキャリブレーション
- チームの貢献レビュー
Step 4: 本番環境に統合
CI/CD 統合
# GitHub Actions の例
name: Agent Evals
on: [push, pull_request]
jobs:
eval:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Run Evals
run: |
python run_evals.py --suite=core --mode=compact
- name: Upload Results
uses: actions/upload-artifact@v4
with:
name: eval-results
path: results/
本番環境の監視
# リアルタイム eval サンプリング
class ProductionMonitor:
def __init__(self, sample_rate: float = 0.1):
self.sample_rate = sample_rate
async def monitor(self, request, response):
if random.random() < self.sample_rate:
eval_result = await self.run_eval(request, response)
self.log_result(eval_result)
if eval_result["score"] < self.threshold:
self.alert("Low quality response detected")
A/B テスト
# エージェントバージョンを比較
def run_ab_test(suite: str, versions: list) -> dict:
results = {}
for version in versions:
results[version] = run_eval_suite(suite, agent_version=version)
return {
"comparison": compare_results(results),
"winner": determine_winner(results),
"confidence": calculate_confidence(results)
}
ベストプラクティス
実施すべき項目 ✅
- 20~50 個の代表的なタスクで開始する
- 可能な限りコードベースのグレーダーを使用する
- パスではなく結果に焦点を当てる
- デバッグのためにトランスクリプトを読む
- Eval の飽和状態を監視する
- ポジティブケース/ネガティブケースのバランスを取る
- Eval 環境を分離する
- Eval スイートをバージョン管理する
実施してはいけない項目 ❌
- キャリブレーションなしでモデルベースのグレーダーに過度に依存しない
- 失敗した eval を無視しない(偽陰性が存在する)
- 中間ステップでグレーディングしない
- トランスクリプト分析をスキップしない
- 本番データをサニタイズせずに使用しない
- Eval スイートを陳腐化させない
成功パターン
パターン 1: 段階的な Eval の複雑さの増加
レベル 1: ユニット eval(単一の機能)
レベル 2: 統合 eval(複合された機能)
レベル 3: エンドツーエンド eval(完全なワークフロー)
レベル 4: 敵対的 eval(エッジケース)
パターン 2: Eval 駆動開発
1. 新機能用の eval タスクを作成
2. eval を実行(失敗を予期)
3. 機能を実装
4. eval を実行(成功を予期)
5. リグレッションスイートに追加
パターン 3: 継続的なキャリブレーション
週単位: グレーダーの精度をレビュー
月単位: フィードバックに基づいてルーブリックを更新
四半期単位: ヒューマンベースラインによる完全なグレーダー監査
トラブルシューティング
問題: Eval スコアが 100%
解決策: より難しいタスクを追加し、eval の飽和状態を確認(Step 7)
問題: モデルベースのグレーダースコアが矛盾している
解決策: ルーブリックにさらに例を追加し、構造化出力を使用し、グレーダーをアンサンブルする
問題: Eval が CI で遅すぎる
解決策: toon モードを使用し、並列化し、PR チェック用にサブセットをサンプリング
問題: エージェントが eval に合格するが本番環境で失敗する
解決策: eval スイートに本番環境の失敗ケースを追加し、多様性を増加させる
参考資料
例
例 1: シンプルなコーディングエージェント Eval
# タスク定義
task = {
"id": "fizzbuzz-001",
"prompt": "Python で fizzbuzz 関数を書いてください",
"test_cases": [
{"input": 3, "expected": "Fizz"},
{"input": 5, "expected": "Buzz"},
{"input": 15, "expected": "FizzBuzz"},
{"input": 7, "expected": "7"}
]
}
# グレーダー
def grade(task, outcome):
code = outcome["code"]
exec(code) # サンドボックス内で実行
for tc in task["test_cases"]:
if fizzbuzz(tc["input"]) != tc["expected"]:
return 0.0
return 1.0
例 2: LLM ルーブリックを使用した会話型エージェント Eval
task:
id: "support-refund-001"
scenario: |
顧客が破損した製品の払い戻しを希望しています。
製品: ノートパソコン、注文: #12345、破損: 画面にひび
expected_actions:
- 問題を認める
- 注文を確認
- 解決策オプションを提供
max_turns: 5
grader:
type: model
model: claude-3-5-sonnet-20241022
rubric: |
各側面について 1~5 で評価:
- Empathy(共感): エージェントは顧客の不満を認めましたか?
- Resolution(解決): 明確なソリューションが提供されましたか?
- Efficiency(効率性): 妥当なターン数で問題が解決されましたか?
ライセンス: Apache-2.0(寛容ライセンスのため全文を引用しています) · 原本リポジトリ
詳細情報
- 作者
- autohandai
- ライセンス
- Apache-2.0
- 最終更新
- 2026/3/18
Source: https://github.com/autohandai/community-skills / ライセンス: Apache-2.0