AIコーディングの非機能要件とは?LLMが機能要件ほど得意でない理由と、人が決めるべき基準

AIコーディングの非機能要件とは?LLMが機能要件ほど得意でない理由と、人が決めるべき基準

非機能要件とは、システムが「何をするか」ではなく、「どれだけ安全に、速く、安く、直し続けやすい形で動くか」を決める要件です。Claude Code などのコーディングエージェントは、画面や API を仕様どおりに作る機能要件の実装で、任せられる場面が増えてきました。一方で、セキュリティとソフトウェアのエンジニアである mizutani 氏(@m_mizutani)は X への投稿で、Claude に指摘している内容は「セキュリティ、パフォーマンス、コスト、保守性などの非機能要件まわりが九割」だと書いています。

この記事は、AI に実装を任せ始めたテックリードや開発責任者に向けて、LLM が機能要件を比較的うまくこなせる理由と、非機能要件に人の手が残る理由を、公開されている調査をもとに整理します。そのうえで、人が何を決め、どんな形で渡せば LLM が基準に沿って動くのかを示します。

機能要件と非機能要件はどう違うのか?

機能要件と非機能要件はどう違うのか?

機能要件は「入力に対して何を返すか」を、非機能要件は「その処理がどんな条件のもとで、どの水準で動くか」を決めます。

規格の分類を押さえておくと、AI に何を任せ、どこを人が見るかをチームで話し合うときの共通語になります。

定義と代表的な分類(ISO/IEC 25010 と非機能要求グレード)

たとえば「ログインしたユーザーが自分の請求書を一覧できる」は機能要件です。同じ画面について「一覧は 1 秒以内に返す」「URL を書き換えても他社の請求書は見えない」「月の運用費を一定額に収める」と決めるのが非機能要件です。前者は画面を触れば満たしたかどうかが分かりますが、後者は条件をそろえて測らないと分かりません。

ソフトウェアの品質特性を定めた国際規格 ISO/IEC 25010 は、2023 年版で製品の品質を 9 つの特性に分けています(arc42 Quality Model の解説)。このうち機能適合性を除く 8 つが、おおむね非機能要件の観点にあたります。日本では、IPA(情報処理推進機構)の非機能要求グレードが、発注者と開発者の認識の行き違いを防ぐための項目の一覧として使われてきました。

2 つの分類は切り口が違いますが、どちらも「機能以外の性質」を漏れなく洗い出すための一覧として使えます。

分類観点決める値の例
ISO/IEC 25010(製品品質)性能効率性、互換性、インタラクション能力、信頼性、セキュリティ、保守性、柔軟性、安全性応答時間、同時に扱える利用者数、障害からの復旧、改修のしやすさ
IPA 非機能要求グレード可用性、性能・拡張性、運用・保守性、移行性、セキュリティ、システム環境・エコロジー稼働率、目標復旧時間、バックアップの世代数、移行の期間

非機能要求グレードはシステム基盤の要求を合意するためのもので、アプリケーションのコードの書き方までは決めていません。AI に渡す基準を作るときは、これらの一覧を漏れの確認に使い、自分たちのシステムで意味のある項目だけを数値に落とすのが現実的です。

非機能要件は「横断的」「トレードオフ」「後から現れる」

非機能要件には、機能要件にはない性質が 3 つあります。

1 つ目は、横断的であることです。認可の漏れは 1 つの画面ではなく、テナントの ID を扱うすべての API にまたがります。性能も同じで、1 本の遅いクエリがほかの画面の応答まで引きずります。どのファイルを開いても「ここに書けば完了」という場所がありません。

2 つ目は、トレードオフであることです。可用性を上げれば費用が増え、キャッシュで速くすれば古いデータを見せる時間が生まれます。どこで折り合うかは、止まったときの損失、払える予算、利用者がどこまで待てるかで決まります。正解はコードの中にありません。

