メインコンテンツへスキップ
見出し画像

コードより先に、AIと「仕様書」から作った話|AIエージェント奮闘記 #5

    今度は、AIにコードではなく「仕様書」を書かせてみました。

    この回で分かること

    • AIチームを「開発チーム」から「文書工程」に組み替えた

    • AIに「推測で空白を埋めるな」と命じた理由

    • 文書に「背番号」を振り、先に"やらないこと"を決めた

    画像
    連載の縦糸の4段階は、化粧品編(第1〜4話)で一周した。請求書編は、同じ型をコードではなく「文書」から始める

    前回までは、化粧品の表記チェッカーを題材に、AIに実装を任せ、それを"使える"まで育てていく話を書いてきました。ここからは、もう一本の個人開発に話を移します。

    化粧品では、私はAIに実装を任せる側でした。今度は、その逆方向の話です。

    コードを1行も書き始める前に、AIと一緒にまず「文書」を作っていく。要件定義書から、設計書、実装計画書まで。私が長年やってきた組込みの世界では、ごく当たり前の順番です。

    題材は、6つのサービスから請求書や明細のPDFを自動で集めてくる、自分用の経理ツールです。

    なぜ「コードから書かない」のか

    フリーランスになると、毎月いろいろなところから請求書や領収書が届きます。メールの添付で来るもの、各サービスのサイトにログインしないと取れないもの。

    これを毎月手で集めるのが、地味に面倒でした。

    そこで、それらをまとめて自動で取得するツールを作ることにしました。取得先は6つ。

    メールに届くもの(Hotmail と Gmail)、Microsoft 365 の課金情報、そして、サイトにログインしないと明細が取れない通販やサブスクのサービス——と入り混じっています。取り方も、2種類のメールのAPI、課金情報のAPI、ブラウザを自動で操作するもの、と4通りに分かれていました。

    ひとつ、先に断っておきます。サイトにログインして取りにいく方式は、サービスによっては利用規約で自動アクセスが制限されていることがあります。

    だからこのツールは、あくまで自分のアカウントの、自分のデータを、規約を確かめたうえで、自己責任で扱う前提です。公式のAPIが用意されているものは、まずそちらを使う。

    この連載でも、規約に触れかねない個別サービスの取得手順そのものには、立ち入りません。

    これだけ相手が多いと、思いついた順にコードを書き始めると、まず間違いなく破綻します。だから今回は、いつも以上に「順番」を守ることにしました。

    最初に決めるのは、コードではなく、「何を作って、何を作らないか」。 それを文書で固めてから動く、という組込みのやり方です。

    では、その文書を、誰に書かせたのか。今回もまた、AIでした。

    AIチームを「開発チーム」から「文書工程」に組み替えた

    第1話で、私は Claude Code の中に「自分専用の開発チーム」を作った話を書きました。全体を統括する役、設計する役、実装する役、テストする役——どちらかと言えば、手を動かして「作る」ことに重心を置いたチームでした。

    今回は、その重心を、もっと上流に移しました。組んだのは、次の5体です。

    • 文書を書く document-writer(要件定義書・基本設計書・詳細設計書を担当)

    • 計画を立てる plan-writer(実装計画書=タスク分解と段取りを担当)

    • 実装する coder

    • レビューする reviewer

    • テストする tester

    画像
    請求書ツールのAIチーム5体。document-writer、plan-writer、coder、reviewer、tester の順で、役割の順番がそのまま開発の順番になっている

    並べてみると分かるとおり、役割の順番が、そのまま開発の順番になっています。そして、コードを書く coder は、わざと工程の3番目に置きました。

    ねらいは単純です。AIは、とにかく手が速い。

    放っておくと、すぐコードを書き始めてしまう。その速さを、いきなり実装にぶつけるのではなく、まず「設計を固める」方向へ流したかったのです。

    最初に文書を書く係を立てておけば、AI自身が「まず文書から」という順番を守ってくれます。

    ただ、AIに文書を書かせるには、一つだけ、厳しい禁止令が必要でした。

    AIに「推測で埋めるな」と命じた

    文書を書く document-writer に、私は最初にこう言い渡しました。要点はいくつかありますが、一番大事だったのはこれです。

    推測で、空白を埋めるな。

    具体的には、こういう原則を持たせました。

    • 分からないことがあったら、勝手に決めず、必ず私に確認してから書くこと

    • 記述は「根拠→理由→数値」の順で書くこと

    • まだ決まっていない箇所は、それらしい言葉でごまかさず、「TBD(未定)」と正直に書いておくこと

    なぜ、ここまで言うのか。

    長く安全性の問われる分野でやってきて、骨身にしみていることがあります。仕様の曖昧さや、誰かの勝手な解釈は、そのまま不具合になり、ときに事故になる、ということです。

    空欄は、気を利かせて埋めるものではありません。「ここはまだ空欄だ」と、ひと目で分かるようにしておくことのほうが、ずっと大事なのです。

    そして、AIがもっとも危ういのは、まさにこの「空白をそれらしく埋める」のが得意な点です。 聞けばもっともらしい答えが返ってくる。

    でも、その中身が確かめられていなければ、後で必ず痛い目を見ます。だから私は、AIに気を利かせて補完してもらうより先に、「分からないことは、分からないと言ってくれ」と頼んだわけです。

    ついでに、コードの「書き方」も人間側で固定しました。

    すべての関数に型の注釈をつける、print での出力は禁止してログの仕組みを使う、設定値は1か所にまとめてハードコードしない、すべての入出力処理に例外対応を入れる——といった規約です。

    判断の根拠も、書き方も、ブレる部分を先に潰しておく。これも、長くやってきた人間の癖なのだと思います。

    文書に「背番号」を振る

    できあがっていく文書には、一つずつ「背番号」を振りました。

    要件定義書、基本設計書、詳細設計書、実装計画書、そしてテストの仕様書と結果レポート。この6種類の文書すべてに、DOC-SPEC-001、DOC-DESIGN-001 といった固有のIDを付けたのです。

    画像
    要件定義書の冒頭。ドキュメントID「DOC-SPEC-001」と、3つの版を重ねた「バージョン 3.0.0」が、文書の先頭に書かれている

    番号を振ったのは、文書だけではありません。

    「どんな機能が必要か」を定める機能要件には、FR-001 から FR-062 まで、取得元ごとに番台を分けた番号を(項目は全部で28)。性能やセキュリティといった裏方の要件には、NFR-001 から NFR-007 の番号を振りました。

    計画を立てる plan-writer のほうも、同じ流儀で動かしました。

    やるべき仕事は、1つあたり1〜4時間で終わる最小単位にまで割る。そして、「この作業は、あの作業が終わってからでないと始められない」という依存関係を、先行する作業の番号で明示する。

    各タスクの状態は、「未着手・進行中・完了・ブロック中」の4つだけで管理する。

    なぜ、ここまで番号にこだわるのか。後になって「この要件を変えたい」となったとき、それがどの設計に響き、どのコードとどのテストに効いてくるのかを、番号でたどれるようにしておきたかったからです。

    これは、組込みの世界で「トレーサビリティ」と呼ばれる考え方そのものです。

    AIは、大量の文書を驚くほど速く書いてくれます。でも、その文書を後から「たどれる」状態に保つ設計は、人間の私が用意するしかありませんでした。

    仕様書は「3回」育ち、先に“やらないこと”を決めた

    文書というと、一度書いたら終わり、という印象があるかもしれません。でも実際は、書いたあとも何度も育てていきました。

    要件定義書は、結果的に3つの版を重ねています。

    1. 最初の第1版は、Hotmail という1つのソースから請求書を取るだけの、ささやかなものでした。

    2. 第2版で、Gmail や Microsoft 365、それにログイン型のサービスを一気に追加し、いまの「6ソース対応」の形になりました。

    3. 第3版では、取得を始める日付の扱いを全体で統一する、といった整理を加えています。

    アプリの成長が、そのまま文書の版番号として残っているわけです。

    そしてもう一つ、最初の版でこだわったことがあります。「やること」より先に、「やらないこと」を書いたことです。

    たとえば、添付ファイルの中身を読み取る文字認識(OCR)はやらない。メールの送信や返信はしない。会社で使うようなメールサーバーは対象にしない——。

    こうした「対象外」を、最初の要件定義書にはっきり書きました。何でもできるようにすると、いつまでも完成しません。

    やらないことを決めるのは、組込みで納期と品質を守るための、基本中の基本です。

    この「やらないこと」を足し引きするのも、結局は人間の仕事でした。

    AIは、機能を「足す」のはとても得意です。でも、「これは作らない」と引き算する判断は、私が握っておくべきものでした。

    実は、この最初の要件定義書には、もう一行、地味だけれど重要な制約が書いてありました。「Hotmail の個人アカウントは、昔ながらのパスワード認証がもう使えないので、別のログイン方式を使う必要がある」。

    このひと言が、この先の伏線になります。

    それでも、骨格は文書でできた

    こうして、コードを1行も書かないうちに、アプリの骨格は文書の形でできあがりました。AIは、設計やコードだけでなく、文書を書くのもやはり速い。

    ただ、今回いちばん大事だった私の仕事は、文書を書くことそのものではありませんでした。AIの速さに「枠」をはめること——推測で空白を埋めさせない、やらないことを先に決める、後からたどれる形に保つ。

    その3つを徹底することが、ベテランとしての役割だったと思います。第1話で引いた「任せる/握る」の線が、今度は「設計の段取り」という形で一歩進んだ感覚でした。

    まとめ

    • 任せたこと:要件定義書・設計書・実装計画書を書くこと(文書工程型の5体)

    • 握ったこと:推測で空白を埋めさせない原則、やらないことの線引き、背番号でたどれる形に保つこと

    • 次の課題:この仕様書を、実際に動かせる「設計」へ

    AIは文書を書くのも速い。その速さに枠をはめることが、ベテランとしての役割でした。


    次回は、この仕様書を、実際に動かせる「設計」へ——基本設計から詳細設計へと、AIとどう詰めていったかを書きます。きれいに見えた設計図が、やがて実装の入口で最初の壁を突きつけてくるのですが、それはもう少し先の話です。

    仕事の依頼(ココナラ):作業の自動化を頼む/Claude Code の使い方を教わる

    あなたへのおすすめ