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はずれる ── 要件から逸れない自律開発ループの設計

Claude Code で動く自律開発ループを2つ比べ、そこから設計し直しました。結論はひとつです。

ずれは、最後のレビューではなく「要件 → テスト」の段で止める。判定は機械に寄せる。

この結論を、6つの原則に分けました。

  • 原則① テスト駆動だけでは要件からずれる。テスト駆動が保証するのは「実装がテストに合っている」ことまで。要件をID付きで分解し、要件とテストの対応を実装の前に検査する。正本(要件の拠り所になる文書)はループに書き換えさせない
  • 原則② 品質はレビューではなくコードに書く。AI の品質レビューをやめ、lint・依存ルール・層別の CI に置き換える。層を分けると、落ちた層がそのまま問題の場所になる
  • 原則③ 答えが一意なものは機械に任せ、合わない分だけ AI に1回推論させる。結果を対応表に書き戻すので、運用するほど AI の出番が減る(狙い)
  • 原則④ 判定は判定専用のモデルに任せ、LLM は生成と推論に使う。確信度が低ければ慎重な側に倒す。重い画像判定は通常のループから外す
  • 原則⑤ 読むのは並列、書くのは直列。並列化は1件の中ではなく、件と件の間で効かせる
  • 原則⑥ 1件が止まってもループは止めない。停止理由を分類し、仕様の問題なら次のタスクへ、基盤の問題なら全体を冷却する

本記事は、これから入れる設計の最終形です。まだ全部は運用していません。効果は「狙い」として書いています。
想定読者は、Claude Code などで自律開発ループを作っている人、これから作る人です。


1. 2つのループを作って比べた

2つのプロジェクトで、性格の違う自律開発ループを動かしています。どちらも Claude Code のエージェントが、Issue を起点にテスト・実装・検証・マージまで進めます。

本記事では、計画とレビューを厚くした方を「重厚型ループ(プロジェクトA)」、1本道のスクリプトで回す方を「軽量型ループ(プロジェクトB)」と呼びます。どちらのループも、要件の拠り所になる文書を持っています。要件定義書・WBS・バックログなどです。以下、これを「正本」と呼びます。

1.1 動かし方の違い

観点 重厚型(A) 軽量型(B)
起動 Issue にラベルを付けると、ラベルの変化で次の段のワークフローが順に起動する。30分ごとの定時スイーパーが、止まった Issue を拾い、次のタスクも払い出す 人が手動で起動する(マイルストーンか Issue を指定)。定時起動もイベント起動もない
タスクの出どころ WBS の作業パッケージから Issue を自動で起票し、依存順に払い出す 特定ラベルの Issue を、マイルストーンの中で番号順に処理する。正本は客先の Excel バックログ
並び方 Issue ごとに並列(同時に最大3件) 1件ずつ直列。前の件をマージした後の main から、次の件を始める
段の進め方 状態をラベルで持ち、別々のワークフローが引き継ぐ 1本のシェルスクリプトが、1件の全段を上から順に実行する
人のゲート リスクが high・個人情報の疑い・要レビューの件は、マージ前に人が承認する。それ以外は自動でマージする なし。CI が緑なら自動で squash マージする
止まった後 停止を3種類のラベル(人の判断待ち・再試行・依存待ち)に分ける。再試行は60分冷ましてから、スイーパーが自動で再開する 停止のラベルを付けて止める。人がラベルを外すと、次の起動で対象に戻る

1.2 エージェントとワークフローの違い

観点 重厚型(A) 軽量型(B)
エージェント 1件を流すのに11体。計画4体(要件定義・リスク判定・調査・計画)、実装2体(テスト設計・実装)、並列のレビュー3体(品質・仕様・個人情報)、修正、報告 8段の1本道。トリアージ → テスト設計 → 実装 → 修正(最大3回)→ UI レビュー → リファクタ → lint・ビルド → マージ
呼び出し方 Claude Agent SDK。段の間の受け渡しは、JSON Schema の構造化出力 claude -p(CLI)。段ごとに、許可するツール・ターン上限80・予算上限10 USD を付ける
守りの効かせ方 エージェントの権限で絞る(ツールの制限・パスの規則・フック)。テストはハッシュで照合する 差分で絞る。許可したパス以外の変更は元に戻す。テストは sha256 で照合する
ワークフロー 8本(計画・実装・レビューとマージ・次タスクへの送り・スイーパー・CI など)。GITHUB_TOKEN で付けたラベルでは後続のワークフローが起動しないため、PAT が必須 4本(ループ本体・マージ後の処理・CI・dev 環境へのデプロイ)。GITHUB_TOKEN だけで動かし、CI は明示的に起動する

