Skill Auditor — エージェント能力低下と適合性評価
概要
スキルは減価する資産です。 モデルバージョンは数ヶ月ごとにリリースされます。前四半期に問題なかったスキルが、気づかれないうちに退行する可能性があります — 出力形式の誤り、ツール呼び出しの破損、トリガーの見逃しなど — そしてユーザーは自分のエージェントが賢くなくなったことに気づきません。
このスキルは評価方法論です。3つの質問に答えます。
- スキルは低下しているか? — モデルバージョン間での能力退行。
- 新しいスキルは実際に優れているか? — 有効性対コスト。
- スキルはこのユーザーに適合するか? — トリガー精度 + 環境 + スタイル。
5つの実行可能なエントリポイントを提供します。
scripts/console.py— 常駐コンソール(データレイヤー):ホストごとにregistry.<host>.jsonを維持し、モデルバージョンの変更を検出し(bump/check)、推奨/削除パネルを出力します。完全なコマンドセットについてはUSAGE.mdを参照してください。scripts/regress.py— ゴールデンセット再生結果を基に、パス率マトリクスを計算し、低下(閾値+方向)をフラグ付けし、アセットが編集された場合はFINGERPRINT-DRIFTをフラグ付けします。scripts/baseline.py— 再生チェックリストをスキャフォールドし、記録された判定結果をbaseline-results.jsonにマージします(アセットごと;完全上書きの場合は--replace)。ドラフトゴールデンケースは--allow-draftがない限りスキップされます。scripts/fingerprint.py— スタンドアロンレポートCLI;scanと同じハッシュコードの薄いラッパーです。fingerprint-report.*のみを書き込みます。レジストリは書き込みません。scripts/install.py— このスキルをマシン上のすべてのエージェントホストにインストールします(~/.workbuddy-ai/skills、~/.claude/skills、~/.agents/skills、~/.dsh/skills、~/.codex/skills)。インストール後に検証し、空のディレクトリを残さず、個人データをコピーしません。
基本原則:ベースラインなしに測定はない。低下 = フィンガープリントが不変の状態での有意なパス率低下 — 「なんとなく賢くない」ではない。
マルチホストアーキテクチャ(スキル vs プラグイン)
1つのコアエンジン、ホストごとのアダプター。同じフィンガープリント/ベースライン/退行/推奨/ニーズ提案ロジックがどこでも実行されます。アダプターはアセットがどこにあるかとマニフェストの読み方だけを知っています。
| ホスト | 種類 | デフォルトルート | マニフェスト |
|---|---|---|---|
| workbuddy | スキル | このスキルを含むスキルルート | SKILL.md |
| claude-code | スキル | ~/.claude/skills | SKILL.md |
| deepseek | プラグイン | ~/.dsh/profiles/desktop(package.jsonの依存関係を読み取る) | package.json / plugin.json |
| generic | アセット | --root を渡す | plugin.json / manifest.json / SKILL.md / package.json |
- 各ホストは独自のレジストリを保持:
registry.<host>.json— ホスト間の上書きはありません。 - ベースライン結果 + ゴールデンセットは共有され、アセット名でキー付けされます。
--host <name> --root <path>で実行。カスタムホストはhosts.jsonに追加します。console.py hostsはすべてのプロファイル、その解決済みルート、検出されたアセット数を表示します。
つまり、WorkBuddyではスキルを評価し、DeepSeekハーネスではプラグインを評価します — 同じコマンド、異なるアダプター。新しいホストの追加は hosts.json エントリ(種類+ルート+マニフェストファイル名)であり、コード変更は不要です。
使用タイミング
- 新しいスキルやプラグインをデプロイする前(「スキルを作って、評価フローを実行して」)
- モデルバージョンアップ後、既存のスキルが退行していないか確認するため
- スキルが「なんかおかしい」と感じたとき — 雰囲気ではなくデータで確認するため
- スキルを維持/書き換え/廃止するかを判断するとき
- スキルやプラグインをユーザーに推奨するとき(適合性+証拠)
使用すべきでない場合: 再利用可能なスキルがない単発のタスク、純粋なナラティブドキュメント。
中核概念:バージョンフィンガープリント
フィンガープリントは減価マトリクスの行です。
fingerprint = hash(能力面ファイルの内容 + 相対パス) # 口径 v2-ability-surface
能力面としてカウントされるもの(変更が実際に動作に影響するファイル):
- 含む:
SKILL.md、scripts/*、lib/*、dist/*、package.json、plugin.json、cordis.patch.yml、テンプレート - 除外:
README*、CHANGELOG*、LICENSE*、画像/音声/フォント、*.map、ロックファイル、node_modules/、test*/、docs/
除外理由:READMEの編集は能力を変更しませんが、ハッシュ化するとフィンガープリントが移動し、機能的な変更がないのに偽の FINGERPRINT-DRIFT(「アセットが編集されました」)を生成します。プラグインではこれが悪化します — インストールされた1つのプラグインが16MBのバンドル出力と57KBのREADMEを持つことがあります。
ルール:
- フィンガープリント不変 ⇒ 行は存続。パス率低下はモデル退行。
- フィンガープリント変更 ⇒ 変更はスキル自身の責任であり、モデルの責任ではない。 新旧の行が共存するため、スキルの編集がモデルドリフトに誤って帰属されることはありません。
python scripts/console.py scan を実行してフィンガープリントを計算し、レジストリに保存します。fingerprint.py はスタンドアロンのレポートラッパーです。レジストリには触れません。
能力面(プラグインに第二の軸が必要な理由)
フィンガープリントは「ファイルが変更されたか」を示します。「同じものを提供しているか」は示せません。
そのため scan はアセットごとに能力面も記録し、前回のスキャンと差分を取ります。
| アセット種類 | 面が記録するもの |
|---|---|
| プラグイン | patch(dsh.bundle.patch)、main/module、bin、exports、deps、skills、mcp、hooks、insert(cordis行)、scripts |
| スキル | tools(許可されたツール数)、scripts |
変更があった場合、scan は明示的に出力します。
[caps] 1つのアセットの能力面が変更されました(これは「外部に提供するものが変わった」ことであり、合格率とは関係ありません):
plug-a +bin
これがプラグインにとって重要な理由: プラグインは、ツールを登録しない/ルートが404になる/フックが動作しないことによって低下します — 「答えが悪くなる」からではありません。プロンプトのゴールデンセットはプラグインには間違ったものを測定します。面の差分は、「v1.1.0がエントリポイントを削除した」ことをホストを起動せずにキャッチします。
既知の境界(ごまかさないでください): 面は宣言された能力であり、観測された能力ではありません。マニフェストが嘘をついている(ロードに失敗するパッチを宣言している)プラグインの場合、これはキャッチできません。
ランタイム証拠(第三の軸、そしてそれができないこと)
「ランタイムプローブ」と呼ばれる2つの非常に異なるものがあります。混同しないでください。
| 能動的プローブ (active probe) | 受動的証拠 (passive evidence) — 実装済み | |
|---|---|---|
| 動作 | ホストを起動し、「実際に登録したツールはどれか」と尋ねる | ホストが既に書き込んでいるログを読む |
| コスト | DSH desktop プロファイルはElectron限定 — dsh --profile desktop --dump-config は拒否されます;ヘッドレスエントリなし → IPCのリバースエンジニアリングかUIの操作が必要 | 1ファイル読み取り、約10ms |
| キャッチするもの | マニフェストが嘘をついているプラグインを含むすべて | プラグインがログに記録したものすべて |
| ステータス | 未構築 | console.py probe / skill_audit_probe |
probe は ~/.dsh/logs/*.log(ホストごとに hosts.json の "logs" で設定可能)を読み取り、<iso> [level] [source] message を解析し、source がインストール済みアセット名と一致する行を属性付け、障害語彙(fail|error|ENOENT|unavailable|timeout|…)に一致する行をフラグ付けします。
実際のキャッチ例(このマシンで):
@wxg-prc-cpg/browser-skill-dsh-plugin 2つの障害兆候
bsk probe failed (spawn bsk ENOENT); browser tools will report install guidance…
ファイルは存在し、マニフェストは有効、caps=4 — すべての静的チェックを通過します。プラグインはロードされツールは登録されていますが、機能しません。それがシェルアウトする bsk CLIがPATHにありません。ファイルハッシュだけでは決して発見できません。
ブラインドスポット(明示し、隠さないでください): ログをまったく出力しないプラグインは不可視です;ログローテーションは古い障害を消去します;誰も使用したことのないプラグインには証拠がありません;info レベルの障害はキーワードマッチングでキャッチされるため、見逃しも誤検出も可能性があります。証拠がないことは健康の証拠ではない — probe は緑のチェックマークではなく、この文自体を出力します。
実装済み vs 方法論のみ(この線を曖昧にしないでください)
以下の方法論はコードよりも広範です。ユーザーは自分がどちらの半分を手にしているかを知るべきです。
| 領域 | ステータス |
|---|---|
能力面に対するフィンガープリント、scan/status、能力差分 | 実装済み |
| ゴールデンスキャフォールド + ベースライン取り込み(アセットごとにマージ、ドラフトガード) | 実装済み(baseline.py) |
パス率マトリクス、≥20pp閾値 +方向、FINGERPRINT-DRIFT | 実装済み(regress.py) |
モデル変更検出(bump/check)、ホストごとのスタンプ | 実装済み — ただしイベントソースは手動;スケジュールされた check は誰かがbumpするまで緑のまま |
| 推奨/削除パネル、ニーズ提案、履歴マイニングによるドラフト | 実装済み(ヒューリスティック;提案は証拠ではない) |
| ホストログからのランタイム証拠 | 実装済み(受動的;プラグインがログに記録したもののみ) |
| アブレーション、シャドウモード導入率、純価値/トークンテレメトリ | 方法論のみ — コードなし |
| トリガー精度/再現率、環境調整、スタイルベースライン | 方法論のみ — コードなし |
| K≥3再生、LLMジャッジによる相互検証 | 未実装;現在の判定はK=1の自己評価 |
risk 列 | メンテナンス面のプロキシ — 価値ではない |
このファイル内の主張が「実装済み」とマークされた行にたどれない場合、それはツールが実行することではなく、監査を実行する人間へのアドバイスとして扱ってください。
判断1 — 能力低下
4つのステップ:
- 履歴からゴールデンセットを構築する。手作業ではなく。 過去のセッションをマイニング:ユーザーが抵抗なく採用した → ポジティブ再生;ユーザーが抵抗/書き換えを依頼した → ネガティブ。再生こそが退行。ユーザー自身の使用履歴がコーパス — テストセットを考案しない。
- 同じゴールデンセットで両方のモデルを実行する、K≥3(LLMジャッジスコアリングケース:K≥5、ジャッジはノイズが多いため)。(フィンガープリント、モデルバージョン)ごとにパス率を記録。
- 決定ルール: 低下が≥20ppかつ方向的一貫性 → 低下を報告;閾値未満 → 「変動監視」。これにより「この出力は変だ」が再現可能な基準に変わります。
- フラグ付けだけでなく、帰属する。 中間成果物を検査:
- ツール呼び出しエラー/形式変更 → ツール説明を修正。
- 出力構造は正しいが内容が間違っている → 指示を書き換え。
- トリガーすべきだったがしなかった → トリガー説明を修正。
- すべての中間成果物が正しいが最終出力のみ間違い → モデル内部の退行;スキルを「単一モデル依存」とマークし、モデル修正を待つ。
「7つが低下、2つが書き換え推奨」という行は、ステップ4の出力の帰属可能なサブセットです — それがレポートを実用的にします。
判断2 — 新しいスキルは優れているか?
2つの測定可能な軸に分割:有効性(より良い結果)と経済性(低コスト)。
- デプロイ前のアブレーション。 同じタスクバッチ、2群:Aはスキルなし、Bはスキルあり。成功率、人間による修正回数、トークンコストを記録。
純便益 = 成功率向上 × タスク頻度 − 限界コスト成功率を30%向上させるが、年に3回トリガーされ毎回+50kトークンかかるスキルは、負債であり資産ではありません。 - デプロイ後のシャドウモード。 新しいスキルは静かに実行:提案を生成するが自動実行はしない。「何が起こったか」をログに記録。採用率(受け入れられた vs オーバーライドされた)を監視。採用率は「良い」の究極の判断基準であり、オフラインメトリクスよりも正直です。境界:書き込み操作スキル(ファイル削除、メール送信)はシャドウモードではシミュレート/注釈のみ可能で、実際に実行することはできません。
- 純価値カード。 スキルごとに1つのダッシュボード:呼び出し回数、成功率、採用率、平均トークン数、累積純便益。90日間純負の場合は、書き換えまたは廃止を提案。これは減価テーブルの消費者側です。
判断3 — このユーザーに適合するか?
「あなたに合う」 = トリガーが正確 + 前提が成立 + スタイルが一致。すべて自動化可能。
- トリガー精度(最も感触に影響し、最もスキップされがち)。履歴からポジティブ(トリガーすべき)とネガティブ(類似しているがトリガーすべきでない — 「このバグを修正して」vs「バグとは何かを説明して」)をサンプリング。再生 → 精度/再現率。低精度 = 迷惑(過剰トリガー);低再現率 = 設置の無駄。最初に手動で10~20ラベル、その後半自動、LLMコストゼロ。
- 環境調整(インストール済み ≠ 実行可能)。スキルメタデータは依存関係を宣言:どのツール/MCP/権限/パス習慣/言語、さらに暗黙のモデル能力前提(長いコンテキスト、コード実行、マルチモーダル)。ユーザーの実際の環境と調整;欠落 → レッドフラグ。「macOSを前提」、「日本語を出力」、「200kコンテキストが必要」 — 目に見えない前提がスキルが使われない理由の第1位。これは判断1にもフィードバックされます:失敗した能力前提 = 静かな低下。
- スタイルベースライン(最も低い重み)。ユーザーの過去の出力 + USER.mdを参照として使用;LLMジャッジが形式、言語、冗長性を比較。同じスコアのスキル間のタイブレークにのみ使用。
組み込みワークフロー(「新しいスキルを作る」場合)
ユーザーがスキルの作成を依頼した場合、配信前にインラインでプロトコルを実行します。
- 環境調整 — ユーザーの環境はスキルの宣言された依存関係+能力前提を満たしていますか?
- トリガー再生 — サンプリングされた10~20ケースを再生;精度/再現率を報告。
- アブレーション — 小さなタスクバッチで、向上対コストを測定。
- 監視を開始 — 合格時、フィンガープリント+ゴールデンセットを登録;常駐コンソールはモデルバンプのたびに再実行。
ニーズベースの提案(該当するスキルがない場合)
これは「空の棚」の動作です:ユーザー(特にスキル/プラグインがゼロのユーザー)がインストール済みスキルでカバーされないものを要求します。「できません」と言うだけでなく、ギャップを表面化し、埋めることを申し出ます。
- 会話からニーズを検出:タスクの種類 + ドメイン(例:「四半期財務報告」 → 財務/分析;「AIトーンを削除」 → ヒューマナイザー;「ダッシュボードを構築」 → フロントエンド/チャート)。
- まずレジストリをチェック —
python scripts/console.py suggest --need "<need>"。以下を返します。✓ 利用可能なスキル/プラグインがあります:<name>→ それを使用、何もインストールしないでください;または💡 新しい追加を提案:[install:<slug>] <title>→ カバーなし、カテゴリを推奨。
- カバーされていない場合、マーケットプレイスを検索して実際の候補(スキル/プラグイン/エキスパート)を見つけ、証拠付きのカードを提示:何をするか、なぜこのニーズに合うか、ソース。自動インストールはしない — ユーザーが選択します。
- インストール時には ...(原文が途切れているため、これ以上翻訳できません)