2026-06-17 セッション 1: 参戦方針の決定とドキュメント基盤構築
今日やったこと
- リポジトリ初期状態を確認 (pyproject.toml, 当時の空の
main.py, サンプル
reinforcement-learning-and-mcts-sample-code.ipynb)。uv
セットアップ済みだが依存はまだ空。
- Kaggle コンペ「Pokemon TCG AI Battle
Challenge」と CABT エンジン (松尾研) のドキュメントを通読 (WebFetch で取得できた範囲)。
- サンプル ipynb (MCTS + Transformer + 自己対戦) を完全に読解。
- サンプル仕様:
MyModel =
d_model=128, heads=2, layers_enc=1, layers_dec=1。SEARCH_COUNT=10。5 イテレーション × 100
self-play で random 相手 76% 勝率まで到達 (notebook 出力済)。
- サンプルの 2 つの弱点を発見 (後で Codex レビューで再確認):
- 隠し情報サンプリングが「雑な determinization 1 本」。相手 deck/hand/prize は Snorlax
(id=1072) / Basic Energy (id=1) 固定。
- policy target が visit 分布ではなく、
child.total/visit - root.total/visit
で作っており、直前の NN policy 出力に強く依存
する自己回帰的ループになっている (AlphaZero の標準実装ではない)。
- 関連研究を WebSearch で広く調査: IS-MCTS, Determinized UCT, AlphaZero/MuZero, DeepStack/Pluribus
(CFR), Suphx (Mahjong, oracle guiding), DouZero+, Hearthstone/MTG AI, Pokemon Showdown (poke-env,
MIT thesis 等), CCG taxonomy。
- Codex (gpt-5.4-codex) で計画レビューを依頼し、以下 3 つの指摘を取り込んだ:
- belief 改善 (IS-MCTS 化) を Phase 2 へ前倒し。
SEARCH_COUNT 拡大より優先。
- 学習 target を visit 分布へ修正。policy head の loss を HuberLoss → CE/KL へ。
- ヒューリスティクス / デッキ研究を前倒し、モデル巨大化は後ろへ。
- 計画書を
/Users/ryo/.claude/plans/...からdocs/PLAN.mdへコピーし、以後はこのファイルを参照する。
- 参考文献を
docs/references.md として独立化。
docs/{journal,exploration,decisions}/
の構造とセッション連続性ルール (開始時に PLAN+journal 読む / 終了時に journal 書く / 重要判断は decisions/NNNN-*.md) をプラン内で確定。
- CABT の使い方とローカルシミュレーション手順を
docs/exploration/cabt-local-simulation.md に整理。
sample/ を新設し、最小サンプル一式を追加。
- sample/README.md
- sample/deck.csv
- sample/run_local_battle.py
- sample/render_kaggle_html.py
uv run python -m py_compile ... でサンプル 2 本の構文確認を実施。
uv run python sample/run_local_battle.py を実行し、cg-lib
未指定時に案内メッセージで止まることを確認。
uv run python sample/render_kaggle_html.py を実行し、kaggle_environments
未導入時に案内メッセージで止まることを確認。
- 添付の beginner notebook をもとに、最初の valid submission 導線を docs / sample に追加。
- docs/exploration/first-valid-submission-guide.md
- sample/submission_main.py
- sample/build_submission_bundle.py
uv run python sample/build_submission_bundle.py
を実行し、sample/submission.tar.gz が main.py と deck.csv
を含むことを確認。
- CABT 用の Linux 実行環境を Docker で追加。
- Dockerfile.cabt
- scripts/run_cabt_docker.sh
- docs/exploration/cabt-docker-runtime.md
bash scripts/run_cabt_docker.sh --max-steps 10 を実行し、Docker 上の Linux amd64 環境で
sample/run_local_battle.py が起動して Battle started. まで進むことを確認。
sample/render_kaggle_html.py の初期デッキ返却バグを修正し、sample/result.html の stderr から
TypeError が消えることを確認。
kaggle_environments の CABT package を調べ、html_renderer() が参照する
visualizer/default/dist/index.html / cabt.js が pip 配布物に含まれていないため、result.html
が共通プレイヤー UI のみになることを確認。
- Docker 内で動くリアルタイム viewer を追加。
- sample/realtime_server.py
- scripts/run_cabt_viewer_docker.sh
bash scripts/run_cabt_viewer_docker.sh
で viewer サーバーを起動し、http://127.0.0.1:8000/api/state から JSON が返ることを確認。
tcg-replay-viewer.ipynb の画像抽出ロジックをベースに、Card_ID List_JP.pdf
から必要カードだけ切り出して使うローカル viewer 生成スクリプト
sample/render_local_viewer.py を追加。
- Docker から同じ viewer を生成できるショートカット
scripts/render_local_viewer_docker.sh
を追加し、Dockerfile.cabt に
pymupdf / Pillow / flask を追加。
- 公式 viewer 系のファイル (sample/official_replay/index.html
/
gameVisualizer.js) を流用して local
battle を replay できる sample/export_official_replay.py
と scripts/render_official_replay_docker.sh
を追加。
- sample/realtime_server.py を拡張し、ブラウザ上で option
index を選択して
battle_select() できる手動プレイ導線を追加。
学んだこと / 観察したこと
コンペの構造 (二次情報、Phase 0 で公式確認すべき)
- 2 部門制: Simulation Category (AI agent 提出) と Strategy Category
(レポート提出、賞金あり)。後者があるため、設計判断の都度ドキュメント化することが直接スコアに効く。
- 賞金: 第 1 ラウンド上位 8 チーム各 $30,000、グランプリ $50,000、総額 $300,000+ と報道。
- タイムライン: 第 1 ラウンド 2026年6月〜8月、最終締切 2026年9月14日と報道。
- カードプール: スタンダードの約 2,000 枚。
- 主催の公式コメント (Overview): 「相手手札不明が最大の課題」「ルールベース単独不可」「novel
methods を推奨」。
技術的に重要な知見
- Determinized UCT は strategy fusion に弱く、IS-MCTS の方が品質高い (Cowling 2012, Dou Di
Zhu での比較)。ただし IS-MCTS は実装コストが高い → 段階的に Determinized → SO-ISMCTS
が現実的。
- Suphx の oracle guiding: 学習時のみ完全情報で auxiliary
head を学習する手法。提出 inference には影響しないが学習品質を底上げ。
- MIT thesis (2024): Pokemon Showdown ランダムバトルで PPO 単体 1677 → PPO+MCTS lookahead 1756
(Glicko-1)。MCTS 併用が効くことの数値証拠。
- CABT の公式 docs には
kaggle_environments.make("cabt") と env.render(mode="html")
を使った HTML 出力例があり、Kaggle 風の見た目確認は「動画」より「HTML リプレイ」と捉えるのが自然。
- ローカル直接対戦の最小 API は
battle_start() → battle_select() のループ → battle_finish()
で十分組める。
- いまの repo には
cg-lib
が含まれていないため、ローカル実行の成否は Kaggle 配布物の取得可否に依存する。
- beginner notebook の観点では、最初の目的は「強さ」ではなく
submission.tar.gz
の構造理解。main.py と deck.csv だけでも提出 bundle の形は再現できる。
cg/libcg.so は Linux x86_64 ELF なので、Apple Silicon / macOS では直接読めないが、Docker の
linux/amd64 ならそのまま動かせる。
- CABT の
env.render(mode="html") は試合データ生成まではできるが、pip 版 kaggle_environments
に CABT 専用 renderer asset が欠けているため、ローカルでは完全な盤面描画にならない。
- その代替として、
obs.current / obs.select / obs.logs / visualize_data()
をブラウザへ配信する自前 viewer は十分実用になる。
サンプルコード詳細 (Phase 3-A 移植時に参照)
- 状態エンコード:
SparseVector で EmbeddingBag
入力。ベンチ 8 枠 + アクティブ + プレイヤー状態 + 手札 + デッキ + スタジアム を順に並べる。
- アクションエンコード:
OptionType ごとに decoder_main_feature
(PLAY/ATTACH/EVOLVE/ABILITY/DISCARD/RETREAT) と decoder_card_offset
(CARD/TOOL/ENERGY/SKILL) で領域分け。
- MCTS: UCB に似た
v + c * prior / (1 + visit)、c = 0.4 * sqrt(parent.visit)。
- λ=0.9 で value をブートストラップ (
value = value * λ + sample.value * (1 - λ))。
次にやること (Phase 0 残り)
直近 (次のセッション最初)
- [ ]
docs/decisions/0001-staged-extension-approach.md を書く (本セッション内で着手予定)
- [ ]
docs/decisions/0002-determinized-then-ismcts-roadmap.md を書く (本セッション内で着手予定)
- [ ] Kaggle Notebook で
cg-lib の実在パスと配布形態を確認し、sample/run_local_battle.py
の想定とずれていないか検証
- [ ]
sample/render_kaggle_html.py を Kaggle 上で実行して result.html の見え方を確認
- [ ]
sample/submission.tar.gz を Kaggle Notebook 側に持ち込み、最小提出 bundle として通るか確認
- [ ] Docker 環境上で
sample/render_kaggle_html.py 相当の HTML 出力まで再現できるか確認
- [ ]
sample/realtime_server.py にカード画像や option のカード名解決を足して viewer を見やすくする
- [ ] Phase 0-A: Kaggle Overview / Data / Rules ページから 公式情報
(提出形式、制限時間、カードプール、賞金、評価方式) を確定し
docs/exploration/competition-rules.md に記載
- [ ] Phase 0-A: Kaggle Discussion を 1 周ざっと眺めて主催アナウンス・既知バグ・参加者 tips を
docs/exploration/discussion-notes.md に記録
Phase 0 残作業
- [ ] Phase 0-B:
cg-lib 入手と配布形態確認 (Kaggle Notebook 上で確認)
- [ ] Phase 0-C:
notebooks/00_api_exploration.ipynb を作って all_card_data / all_attack /
Observation の中身を実観察
- [ ] Phase 0-D:
notebooks/01_card_dictionary.ipynb で全カード一覧と環境上位デッキ候補メモ
- [ ] Phase 0-E:
notebooks/02_one_game_trace.ipynb
で 1 試合手動トレース (option を print して手で index 選ぶ)
- [ ] Phase 0-F:
search_step レイテンシを time.perf_counter で計測 →
docs/exploration/search-api-latency.md
- [ ] Phase 0-G: ポケカ要素 ⇔ API マッピング表を埋める
- [ ] Phase 0 完了基準のチェック (PLAN.md 参照)
行き詰まり / 未解決
cg-lib のローカル入手手段が未確定: Kaggle
Notebook 内でしかインストールパスが取れない可能性がある。Phase 0-B で要確認。
- Kaggle コンペページの本文を WebFetch で取得できない (JS レンダリングの可能性)。Kaggle
Notebook 経由か、ブラウザで手動コピーして
docs/exploration/competition-rules.md
に貼り付ける運用に。
- MPS で EmbeddingBag が動くかは未確認。Phase 1 冒頭で確認、ダメなら CPU フォールバック確定。
- デッキレシピが事前公開かどうかが未確認。これが分かると相手 deck の belief 初期化方法が変わる。Phase
0-A で要確認。
- Strategy Category の評価基準・締切が未確認。Simulation と同じ 9/14 締切かは不明。Phase
0-A で確認必要。
参考リンク
- docs/PLAN.md — 本計画 (この session の決定がベース)
- docs/references.md — 参考文献
- 計画原本:
/Users/ryo/.claude/plans/https-www-kaggle-com-competitions-pokemo-staged-fiddle.md
(Claude Code が plan mode で生成。以後の改訂は docs/PLAN.md 側で行う)