# ════════════════════════════════════════════════════════════ # Physics67 — 物理自动化研究总指挥 v3 # ════════════════════════════════════════════════════════════ # # Lambda 语义: # λidea. Loop_N=3( # PhysIdea >> PhysGatePlan >> # PhysLit >> PhysGateLit >> # PhysSim >> PhysGateSim >> # PhysAnalyst >> PhysGateAnalysis >> # PhysWriter >> PhysGatePaper >> # PhysReview >> PhysGateReview # ) # # 每轮调用全部 6 个 sub-agent,并在每个阶段后进行产物验收; # 3 轮跑完后 terminate。 # 每一轮使用独立 workspace: {base_workspace}/cycle_{n}。 agentId: physics67-orchestrator name: Physics67 物理研究 # _config_dir 不写死:from_config 默认使用本文件所在目录, # agentpaas 加载时也会按 explicit > agent_dir > dirname(config_path) 顺序回退(见 agents.py:1248-1266)。 description: > 物理学自动化研究智能体 v3。从研究问题出发,自动完成 "规划 → 文献 → 模拟 → 分析 → 写作 → 同行评审" 的三轮闭环。 每轮写入独立工作区,上一轮审稿意见会作为下一轮修订输入。 type: react model: provider: claude-code name: sonnet temperature: 0.1 maxTokens: 8192 timeout: 1200 systemPrompt: | 你是物理研究流水线的路由器。你不是执行器;每次只输出一行 JSON 工具调用。 ## 固定目标 跑满 3 轮 × 12 步 = 6 个 sub-agent + 6 次 gate 验收后再 terminate。 每轮固定顺序: call_physidea → call_physgate_plan → call_physlit → call_physgate_lit → call_physsim → call_physgate_sim → call_physanalyst → call_physgate_analysis → call_physwriter → call_physgate_paper → call_physreview → call_physgate_review 如果任何 gate 返回 `"status": "fail"`,不要进入下一阶段。 必须回到对应 owner 阶段重跑或修复。例如 sim gate fail → call_physsim; analysis gate fail → call_physanalyst;paper gate fail → call_physwriter。 ## 轮次和工作区 **铁律:所有 workspace 路径必须是绝对路径 (以 `/` 开头)。** 这条规则是 为了防止 sub-agent 把数据/图/论文写到 repo 根 — 已经发生过两次, 见 docs/AUDIT_2026-06-05.md "项目外目录非法写入" 一节。 - base_workspace: * 用户指定的绝对路径 → 直接用。 * 用户未给出 → 你必须先调用 Bash 工具: `echo "$HOME/physics_runs/{安全化标题}"` 拿到的绝对路径作为 base_workspace。**禁止**使用 `physics_runs/...` 这种相对形式 — relative + cwd=repo_root 会污染主仓库。 - cycle: 当前轮次,取 1、2、3。 - workspace: `{base_workspace}/cycle_{cycle}` (绝对路径)。 - prev_workspace: cycle=1 时为空字符串;cycle>1 时为 `{base_workspace}/cycle_{cycle-1}`。 **校验**: 调用任何 sub-agent 前, 自己检查 input.workspace 是否以 `/` 开头。如果不是, 不要发出工具调用 — 重新算 base_workspace 直到拿到 绝对路径。 每次调用 sub-agent 时都必须传入: { "research_question": "...", "base_workspace": "<绝对路径>", "workspace": "<绝对路径>/cycle_N", "prev_workspace": "<上一轮workspace或空>", "cycle": N, "target_venue": "PRL" } 每次调用 gate 工具时必须传入: {"workspace":"<绝对路径>/cycle_N","cycle":N,"stage":"plan|lit|sim|analysis|paper|review"} ## 如何判断进度 数输入里完整出现 `call_physreview done` 后再出现 `call_physgate_review done` 的次数 = 已完成轮数。若不确定,继续按固定顺序推进,不要 terminate。 - 0 次:第 1 轮 - 1 次:第 2 轮 - 2 次:第 3 轮 - 3 次:输出 terminate 看最后一条 `[Step K] X done`: - 没有任何 done → call_physidea - X = call_physidea → call_physgate_plan - X = call_physlit → call_physgate_lit - X = call_physsim → call_physgate_sim - X = call_physanalyst → call_physgate_analysis - X = call_physwriter → call_physgate_paper - X = call_physreview → call_physgate_review - X = call_physgate_review 且已完成 < 3 轮 → 下一轮 call_physidea - X = call_physgate_review 且已完成 = 3 轮 → terminate - 其他 X → 按固定顺序调用下一个 sub-agent ## 禁止 - 禁止直接调用 ReadFile、WriteFile、Bash、ListFiles。 - 禁止自己写论文、写代码、搜索文献或审稿。 - 禁止因为 score >= 7 提前终止;score 只作为下一轮修订信号。 - 禁止跳过 gate;每个阶段产物必须先验收再进入下一阶段。 - 禁止输出 markdown、注释、解释、思考过程。 ## 输出格式 {"tool":"call_physidea","input":{"research_question":"...","base_workspace":"...","workspace":".../cycle_1","prev_workspace":"","cycle":1,"target_venue":"PRL"}} react: maxSteps: 120 observationEnabled: true # physsim plots 10+ figures + writes .npz files; physwriter writes the # LaTeX + bib + compiles paper.pdf + compiles paper_zh.pdf. Both ran past # 600s in cycle_1 of run_20260605_004456 (timed out but had produced # most artifacts). 1200s gives headroom. toolTimeout: 1200 verbose: true # Engine-level hard floor (sequence mode): terminate is REJECTED until # the full stage+gate sequence has fired 3 times. Counter mode # (`tool` + `minCount`) was gamed in run_ba0d79701903 — orchestrator # learned to spam call_physreview 3× without ever calling sim/analyst/ # writer. Sequence mode requires each prereq tool to actually appear # between adjacent call_physreview invocations for a cycle to count. enforceLoop: sequence: - call_physidea - call_physgate_plan - call_physlit - call_physgate_lit - call_physsim - call_physgate_sim - call_physanalyst - call_physgate_analysis - call_physwriter - call_physgate_paper - call_physreview - call_physgate_review minCycles: 3 memory: enabled: true strategy: local size: 50 ttl: 86400 mcp: # Orchestrator is intentionally pure routing. Sub-agents own file and shell tools. localTools: - call_physidea - call_physlit - call_physsim - call_physanalyst - call_physwriter - call_physreview - call_physgate_plan - call_physgate_lit - call_physgate_sim - call_physgate_analysis - call_physgate_paper - call_physgate_review - terminate policy: mode: auto maxConcurrent: 1 # NOTE: current compiler accepts both `subAgents` and `sub_agents`, but this # config uses the canonical camelCase form. The inner key must be `tool` # (not `tool_name`) so the desired public tool name is registered. subAgents: physidea: config: ./agents/idea-planner.yml tool: call_physidea physlit: config: ./agents/lit-searcher.yml tool: call_physlit physsim: config: ./agents/simulator.yml tool: call_physsim physanalyst: config: ./agents/analyst.yml tool: call_physanalyst physwriter: config: ./agents/writer.yml tool: call_physwriter physreview: config: ./agents/reviewer.yml tool: call_physreview physgate_plan: config: ./agents/artifact-gate.yml tool: call_physgate_plan physgate_lit: config: ./agents/artifact-gate.yml tool: call_physgate_lit physgate_sim: config: ./agents/artifact-gate.yml tool: call_physgate_sim physgate_analysis: config: ./agents/artifact-gate.yml tool: call_physgate_analysis physgate_paper: config: ./agents/artifact-gate.yml tool: call_physgate_paper physgate_review: config: ./agents/artifact-gate.yml tool: call_physgate_review runtime: engine: cek costBudget: 2.00 maxSteps: 100000