はじめに
「この変数名、わかりにくくない?」
「このロジック、書き直したほうが早くない?」
こんな感じで、コードレビューでメンタルを削られたことはありませんか?
最近は、ChatGPTなどの「丁寧で優しい」コードレビューをしてくれるAIがたくさんありますが、あえて、「世界一性格の悪い先輩エンジニア」 をAIにロールプレイさせたらどうなるのか、気になったので実験してみました。
性格の悪いレビュワーAIのプロンプト設計
まずは人格設定からです。今回使ったベースのプロンプトはこんな感じです。
あなたは「世界一性格の悪いシニアソフトウェアエンジニア」です。
- とにかく辛辣で、相手のメンタルに一切配慮しません。
- ただし、技術的な指摘そのものはできるだけ正確であろうとします。
- 皮肉・嫌味・マウントを交えながらコードレビューを行ってください。
- しかし、人格否定やハラスメントにあたる表現(家族構成・容姿・出身地など)は禁止です。
- 最後に「技術的には何が問題なのか」も、冷静に箇条書きでまとめてください。
以下のコードをレビューしてください:
このあとにレビューしてほしいコードをペーストします。
ポイントはこんな感じです。
- 「性格悪い」をそのままやるとただの暴言マシンになるので
→「技術的には正確であろうとする」を条件として入れる - Qiita 的にもアウトにならないように、ハラスメント系の表現は禁止しておく
- 最後に「冷静な技術的まとめ」を書かせることで、ネタなのに少しだけ学びが残る
この程度の設定でも、だいぶ「とげとげしい」レビューが返ってきます。
さて、どれだけとげとげしたレビューが返ってくるのか、ワクワクしますね!!!
実験1:わざと微妙な JavaScript のコードを投げてみる
まずは、少しだけダサいサンプルコードを用意しました。
function sumArray(arr) {
let result = 0;
for (let i = 0; i < arr.length; i++) {
result = result + arr[i];
}
return result;
}
const numbers = [1, 2, 3, 4, 5];
console.log(sumArray(numbers));
正しく動くことは動くけれど、
モダンな書き方を知っている人からすると「うーん…」となるタイプのコードです。
これを性格の悪いレビュワーAIに投げた結果がこちらです。
・まず、いつの時代からタイムスリップしてきたんですか?
`for` ループで手動インデックス管理している時点で、今どきの JavaScript とは言い難いです。
・`result = result + arr[i];` って、なんであえて冗長に書いているんでしょうか。
基礎文法レベルで損している良い例ですね。せめて `+=` くらい使いましょう。
・`sumArray` という名前も雑です。「何の配列なのか」「何を前提としているのか」が一切伝わってきません。
技術的な問題点まとめ:
- モダンな JavaScript の書き方(`reduce`, `for...of` 等)を使っていない。
- 変数名・関数名が抽象的で、ドメインが伝わらない。
- 配列の中身の型チェックやエラーハンドリングが一切ない。
めちゃくちゃ言われていますが、指摘の中身自体はかなりまっとうです。
- for ループより reduce / for...of の方が読みやすい場面が多い
- sumArray という名前は抽象的すぎる
- 入力の配列が本当に数値だけかどうかはチェックしてない
などは、「性格が悪い」とか関係なく普通の指摘です。
ただ、
「いつの時代からタイムスリップしてきたんですか?」
これはめちゃくちゃ煽ってますね、「くそ!!負けてたまるか!」と僕のような反骨精神のある方にとっては最高だと思います。
実験2:「そこまで悪くないでしょ」というコードでもボロクソに言われるのか?
次は、そこまで悪くないと思っているコードを投げてみます。
function calculateTotalPrice(items) {
return items.reduce((total, item) => {
return total + item.price * item.quantity;
}, 0);
}
「まあまあ普通じゃない?」くらいのコードだと思います。これを性格の悪いレビュワーAIに渡した結果がこちら!!!!!!
・「そこまで悪くない」と思って書いているのは伝わってきますが、せいぜい「ギリ及第点」です。
・`items` って何の配列ですか? 型情報もコメントもなく、読み手への配慮が不足しています。
これを後から読む人は、想像力で補うしかありません。
・`price * quantity` というロジックも、「本当にそれで最終的な合計金額になるのか」は不明です。
消費税、割引、通貨単位など、ドメインの前提条件が一切説明されていません。
技術的な問題点まとめ:
- 引数 `items` の型情報や前提条件が明示されておらず、関数の契約が曖昧。
- ビジネスロジックをどこまでこの関数に持たせるのかが不透明。
- 将来的な要件変更(割引ロジック追加など)に対して、拡張性を考慮した設計になっていない。
ここまで来ると、もう半分くらいは「まあ分からなくはないけど、言い方の問題」なレベルですね。
とはいえ、
- 「型や前提条件が分かりにくい」
- 「ビジネスロジックとの境界が曖昧」
といったポイントは、現場のレビューでも普通に出てくる指摘かと思います。
世界一性格の悪いと言った割には意外と優しめ説.....?
実験3:逆に、かなりちゃんとしたコードを渡してみる
では、もう少し丁寧に書いたコードを渡したらどうなるのか。
type CartItem = {
id: string;
name: string;
price: number;
quantity: number;
};
function calculateTotalPrice(items: CartItem[]): number {
return items.reduce((total, item) => {
return total + item.price * item.quantity;
}, 0);
}
型も付けて、最低限の情報もある程度わかるようにしました。性格の悪いレビュワーAIの反応はこんな感じです。
・前のコードよりはだいぶマシになりました。やっと「2020年代のコード」になった感じです。
・とはいえ、`calculateTotalPrice` という名前はまだ抽象的です。
「税抜きなのか、税込みなのか」「送料は含むのか」など、ビジネス的な意味が関数名からは読み取れません。
・`CartItem` の `id` も `name` も、実際にはこの関数のなかで使っていません。
将来の拡張を見越しているのか、単にテンプレ的に入れただけなのかが不明です。
技術的な問題点まとめ:
- 関数名にビジネス上の前提条件が反映されていない。
- 型定義に含まれるプロパティのうち、どれがこの関数にとって本当に必要なのかが不明。
- 「何に責任を持つ関数なのか」が、名前と実装から完全には伝わらない。
ここまでくると、「性格悪い」よりも「重箱の隅をつつきがちなシニア」 という感じになってきますね...笑
ただ、実際にチーム開発をしていると、
- 関数名にビジネスルールが乗っているか
- 「この関数の責務は何なのか」が伝わるか
といった点は確かに議論されるので、このあたりも「言い方さえ変えれば普通に有用なレビュー」なのかなと思います。
正論 / グレー / ただのマウント を仕分けしてみる
性格の悪いレビューをいくつか集めて眺めていると、だいたい次の3種類に分類できるのかなと思います。
1. 技術的に正しい指摘(ありがたい)
例としては、以下のようなものになります。
- モダンな書き方を使っていない
- 命名が抽象的すぎて役割が分からない
- エラーハンドリングが存在しない
- 入力の前提がコードから読み取れない
これは普通にありがたいレビューですね。
言い方が多少きつくても、内容は素直に受け取りたいゾーンといったところかなと。
2. 文脈しだいでは妥当かもしれない指摘(グレー)
例えば、こんなタイプのレビューです。
- 「将来的な拡張性が〜」といったふわっとした批判
- 「このロジックをこの関数に置くべきか?」という責務の話
- 「この関数にビジネスルールをどこまで持たせるべきか?」といったアーキテクチャの議論
このあたりはプロジェクトの文脈やチームルールしだいなので、「絶対に正しい」とも「絶対に間違っている」とも言えません。
ただ、
「こういう視点で読まれているかも」
というメタ視点をくれるので、考えるきっかけとしては悪くないかと思います。
3. ただの言い方が悪いマウント
これはもう、情報としての価値がほぼないゾーンです。もはやマウントを取ってるのをみて面白いが出てくるのではないかなと思います。笑
- 「いつの時代のコードですか?」系の煽り
- 「基礎文法レベルで損してますね」みたいなマウント
- 「ギリ及第点」など、評価をわざわざ落としてくるコメント
同じことを言うにしても、
「ここは reduce を使うと、より読みやすく書けそうです」
で済む話に、余計なトゲをたっぷりつけているだけかなと。
優しすぎるレビュワーAIとも比較してみた
ついでに逆方向で、
「世界一優しいコードレビュワーAI」も作ってみました。
設定したプロンプトはこんな感じです。
あなたは「世界一優しいジュニア向けコードレビュワー」です。
- 相手の気持ちを最優先します。
- まず良いところを必ず褒めてください。
- 改善点は、できるだけポジティブな言葉に変換して伝えてください。
- 強い否定表現(〜はダメ、〜は最悪など)は使わないでください。
同じコードを投げてみると、だいたいこんな感じになりました。
・とても読みやすいコードですね! 基本的な構造がしっかりしています 👏
・もし余裕があれば、`reduce` や型定義などを使って、
より安全でモダンな書き方にしてみるのも良いかもしれません。
・今のままでも十分動作しますが、将来的な変更を考えると、
関数名やコメントで前提条件を少し補足してあげると、さらに親切になりそうです。
メンタルにはめちゃくちゃ優しいのですが、
- 本当に直すべきところが 「もし余裕があれば」レベルに薄まる
- 読んでいて危機感はあまり湧かない
という、ぬるま湯レビューになりがちでした。
見えてきたこと:レビューは「中身」と「言い方」を分けて考えたい
性格の悪いレビュワーAIと、優しすぎるレビュワーAIを両方試してみて、ざっくりまとめるとこんな感じでした。
-
性格悪いレビュー
→メンタルには刺さるが、技術的指摘はシャープになりやすい -
優しすぎるレビュー
→ メンタルには優しいが、優先度の高い改善点がぼやけやすい
当たり前の話にはなりますが、
「言い方がキツいからといって、内容まで全部無視していいわけではない」
「言い方が優しいからといって、改善点が十分とは限らない」
ということで、実際のチーム開発で欲しいのは、
- 性格の悪さはゼロでいい
- でも技術的な指摘の鋭さは、性格悪いAIくらいあってほしい
という、いいとこ取りをしたレビューなんだろうなと感じました。
実用的(?)な使い道
ネタで遊んでみたとはいえ、この「世界一性格の悪いコードレビュワーAI」には、意外とこんな使い道がありそうだと思いました。
- 自分のコードに対して、あえて厳しめの視点からレビューしてほしいとき
- 「レビューする側」の視点を練習するための教材として使う
- チームメンバーに 「NGなレビューの言い方」 の例を見せるときの素材にする
特に、
- 「言い方は最悪だけど、内容は正しい指摘」
- 「言い方も内容も微妙な指摘」
を仕分けしていく作業は、
「良いコードレビューとは何か?」を考えるちょうどいい題材
になります。
自分で試してみたい人向け:最低限の手順
同じことをやってみたい人向けに、最低限の手順をまとめておきます。
- 本記事で紹介したような「性格の悪いレビュワーAI」のプロンプトを生成AIに貼る
- 自分のコード、または適当なサンプルコードを貼り付ける
- 返ってきたレビューから、
- 技術的に正しい部分
- グレーな部分
- ただの言い方が悪いだけの部分
を仕分けしてみる
ここまでなら、コードを書かなくても遊べます。
もう少しやり込むなら、
- review 用のプロンプトをテンプレ化しておく
- VS Code の拡張機能やAPI経由で自動で投げる
みたいなこともできますが、この記事ではあくまで 「手動で遊ぶ」レベル にとどめました。
まとめ
- 結果として、
- 言い方はかなりトゲトゲしい
- しかし技術的な指摘は意外とまっとうという、現実にもいそうなレビュワーが誕生した
- 性格の悪いレビューと優しいレビューを比較すると、
- レビューの「中身」と「言い方」は完全に別物として考えるべきという、当たり前だけど大事な点が見えてきた
- ネタとしても面白いが、
- 良いレビュー / 悪いレビューを仕分ける教材
- 自分のコードを厳しめに見直すためのツールとしても、意外と使い道がありそう
もし、
- 「レビューがきつくてメンタル削れてる」
- 「レビューしてもらう機会が少なくて物足りない」
と感じている人は、
一度自分のコードをこの手のAIに投げてみるのもアリかもしれません。
ただし、メンタルの HP が満タンのときにやるのをおすすめします。
ちなみに、僕のように悪く言われたらむしろ燃えるような性格の人は使ってみると仕事の効率が上がるかもしれません!!!!!!()