首页
/ CLI-Anything Harness 预览方法论:bundle/session/trajectory 三层模型与 Agent 命令契约

CLI-Anything Harness 预览方法论:bundle/session/trajectory 三层模型与 Agent 命令契约

2026-09-07 17:25:41作者:秋泉律Samson

本文解读 CLI-Anything 的 Harness 预览方法论(cli-anything-plugin/guides/preview-methodology.md):当一个 Harness 能够通过图片、视频片段、检查包等“真实软件产出的中间态”向 Agent 反馈时,应该如何设计 preview 命令族。读完本文,你将掌握 producer/consumer 角色分离原则、bundle/session/trajectory 三层数据模型、推荐的 CLI 表面(含 diff/live/poll 可选能力)、面向 Agent 的 preview live status --json 契约,以及真实性约束与落地检查清单;并以仓库中已落地的 Blender、Shotcut、FreeCAD、RenderDoc 等 Harness 源码作为实现级佐证。

Blender 轨道中继无人机场景的实时预览轨迹演示

1. 适用场景与文档定位

这份方法论适用于能够通过图像、视频片段、检查包或其他来自真实软件的诚实产物暴露有意义的中间状态的 Harness。它与 docs/PREVIEW_PROTOCOL.md 是互补关系:

  • 协议文档定义 bundle/session/trajectory 的格式preview-bundle/v1preview-live/v1preview-trajectory/v1);
  • 本文(方法论)定义 Harness 侧的实现方法面向 Agent 的命令契约

协议文档明确了设计边界:预览产物仍必须来自真实软件及其真实后端,协议只标准化“预览产物契约”,不替代渲染器;cli-hub 成为所有 bundle 的通用查看器,而不是让每个 Harness 各自发明监控 UI。

2. 角色分离:Producer 与 Consumer

方法论的第一条硬规则是把预览的生产预览的消费保持为两个独立角色:

角色 命令入口 职责
Producer cli-anything-<software> preview ... 与真实后端通信、计算源指纹、选择 recipe、发布 bundle/session/trajectory
Consumer cli-hub previews ... 只读取已存在的预览状态,提供 inspecthtmlwatchopen从不渲染或合成预览产物

这个分界在仓库中是真实落地的。cli-hubpreviews 命令组帮助文本直白地写明了消费侧边界(cli-hub/cli_hub/cli.py):

@main.group(name="previews", invoke_without_command=True)
def previews(ctx):
    """Inspect existing preview bundles or live sessions; this command does not publish previews."""

消费侧的四个子命令在 cli-hub/cli_hub/cli.py 中实现:

  • cli-hub previews inspect <bundle-or-session>:自动识别引用是 bundle 目录还是 live session 目录(通过是否存在 session.json 判定,见 cli-hub/cli_hub/preview.pyis_live_session_ref),输出 manifest 元数据、源标识、summary 的 headline/facts/warnings、产物表格,以及可用时的 trajectory 摘要;
  • cli-hub previews html <bundle-or-session> [-o output.html]:生成静态 HTML 页,先展示 summary,再渲染 hero/gallery 图像、内嵌 preview-clip<video>、链接 JSON 产物,并在存在 trajectory.json 时渲染会话历史(HTML 渲染逻辑见 cli-hub/cli_hub/preview.py);
  • cli-hub previews watch <session-dir> [--open] [--poll-ms 1500]:通过 localhost 静态服务器托管 live session 并自动刷新页面(cli-hub/cli_hub/cli.py);
  • cli-hub previews open <bundle-or-session>:为 bundle 打开生成的 HTML 文件,或为 session 启动带浏览器后端的 watcher(cli-hub/cli_hub/cli.py)。

方法论要求这个 producer/consumer 区分在命令帮助、README 示例、SKILL.md、live-session 查看器提示中都清晰可见。一句话总结:

发布用 cli-anything-<software>,检查用 cli-hub

3. 三层模型:bundle、session、trajectory

能预览的 Harness 应当显式建模历史,而不是把“最新的 bundle 目录”当作永久对象。三层各司其职:

3.1 bundle_dir:不可变快照

