运行面板(Dashboard)¶
一个 study 的状态都在文件里,而文件不方便盯着看。仓库自带的 dashboard
是一个本地、只读的网页视图,覆盖在 studies/<id>/ 之上,把整条工作流压缩成你
真正关心的东西:哪个阶段做完了、它写出了什么产物、指标曲线怎么长出来的、以及
每个 agent 的轨迹。
它零第三方依赖 —— 用装 SocioVerse 的那个 Python 直接跑,不需要 pip install。
启动¶
--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 数量差多少。它只影响这一张卡,
视图其余部分仍停留在当前版本。
数据从哪来¶
两条通道,刻意分开:
- 文件是权威状态。 服务监听
studies/<id>/,完全从 skills 本来就会写的产物 重建视图 ——study.yaml、environment.json、population.json、simulation.json、trajectory/progress.jsonl、metrics_history.json、reports/、versions.json。这让视图对 Claude Code 重启、子进程写入、手工编辑 都免疫。 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>),用任意静态文件服务器托管即可。