0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

AI エージェントに「仕様どおり」を保証させる — SoT Chain という設計

0
Posted at

本記事は Zenn にも同内容を公開している: https://zenn.dev/flip451/articles/sotohe-sot-chain-overview

AI コーディングエージェントはコードを書くのが速い。しかし「書かれたコードが仕様どおりである」ことは、実は誰も保証していない。この問題を解く一つの方法として、仕様や設計を文書のままにせず、機械が強制する制約として扱う機構を提案する。その機構は、設計判断、仕様、型契約、実装を一方向の参照で結ぶチェーンと、各リンクを検証する CI ゲートからなる。

本記事はシリーズ第 1 回。まず問題設定と全体像を示し、個別の仕組みは第 2 回以降で扱う。

「仕様どおり」は誰が保証するのか

Claude Code や Codex のようなエージェントに機能追加を頼むと、数分でコンパイルが通り、テストも green のコードが返ってくる。それ自体はもう驚くことではない。問題はその先にある。

  • 問 1: そのコードは、合意した仕様を実装しているのか。仕様に書いていない振る舞いを勝手に足していないか
  • 問 2: 仕様の側は、設計判断と矛盾していないか
  • 問 3: テストは仕様の約束を検証しているのか、それとも「テストが存在する」だけなのか

人間だけのチームなら、この整合はレビューと記憶で保たれてきた。しかし AI エージェントが実装の主力になると、生産されるコードの量と速度に対して人間のレビューが構造的に追いつかなくなる。そして、レビューが追いついた範囲でも、仕様と実装の一致を機械が検査しているわけではない。人手による確認である以上、結果は担当者やそのときの状況に左右される。

だとすれば、保証は人の注意力の外側に置くしかない。といって、規約やプロンプトに書いて守らせるだけでは足りない。指示は読み飛ばされることがあり、読まれても守られるとは限らない。だからルールは、迂回できない機構(CI ゲート、フック、スキーマ検証)として実装する。筆者が開発している SoTOHE(Source of Truth Oriented Harness Engine)は、この考え方を一貫させたテンプレートである。

SoTOHE とは

SoTOHE は、AI エージェントによる仕様駆動開発(SDD: Spec-Driven Development)を管理する Rust 製 CLI(sotp)+ エージェントハーネスのテンプレートである。Claude Code / Codex CLI を操作面とする。開発の全工程(設計判断の記録、仕様書の作成、型契約の宣言、実装、レビュー、コミット、PR)を、機械可読な成果物と検証ゲートの連なりとして管理する。

SSoT(Single Source of Truth、その情報について信頼できる唯一の源)という語は広く知られている。SoTOHE はこれを一枚のドキュメントに求めるのではなく、階層ごとに置く。中核にあるアイデアはひとつだけだ。

設計から実装までを 4 つの階層に分け、各階層に SSoT を 1 つずつ独立ファイルとして置き、下流が上流を参照する一方向チェーンを機械検証する。

SoT Chain の 4 階層

階層ごとに置かれた SSoT を、下流から上流への参照で一本の鎖につないだもの。それを SoTOHE では SoT Chain と呼んでいる。各階層と、その SSoT となるファイルは次のとおりである。