3 つ目は、後から現れることです。テスト用の数十件のデータでは、処理の遅さも件数の上限も見えません。攻撃者が送ってくるような入力は、普段の動作確認ではまず入ってきません。非機能要件の欠陥の多くは、設計やレビューの時点では形がなく、本番で違反として初めて姿を見せます。

この 3 つは、次の節で見る「LLM が得意なこと」とちょうど逆を向いています。

なぜ LLM は機能要件を比較的うまく実装できるのか?

なぜ LLM は機能要件を比較的うまく実装できるのか?

機能要件は、正解を入出力で確かめられることが多く、よく知られた実装パターンで解ける場合も多いからです。この 2 つが LLM の強みと重なっています。

正解を入出力で確かめられる

「この入力ならこの出力」と書ける要件は、テストに直せます。テストがあれば、LLM は書いて、走らせて、落ちたら出力を読んで直す、という往復を自分で回せます。Anthropic の Claude Code のベストプラクティスも、合否が返ってくるチェックを渡すことを勧めています。確かめる手段がないと、Claude は「完了したように見える」ことしか判断材料を持てず、結果として人がテストの代わりをすることになる、という説明です。

機能要件は、この往復に乗せやすい性質を持っています。画面の操作、API のレスポンス、計算の結果は、期待する値を先に書いておけるからです。仕様の文章が多少あいまいでも、入力と出力の例を 2〜3 個示せば、LLM はたいてい意図をくみ取ります。人の側も、動かしてみれば合っているかが分かるので、指摘が「この入力でこう返ってほしい」と具体的になります。

裏を返すと、LLM の実装力が上がったと感じる場面の多くは、検証の往復が回っている場面です。同じモデルでも、テストを書けない要件や例を示せない要件では出来が落ちます。そして非機能要件の多くは、そのままではテストを書きにくい側に入ります。

よく知られたパターンで解ける

もう 1 つの理由は、機能要件の多くが、すでに大量の実装例がある問題の組み合わせでできていることです。フォームの入力チェック、一覧のページ送り、CSV の書き出しには、言語やフレームワークごとに定番の書き方があります。LLM は、学習した膨大なコードからその場に合う型を選ぶのが得意です。

この傾向は、セキュリティの調査にも表れています。アプリケーションセキュリティの企業 Veracode は、100 を超える LLM に同じ課題を解かせ、生成されたコードを静的解析で検査する調査を続けています。セキュリティについて何も指示しない条件で、SQL インジェクションを防げた割合は平均 83%、暗号方式の選び方は 87% でした(Veracode「2026 GenAI Code Security Report」)。SQL にはプレースホルダーを使う、古い暗号方式は避ける、といった型の決まった対策は、多くの場合、LLM が指示なしでも選べています。

ただ、同じ報告は、モデルが構文として正しいコードを書く力は伸びた一方で、セキュリティ全体の合格率は横ばいだったとも述べています。平均の合格率は 56% で、最初の報告の 55% からほとんど動いていません。型で解ける部分は伸び、そうでない部分は伸びていない。その「そうでない部分」が、次の節の話です。

なぜ非機能要件には人の手が必要なのか?

なぜ非機能要件には人の手が必要なのか?

非機能要件は、正解がコードの外にあり、欠陥がデータの流れをまたいで現れ、しかも小さなデータでは見えません。LLM が自分で確かめる往復に乗りにくいため、基準を決める人の手が残ります。

正解がコードの外にある

「この API は何秒以内に返すべきか」は、コードをいくら読んでも分かりません。利用者が待てる時間、ピーク時のアクセス数、止まったときの損失、毎月払える運用費で決まるからです。LLM に「速くして」と頼めば、キャッシュを足し、インデックスを張り、処理を並列にもします。けれども、どこまでやれば十分で、どこから先は費用の無駄なのかは判断できません。判断の材料がリポジトリの外にあるからです。

mizutani 氏は続く投稿で、Claude は非機能要件の落としどころを見定め、それをどう実現するかのアイデアを出すのがまだ苦手だと書いています。人がそこまで決めてガイドし、基準を定めれば、ある程度はそれに沿ってくれる。ただ、そこまで持っていくのがまだ大変だ、という見立てです。ここで言う落としどころは、まさにトレードオフの決着点です。

