パルカワ2

最近はFlutterをやっています

プルリクエスト作成時のAIによるコードレビューの所感

プルリクエストを出す流れが結構決まった流れになってきたのでスキル化した。今のところ、Github Copilotを前提とした流れになっている。

  1. Claude Code) /create-pr
    1. Draftでプルリクエスト作成
    2. Github Copilotへのアサイン
    3. テンプレートを元にbodyを作成
  2. Github Copilot) アサインされたらレビューする
  3. 自分) Github Copilotからのレビューを対応する/しないを決めてGithub上でコメントする
  4. Claude Code) /respond-to-review
    1. コメントされた内容を本当にやるべきかも改めて確認する
    2. Github Copilotに指摘された内容を修正
    3. 変更 -> commit -> push -> Github上での対応しましたコメントまで行う
  5. 自分) Github上の対応しましたコメントを確認して、解決していたらResolvedに変更
  6. 自分) Github上のUIで変更を眺めてOKならReady to reviewに変更
  7. 同僚) レビュー + Approveする(AIを使うかもしれないが自分は認知しない)

Github Copilotによるコードレビューは、大きく変更しない限り基本的に1回しか行わない。変更をpushするたびに再度全体を人間にレビューしてもらうことはしないと思うのだが、それと同様にAIもしなくていいという気持ちに今はなっている。


プルリクエスト作成時のAIによるコードレビューの目的は、人間レビュアーの負荷軽減だと自分は思っていて、人間レビュアーが指摘しそうなことを先に潰しておいてレビュアーがわざわざ指摘しなくてもいいようにしたい。

なので、Draft状態でAIによるコードレビューを先んじて行い、レビュイーがすべて対応してから人間にレビュー依頼を行うという形にしている。

自分は、レビュアーとしてアサインされたプルリクエストにAIによるコードレビューが大量に残ってると「これは対応するのか?対応したのか?対応を待ったほうがよいのか?」など考えることが増えてだるいな〜と思うので。


コードレビューには、レビュイーが持つコストとレビュアーが持つコストがあって、AIによってレビュイーのコストは自然と減っていく気はするが、レビュアーのコストはレビュイーが意識しないと減らない気がするので、減らしていきたい。

プルリクエスト作成時のコードレビュー

最近はClaude Codeでしかコードを書いていない。1月に対して2月は自分が関わったプルリクエストの量は3倍になったらしい。

コードを出力するスピードが上がっているのであれば、コードレビューがネックになるでしょう!と思って、Claude Code ActionによるAIレビューを導入してみたのだがあまりしっくりきていない。

考えてみると、コードレビューの何をAIに期待しているのかを自分の中で整理できておらず、期待しすぎてるかもと思ったので整理してみる。

コードレビューの目的と役割分担

コードレビューの目的はかなり多いし、人や組織やプロダクトによっても異なりそう。例えば、検査の観点でいえばバグ発見、コードの質、テストの質などがあるし、チームメンバーと話して疑問をはっきりさせたり、共通認識にしたりする場でもあるみたいな話もあるだろう。

Coding Agent登場以前は、これらすべてを人間がやっていたのかでいえばそうではなくLinterに頼ってもいた。Linterは、答えが明確になっているルールに沿って警告やエラーを出す。

人間とAIは同じ入力に対して異なる結果を返す可能性があるが、LinterやTestは同じ入力に対して常に同じ結果を返す。それを踏まえると以下のような役割分担になるのではないか。

  • 答えが明確でルール化できる → 主にLinter / Test
  • まだ答えがないので人間の判断が必要 → 主にAI
  • 判断・確定 → 主に人間

Linterによるレビュー

スタイル・フォーマット・命名規則みたいなのは当然として、依存方向の違反や禁止されたimportのようなアーキテクチャルールも明文化できるならLinterに寄せられる。

言語イディオムレベルの冗長なコードもLinterが得意。Dartは、関数参照(tear-off)で書けるのにラムダ式を使っている箇所を検出するルール のunnecessary_lambdas とかそういうのがある。コードの質でいえばDart Code Metricsとかもある。

テストの質も頑張ればいける気がする。ミューテーションテストは、ソースコードを自動的に壊して(a > ba < b など)テストを実行し、壊したのにテストが通ったらアサーションが甘いのでテストの質が低いねというのがわかる。*1

ルールとして明文化できるなら、まずLinterに寄せるのがよさそう。

AIによるレビュー

AIが扱うのは、Linterではルール化できないが人間に「確認してほしい」箇所。例えば

  • 既存のコードと異なるパターンで書かれているがLinterは指摘していない
  • テストが書かれていないが書かなくていいのか判断つかない

一方で、AIはAIが持つわずかなコンテキストを元に「このコードは怪しい」という確度を出しているだけなので、AIはバグや間違いっぽいものを検出するが「ここが間違いです」とは断定できない。加えて、人間の方がいろんな情報にアクセス出来るため、コンテキストを多く持っていて「あえてそうやっている」とか「別にそこまでやる必要ない」とかすでに判断していることが多い気がする。

