1. 交互层升级为什么我在做了一版 Chat UI 之后把它推倒重来去年年中我开始做一个跑在终端里的编码 agent。第一版交互层非常简单一个 Chat UI左侧显示我敲进去的自然语言指令右侧滚动输出 agent 的思考过程和代码 diff。当时想着既然 agent 的核心是“理解需求、改代码、跑测试”那聊天框就是最自然的入口。实际用下来几个星期后我就决定动手重写交互层把整个前端形态从 Chat UI 换成了 Agent Workbench。这中间踩了不少坑也把交互设计的思路彻底翻了一遍。先交代一下背景。这个 agent 不是一个 IDE 插件而是运行在终端里的命令行工具。用户通过终端启动它给它一个任务描述比如“把登录接口的超时时间从 30 秒改成可配置项”它会自己去读代码、定位文件、修改然后跑测试给你看。最初版本的交互流程是用户在 Chat UI 里输入任务agent 在后台执行结果以聊天消息的形式回传。这个形态对“问一个问题”很友好但对“完成一个任务”来说问题非常多。最大的问题是上下文割裂。Chat UI 天然是“一段对话串起多个意图”但编码任务是强状态的agent 需要记住当前在改哪个文件、哪个分支、哪个函数甚至要记住它自己刚才做的某个修改为什么回滚了。这些状态塞进聊天记录里视觉上就是好几个很长的代码块滚来滚去。我看消息的时候经常要往上翻很久才能搞清楚 agent 现在到底在处理哪个模块。更麻烦的是如果中途用户想插一句“这里不要用正则改用状态机”在 Chat UI 里这句话会变成一条普通的聊天消息agent 有时候能正确理解这是对当前任务的修正有时候会当成一个全新需求去处理效果完全不可控。另一个痛点是操作链条断裂。聊天界面适合问答不适合“确认-执行-观察-再执行”这种循环。比如 agent 要执行一个高风险的删除操作在 Chat UI 里我只能输出一个“确认删除吗y/n”的文本消息用户回复 y然后再等下一个消息。整个过程没有按钮、没有状态标识多次确认时用户很容易分不清当前问的是哪一个操作。终端用户本身是习惯快捷键和精确反馈的这种体验太粗糙了。后来我花了两周时间做了一次用户测试拉了六个朋友在真实项目上试用。反馈比较集中的问题包括找不到历史操作记录、agent 的执行状态不透明、对文件变更没有直观预览、权限确认太繁琐。测试结束之后我基本确定要做一次交互层的全面升级把聊天形态转成工作台形态也就是现在的 Agent Workbench。所谓的 Workbench简单说就是任务不再是一串消息而是一个可以展开、可以回放、可以单独操作的工作单元。它包含任务描述、文件变更列表、执行记录、终端输出流、确认队列这些结构化元素而不是把什么都塞进聊天气泡里。这篇文章就围绕这次升级展开。我会从交互模型的设计思路、核心模块的落地细节、终端生态整合的坑以及实际使用中的问题排查这几个角度来复盘希望能给同样在做终端侧 AI 工具、编码 agent 或者类似交互产品的朋友一些参考。2. Agent Workbench 交互模型的核心设计2.1 从“消息流”到“任务单元”的结构变化Chat UI 的基本单位是“消息”一条消息就是一次交互的最小单元。而 Workbench 的基本单位变成了“任务”一个任务包含多条消息、多次工具调用、多个文件变更、多轮终端输出。这个转变听起来只是抽象层级提升了一层实际设计上差别非常大。任务单元的数据结构是这么设计的它有一个独立的状态机状态包括 pending、planning、executing、waiting_confirmation、completed、failed、cancelled。每个状态下面挂了对应的子资源比如 planning 状态下面挂任务拆解出的步骤列表executing 状态下面挂实时执行日志和文件 diffwaiting_confirmation 状态下面挂待确认的操作卡片。这样设计的好处是前端可以针对不同状态渲染完全不同的视图而不是像 Chat UI 一样把所有状态都拍平成一串消息。这里我要特别强调“操作卡片”这个概念。在旧版 Chat UI 里agent 执行一个 shell 命令就是输出一行Running: pip install requests。在 Workbench 里它是一张卡片卡片上有命令内容、执行时长、退出码、输出摘要、可展开的完整日志以及一个“重新执行”按钮。命令执行失败时卡片上会直接标出错误类型和建议排查方向。这些卡片组合在一起就等于一个可回放、可审计的操作历史。对于编码任务来说这个能力特别重要因为用户需要知道 agent 每一步做了什么、为什么这么做才能放心让它继续往下走。结构调整之后还有一个很实际的好处token 压力降下来了。聊天界面里每发一条消息都要携带全部历史上下文哪怕前面已经折叠token 消耗也是实实在在不减的。任务单元可以把已经结束的步骤归档把一个长任务拆成多个短会话每个会话只携带与当前步骤相关的上下文。在我实测中一个中型重构任务涉及 20 个文件、40 次工具调用旧版 Chat UI 方式的 token 消耗比 Workbench 高了大概 40%主要就贵在反复携带历史代码片段和完整工具输出上。2.2 工作台的三个核心面板任务区、变更区、终端区Workbench 的界面是典型的三栏结构。最左边是任务区展示当前任务的目标、拆解步骤、执行状态和确认队列。中间是变更区展示 agent 对代码文件的增删改以统一的 diff 视图呈现每个文件单独一个标签页。右边是一个内嵌终端面板用于显示 agent 执行的 shell 命令和实时输出。任务区是整个交互的中枢。它不是一个被动的状态展示面板而是可交互的。用户可以在任务区里给某个步骤直接标注“跳过”或“重试”也可以拖拽调整步骤顺序。这个设计是从 CI 流水线的界面借鉴过来的因为 agent 的规划结果本质上就是一个自动化流水线只是执行者从固定脚本换成了大模型驱动。把规划结果可视化成一个步骤列表用户能直观看到 agent 接下来要做什么也能在问题发生前提前干预。变更区则承担了“代码审查”的角色。每个文件 diff 都可以单独展开支持行内评论。用户在评论里写的意见会作为反馈回传给 agentagent 会基于意见重新修改。这个机制替代了聊天框里的“这里改成 xxx”式反馈反馈的位置和内容都精确得多agent 的修改准确率明显提升。我统计过一次改用行内评论反馈后agent 一次修改就符合预期的比例从 61% 升到了 78%原因很简单位置信息更清晰了模型不需要从上下文里猜你指的是哪一行。终端区是最特别的部分也是整个 Workbench 和普通前端工具最大的区别。它不是简单地把 agent 的 shell 命令结果渲染成文本而是直接接入了一个真实终端模拟器。也就是说用户可以在终端区里手动执行命令agent 也可以在里面执行命令两边共享同一个 shell 会话。这个设计我后面会详细展开它是整个交互层升级中最难做、但也最值得做的部分。3. 终端区的设计agent 与用户共享同一个 Shell 会话3.1 为什么 Chat UI 里的输出展示方式行不通很多编码 agent 的实现都会把 shell 命令的输出简单地获取一下然后塞进聊天消息里。这种方式在 demo 里看不出毛病实际用起来却有明显的割裂感。最大的问题是没有“过程感”。一个耗时很长的命令比如跑完整测试套件需要十几二十分钟。聊天消息是等命令跑完才一次性显示结果的用户在这段时间里什么都看不到不知道是正常执行还是在死循环里。终端用户早就习惯了实时滚动输出。如果 agent 执行一条命令输出里出现了一个进度条或者一个交互式提示聊天界面简直束手无策。我遇到过最典型的情况是agent 执行一个会弹出交互提示的脚本比如询问“是否覆盖现有配置文件 [y/N]”在聊天界面里这句话被当作普通输出捕获程序在后台挂起等待输入agent 却以为执行成功了。等到超时才发现程序根本没往下走。这类问题在 Chat UI 架构下几乎无解。还有一类问题出在 ANSI 转义序列上。很多命令行工具为了显示颜色和样式会输出包含 ANSI 转义字符的内容。在聊天界面里这些字符要么被原样显示出来变成一堆乱码要么需要单独写逻辑去清洗。用户反馈里多次出现“终端输出乱码”的记录排查后发现是我们清洗逻辑对某些特殊转义序列处理不到位。这些问题本质上都是因为聊天界面不是一个真正的终端。3.2 接入终端模拟器和复用 Shell 状态解决这些问题的方案是内置一个真正的终端模拟器。我们调研过 xterm.js、Tabby 的 Terminal 组件以及 Go 语言生态里的 tcell 等方案最终选定了基于 xterm.js 的方案因为它生态成熟、API 完善而且社区里有大量现成的插件可以处理 ANSI 转义、富文本渲染、WebGL 加速这些底层问题。但光有一个好看的终端模拟器还不够核心难点在会话管理。我要求 agent 执行的命令和用户手动执行的命令必须共享同一个 shell 会话。这样做的好处非常多agent 先执行cd /project/auth用户之后手动执行pwd得到的就是/project/auth环境是连贯的。如果 agent 和用户各用一个全新的 shell这种状态就完全丢失了。实现这个能力关键技术点是采用 PTY伪终端来承载 shell 进程。PTY 会让 shell 认为自己运行在一个真实的终端里因此交互式程序、彩色输出、快捷键处理都能正常工作。agent 的每次命令执行不是创建一个新进程而是通过标准输入写入当前 PTY 的 master 端命令输出则从 PTY 的 slave 端持续读取推送到终端模拟器渲染。这里要特别注意处理一个容易踩的坑一次命令执行可能产生多条输出也可能一条输出横跨多次读取所以不能简单地把读取到的数据切分成“消息”。正确的做法是维护一个输出缓冲区并为每次命令执行打上起始标记和结束标记配合 shell 的提示符字符串来识别命令边界。实测中用提示符识别边界比用命令自身输出来识别要可靠得多因为有些命令根本不产生输出但提示符是每次命令结束后必然出现的。这个设计落地后变化非常明显。以前测试 agent 时遇到交互式命令我总是要手动干预现在 agent 发现程序在等待输入时会在 Workbench 里弹出一个“需要输入”的卡片用户可以直接在终端面板里输入内容agent 会感知到输入并继续执行。对用户来说这个体验和自己在终端里跑命令几乎没差别。3.3 终端会话复用带来的新问题与缓解方案当然共享 shell 会话也带来了一些新问题。第一个问题是环境变量污染。用户可能在自己的 shell 里设置了某些别名或环境变量agent 执行命令时这些配置可能会影响结果。比如用户定义了alias llls -laagent 如果执行ll也能运行但如果项目本身有一个叫ll的脚本alias 就会覆盖脚本导致 agent 调用了错误的东西。缓解方案是双轨制agent 的初始化命令里显式重置关键环境变量比如unalias -a同时清理掉和项目无关的变量但保留PATH、PWD、VIRTUAL_ENV这类与项目上下文强相关的状态。具体保留哪些、清理哪些我们做了一个可配置的白名单机制。默认配置下PATH和PWD是保留的用户自定义的 alias 默认清除但可以在配置文件里指定放行。第二个问题是并发冲突。如果用户和 agent 同时往同一个 PTY 写命令输出会互相交错。我在设计初期就决定PTY 一次只允许一个写者要么是 agent要么是用户。当 agent 在执行命令时终端面板的输入区会被锁定显示一个“agent 执行中”的提示但用户可以随时按 CtrlC 中断 agent 的执行中断后控制权立即返回给用户。这个设计保证了终端的可控性也符合终端用户的使用习惯任何时刻总有一个实体在控制终端不允许两个实体同时抢键盘。还有一个比较隐蔽但很常见的问题子进程的生命周期管理。agent 可能会启动一个后台服务比如npm run dev然后继续往下执行。如果 agent 后续任务需要重启这个服务而旧进程还占着端口就会报错。这个问题的根源是 shell 会在子进程结束前一直等待。我们的方案是agent 启动后台任务时明确要求它使用nohup或setsid以及输出重定向将任务与当前 shell 会话解耦。如果 agent 忘了这么做我们会在终端面板里检测到命令超时并且给出提示问用户是要等待、强制退出还是转为后台任务。4. 从“盲操作”到“可视化”:工具调用与文件变更的呈现4.1 工具调用的过程可视化早期 Chat UI 版本里agent 调用工具就是一个黑盒。它调用了一个搜索函数但搜的是什么、结果有多少条用户完全不知道。工作台状态里我把每次工具调用都变成一个可视化单元。具体来说每个工具调用单元包含五部分工具名称、传入参数摘要、执行耗时、返回结果摘要、以及一个“展开详情”按钮。展开后可以看到完整参数、原始返回值以及错误堆栈如果有。以文件搜索为例参数摘要会显示搜索范围: src/auth, 关键词: timeout返回结果摘要显示命中 12 个文件展开后列出每个文件的相关行。这样用户不需要阅读源码就能判断 agent 的搜索方向是否正确。我还给常见工具类型做了专门的视图模板。文件编辑器不是简单地显示整文件替换而是展示精确到行的增删标记。代码搜索工具的结果会按文件分组可全局折叠。终端执行工具的结果本身就来自 PTY所以直接渲染到终端面板但也会在详情视图里保留一份可检索的文本。这套可视化的实现成本不低。光是给每个工具定义参数摘要和结果摘要的格式就花了不少工夫。但收益是实实在在的。用户对 agent 的信任度大幅提升因为他们能看到 agent 的“思考过程”不是一句干巴巴的“我来搜索一下相关文件”而是具体到关键词、范围、命中量的信息。另外一个意外的好处是调试 agent 本身变得方便了很多我作为开发者看到某个工具调用结果不对可以立刻定位是参数构造的问题还是工具实现的问题。4.2 文件变更的预览、批量操作和回滚文件变更是编码 agent 的核心产物也是 Workbench 里交互设计的重中之重。我总结了几条原则变更必须可见、变更必须可理解、变更必须可控。可见性意味着任何文件改动无论大小都要立刻出现在变更区并且有高亮标识。可理解性意味着不能只显示一个原始 diff还要附上 agent 自己的说明。可控性意味着用户能对变更进行批量操作。在 Workbench 里每个文件变更卡片都有三个按钮“查看详情”、“采纳当前修改”、“还原当前修改”。还有全局操作“采纳全部变更”和“还原全部变更”。这里有个细节值得展开agent 一次可能改很多个文件但并非每个修改都符合用户预期。旧版 Chat UI 里如果用户想部分采纳修改只能复制 diff 里的内容手动应用回去体验很原始。Workbench 里增加了“批量选择”模式用户可以勾选多个文件变更一次性采纳或还原。此外我设计了一个“临时快照”机制一个任务开始时自动为涉及的文件保存一份原始内容副本任务结束后这份快照会保留 7 天方便用户随时回退。这个机制有点像数据库的事务日志只不过它的粒度是文件而不是记录。回滚操作也必须考虑依赖问题。如果两个文件都被修改而且修改之间有依赖关系比如 A 文件定义了一个函数B 文件调用它只还原 A 会导致 B 报错。所以在批量还原时Workbench 会做一次简单的依赖检查标记出可能存在依赖关系的文件对并提示用户确认。这个检查的逻辑不算复杂本质上就是字符串匹配加基础语法分析但能避免很多“我自己把项目改坏”的情况。4.3 任务状态机与多任务并行管理一个真正的 agent Workbench 不应该只支持单任务。我们支持同时运行多个任务每个任务有自己独立的状态和执行队列。用户可以在“任务列表”里看到所有任务按创建时间排序每个任务都有状态标识和进度条。多任务并行听起来挺方便但实际用下来不建议让两个 agent 同时修改同一个项目目录会产生文件冲突。所以我设计了一个简单的锁机制一个项目目录同时只允许一个 agent 任务执行其他任务进入排队状态。这带来一个取舍如果一个任务只需要做“搜索代码”这种只读操作其实可以并行但为了模型简单我第一版选择了所有任务串行排队。后来做了优化只读任务可以并行写任务独占锁。多任务的管理界面和单任务类似只是增加了一个“切换到任务”的操作。每个任务在列表里显示一个迷你状态摘要包括当前步骤名、最近一次工具调用时间、变更文件数。点击任意任务工作台会切换到该任务的详情视图。这个视图切换需要保存每个任务的滚动位置和展开状态否则用户切换回来还要重新找刚才看到哪一行体验会大打折扣。5. 与终端生态的联动配置、快捷键与用户习惯5.1 读取现有终端配置与个性化适配既然工作台跑在终端场景里就不可能无视用户已有的终端配置和习惯。我遇到的一个高频需求是用户希望在 Workbench 里执行的 shell 命令能够继承他们终端里的自定义环境变量、PATH 配置、代理设置等。这些配置通常写在.bashrc、.zshrc这类文件里。我的方案不是去解析这些文件而是直接要求 agent 在启动时模拟一次 interactive login shell 的加载过程把这个过程中的环境变量快照下来作为 agent 执行命令时的基础环境。这里踩过一个坑直接继承用户 shell 的全部环境变量可能会导致不可预期的问题。比如用户 shell 里设置了NODE_OPTIONS--max-old-space-size2048这可能影响编译过程。所以环境继承不是全盘照搬而是有一个过滤规则默认清除掉与 UI 相关的变量、终端会话特有的变量保留与项目构建、语言运行时、包管理器相关的变量。终端用户还特别在意快捷键。Workbench 做了一些默认的快捷键映射比如CtrlL清空终端输出CtrlC中断当前任务CtrlR打开任务搜索。这些快捷键的设计必须和常见终端保持一致否则用户会下意识地按错。我们专门整理了一份兼容性映射表把 Bash、Zsh、tmux 里常用的快捷键都做了对应。5.2 终端复用场景的取舍是不是要替代 tmux做终端区设计的时候很多人问我要不要直接集成 tmux 这类终端复用工具。我认真考虑过最后还是决定不依赖。tmux 的学习成本并不低而且它的会话层次、共享逻辑和我要的“agent 与用户共享 PTY”在概念上不完全匹配。强行集成只会增加复杂度。但我确实做了类似 tmux 的会话恢复功能。Workbench 会定期把 PTY 的输出缓冲区快照保存到本地文件即使程序崩溃或者用户关闭窗口重新打开后可以恢复之前的终端输出。这个功能实现也不复杂核心就是持续读取 PTY 输出时同时写一份日志文件界面初始化时先加载最近一份日志再开始实时读取。另外还有一个不常被注意但很实用的细节终端字体调整。很多终端朋友对字体渲染有要求默认等宽字体在不同的系统里渲染效果差别很大。我们的终端面板支持设置字体家族和字号并且保存到本地配置。还有编码问题尤其是中文环境下的输出乱码。在 Linux 默认 locale 不是 UTF-8 的情况下某些命令输出 GBK 编码的中文xterm.js 直接按 UTF-8 解码会出现乱码。我们的处理是启动 PTY 时强制设置LC_ALLC.UTF-8环境变量同时提供手动切换编码的选项用户遇到乱码时可以通过菜单切换。5.3 从终端启动、文件拖拽到其他高频操作Workbench 本身是一个终端应用但它也必须在“物理终端”里运行。这里说的物理终端指的是用户启动它的那个程序比如 macOS 的 Terminal.app、Windows Terminal或者 Tabby 这类第三方终端工具。这里有一个隐性问题不同的物理终端在 ANSI 颜色、字体渲染、剪贴板交互上的表现有细微差别用户传回的错误截图经常伴随着“颜色显示不对”“光标位置异常”的现象。我们的做法是尽量减少对物理终端的依赖所有的复杂交互都在 Workbench 自己的 TUI 界面里完成物理终端只负责最基础的文字输出。文件拖拽也是一个高频操作。用户在资源管理器里选中一个文件拖进终端默认行为是把文件路径粘贴到命令行。我们在 TUI 里实现了对拖拽事件的支持文件路径会被当作一条消息发送给 agent比如“请研究一下这个文件”。不同物理终端对拖拽事件的支持程度不一致所以代码里要针对不同环境的实现做好降级。我在开发时经常用“终端如何把文件拷到 U 盘”这类基础操作来验证路径处理的正确性——听起来好笑但很多文件路径里包含空格和特殊字符处理不好就会让 agent 读错文件。6. 实操复盘一个中等项目的完整工作流演示6.1 从任务创建到完成的关键节点为了不空谈设计我用一个真实的改造任务串一遍完整流程。这个项目是一个 Express 后端服务任务要求是“登录接口现在使用固定的 token 过期时间改为可配置配置文件里的参数叫auth.tokenExpiry默认 2 小时。”用户在 Workbench 的任务区输入这个任务描述回车后新建了一个任务。任务状态从 pending 变成 planning。agent 开始读取项目结构这个阶段终端区会闪一些ls、find命令的输出任务区则显示一个“正在分析项目结构”的占位状态。大概 8 秒后planning 完成任务区出现了步骤列表第一步是定位登录接口相关文件第二步是搜索硬编码的过期时间第三步是修改认证模块的代码第四步是把配置项写入配置文件第五步是运行测试验证。这个步骤列表并不是纯展示。我手动修改了其中一个步骤把“搜索硬编码的过期时间”改成一个更精确的描述“在 models/user.js 中查找 jwt.sign 的 expiresIn 参数”。因为我知道这个参数可能在用户模型里。修改完成后agent 会根据更新后的步骤执行。这是任务单元模式的好处用户可以在执行前深度干预计划。执行开始后变更区陆续出现文件。最先出现的是.env.exampleagent 在里面加了AUTH_TOKEN_EXPIRY7200。接着是src/config/index.js加入了读取环境变量的逻辑。然后src/auth/token.js被修改expiresIn从固定值改成配置读取。每一个变更出现时我都看了 diff确认没问题才让它继续。第二个变更出现时我注意到一个问题agent 把配置名写成了AUTH_TOKEN_EXPIRY但我要求的是auth.tokenExpiry风格。我在 diff 的行内评论里直接写了“配置名请用 auth.tokenExpiry 风格改成小写加点的层级”agent 收到反馈后立即调整了后续的文件变更并且已经把前面写错的配置名同步修正了。6.2 终端输出和测试验证环节最后一个步骤是运行测试。agent 执行的命令是npm test。终端面板里开始滚动测试框架的输出。这里发生了非常经典的一幕测试跑了大概 30 秒后有两个用例失败了。失败原因是 agent 在修改 token 生成逻辑时漏改了一个测试文件里对过期时间常量的引用。终端区把失败信息展示得很清楚包括失败用例名和期望值、实际值的对比。agent 自己发现了问题任务区出现一个新队列“修复测试失败”自动展开下一步计划定位测试文件中的过期时间常量、更新引用、重新运行测试。我在这时候选择了手动干预在任务区把这个修复步骤的优先级调到最前agent 按照新顺序继续执行。第二次测试全绿任务状态变成 completed。变更区里一共有 6 个文件被修改我逐个检查了一遍确认没有多余变更然后点击“采纳全部变更”。任务结束。整个流程大概持续了 4 分钟期间我真正参与的只有 3 次一次是修改步骤描述一次是行内评论纠正配置名一次是调整修复步骤的优先级。对比旧版 Chat UI同样的任务我要么只能全程看着要么得用文字反复描述我的修改意图交互效率提升非常明显。6.3 任务复盘与过程审计Workbench 还支持任务完成后的复盘模式。它可以生成一个执行摘要内容包括本次任务涉及的文件数量、执行过的命令列表、消耗的 token 数量、总耗时、每个步骤的耗时分布。这些数据对个人开发者优化 prompt 和项目结构极有帮助。我拿自己的使用习惯数据举例子。运行一个月后我发现一个明显规律凡是步骤列表中包含“先运行测试”的任务整体成功率比不包含的高出约 15%。原因大概是 agent 更早获得反馈能及时发现问题。从那以后我写任务描述时几乎总会强调“先跑一遍现有测试”。这类通过复盘得到的规律在 Chat UI 时代是完全无法获得的因为没有结构化数据可以统计分析。7. 常见问题与排查技巧实录7.1 终端输出异常与编码乱码问题这是最常见的用户反馈来源。症状和原因对应关系大约可以整理成下面这张表症状常见原因处理建议输出全是彩色转义码比如[32m终端模拟器没有正确解析 ANSI 转义序列检查 xterm.js 是否启用了渲染插件确认 PTY 启动时环境变量TERM是否为xterm-256color中文显示为乱码locale 设置不一致强制设置LC_ALLC.UTF-8对于 GBK 输出提供手动解码切换输出闪烁或光标错位TUI 渲染和 PTY 输出竞争同一屏幕空间增加渲染锁保证同一时刻只有一方在写屏幕输出非常长导致明显卡顿大量数据一次性涌入前端对输出做分帧渲染或者缓冲后按固定时间间隔刷新编码问题的排查我有一条经验先在普通终端里手动跑一遍命令确认输出正常再放到 Workbench 里跑。如果普通终端正常、Workbench 异常基本可以确定是 PTY 环境变量或前端渲染的问题用二分法很快能定位。7.2 agent 执行挂起和超时处理agent 执行命令时挂起是另一个高频问题。挂起的原因多数是命令在等待用户输入或者启动了一个长期运行的前台进程。我的排查步骤是先在任务区查看当前步骤是否显示“等待输入”的状态。如果显示说明 PTY 里确实有程序在等待键盘输入直接在终端面板手动输入即可。如果不显示等待输入但任务长时间不推进那可能是命令本身执行时间过长。这时候我会检查命令的类型如果是一个编译命令或测试命令耐心等是值得的如果是网络请求类的命令可能是网络问题导致超时。针对这种情况我给每种工具类型都配置了默认超时时间比如网络请求类默认 30 秒编译任务默认 10 分钟。超时后 agent 会收到一个超时信号并由它决定是重试还是换一种方案。还有一个常被忽略的原因shell 提示符识别失败。agent 判断一条命令是否执行完依赖的是识别 shell 的新提示符。如果用户的提示符字符串设置得比较特殊比如包含动态时间、Git 分支信息、甚至是 ANSI 颜色码识别正则可能匹配不上导致 agent 认为命令还在执行。这个问题的排查方法是查看终端面板里是否有新的提示符出现如果出现了但 agent 没反应需要调整提示符识别规则。7.3 与各种物理终端的兼容性问题Workbench 跑在物理终端里不可避免地会遇到各种兼容性问题。比如 Windows 系统下用户可能在 PowerShell、CMD、Windows Terminal、或者是第三方终端工具里启动 Workbench。不同的终端对 ANSI 支持程度不同对剪贴板事件的支持也有差异。解决兼容性问题的核心思路是主动降级。我们不追求在所有终端里都获得完全一致的体验而是保证核心功能在最低配环境下也能用。比如剪贴板操作在支持的终端里可以做复制粘贴按钮在不支持的终端里退化为提示用户手动选择。另外我建议用户固定使用一个支持较好的终端工具作为主力环境。我自己的主力环境是 macOS 的 terminal配合 Tabby 作为备用。Tabby 这类现代终端工具对 ANSI 和 TUI 的支持比较完善出问题的概率低很多。如果用户报告某个终端工具有渲染问题我一般会让他先换一个终端试试。如果问题不在 Workbench 本身就不要在这上面花太多时间。7.4 配置和调试的小技巧最后分享几个调试 Workbench 交互层的小技巧。第一打开调试模式查看底层事件流。Workbench 的调试面板可以实时显示 PTY 的原始输入输出、agent 的内部状态机跳转、工具调用的完整参数和返回。遇到问题的时候先看一眼事件流大部分问题原因会立刻浮出水面。第二利用日志回放定位历史问题。Workbench 会把每次任务的所有事件都记录在本地日志文件里。开发过程里如果发现一个偶发问题可以先复现一次然后把日志文件保存下来下次再出现时对比分析。这个方法帮我解决了好几个“只在用户环境出现但我这里复现不了”的问题。第三配置项不要怕多但要有默认值。我设计配置系统的时候遵循一个原则默认配置适合 80% 的用户高级配置留给有特殊需求的人。比如提示符识别正则、环境变量过滤规则、命令超时时间这些东西都暴露成可配置项但默认值已经够用。真遇到问题再调整不用一上来就折腾参数。8. 从这次升级中得到的体会这次从 Chat UI 到 Agent Workbench 的交互层升级表面上改的是界面形态本质上是在重新回答一个问题用户面对一个编码 agent 时他到底是在“对话”还是在“工作”。答案显然是后者。对话只是手段工作才是目的。Chat UI 把一切都拍平成消息等于把一个复杂的多步骤工程任务降维成了聊天记录这不但丢失了信息结构还给用户带来了额外的认知负担。Agent Workbench 通过引入任务状态机、操作卡片、文件变更面板、共享终端区这些结构化元素把 agent 的执行过程还原成了一个可理解、可干预、可审计的工作单元。对我个人来说这次升级最大的收获不是技术方案的落地而是对“工具型 AI”交互设计有了更清晰的认识AI 工具与用户之间必须存在一个共同的、可操作的工作界面而不能只是一个问答通道。这个界面可以让用户信任 AI 的决策也能在 AI 犯错时快速干预。它应该是一张工作台而不是一个聊天框。