セキュリティも同じ構図です。社内向けの管理画面で多要素認証を必須にするか、操作の記録を何年残すか、個人情報をどの国のサーバーに置くかは、業界の規制、取引先との契約、事故が起きたときに誰が説明するかで決まります。コードの書き方の問題ではなく、組織がどこまでのリスクを引き受けるかの問題で、決める権限も責任も人の側にあります。

データの流れと文脈をまたぐ欠陥は見落とされやすい

前の節で触れた Veracode の調査には続きがあります。SQL インジェクションや暗号では 8 割を超えていた合格率が、クロスサイトスクリプティング(XSS)では 15%、ログインジェクションでは 12% まで下がります。報告は、この 2 つが、データの流れ、アプリケーションの文脈、利用者の入力がシステムの中をどう移動するかの理解に左右されるためだと説明しています。その後の更新で平均の合格率は 62% まで上がりましたが、ログインジェクションはほぼ横ばいのままでした(CybrSec Media の報道)。

XSS を防ぐには、ある関数で受け取った文字列がどこに保存され、どの画面で、どんな形で表示されるかを追う必要があります。ログインジェクションも、入力がいくつの関数を経てログに書かれるかを追わないと見つかりません。どちらも、目の前のファイルだけを正しく書いても防げない欠陥です。

テナントの分離や認可も同じ形をしています。1 本の API を正しく書くことと、すべての API がセッションからテナントを決めていることは、別の問題です。LLM は渡されたファイルの範囲では筋の通ったコードを書きますが、リポジトリ全体で 1 つの約束が守られているかまでは、頼まれない限り確かめません。バイブコーディングの失敗事例で取り上げた、データベースの行単位のアクセス制御を設定しないまま公開された事例も、機能としては動いていたアプリで起きています。

小さなデータでは姿が見えない

性能とコストの欠陥は、開発中のデータ量ではまず現れません。EffiBench という研究は、42 の LLM が書いたコードの実行時間を、LeetCode の課題で人が書いた解答のうち、最も効率のよいものと比べました。当時の代表的な商用モデルでも、実行時間は平均 3.12 倍、最も差が開いた課題では 13.89 倍でした。比べたのは、どれもテストに合格した答えです。正しいけれど遅いコードは、機能のテストをすり抜けます。

手元の開発でも、似たことが起きました。Supabase の API(PostgREST)は、既定で 1 回に返す行を 1,000 行までに制限し、超えた分をエラーなしで切り捨てます。一覧を取って集計する処理は、件数が少ないうちは正しく動いていましたが、本番で行数が 1,000 件を超えたところから一部の行を黙って落とし始めました。気づいたきっかけは、集計の金額が合わないという利用者からの報告です。コードを書いたのが人でも AI でも、件数が増える前提を誰かが決めていなければ、テストは緑のままです。

チームや組織の単位で見ても、傾向は同じです。Google の DORA の調査は、AI の採用が開発のスループットとは正の関係に転じた一方で、本番への配備の安定性とは負の関係が続いていると報告しています。自動テスト、成熟したバージョン管理、速いフィードバックの仕組みがないまま変更の量だけが増えると不安定になる、という説明です(Google Cloud の発表)。

LLM に非機能要件を守らせるには、人は何を決めればよいか?

LLM に非機能要件を守らせるには、人は何を決めればよいか?

人が決めるのは、落としどころの数値と禁止事項、それを判定する方法、そして判定を誰が強制するかの 3 つです。ここまで決めれば、実装の多くは LLM に任せられます。

落としどころを数値と禁止事項で決める

「セキュリティに配慮して」「パフォーマンスを意識して」という指示は、LLM にとってほとんど情報になりません。どの水準なら合格なのかが書かれていないからです。渡すべきなのは、人が判断した結果としての数値と、例外を認めない禁止事項です。