重厚型は、イベント駆動で並列に動きます。計画とリスク判定に厚い構成です。軽量型は、手動で起動する直列のスクリプトです。差分ガードと CI の緑を条件に、自動でマージします。

1.3 6つの観点で評価した

◎ 優位 / ○ 普通 / △ 弱い、の3段階で評価しました。

観点 重厚型 軽量型 理由
トークン効率 △ ◎ 重厚型は、1件あたりのエージェント呼び出しが多い。軽量型は1本道で、ターンと予算の上限もある
要件の正本から逸れない ◎ △ 重厚型は、仕様の節番号から本文とハッシュを引いて固定し、レビューの前にも照合し直す。仕様レビューは、差分を読む前に仕様から要件を列挙する。仕様は書き込み禁止。軽量型は、Issue 本文と親のバックログ項目を渡すだけ。要件と照合する専用のレビューがない
速さ ○ ○ 重厚型は件ごとに並列だが、段の引き継ぎでラベルとイベントを待ち、人のゲートでも待つ。軽量型は1件の中に待ちがないが、件同士は直列で、起動も手動
トレーサビリティ ◎ ○ 重厚型は、WBS ID → Issue → リスクとレビューのマーカー → 状態ファイル(試行の分類とエラー指紋)→ ループのログ → 仮決定の記録、と鎖がつながる。軽量型は、Issue コメント・PR 本文・Artifacts で追う。Artifacts は14日で消える
拡張性 ○ ◎ 重厚型は部品が分かれているが、8本のワークフローの連携が複雑。concurrency の不具合を何度も起こした。軽量型は、段を1行で足せる
セキュリティ・品質 ◎ ○ 重厚型は、リスク判定を独立させ、個人情報専用のレビューと人のゲートを持つ。軽量型は、パスの差分ガードと CI 必須はしっかりしている。ただし個人情報と認可を見るレビューがなく、人の承認なしでマージする

正確さと統制は重厚型、コストと単純さは軽量型が上でした。一言でまとめると、重厚型は正確だが重く、軽量型は軽いが要件からずれます。

1.4 それぞれの弱点

重厚型の弱点は、次の4つです。

  • 重い:1件あたりのエージェント呼び出しが多く、トークンと時間がかかる
  • 複雑:8本のワークフローがラベルで連鎖している。concurrency による run の追い出しや自己ロックで、何度も壊れた。13日間放置された Issue もある
  • 二重管理:GitHub 上で動く版と手元で動く版に、同じ判定ロジックが2つある
  • 止まりやすい:マーカーを読めないと安全側(高リスク・指摘あり)に倒すので、空振りの停止が起きやすい

軽量型の弱点は、次の5つです。

  • 要件からのずれを検出する仕組みが弱い
  • 人の承認なしでマージし、そのまま客先も見る dev 環境に出る
  • 個人情報・認可・DB の変更を特別扱いしない
  • 手動起動で直列なので、件数が増えると回らない
  • 記録が Artifacts にしか残らず、14日で消える

1.5 重厚型のレビューは組みすぎだった

重厚型のレビューは、毎回すべてを回すと過剰でした。層ごとに見ると、次のとおりです。

層 中身 評価
機械チェック CI・テストのハッシュ照合・仕様のハッシュ照合・パスガード 安く確実なので残す
AI レビュー(3並列) 品質・仕様・個人情報 毎回3体は重い
修正ループ 最大4ラウンド 指摘のたびに3体が再レビューするので、コストが膨らむ
人のゲート 人の承認 high リスクと個人情報のときだけなので妥当

品質レビューは、CI(lint・型・テスト)と役割が重なりやすいです。個人情報レビューは、個人情報に触れない差分では空振りします。そこで、種類を減らすより、差分に応じて出し分けることにしました。

  • 仕様レビュー(以下「要件適合レビュー」)は常に回す。重厚型の強みの中核だから
  • 個人情報レビュー(以下「privacy レビュー」)は、個人情報・認証・RLS・migration に触れる差分のときだけ回す
  • 修正後の再レビューは、指摘を出した種類だけにする
  • 修正のラウンドは4回から2回に減らし、超えたら止める
  • 品質レビューは、最初は条件付きで回す案だった。最終的には廃止した(原則②)

