綴Photo の修正中、面白いことが起きた。Claude Code(自分の AI 開発パートナー)が、自分が読んでる関数を「バグ」と誤認した。コードに問題があったわけじゃない。問題は コメントに何が書かれてなかったか だった。
その経験から「AI レビューに通す前のセルフチェック観点」として整理した3点ルールの話を書く。
何が起きたか
期間スキャンのパフォーマンスを上げる修正をしてた。対象は scanEmptyMonthsInYear という関数で、「写真のない月の一覧を返す」もの。
Claude Code がコードを読んで、こう言った。
エミュレーターで全写真が EXIF なし(撮影日時不明)の場合、この関数は全月を「写真なし」として返してしまう。結果として全月が completed 扱いになり、UI から全部消える。これはバグ。
自分は「あれ、それバグじゃなくて仕様だよ」と気づいた。写真なし月を隠す という機能で、ユーザーがボタンを押したときに「写真がない月は綴る対象にならない」という意図的な挙動。
Claude Code は呼び出し側のコードを読んでなくて、関数単体だけ見て「自動で全消えする関数」と誤認したのだった。
なぜ誤認したか
当時のコメントはこれだけ:
/// 指定年の未完了月のうち、写真のない月の年月ペアを返す。これだけ読むと、関数が 「何をするか」 は分かります。でも、
- いつ呼ばれるか(自動? ボタン?)
- 返り値がどう使われるか(completed にする? 単に表示する?)
- 写真がない年では全月が返る挙動は意図的か、それともバグか
が、全部 コードからは読み取れません。AI は呼び出し側を別途読まないと意図を再構成できなくて、その手前で「これバグじゃない?」と早合点した。
自分自身、その後コードを見直すために呼び出し側を読みに行って、初めて意図を把握した。コメントが薄いと、書いた本人ですら半年後には誤読します。
3点ルール
ここから整理した「公開関数の docコメントに最低限書くべき3点」がこれ。
① 呼び出し文脈
「どこから呼ばれて、結果が何に使われるか」を1行。
/// **呼び出し文脈**: period_select_page._bulkScanYear(「写真なし月を隠す」
/// ボタン)からのみ呼ばれる。返り値は markMultipleCompleted に渡され、
/// 該当月が一覧から非表示になる。これを書いておくと、レビュアー(人も AI も)は 呼び出し側を読まなくても全体像が見えます。
② 誤認されやすい仕様
「バグと取り違えられそうな意図的な挙動」を「これは仕様」と明記して残します。
/// **誤認されやすい仕様**: 写真が1枚もない年では、endMonth まで全月が返る
/// (=全月 completed になり一覧から消える)。これはバグではなく
/// 「綴る対象がない月は非表示にする」意図的な仕様。これがあると、レビュアーは「これバグじゃない?」と思った瞬間にコメントで「いや、仕様だよ」と返してもらえます。未来の自分や AI の早合点を、コメント1個で止められます。
③ 経緯
「過去に別実装から切り替えた理由」を1段落。
/// **経緯**: 初期実装は画面表示時に自動スキャンしていたが、写真数が多いと
/// 時間がかかりすぎたため、ユーザー操作(ボタン)起点に変更した。
/// 「自動スキャンに戻せば UX 良くなる」と思ったら、まずこの経緯を疑うこと。これが一番強いです。コードを見るだけでは絶対に分からない情報。「自動スキャンに戻そう」と思った半年後の誰か(自分含む)が、過去の失敗を繰り返さずに済みます。
テストとの使い分け
「仕様をテストで固める」アプローチもあって、これも有効です。ただ、コメントとテストでは役割が違います。
| コメント | テスト | |
|---|---|---|
| 得意なこと | なぜそうなってるか(意図・背景) | こう動く(具体的な値での挙動) |
| 何を防ぐか | レビュアーがバグと誤認するのを防ぐ | 後の改修で挙動が変わるのを防ぐ |
| 弱点 | コードが変わって古びるリスク | 「なぜそれが正しいか」は書きにくい |
要は コメントは "WHY"、テストは "WHAT"。今回みたいに「これってバグじゃない?」と疑われそうな仕様には コメントが先に効きます。テストは回帰防止の保険で、書けるなら書きます。
プロジェクト規約にも入れた
書きっぱなしだと再発するので、プロジェクトの規約ファイル(CLAUDE.md = AI が読む規約)にルールとして残した。
公開関数の docコメントには、該当する範囲で以下を書く:
- 呼び出し文脈: どこから呼ばれ、結果が何に使われるか(1行)
- 誤認されやすい仕様: バグと取り違えられそうな意図的な挙動(1行+「これは仕様」明記)
- 経緯: 過去に別実装から切り替えた場合の「初期実装はこうだったが…のため変えた」(1段落)
AI レビューに投げる前に「この関数、呼び出し側を読まないと意図が分からないか?」と自問する。Yes なら docコメントが足りていない。
これで次回以降、AI が同じ誤認をしたら「コメント不足」として検知できます。
学んだこと
- コメントは "AI レビューを通すための事前準備" でもあります。コードに書かれてない意図を読み取らせるのは無理筋なので、書いておくしかありません
- コメント vs テスト は対立じゃなくて役割分担。コメント=意図、テスト=値
- 書いた本人ですら半年後には誤読します。だから「自分のために書く」のが正解
おわりに
「コメントは書かない方が良い」という流派もあります。確かに「何をしてるか」を実況中継するコメントは要りません(コード読めば分かるからです)。
でも 「なぜそうなってるか」は、コード読んでも分かりません。そこを書かないと、未来の自分も AI も呼び出し側を彷徨うことになります。
レビューに通す前に、関数1つずつ「これ呼び出し側を読まないと意図が分からないか?」と自問する習慣をつけたい。Yes なら、まだ docコメントが足りていません。
この記事は2026年5月時点の自分の理解で書いています。仕様や認識が変わってる可能性があります。