たとえば、次のように書きます。

  • 一覧 API は p95 で 500 ミリ秒以内に返す。1 回に取る件数は 100 件までにして、ページ送りで返す
  • テナントは必ずセッションから決める。リクエストの本文やクエリで受け取ったテナント ID は使わない
  • 外部 API の再試行は 1 リクエストあたり 3 回まで。LLM の API は 1 回の処理で使うトークンの上限を設定する
  • 1 ファイルが 500 行を超えたら、機能を足す前に分割を提案する

数値は最初から正しくなくてかまいません。大事なのは、人がトレードオフを一度引き受けて決めたことが、文章として残っていることです。決めた理由を 1 行添えておくと、LLM が想定外の場面で判断するときの手がかりになり、半年後に数値を見直すときにも役立ちます。項目を漏らさないために、ISO/IEC 25010 や非機能要求グレードの一覧を確認用の表として使うとよいでしょう。

基準を判定できる形にする

決めた基準も、文章のままでは LLM が「たぶん守れています」と自己申告して終わります。合否が機械的に返ってくる形に変えておくと、LLM は機能要件と同じ往復で非機能要件も直せるようになります。

この考え方には名前があります。書籍『進化的アーキテクチャ』の著者らは、アーキテクチャの特性を客観的に評価する仕組みを「アーキテクチャのフィットネス関数」と呼んでいます(Thoughtworks Technology Radar)。単体テストだけでなく、メトリクスや監視まで含む広い考え方です。

非機能要件ごとに例を挙げます。性能なら、代表的な API を本番に近い件数のデータで呼び、p95 が基準を超えたら落ちるテスト。認可なら、別テナントのユーザーで全 API を呼び、1 件でもデータが返ったら落ちるテスト。保守性なら、ファイルの行数や依存の向きを調べるスクリプト。コストなら、1 回の処理で外部 API を何回呼んだかを数えるテスト。セキュリティなら、静的解析(SAST)と依存ライブラリの脆弱性検査を CI に入れます。

どれも、一度作っておけば LLM が自分で走らせて結果を読めます。レビューで毎回同じ指摘をしている項目があれば、それが判定の仕組みに変える最初の候補です。

「読ませる指示」と「強制する仕組み」を分ける

判定の仕組みを作っても、それを走らせるかどうかを LLM に任せると、走らせない回が残ります。Claude Code のベストプラクティスは、指示を 2 種類に分けています。プロンプト、CLAUDE.md、スキルのように、モデルが読んで従うかどうかを決める指示と、hook、deny ルール、CI のように、モデルの判断と関係なく毎回実行される仕組みです。前者は「たいてい従う」けれど保証はなく、例外を許さない規則は後者に移すよう勧めています。

例外を認めない基準は強制する仕組みに、状況によって判断が変わる指針は読ませる指示に置きます。

置き場所向いている基準の例
CLAUDE.md・スキル(読ませる指示)命名や分割の方針、ログの書き方、キャッシュを使ってよい場面
hook・deny ルール(強制)秘密情報のファイルを読まない、生成物のディレクトリを編集しない、編集のたびに整形を走らせる
CI・ブランチ保護(強制)型検査、認可のテスト、性能のテスト、依存の脆弱性検査、人の承認がないとマージできない

手元の開発環境でも、env ファイルの読み取り、開発サーバーの起動、編集先リポジトリの取り違えは、CLAUDE.md に書くだけでなく hook で止めています。どれも 1 回起きると影響が大きく、「ほとんど守られる」では足りない規則です。反対に、強制する規則を増やしすぎると、誤検知と保守の手間が積み上がります。公式のドキュメントも、強制する規則は少なく保ち、好みの問題は LLM の判断に任せるよう書いています。hook の設定方法は Claude Code チーム導入ガイドで扱っています。

観点別に見る:LLM に任せる範囲と人が持つ範囲

観点別に見る:LLM に任せる範囲と人が持つ範囲

非機能要件を 5 つの観点に分けると、LLM に任せやすいのは「決まった基準を満たす実装」で、人が持つのは「基準を決めること」と「基準の外で起きる例外の判断」です。