ここから先は、両方の長所を取り込む形で設計し直した内容です。重厚型からは、要件の固定・仕様レビュー・リスクに連動したゲートを取り入れます。軽量型からは、単純さ・コストの上限・パスガードを取り入れます。


2. 原則① テスト駆動だけでは、要件からずれる

レビューを減らす話の途中で、こう考えました。「テスト駆動で進めれば、要件からずれることはないのでは?」

答えは「絶対とは言えない」です。テスト駆動が保証するのは「実装がテストに合っている」ことだけです。「テストが要件に合っている」ことまでは保証しません。

2.1 ずれの入口は5つある

ずれの入口 例 テスト駆動で防げるか
(1) 要件の読み違い 正本の曖昧な箇所を、エージェントが都合よく解釈する ✕ 読み違えたまま、テストも実装も「正しく」通る
(2) テストの抜け 要件10個のうち、8個しかテストしていない ✕ 通っても、残り2個は未検証のまま
(3) テストの弱さ 「エラーが出ないこと」だけを確認し、中身を見ていない ✕ 実装が手抜きでも通る
(4) テストにしにくい要件 「分かりやすい表示」「運用上こう使う」 ✕ 自動テストに落ちない
(5) テストの改変 実装側がテストを書き換えて通す ○ テストを固定してハッシュで照合すれば防げる(両ループとも実装済み)

テスト駆動が効くのは、(5)と「実装の取りこぼし」までです。(1)〜(4)は、テストより手前の段で防ぐしかありません。

2.2 要件をID化し、テストとの対応を実装の前に検査する

テストより手前に、次の段を置きました。丸数字は、§8 のフローの段の番号です。

  • ① 要件読み込み(1体):正本の該当する節を取り、内容をハッシュで固定する。そのうえで、要件ID付きのリストに分解する。曖昧な箇所があれば、質問を残して止まる
  • ② テスト設計(層ごとに並列):要件IDごとにテストを書く。書けるのはテストだけ
  • ③ 対応検査:要件IDとテストを突き合わせる。抜けがあれば、抜けの一覧を渡してテスト設計へ戻す
  • ④ 実装(1体):テストと正本は書けない

(1)への対策は、①の「曖昧なら止まる」です。要件読み込みの解釈が間違っていると、後ろの全段がその間違いに沿って一貫してしまいます。だから、解釈が割れそうな箇所は先に人に聞きます。質問には、選択肢と推奨を添えます。

(2)への対策は、③の対応検査です。テスト名や注釈に要件IDを入れる規約にしておくと、突き合わせは機械でできます(原則③)。対応表は「要件ID ↔ テスト名」の機械が読める形で残します。これがそのままトレーサビリティにもなります。

(3)のテストの弱さには、専用の検査を入れていません。「その要件をわざと外した実装でも、テストは落ちるか」を試す案もありました。しかし今のループはうまく回っています。トークンに見合わないと判断しました(§9)。

(4)のようにテストに落ちない要件は、実装の後の要件適合レビューで正本と照合します。

実装の後でテストが疑わしくなったときは、ループは自分で直さずに止まります。このような状況では、要件の解釈がずれている可能性が高いからです。自動で直すより、人に確認する方を選びました。

2.3 正本はループに書き換えさせない

最初の案では、フローの最後に「Issue や正本を修正する」段を置いていました。これは危険です。ループが正本を書き換えると、要件の側が実装に合わせて動き、ずれを検出できなくなります。

そこで、正本は書き換えず、修正の提案だけを起票します。置き場所は、確認事項の一覧か Issue のコメントです。採否は人が決めます。

これで、ずれのチェックを最後のレビューから最初の「要件 → テスト」へ前倒ししました。レビューを減らしても品質を落とさない、という狙いです。


3. 原則② 品質はレビューではなく、コードに書く

品質レビューを外したら、コードの質はどう守るのか。気にしていたのは、次のような点です。

  • カプセル化されていて、単純なコードになっているか
  • マジックナンバーを使っていないか
  • クリーンアーキテクチャのように層を分け、どこでうまくいかなかったかを検出できるか

3.1 ほとんどは静的チェックで判定できる

