Agent 工作台一次实测暴露的四个问题:失败步骤仍写「正在执行」、40+ 分钟才判失败、头部数字不可解、pdf-create 分页错乱
- Dominant language
- TypeScript
- Stars
- 0
- Forks
- 0
- Avg merge
- 1h 7m
- Merged PRs (30d)
- 969
Description
> 来源:devapp 一次真实任务的执行轨迹截图(2026-09-10)。四条问题各自独立、可分别修,合并在一条里方便一起看上下文。
> 原先拆成 #3362 / #3363 / #3364,已按人类要求并入本条。
---
## ① 失败的 run 里步骤文字仍写「正在执行」——#3316 修了图标,没修同一行的文字
### 现象
一条 run 头部写着 **`执行失败 · 历时 57:44`**,展开后最后一行是 `正在执行 · execute` ⟳。run 已经结束(失败)了,里面的步骤还写着「正在执行」——用户合理的读法是「它还在跑」,于是继续等。
### 根因(已在代码里核实)
`apps/web/components/chat/workbench/run-trace-panel.tsx`:
**图标那一半 #3316 已经修好了**(第 132 行)——`active` 为假时不转、`aria-label` 变成「未收到完成状态」:
```tsx
entry.status === "running"
?
```
**但同一行的文字没跟着修**(第 43 行)——只看 `entry.status`,根本拿不到 `active`:
```tsx
return `${entry.status === "failed" ? "执行失败"
: entry.status === "running" ? "正在执行"
: "已执行"} · ${toolLabel(entry.text)}`;
```
于是同一行里**图标和文字互相打脸**:无障碍标签说「未收到完成状态」,可见文字说「正在执行」。
`entry.status === "running"` 的真实含义是「有 `tool_start`、没等到配对的 `tool_end`」。run 还活着时那确实是「正在执行」;run 已经结束时,它的含义是**「这一步没有收到完成状态」**——两种情况共用一个词,是这个 bug 的全部内容。
### 判据
- run 处于 active ⇒ 文字仍是「正在执行」(不回归)。
- run 已结束而某步仍是 `running` ⇒ 文字**不许**是「正在执行」,应与图标的 `aria-label` 同义。
- 文案与图标 `aria-label` **取自同一处**,别再写两遍——这正是本仓「同一事实不得声明在两处」,而 #3316 只修了其中一处。
- 反证:撤掉修法,该用例必须红。
---
## ② 两次执行分别跑了 43:46 / 57:44 才判失败
### 现象
同一个任务里两条 run 先后失败:
```
执行失败 · 历时 43:46 · 工具 5 次 · 技能活动 22 项
执行失败 · 历时 57:44 · 工具 5 次 · 技能活动 22 项
```
用户在这两条上各等了 **43 分钟**和 **58 分钟**,最后拿到的是「执行失败」。
### 这和现有预算对不上
`apps/api/src/application/agent-run/poll-budget.ts`:
```ts
export const DEFAULT_RUN_POLL_INTERVAL_MS = 400;
export const DEFAULT_RUN_MAX_POLLS = 2250; // 2250 × 400ms = 900s = 15 分钟
```
文件头注还逐字写了这个数怎么来的:「一次模型调用(300s)+ 完整一轮沙箱重试循环(3×120s=360s)= 660s,再留安全余量到 900s」。**实测是这个预算的 3–4 倍。**
### 我没有断定根因,只列可能与判别方法
面板上的「历时」取自事实流(`run-trace-panel.tsx:90`:末条事件时间 − 首条事件时间),所以那两个数字是**事件真的横跨了这么久**,不是显示错。可能是:
1. 预算没作用到这条路径;
2. 预算**只管 SSE 桥**——桥超时写了 `AGENT_RUN_TIMEOUT`,底层 run 在后台继续跑、事件继续落库;
3. 单次工具调用(`execute`)自己没有上界,把总预算吃穿。
判别很直接:把这两条 run 的执行事件按时间排一遍,看 `RUN_ERROR` 写入时刻与最后一条事件时刻差多少。差很大 ⇒ 是 (2)。
### 为什么值得修
「失败」不可怕,**让用户等一小时才告诉他失败**才是。而且两条 run 形状完全一样(`工具 5 次 · 技能活动 22 项`),说明重试**把同一件事原样又做了一遍**——没有从上一次失败拿到任何东西,那一小时是纯浪费。
### 判据
- 一条 run 到判失败有**明确上界**,且界面上说得出来(用户知道最坏等多久)。
- 超时时用户看到**为什么**(卡在哪个工具/哪一步),不是一句「执行失败」。
- 若确认是 (2):桥超时后底层 run 必须被真的取消,不留后台幽灵。
---
## ③ run 头部那行的两个数字都不可解
### 问题 3a:「技能活动 N 项」不具区分度
三条 run 全是 **22**,其中两条失败、一条在跑。一个在任何情况下都给同一个数的指标,读不出任何东西。
原因(已核实):它数的是技能事实条目(`apps/web/lib/chat-workbench/run-trace.ts` 头注:「顶部的『技能活动 N 项』仍然数 `traceEntries` 的事实条目」),而这类条目绝大多数是**首轮的技能发现**——展开层第一行就是「已发现 21 个技能」。21 次发现 + 1 次读取正文 = 22。
也就是说这个数字实际是「这个组织有多少个技能」,跟这一轮 run **做了什么**几乎无关。#3218 已经把 20 行发现折叠成一行了(呈现层),但**顶部计数没跟着走**。
### 问题 3b:同屏两个「步」,指两种东西
| 屏上文案 | 实际数的是 | 出处 |
|---|---|---|
| `已完成 9 步` | **工具调用**(succeeded/failed 的 trace entry) | `run-trace-live-strip.tsx:35` |
| `3/4 步已标记完成` | **计划条目**(write_todos 账本的 steps) | `copilotkit-v2-plan-control.tsx:425` |
两者都对,但**都叫「步」**,数字还差一个量级(9 vs 3/4)。这不是「同一事实两处」(确实是两件事),是**两件事共用一个词**——症状一样:屏上自相矛盾。
### 判据
- 顶部计数换成对这一轮**有区分度**的量(例如排除发现类事实),或者干脆不显示——恒定的数字不如没有。
- 两个「步」各自改名到能自解释;改完同屏不出现两个含义不同的「步」。
- 反证:造一条「发现 21 个技能但只执行 1 次技能」的 run,新计数必须显著不同于旧计数。
- 不改事实层:分组/计数都是派生视图,不是第二份事实源(同 #3218)。
---
## ④ pdf-create 分页逻辑有缺陷
### 现象
agent 自己的渲染检查逐字写道:
> 渲染检查发现两个问题:第 1 页内容溢出导致文字重叠,第 2 页「闭环验证」标题下内容为空(被挤到下一页但分页逻辑有误)。需要修复分页逻辑,确保每个 section 有足够空间。
两个具体缺陷:
1. **溢出不换页 ⇒ 文字叠在一起**(第 1 页);
2. **换页点算错 ⇒ 标题留在上一页、内容被推到下一页**,「闭环验证」标题下面是空的(第 2 页)。第 2 条是排版里最典型的孤行/寡行问题。
### 为什么现在提
同一个任务里 agent **连续两轮**试图修这个分页逻辑,各跑 43:46 / 57:44,两轮都失败(即上面 ②),第三轮还在跑。说明这个缺陷**不是偶发**——agent 能稳定复现,而且落在**运行期让 agent 反复自救**的位置上。把它作为 skill 自身的缺陷修掉,比让每个用户的每一轮任务现场重修一遍便宜得多。
### 判据
- **不许重叠**:任何 section 正文渲染后不与相邻内容重叠(渲染后检查,不是只看布局代码)。
- **标题不与内容分离**:标题若放不下后面至少 N 行内容,整体推到下一页。
- **不许出现空 section**:不存在「有标题、下面什么都没有」的 section。
- 反证:造一份内容长度正好卡在分页边界的输入,撤掉修法必须能复现上面任意一条。
### ⚠ 需要补的取证
我手上只有 agent 自述 + 截图,**没有**那份 PDF、也没有触发它的输入。要修得先拿到:
- 触发这次生成的原始需求(截图里建议 chip 是「生成PESTEL 分析 / 生成价值主张宣言 / 生成AI 商业模型画布」,本轮具体输入未知);
- 产出的 PDF 或中间产物。
有这两样才谈得上「造一份卡边界的输入」。
---
## 建议的优先级
① 最小(一处文案 + 一个用例),且是用户**误判系统状态**的直接原因。
④ 用户可见的产出质量问题,但缺取证。
② 影响最大(一小时的等待),但要先做取证判别根因。
③ 纯呈现层,随手可做。
Contributor guide
No contributing guide indexed for this repository
Research direction
First split the report into four independently testable bugs. Read apps/web/components/chat/workbench/run-trace-panel.tsx, apps/api/src/application/agent-run/poll-budget.ts, apps/web/lib/chat-workbench/run-trace.ts, run-trace-live-strip.tsx, and copilotkit-v2-plan-control.tsx; trace the timeout path and locate the pdf-create entry point. Obtain the missing PDF and original input, then verify each stated acceptance criterion with existing or focused tests.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- typescript
- Domain
- backend, frontend, testing
- Issue type
- Bug
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 32/100