AI Agentの要件は、ユーザーが一件の仕事を頼み、Agentが結果を返す場面から考えると整理しやすい。まずは画面やアプリの中継を省き、両者のやり取りだけを見る。
たとえば「この資料を分析して」という依頼から、分析結果を受け取るまでが1タスク。途中で情報の取得やユーザーへの確認が入っても、同じ依頼を完了するための作業なら同じタスクに含める。図の「4つの処理」は、次の1〜4を指す。
- 出力形式を決める
- 文章、一覧、構造化データ、ファイルなど、何をどの形で返すかを決める。後続の画面や機能が扱える形にする。
- 関連ナレッジを集める
- ユーザーが渡した資料や、その機能に必要な外部・内部の情報を取得する。
- 依頼に応じた処理を実行する
- 集めた情報を使って分析、調査、生成などを行う。必要なら複数の処理を順に実行する。
- 結果を検査し、例外を扱う
- 形式や根拠、機能ごとの制約を確認する。満たせなければ、やり直すか、部分結果や失敗をユーザーに伝える。
順番はこのとおりに実装しなければならない、という意味ではない。要件定義では、各機能についてこの4つを決め忘れないための枠組みとして使う。
ユーザーの指示と、Agentに渡す情報
「ユーザーが仕事を頼む」といっても、毎回自由なチャットを入力するとは限らない。画面で機能を選び、ファイルを添付してボタンを押すだけの場合もある。そのときAgentに渡す依頼文は、機能ごとにアプリ側が用意することになる。
このため、要件上は次の要素を分けて書いておきたい。
| 要素 | 主に用意する側 | 役割・例 |
|---|---|---|
| 画面からの入力 | ユーザー | 機能の選択、入力文、選択肢、添付ファイル。 |
| 機能別の指示と文脈 | アプリ | その機能の依頼文、前の処理の結果、対象ID。 |
| Agentの役割・基本方針 | プロダクト側 | Agentが担う役割と、そのタスクを通じて守るルール。 |
| 関連ナレッジ | Agentが情報源から取得 | 依頼に応じて参照する文書やデータ。 |
| 出力形式 | 機能の仕様で定義 | 返す項目や構造。後続の画面・機能との受け渡し条件。 |
LLM APIに対応させると、機能別の依頼、Agentの役割・基本方針、ナレッジ取得、構造化出力といった要素になる。ただし、どのAPIのロールや関数に置くかは実装の選択だ。仕様では先に、それぞれの情報を誰が用意し、何のために使うかを決める。
system / user / assistant の使い分け
チャット欄のない機能では、何を user の入力とみなすか迷いやすい。私は、そのタスクをChatGPTで自分が実行するなら、何を入力・添付するかと考える。
| 役割 | この考え方での中身 |
|---|---|
system | Agentの役割と、そのタスクの実行中に一貫して守るルール。 |
user | 自分ならChatGPTに入力・添付する依頼、条件、対象資料。画面上ではボタンやフォームの操作だけでも、アプリが組み立てる機能別の依頼はここに含めて考える。 |
assistant | 依頼に対してAgentが返す結果。 |
これは私の整理の仕方で、API上の配置を一律に決めるルールではない。特に、ナレッジの取得方法や出力スキーマの指定方法は、使うAPIと機能に応じて決める。
全体では機能の一覧を作る
ここでいう「機能」は、繰り返し使える仕事の種類を指す。「資料を分析する」が機能なら、資料を渡して分析結果を受け取る一回ごとの実行がタスクになる。
複数の機能があるなら、個別の仕様を書く前に「ユーザーが何を頼めるか」を並べる。たとえば、入力資料を分析する、足りない情報を調べる、案を作る、成果物にまとめる、といった単位だ。
一覧には各機能の依頼、返す結果、次に使う機能を明示する。今回扱わない機能も対象外として残す。ここで境界を決めてから、1機能につき1つの仕様に進むと、似た処理をどこで扱うかが見えやすい。
各機能で決めること
1機能の仕様は、まず以下の粒度で埋める。プロンプト本文や関数名を先に書き込むよりも、ユーザーから見た依頼と結果を揃えることを優先する。
機能要件
| 項目 | 決めること |
|---|---|
| ユーザー指示 | 起点となる操作、ユーザーが渡すもの、アプリが補う機能別の依頼文。何をしてほしいか、何をしてはいけないか。 |
| 出力形式・内容 | 返す項目とその意味、件数、画面での見え方。0件を正常な結果とする条件。 |
| 関連ナレッジ | 使う情報の名前と理由、取得できないときに続けるか止めるか。 |
| 処理内容 | 情報を集めてから返却するまでの流れ。分岐、繰り返し、ユーザーの選択が入る箇所。 |
| 品質チェック | 返す前に何をどう確かめるか。不合格ならやり直す、除外する、人に確認するなどの扱い。 |
| 例外処理 | 入力不足、時間切れ、部分的な成功、処理失敗をどう扱い、ユーザーへどう見せるか。 |
出力形式はJSONの型だけで終わらせない。たとえば「根拠ID」という項目があるなら、何を指すIDか、存在しない場合にどうするかまで決める。Structured Outputsはスキーマへの準拠を助けるが、根拠が入力と一致するかは別に検査する必要がある。
機能別のプロンプト本文を別の場所で管理する場合も、判断基準や禁止事項はこの仕様に残す。プロンプトの置き場所だけを参照して、機能の要件そのものを外に逃がさない。
非機能要件
| 項目 | 決めること |
|---|---|
| 処理速度 | ユーザーが画面で待てる時間。長くなるなら背景実行や進捗表示にするか。 |
| 受け入れ品質 | 人が直す下書きなのか、そのまま使う成果物なのか。代表例で何が返れば採用できるか。 |
外部への送信やデータの書き込みを伴う機能なら、Agentに許す操作と人の承認が必要な場面も追加する。費用やデータの扱いが重要な機能なら、その制約も非機能要件に書く。
仕様を書きながら残すもの
各機能の末尾には、決めたことと理由、未決のことを短く残す。たとえば「入力に根拠がない示唆は返さない」「ナレッジが取得できない場合に部分結果を返すかは未決」といった具合だ。後からプロンプトや処理を変更するときにも、何を守るべきかが分かる。
最初からすべての処理手順を固める必要はない。ユーザーからの依頼と返す結果を起点に、4つの流れと各機能の仕様項目を順に決めていく。そうすると、Agentに任せることと、アプリや人が引き受けることも整理しやすくなる。