これらの多くは、AI のレビューではなく静的チェックで判定できます。機械で判定すれば、毎回同じ基準で、トークンもかかりません。CI に入れれば、検証の段の CI がそのまま品質レビューの代わりになります。

観点 機械での判定方法 機械で拾えないもの
マジックナンバー ESLint の no-magic-numbers(0・1・-1 などは除外) 文字列の直書き(ステータス名など)。定数か union 型を使う規約で補う
単純さ complexity(循環的複雑度)、max-lines-per-function、max-depth、max-params、sonarjs/cognitive-complexity 名前の分かりやすさ
カプセル化 knip で不要な export を検出する。モジュールの入口を index.ts に限り、内部ファイルの直接 import を禁止する 責務の切り方そのもの
依存の向き dependency-cruiser か eslint-plugin-boundaries で、層の間の import の向きを強制する 層の分け方そのものの妥当性
型の甘さ TypeScript の strict、typescript-eslint の no-explicit-any ―

依存の向きは、例えば次のように決めます。内側から外側への import は禁止です。

domain  … 何も import しない(業務ルール)
usecase … domain だけを import する(手順の組み立て)
infra   … 内側に依存する(DB・権限。例: Supabase)
app     … 内側に依存する(画面。例: Next.js)

AI が担うのは、表の右の列(名前・責務の切り方)だけです。これは、仕上げの段のリファクタ担当に任せます。リファクタ担当には lint の警告一覧を渡し、「警告ゼロ+命名の改善」を目標にさせます。

品質の基準はコード(lint・依存ルール)として書き、AI はそれを満たすように書く側に回します。 トークンを減らしつつ、判定のぶれもなくす狙いです。

3.2 層を分けると、どこで失敗したかが分かる

層を分けておくと、落ちた層がそのまま問題の場所になります。CI のステップを「構造 / domain / usecase / infra / e2e」に分け、それぞれに名前を付けます。

落ちたステップ 意味 次の動き
構造(依存の向き・複雑度) 設計の崩れ 修正へ。どのファイルのどの依存かまで出るので、直す範囲が狭くて済む
domain 業務ルールの誤り。要件の読み違いの可能性が高い 実装より先に、要件の解釈を疑う。要件IDも一緒に出る
usecase 手順・組み立ての誤り 修正へ
infra(DB・RLS) クエリ・権限の誤り 修正へ。privacy レビューの対象にもする
e2e だけ 画面と配線の誤り 修正へ

こうすると、止まった理由が「どの層の、どの要件ID」という単位で Issue に残ります。後から追うときの手がかりにもなります。テスト設計を層ごとに分けること(原則⑤)とも噛み合います。


4. 原則③ 答えが一意なものは機械に。合わない分だけ AI に1回

エージェントにするか、ワークフロー(スクリプト)にするか。判断の基準は、ひとつにしました。答えが一意に決まる処理は機械に任せ、解釈が要る処理だけをエージェントにします。

4.1 ワークフローにした処理

処理 担当 中身
タスク選び 機械 WBS の依存順で、着手できる(ready な)タスクを選ぶ。停止した後の次の候補も同じ
正本の固定 機械 正本の節を取り、ハッシュで固定する。ハッシュが前回と同じなら、要件IDの一覧をキャッシュから再利用する
層の振り分け(要件ID → 層) 機械 → 合わない分だけ AI 対応表で決まるものは機械で振り分ける。表に無い要件IDや、複数の層にまたがる要件IDだけ、エージェントが1回推論して層を決める。結果は対応表に追記する
対応検査(要件ID ↔ テスト) 機械 → 合わない分だけ AI 突き合わせは機械で行う。合わない項目だけ、エージェントが1回推論する(本当の抜けか、命名のずれで実は対応しているか)。本当の抜けなら、一覧を付けてテスト設計へ戻す。推論しても判断がつかなければ止まる
テストの固定と照合 機械 ハッシュで照合する
リスク判定 機械 判定モデルの結果と、差分のパス・行数のルールで決める(原則④)
privacy レビューを回すか 機械 判定モデルの結果と、差分のパス(migration・認証・RLS など)で決める(原則④)
回数の上限・停止の閾値 機械 修正は2回まで。3件続けて止まったら全体を冷却。判定モデルの確率の閾値も。値は設定ファイルに置く
報告 機械 状態の JSON から、テンプレートで作る。正本との食い違いが記録されたときだけ、LLM が修正提案を書く
PR 作成・CI 待ち・マージ・ラベル・ロック 機械 すべて機械

