两种方式的差别通常不在任务结果本身,而在界面层多做了什么:dsh-TUI 会接管输入回显、把会话状态重排成常驻状态栏、并按视口高度裁剪长输出;直接跑 Harness 命令行则是把 stdout/stderr 原样交给终端或落盘文件。判断两者是否一致,不建议靠手感,而是固定同一份任务和同一份配置各跑一遍,只比对三处可观察现象——输出的先后顺序、状态栏字段能否在命令行输出里找到对应行、长输出是滚动还是被截断。
如果你只关心任务结果落盘,两种方式通常等价;如果你依赖阅读过程,dsh-TUI 多出来的是状态栏和视口管理,代价是输出被重定向到文件时顺序可能被重排、长行可能被裁剪。建议在同一份配置下各跑一遍,用 script 或 tee 记录成文件再 diff,不要凭肉眼感觉下结论。状态栏字段来源无法确认时,按“界面自算”处理,别把它当结果校验依据。
同一条任务在两种方式下各跑一遍
先固定任务输入,避免两次跑的不是同一件事。把任务写进文件而不是直接敲在交互行里,输出顺序才有可比性。下面命令里的 harness 与 dsh-tui 请替换成你环境里的实际入口名,配置路径也按自己的目录调整。
mkdir -p ~/tui-diff && cd ~/tui-diff
printf '%s\n' '列出当前目录结构,并统计 .py 文件行数' > task.txt
# 方式一:直接跑命令行,stderr 单独留一份,便于看顺序
harness run `--config` ./cfg.toml `--input` task.txt > cli.out 2> cli.err
# 方式二:TUI 需要 pty,用 script 把整屏输出录下来
script -q -c 'dsh-tui run `--config` ./cfg.toml `--input` task.txt' tui.raw > /dev/null
# 再看一遍纯文本结果
wc -l cli.out cli.err tui.raw跑完后不要急着读内容,先读顺序。把两次执行的“先出现什么、后出现什么”各自记一行,例如:命令行方式先打印启动横幅,再逐行输出任务结果,最后打印一行退出摘要;dsh-TUI 方式则在启动横幅之后插入状态栏刷新行,任务结果与状态行交替出现,结束时状态栏不随进程退出而清屏。差异清单可以按下面四项填:
- 启动信息出现的时机:命令行方式一次性打印,TUI 方式可能与首次界面重绘混在一起。
- 结果输出是否被拆行:TUI 方式受终端宽度影响,同一段文本可能被换成多行。
- 结尾信息:命令行方式通常有明确的退出码和摘要行;TUI 方式退出后状态栏内容可能残留在录制文件末尾。
- stderr 归属:命令行方式可单独重定向到 cli.err,TUI 方式下的错误常常并入主屏输出,需要靠关键字筛。
观察状态栏显示的信息与命令行输出是否同源
状态栏一般会显示工作目录、当前模型或后端标识、会话标识、已用时长、token 或字符计数、正在执行的工具名这几类字段。判断它们是不是从 Harness 内部事件流读出来的,方法不是看样式,而是改一个可观测变量再观察谁跟着变。先记下当前状态栏的文字描述(没有截图条件时,把字段名和取值抄成一行文字即可,例如“cwd=/home/me/proj model=base turns=3”),然后:
- 改工作目录再启动:如果状态栏的 cwd 变了,而命令行输出里也出现了同样的路径,说明该字段来自 Harness 传给界面的上下文。
- 换一个后端或模型标识:命令行若支持打印生效配置(如
`--print-config`、`--dry-run`一类开关,按你的 Harness 实际支持情况使用),对比两边显示的标识是否一致。 - 跑一个多轮任务:对比状态栏的轮次计数与命令行输出里可数的工具调用行数。
对应关系只有三种结论:能一一对上,说明同源;只有部分字段能对上,说明剩下的由 TUI 自行统计;完全对不上,就标注为“无法确认”,并明确它不能作为任务是否完成的判断依据。计数类字段尤其容易两边算法不同,例如 TUI 按流式分片计数、命令行按最终文本计数,这种差异需要结合具体实现确认,不能默认相等。
在长输出场景下对比滚动与截断行为
长输出要人为构造,别指望真实任务每次都跑出几千行。用固定行数、固定列宽的内容最容易比较:
# 构造长输出任务:行数多,且单行较长
printf 'for i in $(seq 1 20000); do printf "line-%05d %s\n" $i "$(printf 'x%.0s' {1..200})"; done\n' > long.sh
harness run `--config` ./cfg.toml `--input` long.sh > long.cli 2>&1
script -q -c 'dsh-tui run `--config` ./cfg.toml `--input` long.sh' long.tui > /dev/null
wc -l long.cli long.tui比较时看两点。一是滚动:命令行方式是终端自己在滚,回看只能靠终端缓冲或重定向文件;dsh-TUI 通常是自绘视口,只渲染可见区域,回看靠界面自己的滚动缓冲,缓冲区上限往往是配置项或固定值,超出后前面的内容可能不再保留。二是截断与折行:命令行方式受管道影响小,重定向到文件时内容完整;dsh-TUI 在宽度不足时对超长行可能折行或截断,且输出被重定向到非 tty 时,有的实现会退化成纯文本、有的仍按固定宽度排版。判断方法是看 long.tui 里是否存在被截掉的尾部字符、以及行数是否明显少于 long.cli。如果确实少于,说明界面层做了裁剪,落盘归档建议直接用命令行方式。
用同一份配置来回切换两种方式
上面结论要成立,前提是两次跑的是同一份配置。先确认配置来源:常见有三处——命令行的 `--config` 显式指定、环境变量指定、以及默认路径下的配置文件(例如 ~/.config/ 下的同名文件)。切换步骤建议这样走:
- 在命令行方式下把生效配置打印或记录下来,作为基准快照。
- 用同一路径的配置启动 dsh-TUI,再打印或从日志里找出生效配置,与快照逐项比对。
- 删掉环境变量与默认配置文件的影响(例如临时
env -i起一个干净环境),再各跑一遍第一小节里的 task.txt。 - 对两次输出做
diff -u,把差异归因到“界面重排”还是“配置不同”。
如果去掉了环境干扰、配置完全一致,两次的任务结果文本仍应一致,不一致的部分通常集中在前一节的顺序、状态栏行和长行裁剪上,这些属于界面层差异,不是行为不一致。反过来,如果干净环境下结果本身就不一样,那多半是两条入口读了不同配置或不同默认值,这时先修配置,不要再去调界面设置。是否需要长期用 dsh-TUI,取决于你是否真的需要常驻状态栏与视口滚动;只需要结果和日志的话,直接跑 Harness 命令行更省事。