一个 bundle 目录对应一次具体的预览结果:一次静态抓取、一次 diff 抓取、或一次 live session 的发布步骤。它应实现 preview-bundle/v1 并包含:

<bundle_dir>/
  manifest.json    # 机器契约
  summary.json     # 面向人/Agent 的摘要
  artifacts/       # hero.png、gallery_*.png、preview.mp4 等

bundle 一旦发布即视为不可变。这一约定在 canonical helper 中得到强制:prepare_bundle 创建新目录时使用 exist_ok=False 确保不覆盖已发布的 bundle,finalize_bundle 只负责写入 manifest.jsonsummary.jsoncli-anything-plugin/preview_bundle.py)。

Bundle ID 采用 <UTC 时间戳>_<短指纹>_<recipe> 形式(如 20260419T104530Z_9f0a2c4b_quick),指纹派生自源指纹、recipe、归一化后的预览参数、harness 版本与协议版本,使 bundle 可缓存、可复现。canonical helper 中的实现为:

bundle_id = f"{now}_{cache_key.split(':', 1)[-1][:8]}_{_slug(recipe)}"

cli-anything-plugin/preview_bundle.py

3.2 session.json:可变的 live 头部

session.json 代表某项目某 recipe 的当前 live 视图,是“现在是什么”的稳定入口。典型字段包括:当前 bundle id 与路径、session 根目录与 recipe、查看器命令(watch_commandinspect_command 等)、当前 step id、trajectory 位置。

以仓库中最完整的参考实现 Blender Harness 为例,其 _publish_live_session 写入的 session 负载覆盖了方法论列出的全部字段,并额外携带可直接复制执行的命令提示(blender/agent-harness/cli_anything/blender/core/preview.py):

"current_bundle_id": bundle_manifest.get("bundle_id"),
"current_bundle_dir": bundle_manifest.get("_bundle_dir"),
"current_manifest_path": bundle_manifest.get("_manifest_path"),
"current_summary_path": bundle_manifest.get("_summary_path"),
"current_step_id": trajectory.get("current_step_id"),
"trajectory_path": trajectory_rel,
"publish_command": f"cli-anything-blender{project_flag} preview live push --recipe {recipe}{root_flag}",
"watch_command":   f"cli-hub previews watch {session_dir} --open --poll-ms {current_refresh_hint_ms}",
"inspect_command": f"cli-hub previews inspect {session_dir}",

从源码结构看,这些 *_command 字段正是方法论中“live-session viewer hints”要求的落地:session 自己告诉 Agent“下一步该跑什么命令”。

3.3 trajectory.json:append-only 的永久历史

trajectory.json持久的可重放对象,它必须能超越当前头部存活,让后续工具重建产物是如何演进的。方法论要求每个 trajectory step 至少捕获:

  • step_idstep_indexcommand
  • command_started_atcommand_finished_at
  • publish_reason
  • source_fingerprint
  • bundle_idbundle_dirmanifest_pathsummary_path
  • 可选:stage_labelnote

方法论特别强调:把 Agent 动作绑定到预览状态应该发生在这里,不要指望 _bundle_dir 独自承担这个角色。canonical helper 提供了现成的实现:append_live_trajectory 读取既有 trajectory、按 len(steps) + 1 生成 step-000N 编号、追加新 step 后整体重写 trajectory.jsoncli-anything-plugin/preview_bundle.py);step 字段装配由 build_live_history_item 完成,它会自动从 bundle manifest 中兜底解析 commandsource_fingerprintcli-anything-plugin/preview_bundle.py)。

消费侧同样为这种 append-only 结构做了容错解析:cli-hub/cli_hub/preview.py_pick_trajectory_events 会依次尝试 preview_events/events/publishes/entries/history/steps/timeline 等键名,_normalize_timeline_row 则归一化多种命令/时间戳命名,保证不同 Harness 写出的 trajectory 都能被统一展示。

4. Canonical helper:发布流程的复用模式

