「決定性のないソフトウェア」をどう設計し評価するか — t_wada 氏の視点と skill-creator が実装した答え

和田卓人(@t_wada)氏が X で言及した、skill-creator の設計に関するコメントが注目を集めています。

skill-creator いい感じで動作すると思っていたら中身がこのようになっていたのか。決定性のないソフトウェアをどう実践的に設計して評価するかといった観点でも参考になるエントリ。

t_wada 氏は、テスト駆動開発(TDD)の日本における第一人者であり、Kent Beck 著『テスト駆動開発』の翻訳者、power-assert-js の作者として知られるプログラマです。その t_wada 氏が「決定性のないソフトウェアの設計と評価」という観点で skill-creator を評価しています。

元記事は逆瀬川ちゃん氏のブログ「skill-creator から学ぶ Skill 設計と、Orchestration Skill の作り方」です。本記事では、t_wada 氏の指摘する「決定性のないソフトウェア」の設計問題に焦点を当て、skill-creator がどのような解を実装しているかを解説します。

「決定性のないソフトウェア」とは何か

従来のソフトウェアとの違い

決定的ソフトウェア(従来):
  入力 A → 常に出力 X
  入力 B → 常に出力 Y
  → 「2 + 2 = 4」を assert できる

非決定的ソフトウェア(LLM ベース):
  入力 A → 出力 X1, X2, X3...(毎回異なる)
  入力 B → 出力 Y1, Y2, Y3...(毎回異なる)
  → 「正解」が一意に定まらない

LLM の出力は確率的です。同じプロンプトを送っても、temperature やサンプリングの影響で異なる結果が返ります。従来の assertEqual(expected, actual) というテスト手法が通用しない世界です。

なぜこれが「設計」の問題なのか

t_wada 氏の指摘の核心は、これはテストの問題ではなく設計の問題だという点です。非決定的な出力を持つシステムを、どう構造化すれば品質を保証できるか。これはアーキテクチャの問題です。

テストの問題として捉えると:
  「LLM の出力をどうテストするか?」
  → テスト手法の工夫に終始する

設計の問題として捉えると:
  「非決定的な部分と決定的な部分をどう分離するか?」
  → アーキテクチャレベルの判断が求められる

skill-creator が実装した 3 つの設計原則

原則 1: 決定的処理と非決定的処理の分離

skill-creator の最も重要な設計判断は、LLM に任せる部分とスクリプトに任せる部分の明確な分離です。

skill-creator のフォルダ構成:

  SKILL.md(480 行)
    → フロー制御(非決定的 LLM が判断)

  agents/
    ├── grader.md(224 行)  → 評価(非決定的)
    ├── comparator.md(203 行) → 比較(非決定的)
    └── analyzer.md(275 行)  → 分析(非決定的)

  scripts/(8 個の Python/Bash)
    → ループ、並列処理、集計(決定的)

  references/schemas.md
    → JSON スキーマ定義(決定的な契約)

分離の基準は明確です。

処理担当理由
判断・分析・文章生成LLM(非決定的)創造性・推論が必要
ループ・並列処理スクリプト(決定的)LLM はループが苦手
数値集計スクリプト(決定的)計算の正確性が必要
ファイル操作スクリプト(決定的)再現性が必要
API 呼び出しスクリプト(決定的)自身の API 呼び出しが必要

この設計は、t_wada 氏が提唱する**「テスト容易性の設計」**と同じ原理です。テストしやすいコードを書くには、副作用のある処理と純粋な処理を分離する。LLM ベースのシステムでは、非決定的な処理と決定的な処理を分離することで、同じ効果が得られます。

原則 2: スキーマ契約による接続点の厳密化

skill-creator は references/schemas.md7 種の JSON スキーマを定義しています。これは LLM の非決定的出力と、スクリプトの決定的処理の接続点を厳密化する契約です。

スキーマ契約のフロー:

  SKILL.md → 「schemas.md に従え」と指示
    ↓
  LLM → スキーマ準拠の JSON を出力(非決定的だが形式は決定的)
    ↓
  スクリプト → スキーマを前提にパース(決定的)
    ↓
  UI → スキーマ準拠で描画(決定的)

