Pleiades 队:这是我们参加 GOSIM 2026 Agentic Observer 时的实验仓库。参赛智能体(最终版本 c48)、各版本提交说明和决赛复盘在 formal_v4/pleiades/。 下文"不追求奖项、程序不使用大模型"是 2026-10-03 时的研究目标,后来改变了:最终版本在数值优化执行层之上,用大模型(DeepSeek)通读值班日志,由代码换算时刻并确认后报修。本页其余内容是 v3 入门套件和早期研究的记录。 我们写的代码采用 MIT 许可证(LICENSE);仓库里来自主办方的材料(v3 入门套件、官方示例、卡片与赛题数据等,见 formal_v4/ATTRIBUTION.md)仍按主办方的 CC BY-NC 4.0。
**正式规则已经改变任务和提交方式。**完整核实见 FORMAL_RULES_20261003_ZH.md:只收完整项目、v4 自选指向与光纤目标、逐轮提供信息、每卡 900 秒、平台 2 核 CPU/2 GB,允许外部算力;评奖要求至少两个大模型驱动环节,最终排名只看隐藏卡 E–H。本仓库现有求解代码与下文的分数、上界仍属于旧 v3 实例,不能直接提交或用于估计正式成绩。
**本队研究目标:**按用户 2026-10-03 的明确要求,不追求奖项,采用数学模型、传统算法或传统神经网络提高成绩,程序不使用大模型;同时研究可行分与可证明上界的差距。赛事的评奖资格要求不作为实现目标。
比赛规则的完整中文抽象见 PROBLEM_ZH.md,精确状态及复杂度见 STRUCTURE_ZH.md。公开练习场当前最好可行路径经官方本地评分器回放得 21,119.494551,文件为 results/practice_best.csv;多起点、事件层精确大邻域搜索与受限列 CP 重组见 EVENT_LNS_ZH.md 和 POPULATION_CP_ZH.md。这条先知路径使用了整季公开天气真值与全部请求。GPU 完整扫描固定 K18 基础上的 1035 个 K20 双天区扩块后,全 17 请求的最紧上界为 21,257.69;少于 17 请求的完整分支证书给出 21,119.25 上界。两者合成对任意合法路径的无条件上界 21,257.69,与可行分尚差 138.195449 分;少于 17 请求的界低于可行分,因此全局最优解必定拿满 17 个可获奖请求。固定首访顺序的基础 DP 见 PATH_DP_ZH.md 和 ACTIVE_REQUEST_DP_ZH.md,其他全局路线见 MULTISTART_LNS_ZH.md。
**历史赛制说明已被取代:**2026-09-24 曾按当时参赛者提供的信息,将正式赛理解为可取得完整真值后提交先知轨迹。2026-10-03 核实的官网正式规则 2.0 明确只接受完整项目,并保密未来天气、事件和故障;当前研究结果只对应旧 dev-reference。正式 v4 必须重新建模,详见上方新规则记录。
冲击离线最优的实验顺序、验收指标与上下界账本见 ORACLE_ITERATION_ZH.md。
只使用已发布快照的在线策略为 agent/model_policy.py,模型及独立场景验证见 MODEL_POLICY_ZH.md。python3 build_submission.py 从版本化源码构建可执行包;包是可再生输出,不保存在 Git。离线求解脚本额外需要 requirements-research.txt 所列依赖,可用 python3 -m venv .venv-solver 后运行 .venv-solver/bin/python -m pip install -r requirements-research.txt 重建本地求解环境。
New to this? Read QUICKSTART.md / QUICKSTART_ZH.md(中文): double-click
run_baseline, editagent/my_strategy.py, drop that one file on the website. This README is the detailed engineering version.
Everything in this folder is what the evaluation platform runs: the same workflow, the same JSON-Lines
transport, the same scorer. A local run on a public scenario reproduces the platform's score_report.json
for the same decisions.csv.
Windows, macOS and Linux are supported (verified on Windows 11 with Python 3.12 from python.org: same scores, byte-identical generated scenarios; the runner uses a thread-based transport there). Python 3.9 or newer and the standard library are enough: the python3 that ships with macOS works as is; on Windows install Python 3.12 from python.org (tick "Add python.exe to PATH"). Only an LLM-backed agent needs the optional packages in
agent/requirements.txt.
| Path | Purpose |
|---|---|
agent/ |
Your agent. my_strategy.py is the one file most teams edit (choose_action); minimal_agent.py is the entry script; decision_graph.py holds the full pipeline and anomaly_detection.py the reference anomaly-reporting layer for those who want more. |
run_baseline.command / .bat / .sh |
Double-click launchers: run the baseline on the bundled scenario and open the replay. |
run_demo_week.command / .bat / .sh |
Same launchers on the seven-night demo scenario: about two seconds, replay short enough to read night by night. |
run_finals_preview.command / .bat / .sh |
Same launchers on scenarios/finals-preview/: the finals mechanics rehearsal. |
challenge/ |
The public environment: contracts, calendar, tile geometry, weather, requests, workflow, scorer, replay renderer. Do not edit. |
scenarios/dev-reference/ |
Public reference scenario: 180 nights, 7,928 slots, 64 tiles, weather truth included. |
scenarios/demo-week/ |
Public one-week demo scenario: 7 nights, 294 slots, 64 tiles, 1 observation request, weather truth included. |
scenarios/finals-preview/ |
Finals-mechanics rehearsal: 7 nights with hidden nova/reddening tags (tile_anomalies.csv shipped here so local scoring works), an instrument fault, per-slot efficiency jitter, score feedback, the report channel and the coverage-evenness term. The unmodified kit scores about 8214.26 here and reports the fault correctly. |
local_runner.py |
Runs an agent through the platform transport on a scenario and scores it. |
score_decisions.py |
Re-scores a decisions.csv (public scenarios only), including its report_* rows. |
make_scenario.py |
Generates new public practice scenarios from a seed. |
fetch_scenario.py |
Downloads any scenario the platform publishes (--list, then fetch_scenario.py dev-fortnight) into scenarios/<slug>/. |
pack_agent.py |
Zips agent/ into the submission package and validates it. |
sac_submit.py |
Uploads a package or a results file to the platform and waits for the score. |
SKILL.md |
Step-by-step instructions an AI coding assistant can follow. |
The platform's practice phase still runs the pre-anomaly rules: its scenarios (dev-reference,
demo-week, dev-fortnight) carry no anomaly tags, publish no score feedback, accept no reports, and a
repeat observation of a completed tile stays invalid there — local runs on the bundled copies reproduce the
platform's practice scores exactly. The online competition scenarios enable the full mechanics described
in this README (hidden tags, instrument faults, repeat observations banking the per-tile maximum, the
report channel). scenarios/finals-preview/ is the rehearsal copy of those rules; the kit's agent and
runner speak both generations automatically, so one agent package works everywhere.
unzip agent-observer-starter-kit.zip && cd agent-observer-starter-kit
python3 local_runner.py --scenario scenarios/demo-week --agent agent/minimal_agent.py --wallclock 900 --out demo_week_output # 7 nights, ~2 s
python3 local_runner.py --scenario scenarios/dev-reference --agent agent/minimal_agent.py --wallclock 600 --out run_output # 180 nights, ~15 sStandard output ends with a JSON summary (with --quiet it is the only output); on the reference scenario the shipped deterministic agent completes
the survey ("termination_reason": "survey_complete") with total ≈ 12287.48 in about 15 s of wall clock.
run_output/ holds decisions.csv (the whole trace — anomaly reports appear as report_* action rows right
after their carrier decision), workflow_result.json, score_report.json, agent.log (your agent's
stderr) and decision_replay.html (open it in a browser to step through every night).
More scenarios keep a strategy from tuning to one weather sequence:
python3 make_scenario.py --out scenarios/mine --seed 7 --days 30 --start-date 2026-10-05
python3 local_runner.py --scenario scenarios/mine --agent agent/minimal_agent.py --out run_mine
python3 score_decisions.py --scenario scenarios/mine --decisions run_mine/decisions.csv
python3 fetch_scenario.py --list # scenarios published by the platform
python3 fetch_scenario.py dev-fortnight # -> scenarios/dev-fortnight/, ready for local_runner.pyEvery scenario (the shipped scenarios/dev-reference/, anything make_scenario.py writes, and the platform's
hidden competition scenarios) has the same layout. local_runner.py and score_decisions.py read it directly.
| Path | Contents |
|---|---|
config/scenario_config.json |
scenario id, seed, competition.global_wallclock_seconds |
config/calendar_config.json |
site (latitude 31.9634°, longitude −111.599°, UTC−7, sun altitude limit −12°), survey start, days, slot_seconds 900 |
config/tile_config.json |
8 regions × 8 tiles, 2 REQUIRED per region (one available for 14 days only), altitude limit 30°, lunar model, target classes, hidden anomaly-tag counts |
config/weather_config.json |
quality processes (instrument efficiency jitters per slot in [0.90, 1.00]), closure model, forecast horizon and error model (12 % misses, 6 false positives), event catalogue |
config/request_config.json |
request cadence (every 7 nights, p = 0.55), deadline classes ONE_WEEK / TWO_WEEKS / ONE_MONTH, completion modes ALL / AT_LEAST_N, reward 140 and miss penalty 190 per required tile |
config/workflow_config.json |
global_wallclock_seconds, weekly horizon 7 days, tile-window horizon 7 days, per_decision_timeout_seconds: null, clock starts after the initial publication |
config/score_config.json |
challenge-score-v3 thresholds, program bonus, penalties, FLEXIBLE quota |
outputs/reference/night_calendar.csv, slots.csv |
the shared time axis: solar dusk/dawn per night, 900 s slots |
outputs/reference/tiles.csv, targets.csv, tile_windows.csv |
catalogue, per-target science weights, per-night visibility windows |
outputs/reference/observation_requests.csv, observation_request_tiles.csv |
pre-generated requests and their tiles |
outputs/reference/weather.csv |
site baseline weather per slot (public on practice scenarios only) |
outputs/reference/weather_forecasts.csv |
uncertain, daily-revised forecasts (the snapshots only show revisions issued so far) |
outputs/reference/weather_events.csv |
directional events: rainy, cloudy, smoggy, rocket_launch, cold_wave, tornado, instrument_fault with scope ALL / REGION_SET / SKY_CAP_ICRS / HORIZON_SECTOR, force_close and quality multipliers (hidden on competition scenarios; faults never appear in forecasts) |
outputs/reference/tile_anomalies.csv |
hidden per-tile truth tags (nova ×1.5, reddening ×0.8 on the tile's score); never shown to the agent, auditable after the fact |
outputs/reference/scenario_manifest.json, *_metadata.json |
row counts and SHA-256 of every file |
The platform never mounts this directory into your agent's sandbox: the only weather an agent sees is the
current_site_weather and per-candidate effective_weather of each snapshot, plus the forecast revisions in
weekly. A decisions.csv scored with score_decisions.py reports termination_reason = trace_complete; a
live run reports survey_complete, global_wallclock_expired, agent_error or agent_initialization_error.
- The platform starts your entry script once (
python -B minimal_agent.py, cwd = your package folder, a scrubbed environment plus theKEY=VALUElines of your.env, stderr captured toagent.log). - It writes one
initializeline: the immutable catalogs (tiles withtile_science_value, targets, calendar, site) and the exactscoring_contract(challenge-score-v3config, weather score interface, lunar model). No reply is expected. Up to 30 s are allowed for the process to accept it. - The global wall clock starts. For every decision opportunity the platform writes one
decision_requestline and waits for onedecision_responseline with the samedecision_sequence. Reading a snapshot never advances simulated time; a committed action does. - The run ends when the survey is complete, when the wall clock expires (the process is killed; an
in-flight response is ignored), or when the agent exits / answers with something unparseable
(
agent_error: the remaining survey stays unobserved, so every remaining REQUIRED tile counts as missed). - The platform replays
decisions.csvwith the public scorer and storesscore_report.json.
The wall clock is the only time rule: no per-decision timeout, no synthetic fallback action. The reference
scenario's budget is 7200 s; hidden scenarios publish their own budget in initialize.global_wallclock_seconds
and in the SAC_WALLCLOCK_SECONDS environment variable.
action is observe or wait. program is DARK, BRIGHT or BACKUP; request_id may be empty. Only
stdout carries protocol lines; print diagnostics to stderr.
Snapshot feedback and publications:
tile_last_finished— the realized official score (base + program_bonus) of your most recently finished exposure, ornullbefore the first one. Interrupted exposures report 0. Waits and invalid actions produce no update. Compare it against the public-formula estimate to detect hidden anomalies.fault_status— present only on the first decision of a night, and only after a fault report of yours was correct: one simulated day after the report it appears as{"status":"fault","event_id":...,"spatial_scope_type":...,"spatial_scope_payload":{...},"instrument_efficiency_multiplier":...,"reported_at_utc":...,"published_at_utc":...,"repair_complete_utc":...}, is re-published nightly while the repair is running, and disappears oncerepair_complete_utcpasses (two simulated days after the report). A fault report with no active fault gets, on the same one-day schedule, a one-night{"status":"normal","reference_report_id":...}answer instead.
reports rides on a decision_response: zero or more entries, each {"kind":"Instrument_Failure"} or
{"kind":"NOVA"|"Reddening","tile_id":"..."}. Reports never consume slot time. Malformed entries are dropped
(the action still counts); duplicates are tolerated and deduplicated at settlement. Each accepted report lands
in decisions.csv as a report_instrument_failure / report_nova / report_reddening action row immediately
after its carrier decision (sharing the incrementing decision_id sequence), so the single file replays
everything. Settlement: a correct
NOVA/Reddening tag earns +100, a wrong one −150 (first report per tile and tag counts; both tags may be
reported on one tile). For faults: reporting while an unacknowledged fault is active is correct (it triggers
the fault_status publication and the repair clock); with no active fault it is a misreport — one misreport
between two correct reports is free, each further one costs 100; re-reporting an acknowledged fault under
repair is neutral.
For each exposure segment: A = instrument_efficiency * transparency * sky_quality / (seeing_arcsec * airmass),
A_used = A * lunar_quality_factor, S = V_tile * (segment_seconds / nominal_exptime_seconds) * A_used * (1 + program_bonus).
Program bands are determined on the efficiency-free quality (A without the efficiency factor), so the preview
and the replay always agree on the band; efficiency still scales the score itself.
V_tile is the sum of the tile's target science_weights (published as tile_science_value). The program bonus
applies only when the chosen program matches the quality band of A_used (DARK ≥ 0.65, BRIGHT ≥ 0.40, else
BACKUP; bonuses 0.25 / 0.15 / 0.08). Repeat observations are legal: a tile's science score is the maximum
over its observations (a worse repeat never lowers it), completion still banks on the first legal observation,
and a request-tagged observation scores normally — a request naming an already-observed tile needs a new
post-issue observation to count a visit. Hidden tile tags multiply a tile's score silently: nova ×1.5,
reddening ×0.8 (both may stack); the published tile_science_value stays the untagged baseline.
total = science + program_bonus + completed_request_reward + coverage_bonus + report_reward − penalties, where the penalties are:
| Penalty | Amount |
|---|---|
unsafe observation (starting while is_observable is false) |
2000 per action |
| invalid action (unknown or out-of-window tile, bad program / request) | 100 per action |
| avoidable wait (waiting while a score-improving observation existed) | 0.001 per second |
| REQUIRED tile never completed | 1000 per tile |
| FLEXIBLE region below its quota of 4 completed tiles | 100 per missing tile |
| observation request expired without completion | the request's miss_penalty (waived when no legal opportunity existed) |
| wrong NOVA/Reddening report | 150 per report (a correct one earns +100 in report_reward) |
| fault misreports beyond the free allowance of one per correct report | 100 per misreport |
agent/scoring_preview.py applies this formula to the current snapshot without side effects — except that
snapshots never carry instrument_efficiency, so the preview baseline is efficiency-free: the gap between a
preview estimate and the realized tile_last_finished score isolates the hidden instrument side (efficiency
jitter × fault multiplier × tag multiplier). The authoritative
scorer integrates the real exposure segments during replay. The shipped deterministic minimal agent reaches
about 12287 on the reference scenario (64 of 64 tiles, 17 of 18 requests, no penalties); a random feasible
policy scores far lower, mostly through missed REQUIRED tiles and invalid actions.
agent/decision_graph.py— the decision logic (_prepare,_model_node,_finalize). The deterministic path rankspreview_actions(...)by estimated gain and observes the best;waitonly when nothing can be completed. Add your own planning, memory across decisions, or candidate filtering here.agent/model_factory.pyandagent/.env— optional LLM. Copy.env.exampleto.env, setMODEL_PROVIDER,MODEL_NAMEand the provider key; installagent/requirements.txtin your environment (python3 -m pip install -r agent/requirements.txt). Platform runs may reach LLM APIs over the network and installrequirements.txtinto a fresh virtualenv before starting your process.- Keep
minimal_agent.py/protocol.pycompatible with the envelopes above; the platform validates every response. - Anything your agent imports must live inside
agent/. The kit'schallenge/package is not available on the platform;scoring_preview.pyis copied intoagent/for that reason.
python3 pack_agent.py --agent agent --out my-agent.zip
python3 sac_submit.py --url https://<ref>.supabase.co --key <anon key> --email you@x.org --password '...' \
--phase online --kind agent --file my-agent.zip --wait
python3 sac_submit.py --url ... --key ... --email ... --password ... \
--phase practice --kind results --scenario dev-reference --file run_output/decisions.csv --waitThe URL and anon key are on the platform's Resources page. pack_agent.py includes .env (your keys are only
exposed to your own agent process); pass --no-env to leave it out.
参赛 Agent 的中文说明(责任边界、启用各家 LLM 的 .env 配置、JSON-Lines 协议、评分参数与回退保障)见
agent/README_ZH.md。本地流程:local_runner.py 跑基线 → make_scenario.py 生成更多场景 →
修改 agent/decision_graph.py → pack_agent.py 打包 → sac_submit.py 提交。