AI 生成コードを「使うか使わないか」ではなく、「どこまで受け入れるか」を整理する。
この記事で扱わないもの:
- AI エディタやエージェントの比較
- プロンプト設計の細かなコツ
- ベンダー別 API 機能比較
- 法務や契約の包括的整理
1. 前提と結論
AI 生成コードで困りやすいのは、「全部だめ」と「全部速い」の間にある判断が抜けやすいこと。 実際には、同じ AI の出力でも扱い方はまるで違う。
- 小さくて確認しやすい差分
- 方針は使えるが、そのままでは扱いにくい差分
- もっともらしく見えても、読み解くより書き直したほうが早い差分
この違いを無視すると、レビュー負荷も事故率も上がりやすい。 最初から境界線を持っておけば、AI を怖がりすぎず、雑にも扱わずに済む。
2. なぜ境界線が必要か
AI 生成コードは、短時間でそれらしいものが出てくる。 だからこそ、見た目の自然さに引っ張られやすい。
特に立ち止まって見たいのは、次のような差分だ。
- 正常系だけはきれいに見える
- 変更多そうに見えない
- ちょっと読んだだけでは破綻が見えない
- でも実は、権限、例外、設定、ログ、副作用が雑
ここで必要なのは、AI を信用しないことではない。 「差分の性質に応じて受け取り方を変える」こと。それで十分なことが多い。
| 見た目 | 実際に起こりやすい問題 | 境界線が必要になる理由 |
|---|---|---|
| 小さく見える差分 | 設定、ログ、権限が裏で混ざっている | 見た目だけで受け入れると確認漏れが起きやすい |
| 正常系がきれい | 失敗時の扱いが曖昧 | 事故は正常系より失敗時に出やすい |
| すぐ動きそう | 差分が広く、責任範囲が見えない | レビュー負荷が高く、捨てたほうが早い場合がある |
受け入れ判断があると、その後の流れもはっきりする。
- まず、この差分を受け取る価値があるかを見る
- 受け取るなら、品質ゲートで機械的に落とせるものを落とす
- そのうえで、人間レビューで残りを見る
この順番があるだけで、AI 生成コードとの付き合い方はだいぶ楽になる。
3. 受け入れやすい差分
受け入れやすいのは、小さくて確認しやすい差分だ。 入力と出力が明確で、戻しやすく、テストも書ける。そういう差分は素直に扱える。
次のコードは、比較的受け入れやすい部類に入る。
<?php
declare(strict_types=1);
final class DraftReplyTextFormatter
{
public function format(string $draft): string
{
$trimmed = trim($draft);
if ($trimmed === '') {
return '';
}
return mb_substr($trimmed, 0, 2000);
}
}
このコードは、判断しやすい要素がそろっている。
- 入力が 1 つ
- 出力も 1 つ
- 副作用がない
- 壊れても戻しやすい
- テストしやすい
こういう差分は、AI に下書きを作らせて、人がさっと確認して受け入れる形と相性がよい。 受け入れるといっても、そのまま即マージするわけではない。 「人が責任を持って確認できる」から受け取りやすい、という話だ。
4. 人間主導で書き直す前提にしたい差分
次は、方針だけ借りて、人間主導で組み直したほうがよい差分。 典型的なのは、設定、ログ、権限、例外処理、外部 I/O が混ざっているコードだ。
<?php
declare(strict_types=1);
interface DraftReplyClient
{
public function generate(string $body, int $timeoutSeconds): string;
}
final class User
{
public function __construct(
public readonly int $id,
public readonly string $role,
) {
}
}
final class DraftReplyController
{
public function __construct(private DraftReplyClient $client)
{
}
public function __invoke(User $user, array $request): array
{
$timeoutSeconds = (int) getenv('AI_TIMEOUT_SECONDS');
$body = (string) ($request['body'] ?? '');
error_log('draft reply requested: ' . $body);
return [
'draft' => $this->client->generate($body, $timeoutSeconds),
];
}
}
このコードは、すぐ捨てるほどではない。 ただ、そのまま受け入れるのは危うい。
理由は次のとおり。
- 環境変数をコントローラの中で直読みしている
- 問い合わせ本文をそのままログへ出している
Userを受け取っているのに権限確認がない- 失敗時に何を返すかが見えない
この種の差分は、AI が出した方向性だけを参考にして、人間主導で整理し直したほうが早いことが多い。 「全部捨てる」ではなく、「叩き台としてだけ使う」位置づけだ。
5. 書き直したほうが早い差分
次のような差分は、無理に読み解くより、最初から書き直したほうが早いことが多い。
- 認証や権限と、重要な状態変更が一気に混ざっている
- 削除、課金、送信確定のように失敗コストが高い
- 並行性や再実行を考えないと事故になる
- 差分が広すぎて、何が変わったのか追いにくい
- もっともらしいが、責任の所在が見えない
たとえば、次のような処理は「捨てる」判断に傾く。
- 返信の送信確定と監査ログとポイント減算をまとめて追加している
- 削除処理と権限処理と通知送信が一度に変わっている
- 既存の広いクラスをまとめて AI が書き換えている
言いたいのは「危ないから AI 禁止」ではない。 レビューの負荷と事故コストを考えると、最初から人間が書き直したほうが進めやすい差分がある、というだけだ。
6. 3段階で見るための判断軸
ここまでを表にまとめる。
| 段階 | どんな差分か | どう扱うか |
|---|---|---|
| 受け入れる | 小さい、入出力が明確、テストしやすい、副作用が少ない | 人が確認したうえで受け取り、品質ゲートへ回す |
| 人間主導で書き直す | 方針は使えるが、設定・ログ・権限・例外・外部 I/O が混ざる | アイデアだけ借りて、人間が境界を決め直す |
| 捨てる | 失敗コストが高い、差分が広い、責任範囲が大きい | 読み解くより最初から書き直す |
見る軸は多くなくていい。 実務では、次の 5 つくらいで十分だ。
- 差分は小さいか
- 入出力は明確か
- 副作用は限定されているか
- 戻しやすいか
- 人が責任を持って確認できるか
この 5 つで Yes が多いなら受け入れやすく、No が増えるほど書き直しや破棄に寄る。
7. 品質ゲートと人間レビューの前に見ること
受け入れ判断が終わったら、その次に品質ゲートと人間レビューがある。 この順番を分けておくと、役割がぶれにくい。
- 受け入れ判断: この差分をそもそも受け取る価値があるか
- 品質ゲート: 整形、型、既知の振る舞い崩れを機械で落とす
- 人間レビュー: 例外、設定、ログ、権限、副作用を読む
品質ゲートとレビューの具体的な進め方は、次の記事で扱っている。
最後に、差分を受け取る前の確認リストを置いておく。
- 差分は小さくて、変更点を説明できるか
- 入出力と副作用を人が追えるか
- 失敗しても戻しやすいか
- 設定、ログ、権限、例外処理が雑に混ざっていないか
- 捨てて書き直したほうが早くないか
この 5 つに答えるだけでも、AI 生成コードの扱いは安定する。
8. まとめ
AI 生成コードとの付き合い方は、「使うか使わないか」の二択ではない。 受け入れる、書き直す、捨てるの 3 段階で見ると、差分を落ち着いて扱えるようになる。
小さくて確認しやすい差分は、AI の速度をそのまま価値に変えられる。 設定、ログ、権限、重要な状態変更が絡む差分は、人間主導で組み直すか、最初から書き直したほうが早いことが多い。
受け取り方の境界線を持つこと。それが AI 生成コードと長く付き合うための土台になる。