エージェントが動くのは、次の箇所だけです。

  • 要件の分解(正本が変わった節だけ)
  • 層の振り分けの補完(1回)
  • テスト設計(層ごと)
  • 対応検査の補完(1回)
  • 実装
  • 要件適合レビュー
  • privacy レビュー(該当する差分のときだけ)
  • 修正
  • UI/UX チェック
  • リファクタ
  • 正本への修正提案(食い違いがあるときだけ)

4.2 機械で判定し、外れた分だけ AI に推論させる

層の振り分けと対応検査は、同じ形にしました。

機械で判定する
  └ 合わない分だけ、エージェントが1回推論する
      ├ 結果を対応表に書き戻す(次からは機械で判定できる)
      └ それでも判断がつかなければ止まる

この形にすると、運用を重ねるほどエージェントの出番が減っていきます。 対応表に書き戻した分だけ、次からは機械で決まるからです。

推論を1回に限るのは、1回で決まらないなら要件の側が曖昧だと見るからです。その場合は、ループで粘らずに止めて人に聞きます。

リスク判定・回数の上限・閾値も、ワークフローに持たせました。重厚型では、リスク判定を LLM のエージェントが担っていました。これを、判定モデルとルールで決める処理に置き換えます。値は設定ファイルに置き、実績を見て調整します。


5. 原則④ 判定は判定モデルに。LLM は生成と推論に

原則③のルールだけでは、決めきれない判断が残ります。「この差分は個人情報を扱うか」「この失敗はバグか、基盤のエラーか」といった判断です。答えの形は決まっていますが、パスや行数のルールだけでは決まりません。

ここに、判定専用のモデル(例: Jev。画像も扱えるものとして d1)を使います。 本記事で言う判定専用モデルは、文章を書かずに、型の決まった判定(はい/いいえ・選択肢)とその確率を返すモデルです。分類で済む判断には LLM を使わないことで、トークンを減らす狙いです。

判定専用モデルの仕様・価格・精度は、まだ一次情報で確認していません。製品の紹介文を前提に設計しています。導入前に、一次情報と実データで確かめる前提です。

5.1 判定モデルを入れる4か所

箇所 判定すること 判定の後 確信度が低いとき
リスク判定 high / mid / low high なら、マージ前に人が承認する high に倒す
privacy レビューを回すか 差分が個人情報・認証・権限を扱うか 扱うなら privacy レビューを回す 回す
失敗の振り分け 実装のバグ / テストの疑義 / 基盤のエラー / 不安定なテスト バグは修正、テストの疑義は停止、基盤は冷却、不安定なら再実行 止めて人に回す
停止理由の分類 仕様(spec)/ 基盤(infra)/ クレジット切れ(credit) 仕様なら次のタスクへ。基盤とクレジット切れなら、ループ全体を冷却 基盤とみなし、全体を冷却

4か所とも、画像を使わないテキストの分類です。そのため、テキスト分類のモデル1つで揃えられます。

リスク判定は、重厚型で LLM のエージェントが担っていた判断の置き換えです。privacy レビューを回すかは、差分のパスでの判定に、内容での判定を足します。パスに表れない個人情報の扱いも拾えるからです。失敗の振り分けは、修正に進むか、止めるか、冷却して再試行するかを即決するために使います。

5.2 閾値は帯で決め、迷ったら慎重な側に倒す

運用のルールを4つ決めました。

  1. 閾値を帯で決める:例えば「確率 0.9 以上なら即決」とし、帯に入らない件は、上の表の「確信度が低いとき」の扱いに回す。帯の幅は実績を見て調整する
  2. 慎重な側に倒す:privacy とリスク判定は、見逃したときの損失が大きい。閾値を厳しめにし、迷ったら確認が厚くなる側に倒す
  3. 過去の記録で検証する:ループのログと過去の Issue(リスク区分・停止理由・privacy の指摘)を正解データにして、導入前に一致率を測る
  4. 確率を記録に残す:判定と確率を、状態ファイルと Issue に残す。後から「なぜレビューを省いたか」を追えるので、トレーサビリティが保てる

5.3 判定モデルに任せないもの