観点LLM に任せやすい作業人が決めること判定の仕組みの例
セキュリティ入力チェックやエスケープの実装、定番の暗号ライブラリの利用守るデータの分類、認可のモデル、引き受けるリスク別テナントでの認可テスト、SAST、依存の脆弱性検査
性能インデックスの追加、N+1 クエリの解消、ページ送りの実装応答時間の目標、想定するデータ量とアクセス数本番に近い件数での負荷テスト、p95 の監視
コストキャッシュやまとめて処理する形への書き換え月の予算、1 リクエストあたりの上限外部 API の呼び出し回数のテスト、利用額のアラート
保守性分割、命名の統一、テストの追加層の分け方、依存してよい向き、許す複雑さ行数や依存の向きの検査、型検査
可用性・運用再試行やタイムアウトの実装、ログの出力止まってよい時間、復旧の目標、障害時に誰が対応するか障害を起こして確かめるテスト、監視とアラート

表の右 2 列が埋まっていれば、左の列の作業はかなり LLM に任せられます。逆に、真ん中の列が空いたままだと、LLM はもっともらしい値を自分で置いて実装を進めます。想定するデータ量を決めないまま一覧画面を頼めば、全件を取ってから画面側で絞り込むコードが出てきても不思議ではありません。小さなデータでは何の問題もなく動くからです。

レビューで人が確かめる問いも、この表から作れます。まず、この変更が決めた基準のどれに関わるか。次に、その基準を判定する仕組みを今回の変更が通ったか。そして、基準に書いていない判断を LLM が勝手に下していないか。最後の問いだけは機械に置き換えにくく、人が持ち続ける部分になります。

よくある失敗と避け方

よくある失敗と避け方

非機能要件を LLM に渡すときの失敗は、基準があいまいなまま渡すことと、テストが通ったことを非機能の合格と取り違えることに集まりがちです。

「セキュリティに注意」と書いて終わる

CLAUDE.md に「セキュリティに十分注意すること」「パフォーマンスを意識すること」と書き、それで非機能要件を伝えたつもりになるのが、いちばんよくある失敗です。LLM はこの一文を読んでも、何をどこまでやれば合格なのかが分かりません。結果として、目に見えやすい対策(入力のエスケープ、例外処理)は増えますが、認可の一貫性やデータ量への備えのような見えにくい部分は残ります。

先に挙げた Veracode の数字も、セキュリティについて何も指示しない条件で測ったものです。何も言わなければ、4 割前後の課題で既知の脆弱性が入る前提で考えておく必要があります。そこに抽象的な一文を足しても、データの流れを追わないと見つからない種類の欠陥まで防げるとは限りません。

避け方は、注意書きを基準に置き換えることです。「テナントはセッションから決める」「画面に出す値は必ずテンプレートのエスケープを通す」のように、守ったかどうかを人が読んで判断できる文にします。そのうえで、その文を判定するテストか検査を 1 つ用意します。CLAUDE.md の 1 行を「重要」「絶対」で強めても守られないなら、それは強制する仕組みへ移す合図だと、公式のドキュメントも書いています。

テストが通ったことを非機能の合格とみなす

LLM が「テストはすべて通りました」と報告すると、変更全体が正しいように感じます。ところが、そのテストの多くは機能要件のテストです。正しいけれど遅いコードも、正しいけれど別テナントのデータまで返すコードも、機能のテストは通ります。

この思い込みは、人の側の自信を強める方向にも働きます。スタンフォード大学の研究では、AI アシスタントを使って課題を解いた参加者は、使わなかった参加者より安全でないコードを書き、しかも自分のコードは安全だと答える傾向が強くなりました(Perry ほか「Do Users Write More Insecure Code with AI Assistants?」)。AI が書いたコードは、読み手に「ちゃんとしていそうだ」と思わせる見た目で出てきます。

