本文へスキップ
Articles

2026-08-20 公開 / AI活用

AIに一覧を作らせると、調べ落としは「該当なし」と同じ顔で返ってくる

20件ほどの対象について「今こういう募集が出ていないか」を毎日AIに調べさせ、一覧にする仕組みを動かしていました。ある日たまたま自分でネットを見ていて、一覧に出ていない募集を見つけました。調べたら、対象20件強のうち14件が、一度も結果に出ていませんでした。壊れてはいません。毎日ちゃんと動いて、毎日それらしい一覧を出していました。原因は指示文のたった1行です。

何が起きていたか

仕組みはよくある形です。調べてほしい対象をリストにして、「この対象それぞれについて、今出ている募集を調べて、決まった形式のJSONで返して」とAIに投げる。返ってきたものを検証して保存し、画面に並べる。

指示文の最後のほうに、私はこう書いていました。

見つからない対象は無理に作らず、その対象は結果から省く。

これはでっち上げを防ぐために書いた行です。実際その目的では機能していました。ありもしない日付やURLを作られるよりずっといい。

ただ、この書き方だと出力はこうなります。

この2つが、受け取る側からは完全に同じ見た目になります。どちらも「その対象の行が無い」だけです。画面には何も出ないので、異常だと気づく材料がありません。エラーも出ません。処理は成功しています。

なぜ調べきれないのか

20件強を1回の指示にまとめて投げていたのが直接の原因でした。AIは上から順に調べますが、全部を回りきる前に「もう十分だろう」という判断で出力に入ります。これは能力の問題というより、1回の応答で使える手数に限りがあるためです。

実際に分けて投げ直したら、それまで一度も出てこなかった対象から、その場で情報が取れました。対象が悪かったのでも、情報が無かったのでもありません。順番の後ろにいたから、そこまで到達していなかっただけです。

そして先ほどの1行があるので、到達しなかった対象は「見つからなかった」として静かに省かれます。ここが噛み合うと、「毎日正常に動いている、中身が欠けた一覧」ができあがります。私の場合、それが半年近く続いていました。

対策1: 対象を分けて、何回かに分けて聞く

いちばん効いたのはこれです。20件強を1回で聞くのをやめ、6件ずつ4回に分けました。1回あたりの担当が減るので、最後まで到達します。

分けるときに気をつけた点が2つあります。

分割数は「1回あたり何件までなら最後まで到達するか」で決めます。私は6件にしましたが、対象1件あたりの調査量によって変わります。まず全部を1回で投げたときの結果と、分けたときの結果を比べれば、到達していたかどうかはすぐ分かります。

対策2: 対象ごとに「調べた」記録を残す

分割は再発防止になりません。件数が増えればまた同じことが起きます。必要なのは「調べたのに0件」と「調べていない」を区別できる記録です。

私は対象ごとに、次の3つを別ファイルに持たせました。

この3つがあると、状態を4つに分けられます。

そしてこの一覧を画面に出しました。問題のある対象が上に来るように並べています。今回のように「一度も取れていない対象が14件ある」という状態は、この画面があれば初日に分かります。

画面に出すときは「未取得=募集が無いという意味ではない」と明記しておくと良いです。ここを取り違えると、せっかく可視化しても「そういうものか」で流してしまいます。

対策3: 「0件」を失敗として扱わない

これは分割した後に出てきた問題です。分ける前は、全対象を1回で聞くので結果が完全に空になることはまずありませんでした。そのため私は「空の配列が返ってきたら異常」という判定を入れていました。AIが質問を返してきたり、指示を理解できずに何も出さないケースを捕まえるためです。

ところが分割すると、「この6件には今どこも募集が無い」が普通に起きます。正しい答えである空の配列が、毎回「失敗」と判定されるようになりました。私の場合はそこから予備の手段に切り替える作りだったので、正しい0件のたびに予備側を無駄に消費していました。

直し方は、この2つを分けることです。

分割は「1回あたりの担当を減らす」変更ですが、同時に「空が正常になる」という副作用を持ち込みます。判定を見直さないと、分割した分だけ無駄が増えます。

分割で増えるもの

正直に書くと、分けた分だけ呼び出し回数は増えます。1回だったものが4回です。所要時間も、私の環境では全体で2分程度だったものが11分程度になりました。1日1回動かす用途なので許容していますが、頻繁に回すなら効いてきます。

それと、短時間に連続で呼ぶと制限に当たりやすくなります。実際、検証のために立て続けに2回動かしたときは、後半の回が失敗しました。分割は「1回あたりを軽くする」代わりに「呼ぶ回数を増やす」ので、間隔のほうに余裕を持たせておく必要があります。

これは自動化全般の話でもある

今回の件で私が反省したのは、分割の設計より「出力を見て正常だと判断していた」ことのほうです。毎日それらしい一覧が出ていたので、動いていると思っていました。

ですが一覧は「取れたもの」しか映しません。取れなかったものは、定義上そこに映らない。つまり出力を見ている限り、欠損は永久に見えません。見るべきだったのは出力ではなく、「聞いた対象」と「返ってきた対象」の差でした。

これはAIに限った話ではなく、スクレイピングでも、外部APIをまとめて叩く処理でも同じです。収集する自動化を書くときは、成果物とは別に「網羅率」を持つ。今回いちばん学んだのはここでした。

持ち帰れること

一覧を作る自動化は、動いていることの確認が「一覧が出ていること」になりがちです。ですが一覧が出ていることと、一覧が正しいことは別でした。何が載っていないかを教えてくれる仕組みを、成果物とは別に持っておくのがおすすめです。