STORYAI の開発では、コードの大半を AI エージェント(Claude Code)が書いています。始めたころは「バイブコーディング」と呼ばれる進め方に近く、AI の出した変更を細かく読まずに受け入れていました。けれども、本番で動くサービスを毎日更新していくと、それでは回りません。数か月の試行錯誤を経て、仕様と判断と承認は人が持ち、実装と検証と記録を AI が回す形に落ち着きました。
この記事では、その進め方と、AI 駆動開発として見直して仕組みに変えたところを書きます。
仕様を先に合意しておくと、AI の出力がぶれない
新機能や大きな改修では、いきなりコードを書かせません。AI にまず要件定義と詳細設計を出させ、人が読んで合意してから実装に入ります。合意した内容は Issue か PR の本文に残します。こうしておくと、実装の途中で AI が独自の解釈を足したとき、どこが合意から外れたのかを指し示せます。
参照物がある作業では、もう一段の手当てをしています。トップページのアニメーションを、用意したデモのとおりに移植するよう頼んだことがありました。届いたものには、デモにない半透明の色の層が足されていました。回転すると色がくすみます。それ以来、参照物がある作業ではまず「参照と現状の差分」を表にさせます。見た目の選択肢はプレビューを並べ、質問は一度にまとめて決めています。
AI 向けの文書は、入口 1 枚と領域別の規則に分ける
リポジトリの直下に全体のガイドラインを 1 枚だけ置き、全作業に共通する規則をまとめています。Git の運用、検証の基準、承認が必要な操作などです。フロントエンド、API、データベース、デザイン、セキュリティの規則は、それぞれの領域の文書に分けました。作業ごとに、必要な文書だけを読ませます。
同じ内容を複数の文書に書かないことも決めています。重複させると、片方だけが更新されて食い違うからです。
モデルは役割と条件で使い分ける
全工程を最上位のモデルで回すと、費用がかさみます。これは開発を回すエージェントでも、STORYAI の中に組み込む機能でも同じでした。そこで、開発とプロダクトの両方で、工程や条件ごとに Claude・GPT・Gemini を使い分けています。
まず開発の側では、エージェントの中で役割ごとにモデルを分けました。
| 担当 | モデル | 受け持つ作業 |
|---|---|---|
| メインのエージェント | 最上位(Opus) | 要件の整理、設計判断、本番に関わる操作の可否、結果の統合 |
| 実装・テスト・調査・画面確認・PR 作成 | Sonnet 5.5 | 決まった作業の実行 |
| コードレビュー | Opus 5.5 | 回帰や権限漏れの検出 |
| 定型の整形・データ収集 | Sonnet 5.5 / Haiku 5.5 | 一覧の整形、起票文の下書き |
レビューに Opus を当てているのは、見落としが一番高くつく工程だからです。役割ごとの指示は定義ファイルにまとめ、サブエージェントを起動するときはモデルを必ず明示します。あわせて、OpenAI の Codex も併用し、設計の比較や一歩ずつ進める実装タスクで使い分けています。
うまくいかなかったこともあります。20 ファイルを超える実装を一度に Sonnet へ渡したところ、テストを残したまま途中で止まってしまいました。また、環境設定の都合で古い世代のモデルが使われていた時期には、テストが通らない状態のまま「完了」と報告されたこともあります。今はモデル指定を新しい世代に固定したうえで、大きな規模なら最初から Opus にするか、依頼を小さく切っています。
プロダクトの機能や CMS 運用でも、一つのモデルには寄せていません。精度、速度、単価、扱うメディア(文章・画像・音声・動画)の条件で、モデルを切り替えています。
| 用途・条件 | 主に使うモデル | 使い分けの理由・フォールバック |
|---|---|---|
| マンガのコマ分割 | GPT 6.1 Sol(第 1 候補)→ Gemini 4 Argon | 複数 LLM の比較で、複雑なコマ割りやコマ外セリフの領域抽出は GPT 6.1 Sol が最も安定していたため。失敗時は Gemini 4 Argon へ切り替える |
| 知識抽出と裏付け検証 | 抽出:GPT 6 Luna → 検証:Claude Sonnet 5.5 | 全文を走査する抽出は単価が Sonnet の約 1/8 で精度も並んだ GPT 6 Luna で回し、引用の機械照合を通したあと、裏付け判定と名寄せだけを Sonnet 5.5 で行う |
| Studio の対話エージェント | GPT 6 Luna | 発言回数が多くなりやすいため、無料プランでも使える軽量モデルに固定 |
| 作品詳細の読み物レポート・根拠付き QA | Claude Sonnet 5.5(無料プランの要約版は Haiku 5.5) | 長文の一貫性と根拠の引用精度を優先。無料プラン向けのダイジェストだけは Haiku 5.5 で費用を抑える |
| 設定資料集・冊子の AI 文案 | Gemini 4 Argon / Gemini 3.8 Flash / Claude Haiku 5.5 | 契約プランで切り替える。上位プランは表現力の高い Gemini 4 Argon(月間上限到達時は 3.8 Flash)、Starter は 3.8 Flash、無料プランは Haiku 5.5 |
| 分析設定の自動提案・トレンド分析・動画台本・CMS 自動翻訳 | Gemini 3.8 Flash | 応答速度と構造化出力のバランスが良く、呼び出し回数が多い定型生成に向くため。CMS の多言語翻訳(英・中)も Opus から切り替えて費用を下げた |
| 本編の分析パイプライン(感情・年表・人物相関図) | テキストのみ:Claude Sonnet 5.5 優先/メディアあり:Gemini 3.8 Flash 優先 | 音声・動画を含む章はマルチモーダルに強い Gemini を優先し、テキストの章(または書き起こしが揃った動画の章)は Sonnet 5.5 を第 1 候補にして、後続モデルへ順にフォールバックする |
どのモデルを使うかは、コードのあちこちにモデル名を直書きせず、役割とモデルの対応表に集約しました。新しいモデルが出たときや、コストを見直すときは、この表だけを差し替えます。
そして、開発でもプロダクトでも、AI の「完了しました」はそのまま信じません。リリース時に人が確認する手順をサブエージェントに要約させ、その結果をそのまま答えたことがあります。実際には 10 件近くあった手順を、2 件だと報告してしまいました。答えそのものになる事実は、メインのエージェントが一次情報を自分で読みます。
並行させるなら、作業場所を分けておく
同じリポジトリで、複数のチャットを同時に動かしています。git worktree で作業ごとに別のディレクトリを切り、ブランチの切り替えは各作業場所の中でしか起きないようにしました。
これは並行作業での混線を防ぐための規則です。以前は、実装を任せたサブエージェントが別チャットのブランチへ切り替えてしまい、そこにコミットが混ざったことがありました。今はサブエージェントに作業を渡すたびに、ブランチ切り替えや履歴を巻き戻す操作を禁じ、想定外のブランチにいたら手を止めて報告するよう徹底しています。
履歴の整理でもヒヤリとした経験があります。リモートの統合ブランチ名を基点に履歴をまとめたところ、別チャットの同期で基点が先に進んでしまい、他のメンバーの変更分まで差分に混ざりかけたのです。それ以来、基点は動くブランチ名ではなく固定のコミット ID で取り、push の前に差分が自分の担当分だけかを確かめています。
PR は積み上げず、すべて統合ブランチを直接の向き先にしています。親子に積み上げた PR のうち親だけが先にマージされ、子の変更が取り残されるのを防ぐためです。
失敗を記録して、次のセッションに持ち込む
AI エージェントは、セッションが変わると前の会話を覚えていません。そこでエージェントのメモリ機能に、指摘された内容を一件ずつ記録しています。何を言われたか、なぜ問題だったか、次にどうするか、の 3 点です。
今いちばん効いているのは「見つけたバグは直す」という記録です。頼まれた範囲だけを直し、作業中に見つけた別の不具合は「範囲外」「変更前からある」と言って残す。AI にはこの癖がありました。これを繰り返し見直し、本題とは別のコミットで直すことを既定にしました。Lint や整形の既存の警告も同じ扱いです。
もう一つは「遅いのも品質課題」という記録です。集計処理が重く、タイムアウトしそうになったことがありました。AI が最初に出したのは、同時実行数を絞ってエラーだけを避ける案でした。エラーは出なくなっても、画面の表示は遅くなります。本命は重い集計そのものを事前集計に置き換えることで、今は性能の課題には原因を取り除く案から出させています。
本番と削除の判断は人が持つ
本番環境への反映、クラウド上のリソースの削除、データベースのスキーマ変更、認証や課金の仕様変更は、AI に判断させません。調査と一覧づくりまでは AI が行い、実行するのは人が個別に承認したものだけです。秘密情報は値を AI の文脈に入れず、実行時に解決させています。PR は必ず人がレビューしてからマージします。
弱いところは、規則が「お願い」のままだったこと
規則は役に立っていました。ただ、AI 駆動開発として見直すと、どれも守れるかどうかが AI の注意力しだいでした。
モデルの指定、git 操作の制限、不具合を見逃さないこと。どれも文書とメモリで伝えているだけで、うっかり抜けることがあります。実際、「見つけたバグは直す」は記録した後にも何度か指摘を受けました。しかも規則の多くは、一人の開発者の手元のメモリにしかありませんでした。チームの他のメンバーや、別の AI ツールには共有されません。
検証の土台も、人の確認に頼っていた時期があります。自動テストの範囲に抜けがあったり、実装の変更にテストが追従していなかったりすると、「テストは通りました」と AI が報告しても十分な裏付けになりません。
規則を仕組みに置き換えた
そこで、注意力に頼っていた規則を、仕組みで守れる形に移しました。
ツールの実行前に自動で止める。 Claude Code の hooks(ツールが実行される直前にチェックを挟める機能)を使い、ルールから外れる操作を自動で拒否するようにしました。モデルを指定しないサブエージェントの起動、サブエージェントによるブランチ切り替えやコミット、保護オプションなしの強制 push の三つです。主担当の通常の操作は止めず、サブエージェントからのルール外の呼び出しだけを止めます。拒否するときは理由と正しいやり方を返すので、AI はそれを読んで自分でやり直します。
規則をチームの文書に移す。 個人のメモリにあった規則のうち、チーム全体で守りたいものをリポジトリの共通ガイドに移しました。見つけたバグは別のコミットで直す、PR は積み上げない、履歴整理は固定のコミット ID を基点にする、答えの根拠は一次情報で確かめる、遅さも原因から取り除く、の五つです。自動で強制しているルールは、ガイドにも一覧を載せて対応させています。
合否を CI に寄せる。 CI で実行する自動テストの範囲を、フロントエンドに加えてサーバー側にも広げました。CI の結果をマージの必須条件にする運用もあわせて整えています。
数字を週に一度出す。 PR が作られてからマージされるまでの日数と、レビュー待ちの PR の一覧を、毎週自動で集計するようにしました。見積もりと人の実作業時間の記録と突き合わせることで、AI を使った開発の進み具合を継続して追えるようにしています。
まだ残っている課題
人のレビュー負担を減らす工夫は、まだ途中です。PR を出す前に、AI が作った差分を上位モデル(Opus)で一度レビューし、その結果と対応内容を PR に添える運用を始めました。人は、AI が判断できない仕様や運用の妥当性に集中できます。ステージング環境での画面確認の自動化は、規模が大きいので段階的に進めていきます。
また、実行前のチェックで止められるのは、機械的に判定できる規則だけです。「見つけたバグを直す」のような判断を伴う姿勢は、今もガイドラインと日々の振り返りに支えられています。
AI 駆動開発で人に残るのは、決めることと止めること
AI に任せる範囲は、この数か月で大きく広がりました。実装、テスト、調査、画面確認、PR の作成まで、今は AI が回しています。それでも、何を作るかを決めること、どの条件にどのモデルを当てるかを決めること、本番に出すかを決めること、危ない操作を止めることは、人の仕事として残りました。
その「止める」を、人の注意力から少しずつ仕組みへ移しているところです。