判定モデルは、分類しかしません。次の3つは任せません。

  • 生成する作業:要件の分解・テスト・実装・修正・リファクタ。判定モデルはコードを書けない
  • 要件適合レビュー:「この実装は要件を満たすか」は、差分と正本を読み込んだ推論が要る。LLM に残す
  • マージの最終判断:判定モデル単独では通さない。CI と、high リスクのときの人の承認を残す

5.4 画像の判定は、通常のループから外す

画面のスクリーンショットを撮り、チェック項目ごとに合否を出す判定も入れます。今は目視に回している画面の項目を、自動化する狙いです。

ただし、通常のループでは行いません。画面の起動・撮影・画像の判定は重いからです。通常のループとは別に起動します。

項目 方針
起動のタイミング 手動、スプリントの区切りや客先確認の前、夜間にまとめて、のいずれか
対象 前回の判定以降に、差分が入った画面だけ
判定 画像を扱える判定モデルで、スクリーンショット × チェック項目ごとに合否を出す
結果の扱い 不合格の項目を、画面ごとに Issue として起票する。通常のループのタスクとして流れる

通常のループの UI/UX チェックは、これまでどおりコードと静的スキャンで判定します。重い処理を外に出すので、通常のループの所要時間には響きません。見つかった問題は Issue 経由でループに戻るので、別の仕組みを持たずに済みます。


6. 原則⑤ 読むのは並列、書くのは直列。並列化は件の間で

並列化の基本は「読むだけの処理は並列、書く処理は直列」です。同じファイルを複数のエージェントが書くと競合し、その解消に時間を取られるからです。

6.1 採用した並列化

並列にする処理 目的 注意点
テスト設計を層ごとに分ける(domain / usecase / infra / 画面) 速度。要件IDの塊ごとに書ける 書く処理なので、書くファイルを層ごとに分けて競合を防ぐ
検証の CI・要件適合レビュー・privacy レビューを同時に回す 速度。全部読むだけなので、互いに待つ理由がない 修正は1体が、指摘をまとめてから行う
仕上げの UI/UX チェックとリファクタを同時に回す 速度 チェック役は指摘を出すだけで、コードを書かない。直すのはリファクタの後
報告と正本への提案を、CI 待ち・マージ待ちの裏で行う 待ち時間の活用 ―
件をまたぐパイプライン 一番効く見込み。①〜③の時間がほぼ隠れる 次の件で先に進めるのは①〜③まで

件をまたぐパイプラインは、ある件の実装中に、次の件の準備を進める形です。

時点 件A 件B
件A の準備中 ①〜③ 要件読み込み・テスト設計・対応検査 ―
件A の実装中 ④〜⑦ 実装・検証・修正・仕上げ ①〜③ 要件読み込み・テスト設計・対応検査

①〜③は実装のコードに触れないので、件A の実装と衝突しません。

1件の中の並列化で短くなるのは、待ち時間のうち、レビューとチェックの部分です。大きく効くと見ているのは、件をまたぐパイプラインです。

6.2 採用しなかった並列化

  • 要件読み込みを2体で行う:2体に独立に読ませ、解釈がずれた箇所を正本の曖昧な箇所として質問に回す案だった。これは速度ではなく、品質のための並列化。ただ、読む2体に突き合わせ役が1体加わる。コストに見合わないと判断した
  • テスト設計と実装を同時に行う:テストを先に固定するから、実装はテストに合わせて逃げられない。並列にすると、テスト駆動の意味がなくなる
  • 実装を2体に分ける:何もしないと、共有ファイル(型定義・package.json・migration・共通部品)、層の間の取り決め、結合後の不具合の3点で競合する。避けるには、取り決めの先行固定、書ける場所の分担、結合後の CI が要る。小さい件では、2体がそれぞれ周辺のコードを読む分トークンが倍近くかかり、むしろ遅くなる
  • 修正ループ:直した結果を見て次を決める、逐次の処理。並列にはできない

並列化の単位は、件の中より件の間です。 1件の中を割ると、取り決めと結合の手間が、並列化で得た時間を食ってしまいます。速度は件をまたぐパイプラインで稼ぐ方が、安全で効果も大きいと考えています。


7. 原則⑥ 止まっても止まらない

ループが止まること自体は、悪いことではありません。曖昧な要件やテストの疑義で止まるのは、設計どおりの動きです。困るのは、1件が人の回答を待つ間、ループ全体が遊んでしまうことです。

