はじめに
AIコーディングツールを日常的に使っていると、ある日ふとレビューで「ここ、なんでこう書いたの?」と聞かれて答えに詰まる瞬間がある。動いている、テストも通っている、なのに自分の口で説明できない。これは個人のサボりというより、AI併用ワークフローの構造的な副作用だ。
この記事の対象読者は、ClaudeCode・Copilot・Cursor 等で日常的にコードを生成しているエンジニア。結論を先に書くと、「AIに書かせる前に意図を言語化し、生成後に差分を読み直す」二段のチェックポイントを仕組み化するだけで「分かったつもり」はかなり減らせる。本稿ではそのための具体的なレビュー手順と、実装に落とせるテンプレートを示す。
なぜ「分かったつもり」が起きるのか
人間がコードを書くとき、頭の中では「この変数名にしよう」「この型で受け取ろう」と小さな選択の連続が走っている。この選択の履歴こそが、後から「なぜそう書いたか」を説明できる根拠になる。
AIに生成させると、この選択の履歴が外注される。出力は「動く完成形」として降ってくるので、人間側は「OKそうだから採用」という1回の判断しかしていない。レビュアーから「なぜこの型?」と聞かれても、自分は選択をしていないから答えられない、というのが正体だ。
ここで「AIに聞き直せばいい」は半分しか正しい。聞き直しても、それは事後の正当化であって、設計判断ではない。重要なのは生成前に意図を文章化しておくことだ。
実装パターン1: プロンプトに「制約と非選択肢」を書く
ありがちな失敗プロンプトは「○○を実装して」だけで投げること。これだと AI は無難な最大公約数を返してきて、なぜその設計になったのか後から辿れない。
良いプロンプトは「何を選ばないか」も含める。
# 悪い例 "ユーザー登録APIを実装して" # 良い例 (制約と非選択肢を明示) """ ユーザー登録APIを FastAPI で実装してほしい。 採用する設計: - Pydantic v2 の BaseModel でリクエスト検証 - パスワードは argon2 でハッシュ化 (bcrypt は使わない) - DB アクセスは SQLAlchemy 2.0 の async セッション 採用しない設計と理由: - ORM のリレーション lazy load は使わない (N+1 が見えなくなるため) - 例外を握りつぶす try/except は禁止 (障害切り分けが困難) - 同期版 SQLAlchemy はパフォーマンス計測で不可と判断済み """
「採用しない設計」を書く効果は2つある。AIの探索空間を狭めて品質を上げることと、自分自身の設計判断を強制的に言語化すること。後者は「分かったつもり」防止に直接効く。
実装パターン2: 生成後の差分を「再質問」する
生成されたコードをそのままコミットせず、自分→AIへの逆質問を1ターン挟む。これは自動化できる。
// scripts/explain-diff.ts
// 直前の git diff を Claude に投げて
// 「設計判断の論点」と「人間が確認すべき点」を引き出す
import { execSync } from "node:child_process";
import Anthropic from "@anthropic-ai/sdk";
const client = new Anthropic();
const diff = execSync("git diff --cached", { encoding: "utf8" });
const res = await client.messages.create({
model: "claude-opus-4-7",
max_tokens: 1024,
messages: [{
role: "user",
content: `以下の差分について、次の3点だけ箇条書きで答えて。
1. 暗黙に選ばれている設計判断 (型・命名・エラー処理)
2. 後でレビュアーに聞かれそうな観点
3. テストで担保すべき不変条件
差分:
${diff}`
}],
});
console.log(res.content[0].type === "text" ? res.content[0].text : "");
ポイントは「コードを直して」ではなく「論点を出して」と頼むこと。修正させると AI の判断にまた依存するが、論点抽出は「自分が考える材料」を得るための作業に留まる。出てきた論点を1つでも自分の言葉で答えられないなら、コミットは止める。
実装パターン3: PR テンプレートに「意図」欄を強制する
仕組みでカバーするのが一番強い。PR テンプレートに自分の言葉で書かないと埋まらない欄を用意する。
<!-- .github/pull_request_template.md --> ## 変更内容 (自動生成可。AI に書かせて OK) ## 設計判断ログ (★必須・自分の言葉で書く) - なぜこの型/構造を選んだか: - 代わりに検討して棄却した案: - 後から変えるとしたら最初に触る場所: ## AI 利用状況 - 利用ツール: - AI 生成部分の割合 (体感): - 自分でゼロから書き直せるか (yes/no):
「自分でゼロから書き直せるか」に no が並ぶようなら、それは技術的負債のシグナルだ。レビューで弾くべきか、ペアプロでキャッチアップすべきかの判断材料になる。
落とし穴: AI に「意図」まで書かせない
最大の罠は、上記の「設計判断ログ」まで AI に書かせてしまうこと。読みやすい日本語が返ってくるので一見問題なく見えるが、それは事後の物語であって設計判断ではない。ログの目的は文書化ではなく、書く過程で自分の理解を確認することにある。手書き or 音声入力で、たどたどしくても自分の言葉で書くのが正解。
もう1つの落とし穴は、レビュアー側が「AI生成だから」と甘く見ること。生成コードでも責任は提出者にあり、レビュー基準を下げる理由にはならない。むしろ設計判断ログが薄い PR ほど厳しく見る運用にした方が、長期的なコード健康度は保たれる。
まとめ
「分かったつもり」は意志の弱さではなく、AI 併用ワークフローの構造から生まれる。対策は次の3点に集約できる。
- プロンプトに「採用しない設計」を書き、生成前に判断を言語化する
- 生成後に差分を AI へ逆質問し、論点を自分で答えられるか確認する
- PR テンプレートで設計判断ログを必須化し、レビュー文化として支える
次のステップとして、今週コミットした PR を1つ選び、設計判断ログを後追いで書いてみることをおすすめ!スラスラ書けない箇所が、まさに「分かったつもり」だった部分だ。そこから読み直せば、AI 生成コードに対する自分の関わり方が変わりますよ。