SSoT ファイル ライフサイクル
ADR knowledge/adr/*.md 開発単位を跨ぐ恒久的な設計判断
仕様書 spec.json 開発単位ごとの要件(目的 / スコープ / 制約 / 受け入れ基準)
型契約 <layer>-types.json 開発単位ごとの型宣言(型レベルのテスト)
実装 libs/* / apps/* のソース 恒久的なコード

最上流の ADR (Architecture Decision Record) は、「なぜこの設計にしたのか」という決定を、理由ごと 1 件ずつ短い文書として残す記録形式である。SoTOHE 固有の発明ではなく、広く使われているこの実践をチェーンの起点に置いている。

この参照には向きがある。下流は必ず上流を参照する1。仕様書の各項目は根拠となる ADR を引用し、型契約の各型宣言は根拠となる仕様項目を引用し、実装は型契約と突合される。参照が切れる(上流に根拠のない記述が下流に現れる)と、CI が止まる。

「ドキュメントとコードを同期させましょう」という掛け声とこの仕組みの違いは、参照が機械可読であることだ。引用は JSON のフィールドとして書かれ、チェーンの評価はコマンド一発で再現できる。実装と型契約の一致も機械的に検証可能だ。

参照を 3 色で評価する信号機

各リンクの評価結果は信号機で表現される2

参照 🔵 Blue 🟡 Yellow 🔴 Red
実装 → 型契約 実装と契約が一致 未実装 契約違反
型契約 → 仕様書 宣言の根拠あり 根拠あるが未文書化 根拠なし
仕様書 → ADR 永続化文書に根拠あり 根拠あるが非永続化 根拠なし

色は検査の結果であって、作業を止める指示ではない。止めるかどうかを決めるのは、色を読む側の「ゲート」である。3 色それぞれの扱いは次のようになる。

  • 🔵 は根拠がつながっている。そのまま進んでよい
  • 🟡 はつながっているが、解消すべき課題が残る。止まるかどうかはゲートの設定次第だが、開発単位の完了までには必ず解消する
  • 🔴 は参照が切れている。どのゲートでも止まり、即修正

なお、この 3 色は CI 自体の green / red とは別レイヤーの語彙である。信号の評価結果が、コミットゲートや CI の pass / fail に翻訳される。🔴 が残っている限り、コミットは物理的にできない。人間の注意力を当てにしない。

構造と意味論の二層検証

ここまでの検証は決定論的な構造検査である。しかし構造検査で分かるのは「参照がある」ことまでで、「参照が意味的に正しい」ことは分からない。ADR を引用した仕様書が、その ADR と矛盾する内容を書くことはいくらでもできる。

そこで SoTOHE は各リンクを二層で守る。

  1. 構造検証(決定論):参照の存在と整合を機械が検査する
  2. 意味論検証(LLM 判定):「この引用は意味的に成立しているか」を LLM が判定する

意味論の判定結果は、信号機の 3 色に混ぜず、別レーンの結果として持つ(そうする理由は第 4 回で述べる)。

「LLM に判定させる」と聞くと不安になるだろう。SoTOHE はこの判定を CI ゲートとして信頼できるものにするため、いくつかの規律を課している。合格判定には根拠箇所の引用が必須である(「LGTM」だけの合格は存在しない)。判定結果は入力の hash に凍結され、上流か下流が 1 文字でも変われば失効する。失効の回復手段は hash の再計算ではなく、再判定の合格のみである。これは「変更を読んで整合を確かめた」ことと「盲目的に再発行した」ことを区別するためだ。詳細は第 4 回で扱う。

さらに、最後のリンク(実装 → 型契約)には、もう一段の意味論検証がある。型宣言からテスト義務を機械導出する。その義務が果たされているかを検証するゲートだ。「書くべきテストが書かれていない」を CI で検出する仕組みで、これは第 5 回の主題である。

作業単位としての track

SoTOHE はすべての作業を track という単位で管理する。1 track は 1 機能追加または 1 バグ修正に相当する。各 track は専用ブランチ上で進む。仕様書、型契約、実装計画、レビュー結果は、track ディレクトリに独立ファイルとして残る。

正規フローは 2 コマンドに集約されている。

/adr:add <slug>      # 設計判断を ADR として記録する(対話ヒアリング)
/track:adr2pr        # その ADR を起点に、仕様 ⇒ 型契約 ⇒ 実装計画 ⇒ 実装
                     # ⇒ レビュー ⇒ コミット ⇒ PR まで自走する

この 1 本のコマンドの内側では、仕様を書くエージェント、型を設計するエージェント、実装するエージェント、レビューするエージェントが役割分担して動く。役割ごとに担当プロバイダ(Claude / Codex / Gemini)を設定ファイルで割り当てられる。たとえばレビューは、実装したエージェントとは別に起動される独立したレビュアーが行い、指摘ゼロになるまでコミットできない。git commit の直接実行はフックでブロックされ、コミットはガード付きの経路しか存在しない。

こうして工程の大半が自動で進むので、人間が判断する地点は二つに絞られる。入口で ADR を書いて確定させることと、出口で PR をマージすることだ。ワークフローの詳細は第 2 回で扱う。

SoTOHE 自身の dogfooding

この仕組みは机上のフレームワークではない。SoTOHE 自身(sotp CLI)が、SoTOHE のワークフローで開発されている。本稿執筆時点で、200 個以上の track がこのパイプラインを通っている。この記事で紹介した信号機も意味論検証も、それ自体が track として仕様化され、型契約を宣言され、レビューゲートを通って実装されたものだ。

自作の仕組みを自分の開発に使うこと(dogfooding)は、品質保証であると同時に、設計への強制力でもある。ゲートを一つ増やすたびに、その煩雑さのコストを最初に払うのは筆者自身である3

正直なコストの話

よいことばかりではない。この仕組みには実費がかかる。

  • 意味論検証の LLM 判定にはトークンコストがかかる(hash 凍結キャッシュにより変更がなければゼロだが、初回と変更時は実費)
  • 実装に着手する前に ADR、仕様書、型契約を書くため、着手までのリードタイムは「いきなり書く」より長い
  • 成果物のスキーマや規約という学習コストがある

それでも筆者は、このコストを開発を人間から AI へ明け渡すための対価としてとらえている。人間がすべての成果物をレビューし続ける限り、明け渡しは起きない。AI が書く量が増えると、人間のレビューで品質を支える路線はいずれ破綻する。だから「仕様どおり」を保証する仕事を、人間の注意力から機構と成果物の側へ移す。実装前に書く ADR、仕様書、型契約も、LLM 判定の実費も、その移転のための支払いである。

このシリーズで書くこと

最後に、シリーズ全体の地図を置いておく。本記事で見た SoT Chain(📍)が中心にあり、続く各回はその周辺を一つずつ掘っていく。

以降の回で、各層を順に扱う。冒頭の問 1 から問 3 に答えるのは、第 3 回から第 5 回である。問 1 は構造の話と振る舞いの話に分かれるので、担当も 2 回にまたがる。

  • 第 2 回: ADR から PR まで自走する track ワークフローとマルチエージェント分業
  • 第 3 回: 型契約書を SSoT にする TDDD(型定義駆動開発)(問 1)
  • 第 4 回: hash 凍結 verdict と引用義務で LLM の判定を CI ゲートにする(問 2)
  • 第 5 回: 「書くべきテストが書かれていない」を検出するテスト義務ゲート(問 1 と問 3)
  • 第 6 回: SoTOHE を使い始めるためのテンプレート export と新規プロジェクト実走記録
  • 第 7 回: SoTOHE を支える設計原則

シリーズ一覧

  1. AI エージェントに「仕様どおり」を保証させる — SoT Chain という設計(本記事)
  2. ADR から PR まで自走する track ワークフローとマルチエージェント分業(公開予定)
  3. 型契約書を SSoT にする — TDDD(公開予定)
  4. LLM の判定を CI ゲートにする — hash 凍結 verdict と引用義務(公開予定)
  5. 「書くべきテストが書かれていない」を検出する — テスト義務ゲート(公開予定)
  6. SoTOHE を使い始める — テンプレート export と新規プロジェクト実走記録(公開予定)
  7. SoTOHE を支える設計原則(公開予定)

リポジトリ: https://github.com/Flip451/SoTOHE-core

  1. 本シリーズでは矢印を書き分ける。→ は参照の向きで、「参照する側 → 参照される側」、つまり下流から上流を指す(実装 → 型契約 など)。← はその逆から書いた表記で、チェーン全体の列挙(ADR ← 仕様書 ← 型契約 ← 実装)に使う。⇒ は工程の順序で、時間の前後を表す(仕様化 ⇒ 実装 ⇒ レビュー など)。

  2. もともとクラスメソッド社の AI 駆動開発フレームワーク Tsumiki に着想を得て作成した機能だったが、気がついたら別物になっていた。

  3. 実際に払った例がある。コードの意味的な重複を LLM で検査するゲートは、かつて全コミットで必須だった。だが自分の開発を計測すると、この検査にまつわる作業が開発時間の約 15% を占めていた。しかも再検査 58 回のうち 84% は指摘ゼロの空振りだった。いまは既定で無効にし、必要なときだけ有効にする位置づけへ下げている。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?