前書き
今回は私がAI、具体的にはClaude Codeで失敗した話になります。同じような作業を行われる方もいらっしゃるでしょうから、何かしらの参考になれば幸いです。
なお、ここでいう「43件」は、TeamManagerとTeamの関連付け処理が存在するとAIが判定したファイル数です。 最終的には46ファイル・95箇所が対象となりました。
前提条件
現在開発中のプロダクトにおいて、データ構造を大きく変更する必要がでました。具体的には、これまでmany to manyかつnullableとしていた属性を、FKかつNOT NULLとするものです。
イメージ的に、当初は以下のような感じでした。
from django.db import models
class Team(models.Model):
name = models.CharField(max_length=50, unique=True)
class TeamManager(models.Model):
username = models.CharField(max_length=50, unique=True)
teams = models.ManyToManyField(
Team,
related_name="managers",
blank=True,
)
ただ、詳細な理由は割愛しますが、業務上「管理者は必ず1組織に所属する」が正しいと判断し、M2M + nullableからFK + NOT NULLへ変更することにしました。
from django.db import models
class Team(models.Model):
name = models.CharField(max_length=50, unique=True)
class TeamManager(models.Model):
username = models.CharField(max_length=50, unique=True)
teams = models.ManyToManyField( # ここはいったんそのまま
Team,
related_name="managers",
blank=True,
)
team = models.ForeignKey( # 後々はこちらを利用する予定
Team,
on_delete=models.PROTECT,
null=True,
blank=True
)
これの追加に伴い、TeamManagerにTeamを紐づける場面についても、
manager.team = Ateam
manager.teams.add(Ateam)
のように並列して処理する必要がありました。
調査
初めの調査
先程はTeamManagerにTeamを紐づける場面としれっと書きましたが、これは具体的な業務以外にもテストコードも含みます。そのため、まずはそこも含めて、「いったいどこで紐づけが発生しているか」を調べる必要がありました。
こうした網羅的な作業は、AIの得意とする所です。いつも通りClaude Codeに、「TeamManagerにTeamが紐づけられている箇所を探して」と指示すると、「43ファイルに該当があります」との結果が。
私はこれに対して、「なるほど。AIが言うならきっと正しいんだね」と思い、これを文書化。ここで一旦の調査を閉じました。
実装前の再調査
そうして前提作業が終わって、いよいよ紐づけの並列化に入りました。一応文書化したものを共有しつつ、念のため再調査すると、「いや、43ファイルは正規表現検索の際のバグ。カッコを閉じ忘れていたので、余計なものが含まれている」との評価。該当するものは15ファイルとの結果が返ってきました。
これを見て私は、「なるほど。AIが言うならきっと……本当に?」と疑いました。いくら何でも極端すぎる。実は触っていたのを見逃していた?あるいは調べ方ががらっと変わった?と凄く迷いました。
ただ、これは後述する通り、逆に幸運だったと思います。
念押しの再調査
そこで私は、「43から15はかなり変化が大きいが、本当に妥当な数字か?」という念押しの再調査をお願いしました。その際に、「該当場所を教えてください」「チェック方法を教えて下さい」という追加のお願いも入れています。
そうすると、なんと結果は「46ファイル」という大バウンド。43でもやや過小だったとのことです。理由はいくつかありましたが、代表的なものは
- モデル構造の確認不足
私のプロジェクトでは、まず全員がBaseUserという基底モデルを持っていて、そこから各ロールで役割が派生するのですが、そこが抜けていた。 - イディオムの見落とし
テストでは頻繁にユーザーを作るので、毎回毎回ORMを書くのは大変です。そのため、create_userのように作成用のミニ関数を作っていたのですが、そこが全くチェックされておらず、ORMだけが見られていた
あたりでした。
なぜこうなったか
私の指示が曖昧だったのが主因ですね。
- アプリケーション全体で該当箇所を調べて
- 細かいテストなんかも全部見て
- たまに作成方法が違うから注意して
みたいなざっくりで広範囲に渡る指示を調べての一言で、なんかいい感じでこなしてくれると思っていました。設計の丸投げよりは毛ほどマシですが、やってる事自体はほぼ同じです。
考えてみれば当然なのですが、AIだって別にこれまでの設計を全部覚えているわけではありません。全部調べるわけでもありません。そのため、たとえばプロジェクト開始時から一貫して同じスタイルを徹底して貫けている、という状況でも無い限り、普通に漏れがでてしまうことは自然なのだと思います。
その時どう対処したか
割とパワープレイで対処しました。具体的には
- TeamManagerをimportしている箇所を全部チェックして
- addという単語も片っ端から調べて
- ただし、全部を1つとして扱うのではなく、「今回の作業に関係があるもの」「たまたま表現がかぶっているがあんまり関係ないもの」に分けて、該当箇所を表で見せて
みたいな感じです。網羅的に、の定義をもう少しはっきり指示しているような形になりますね。
以降どう対処しているか
広範囲に渡るものは、いきなり計画を立ててもらうのではなく、まずはフェーズを分けて取り組んでもらう形になりました。つまりいきなり「実装して」ではなくて、「こういうこと考えているので調査して」「実装は一旦おいていてOKです」という指示ですね。
これをやるだけで、何というかリソースがきちんと集中されている感覚があります。定性的な表現で恐縮ですが、多分完了条件が単純化されるので、AIも動きやすいのかなと。
また、指示に関しても基本的に具体的に
- ~というワードを検索して
- ~という表現が何箇所かあるから注意して
などを挟むようになりました。
さらに、調査に際してはどうしてもコンテキストを圧迫してしまうので、一二のポカンをできる限り避けるため、調査は別ウィンドウに投げるようになりました。
これらに加えて、作業範囲がさらに広い。私の方で把握しきれていないと感じる場合は、いきなり該当の調査をお願いするのではなく、
- import部のチェックをお願い
- インスタンスの作成方法を分類して
で前準備を踏んでから、本番の調査に入ってもらうこともでてきました。
いずれも、なるべくコンテキストが無為に膨らまないように分割しながら調査すると表せるのではないでしょうか。
以下、完全に余談
完全になんとなくで恐縮なのですが、45~50%を超えると、ちょっと挙動が怪しくなって、60%を超えると非線形的というか、急激に動作が不安定になる傾向がある気がしますね。
もちろん、これは私個人の体感ですが、裏付けになりそう……とまではいかなくても、ならなくもなさそうな話はいくつかあります。
たとえば、Claude Codeのユーザーからも、コンテキスト使用率が40〜60%を超えたあたりから、同じ修正を繰り返す・過去の決定を忘れるといった劣化を感じたという報告が上がっています。
こちらは正式な研究ではなく個別ユーザーの体験談なので割り引いて見る必要がありますが、私が体感していた「50%を超えると手間取りやすい」という感覚も、あながち的外れではなさそうです。
あとはChromaが2025年に発表した"Context Rot"という調査では、GPT-4.1・Claude 4・Gemini 2.5・Qwen3を含む18のLLMを対象に検証したところ、入力トークン数が増えるにつれて性能が一様にではなく、あるところから急激に劣化する(崖のように落ちる)ケースがあると報告されています。なので、非線形というのも妄言とまではいかないんじゃないかなと。
何を学んだか
冒頭で、
こうした網羅的な作業は、AIの得意とする所です
と書きましたが、これは少し不正確だと今では思います。正確には、
AIは網羅的な作業が確かに得意だが、網羅する探索空間自体は人間が管理するべき
だと思います。
「検索する」「読む」「分類する」はAIと相性がよい一方、「検索空間を正しく定義する」「これで全部だと保証する」は別の仕事なのだと思います。前者はAIに任せられても、後者は今のところ人間側が引き受けるしかない役割なのだと。
そして、ここを「ふわっといい感じでよろしく」は、少なくとも今のAI、あるいは私のワークフローだとまだ厳しいのだと思います。
また、誤差の捉え方も少しアップデートする必要があるなと思いました。
既に書いた通り、43ファイルから15ファイルという極端な変化だからこそたまたま疑えたわけで、これがたとえば38ファイルや45ファイルみたいな絶妙な数だったら、「なるほど誤差を修正してくれたんだな」と考えたと思います。
つまり数字ではなく、どのような経路で、どのような対象に検索を実行したのか、というのところにもっと注意してみるべきなのだと思います。
今回はここまで。閲覧いただきありがとうございました。何かありましたらコメント欄にて指摘、共有していただけると助かります。