避け方は 2 つあります。1 つは、完了の報告に「どの基準の判定を通したか」を含めてもらうことです。走らせたコマンドと出力を貼ってもらえば、非機能のテストが走っていないことにすぐ気づけます。もう 1 つは、非機能のテストを CI に入れ、通らなければマージできないようにすることです。そうすれば、報告を信じてよいかを人が毎回判断せずに済みます。権限やレビュー、停止の設計まで含めた全体像は、AI エージェントのガードレール運用チェックリストにまとめています。

AIコーディングの非機能要件に関するよくある質問

AIコーディングの非機能要件に関するよくある質問

AI に実装を任せるときによく出る 3 つの質問に答えます。

Q1: AIが書いたコードのセキュリティレビューは、人が全部見る必要がありますか?

いいえ、全部を同じ深さで見る必要はありません。型で防げる部分(SQL の組み立て、暗号ライブラリの使い方)は SAST と依存の検査に任せ、人はテナントや権限を判定する箇所と、利用者の入力を画面やログに出す箇所に絞って見てください。

Q2: 非機能要件の定義そのものをAIに書かせてもよいですか?

叩き台としては役に立ちます。システムの種類、利用者の規模、扱うデータの種類を伝えれば、非機能要求グレードのような項目に沿って、確かめるべき観点と仮の数値を一通り挙げてくれます。移行するデータの量やバックアップの世代数のように、自分たちでは思いつかなかった観点が出てくることもあります。

ただし、その数値で決めてよいかは別の話です。たとえば目標復旧時間を「1 時間以内」にするか「翌営業日まで」にするかで、必要な構成も運用の費用も大きく変わります。どちらが正しいかは、止まったときに失うものと払える費用を比べないと決まりません。AI の案は抜けの確認に使い、数値を確定させるのは、その比較を説明できる事業と運用の責任者にしてください。

Q3: モデルが新しくなれば、非機能要件もAIに任せられるようになりますか?

実装の側は、任せられる範囲が広がっていくはずです。Veracode の直近の更新でも平均の合格率は上がり、型で防げる種類の欠陥から改善が進んでいます。一方で、どこまで速く、どこまで安く、どこまで守るかという落としどころは、モデルの性能ではなく事業の条件で決まるので、モデルが替わっても人の側に残ります。基準を判定できる形で残しておけば、モデルを替えた日にもそのまま効きます。

まとめ

まとめ

LLM が機能要件を比較的うまく実装できるのは、正解を入出力で確かめられ、よく知られたパターンで解けることが多いからです。非機能要件に人の手が残るのは、正解が事業や運用の条件というコードの外にあり、欠陥がデータの流れをまたいで、大きなデータや本番の状況でしか姿を見せないからです。

mizutani 氏もその後の投稿で、いまのソフトウェアエンジニアに求められる技量として「非機能要件をいかにうまく設計・実装できるか」がより重要視されていくだろうと書いています。

人が担うのは、実装の細部をすべて見張ることではありません。落としどころを数値と禁止事項で決め、それを判定できる形にし、例外を許さない部分は hook や CI で強制することです。ここまで整えれば、非機能要件の実装も、機能要件と同じ往復で LLM に任せられる範囲が広がります。まずは、レビューで何度も同じ指摘をしている項目を 1 つ選び、基準の文と判定のテストに変えるところから始めてみてください。AI エージェントの失敗を仕組みで防ぐ考え方は、ハーネスエンジニアリングとは?でも詳しく解説しています。

当社では、コーディングエージェントを使った開発の進め方や、非機能要件の基準づくりも支援しています。ご相談は AI・DX 支援からお寄せください。

著者・監修者

Yusuke Ishihara

Yusuke Ishihara

13歳でMSXに触れプログラミングを開始。武蔵大学卒業後、航空会社の基幹システム開発や日本初のWindowsサーバホスティング・VPS基盤構築など、大規模システム開発に従事。 2008年にサイトエンジン株式会社を共同創業。2010年にユニモン株式会社、2025年にエニソン株式会社を設立し、業務システム・自然言語処理・プラットフォーム開発をリード。 現在は生成AI・大規模言語モデル(LLM)を活用したプロダクト開発およびAI・DX推進を手がける。