これは従来のソフトウェア工学で言う**インターフェース契約(Design by Contract)**そのものです。Bertrand Meyer の DbC がクラス間の契約を定義するように、skill-creator は LLM とスクリプト間の契約を定義しています。

Design by Contract との対比:

  DbC(従来):
    事前条件: メソッド呼び出し前の状態
    事後条件: メソッド呼び出し後の状態
    不変条件: 常に成り立つ条件

  スキーマ契約(skill-creator):
    事前条件: LLM への入力プロンプト
    事後条件: JSON スキーマに準拠した出力
    不変条件: フィールド名・型・構造の一貫性

元記事では「フィールド名を config と誤ると"ビューアが空値表示"」という具体例が挙げられています。非決定的な LLM 出力でも、構造レベルの決定性はスキーマで保証できるということです。

原則 3: 統計的評価による品質保証

従来のテストは「1 回実行して合否を判定」しますが、skill-creator は複数回実行の統計的評価で品質を保証します。

skill-creator の評価プロセス:

  description の最適化:
    1. 20 個のテストクエリを用意
       ├── should_trigger(発火すべき)
       └── should_not_trigger(発火すべきでない)
    2. 60/40 で train/test 分割
    3. 各クエリを 3 回実行(統計信頼性)
    4. Extended Thinking で description を改善
    5. 最大 5 反復、test スコアでベスト選択
       → 過学習防止のために test セットで検証

  スキル品質の評価:
    1. with_skill 版と baseline 版を並列実行
    2. grader エージェントがアサーション評価
    3. comparator エージェントが A/B 比較
    4. aggregate_benchmark.py が 3 段階集計
       per-run → per-eval → per-config

これは t_wada 氏が指摘する「決定性のないソフトウェアの評価」への実践的な回答です。

TDD と評価駆動開発(EDD)の接点

TDD の Red-Green-Refactor と EDD

t_wada 氏が翻訳した Kent Beck の TDD サイクル(Red → Green → Refactor)と、LLM ベースの評価駆動開発(EDD)のサイクルは構造的に対応します。

TDD サイクル:
  Red:     失敗するテストを書く
  Green:   テストを通す最小のコードを書く
  Refactor: コードを整理する

EDD サイクル:
  Red:     失敗する評価基準を定義する
  Green:   基準を満たすようプロンプト/設計を改善する
  Refactor: プロンプト・アーキテクチャを最適化する

共通する原理は**「先に定義する」**ことです。TDD は「テストを先に書く」ことで使う側の期待を明確にし、EDD は「評価基準を先に定義する」ことで成功の定義を明確にします。

skill-creator における TDD 的要素

skill-creator は EDD を実装していますが、その中に TDD 的な要素が組み込まれています。

TDD の概念skill-creator での実装
テストファーストdescription 最適化で「テストクエリを先に定義」
アサーションgrader エージェントが「アサーション評価」
テストスイート20 個のテストクエリセット
リグレッションテストbaseline 比較で「既存品質を壊さないか」検証
テストカバレッジshould_trigger / should_not_trigger の網羅性
過学習防止train/test 分割(機械学習の手法を借用)

t_wada 氏の「ガードレール」としての TDD

t_wada 氏は別のインタビューで、AI エージェント時代における TDD の役割を**「ガードレール」**と表現しています。

TDD as ガードレール:

  AI エージェントの問題:
    「試行錯誤の過程でコードを壊す傾向がある」

  TDD の解:
    「これまで動いていたコードは変わらず動き、
     かつ、新しいコードも動いている状態を目指すよう、
     AI にはっきり伝える必要がある」

  具体的な手段:
    自動テストが「壊れていないか」の判定に最適

skill-creator の baseline 比較は、まさにこのガードレールの実装です。「スキルを改善したが、既存の性能が劣化していないか」を自動的に検証します。

非決定的ソフトウェアの設計パターン

skill-creator の設計から、非決定的ソフトウェアの一般的な設計パターンを抽出できます。

