はじめに
NewsPicks で QA エンジニアをしています、西薗(@yurizono)です。本稿では、私が取り組んでいるAI4QAの話をします。
私なんかよりよっぽどしっかりしたコードを書いてくれるLLM君ですが、QAっぽいタスクになった途端、頼りなく見えます。これは私がQAエンジニアで自分の仕事に誇りを持っているからなのか、それとも何かうまくいかない理由があるのか。私のたどり着いた結論を一言で表すと「プロダクトに特化したコンテキストの整備が足りていなかった」です。
QAチームの現状
我がQAチームはテストをすることもあるのですが、ツール提供や基盤整備、つまり開発者による開発プロセスにアプローチをして品質向上を目指すこと、が主な活動です。
今年の初めにSREとQAのチーム合併があり、西薗個人としてはSRE領域にも手を伸ばしていこうということでNewsPicks Web版のインフラ改善をしていました。慣れないCDKを書き、慣れないインフラリリースをして、何度か障害を起こしたりしました(立場が変われば……)。この過程で、私自身も開発エンジニアとしてAIを使い倒しまして、なんとかみんなの使っているClaude Codeがどういうものかが掴めた気がします。結論、もはやコーダーとしての私の存在意義は残っていませんでした。これは勝てない。
そんな感じで見習いSREとしてしばし楽しませて頂いたところで、そろそろこの頼れるAIを本職の方で使っていこうと、この春から新たな活動を始めました。それがAI4QA(エーアイフォーキューエー)です。AIをQAプロセスで使っていこう、ってやつですね。もはや開発現場では当たり前の概念かと思いますが、そこへの私なりの取り組み方についてお話しします。
問題意識
プロジェクトの議事録や仕様書をインプットにして、AIにテストケース作成をさせたことがありました。結果、それなりにテストケースっぽいものは生成してくれてこりゃ便利だなぁと思ったのですが、いざそれをレビューしてみるとチラホラ見つかる観点漏れ。まだまだ人間の仕事はなくならないんだな、と少し残念に思うと同時に、どうやったら満足のいくクオリティのものを出してくれるのだろうか、という試行錯誤が始まりました。
気づいたこと
冒頭でも述べた通り「プロダクトに特化したコンテキストの整備が足りていない」ことに気付きました。
さきほどのプロジェクトの例では、プロジェクトの内容についてのコンテキストはある程度揃っていたものの、それ以外の、プロジェクトの外にあるコンテキストが不足していました。つまり、これから作る機能がどういうものかは把握できていて、それに対するテストケースは作れる。しかし、では既存機能への影響はみれているのか、仕様書で言及されていないユーザー種別に関しての考慮は漏れていないか、というと不足だらけだったというわけです。
コンテキストとは
この文脈でいう「コンテキスト」ですが、LLMへ直接投げる指示文を「プロンプト」と呼び、それ以外にLLMが読み込んだり把握しているもの全てを「コンテキスト」と呼びます(あくまで私の理解です)。人間に例えると、プロンプトが仕事の依頼だとすれば、コンテキストとは「ベテラン社員が持つ知識を新人に叩き込むためのオンボーディング資料」のようなものです。つまり、いろんな仕事の前提となる知識です。
昨今のLLMは優秀なエンジニアだと思いますし、コードベースがあって仕様をうまく伝えられれば、少なくとも私レベルの開発者にとってはコーディング部分をまるっとお任せできてしまうレベルです。コーダー廃業はもはや避けられません。一方で、QA廃業という話は現時点で聞こえてきません。ここに非対称性が存在します。
なぜコーディングが任せられるかというと、「人間離れした速度でコードを書けるから」でも「コーディングが単純なタスクだから」でもありません。コーディングを任せる場合、コードをLLMに渡していて、かつ「コードを読めばそのコードで何をしているかが分かるから」です。What に限定すれば、正解がそこにある。
当然、チーム構成によって採用すべき設計は変わりますし、コードに表現しきれていない思想もあるでしょうから、コードの外の知識が必要なシーンは多いはずです1。いまはそういう知識をPRレビューなどを通して人間が補完している状態だと思いますが、現時点で「LLMがコーダーとして使い物になる」ことは疑いようもありません。
ではQA活動、例えばテストケース作成はどうでしょうか(ここでは一般的なQAエンジニアが作るレベルのテストケース、例えば統合テストを想定)。仕様書をLLMに渡したとして、「あ、その観点は抜けてました」と開発者に気付きを与えられるレベルのテストケースが出てくるでしょうか。過去の数多くの障害をその身で経験し、普段からアプリを使っていて機能に詳しく、各チームが進めている開発案件を横軸で抑えている、そんなQAエンジニアが行うテスト設計がAIで代替できるでしょうか。……私の実感としても、まだ難しいのかなと感じました。
仕様書に書かれた内容に閉じたテストを作る、というタスクに限定すれば、すでに代替可能です。この点はコーダーと事情は変わりません。ただし、コーディングについては「リポジトリをまるっと渡す」、もっと言えば「リポジトリをチェックアウトしたディレクトリでClaude Codeを起動する」だけで膨大なコンテキストをLLMに渡せる(実際に読むかどうかはさておき、読める状態にはなる)のに対して、テストケース作成となると途端に「仕様書ペラ一枚」になってしまう、というのが現状かと思います。つまり、我々が特段意識せずに渡せるコンテキストのサイズに、コーディングとテストケース作成では大きな差があるわけです。
上記ではテストケース作成という例を出しましたが、仕様書レビュー、設計の壁打ち、バグ管理などあらゆる場面でこのコンテキストが効いてきます。何せプロダクト特有のコンテキストがなければ施策立案にせよデータ分析にせよ、前提となる知識なしに立ち向かうこととなり、非効率です。期待した性能も出し切れません。
AIと付き合うには、コーディングとコーディング以外のタスクとの間にあるこの差を埋める必要があります。
仕様はどこにあるのか
膨大なコンテキストをLLMに渡せばよいのだ、ということが分かったところで、ではそれをどうやって渡すのかを考えます。コンテキストといっても、既存仕様、改修内容、過去の障害情報など種類はいくつか必要そうです。改修内容を渡さずにテストケースを作らせる人はいないでしょう。障害は昔からチケット管理システムを使うのが当たり前でしたから、MCPで繋ぐなりすれば解決しそうです。なら、既存仕様はどうしましょうか?ふたつ思いつきました。
①これまでに作られた仕様書を全て渡す
ペラ一枚に比べるとマシですね。今回のプロジェクトのスコープ外の仕様が手に入ります。ただし、コードと違って作成日が一年前の仕様書はおそらく役に立ちません。その仕様書をインプットに書かれたコードはすでに書き換えられている可能性が高く、また仕様書自体はおそらくメンテナンスされていません。つまり、嘘が混じっていますから、出てきたテストケースの前提も全て疑ってかかる必要があり、人間のレビュー工数が大変なことになるでしょう。
全ての仕様書を積み上げればそれが今の仕様になる、と私も考えたことはありますが、弊社の場合、現実問題そうはなりません。仕様を書かずにコードを変えることなど日常茶飯事だからですね。また、バグと違って仕様書は統一された書き方・置き場が決まっていないことが多いでしょうから、そもそも全てを集めてくること自体が困難でもあります。
②コードを全て渡す
これまた悪くありません。仕様書とちがってさすがにコードの全ては直ちにアクセス可能な場所にあるでしょうし、なにより、コードは嘘を吐きません。ただし、コードというのは「現時点でどう振る舞うか」しか教えてくれません。テストというのは「どう振る舞って欲しいか」、つまり仕様や要求をもとに作らなければ意味がありません。要求された機能が漏れなく間違いなくコードに落ちているかを確認するのには、コードだけではどうしたって不十分です。
仕様DBを作ろう
今回、私がとったアプローチがこちらです。仕様を表現した短い文言、社内ではユーザージャーニーと呼んでいますが、これをたくさん集め、それを検索可能な形で(Notion DBに)格納しました。
「いやさっき『仕様書はメンテナンスされない』って言ってなかった?」というツッコミが来そうですが、キモはそこで、メンテナンス可能な粒度でしか端から作りません。仕様変更があった際には私たちQAエンジニアが変更を手で反映しています。
具体例を出すと『有料課金したユーザーは有料記事にコメントができる』『有料課金していないユーザーは動画をバックグラウンド再生できない』といった粒度です。細かな画面仕様や、複雑な条件の組み合わせまでは網羅しません。
仕様変更があれば、それをリリースノートの定期チェックや、依頼されたテストを行う過程で拾い上げ2、『有料課金していないユーザーも動画をバックグラウンド再生できる』という仕様に書き換えたりするわけです。
仕様DBをコンテキストとして渡そう
あとはその仕様DBをLLMに渡せば、かなり良い具合に仕様書レビューをしてくれたり、テストケースを作成したりしてくれるようになりました。例えば仕様書に書かれていない既存機能へのリグレッションを指摘したり、過去発生した障害に関連したテストケースが出てきたり。
当初は、ただのユーザージャーニーの寄せ集めだとうまく動かないだろうと考えていました。タグを振る、構造化する、前提知識を別途書き起こすなどが必要で、レビューなどの精度向上に効果が出てくるのはそれらが揃ってからだろう、と。
しかし、互いにバラバラなユーザージャーニーの寄せ集めDBをMCPで繋いだだけで、それなりに動いてくれました。LLM自ら目的に照らして仕様DBを自然言語で検索し、検索結果をサマったり比較したりしながら、タスク実行に必要な知識を構築してくれます。少し前はこれだけでは上手くいかず、実際に私も同じDBをつかってRAGを組んだりしていましたが、最近はもはやDBへのアクセスを提供するだけでよしなに使ってくれるようです。AIの進化は恐ろしいですね。
なお技術的な話をし始めると長くなるのでここではしませんが、Notion MCPで繋いでいて、レート制限を超えないように調整をかけたり、できる限り一度で検索を済ませたりといった工夫はさせています。たまに失敗することはありますが、およそうまく動いているようです。ただ、動作速度に満足できなかったので、さらなる高速化を進めています(その話はまた改めて)。
NewsPicksではこれをClaudeのPluginにし、社内Marketplaceで配布しています。ただ配るだけだと使ってくれませんから、私が社内に営業して回り、少しずつユーザーを増やしているところです。
メンテナンスについて
この仕様DB、メンテナンス可能な粒度でしか作らない、と言いましたが、これはあくまでAI導入前の世界を前提とした設計です。そもそもこの仕様DB自体、AIに食わせるために設計・構築したものではなく、人間が使うために2022年ごろから私が作り始めたものです(テストカバレッジはテストの家計簿だよねって話)。今ならAIをうまく使ってメンテナンスが回せるはずなので、最近はAIを使った自律的な仕様DBのメンテナンスに取り組んでいます。これについてはもう少し成果が出てきたら、また記事にしようと思います。
用語について
以上で語ってきた内容ですが、いわゆる「コンテキストエンジニアリング」と呼ばれる内容が主となっているかと思います。こう書くと流行りに乗っただけの陳腐なものに見えてしまうので、あえて本稿ではボトムアップに書きました。が、ご参考まで。
おわりに
テスト設計や仕様レビューはまだAIには難しいでしょ、と思って安心しきっているQAエンジニアの方がもしいらっしゃるなら、少し焦った方が良いかもしれません。もしかすると、我々が十分なコンテキストを設計しきれていないだけで、それさえしっかり渡してあげれば、我々よりも優れた成果物が数ドルで手に入る時代がすでに来ているかもしれません。