はじめに
Kaggle CLI が HTTP 429 を返したとき、ルールには「止まって報告」と書いてありました。
エージェントは、こう言って次のコマンドを出しました。
「429 は即死エラーではない。ノートブックのコードエラーでもない。原因を確認する。」と言って、さらにCLI操作を続けました。
文章の注意書きだけでは足りない、と思ったのはこの文章です (´・ω・\)`
429 が公式でどう書かれているかと、次の Kaggle CLI を 10 分出せなくした経緯を残します。
この記事で分かること:
- 429 は「リクエストが多すぎる」という API の返事であること
- アカウント停止(垢バン)は公式の Rate Limits には無く、X (旧Twitter)上の推測であること
- 待ち時間の下限を 10 分にした理由
- ラッパーとシェルフックで、次の CLI を拒否する流れ
想定読者
- エージェントに Kaggle CLI を叩かせている方
- 429 のあと「エラーではないので続行する」と言われた方
- 制限の秒数を公式で探して、見つからなかった方
429 は、サーバーが「多すぎる」と言っている
HTTP の 429 はステータスコードです。意味は Too Many Requests、リクエストが多すぎる、です。
呼び出した API が返した返事です。
公式に書いてあること
Kaggle の Public API に Rate Limits の節があります。
https://www.kaggle.com/docs/api
書いてある対処は次の 3 つです。
- 数分待って、あとでもう一度試す
- 意図しないループや、同じ呼び出しの繰り返しがないか見直す
- サイト側の不具合だと思ったら Product Feedback に報告する
制限の回数も秒数も、このページには出ていません。
API の issue では、Kaggle 側が、上限は時期で変わるので数字は出せない、429 のあとは少し待って再試行する、と説明しています。
CLI の案内も同じ方向です。429 のときは You have been rate limited. Wait a little while before retrying. と出ます。
公式が公開している待ちの目安は「a few minutes(数分)」までです。この記事の 10 分は、公式の秒数ではありません。手元のインフラで決めた下限です。
アカウント停止の話は、X 上の推測
X(旧 Twitter)で、「429 を繰り返すとアカウントが止まるのでは」という推測を見かけました。
特定の投稿は引用していません。真偽は、私には確認できていません。
公式の Rate Limits に書いてあるのは、待って、呼び出しを見直すことまでです。
別ページの コミュニティガイドライン には、スパムやカーネル資源の乱用でアカウントが止まり得る、と書いてあります。429 の説明文とは別のページです。
X の推測が本当かは未確認のままです。⇒ それでも、429 の直後にエージェントが CLI を足す状態は残したくありませんでした。公式が先に言っているのは、待つことと、呼び出しの見直しだからです。
ルールに書いても、エージェントは続けた
Skill と Rule には、以前からこう書いてありました。
- HTTP 429 を見たら停止して報告する
- API・kernel の version・submit を、独断でやり直さない
返ってきた解釈は、「即死ではない」「ノートブックのコードエラーではない」でした。
ステータス確認やログ取得は、作業の続きに見えます(笑)
どちらも Kaggle CLI なので、429 をもう一度もらい得ます。
文章の「止まれ」は、モデルが読んでから解釈します。
公式が「少し待てば再試行できる」と言っているので、「即死ではない」は筋が通っています。
その筋が通ったまま、待ち時間がゼロの再試行になっていました。
指示の置き場を分ける話は、Cursor の 5 レイヤー に書きました。
Rule は文章です。Hook は、次の操作を拒否できます。
書いてあることと、次のシェルが出ることは、別でした。
「429 で停止」と書いてあっても、次のコマンドを出せるなら、エージェントは理由を付けて出せます。ログ取得も、その一手です。
次の Kaggle CLI を、10 分出せなくした
止める場所は 2 つです。CLI のラッパーと、シェル実行の直前のフックです。
ラッパーが停止ファイルを書く
Kaggle CLI は scripts/kaggle-cli.ps1 経由にしています。
ラッパーはコマンドの出力を受け取り、429 らしい文言があるかを見ます。
見るのは、だいたい次です。
Too many requests429 Client Error-
HTTP 429や、ステータスコードが 429
見つけたら、再開時刻を .cursor/kaggle-api-429.stop に書いて終了します。このファイルは Git に入れません。
待ち秒数はこう決めています。
- 下限は 600 秒(10 分)
- 応答に
Retry-Afterがあり、その秒数が 600 より大きいときは、そちらの秒数 -
Retry-After: 30のように短い値でも、下限の 600 は切らない
Retry-After が短いと足りない、という話は CLI の issue にあります。その後 Kaggle 側は、ヘッダの値を直したと返しています。ヘッダが正しくても、数秒で次を出すエージェントには短いです。下限はこちらで固定しました。
フックが時刻まで拒否する
Cursor の beforeShellExecution が、コマンドの前に動きます。
対象は kaggle-cli.ps1 と、生の kaggle です。
停止ファイルがあり、until が未来なら拒否します。ファイルはそのまま残します。
拒否メッセージには、その時刻まで再試行しないこと、ログを取りに行かないこと、push しないこと、を書いています。読むのはエージェントです。
時刻を過ぎた次の CLI では、ファイルを消してから、いつもの許可判定に進みます。手動でファイルを消す手順は置いていません。
生の kaggle は、待ちが終わったあとも別ルールで拒否したままです。通すのはラッパーだけです。待ち時間中は、どちらにも 429 用の拒否が先にかかります。
4294967295 は HTTP 429 ではない
PowerShell では、終了コード -1 が符号なしで 4294967295 と出ることがあります。
先頭が 429 なので、雑に検索するとレート制限に見えます。こちらはラッパー側の異常で、HTTP の 429 とは別扱いにしています。
待ち時間のテストで見ていること
- 出力が
exit 4294967295だけのときは 429 とみなさない -
Retry-After: 30のとき、待ちは 30 秒にせず 600 秒 -
Retry-After: 900のときは 900 秒
ルールの文面も、仕組みに合わせました。
- HTTP 429 は停止して報告。独断の retry は禁止
+ 次の Kaggle CLI は 10 分拒否する。Retry-After が長ければその秒数。時刻後は自動で再開する。手動解除はしない
「停止して報告して終わり」のままだと、10 分後に自動で再開する仕組みと文面が食い違います。
エージェントは、古い文面の方を読むことがあります。
まとめ
429 は、API が「多すぎる」と返した返事です。
公式は、数分待って呼び出しを見直せ、と書いています。秒数は非公開です。
「即死ではない」と解釈されると、文章の「止まれ」は通りません。
次の CLI を時刻まで拒否すると、待つしかなくなります (=^・ω・^=)
X 上の垢バンは推測です。公式の Rate Limits には書いてありません。
次の CLI を出せない状態まで作っておく、で十分でした ´▽`