协议文档与仓库共同确立了一个“把 canonical helper 复制进 Harness”的落地模式(与 repl_skin.py 同款):canonical 版本位于 cli-anything-plugin/preview_bundle.py,试点 Harness 将其 vendored-copy 为 utils/preview_bundle.py,避免为所有 harness 包引入新的共享运行时依赖。当前仓库中已存在的 vendor 副本包括:

这个 helper 承担了方法论检查清单中“发布 preview-bundle/v1 bundle”所需的全部脏活:bundle 目录创建、manifest/summary 写入、相对路径的产物描述符、缓存键生成。preview capture 的典型调用链为:

  1. prepare_bundlecli-anything-plugin/preview_bundle.py):用 build_cache_keyprotocol_version + software + recipe + bundle_kind + source_fingerprint + options + harness_version 做 sha256 得到缓存键(cli-anything-plugin/preview_bundle.py);除非 --force,先调用 find_cached_manifest 扫描同 cache_key 且状态为 ok/partial 的既有 manifest,命中即返回 cached: True,否则创建新 bundle 目录。
  2. 真实后端渲染:这是 Harness 自己的逻辑,产物写入 artifacts/
  3. artifact_recordcli-anything-plugin/preview_bundle.py):把产物文件转换为带相对路径的 manifest 描述符,自动猜测 media_type、记录 bytes
  4. finalize_bundlecli-anything-plugin/preview_bundle.py):先写 summary.json 再写 manifest.json,并回挂 _manifest_path/_bundle_dir/_summary_path 供后续 live 发布引用。

bundle 的默认位置也在此实现中固化(cli-anything-plugin/preview_bundle.py):

# 有项目路径:<project_dir>/.cli-anything/previews/<software>/<recipe>/
# 无项目路径:~/.cli-anything/previews/<software>/<recipe>/

这与协议文档“产物尽量留在项目附近、bundle 便于垃圾回收、cli-hub 可扫描可预测的根”的理由一致。

5. 推荐的 CLI 表面

5.1 基线表面

当软件拥有有意义的可预览状态时,应暴露三个基础命令:

命令 推荐行为
preview recipes 列出支持的预览 recipe 及其产物
preview capture 从当前源状态产出新的或缓存复用的 bundle
preview latest 返回该项目与 recipe 的最新已存在 bundle,不重新渲染

preview latest 必须只读。Blender 的实现印证了这一点:latest 直接调用 find_latest_manifest 按时间序倒排扫描 manifest 并返回第一个 statusok/partial 的条目,找不到则抛出 FileNotFoundErrorblender/agent-harness/cli_anything/blender/core/preview.py),全程不触发渲染。

5.2 可选 diff 表面

当软件适合直接的 A/B 对比时才暴露 preview diff。适合场景:GPU 抓取工具、具有 before/after 检查状态的工具、以及差量比当前 hero 帧更重要的工作流。RenderDoc Harness 就是协议文档中规划的 diff 试点:preview capture --event-id N 输出缩略图 + 输出目标 + pipeline JSON,preview diff --event-a A --event-b B 则把 A 侧输出标为 before、B 侧标为 after,并附带 diff-json 载荷(设计见 docs/PREVIEW_PROTOCOL.md 的 PR4 章节)。

5.3 可选 live 表面

当迭代式 live 检查有价值时,暴露四件套并遵循以下语义:

命令 语义
preview live start 初始化 session 根目录并发布首个 bundle
preview live push 向既有 live session 追加一个新 bundle
preview live status 只报告当前状态,不渲染
preview live stop 标记 session 非活跃,但保留全部已发布历史

Blender 的实现完整覆盖了这四条:live_startcapture_publish_live_sessionblender/agent-harness/cli_anything/blender/core/preview.py);live_push 读取既有 session 的 mode 与 poll 参数后复用 live_start 通路,publish_reasonmanual-pushblender/agent-harness/cli_anything/blender/core/preview.py);live_status 只读 session.json 并附加 trajectory 摘要(blender/agent-harness/cli_anything/blender/core/preview.py);live_stop 终止 poller 进程、置 status: "stopped" 并落盘,但不动任何已发布 bundle(blender/agent-harness/cli_anything/blender/core/preview.py)。