パターン 1: 層分離(Deterministic Sandwich)

決定的処理で非決定的処理を挟む:

  [決定的] 入力の前処理・バリデーション
      ↓
  [非決定的] LLM による判断・生成
      ↓
  [決定的] 出力のスキーマ検証・後処理

skill-creator では、スクリプトが入力を準備し、LLM が判断・生成し、スクリプトが出力を集計・検証します。

パターン 2: 統計的信頼性(Multiple Runs)

1 回の実行で判定しない:

  実行 1 → 結果 A
  実行 2 → 結果 B
  実行 3 → 結果 C
      ↓
  集計 → 平均スコアで判定

skill-creator は各テストクエリを 3 回実行し、統計的な信頼性を確保しています。

パターン 3: 比較評価(A/B Testing)

絶対評価ではなく相対評価:

  × 「この出力は 80 点か?」(絶対評価は困難)
  ○ 「スキルありの出力はなしより良いか?」(相対評価は可能)

skill-creator の comparator エージェントは、with_skill 版と baseline 版の A/B 比較で品質を判定します。

パターン 4: 契約ベースの接続(Schema Contract)

非決定的な「内容」と決定的な「形式」を分離:

  内容: LLM が自由に生成(非決定的)
  形式: JSON スキーマに従う(決定的)
  → 形式の決定性で、後続処理の安定性を保証

パターン 5: 段階的開示(Progressive Disclosure)

情報量を制御してノイズを減らす:

  Level 1: name + description(〜100 トークン)
  Level 2: SKILL.md 本文(<5,000 トークン推奨)
  Level 3: scripts/ + references/(参照時のみ)

  → コンテキストウィンドウの汚染を防ぎ、
     LLM の判断精度を維持

開発者への実践指針

非決定的ソフトウェアを設計するときに

設計チェックリスト:

  □ 決定的処理と非決定的処理を分離したか
  □ 接続点に契約(スキーマ)を定義したか
  □ 評価基準を「先に」定義したか
  □ 複数回実行の統計的評価を設計したか
  □ baseline との比較評価を組み込んだか
  □ 人間のフィードバックポイントを設計したか
  □ 環境依存しないコアワークフローを定義したか

TDD 実践者が LLM ベースシステムに移行するとき

TDD から EDD への移行:

  変わること:
    assertEqual → 統計的スコア判定
    1 回の実行 → 複数回実行の平均
    正解/不正解 → スコアの閾値
    単体テスト → A/B 比較評価

  変わらないこと:
    「先に定義する」原則
    Red-Green-Refactor のサイクル
    リグレッション防止の思想
    テスト容易性のための設計

まとめ

  • t_wada 氏の視点: TDD の第一人者が skill-creator を「決定性のないソフトウェアの設計と評価」の参考例として評価。テストの問題ではなくアーキテクチャの問題として捉えている
  • 決定的 / 非決定的の分離が核: skill-creator は LLM(判断・生成)とスクリプト(ループ・集計・ファイル操作)を明確に分離。非決定的な処理を決定的な処理でサンドイッチする設計
  • スキーマ契約で接続点を厳密化: references/schemas.md の 7 種の JSON スキーマが LLM とスクリプトの契約として機能。Design by Contract の LLM 時代版
  • 統計的評価で品質を保証: 各テストクエリを 3 回実行、train/test 分割、baseline 比較。1 回の実行での合否判定ではなく、分布として品質を評価
  • TDD と EDD は構造的に対応: Red-Green-Refactor のサイクル、「先に定義する」原則、リグレッション防止の思想は共通。assertEqual が統計的スコア判定に変わる
  • TDD は AI 時代の「ガードレール」: t_wada 氏の主張通り、自動テストが AI エージェントの暴走を防ぐ仕組みとして機能。skill-creator の baseline 比較がその実装例
  • 5 つの設計パターンを抽出: 層分離、統計的信頼性、比較評価、契約ベース接続、段階的開示。非決定的ソフトウェアの設計に汎用的に適用可能

参考