跳转至

运行面板(Dashboard)

一个 study 的状态都在文件里,而文件不方便盯着看。仓库自带的 dashboard 是一个本地、只读的网页视图,覆盖在 studies/<id>/ 之上,把整条工作流压缩成你 真正关心的东西:哪个阶段做完了、它写出了什么产物、指标曲线怎么长出来的、以及 每个 agent 的轨迹。

零第三方依赖 —— 用装 SocioVerse 的那个 Python 直接跑,不需要 pip install

启动

python dashboard/server/app.py --port 8787 --open
# 然后打开 http://127.0.0.1:8787

--open 会拉起浏览器。实际上你很少手敲这条命令:agentic 工作流会替你启动它 —— /sv-init 的第一个动作就是拉起面板、开标签页、打印 URL;之后每个 sv-* 阶段都 静默复用同一个服务。

一个工作区一个服务

如果 8787 已经起来了,再次启动会直接 no-op。所以同一工作区开多个 Claude Code 会话时它们共用一个面板,不会抢端口。空闲自动回收默认是关的 —— 一旦启动, 服务会在整个会话期间占住端口,后台标签页或暂停中的跑批都不会丢掉它。想恢复 "空闲 N 秒后退出"的老行为,设 SV_DASH_IDLE=<秒数>

参数 默认 作用
--port 8787 绑定端口
--host 127.0.0.1 绑定地址;容器内提供服务用 0.0.0.0
--root 仓库的 studies/ 指向另一个 studies 目录
--open 启动时开浏览器标签页
环境变量 默认 作用
SV_DASH_PORT 8787 工作流 hooks 访问的端口
SV_DASH_OPEN 1 0 = 只播报 URL,不开浏览器
SV_DASH_IDLE 0(关闭) 空闲多少秒后自杀
SV_DASH_DISABLE 设成任意值 = 工作流不再启动/播报面板
SV_DASH_SHOW_TEMPLATES 1 = 列表里也显示空的 abm_* 模板壳

界面上有什么

┌ 顶栏 ── 标题 · 路径 · 研究问题 · 运行状态 · study 切换器 ─────────────────┐
├ 流水线 ─┬─ 当前阶段详情 ──────────────────────────────────────────────────┤
│ sv-init ✓│  逐阶段卡片(init 事实 / 环境层 / 运行配置 / 报告)             │
│ …model  –│                                                                │
│ …env    ✓│                                                                │
│ …pop    ✓├─ 指标时间线 ───────────────────┬─ 图集 ──────────────────────┤
│ …run    ✓│  折线 + 干预标记               │  reports/figures/*.png       │
│ …report ◔├─ 事件流 ───────────────────────┴─────────────────────────────┤
└──────────┴─ 只保留语义,没有原始工具调用刷屏 ─────────────────────────────┘
  • 流水线导轨 —— 每个 sv-* 阶段一个 chip,带状态(状态词汇见下)。点击展开详情卡。
  • 阶段详情 —— 把该阶段写出的产物渲染出来:sv-init 的锚定事实、环境的层与 计划干预、人群构成、运行配置(含 time_unit / step_meaning)、报告。每张卡还带 一段该 skill 运行时自报的推理说明
  • 指标时间线 —— 每个声明的指标一条线,干预触发处打标记。图例项的 tooltip 是该 指标的 metric_descriptions 文案;点击图例可隐藏该条曲线。
  • 图集 —— reports/figures/ 下的 PNG。
  • Agent 面板 —— 列出所有实例化的 agent,选中一个即可看它逐步的状态决策产出。这就是把面板数据可视化出来:一个 agent 的轨迹就是它的记忆。
  • 事件流 —— 一份日志。每次请求都重建完整历史,所以后续迭代重跑某个阶段时, 更早的记录不会消失。
  • 版本盒 —— /sv-iterate 的版本树;选中某个归档版本会以只读方式从快照渲染。

状态词汇

颜色是有讲究的,这些区分本身就是设计:

徽标 含义
done 该阶段的产物是最新的
stale(珊瑚色,"re-run") 产物早于它所依赖的某个构建产物 —— 上游在它下面变过了
inherited(琥珀色) Path-A fork 从源 study 拷来的产物,你还没重新撰写
from v\<parent>(中性色) 某个版本有意复用父版本的产物 —— 复用是预期行为,不是警告
archived(紫色) 你正在看 versions/vN/ 的冻结快照,不是活动目录

运行中的实时视图

/sv-run 跑的时候面板是流式的。引擎每步向 trajectory/progress.jsonl 追加一行, 另有一份无锁的 trajectory/panel_live.jsonl 镜像面板行(跑批期间 DuckDB 处于写锁 状态)—— 所以步进条会走、图会长、agent 面板会更新,不必等跑完。服务重启时浏览器 会自己走 SSE 重连。

当工作流卡在等你回答时,顶部会出现横幅、标签页标题会变成 ⏳ waiting for you, 后台标签页也能给出信号。

两个版本对比

指标时间线卡片的标题行里有一个 对比 / vs 选择器。选定基线版本后,它会以同色系 虚线叠加在时间线上,分别绘制两个版本的干预标记,并给出一条 Δ-配置带:n_steps / seed 变了什么、增删了哪些计划事件与广播、persona 数量差多少。它只影响这一张卡, 视图其余部分仍停留在当前版本。

数据从哪来

两条通道,刻意分开:

  1. 文件是权威状态。 服务监听 studies/<id>/,完全从 skills 本来就会写的产物 重建视图 —— study.yamlenvironment.jsonpopulation.jsonsimulation.jsontrajectory/progress.jsonlmetrics_history.jsonreports/versions.json。这让视图对 Claude Code 重启、子进程写入、手工编辑 都免疫。
  2. POST /ingest 承载推理。 每个阶段自报一行叙述,合并到对应卡片和事件流。 除此之外不推送任何东西 —— 没有原始工具调用流。

HTTP 接口很小,稳定到可以直接拿去写脚本:

路由 用途
GET /api/state study 列表 + 进度 + 当前选中
GET /api/study/<id> 单个 study 的完整重建详情
GET /api/study/<id>/agents · …/agent/<aid> agent 面板
GET /api/study/<id>/version/<v> 归档版本详情(同样有 …/agents…/figure/<name>
GET /api/stream SSE,任意产物写入时推一次 nudge
POST /ingest 记录一条阶段叙述
curl -X POST http://127.0.0.1:8787/ingest -H 'Content-Type: application/json' \
  -d '{"study_id":"chicago_schelling","stage":"sv-init",
       "narrative":"Routed to Path A — matched on domain=urban-segregation; forked the baseline."}'

只读是设计,不是缺陷

面板从不写 study。它不能发起跑批、不能改产物、不能删版本 —— 那些是工作流的动作。 唯一的例外是在线托管服务:那里同一个视图旁边多了一个对话面板,见 在线工作台

导出静态副本

想在不带服务端的情况下分享结果(论文附录、项目页),可以导出一份自包含快照:

python scripts/export_dashboard_static.py \
  --studies opinion_diffusion consumer_confidence chicago_schelling \
  --out ./gallery

产物是纯 HTML + JSON,带深链(index.html?study=<id>),用任意静态文件服务器托管即可。