0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

サブエージェント120本が集めた学校データを本番投入したら、想定外が5連発だった話

0
Last updated at Posted at 2026-07-11

前回、「データは揃いましたが、本番投入とアプリ側の対応はこれから」と書きました。この記事はその続編です。前編(データ収集編)はこちら。

その「これから」をやりました。個人開発している「まなびマップ」(親子で使う学校選びの地図ノート、https://manabi-map.app )の全国展開に向けて、AI サブエージェント約120本が集めた東日本13道県の学校データを、本番の PostgreSQL(Supabase)に投入する日です。結論から言うと、投入は無事に終わりました。ただし想定外が5連発。この記事はその検収と本番投入のログです。Claude Code のマルチエージェント運用の続編ですが、中身は泥臭いデータ検証の話です。

まず訂正から。前回の記事、数字が間違っていました

前回「1,294拠点」と書きました。正しくは 1,194 拠点です。

投入時に県別の count(*) を照合して発覚しました。間違い方が興味深くて、県別の内訳(北陸154、甲信越273、東北473、北海道294)は全部合っていた。足すと 1,194 なのに、報告書の合計欄だけ 1,294 になっていた。偏差値の件数も同じで、内訳の和は 451 なのに、合計だけ 551。どちらも、ちょうど 100 多い。

どこかのエージェントが合計を書くときに足し損ね、以降の報告が全部その数字を引用した、という流れだと見ています。人間の集計ミスとまったく同じ形。悔しいのは、データ本体の検査は4重にやったのに、「内訳と合計の検算」だけは誰もやっていなかったことです。指揮役の自分も、検収エージェントも、報告書の足し算を疑わなかった。

DB に入れれば count(*) は嘘をつきません。集計の最終検収は投入時の実測。これを先に言っておきます。

投入前の grep で、本番から33校消えていることが分かった

今回の作業には「既存の本番データへの疑い」の白黒付けも含まれていました。入試実績を集めていたエージェントが、「この学校たち、本番データに存在しなくないですか」という報告を残していたからです。

正本の SQL を grep してみたら、すぐ分かりました。あるブロックの見出しコメントは「相模原市 県立12校」。なのに、その下に並んでいる insert 文は横須賀・三浦・鎌倉の13校でした。担当エージェントの取り違えで、相模原の学校が丸ごと収録されていなかった。さらに学校名簿と全件突合すると、私立も18校足りない。合計33校です。学校選びの地図サービスで、慶應義塾や浅野クラスの有名校が検索しても出てこない状態が、公開から5日間続いていたことになります。

図にすると単純で、見出しと中身がずれていただけです。ただ、当時の検収はブロックの見出しと校数合計を見て通していた。中身の市区町村までは見ていなかった。今回の発見に DB 接続は不要で、grep とリストの突合だけで白黒が付きました。調査系のミスは、派手な照合よりまず grep です。

投入当日。エラーが3回、止めてくれた

migration、修正 SQL、13道県の順で流し始めてすぐ、学科を入れ替える update SQL が外部キー制約で止まりました。旧学科の行に偏差値データが20件ぶら下がっていて、こちらは cascade で一緒に消える前提でいた。実際の定義は restrict。DELETE ごと拒否です。トランザクションのおかげで中途半端には壊れず、旧学科の偏差値を先に消す SQL を1本挟んで解決しました。ここは事前に「ユーザーのお気に入りデータからの参照はゼロ」まで確認して安心しきっていた場所で、刺さったのは自前の推計値テーブルのほうでした。

次は宮城の入試実績で一意制約違反。掘ってみると、原因は自作の SQL 生成スクリプトの仕様でした。CSV の学科名が学校データと完全一致しないとき、警告を出さずに黙って NULL を入れる。学科改編前の旧名で書かれた行が2つとも NULL になり、同じ学校・同じ年度で衝突して、たまたまエラーになった。

たまたま、です。実際、先に投入した新潟には NULL の行が3件、音もなく入っていました。エラーで止まる失敗はありがたい。静かに壊れる失敗が一番高くつく。

上の図が今回の教訓の核心です。同じ「学科名の不一致」から出た NULL でも、行き先は3通りありました。制約違反で止まって発覚したもの(幸運)、静かに混入していたもの(実害)、そして千葉の30行のように「くくり募集で学科別の数字が公表されない」ための意図的な NULL(仕様)。ここで手を止めて、20都道県ぶんの CSV の校名と学科名を DB と機械突合しました。旧学科名の残存が9行(収録対象外として除去)、学科名がそもそも間違っていたのが2件。うち1件は「・」の有無、もう1件は20年以上前の学科改編に気づいていなかったもので、どちらも学校の公式サイトで現行名を確定して直しました。

学んだこと

  • 集計は自己申告を信じない。内訳と合計の検算、最後は DB の count(*) との照合までを検収に含める
  • エラーで止まるのは良い設計。今回の被害を防いだのは外部キー制約・一意制約・トランザクション、つまり DB の基本機能だった
  • 一番怖いのは黙って NULL が入る系。生成スクリプトには「解決できなかったら警告」を足してから西日本に行く
  • 本番に触る操作は1つの関門に集約する。直前にバックアップ、実行は人間の承認後。120本のエージェントの成果物も、この関門だけは全部通した

投入後、プレビューの地図には20都道県・2,589校が並びました。前回「地図はまだ半分です」と書きましたが、データの上では半分を超えました。アプリ側の検索対応とリリースはこれから。西日本には、今回できあがった検収装置を一式持って行きます。

たぶんまた、想定外は出ます。出る前提で、止まってくれる仕組みを増やしておきます。

このデータが載るサービス本体はこちらです。住所を入れると通える高校が地図に出て、気になる学校を家族でメモできる無料の学校選びノートです。中学生のお子さんがいる方はぜひ。

前編(サブエージェント120本でデータを集めた話)を読んでいない方はこちらからどうぞ。


※ ヘッダー画像とインフォグラフィックは AI(画像生成)で作成しています。

書いた人: ishizakahiroshi
群馬の北部で、保護猫2匹と暮らす、在宅エンジニア(何でも屋)
https://ishizakahiroshi.github.io/
https://github.com/ishizakahiroshi
X(業務委託・各種相談はこちら):
https://x.com/ishizakahiroshi

バックエンド・インフラ・AI連携まわりで、業務委託のご相談を受け付けています。フルリモートです。スポットや週2〜3時間からでも歓迎で、いろんな案件に携われたらうれしいです。こんな相談、歓迎です。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?