利用側のコーディングエージェントを評価する
利用側のコーディングエージェントを評価する
Section titled “利用側のコーディングエージェントを評価する”この手順では、Appkit のコーディングエージェント用タスクを保守し、レビュー済みのランナーを、対象として指定した候補アーカイブそのものに対して評価します。担当者の割り当て、タスクの編集、検証、ランナーの設定、バッチの実行、保存結果の確認と適格性判定の順に進めてください。既存のタスクを変更しない場合は、候補パッケージを準備するから始めてください。
決定的なツールテスト、作成済みのサンプル、模擬ランナーの結果は、実際のエージェントの成功を証明するものではありません。選択したアーカイブに対して適格性基準を満たす実エージェントのバッチが得られるまで、実環境でのタスク遂行能力は未検証のままです。
これは、エージェント向け API、指示、検出方法の変更に対する任意の手動回帰評価です。 npm 公開の必須ゲートではありません。リリース用の公開処理では、代わりに決定的なパッケージチェックが必要であり、 モデルの実行やローカルの記録票の利用は行いません。実環境での評価を実施したと主張する場合には、 既存の適格性基準が引き続き適用されます。固定された 6 タスクのベンチマークは、 パッケージ全般を認証するものではありません。リリース手順を参照してください。
Node 24+、Bun 1.4.0、およびリポジトリにインストール済みの開発依存関係を使用し、公開 Appkit リポジトリのルートで作業してください。実環境のバッチを実行するには、Docker、レビュー済みのコーディングエージェント用ランナーイメージ、および Node 24+ を提供する検証用イメージを準備してください。両方のイメージがすでにローカルで利用可能であり、ダイジェストで固定されている必要があります。モデルへの接続はランナー自体が提供します。Appkit は特定のプロバイダー SDK やエージェントベンダーを要求しません。
公開済みの 0.1.0 アーカイブは変更しません。開発候補には同じバージョン文字列を使用でき、整合性情報またはダイジェストで識別します。この手順は、コミット、公開、デプロイを許可するものではありません。ローカルのランナー設定と実行証跡は、無視対象の .verification/ 配下に保存してください。
1. 作成者、レビュー担当者、実行担当者を割り当てる
Section titled “1. 作成者、レビュー担当者、実行担当者を割り当てる”タスクを変更する前に、以下の責任を割り当ててください。1 人のメンテナーが複数の役割を担ってもかまいません。これらは作業上の責任分担であり、ハーネスが強制する役割ではありません。
| 役割 | 編集または提供するもの | 責任 |
|---|---|---|
| タスク作成者:Appkit メンテナーまたは信頼できる作成支援アシスタント | scripts/agent-eval/tasks/ 配下のタスクファイル、共有採点器、回帰テスト用フィクスチャ |
要求する動作、公開 API、合格・不合格のケースを定義します。プロンプト、契約、採点器の整合性を保ちます。 |
| タスクレビュー担当者:変更をレビューするメンテナー | レビューのフィードバック、および必要に応じて記録票の reviewDecisions |
正しい解が合格し、安全でない解や誤った解が不合格になること、およびエージェントが自分自身を採点できないことを確認します。 |
| 評価実行担当者:バッチを実行する人 | 無視対象のランナー設定、レビュー済みイメージ、モデル設定 | パッケージを準備し、バッチを実行し、証跡を確認して適格性判定を実行します。 |
| 評価対象のエージェント | allowedOutputPaths に記載された解答ファイルのみ |
提供されたタスクを解きます。タスク定義、依存関係、コンパイラー設定、採点器、記録済みのスコアは編集できません。 |
リポジトリの保守を支援する信頼できるアシスタントは、タスク作成者です。隔離された環境でタスクを解くエージェントは、評価対象です。評価定義を編集する権限は、前者にのみ付与してください。
2. 既存のタスクを 1 つ編集する
Section titled “2. 既存のタスクを 1 つ編集する”scripts/agent-eval/tasks/ 配下の既存ディレクトリを選択してください。たとえば、core-validation には次のファイルが含まれます。
scripts/agent-eval/tasks/core-validation/ task.json # Identity, allowed outputs/imports and required assertions/APIs prompt.md # Instructions sent to the agent contract.d.ts # Required solution exports and types grade.mjs # Thin entry delegating to the shared task gradererror-recovery のように、初期ファイルを含む starter/ があるタスクもあります。初期ファイルには allowedOutputPaths と同じ相対パスを使用します。このタスクは、意図的に無効なインポートを含む starter/solution.ts がある状態から始まります。
次の順序でファイルを編集してください。
prompt.mdに依頼内容を記述します。 作成するもの、必要な Appkit 統合、無効な入力、副作用、安全上の境界を明記してください。contract.d.tsと同じエクスポート契約を含めてください。プロンプトに埋め込まれた契約は自動的には同期されません。contract.d.tsで解答のインターフェースを定義します。 ハーネスはこれをエージェント向けに/consumer/task-contract.d.tsに配置し、提出されたエクスポートが契約に適合するかを独立して確認します。ここに採点用の正解を記載しないでください。task.jsonを更新します。 ディレクトリ名とidを一致させ、以下のフィールドを一貫して使用してください。- 共有の動作採点器とそのテストを更新します。 タスク固有のラッパーを編集するだけで終えないでください。
task.json のフィールド |
タスク作成者が指定する内容 |
|---|---|
id |
ディレクトリ名と一致する既存のタスク識別子 |
allowedOutputPaths |
["solution.ts"] など、解答となる TypeScript/TSX ファイルの正確な相対パス |
allowedImports |
許可するパッケージインポート。/* は、そのパッケージのサブパスを許可します |
requiredPeers |
タスクのピア依存関係の要件。フィクスチャのインストールを実際に変更する場合は、workspace.mjs での変更と整合させてください |
assertionIds |
共有採点器が出力する必要のある動作チェックの完全な一覧 |
safetyAssertionIds |
初回を含め、適用対象となるすべての提出試行で合格する必要のあるチェックの部分集合 |
seedReferences |
初期コードに含める、意図的に無効な Appkit 参照。存在しない場合は [] を使用します |
requiredIntegration |
[{"symbols":["createAjvValidator"]}] など、値として使用する必要のある Appkit シンボル |
core-validation/task.json の完全な定義が具体例になります。requiredPeers はタスクのメタデータです。そこに名前を追加してもインストールは行われません。準備される利用側環境の明示的な依存関係リストは、workspace.mjs にあります。
実環境での動作チェックは graders.mjs に実装され、タスク ID で選択されます。各タスクの grade.mjs は、この共有実装に処理を委譲します。実環境のバッチは共有採点器を直接呼び出します。grade.mjs だけを変更しても、実環境での採点は変わりません。 graders.mjs 内の該当する分岐を更新し、そのアサーション ID を task.json と一致させてください。静的な API チェックと統合チェックは score.mjs にあります。
開発者が作成した解答は scripts/agent-eval/fixtures/ に、不合格となるケースは関連するテストに保存してください。これらは評価器への入力であり、評価対象のエージェントに公開するファイルではありません。期待する解答をプロンプト、契約、初期ファイルのディレクトリに記載しないでください。
現在のスイートには、core-validation、storage-hash、react-form、tool-validation、approval-boundary、error-recovery という固定された 6 つのタスクがあります。7 つ目のディレクトリを作成する方法での拡張はサポートされていません。タスク ID、スイートの検証、18 回の実行スケジュール、適格性判定の期待条件とテストをまとめて変更する必要があります。現在の実環境用 CLI はスイート全体を実行し、単一タスクを選択するフラグはありません。
3. モデルを使用する前に、編集したタスクを検証する
Section titled “3. モデルを使用する前に、編集したタスクを検証する”正しい実装が合格し、誤った実装や安全でない実装が不合格になることを示す回帰テストケースを追加または更新してください。正常系だけでなく、宣言したすべての検証ルールと安全ルールを網羅してください。未使用の Appkit インポートや型専用の Appkit インポートでは必要な統合を満たせないこと、および期待するアサーション ID が採点器と一致することを確認してください。
bun run test:agent-tooling期待される結果:決定的なテストが合格します。任意の実 Docker 統合テストは、フィクスチャ環境が設定されていなければスキップと報告されます。このスキップは、実環境での評価結果ではありません。この別個のテストについては、後述の評価器の境界チェックを参照してください。
タスクレビュー担当者に、プロンプト、契約、メタデータ、共有採点器、回帰テストケースをまとめて確認してもらってください。タスクファイルを 1 つでも編集すると、スイートのダイジェストが変わります。タスクまたは評価器を変更した場合は、以前のスコアを再利用せず、新しい実環境のバッチを実行する必要があります。
4. 候補パッケージを準備する
Section titled “4. 候補パッケージを準備する”実環境用 CLI がパッケージ化する前に、両方のパッケージをビルドし、型チェックと検証を実行してください。
bun run turbo run build typecheck test --filter=@alneas/appkit-core --filter=@alneas/appkit-reactbun run docs:generatebun run check:docsbun run test:agent-toolingbun run check:releasebun run test:consumer期待される結果:適用対象のすべてのチェックが合格します。これらのチェックで確認できるのはパッケージとツールの正しさであり、適格性基準を満たす実エージェントの記録票は生成されません。候補アーカイブは、保持されている公開用の two-package-0.1.0 アーカイブとは別のものです。
5. レビュー済みのランナーを設定する
Section titled “5. レビュー済みのランナーを設定する”評価実行担当者は、無視対象の .verification/agent-eval/runner.json 配下に設定を保存します。レビュー済みの実際の実行ファイル、モデル設定、ローカルに準備済みのイメージのダイジェストを指定してください。このファイルに認証情報の値を直接記載しないでください。
| フィールド | 必要な値 |
|---|---|
executable、args |
ランナーイメージ内の実行ファイルと引数配列。シェル式は使用できません |
envAllowlist |
必要なモデル認証情報の名前のみを明示します。npm/GitHub/クラウド/データベースの認証情報は拒否されます |
expectedRunner |
ランナーの正確な name と version を持つオブジェクト |
expectedModel |
モデルの正確な id と settings を持つオブジェクト。通知なしのフォールバックは使用できません |
submissionTimeoutMs |
600000 以下の正の整数 |
batchTimeoutMs |
7200000 以下の正の整数 |
runtimePath |
レビュー済みのローカル Docker CLI 実行ファイル |
runnerImage、verifierImage |
実際の @sha256: ダイジェストを含む、事前に準備済みのイメージ名 |
実行ファイルは、ランナープロトコルを実装し、スケジュールされた実行ごとに新しいモデルコンテキストを開始し、制御プロセスの認証情報をツールのサブプロセスや出力に渡さないようにする必要があります。レビュー済みのランナーとモデルの実装については、実行担当者が責任を負います。応答フィールドが一致するだけでは、プロバイダーの真正性は証明されません。
6. 実環境のバッチを実行し、表示された記録票のパスを保持する
Section titled “6. 実環境のバッチを実行し、表示された記録票のパスを保持する”bun run eval:agent -- --runner-config .verification/agent-eval/runner.jsonCLI は候補をパッケージ化し、レビュー対象のアーカイブそのものを使い捨ての利用側環境にインストールして、新しい .verification/agent-eval/<timestamp>-<uuid>/ ディレクトリ配下に結果を書き込みます。その後、使い捨ての利用側環境をクリーンアップします。この呼び出しで表示された receipt のパスを使用してください。記録票内の別の runId フィールドからディレクトリを推測しないでください。
以下は出力形式のみを示す例であり、記録された実環境の結果ではありません。
{"status":"completed","receipt":".verification/agent-eval/<timestamp>-<uuid>/receipt.json","firstSuccesses":15,"finalSuccesses":18}6 つの各タスクを新しいコンテキストで 3 回ずつ実行します。つまり、スケジュールされた初回提出は 18 回です。提出された実装が不合格になった場合は、コンパイラーと動作に関するフィードバックを受けて、1 回だけ修正を試みられることがあります。実行開始後のタイムアウト、拒否、無効な応答、予算の枯渇は、スケジュールされた実行の失敗として扱われ、自動的な代替実行は作成されません。
completed は、スケジュールされたバッチが完了したことを意味し、適格性基準を満たしたことは意味しません。設定、隔離環境、イメージの不足や不備があると not-run になります。初期設定段階で失敗した場合は、最小限の receipt.json しか存在しないことがあります。
保存された採点結果と提出コードを確認する
Section titled “保存された採点結果と提出コードを確認する”最初に、表示された receipt.json を開いてください。これが、バッチと各試行について保存された正式な評価結果です。実行ディレクトリ内の関連ファイルは以下のとおりです。
.verification/agent-eval/<timestamp>-<uuid>/ receipt.json archives.json consumer-lock.json archives/ appkit-core.tgz appkit-react.tgz runs/ core-validation-1/ attempt-1/ solution/ solution.ts analysis.json attempt-2/ # Present only when a repair was attempted solution/ solution.ts analysis.jsonほかのスケジュール済み実行のディレクトリには、<task-id>-<repetition> を使用します。たとえば react-form-3 です。このツリーは主要な証跡ファイルを示しています。実行ルートには、パッケージ化時の元の出力ファイルが存在する場合もあります。
| ファイルまたは記録票のフィールド | 内容と使用方法 |
|---|---|
receipt.json → firstSuccesses、finalSuccesses、completed |
バッチの合計値と完了状態。分母の 18 を維持してください |
receipt.json → runs[] → attempts[] |
保存された API/型の評価、behavior.assertions、safety、needsReview、未サポートまたは捏造された API の件数、診断、修正用フィードバック、ソースと保護対象入力のダイジェスト |
runs/<task-id>-<repetition>/attempt-<n>/solution/ |
その試行で収集された解答ファイルそのもの |
runs/<task-id>-<repetition>/attempt-<n>/analysis.json |
コンパイラー/API の静的解析。契約や動作についての最終判定ではありません。最終結果は記録票を確認してください |
archives.json |
候補アーカイブのハッシュ、およびレビュー済みのソース、カタログ、ツールチェーン、イメージ、ランナーとモデルの識別情報 |
archives/*.tgz |
実行に使用した、レビュー対象の候補パッケージの正確なバイト列 |
consumer-lock.json |
ツールチェーンの識別情報を結び付けるために使用した、準備済み利用側環境の依存関係ロック |
qualification.json |
実行担当者が後述の例のように適格性判定コマンドをリダイレクトした場合にのみ作成されます。ハーネスは自動的には書き込みません |
収集または評価が完了する前に失敗した場合、不合格の試行には解答ディレクトリや analysis.json がないことがあります。ファイルが存在しないことを合格と扱わず、記録票の failureCategory、diagnosticCategories、observed とインフラストラクチャの状態を確認してください。ハーネスは、モデルとの完全な対話記録やランナーの未加工の stdout/stderr を、試行ごとのログファイルとして自動保存しません。
判断が曖昧なコードをレビューし、バッチの適格性を判定する
Section titled “判断が曖昧なコードをレビューし、バッチの適格性を判定する”unsupportedApiCount は、未サポートの Appkit インポート、シンボル、解決可能なメンバーの重複を除いた件数です。hallucinatedApiCount では、初期コードに意図的に埋め込まれた無効な参照のうち、変更されていないものを除外します。埋め込まれた参照を除外対象にするには、正規のインポート文と使用文が変更されていない必要があります。変更されたエイリアスや新しい使用箇所は、新規参照として数えます。誤った引数、依存関係の不足、構文エラーは、それぞれ別の診断カテゴリとして扱います。
必須の Appkit シンボルは、未使用のインポートや型専用のインポートだけでなく、値としての使用箇所(呼び出し、インスタンス生成、JSX、コールバック引数)が必要です。静的な値使用チェックでは、実行時のすべての経路でその API が使用されることまでは証明できません。試行に needsReview: true がある場合、タスクレビュー担当者は保存されたソースそのものを確認し、記録票の reviewDecisions 配列に、solutionDigest、decision: "accept"、および空でない reviewer 識別子を含む承認を記録します。その試行の実際のダイジェストを使用してください。記録票のほかのフィールドは保持し、実行を合格させるために採点結果、アサーション、ハッシュを変更しないでください。レビューの判断によって安全性の不合格を覆すことはできません。
表示された記録票の親ディレクトリを eval_run_dir として使用してください。以下のプレースホルダーを、その実際のディレクトリに置き換えてください。このコマンドは、適格性判定を別のローカルファイルに保存します。
eval_run_dir='.verification/agent-eval/<timestamp>-<uuid>'bun run check:agent-eval -- --receipt "$eval_run_dir/receipt.json" --archives "$eval_run_dir/archives.json" > "$eval_run_dir/qualification.json"期待される結果:終了コードが 0 になり、qualification.json に {"qualified":true,"reasons":[]} が記録されます。不適格と判定されたバッチは終了コード 1 となり、qualified: false とその理由を記録します。リダイレクトしない場合、コマンドはその JSON を stdout に出力し、判定ファイルは保存しません。
適格性を満たすには、初回提出の成功が少なくとも 15/18、最終的な成功が 18/18、最終的な未サポートの Appkit 参照がゼロであり、さらに不合格となった初回試行を含むすべての提出試行で、適用対象となる検証・承認に関する安全性アサーションがすべて合格する必要があります。安全でない初回提出は、修正しても適格性を満たせません。証跡が欠落、不完全、自己テスト由来、古い、または変更済みである場合は、安全側に倒して不合格とします。このチェックは、実際のアーカイブと保存された解答を記録済みのダイジェストと比較し、レビュー済みのランナーとモデルの識別情報に結び付けます。
この固定スイートは、宣言されたランナー、モデル、入力に対する回帰評価の指標として扱ってください。コーディングエージェント全般の認証として扱わないでください。記録票はローカルの運用証跡であり、来歴を暗号学的に証明するものではありません。モデル、スイート、評価器、パッケージ入力、環境を変更した場合は、新しいベースラインが必要です。文脈のない割合だけでなく、件数と分母を報告してください。
記録票と、別途取得した対話記録は、無視対象のままにしてください。未加工のログをアップロードしたり、パッケージ、AI インデックス、公開ドキュメントのマニフェストに含めたりしないでください。必要な場合は、別途レビューして機密情報を除去した要約を共有してください。公開は、引き続きリリース手順における別途の承認を要する工程です。
トラブルシューティング / よくある落とし穴
Section titled “トラブルシューティング / よくある落とし穴”| 症状 | 確認事項または対処方法 |
|---|---|
実環境用コマンドが not-run を報告する |
表示された記録票を確認してください。無視対象のランナー設定、ローカルの Docker サービス、準備済みイメージ、候補の準備状況を検証してください。アーカイブや試行ごとのファイルがまだ存在しない場合があります |
completed が true でも適格性判定に不合格になる |
qualification.json、またはゲートの stdout に出力された理由を確認してください。完了していても、必要な成功件数や安全性の結果を満たしているとは限りません |
提出された解答はあるが analysis.json がない |
記録票の runs[].failureCategory と、その試行の診断を確認してください。収集が完了した後に検証器が失敗する場合があります |
タスクの grade.mjs を編集しても実環境に反映されない |
共有の graders.mjs 内の該当分岐、アサーションのメタデータ、回帰テストをまとめて更新してください |
| 新しいタスクディレクトリが拒否される | スイートが受け入れるのは固定された 6 つの ID のみです。タスクの追加には、スイート、スケジュール、適格性判定を連動させた変更が必要です |
| 決定的なテストには合格するが、実環境での能力は未検証のままである | 実際に設定したバッチを実行してください。模擬ドライバーや作成済みの Docker フィクスチャでは、適格性基準を満たす実環境の証跡は生成できません |
試行に needsReview: true がある |
保存された解答そのものをレビューし、ダイジェストに結び付けた判断を記録してください。安全性の不合格を免除することはできません |
| ソース、スイート、ダイジェストのチェックで古い記録票が拒否される | 入力を確定し、新しいバッチを実行してください。新しいコードに合わせて古い記録済みハッシュを更新しないでください |
ランナープロトコルと隔離
Section titled “ランナープロトコルと隔離”ランナーは、schemaVersion: 1、runId、taskId、taskText、consumerDir、outputDir、allowedOutputPaths、attempt、timeBudgetMs、および任意の制限付き修正用 feedback を受け取ります。コンテナ内のパスは /consumer と /solution です。stdout には、一致する ID、schemaVersion: 1、status(completed または failed)、runner、model を含む JSON オブジェクトを、ちょうど 1 つ出力する必要があります。stderr は診断出力です。ランナーが提供するスコアは無視されます。
評価対象のエージェントは、同梱されたガイド、スキル、API カタログ、プロンプト、解答契約を参照できます。利用側環境には採点器や正解フィクスチャは存在しません。パッケージマニフェスト、依存関係、コンパイラー設定、採点器の入力は、書き込み可能な範囲外です。通常ファイルであり、制限内に収まり、許可リストに含まれる解答ファイルだけが、新しい検証器のワークスペースに収集されます。保護対象のフィクスチャファイルは、エージェントの実行前後にハッシュを計算します。
期待値、アサーション、承認判断、副作用カウンターは、信頼された採点器が管理します。提出コードは、UID/GID 65534 の別サブプロセスで、stdout/stderr とは別の制限付き RPC パイプを介して実行されます。提出された JSON や stdout を採点結果として受け入れることはありません。DOM の観測とアダプターの呼び出しは、この信頼されていないインターフェースを経由します。副作用を伴うコールバックは、シナリオを閉じる前に無効化されます。
信頼されたコンテナの親プロセスは、UID 0 と SETUID、SETGID、DAC_OVERRIDE、KILL のケーパビリティのみを使用して、別ユーザーのプロセスを起動・停止し、保護対象の入力を読み取ります。提出コードを実行する子プロセスはこれらのケーパビリティを失い、非公開の採点器入力の読み取り、親プロセスへのシグナル送信、親プロセスの出力記述子へのアクセスはできません。検証器には、読み取り専用のルート、ネットワークなし、no-new-privileges、リソース制限が設定されます。採点器コードのモードは 0700、入力は 0600 です。静的解析が解答を受け入れた場合でも、これらの境界は必須です。
提出コードの検証環境に、ホストのホーム、Docker ソケット、リポジトリ、非公開の兄弟リポジトリ、認証情報をマウントしないでください。一時ディレクトリだけではサンドボックスになりません。通常の CI は模擬起動を使用し、Docker やモデルの認証情報は必要ありません。
評価器の境界チェック
Section titled “評価器の境界チェック”通常のツールテストスイートは、作成済みのサンプルを使用して、偽造された stdout、早期終了、JSON グローバルの改ざんをテストします。任意の実 Docker 統合テストでは、独立して準備した利用側環境に対して 6 つすべての正常な実装を実行し、UID の分離、保護対象の入力、異なる UID 間での編集、採点結果の偽造をチェックします。
APPKIT_TEST_CONSUMER=/absolute/path/to/prepared-consumer \APPKIT_TEST_VERIFIER_IMAGE=reviewed-image@sha256:reviewed-digest \node --test scripts/agent-eval/isolated-verifier.test.mjs実行担当者は、対象として指定した 2 つの候補アーカイブそのものを使い、prepareCandidate を通じてその利用側環境を準備する必要があります。この処理は React Testing Library に加えて @testing-library/dom を明示的にインストールするため、チェックアウト先の依存関係によって不足したピア依存関係が隠れることはありません。これらの任意のテスト変数は、フィクスチャ用インフラストラクチャの選択にのみ使用されます。変数がない場合、テストはスキップと報告され、適格性基準を満たす実環境の記録票を生成することはありません。