0
2

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と、それを疑うAIを分ける ― 人間1人 + AI3種で B2B SaaS を回している話

0
Posted at

はじめに

鋼材切断計画の B2B SaaS TORIAI を、 人間1人 + AI 3種類で開発・運用しています。 コードを書くAI、 それをレビューするAI、 観点別にQAするAI を 役割で分けたところ、 「AI が自分の書いたコードを自分で『大丈夫です』と太鼓判を押す」 という一番危ない状態を避けられるようになりました。

この記事は、 その分業の組み方と、 実際に効いた/事故った具体例の記録です。 AI に実装を任せたいが品質が不安、 という人の参考になればと思います。

体制: 実装・レビュー・QA・判断 を分ける

役割 担い手 やること
実装 / 議長 Claude (Claude Code) 仕様・実装・全体設計・統合
レビュー / DB Codex (別ベンダーの coding AI) 実装の独立レビュー、 DB migration、 重い refactor
観点別 QA subagent (code-reviewer / security-auditor / migration-checker 等) commit 前の自動チェック
判断 人間 (1人) 公開可否・価格・本番DB変更・方向性

ポイントは 「実装したのと別の主体にレビューさせる」 ことです。 同じAIに「これ大丈夫?」と聞くと、 だいたい「大丈夫です」と返ってきます (自分の出力への確証バイアス)。 実装=Claude / レビュー=Codex や fresh-context の subagent と分けると、 片方が見落とした前提を もう片方が拾えます。

仕組み1: git worktree で実装AIを隔離する

レビューAI(Codex)に実装を任せるとき、 本番ブランチ(main)で直接やらせると事故が怖い。 そこで git worktree で隔離します。

# main とは別のディレクトリに作業ツリーを作る
git worktree add ../proj-cx -b ai/feature-x

# そのツリーで Codex を走らせる (CLI)
cd ../proj-cx
codex exec --dangerously-bypass-approvals-and-sandbox "$(cat /tmp/brief.txt)"

実装が上がったら、 人間(の議長役Claude)が 3-way merge で main に取り込みます。 fast-forward ではなく 3-way にするのは、 隔離中に main 側で進んだ別コミットを保持するためです。

git merge ai/feature-x --no-edit   # 3-way。main の進捗を潰さない
git worktree remove ../proj-cx --force

これで「実装AIは隔離ツリーで自由に試す → 検証が通ってから本番へ」 という安全弁ができます。

ハマりどころ: AI CLI に渡す指示文(brief)を インラインのシェル引数に直書きすると、 バッククォートや $() が シェルに解釈されて壊れます。 必ずファイルに書いて "$(cat brief.txt)" で渡すこと。 これで一度、 指示が無言で失敗して作業ツリーが空のまま、 という事故をやりました。

仕組み2: commit 前に subagent を並列で投げる

コードを書いたら commit 前に、 観点別の subagent を 並列で投入します。

  • code-reviewer: 正確性バグ / 命名 / 既存コードとの不整合
  • security-auditor: 認証 / RLS / 入力描画 (XSS) / 越境
  • migration-checker: DB migration が設計方針に沿うか

それぞれ 独立したコンテキストで動くので、 実装者が「当然そうなってる」と思い込んでいる前提を 容赦なく突きます。

仕組み3: 連携は「掲示板」で非同期に

AI 同士のやり取りは、 チャットで流すと消えるので、 リポジトリ内の AI_BULLETIN.md という1枚に追記していきます。 「Claude → Codex: この migration の越境チェック見て」「Codex → Claude: ここが情報漏れる」 を全部 git 履歴に残す。 後から「なぜこの設計にしたか」 を追えるのが効きます。

効いた例: AIの「それっぽい正論」を実機で潰した

ここが一番伝えたい話です。

残材在庫の登録タイミングを変える、 という変更を Codex に実装させ、 code-reviewer にレビューさせたところ、 「CRITICAL: 再印刷時に登録漏れが起きる」 という指摘が返ってきました。 一見もっともらしい。

でも 鵜呑みにせず、 実機(本番同等環境)で実際に操作して再現を試みました。 計算 → カート追加 → 印刷、 を本物のUIで動かして在庫の数を各段階で確認する。 結果:

  • カート追加直後: 在庫は 増えない (狙い通り)
  • 印刷後: 端材が 1本だけ登録 され、 カートはクリア

つまり登録は「印刷の確定時に1回だけ」 正しく走っていて、 CRITICAL は誤検知でした (レビューAIは「クリア後に再印刷したら」 という、 実際には起こらない経路を心配していた)。

逆の方向もあります。 別の変更では、 ユニットテストもローカルも全部緑なのに、 本番でだけ動かないバグを実機E2Eで見つけました。 原因は DB の関数の戻り値フィールド名が想定と違った (id ではなく remnant_id だった) こと。 これは 実際にログインして本物のDBを叩かないと絶対に出ない。

教訓はシンプルです。

AIのレビューは「容疑」、 実機の挙動が「判決」。

AIレビューは観点出しには最強ですが、 それ自体が真実ではない。 だから運用ルールに 「subagent の指摘は実機で再現してから直す」 を明文化しています。 誤検知を鵜呑みにして直すと、 動いていたものを逆に壊します。

正直に: AIに任せて事故ったこと

良いことばかりではないので、 やらかしも書きます。

  • キャッシュ焼き付き: 変更を出荷した直後、 確認のために本番ファイルを デプロイ伝播の前に 取得してしまい、 CDN が「その時点の古い中身」 を immutable キャッシュに固定。 一瞬ユーザーが旧コードを掴む状態になりました。 すぐ気づいてキャッシュキーを振り直して復旧。 → 「新しい cache-buster URL は、 デプロイ完了まで触らない」 をルール化。
  • 死にコードに配線: ある機能を、 既に呼ばれなくなっていた関数(死にコード)に配線してしまい、 実機まで気づけなかった。 → これも実機E2Eで発覚。

どれも 「実機で動かす」 工程があったから捕まえられたもので、 AIの自己申告だけで進めていたら本番に流れていました。

まとめ: 1人 + AIでも「相互監視」は作れる

  • 実装するAIと、 それをレビューするAIを分ける (確証バイアスを切る)
  • 実装AIは git worktree で隔離 → 検証後に 3-way merge
  • commit 前に観点別 subagent を並列投入
  • AIの指摘は鵜呑みにせず、 実機の挙動で最終判断する
  • 人間は 判断(公開・価格・本番DB・方向性)に専念する

「AIに任せると品質が不安」 の解は、 「もっと賢い1体のAI」 ではなく、 役割を分けて相互監視させる + 最後は実機で殴る、 だと感じています。 1人開発でも、 この相互監視の構造は十分に組めます。


TORIAI について

中小の鉄鋼商社 / 切断加工向けに、 1D 鋼材の切断計画 + 残材在庫 + 営業所共有を 1 ツールで。 登録不要・Free で使えます。

→ toriai.app


0
2
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
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?