5.4 可选 poll-first 刷新

事实源是文件型、且 Agent 可能在预览调用之间通过其他命令保存文件时,使用 poll-first 刷新。适合:JSON 项目文件、XML 时间线、以及指纹重算廉价的抓取/场景文件。Poll 支持的典型形态:

preview live start --mode poll
# + 内部后台 monitor 循环
# + 渲染前先做源指纹检查

方法论同时给出明确警告:只有当 poll 模式确实降低 Agent 摩擦时才加它。不要添加会发布无意义重复 bundle 的后台循环。 指纹检查机制在 canonical helper 中即有支撑:fingerprint_file 基于 path + size + mtime_ns 计算 sha256(cli-anything-plugin/preview_bundle.py),Blender 侧则用 _project_file_fingerprint 在每次发布时更新 source_state.last_seen_fingerprint/last_rendered_fingerprint 供 monitor 对比(blender/agent-harness/cli_anything/blender/core/preview.py)。

6. 面向 Agent 的 preview live status --json 契约

这条命令存在的目的,是让 Agent 的 live 循环足够廉价。它应当回答五个问题:

  1. live session 是否存在?
  2. 是否处于 active 状态?
  3. 当前 bundle 是什么?
  4. 最近一次发布原因(publish reason)是什么?
  5. 最近一次“命令 → 预览”的映射是什么?

方法论推荐 --json 输出包含:

status, active, _session_dir, _session_path,
current_bundle_id, current_bundle_dir, current_manifest_path, current_summary_path,
_trajectory_path, current_step_id, latest_command, latest_publish_reason,
trajectory_summary

其中 trajectory_summary 必须紧凑且解析廉价,包含:

  • step_count
  • current_step_id
  • latest_command
  • latest_publish_reason
  • latest_bundle_id
  • recent_steps

这样 Agent 无需在每次循环中打开完整 trajectory 文件就能判断 session 是否在推进。canonical helper 的 summarize_trajectory 正是按此契约实现:取最后 recent_steps(默认 3)步,每步仅保留 step_id/step_index/bundle_id/publish_reason/command/command_finished_at/status/cached,并清理 None 字段(cli-anything-plugin/preview_bundle.py);Blender 的 live_status 在检测到 trajectory.json 时自动注入 payload["trajectory_summary"]blender/agent-harness/cli_anything/blender/core/preview.py)。

此外,Blender 的 session 负载还把 _session_dir 等带下划线前缀的内部引用统一通过 _with_live_refs 注入——这解释了推荐字段中为何出现 _session_dir/_session_path/_trajectory_path 这类下划线键:它们是给 Agent 定位文件用的机器字段,与人类可读字段区分。

7. README 与 SKILL 文档指引

支持预览的 Harness 必须在 README.mdSKILL.md 两处都讲清预览。

README.md 应覆盖:

  • 存在哪些预览模式;
  • 每个 recipe 产出什么;
  • 如何发布 bundle;
  • 如何用 cli-hub previews ... 检查/watch/open;
  • live session 的行为方式;
  • 真实性注意事项(如注入的预览相机、辅助 rig)。

SKILL.md 应覆盖:

  • preview 下的 producer 命令表面;
  • difflive、poll 模式是否可用;
  • cli-hub previews ...只读消费者这一事实;
  • 面向 Agent 的 --json 使用指引;
  • 预期的产物角色(herogalleryclip、diff 输出等)。

方法论要求每个预览示例都必须同时展示两侧

cli-anything-<software> --project demo.ext preview capture --recipe quick --json
cli-hub previews inspect /path/to/bundle

仓库中各 Harness 的 SKILL.md(如 skills/cli-anything-blender/SKILL.mdskills/cli-anything-freecad/SKILL.md)即是该规范在技能层的具体体现。

8. 何时添加 diff、live 或 poll:决策表

方法论给出的取舍标准:

能力 添加条件 避免条件
preview diff 对比本身就是产品 当前状态 bundle 已能回答该问题
preview live 迭代式 Agent 工作受益于稳定的“当前头部” 工具只产出偶发的一次性导出
poll-first 刷新 项目指纹会在 preview 命令之外发生变化 源指纹昂贵或更新很少

