Просмотр исходного кода

feat(research67): 接入百炼并区分研究状态与执行完成

为科学假设与研究计划配置连接百炼 Qwen,避免把任务执行结束展示成科学验证成功。

- Research67 门面统一使用百炼配置,保留研究问题、人工反馈和版本关联
- 实时及完成输出显示证据不足、方案待修订或待人工审阅,并保留鉴权产物链接
- 明确受限模拟能力及调用边界,避免门面夸大未确认流程
- 相关桥接测试 34 项通过,bun typecheck 通过;真实 OpenCode 门面路由和两版科研桥接联调分别验证通过
邵勃源 4 дней назад
Родитель
Сommit
3a68f32771

+ 8 - 0
.opencode/README.md

@@ -4,6 +4,14 @@
 
 ## 一句话架构
 
+参赛版使用 PaaS 的 `agentexample/research67/competition.yml`,可只启动本机 API 和执行服务。
+此配置执行证据检索、假设与计划检查、受限 Q124 模拟和反馈修订;下文完整编排流程仅适用于另外注册的完整科研配置。
+科研门面统一使用百炼 `bailian/qwen3.8-flash`,需要向 OpenCode 进程提供 `DASHSCOPE_API_KEY`。
+详细启动和验收方法见配套 PaaS 仓库的 `docs/research67-competition.md`。
+
+`completed` 是执行状态。`research.science.status` 的 `needs_evidence`、`needs_revision`、
+`needs_review` 分别表示证据不足、方案待修订、检查通过待人工审阅,不能表述成科学结论已成立。
+
 ```text
 OpenCode CLI
 → .opencode/agent/research67.md

+ 1 - 1
.opencode/agent/research-67-action-reasoner.md

@@ -1,6 +1,6 @@
 ---
 mode: subagent
-model: opencode/mimo-v2.5-free
+model: bailian/qwen3.8-flash
 steps: 2
 color: "#F59E0B"
 description: 本体动作推理员,负责证据评估、证伪判断、综合结论和本体再审计。

+ 1 - 1
.opencode/agent/research-67-claim-verifier.md

@@ -1,6 +1,6 @@
 ---
 mode: subagent
-model: opencode/mimo-v2.5-free
+model: bailian/qwen3.8-flash
 steps: 2
 color: "#EF4444"
 description: 本体主张核验员,检查科学主张、来源、证据状态和论文表达是否一致。

+ 1 - 1
.opencode/agent/research-67-data-verifier.md

@@ -1,6 +1,6 @@
 ---
 mode: subagent
-model: opencode/mimo-v2.5-free
+model: bailian/qwen3.8-flash
 color: "#EAB308"
 description: 数据核验员。核验论文中的数据、引用、表述和强主张是否与证据及 artifact 一致。
 tools:

+ 1 - 1
.opencode/agent/research-67-exp-executor.md

@@ -1,6 +1,6 @@
 ---
 mode: subagent
-model: opencode/mimo-v2.5-free
+model: bailian/qwen3.8-flash
 color: "#EC4899"
 description: 实验执行员。仅在授权且本地可执行时运行计算/数据实验,收集原始结果和执行日志。
 tools:

+ 1 - 1
.opencode/agent/research-67-exp-planner.md

@@ -1,6 +1,6 @@
 ---
 mode: subagent
-model: opencode/mimo-v2.5-free
+model: bailian/qwen3.8-flash
 color: "#D946EF"
 description: 实验规划师。基于假设、本体缺口和研究计划生成实验方案、指标、对照和授权需求。
 tools:

+ 1 - 1
.opencode/agent/research-67-hypothesis-builder.md

@@ -1,6 +1,6 @@
 ---
 mode: subagent
-model: opencode/mimo-v2.5-free
+model: bailian/qwen3.8-flash
 steps: 2
 color: "#10B981"
 description: 可证伪假设构建员,基于已核验证据生成科学假设与可证伪条件。

+ 1 - 1
.opencode/agent/research-67-idea-analyst.md

@@ -1,6 +1,6 @@
 ---
 mode: subagent
-model: opencode/mimo-v2.5-free
+model: bailian/qwen3.8-flash
 color: "#8B5CF6"
 description: 创意分析师。分析研究想法的可研究性、学科范围、证据类型、风险和方向。
 tools:

+ 1 - 1
.opencode/agent/research-67-lit-searcher.md

@@ -1,6 +1,6 @@
 ---
 mode: subagent
-model: opencode/mimo-v2.5-free
+model: bailian/qwen3.8-flash
 color: "#A855F7"
 description: 文献检索员。进行结构化文献检索和来源组织,为本体补全和论文写作提供候选证据。
 tools:

+ 1 - 1
.opencode/agent/research-67-ontology-auditor.md

@@ -1,6 +1,6 @@
 ---
 mode: subagent
-model: opencode/mimo-v2.5-free
+model: bailian/qwen3.8-flash
 steps: 2
 color: "#0EA5E9"
 description: 本体完备性审计员,检查实体、机制、证据、关系、假设和可证伪条件缺口。

+ 1 - 1
.opencode/agent/research-67-ontology-enricher.md

@@ -1,6 +1,6 @@
 ---
 mode: subagent
-model: opencode/mimo-v2.5-free
+model: bailian/qwen3.8-flash
 steps: 2
 color: "#14B8A6"
 description: 本体证据补全员,调用知识库和检索工具补充实体、机制、证据、未知项和关系。

+ 1 - 1
.opencode/agent/research-67-ontology-experiment-planner.md

@@ -1,6 +1,6 @@
 ---
 mode: subagent
-model: opencode/mimo-v2.5-free
+model: bailian/qwen3.8-flash
 steps: 2
 color: "#A855F7"
 description: 本体实验规划员,围绕假设、证据缺口和可证伪条件生成实验协议。

+ 1 - 1
.opencode/agent/research-67-orchestrator.md

@@ -1,6 +1,6 @@
 ---
 mode: subagent
-model: opencode/mimo-v2.5-free
+model: bailian/qwen3.8-flash
 steps: 2
 color: "#4F46E5"
 description: Research67 科研主编排器入口,调度多智能体科研闭环。

+ 1 - 1
.opencode/agent/research-67-paper-reviewer.md

@@ -1,6 +1,6 @@
 ---
 mode: subagent
-model: opencode/mimo-v2.5-free
+model: bailian/qwen3.8-flash
 color: "#22C55E"
 description: 论文评审员。从科学性、证据充分性、可复现性和表达质量角度评审产物。
 tools:

+ 1 - 1
.opencode/agent/research-67-paper-writer.md

@@ -1,6 +1,6 @@
 ---
 mode: subagent
-model: opencode/mimo-v2.5-free
+model: bailian/qwen3.8-flash
 color: "#F97316"
 description: 论文撰写员。基于已核验证据和 action receipts 生成中英论文、LaTeX、BibTeX 和 PDF。
 tools:

+ 3 - 1
.opencode/agent/research-67-pipeline.md

@@ -1,6 +1,6 @@
 ---
 mode: subagent
-model: opencode/mimo-v2.5-free
+model: bailian/qwen3.8-flash
 steps: 2
 color: "#6366F1"
 description: Research67 Lite 三阶段研究草稿流水线入口。
@@ -28,3 +28,5 @@ tools:
 - 失败回复不得提出“基于已有产物继续完成报告”等补做建议,只能给出失败事实和等待用户决定的提示。
 
 > 注:Research67 Lite 当前使用 pipeline,不调用 orchestrator;agentpaas_run 会按 agent_name 动态解析当前 Agent ID。
+
+此三阶段研究草稿流水线不执行真实实验;请以实际返回的阶段和产物为准。

+ 1 - 1
.opencode/agent/research-67-plan-builder.md

@@ -1,6 +1,6 @@
 ---
 mode: subagent
-model: opencode/mimo-v2.5-free
+model: bailian/qwen3.8-flash
 steps: 2
 color: "#84CC16"
 description: 本体动作研究计划员,把假设本体编译为研究计划和 Action DAG。

+ 1 - 1
.opencode/agent/research-67-result-analyst.md

@@ -1,6 +1,6 @@
 ---
 mode: subagent
-model: opencode/mimo-v2.5-free
+model: bailian/qwen3.8-flash
 color: "#F43F5E"
 description: 结果分析师。分析实验结果数据,生成统计检验、对比表格和可视化图表。
 tools:

+ 1 - 1
.opencode/agent/research-67-result-analyzer.md

@@ -1,6 +1,6 @@
 ---
 mode: subagent
-model: opencode/mimo-v2.5-free
+model: bailian/qwen3.8-flash
 color: "#F43F5E"
 description: 结果分析师。分析实验结果或外部回传数据,生成统计检验、对比表格、图表和观察补丁。
 tools:

+ 1 - 1
.opencode/agent/research-67-review-feedback.md

@@ -1,6 +1,6 @@
 ---
 mode: subagent
-model: opencode/mimo-v2.5-free
+model: bailian/qwen3.8-flash
 color: "#06B6D4"
 description: 评审反馈合成器。将评审意见转成下一轮 action、修订指令和本体补丁。
 tools:

+ 26 - 38
.opencode/agent/research67.md

@@ -1,49 +1,37 @@
 ---
 mode: primary
-model: opencode/mimo-v2.5-free
+model: bailian/qwen3.8-flash
 steps: 3
 color: "#0F766E"
-description: Research67 完整科研系统入口:本体构建、证据补全、假设生成、研究计划、实验规划、论文写作、核验评审与反馈迭代。
+description: 科学假设与研究计划入口:转发研究问题、展示证据和检查结果、继续反馈修订。
 tools:
   "*": false
   "agentpaas_run": true
 ---
 
-你是 Docker 版对话式 Research67 入口(research67)。
-
-Research67 不是普通问答助手,也不是固定 3 Agent 或固定 9 Agent 流水线;它是远端 AgentPaaS 中注册的本体驱动多智能体科研系统。用户通过 OpenCode 输入科学问题、125 Questions 题号、研究想法、追问或修改要求时,你只负责把请求桥接到远端 Research67,由远端系统执行:
-
-```text
-科学问题
-→ 本体构建
-→ 本体审计与知识补全
-→ 可证伪假设生成
-→ 研究计划与 Action DAG
-→ 实验规划 / 授权包 / 可执行实验
-→ 结果分析
-→ 论文写作
-→ 数据与主张核验
-→ 论文评审
-→ 反馈合成
-→ 本体再审计与下一轮迭代
-```
-
-每个用户回合使用一次 `agentpaas_run`,参数固定为:
+你是 Research67 的交互入口,通过 agentpaas_run 连接本机或远端 LambdaAgentPaaS。
+每个用户回合只允许调用一次该工具,不自行执行科研推理或补造产物。
 
+参数:
 - agent_name: research67
-- mode: 问候、澄清、概念讨论和产物追问用 `chat`;用户明确要求检索、分析、实验、写作、生成文件、运行 125 Questions 或推进科研闭环时用 `iterate`
-- conversation: 默认 `continue`;只有用户明确切换到不相关新课题或要求新会话时用 `new`
-- question_id: 用户明确给出的 1–125 题号;未给出时不猜编号
-- feedback_kind: 对已有研究提出修改意见时传 `human`;只有反馈明确来自程序检查、执行结果或补充证据时,分别使用 `program_check`、`execution_result` 或 `evidence`
-- input: 用户任务原文;可以补充用户明确给出的时间、成本、授权和交付物边界,但不得改变研究问题
-- parameters: 需要科研执行、125 Questions、科学假设、研究计划、实验规划、论文写作、核验评审或闭环迭代时传 `{ "workflow": "RESEARCH67_UNIFIED_LOOP_V1" }`;纯问候和概念闲聊可留空
-
-OpenCode 侧只做桥接,不做科研推理。不得在 OpenCode 本地伪造研究产物、不得自行改写远端结论、不得在同一回合重复调用 `agentpaas_run`,也不得失败后擅自改调其他 Agent 补做。
-
-同一 OpenCode session 会自动复用 AgentPaaS thread 和上一轮运行引用。研究修订会使用独立 workspace,复制上一轮已登记的成果,保留旧版。用户追问“产物在哪”“继续下一轮”“补做实验规划”“写论文”“核验数据”等,都应继续转发到同一个远端会话,使 Research67 能沿用已有本体、Action DAG、receipt 和 artifact。研究修订不传 `work_dir`,也不自行编造 `input_artifact_ids`。
-
-若用户引用 125 Questions 中的问题,保留编号、原问题文本和学科语境;背景摘要只能作为待核验线索,不得当作可靠证据。用户只给编号而未给正文时,原样转发编号并启用统一工作流,让远端 Research67 从已部署题库读取;若远端明确报告题库不可用,再向用户索要正文,OpenCode 不得猜题。
-
-真实实验、人体/动物实验、湿实验和硬件实验必须遵守远端授权门禁。OpenCode 不能把未授权实验包装成已完成验证;如远端返回 `external_authorization_package.json`,应忠实说明这是实验授权与数据回传包,而不是实验结果。
-
-当工具返回 `status=completed` 或标题为“任务已完成”时,明确写“任务已完成”,原样保留工作目录和文件表格;禁止改写成“已提交”“已接收”“开始执行”或“完成后再返回”。
+- mode: 问候、能力询问与概念澄清用 chat;明确启动研究、检索、研究计划或修订用 iterate。
+- conversation: 默认 continue;用户明确换到不相关的新问题时用 new。
+- question_id: 用户明确提供的 1–125 题号。没有编号时不猜编号,不从个人知识猜题目正文。
+- feedback_kind: 人工修改意见用 human;程序检查、执行结果或证据补充分别用 program_check、execution_result、evidence。
+- input: 用户原始要求,保留用户给出的范围、成本和交付边界。
+
+继续修订时复用会话,不指定 work_dir,也不猜测 input_artifact_ids。工具负责父版本和成果复制。
+不要在失败后自动重跑、换键、拆分请求或改调其他 Agent。保留原 run_id 和已生成的产物。
+
+参赛配置的交付物是候选假设、来源证据、研究计划、程序检查和反馈修订。
+明确启用时可执行 Q124 受限高斯模拟,其他计划中的动作默认没有执行。
+是否接入其他流程或仪器,必须以远端实际返回为准;不要自行介绍论文写作、实验授权或其他未确认能力。
+
+status=completed 只表示执行结束。若有 research.science.status,优先原样解释:
+- needs_evidence:证据不足。
+- needs_revision:方案待修订。
+- needs_review:程序检查通过,待人工审阅。
+引用原句存在不等于主张成立;模拟结果不等于真实人群实验。不得声称科学问题已解决。
+
+工具返回后简洁展示研究状态、主要结论及限制、修改依据和产物链接,保留实际工作目录。
+对纯问候或能力查询,仅转述远端确认的能力,不扩写未确认流程,不自行启动研究。

+ 13 - 1
.opencode/opencode.jsonc

@@ -1,6 +1,18 @@
 {
   "$schema": "https://opencode.ai/config.json",
-  "provider": {},
+  "provider": {
+    "bailian": {
+      "npm": "@ai-sdk/openai-compatible",
+      "name": "Alibaba Bailian",
+      "options": {
+        "baseURL": "https://dashscope.aliyuncs.com/compatible-mode/v1",
+        "apiKey": "{env:DASHSCOPE_API_KEY}",
+      },
+      "models": {
+        "qwen3.8-flash": { "name": "Qwen3.8 Flash", "tool_call": true },
+      },
+    },
+  },
   "permission": {},
   "references": {
     "effect": {

+ 12 - 1
.opencode/tool/agentpaas_run.ts

@@ -305,6 +305,8 @@ export default tool({
           sawCancelled = true
           progress.cancel()
           updateMetadata("Research67 已取消", { latest_event: ev.event, status: "cancelled" })
+        } else if (ev.event === "research_status" && data) {
+          updateMetadata(scientificLabel(data.status), { scientific_status: data.status, latest_event: ev.event })
         } else if (ev.event === "done" && data) {
           done = data
           break
@@ -352,10 +354,12 @@ export default tool({
         `- [${name}](${config.url}/api/v1/agents/${encodeURIComponent(agentID)}/runs/${encodeURIComponent(String(metadata.run_id))}/artifacts/${encodeURIComponent(id)}/download)`,
       ]
     })
+    const science = asRecord(asRecord(done.research)?.science)
     if (status === "completed")
       return {
-        title: `AgentPaaS ${args.agent_name}`,
+        title: science ? scientificLabel(science.status) : `AgentPaaS ${args.agent_name}`,
         output: [
+          ...(science ? [`研究状态:${scientificLabel(science.status)}。执行结束不代表科学结论成立。\n`] : []),
           String(done.output ?? ""),
           ...(artifactLinks.length ? ["\n研究产物(通过 PaaS 身份验证后下载):", ...artifactLinks] : []),
         ].join("\n"),
@@ -388,6 +392,13 @@ export default tool({
   },
 })
 
+function scientificLabel(status: unknown): string {
+  if (status === "needs_evidence") return "证据不足"
+  if (status === "needs_revision") return "方案待修订"
+  if (status === "needs_review") return "方案检查通过,待人工审阅"
+  return "研究状态待核查"
+}
+
 async function resolveAgentID(config: { url: string; apiKey: string }, agentName: string, signal: AbortSignal) {
   const name = agentName.trim()
   if (!name) throw new Error("agent_name 不能为空")

+ 11 - 0
packages/opencode/test/tool/agentpaas-protocol.test.ts

@@ -81,6 +81,17 @@ test("local ID remains accepted", async () => {
   expect(actual.result.output).toBe("ok")
   expect(actual.requests[1].path).toBe("/api/v1/agents/ag_research67/run/stream")
 })
+for (const [status, label] of [["needs_evidence", "证据不足"], ["needs_revision", "方案待修订"], ["needs_review", "待人工审阅"]]) {
+  test(`execution completion preserves scientific state ${status}`, async () => {
+    const actual = await execute("ag_research67", [["done", {
+      run_id: "run_probe", status: "completed", output: "Research report",
+      research: { revision: 2, science: { status } },
+    }]])
+    expect(actual.result.title).toContain(label)
+    expect(actual.result.output).toContain("执行结束不代表科学结论成立")
+    expect(actual.result.metadata.research).toEqual({ revision: 2, science: { status } })
+  })
+}
 test("remote namespaced ID accepted and encoded as one route segment", async () => {
   const actual = await execute("locostack:science-team:research67.v1", [done()])
   expect(actual.result.output).toBe("ok")