ブログ

    2026.06.17

    エージェントの再現性をどう設計するか ── Fairy Tale が実装する Skill・Residency Check・Feedback Governance

    なぜこの仕組みが必要なのか ── これは「プロンプト設計」ではなく「ソフトウェアガバナンス」の問題だ

    LLMエージェントの改善は、多くの場合「プロンプトに一文を足す」ことで行われます。失敗を見た、だからルールを追加する。一見、合理的です。

    しかし実運用でこれを続けると、次の問題が必ず起きます。

    ・プロンプトが肥大化する ── 足す一方で、誰も消さない
    ・チームごとにコピーが分岐する ── どれが正なのか分からなくなる
    ・成功事例が属人的になる ── 「あの人のプロンプトはなぜか効く」が残る
    ・ベンチマーク最適化が進む ── 特定タスクだけに効くルールが紛れ込む

    結果、エンジニアにとって最悪の状態に陥ります。

    「なぜそのルールが存在するのか」
    「本当に効果があるのか」
    「最新版はどれなのか」

    これらが、誰にも説明できなくなるのです。

    これはプロンプトの巧拙ではなく、変更履歴・根拠・整合性・配布が管理されていないという、れっきとしたソフトウェアガバナンスの問題です。

    この記事で扱う構造を、先に1枚にまとめておきます。

    私たちが OSS として公開している bonginkan/fairy-tale は、この問題をプロンプト芸ではなく運用基盤の設計として解こうとしています。

    新しいモデルでも魔法の呪文でもありません。

    「優れたエージェント仕事の公開された記述を研究し、旋律(melody)と神話(myth)を切り分け、再現可能なパターンを skill・check・adapter として書き下す」研究ワークスペースです。

    以下、中核を支える3つの機構を、実コードに即して「なぜ他のやり方より優れているのか」まで踏み込んで解説します。



    1.skillの仕組み

    skill の実体は1枚の Markdown、SKILL.md です。

    先頭の YAML には name と description だけが置かれ、この description が「いつ起動するか」の判定材料を兼ねます。

    name: fairy-taledescription: Provides Fable/Mythos-informed workflow augmentation forbudgeted, evidence-driven, validation-gated agent execution ...

    重要なのは、エージェントが起動時に全 skill の本文を読まないことです。

    読むのは description のみ。

    タスクの意図に合致した skill だけが本文ごと展開される。

    これが progressive disclosure、つまり段階的開示という設計です。

    「全ルールを常時プロンプトに入れる」素朴な設計と比べると、優位は明白です。

    後者はコンテキストを食い潰し、タスク情報を押し出し、しかも肥大化を止める力学が働きません。

    Fairy Tale は本体に「常に効かせたい骨格」だけを置き、長いチェックリストや出典は references/ に切り出して、Read only when needed とする。

    常駐させる指針と、必要時に引くリファレンスを別の寿命で管理するわけです。

    長いセッションでは初期指示が薄まる問題もあります。

    Fairy Tale は residency check 内の inject_residency() で、セッション開始時に standing instruction を注入します。

    具体的には、予算設定・証拠駆動・完了前の検証・skill 起動といった指針です。

    肝は fail-open で動く点です。

    検証に失敗してもセッションは止めず、最低限の指針だけは流し込む。

    安全側に倒しつつ開発体験を壊さない妥協点です。


    2.residency check

    skill ベース設計には、運用上の弱点もあります。

    同じ skill が複数の場所にコピーされると、更新漏れが起きやすくなります。canonical なソースは更新されているのに、配布用のコピーやローカル環境のコピーは古いまま残る。

    こうした差分は表面化しにくく、気づかないうちにエージェントが古い指針で動き続けてしまいます。

    これは、冒頭で述べた「どれが最新版なのか分からない」問題そのものです。

    Fairy Tale はこれを明確に「ハーネスの故障」と定義し、scripts/fairy_tale_residency_check.py で機械的に検査します。

    以下はすべて実コードからの引用です。


    ①必須マーカーで「中身の同一性」を担保する

    各 skill が満たすべき必須文字列を定義し、存在チェックと同時に内容も検証します。

    SKILL_MARKERS = {
        "fairy-tale": (
            "Residency Guard",
            "Implementation Validation Gate",
            "Benchmark Delta Harness",
            "Latent Structure Harness",
            "fairy-tale-benchmark-feedback",
        ),
        "fairy-tale-benchmark-feedback": (
            "SWE-Bench Pro",
            "HLE-style",
            "ExploitBench",
            "Promotion Rules",
        ),
        "fairy-tale-legal-feedback": (
            "Required Closure Sweep",
            "Fairy Fusion Review",
            "Evaluated Feedback Loop",
        ),
    }

    「ファイルが存在する」だけでなく、中核セクションが含まれているかまで確認することで、空ファイルや切り詰められたコピーを弾けます。


    ②anonical との等値比較でドリフトを検出する

    canonical = ROOT / "skills" / skill / "SKILL.md"
    copy = ROOT / copy_root / skill / "SKILL.md"
    canonical_text = read_text(canonical)
    copy_text = read_text(copy)
    label = f"{copy_root}/{skill} parity"
    if canonical_text is None or copy_text is None:
        add(checks, "FAIL", label, "cannot compare because one copy is missing")
    elif canonical_text == copy_text:
        add(checks, "OK", label, "matches canonical skill")
    else:
        add(checks, "FAIL", label, "drifted from canonical skills source")
    

    設計判断として興味深いのは、意味的な差分ではなく canonical_text == copy_text という素朴な文字列等値で十分とした点です。

    コピーは canonical の完全な複製であるべきです。

    「だいたい同じ」を許せば、そこからドリフトが侵入します。

    許容幅をゼロにすることで判定が一意になり、原因特定も容易になります。


    ③配布マニフェストの整合も検査する

    failures = []
    if data.get("name") != "fairy-tale":
        failures.append("name must be fairy-tale")
    if data.get("skills") != "./skills/":
        failures.append("skills must be ./skills/")
    if not data.get("version"):
        failures.append("version is required")
    

    そして全体は、CI に組み込める素直な終了コードで返ります。

    return 1 if failed else 0

    すべて通れば 0。

    1つでも失敗すれば 1。

    「skill が本当に生きているか」を、祈りではなくパイプラインで落とせるようにしてあります。


    3.feedback governance

    ここが Fairy Tale で最も価値のある部分だと考えています。skill より重要だと言ってもいい。

    ①「改善した」と「改善効果を観測した」は違う

    従来のエージェント改善は、「失敗したからルールを追加する」という職人的な作業になりがちです。

    しかしこの方法には決定的な欠陥があります。

    追加したルールが本当に有効だったのかを、誰も検証していないのです。

    Fairy Tale では、改善案をまず仮説として扱い、次の段階を経て初めて採用候補とします。

    1.記録(preserve)model・effort・prompt・tools・scorer・sample ID・予算・成果物を保存する。これがなければ前後比較すらできません。
    2.分類・台帳化(ledger)失敗と成功実践を scripts/benchmark_feedback_ledger.py(swe-bench-pro / hle / exploitbench)で構造化する。
    3.剪定(prune)scripts/feedback_pruner.py で、矛盾・重複・陳腐化・計測済みリグレッションを検出する。足す前に、まず削るパスを必ず通します。
    4.再試行(held-out retry)保留したスライスを同じ scorer で再実行し、前後の pass rate・信頼区間・コスト・リグレッションを計測する。

    つまり Fairy Tale が作るのは「プロンプトを改善した」という主観ではなく、「改善効果を観測した」という再現可能な状態です。

    プロンプトエンジニアリングを経験則から実験科学へ移す、と言い換えてもいい。


    ②「もっともらしい」だけのルールは採用しない

    統制の肝は promotion rule、つまり昇格条件です。

    候補ルールは、次をすべて満たすまでデフォルト挙動に入りません。

    ・計測された証拠がある
    ・held-out retry の結果がある
    ・task-ID やサンプル固有の文言を含まない
    ・既存の採用済みルールと矛盾しない
    ・他のタスクファミリーで実質的なリグレッションを起こさない

    未証明の候補は keep、つまり採用ではなく、review、つまり要検証に留め置き、「それっぽいから入れる」を構造的に禁止しています。

    これが、冒頭の「なぜそのルールが存在するのか分からない」問題への直接の回答です。

    Fairy Tale のルールには、必ず「どの計測を根拠に・どの再試行で効果が確認されて」採用されたかが付随します。


    4.Fairy Fusion

    同じ失敗が繰り返される、差分が出ない、検証台帳が欠落しています。

    そうした停滞条件が揃ったとき、scripts/fairy_fusion_review.py 相当の Fairy Fusion を起動します。

    独立したレビュアーを隔離されたサイドチェーンとして走らせ、合議では少数派のリスクを多数決で潰しません。

    fan-out には上限を課し、再帰は原則1段。

    レビュアーの全出力は append-only の成果物として残し、メインには圧縮された closure hint だけを返す。

    「証拠を残す」「境界を引く」という原則が、レビュー機構そのものにも貫かれています。


    5.まとめ

    3つの機構を貫く思想は、ひとつに収束します。

    再現性をエンジニアリングの対象として扱う、ということです。

    ・skillは、知識をコンテキストを食わずに必要時だけ展開し、再現性の土台
     を作る。
    ・residency checkは、その skill が分散
    ・ドリフトせず生きているかを CI で機械的に保証する。
    ・feedback governanceは、改善を「計測 → 剪定 → 再試行 → 昇格条件」を
     通った 再利用可能なルールとして蓄積する。

    強調したいのは、Fairy Tale が管理しているのはモデルそのものではないということです。

    管理しているのは、どの知識を使うか、どのタイミングで使うか、どう検証するか、どう改善を採用するか、という運用プロセスです。

    LLM の出力が確率的である以上、挙動を100%固定はできません。

    しかし「どの指針が・どこに・どんな状態で常駐しているか」「何を根拠に改善を採用したか」は、設計とコードで決定論的に統制できます。

    確率的なモデルの上に、決定論的なハーネスを敷く。

    それが、エージェントを実運用に耐えるものへ変える現実的な解法です。

    性能競争は今後もモデルの進化によって続くでしょう。

    しかし実運用では、性能だけでは説明できない問題が増えています。

    なぜそのルールが存在するのか。
    なぜその改善を採用したのか。
    どの指針が現在有効なのか。

    これらに答えられなければ、エージェントは組織の資産になりません。

    Fairy Tale は、エージェントを賢くするためのプロジェクトではなく、エージェント運用を説明可能にするためのプロジェクトです。


    試してみる(github)

    GitHub:
    https://github.com/bonginkan/fairy_tale

    Plugin:
    /plugin marketplace add bonginkan/fairy_tale

    まずはここから:
    scripts/fairy_tale_residency_check.py を自分の環境で走らせ、「自分の skill 群が本当に生きているか」を確かめるところから始めてみてください。

    コードは Apache-2.0 で公開しています。ブランド資産の商標は留保しています。

    ホーム

    ・

    実績紹介

    ・

    エージェントの再現性をどう設計するか ── Fairy Tale が実装する Skill・Residency Check・Feedback Governance

    お問い合わせ

    サービスに関するご質問や、取材・パートナーシップのご相談などはこちらからお気軽にご連絡ください。

    お問い合わせはこちら