この記事はCodeRabbitのBlogを日本語に翻訳したものです。 ( https://www.coderabbit.ai/blog/coderabbit-deep-dive )
私たちはいま、ソフトウェア開発業界における大きな転換点に直面しています。
世界中の開発者が、AIがもたらす驚くべき可能性に気づき始めました。
GitHub CopilotやChatGPTの登場はソフトウェア開発を革命的に変えました。これらはソフトウェア開発の歴史上で最も急速に普及したツールだと言っても過言ではありません。
しかし、コード生成の分野では多くのツールが登場している一方、コードレビューのプロセスはほとんど変化していません。10年前と同じツールやプロセスを今も使い続け、依然としてコードを手作業でレビューしています。
このフローは生産性を下げ、ミスが起こりやすく、コストもかさみます。
そこで私たちは、PR上またはCI/CDプロセスの一部として動作するAIコードレビューツール「CodeRabbit」を開発しています。
CodeRabbitのビジョンはプロダクト開発のプロセスを高速化し、人間のレビュアーや既存のリンターツールだけでは実現できない高いコード品質を提供することです。
高品質ソフトウェアを出荷するうえでの障害
一般的な開発者はコードを書く時間と同じくらい、レビューのための時間も費やしています。
一般的な開発の流れとしては、メインのコードベースからブランチを切り、新機能の開発やバグ修正を行い、その後メインのブランチにコードをマージします。
開発者がソフトウェアを書く際には、Visual Studio Codeのような最新エディターを使い、洗練された言語サーバーや静的解析ツール、Linterを活用します。
さらに最近では、GitHub CopilotのようなAIを活用した拡張機能も急速に普及しています。
これらのAIのよるソリューションが提供されているとはいえ、開発者ごとにローカルツールが統一されていないこともあり、基準を徹底することが難しいため、品質を保証するには不十分です。
そのため、エンジニアによって書かれたソースコードはGitHubやGitLabのようなプラットフォームでプルリクエスト(PR)という形で共同レビューされます。PRが作成されると同時にCI/CDプロセスが始まり、Lintやビルド、テストを実行します。
とりわけ重要なのは、ピア(同僚)によるコードレビューで、変更の意図を理解するだけでなく、コーディング規約やセキュリティ上の脆弱性など様々な観点からソースコードをチェックします。
また、レビューには変更内容を理解するだけでなく、プロジェクト全体への影響を評価する広い視点が求められます。
最終的にレビュアーがPRを承認すると、コードはメインのコードベースにマージされます。
もちろん、コードレビューは品質確保だけでなく、コンプライアンスや規制要件を満たすうえでも必須です。
理想的なコードレビューの流れはスムーズで効率的に進むはずですが、現実には多くの課題や非効率が存在します。特に、手動のレビューは開発プロセスのなかで最も遅い部分となりがちです。場合によっては、PRのマージに数日から数週間かかることも珍しくありません。以下に、その主な問題点をまとめます:
- チーム全体の遅延: コードレビューやマージを待つ時間は、個々の開発者だけでなくチーム全体に影響します。プロジェクトのスケジュールが伸び、機能リリースやバグ修正の遅れにつながります
- コンテキストスイッチ: 開発者はコーディングからレビュー待ちに移る際に作業の文脈を失いがちです。再びコードに戻る際、生産性が下がります
- 形だけのレビュー(Rubber-Stamp Reviews): 機能不全なチームでは、レビューが形骸化していることがあります。レビュアーがコードをしっかりチェックせずに承認してしまい、バグや脆弱性が見逃されることもあります
- 個人的な衝突: 時には、開発者とレビュアーの間でコード品質以外の要因による摩擦が起こり、必要以上に細かい指摘をされてレビューが長引くこともあります。これによってチームの関係が悪化し、チームの士気に影響を与えることもあります
- 仕事への不満: コードマージの遅延や非効率が続くと、開発者はモチベーションを失い、退職を検討する可能性が高まります。企業としても人材流出のリスクが高まります
要するに、現在の状況は最適とは言えず、頻繁に発生するソフトウェアのバグ、セキュリティ脆弱性、サービス障害が、その現状を証明しています。
CodeRabbitでコードマージを10倍速く
CodeRabbitはAIを活用したコードレビューツールで、コードレビューのプロセスを劇的に高速化すると同時に、コードの品質を向上させます。
プルリクエストのワークフローにシームレスに統合され、開発者やレビュアーと協調しながらコードの品質を担保します。既存のリンターや静的解析ツールだけでは見つけられない問題や改善点も、人間に近い感覚でコードの目的を理解し提案します。
CodeRabbitを使えば、開発者は数分以内にコンテキストを考慮したフィードバックを受け取り、それをもとにベストプラクティスに沿った修正を行い、より早くマージ準備を整えることができます。また、レビュアーにとっても、CodeRabbitが自動生成するコード変更の要約や提案のおかげで、レビューに対する自信と速度が向上します。開発者、ピアレビュアー、そしてCodeRabbitの3者が共同作業することで、レビューの質が向上し、時間と労力の節約につながります。
CodeRabbitは生成AI(Generative AI)の上に構築されており、以下の主要な機能を提供します:
- 要約(Summarization): CodeRabbitはPR内のコード変更を要約し、高レベルな概要を提示します。これにより、レビュアーやプロダクトチームは変更内容とプロダクトへの影響を素早く把握できます
- インクリメンタルレビュー(Incremental Reviews): CodeRabbitは各コミットのたびにコードをしっかりレビューし、開発者に対して段階的なフィードバックを提供します。問題点や改善点を見つけ、あたかも人間のレビュアーのようにコードにコメントを付けてくれます
- 変更内容に関するチャット(Chat about changes): CodeRabbitは会話形式のインターフェースを備えており、開発者やレビュアーは変更内容の文脈で質問をしたりコードを生成したり、フィードバックを得ることができます
CodeRabbitの設計
レビューのプロセスは複数のステージに分かれており、下図のように進行します。開発者がプルリクエストを作成、または既存のプルリクエストにコミットを追加したタイミングでCodeRabbitのワークフローが起動し、さまざまな要約ステージとレビューステージが続きます。
CodeRabbitは単なるLLM(大規模言語モデル)へのパススルーではありません。
コンテキストウィンドウの制限を回避するために、CodeRabbitは革新的なマルチLLM&マルチステージのアプローチを採用し、大規模な変更セットにも対応できるように設計されています。AIベースのコード補完ツールとは異なり、コードレビューはより複雑な問題です。
レビュアーは開発者よりも広い文脈を理解する必要があり、単なる表面的な問題を見つけるだけでなく、プルリクエスト全体の意図や多くのファイルにまたがる変更点を把握しなければなりません。以下に、私たちが直面した課題とその解決策を示します:
- コンテキストウィンドウのサイズ: LLMにはコンテキストウィンドウがあり、たとえばgpt-3.5-turboは4Kまたは16Kトークン、gpt-4は8Kトークンの上限があります。これは大きな変更セットを扱うには不十分な場合があります。そこで、ファイルごとに要約を用意したり、優先度を考慮して必要な情報をリクエストごとに効率的に詰め込むなどの工夫を行っています
- 構造化されたコンテンツの入出力: LLMは、構造化データや数学的計算の扱いが苦手です。私たちは、標準のunified diff形式ではなく、人間が変更を理解するのに近い形式で入力を与えるなど、入力フォーマットを工夫しました。また、期待する出力を得るために数ショット例を提示する技法を用いています
- ノイズ: LLMはノイズとシグナルの区別が苦手です。たとえば「20個の提案をして」と頼めば本当に20個の提案が返ってきますが、そのうち有用なものは少数ということもあります。とりわけコードレビューでこの問題は顕著です。私たちは、複数ステージを経てレビューを行い、有用な情報を強化しノイズを除去する仕組みを設計しました
- コスト: gpt-4のような高機能モデルは非常に優秀ですが、gpt-3.5-turboなどのシンプルなモデルと比べると何桁もコストがかかります。私たちは、要約作業にはシンプルなモデルを使い、コードレビューのような複雑なタスクには高機能モデルを使うというマルチモデルアプローチを導入しています。また、シンプルなモデルはトリアージ機能を担い、重要度の高い変更だけを高機能モデルが詳細にレビューする仕組みを整えています
- 不正確さ: LLMは万能ではなく、不正確な結果を返したり、指示を無視して全く別の回答を返すこともあります。私たちは、LLMとの「いたちごっこ」を続けるのではなく、LLMが返す結果を検証・修正し、ユーザーには誤りの少ない結果を提示する仕組みを導入しています
- データプライバシー: ユーザーの最大の懸念は、自分のコードが学習データとして保存・再利用されるのではないかという点です。私たちはLLMへのクエリはすべて一時的に扱い、サービス上では即座に破棄する設計にしました。一方で、継続的なレビューを行うにはある程度の状態管理が必要です。そこで、可能な限り状態をプルリクエスト自体に保存し、弊社サービス側に保持しない仕組みを考案しました。これにより、最大限のプライバシーを確保しています
結論
LLMの上にソフトウェアを構築するという分野はまだ新しく、かつてMS-DOSがIBM PCやIntelのマイクロプロセッサ上に作られた頃と多くの共通点があります。
当時のコンピュータはメモリが限られていましたが、その制約の中で画期的なアプリケーションが誕生しました。現在のLLMにおけるコンテキストウィンドウの制限も、それと同様に革新的な工夫を促す原動力になっています。初期の3Dゲームが限られたPC資源を巧みに活用していたように、LLMの能力を最大限に活かすための技術や手法が重要になってきています。
さらに、LLMやAIインフラストラクチャ(ベクターデータベースなど)は急速にコモディティ化が進む一方で、その上で差別化を図るアプリケーションには大きな価値が生まれるでしょう。また、モデルのトレーニングとプロンプト(Few-Shot例やファインチューニングなど)の境界はどんどん曖昧になっています。こうした技術を巧みに組み合わせることで、得られる結果の品質に大きな差が生まれ、その点が今後のプロダクトの差別化要因となるでしょう。
CodeRabbitでは、こうしたイノベーションの最前線で、AIを中心に据えた開発者向けツールをゼロから構築しています。
既存のリンターや静的解析ツールとは大きく異なるアプローチを取り、まったく新しい視点で問題を解決しようとしています。AIはまだ多くの制限がありますが、実用に耐えるレベルに達してきた今こそが転換点であり、その限界を逆手に取ってイノベーションを起こすチャンスだと考えています。
今後の私たちのロードマップには、AIの可能性を最大限に引き出すためのさらなる開発や改良が盛り込まれており、近い将来にお客様に大きな価値を提供できると確信しています。