AIがアクセス出来る場所にコード以外のコンテキストも含めていくのが必要で、難しければAIには暗黙知っぽいところを指摘してもらうくらいしか出来ないのではなかろうか。

人間によるレビュー

AIによるレビューで書いたことは、人間によるレビューにも言えるが、人間にしか出来ないことは、以下のようなものがある。

  • 設計の妥当性の判断
  • ビジネスロジックの正しさの判断
  • AIの指摘に対する判断
  • 知識共有の会話

判断するのは人間で決定したことをLinterで気付けるようにしていくみたいなのをAIに指示するのも人間ですね。

まとめ

Claude Code Actionでのコードレビューは、Linterでやるべきことも指摘しようとしていたからしっくりこなかったんだとおもう。

今まであんまりやりきれてなかったLinterカスタムルールなどを色々整備していくことが今後重要になっていくだろうし、Coding Agentによってそれがしやすい環境になってきた。加えて、AIは答えが不確定で、チューニングや期待値の調整が必要なため効果が読みにくい。Linterで地盤を固めたりリポジトリ内にコンテキストを持てるようになった上でAIによるレビューを導入するか、さくっと使えるGithub Copilotでレビューしたりするほうがよさそうではある。

いま悩ましいのは、custom_lintを使わずにカスタムルールを書くにはanalyzerのアップデートが必要で、そのためにはRiverpodのアップデートやcustom_lintからの移行を真面目に考える必要があるということ!やるしかねえ

*1:もちろんそれだけでテストの質が高い!とは言い切れないとは思うんだけど…

諦めない

仕事をしていると実装に対して「もっとこうしたほうがいいな!」と思うことはある。一方同時にたくさん積み上げられたタスク、期待されているであろうことを踏まえると「今じゃない…」とも思う。

「今じゃない」と言って諦めるのは簡単だし、コストもかからない。でも、「今じゃない」を重ねていくと「こうしたほうがいいな!」は忘れて、保守性は下がったまま。もしくはもっと下がる。

自分も「今じゃない」と思いがちなのだが、「今じゃない」で済ませないこと、つまり諦めないことが重要なんじゃないかと最近よく思う。全部やるのは今すぐじゃないとしても、今できる最小のことはなにかを考えてやる。

最小のことは、例えばコードにコメントを書くことかもしれないし、Coding Agentにクラスを分けさせることなのかもしれない。

最近はAIのおかげで諦めないことが容易になってきた。諦めずにやっていきたいですね。

モバイルアプリの開発をしているとターミナルを使うのは、gitやadbを操作するときくらいであんまり使わないので、panelを複数出すこともそんなになかったのだが、最近はClaude Codeでコードを書いており、ターミナルに滞在することが多いので、画面分割をよくしている。画面分割をしたあとにブラウザとかVSCodeを見てターミナルに戻ってくるとカーソルがどこにいったのかわからなくなることが多々あったので、tmuxの設定を見直した。

元々はこんな感じでカーソルを探すか真ん中の線の色表示で見分けてた。

panelのtopに線を表示して、フォーカスが合っていると色が変わるようにした。全体をぼんやり見れば、どこにフォーカスが当たっているのかわかるし、位置が固定されているので目の移動が少なくなったので便利

set -g pane-border-status top
set -g pane-border-format "#{?pane_active,#[reverse] #P #[noreverse], #P }"

見た目的には前のほうがすきだけど、めんどくささには勝てなかった

Claude Code使い始めた

かなり今更だけど、去年の12月末に元同僚のエンジニアたちとご飯を食べたときに「さすがに使ってみたほうがいいよ」と言われたので使い始めて1ヶ月ほど経った。

年末年始は、公式ドキュメントとこの本読んだ。公式ドキュメントだけでいいと思う。あとは、いろんな人の記事を読みまくっている。学生の頃にとにかく人のブログを読みまくっていたので懐かしい。全員どうでもいいことでもいいからブログを書いてほしい。とはいえClaude Codeベストプラクティスの文体練習みたいなのが大量にあるのは悩ましい。もっと自分のどうでもいいことを書いたほうがよい。

それはそうと、もうClaude Codeがない生活は想像できない!

自分の出力量は増えたし、わからないことに対する答えにたどり着きやすくなった。

とはいえまだ試行錯誤中で、Agentic Codingの良さは個人の力を底上げするだけではなく、複利エンジニアリングのようなチームでの活用にもあるとおもう。そこまでは引き出せていない。

引き出すためには、早めに自分たちが良しとするものを定義したり、それを更新し続けるプロセスを設計するというのに時間がかけたほうがよいとおもう。

ただAIに向けてのドキュメントが肝だと思うけど、そのドキュメントの良し悪しの評価の仕方がよくわからなくて行数が短くていいみたいな雑な評価になりがち。とりあえず、自分がやる実装をほぼClaude Codeで進めて、使っておかしいところを直すみたいな力で解決する方法を今取ってる。