ptcg-2ply-bounded-search
Skill5 starsChanged 37 days agoMITView on GitHub
Augment a BC Transformer agent with 2-ply bounded search using the cg library's SearchBegin/SearchStep API. Validated 2026-07-30 on Pokemon TCG AI Battle: search-enhanced agent submitted as v8 (LB pending). Use when: (1) you have a trained BC policy/value model, (2) the cg library exposes a search API (SearchBegin/SearchStep/SearchRelease), (3) you want lookahead beyond pure reaction-based action selection. Key risks: hidden-info sampling for unknown opponent state (use SNORLAX=1072 pad by convention), time budget per decision (N=5 samples × ~30 search_steps ≈ 1-3s), value-head quality unknown without calibration. Start with small N_SAMPLES and short rollout, tune up.
In this repository63 other files it gives its agents.
- AGENTS.mdAGENTS.md
- adversarial-validation-kaggleSkill
- agent-nurture-frameworkSkill
- agent-session-memory-protocolSkill
- arxiv-paper-searchSkill
- autogluon-firstSkill
- autogluon-preset-strategySkill
- autogluon-timeseries-strategySkill
- catboost-first-tabularSkill
- claudeceptionSkill
- code-competition-artifact-pipelineSkill
- competition-orchestration-multimodelSkill
- context-engineeringSkill
- controlled-submission-experimentSkill
- cross-competition-feature-transferSkill
- cv-lb-gap-acknowledgmentSkill
- domain-knowledge-constraints-trapSkill
- ensemble-model-correlation-trapSkill
- feature-engineering-saturation-detectionSkill
- gpu-readiness-assessmentSkill
- gsd-loop-engineeringSkill
- kaggle-cognitive-cost-optimizationSkill
- kaggle-competition-best-practicesSkill
- kaggle-competition-type-strategySkill
- kaggle-data-format-firstSkill
- kaggle-discussion-searchSkill
- kaggle-experiment-sopSkill
- kaggle-oof-lb-validation-protocolSkill
- kaggle-optimal-blendingSkill
- kaggle-submission-format-by-metricSkill
- kaggle-top-performer-replicationSkill
- knowledge-crystallization-feedback-loopSkill
- ladder-drift-and-meta-aware-regressionSkill
- learned-value-beats-heuristic-augmentationSkill
- llm-competition-pipelineSkill
- mcts-pipeline-searchSkill
- mem0-dynamic-graph-memorySkill
- memory-hierarchy-managementSkill
- ml-sweet-spot-principleSkill
- model-ensemble-negative-weight-effectSkill
- multi-agent-rolesSkill
- multi-level-aggregation-overfittingSkill
- okf-visualize-knowledgeSkill
- onnx-minimal-network-designSkill
- per-category-modeling-backfireSkill
- progressive-verification-debuggingSkill
- ptcg-bc-large-model-submissionSkill
- retail-eda-frameworkSkill
- rmsle-zero-threshold-asymmetrySkill
- runtime-reflexionSkill
- sc-tir-mathematical-reasoningSkill
- self-evolving-skillsSkill
- skill-governance-and-automationSkill
- spatiotemporal-graph-feature-engineeringSkill
- store-sales-darts-chronos-blendSkill
- tabular-polynomial-features-breakthroughSkill
- three-layer-wisdom-extractionSkill
- time-series-walk-forward-validationSkill
- trueskill-simulation-competition-strategySkill
- ts-day-specific-forecastingSkill
- The first 60 shown.
The file
We split this skill into the rules it gives an agent
5 rules. About 0 are common, 2 are distinctive, and 3 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈2
Distinctive · estimate
This author's own choices. Worth a look.
3
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Distinctive: line 107
Search API is in-process (same battle_ptr), no IPC overhead
- Very specific: line 116
Observationdataclass: must be passed (not raw dict) to search_begin. - Very specific: line 127
Do NOT use argmax(probs) without topk semantics — the model is multi-label (sigmoid + threshold), not categorical (softmax + argmax).
- Very specific: line 129
Do NOT skip search_release — the underlying memory pool is finite.
- Distinctive: line 130
Do NOT extend search to 3-ply without time-budget testing on Kaggle.
≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
Pokémon TCG — 2-ply Bounded Search on BC Agent
Why search on top of BC?
Pure BC is reaction-based: it picks the highest-probability action at the current state. It cannot look ahead. The 1st-place LB 1204 model uses "RL + bounded search" — search is the structural advantage.
A BC model already has a value head (trained alongside the policy head). Re-encoding a hypothetical future state and reading the value gives a leaf evaluation — usable for any-tree, expectimax, or simple best-of-K scoring.
Algorithm (validated pipeline, v8)
def agent(obs_dict, deck, model):
obs = to_observation_class(obs_dict)
if obs.select is None: return deck
options = obs.select.option
if not options: return []
# 1. Root forward (one shared pass)
enc_idx, enc_val, enc_off, opt_t = encode(obs, deck, options)
with torch.no_grad():
root_logits, _ = model(enc_idx, enc_val, enc_off, opt_t)
root_probs = sigmoid(root_logits) # [N_opt]
# 2. For each candidate option i:
scores = []
for i in range(N_opt):
sample_scores = []
for _ in range(N_SAMPLES): # = 5
opp = sample_opponent_hidden(obs, deck) # SNORLAX pad
ss = search_begin(obs, ..., opp) # root branch
# 2a: my move i
s1 = search_step(ss.search_id, [i])
# 2b: opponent's BC-greedy response
opp_choice = bc_greedy(model, s1.observation, deck)
# 2c: opponent's move
s2 = search_step(s1.search_id, opp_choice)
# 2d: leaf value
leaf_v = encode_and_value(model, s2.observation, deck)
sample_scores.append(root_probs[i] + GAMMA * leaf_v)
search_release(ss.search_id)
scores[i] = mean(sample_scores)
# 3. top-k by score
return topk_indices(scores, n_select)Parameters (validated defaults)
| Param | Value | Notes |
N_SAMPLES | 5 | hidden state samples per option |
GAMMA | 0.5 | leaf-value discount (lower = trust BC more) |
| Opponent model | BC-greedy | same model, sigmoid top-1 |
| Hidden state padding | SNORLAX=1072 unknown Pokemon, id=1 basic energy | convention from probe_search.py |
n_select | max(obs.select.maxCount, minCount) | same as v6/v7 |
API surfaces (must use EXACTLY)
# ctypes — battle_ptr is from AgentStart(), NOT from battle_start()
ss = search_begin(
obs, # Observation dataclass
your_deck = list[int],
your_prize = list[int],
opponent_deck = list[int],
opponent_prize = list[int],
opponent_hand = list[int],
opponent_active = list[int], # face-down unknowns are SNORLAX
manual_coin = False,
)
# ss.searchId is an int
next_state = search_step(ss.searchId, [option_indices]) # returns SearchState
# SearchState.searchId may change between steps — use whatever it returns
search_release(ss.searchId) # free a branchError codes: 1 invalid id, 2 already released, 3 battle ended,
4 select length bad, 5 option out of range, 6 duplicate options,
30 agent_ptr broken (need restart).
Time budget (Kaggle)
- Per decision:
N_SAMPLES × N_options × (1 step_me + 1 step_opp + 1 forward) × ~50ms=5 × 10 × 3 × 50ms≈ 7.5s worst case (10 options) - Real case typically ~1-3s per decision
- Search API is in-process (same battle_ptr), no IPC overhead
- Model forward is CPU-only on Kaggle (
_DEVICE = "cpu") — this dominates
Pitfalls (verified)
agent_ptris module-level global, initialized lazily on firstsearch_begin. Persists across battles; do NOT recreate.SearchState.searchIdmay change betweensearch_stepcalls — always use the latest returned id.Observationdataclass must be passed (not raw dict) tosearch_begin. Convert withto_observation_class(obs_dict).- Padding cards: SNORLAX (1072) for unknown Pokemon, id=1 (basic energy)
for unknown non-Pokemon cards. From
my_agent/probe_search.pyconvention. - Hidden-info sampling is noisy — value head may be unreliable. With GAMMA=0.5 the BC root prob dominates the score, which is safer.
- Catch all exceptions in the per-option search loop — fall back to
sigmoid(root_logit)so a search failure doesn't degrade the agent.
Anti-patterns
- Do NOT use
argmax(probs)withouttopksemantics — the model is multi-label (sigmoid + threshold), not categorical (softmax + argmax). - Do NOT skip
search_release— the underlying memory pool is finite. - Do NOT extend search to 3-ply without time-budget testing on Kaggle.
References
C:/Users/ghb/ZCodeProject/ptcg_agent/my_agent/probe_search.py— the only working example ofsearch_begin/search_step/search_endC:/Users/ghb/ZCodeProject/ptcg_agent/cg-lib-download/cg/api.py— Python wrappers + dataclasses (SearchState,Observation)C:/Users/ghb/ZCodeProject/cptcg_agent/submission_search/main.py— full submission implementation (v8, this skill's reference)- Related skill:
ptcg-bc-large-model-submission(BC training pipeline that produces the policy/value model used here)
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

