候補は見つかっていたのに、答えを読む所で毎回落ちていた:200 トークンで切れた URL と、ハイフンで 400 になる検索

English version

トレカダッシュ 開発の記録 / 2026年8月

iOS アプリ「トレカダッシュ」の、まとめサイト由来の記事は、お店の公式の告知のページへ、リンクを張り替えます。ところが、開発者モードの報告が、続けて 7 件、来ました。「正しい告知の URL は、これ。ちゃんとやって」。

調べると、候補は見つかっていたのに、答えを読む所で、毎回落ちていました。この記事は、その真因と、同じ時期に見つけた、よく似た 1 件の記録です。

数字は、2026 年 8 月 23 日と 24 日の作業の記録から書いています。

真因:AI の返事が、200 トークンで途中で切れていた

公式の告知ページを選ぶ処理は、最後に AI に、「候補のどれが、そのお店の告知か」を答えさせます。その返事の長さの上限(max_output_tokens)を、200 にしていました。

ところが、返事には、日本語をパーセント符号化した、長い URLが入ります。1 つで 200 文字を超えます。返事は途中で切れ、JSON として読めなくなり、Unterminated string in JSON という例外になっていました。

WARN [応募リンク] 公式ページの判定に失敗 [お宝創庫・プレイズ / …]: Unterminated st…
→ 対象 10 件、すべて「見つからず」

候補は、見つかっていたのです。答えを読むところで、毎回、落ちていました。上限を 800 に上げました。さらに、それでも切れたときに、全部を捨てず、"url": "… の部分だけを拾い直す救済も入れました。

直しても、採用が 0 件だった:AI が指示に忠実だった

JSON を直しても、採用は 0 件でした。ログを見ると、候補はあるのに、「採用なし」です。原因は、AI が、指示に忠実だったことでした。お店の告知は、こういう書き方をします。

「【アプリ会員様限定】再版/ポケモンカードゲーム 4 種 抽選販売に関して」

個別の商品名を書いていません。指示には、「商品が違う場合は、選ぶな」とありました。AI は、それに従って、拒否していたのです。

2 つ直しました。

  1. 商品名で絞った検索に加えて、いつも、site:店のドメイン 抽選 も検索して、候補にまとめる。(「空振りしたときだけ」では、無関係なページが 1 件返るだけで、発動しませんでした。)
  2. 指示に、「その店自身の告知のページが、複数の商品をまとめて案内していて、個別の名前を書いていないときは、選んでよい」を足す。ただし、ほかの店やまとめサイトは、まとめて案内していても、絶対に選ばない。

結果は、10 件のうち、3 件が、お店の公式の告知のページへ張り替わりました。

もう 1 つ、アプリ限定の店(アプリでしか、抽選の案内を出さない店)のために、「アプリでご確認ください」と出せる一覧を作りました。アプリが実在すると分かっている店だけです。推測で足しません。

よく似た 1 件:楽天のキーワード検索が、ハイフンで丸ごと失敗していた(8 月 24 日)

ログに、「楽天市場の個別弾の検索に失敗しました」が、遊戯王だけで 8 種以上、繰り返し出ていました。調べると、楽天の API は、検索のキーワードのハイフンの使い方によっては、リクエスト自体が 400 wrong_parameter で失敗しました。

キーワードの形結果
"A - B"(ハイフンの前後に空白)400
"A B "(末尾に空白だけ残る)400
"A B-"(末尾がハイフンで終わる)400
"AB-"(空白を挟まない単語 + 末尾ハイフン)200(正常)

遊戯王の商品名は、「LIMIT OVER COLLECTION - THE RIVALS -」のように、副題をハイフンで挟む書き方が多く、この形の弾は、個別弾の検索から、一度も拾えていませんでした。

直し方は、2 段階です。(1) ハイフンの直後の空白を詰める。(2) 末尾に残るハイフンと空白を落とす。「LIMIT OVER COLLECTION - THE RIVALS -」は、「LIMIT OVER COLLECTION -THE RIVALS」になり、200 を確かめました。同じ問題は、楽天ブックスの API でも、起きることを確かめたので、同じ整形を、キーワードを渡す 4 つの関数に当てました。

分かったこと

候補が見つかっているのに、結果が 0 件のときは、答えを読む所を疑う。

この話に出てくるもの

ほかの記録

コメント

感想や、記事の間違いの指摘は、ここへ。書くには、GitHub のアカウントが要ります。

押すと、giscus(giscus.app)と GitHub に接続します。押さなければ、接続しません。詳しくはあつかいに書いています。