收尾原则同样重要:不要为了对齐另一个 Harness 而增加复杂度。只有在能力匹配软件真实迭代节奏时才添加。

9. 真实性规则(Truthfulness)

预览必须“诚实到足以支撑 Agent 决策”。数据来源按优先级排序:

  1. 真实后端的原生渲染/导出;
  2. 真实工具的原生检查或回放输出;
  3. 真实项目的离屏抓取辅助。

必须避免:

  • 在工具之外合成的假渲染;
  • 把 GUI 录屏作为主要预览产物;
  • 与软件真实输出悄悄偏离的近似。

如果 Harness 需要临时辅助状态,应诚实暴露

  • 将 bundle 标记为 partial 或等价状态(canonical helper 的 finalize_bundle 原生支持 status 参数,且缓存命中也接受 partial,见 cli-anything-plugin/preview_bundle.py);
  • 在 summary/context 输出中注明注入的预览相机、灯光或辅助件;
  • 在可能时把项目指纹与注入的预览 rig 分开计算。

这与协议文档的渲染规则一脉相承:允许用真实应用/后端做低分辨率预览、用 ffmpeg/RenderDoc API 等原生工具从真实渲染中提取帧,但禁止发明玩具渲染器,也禁止以无关 GUI 窗口的截图作为唯一事实源。

10. 实施检查清单

落地前逐条核对:

  • [ ] 判断预览对该软件是否真正有意义;
  • [ ] 定义一个或多个输出明确的 recipe;
  • [ ] 发布 preview-bundle/v1 bundle;
  • [ ] 保持 bundle、session、trajectory 三者相互独立;
  • [ ] 所有 preview 命令支持 --json
  • [ ] preview latest 只读;
  • [ ] preview live status --json 对 Agent 足够廉价;
  • [ ] 在 README 与 SKILL 中记录 producer vs consumer 命令;
  • [ ] 验证输出确实来自真实后端。

11. 相关参考

登录后查看全文
热门项目推荐
相关项目推荐

项目优选

收起
kernelkernel
deepin linux kernel
C
33
18
docsdocs
暂无描述
Markdown
899
5.83 K
ops-transformerops-transformer
本项目是CANN提供的transformer类大模型算子库,实现网络在NPU上加速计算。
C++
1.14 K
2.76 K
pytorchpytorch
作为 Ascend for PyTorch 社区的核心组件,TorchNPU 是昇腾专为 PyTorch 打造的深度学习适配插件,使 PyTorch 框架能够直接调用昇腾 NPU,为开发者提供昇腾 AI 处理器的超强算力。
Python
860
1.35 K
ops-nnops-nn
本项目是CANN提供的神经网络类计算算子库,实现网络在NPU上加速计算。
C++
925
1.85 K
jiuwenswarmjiuwenswarm
JiuwenSwarm 是一款基于openJiuwen开发的智能AI Agent,它能够将大语言模型的强大能力,通过你日常使用的各类通讯应用,直接延伸至你的指尖。
Python
3.84 K
1.02 K
kernelkernel
openEuler内核是openEuler操作系统的核心,既是系统性能与稳定性的基石,也是连接处理器、设备与服务的桥梁。
C
533
601
ops-mathops-math
本项目是CANN提供的数学类基础计算算子库,实现网络在NPU上加速计算。
C++
1.37 K
1.46 K
AscendNPU-IRAscendNPU-IR
AscendNPU-IR是基于MLIR(Multi-Level Intermediate Representation)构建的,面向昇腾亲和算子编译时使用的中间表示,提供昇腾完备表达能力,通过编译优化提升昇腾AI处理器计算效率,支持通过生态框架使能昇腾AI处理器与深度调优
C++
548
395
cann-learning-hubcann-learning-hub
CANN 学习中心仓,支持在线互动运行、边学边练,提供教程、示例与优化方案,一站式助力昇腾开发者快速上手。
Jupyter Notebook
1.04 K
525