はじめに
LLMに要件定義書の初稿を書かせると、章立てが整った文書が、あっという間に出てきます。ただ、整って見えるぶん、中身の抜けや矛盾には気づきにくくなります。
この記事では、初稿を作るためのプロンプトの型と、出てきた初稿を機械的に検査するPythonスクリプト、そして人が見るべきところを書きます。考え方は、機械でできる確認は機械に任せて、文脈がないと判断できない確認は人がやる、というものです。
この記事の流れ
1 プロンプトで初稿を作る (LLM)
2 スクリプトで機械的に検査する (Python)
3 人が通しで読む (暗黙のルール、矛盾)
環境
macOS、Python 3.14.6(標準ライブラリのみ)で動作を確認しています。LLMはClaudeを使っていますが、プロンプトは他のLLMでも使える形です。LLMの出力は毎回変わるので、プロンプトは型としてお使いください。同じ結果になることは保証できません。
1 プロンプトの型
初稿を作るときは、次のように書いておくと、あとの検査がしやすくなります。
次のヒアリングメモから、要件定義書の初稿をMarkdownで作成してください。
# 守ること
- 章立ては、下のテンプレートに従う
- メモに書かれていないことは、推測で書かない。分からない箇所には「要確認」と書き、何が分からないかを1行で添える
- 用語は、下の用語集の表記に統一する
# テンプレート
(章立てをここに貼る)
# 用語集
ユーザー: 「利用者」「使用者」は使わない
# ヒアリングメモ
(ここに貼る)
ポイントは2つです。ひとつは、テンプレートを入れておくことです。誰が使っても同じ章立てになるので、レビューする側が読みやすくなります。もうひとつは、「推測で書かない」と指示して、分からない箇所を「要確認」として見えるようにすることです。抜けを隠さずに残しておけば、あとで人が拾えます。
2 初稿を機械で検査する
出てきた初稿を、次のスクリプトで検査します。見るのは、用語のゆれ、「要確認」の残り、権限に関わる記述の3つです。
検査の対象は、次のような要件定義書です(説明用に作った架空のサンプルです)。
# 受注管理システム 要件定義書(サンプル)
## 1. 画面
### 1.1 受注一覧
- ユーザーは受注一覧を検索できる。
- 管理者のみ、受注を削除できる。
### 1.2 受注詳細
- 利用者は受注の詳細を閲覧できる。
- 担当者は、担当分の受注を削除できる。
## 2. 承認
- 金額が一定以上の受注は、承認が必要である。
- 承認フローの例外(繁忙期の扱い): 要確認
スクリプトは次のとおりです。
#!/usr/bin/env python3
"""LLMが作った要件定義書(Markdown)を、機械的に検査する。
矛盾を「見つける」のではなく、人が確認すべき候補を並べる。"""
import sys
from pathlib import Path
# 正しい表記と、ゆれの候補
GLOSSARY = {"ユーザー": ["利用者", "使用者"]}
# 権限に関わる語。同じ操作について書き方が食い違っていないか、人が確認する
REVIEW_KEYWORDS = ["削除", "承認", "閲覧", "編集"]
MARKER = "要確認"
def main(path: str) -> None:
lines = Path(path).read_text(encoding="utf-8").splitlines()
print("== 用語のゆれ ==")
for standard, variants in GLOSSARY.items():
for word in [standard, *variants]:
hits = [i for i, l in enumerate(lines, 1) if word in l]
if hits:
print(f"{word}: {len(hits)}件 (行 {', '.join(map(str, hits))})")
print("\n== 「要確認」の箇所 ==")
for i, l in enumerate(lines, 1):
if MARKER in l:
print(f"{i}: {l.strip()}")
print("\n== 人が矛盾を確認する候補 ==")
for kw in REVIEW_KEYWORDS:
for i, l in enumerate(lines, 1):
if kw in l:
print(f"[{kw}] {i}: {l.strip()}")
if __name__ == "__main__":
if len(sys.argv) != 2:
sys.exit("使い方: python3 check_requirements_doc.py 要件定義書.md")
main(sys.argv[1])
実行します。
python3 check_requirements_doc.py requirements_sample.md
== 用語のゆれ ==
ユーザー: 1件 (行 6)
利用者: 1件 (行 10)
== 「要確認」の箇所 ==
15: - 承認フローの例外(繁忙期の扱い): 要確認
== 人が矛盾を確認する候補 ==
[削除] 7: - 管理者のみ、受注を削除できる。
[削除] 11: - 担当者は、担当分の受注を削除できる。
[承認] 13: ## 2. 承認
[承認] 14: - 金額が一定以上の受注は、承認が必要である。
[承認] 15: - 承認フローの例外(繁忙期の扱い): 要確認
[閲覧] 10: - 利用者は受注の詳細を閲覧できる。
用語のゆれは、「ユーザー」と「利用者」が混ざっていることがすぐ分かります。「削除」の候補を見ると、7行目では管理者のみ、11行目では担当者もできる、という食い違いが並びます。スクリプトが矛盾を判定しているわけではありません。並べてあるので、人が見つけやすくなります。
3 人が見るところ
機械で拾えないものは、人が確認します。
- 暗黙の業務ルール。たとえば「繁忙期は承認を一部省略する」のような、誰も明文化していないルールは、メモに含まれていない以上、初稿にも出てきません。担当者に「例外的な運用はありますか」と聞くのが確実です。
- 権限の食い違い。上の候補を突き合わせて、同じ操作について書き方が揃っているかを見ます。
- 画面をまたぐ整合。ある画面と別の画面で、前提が食い違っていないかを、通しで読んで確かめます。
- 「要確認」の解消。残っている箇所は、担当者に確認して埋めます。
できないこと
この方法には、次のような限界があります。
- スクリプトは、用語集に書いた語しか検査できません。辞書にないゆれは拾えません。
- キーワードの一致で探しているので、「消去」「取り消し」のような言い換えは拾えません。
- 矛盾の判定は、していません。候補を並べているだけです。
- LLMの出力は毎回変わります。プロンプトの型を使っても、結果が一定になるわけではありません。
- 業務の暗黙のルールは、LLMにもスクリプトにも見えません。
LLMを使っても、人が通しで読む工程は省けません。省くと、形式は整っているのに、中身が矛盾した文書が、そのまま通ってしまうことがあります。
最後に
初稿を作る部分は、LLMで速くなります。その分、確認の工程を決めておくことが大事になります。機械でできる確認と、人にしかできない確認を分けておくと、見落としが減ります。気になったところから、手元の要件定義書で試してみてください。
参考文献
- Python 公式ドキュメント(
pathlib、sys)
この記事はZennにも掲載しています(一部加筆・修正):https://zenn.dev/vaonvn/articles/a6dab104e54ee4