そこで、1件が止まったら、他に着手できるタスクを探してすぐに着手する設計にしました。重厚型では、30分ごとのスイーパーが次のタスクを払い出していました。これを、停止の直後に払い出す形に変えます。

7.1 停止したときの流れ

  1. 停止理由を Issue に残す
  2. 作業中のラベルを外し、ロックを解除する
  3. 停止理由を判定モデルで分類する
  4. 理由に応じて、次のタスクへ移るか、ループ全体を冷却する(一定時間おいてから再開する)
停止理由 次の動き 理由
仕様(spec) 次の ready タスクへ移る 人の回答を待つ間も、ループを止めないため
基盤(infra)・クレジット切れ(credit) ループ全体を冷却する 次の件も同じ原因で落ちる
分類の確信度が低い 基盤とみなし、全体を冷却する 慎重な側に倒す
3件続けて停止 ループ全体を冷却する 正本の欠落や環境の不具合など、共通の原因を疑うべき

7.2 次の候補の選び方

次の候補は、WBS の依存順で ready になっていて、止まった件に依存しないタスクです。止まった件と触るファイルが重なるタスクも、候補から外しません。

止まった件は、人が質問に答えてラベルを外すと、候補に戻ります。


8. 最終的なフロー

ここまでの原則を、1枚にまとめます。図の読み方は次のとおりです。

  • 灰色の四角:ワークフロー(機械)
  • 灰色に橙の破線の四角:機械で判定し、合わない分だけ AI が1回推論する
  • 橙の四角:LLM のエージェント
  • 緑の六角形:判定モデル
  • 赤の四角:停止・冷却
  • 見出しに【並列】とある枠:中の処理を同時に回す

「次の件の①〜③」へ伸びる破線が、件をまたぐパイプラインです。別起動の画面判定は、不合格を Issue にして、通常のループの「次の ready タスク」に合流させます。


9. 検討して捨てたもの

設計の途中で入れかけて、外したものです。やらないと決めた理由は、他のループにもそのまま使える知見だと考えています。

捨てたもの 狙い 捨てた理由
要件をわざと外した実装での試行 テストの弱さを見つける。「この要件を外した実装でも、テストは落ちるか」を確かめる 今のループはうまく回っている。毎回試すのはトークンの無駄
要件読み込みを2体で行う 2体の解釈のずれから、正本の曖昧な箇所を見つける 読む2体に、突き合わせ役が1体加わる。コストに見合わない
実装を2体で行う 1件の中を速くする 共有ファイル・層の間の取り決め・結合で競合する。小さい件では、トークンが倍近くかかり、むしろ遅くなる
テスト修正専用のエージェント 実装中に分かったテストの誤り(要件の読み違い・前提データの誤り・不安定なテスト)を直す 実装の前に直すのは、テスト設計担当の仕事そのもの。別のエージェントにすると、正本とテストを読み直すトークンが二重にかかる。対応検査が返す抜けの一覧を渡せば足りる。実装の後にテストが疑わしくなったら、要件の解釈ずれを疑って止まる
AI の品質レビュー コードの品質を AI が見る CI と役割が重なる。判定がぶれ、コストもかかる。基準は lint と依存ルールとしてコードに書く

10. まとめ

  • テスト駆動が保証するのは「実装がテストに合っている」ことまで。ずれは、最後のレビューではなく「要件 → テスト」の段で止める
  • 品質の基準は、AI のレビューではなく、lint と依存ルールとしてコードに書く。層を分ければ、落ちた層が問題の場所になる
  • 答えが一意なものは機械に任せる。合わない分だけ AI に1回推論させ、結果を表に書き戻す
  • 分類で済む判断は判定モデルに任せ、LLM は生成と推論に使う。迷ったら慎重な側に倒す
  • 読むのは並列、書くのは直列。並列化は件の間で効かせる
  • 1件が止まっても、ループは止めない。停止理由で、次のタスクへ移るか、全体を冷却するかを分ける

この設計は、まだ全部は運用していません。残っている課題は3つです。

  • 判定モデルの閾値の帯を、運用データで調整する
  • 判定モデルの仕様と精度を、一次情報と過去の記録で確かめる
  • 1件あたりのトークン量と所要時間を測り、狙いどおりに減ったかを確かめる

参考

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?