背景と課題
AIに開発を任せる際、以前は次の流れで進めていた。
要望 → 設計 → 実装
設計の内容に問題がなければ実装に進む、という進め方である。
ただ、開発が複雑になり、複数のタスクを同時に回すようになると、次の2つが目立つようになった。
- AIの設計書は丁寧に書かれる一方で、文量から「どこが重要で、どこが重要でないか」を読み取りにくい
- 自分の理解とAIの理解がずれて、見当違いな実装をする
人間として開発のオーナーシップを持つなら、「AIに実装させた」だけでは完結しない。どういう意図でこの設計にしたのかを自分が把握している必要がある。
軸1:新機能の開発では、必ず設計意図を確認する
やったこと
設計の前後に、1段階を追加した。次のどちらかである。
A. 要望 → 要件・設計意図 → 設計 → 実装
B. 要望 → 設計 → 設計意図(要望の解釈)を出力 → 確認 → 実装
要望から直接設計を出させるのではなく、「この意図で開発を進めればよい」という要件定義に近いものを一度出力させる。
実際に使った指示は、次のような短い問いかけである。AはAの前段で、Bは生成された成果物に対して使う。
# 要望から設計・実装に進む場合(A)
私の要望から、どういう意図を抽出できましたか?
# 生成された成果物に対して(B)
これらの質問を生成した設計意図はどうなっていますか?
特別な書き方をしなくても、設計意図は十分に出力された。
AとBでは、出力される意図の性質が大きく違う。
- A:設計の前に意図を出力させ、その意図を前提に設計させる。意図でAIを縛ったうえで出力させられるため、制御できている状態になる
- B:すでにあるものから意図を推測する。人が書いたコードでも、AIが書いたコードでも、設計書でも、コード内のコメントでも同じで、出てくる意図は推測にすぎない
以降の2つの例はどちらも、AIが何を根拠に作ろうとしていたかを見るために使った。Bの意図は推測であることを前提に、自分の要望と照らして確認している。
具体例1:RAGの評価用質問セットを作ったとき
登場人物は次のとおりである。
- 業務側の担当者:RAGを評価する人であり、実際に質問をする利用者でもある。それぞれの業界のドメイン知識を持っているが、今回のドキュメントのフォルダ構造は知らない
- 私たち開発側:回答例を書く人。ドメイン知識はないが、フォルダ階層はおおよそ把握している
- 質問を作るAI:私たち開発側が開発に使っているAIである。RAGの中で実際に回答するAIとは別のAIである
業務側と開発側の関係は、事業会社の社内でも、受託開発と発注側の間でも、同じように成り立つ構図である。
RAGの評価では、実際の利用者からの質問が特定のトピックに偏りやすい、という課題があった。そこで今回は、開発側で事前に質問と回答例をExcelにまとめ、「この質問に対して、実際にうまく回答できているか」を確認する方針にした。
質問を作る段階で、ずれが起きた。
- AIは、参照ドキュメントの中身から質問を作っていた
- RAGは、ドキュメントを参照すれば答えられるように作られている。ドキュメントから作った質問は、答えられて当たり前になる
- 評価として意味のある質問にするには、ドキュメントの内容に引きずられない、ある程度のランダム性が必要だった
この意図がAIに伝わっていなかった。そこで、「今の質問作成の設計意図はどうなっているか」を出力させたところ、認識違いが明確になった。
その後、次の方針に整理し直した。
- 私たち開発側には、対象分野のドメイン知識がない
- ただし、ドキュメントを集めたフォルダの階層(フォルダツリー)を見れば、どの分野の資料かをある程度つかめる
- 業務側の担当者はドメイン知識を持っているが、フォルダ構造は知らない。この「業務側は構造を知らない」という違いが、開発側がフォルダ階層から分野を推測して質問を作ることの意味になる
- つまり質問は、ドキュメントの本文ではなく、フォルダ階層から読み取れる分野の情報をもとに作る
設計書をそのまま読んでいたら、おそらく気づけなかったずれである。設計意図を別に出力させたことで、「何をもとに質問を作ろうとしているか」が一目で確認できた。
具体例2:動画ダウンロードアプリのログイン機能
個人で、YouTubeやXの動画をダウンロードできるアプリを作っている。Xなどはログインして連携しないとダウンロードが弾かれてエラーになるため、ログイン機能が必要だった。
- 私の意図:すでにログイン済みの、開いているブラウザからログインセッションの情報を持ってくる
- 実際にできたもの:「ログイン」ボタンを押すと、ログインされていない新しいブラウザが開き、そこで改めてログイン操作をしなければならない実装
意図とは違う実装になっていたため、直す前に「今の設計意図はどうなっていますか?」と出力させ、AIの解釈と私の意図のずれを確認したうえで修正に入った。
今後
新機能の開発では、設計の前後で必ず設計意図を確認する(自分の運用ルールとして)。
設計意図の出力を挟むと品質が上がると感じているが、これは今回の環境での体感であり、比較検証した結果ではない。
理解負債・技術負債との関係
他の記事での整理(一般論)
AIコーディングでは、従来の技術負債に加えて、新しい負債が語られている。
- 技術負債:設計の妥協や低品質なコードによって、将来の修正コストが増える状態(@IT、Zenn)
- 理解負債:コードは動くが、なぜそう動くのかを人が説明できない状態。AI生成コードを十分に理解しないまま取り込むと、保守や修正のコストが蓄積する(Zenn、@IT)
- 認知負債:AIに思考を委ねすぎて、システム全体の設計を把握する力が落ちる状態(@IT)。SO Technologiesの記事では、個人やチームが持っていたはずのコードへの理解が失われていくことと説明されている
- 意図負債(意図的負債):システムをどう発展させるかの根拠・目標・制約が失われていく状態。AIは「何を作るか」は出力するが「なぜそう作ったか」は出力しないため、コード生成量に比例して溜まるとされる。軽減策として、重要なアーキテクチャ上の決定を記録するADRや、目的を捉えるBDDが挙げられている(SO Technologies)
Addy Osmaniは理解負債を、システム内に存在するコードの量と、人が実際に理解している量との開いていく差として説明している。コードはきれいに見え、テストも通り、開発速度の指標も良好に見えるため、技術負債と違って気づきにくい点が特徴とされる。
今回の経験との接続(私の解釈)
- 設計書を読み切れない状態は、理解負債が溜まり始める入り口だと捉えた
- 設計意図の出力は、実装の前に人が意図を確認する手段であり、理解負債・意図負債に対する予防策として位置づけられると考えた
- 設計意図をADRに残すことは、意図負債の対策として挙がっている手段と重なる
上記の接続は私自身の解釈である。参考記事が、設計意図をAIに出力させる方法を推奨しているわけではない。
今後の対応
実装後の結果の出力は、まだ実施していない。今後の検討事項である。
- 考えていること:設計意図と実装結果を突き合わせれば、意図どおりに実装できているかを判断できる
- 検討している方法:実装後の結果を、処理の流れが分かる形でHTMLにして出力させる。マークダウンよりもスライドに近い表現ができ、見やすく出せるのではないかと考えている
- 現時点の状態:仮説であり、未検証
設計意図と実装結果の差分を確認する運用ができれば、理解負債・技術負債を残さないことにつながると考えている。
軸2:設計意図を出力させていない過去の実装を、後から見直す
この記事は自分の認識を残すメモが主目的だが、この章は、同じように設計意図を残さず進めてしまった人へのアドバイスとしても読めるように書いている。軸1の出力をADRなどに残していれば、この状況は起きにくくなる。
状況
設計意図を出力させないまま、AIとの会話で実装を進めてしまった。後から「なぜこの設計にしたのか」「ここは別の形にした方がよいのではないか」と考え直したくなる。
手がかりになるもの
- 自分が覚えている、当時のAIとのやりとり
- ADR(アーキテクチャ・ディシジョン・レコード):私は当時の判断と理由をADRに残すことが多く、「なぜこの設計にしたのか」を後から確認できる
これらと現在の実装を照らし合わせると、「当時の設計との間に、実はずれがある」「こちらに寄せた方がよい」といった点が見つかり、リファクタリングにつながる。
注意点
コードから設計意図を逆算させることもできるが、そこで出てくる意図は推測である。当時の判断そのものではなく、AIが後から付けた理由かもしれない。ADRや記憶と突き合わせて使うのが安全である。
2つの軸の関係
| 軸1 | 軸2 | |
|---|---|---|
| 場面 | 新機能の開発 | 過去の実装の見直し |
| 設計意図 | 設計の前後で出力させる | 出力させていない |
| 手がかり | AIの出力(要件・設計意図) | 自分の記憶、ADR |
| 自分の扱い | 必ずやる | 軸1をやっていなかった場合の救済策 |
軸2は、軸1をやっていなかった実装に対する救済策という位置づけである。軸1の出力を残していけば、軸2の場面は減っていく。
次に同じ状況になったら
- 新機能の開発では、設計の前後で設計意図(要望の解釈)を出力させる
- 出力された意図を読み、自分の認識とずれていないか確認する
- (今後の検討)実装後の結果を出力させ、設計意図との差分を確認する
- 判断の理由はADRに残す
- 設計意図を出力させていない過去の実装を見直すときは、記憶とADRを手がかりにする。逆算した意図は推測として扱う
