---
summary: "维护一份持久的会话计划和状态卡"
title: "进度卡"
sidebarTitle: "进度卡"
read_when:
- "您希望代理发布当前会话的持久、一目了然的进度"
- "您需要 progress_card 输入、限制、渲染或清算合约"
---
`progress_card` 是会话的单一座席状态工具。它存储有序的步骤计划、紧凑的 Markdown 注释或两者。每次调用都会替换整张卡片,因此对于那些在不阅读文字记录的情况下关注工作的人来说,最新的写入是事实来源。
该卡属于用户正在与之交谈的父会话及其代理。生成的子代理永远不会收到 `progress_card` 或其提示提醒,包括可见的仪表板子代理和恢复的子代理。他们的结果返回给拥有进度更新的父级。该工具从正在运行的会话中绑定会话和代理;该模型仅提供`markdown`和`plan`。
该卡处于持久会话状态。重新连接或页面重新加载会从网关读取最新的卡片,而不是从工具事件或转录历史记录中重建它。成绩单仅保留简短的更新收据,而不是该卡的另一份完整副本。
## 采用
仅针对至少两个有意义的连续步骤的实质性工作创建一张卡片。跳过问候、快速提问和单步请求;不要发明步骤来证明一张卡的合理性。该清单仍然是可选的:符合条件的工作可以使用 Markdown、计划或两者。当进度发生有意义的变化时,现有的卡片仍然可以更新,或者根据要求清除。
当 Web、iOS、Android 或 macOS 卡渲染器与网关配对且运行未使用代理的实用模型时,OpenClaw 仅针对非主、非子代理会话添加简短的进度卡提醒。仅通道部署(例如 WhatsApp-only 网关)不会收到提醒。
提醒中写道:
> 使用 progress_card 创建卡片仅用于具有至少两个有意义的连续步骤的实质性工作,切勿用于问候、快速提问或单步请求。对于已知总数的可测量工作,最好使用领先的进度条,标有测量和观察到的 completed/total 计数;永远不要发明百分比。根据需要更新或清除现有卡。
该提醒不会覆盖工具策略。 `tools.updatePlan: false` 或匹配的 `tools.deny` 条目仍会从运行中完全删除 `progress_card`。
## 更新卡
两个输入字段都是可选的:
- `plan`:最多 50 个有序步骤。每个步骤都有非空 `step` 文本和 `pending`、`in_progress` 或 `completed` 的 `status`。最多一步可能是`in_progress`。
- `markdown`:关于发生的事情、被阻止的事情或接下来会发生什么的紧凑叙述。当一目了然的注释说明的内容比步骤列表更多时,请使用它;不要重复Markdown中的计划。
对于已知总数的批处理工作,更喜欢领先的进度条:
```json
{
"markdown": "\n\nTwo obsolete PRs closed. Verifying the next fix."
}
```
对于真正的顺序工作,清单可以显示当前阶段:
```json
{
"plan": [
{ "step": "Inspect the failing route", "status": "completed" },
{ "step": "Repair the session owner", "status": "in_progress" },
{ "step": "Run focused verification", "status": "pending" }
],
"markdown": "The failure is isolated to session ownership. No blocker."
}
```
每次调用都是替换,而不是补丁。省略 `markdown` 将删除之前的注释;省略 `plan` 将删除先前的清单。
当没有计划时,该工具会返回简短收据,例如 `Progress card updated (rev 4, 1/3 done)` 或 `Progress card updated (rev 4)`。其结构化结果包含修订和 completed/total 步数,或没有计划的 `null`。成功的写入还会更新完整计划状态的通道预览。失败或阻止的写入会保留之前的计划。活动通道预览保留安全故障通知。
## 活动运行结束之前
当运行仍欠可见回复时,如果该运行成功保存未完成的清单,然后生成正常的最终答案,则内置代理运行时最多执行一次完成自检。代理重新检查最新的用户指令:继续可行的、已授权的工作,协调已完成的步骤,或解释无法继续的具体原因。当其先前的答复已经解释了该原因时,检查会默默结束,并且该答复仍然是答案。这可能会添加一个模型响应;它不能保证模型完成每项任务。
检查将继续使用其现有记录、权限、时间限制和已完成的工具结果进行相同的活动运行。它不会重播之前的操作或重新启动原始请求。当工作继续进行时,聊天中已显示的检查点仍保留在对话中。真正的阻止者可以在检查后留下待处理的步骤。
旧卡不会重新启动闲置工作。已完成、已清除和仅注释的替换件不要求检查。取消、批准等待、接受的 child/media 完成移交、仅状态刷新和显式插件最终确定保留其现有行为。其他代理工具保留自己的最终确定策略。
## 暂停而不标记工作完成
如果由于明确暂停、需要批准或外部依赖性而无法继续授权步骤,请使用 Markdown-only 卡替换清单。让未完成的工作、阻碍者、负责人以及恢复情况保持可见。不要将阻止的步骤标记为已完成或暗示请求已完成。
```json
{
"markdown": "Update remains open and paused. Waiting for the source owner to publish the reviewed repair. No deployment is authorized; reconcile the new packet and current instructions before resuming."
}
```
省略 `plan` 会删除清单,而不是注释或任务的未解决工作。仅注释更换不要求完成自检。在以后的普通回合中重新保存未完成的检查表可以请求另一次检查,即使仍然存在相同的阻挡者。当授权工作可以继续进行时恢复清单;将任何其他未解决的依赖关系保留在注释中。
## 格式化注释
对于已知总数的合格多步骤工作,更喜欢使用观察到的 completed/total 计数的领先进度条:已审查的 PR、已完成的测试、已处理的文件或其他有意义的工作单元。优先选择这些计数而不是粗略的阶段计数,例如“3 个步骤中的 1 个”。准确标记计数测量的内容:经过审查的 PR 不是合并的 PR,完成的测试不一定是通过测试。切勿发明百分比或根据经过的时间推断完成情况。当总数未知时,请使用简洁的状态说明或表格。
跟随条形图,给出简短的结果、阻碍因素或下一步行动。仅当工作确实是连续的时才使用表格进行比较和清单。当表格、栏或句子表达得更好时,请省略清单,并且不要在计划和 Markdown 中重复相同的事实。在有意义的批次或状态更改后进行更新,使条形图及其标签在每次替换中保持最新状态。 Markdown 接受普通格式、链接和进度条:
```md
Tests are running.
| check | state |
| ---------- | ------- |
| unit tests | passed |
| live flow | running |
```
首先放置一个进度条,并为其指定一个简短的 `aria-label` 及其用途和 current/total 值。在会话悬停卡中,代理记事本将条固定在注释上方并显示该标签。其他原料HTML被Markdown消毒剂剥离。
## 限制
- Markdown:最多 8,192 UTF-8 字节。
- Plan:最多 50 个步骤。
- Step 文本:非空且每步最多 512 UTF-8 字节。
- 主动工作:最多一步`in_progress`。
网关在存储卡之前从 Markdown 和步骤文本中删除不可见的 Unicode 和双向控制字符。
## 清除卡片
调用 `progress_card` 两个部分都不存在或为空以删除当前卡:
```json
{}
```
空计划加上空或仅空白 Markdown 也会清除它。成功清除将返回 `Progress card cleared`。频道预览会删除清单及其状态,保留其他活动,并删除原本为空的草稿。稍后的卡片更新可以创建新的草稿。
在 Control UI、**关闭进度卡** (×) 中,仅在单击的聊天窗格中隐藏该卡,无论是展开还是折叠。任何可以查看该卡的人都可以将其隐藏,包括未完成的卡、暂停的卡、已完成的卡和仅笔记卡。
单击不会写入网关或更改已保存的卡、其他客户端、仪表板小部件、对话或活动运行。对同一张卡的更新会隐藏在该窗格中,包括在会话之间切换时。网关确认之前的卡已清除后,新创建的卡会再次出现。重新加载页面或更改网关连接可恢复保存的卡。
具有写入权限的用户可以在“详细信息”的任务进度选项菜单中选择“**清除每个人保存的进度”**,或者使用嵌入式编辑器中的垃圾箱操作。这会保留经过修订检查的共享清除:如果更新的卡修订版本到达,则会保留而不是删除。代理还可以使用 `progress_card` 工具清除保存的进度,并将两个字段清空。
完全就地对话重置(没有 `soft` 的 `/reset` 或 `sessions.reset`)也会清除上一个任务的卡。清除提交并重置边界并刷新订阅的客户端;新页面加载也看不到旧卡。在重置之前接受的写入无法恢复它。重置会保留成绩单历史记录和仪表板布局。保留先前上下文的自动连续性重置不会清除该卡。
## 卡片出现的地方
带有进度草稿的频道会在活动的 `partial`、`block` 和 `progress` 预览中显示最新的清单,具体取决于其预览设置和线路限制。带有步骤的卡片提供完成计数。没有步骤的注释提供具有 Markdown 格式的可读文本,并删除了创作的 HTML,但受现有标题限制的约束。没有可读文本的注释提供了 `Progress updated`。完整的 Markdown 保留在耐用卡中。 Telegram 使用带有 `channels.telegram.richMessages: true` 的本机复选框和可读的 HTML 清单。请参阅 [ 流式处理和分块 ](/concepts/streaming#progress-draft-rendering)。
在普通 Control UI 对话中,选择对话右上角的 **Details** 可查看当前任务进度卡。 **会话详细信息**和**任务进度**是独立的可折叠部分。详细信息开始关闭,仅根据要求开放。新消息、运行完成和进度更新永远不会自动打开它。拉取请求和进度不会在作曲家上方重复。
进度卡保留其对相同网关、会话和卡生命周期的公开选择。新创建的卡片使用现有的默认折叠首选项;其注释或清单的更新并不是一张新卡。详细信息放置使用显式披露控件,而不是作曲家的拖动调整大小和转录滚动折叠手势。
**设置→外观→聊天→显示任务进度卡**隐藏或显示聊天卡。它默认启用并仅存储在此浏览器中。扩展卡的**任务进度选项**菜单还提供**不再显示任务进度**,这会关闭相同的首选项并提供**撤消**。这不会停止代理工作、清除保存的进度或隐藏会话详细信息。隐藏卡片时,桌面上默认情况下单独的 **折叠任务进度** 首选项将被保留。该菜单还链接到进度设置,并将共享已保存卡片清除与本地隐藏分开。
仪表板小部件和会话悬停卡仍然是单独的只读位置。将鼠标悬停在边栏中的会话行或聊天中的会话参考链接即可查看该会话的同一张卡,即使聊天卡首选项已关闭。所有展示位置均读取相同的网关支持状态并在 `progressCard.changed` 通知后刷新。通知是刷新提示,包括空修订;客户端通过对该会话和代理的读取或明确响应来确认删除。
### 嵌入式作曲家布置
紧凑的嵌入式聊天和目录演示保留了现有的作曲家合同。以下手势行为适用于作曲家卡,而不适用于用户打开的“详细信息”表面。
在移动设备上,作曲家卡开始折叠,发送新消息不会打开它。在桌面上,新创建的卡将开始展开,除非在桌面上默认启用 **折叠任务进度**。安装卡或切换会话会显示其初始状态,而不会出现折叠动画。阅读较早的消息时,自动折叠需要至少两次向上滚动手势,总计至少 320 像素,然后 300 毫秒不滚动。间隔超过200毫秒的车轮爆裂单独计数;每次触摸拖动都算作一个手势,包括其惯性。只有转录消耗的向上移动才算在内;滚动工具输出内部、取消输入和编程位置调整则不会。返回底部会重置计数。
虽然扩展问题取代了作曲家,但任务进度卡也随之隐藏。回答、跳过或折叠问题可恢复卡片并保留其公开状态。展开问题时滚动文字记录不会折叠隐藏的卡片。
发送新消息、完成运行、返回底部和进度更新永远不会重新打开折叠的卡片。打开的卡片同样通过新消息和完成来保持其选定的打开状态。只有在网关确认之前的卡已清除后,新卡才会获得其初始桌面或移动默认值;更改注释或清单是更新,而不是创建。如果客户端无法确认清楚,它会保留之前的选择,而不是猜测新任务开始了。
系统会记住当前网关连接中每张卡的完全打开、关闭和部分高度选择,直到页面重新加载。切换网关连接从一个新的选择开始。手动关闭可防止自动重新打开。在访问或跑步期间第一次手动重新打开后,继续向上滚动可能会再次折叠卡片,但阈值更高:三个手势和 640 像素,然后是同样的 300 毫秒暂停。那次崩溃会记住关闭状态。第二次手动重新打开会停止该访问的自动折叠。离开和返回聊天会恢复基本阈值,同时保留卡片记住的打开状态。新消息和运行完成不会重置选择。
向上拖动作曲家卡的标题,或在指针位于其上方时向上滚动,以显示更多面板。向下移动将其关闭。完全关闭它会记住与单击标题相同的完全关闭选择,包括跨新消息。面板会跟随您移动的距离:停止时会保留部分开口,而反转则将其向后移动,而无需定时动画或释放捕捉。这也适用于标题上的触摸拖动。注释和清单保持正常的滚动和链接。
单击标题,或将其聚焦并按 Enter 或 Space,以打开或关闭整个卡片。部分开口在激活后完全展开;已经显示整个面板的开口在第一次激活时关闭,包括通过手势到达时。
部分打开是当前卡的像素高度选择:新输出、卡修订、新运行和最终响应不会完成或撤消它。离开和返回当前网关连接中的同一张卡将保留高度;清除它并创建一张新卡会丢弃它。其他会话和网关连接不会继承它。较小的视口将保留的高度限制在可用的面板空间内。
接管标题会清除待处理的转录折叠手势。翻开一张已关闭的牌算作一次手动重新打开,而不是每次移动一张;后续的真实转录手势仍遵循上述阈值。直接操作也会暂停转录跟踪;使用 **Latest** 或向后滚动至最新消息以继续。 **Latest** 不会更改所选卡的高度。
瞬时刷新失败会保留最后加载的卡。仪表板小部件会显示重试通知,直到刷新成功。如果网关报告连接不再参与会话,客户端将隐藏该卡,直到访问恢复且刷新成功。
详细信息、编辑器和仪表板位置显示上次进度更新的当地时间。相反,悬停卡显示当前或下一个计划步骤及其 completed/total 计数,当存在注释时,后面会在单独的代理记事本中显示 Markdown。
如果没有匹配的终端结果,当网关报告没有活动运行或卡早于稍后的运行时,未完成的步骤将显示为暂停。最后更新时间显示客服人员上次修改卡片的时间;仅经过时间并不会使属于活动运行的卡失效。
## 刷新当前工作状态
在 Control UI 编辑器中,选择卡时间戳旁边的 **刷新任务进度**,以要求代理将卡与其当前工作进行协调。当卡片折叠时,该操作仍然可用。它不发送可见的聊天消息。
当请求待处理时,上一张卡及其上次更新时间仍然可见。仅在网关返回更新的保存卡后才确认刷新。如果请求失败或耗时太长,请使用重试操作;超时不会取消正在运行的工作。
活动代理在其下一个支持的转向边界处接收请求,而不中断正在运行的工具或回答未决问题。如果转向不可用,请求将等待仅状态转向。空闲代理可以使用只读上下文工具和 `progress_card` 更新卡;刷新并不授权它恢复停止的工作或更改任务目标。控制请求和独立刷新输出对聊天保持隐藏,包括重新加载的历史记录。来自已处于活动状态的任务的正常回复仍然可见。
转向目标是当前会话自己的运行。如果父代理已让步而子代理继续工作,则刷新会在父会话中使用单独的仅状态轮次。
该操作使用会话的现有写入权限。仪表板和悬浮卡放置保持只读。
## 网关请求
`progressCard.get`、`progressCard.put` 和 `progressCard.refresh` 接受必需的 `sessionKey` 和可选的 `agentId`。明确选择代理时传递两者,例如 `{ "sessionKey": "global", "agentId": "research" }`。省略 `agentId` 将保留网关现有的会话所有者解析。未知代理或与会话所有者冲突的代理将被拒绝。
将原始会话和代理放在一起以供后续读取和清除。退卡和更改事件使用代理合格的显示密钥;仅该密钥无法区分保留的 `global` 会话和密钥为 `agent::global` 的普通会话。除了操作员读取或写入范围之外,所有三种方法都使用所选会话的正常访问检查。
`progressCard.refresh` 还需要一张 `idempotencyKey` 和一张现有卡。它不接受提示文本。其 `{ runId, status: "accepted", revision }` 响应确认请求并标识基线修订;这并不意味着该卡已更新。客户端通过现有的变更事件和读取路径确认更新的卡。
使用相同的 `idempotencyKey` 重试保留原始修订基线并将已完成的工作与最新保存的卡进行比较。
Control UI 随其网关一起提供,并跟随捕获的会话所有者而无需版本协商:普通代理限定密钥省略冗余的 `agentId`,而原始目标保留其显式所有者。网关还在 `hello.features.capabilities` 中为独立升级的客户端(例如本机应用程序)通告 `progress-card-agent-scope-v1`。这些客户端在发送 `agentId` 之前检查功能:普通代理限定密钥可以省略该字段,而具有显式所有者的 `global` 目标则需要该字段。如果缺少该功能,独立升级的客户端会报告需要网关更新。
## 将卡固定到仪表板上
使用 `dashboard` 工具将实时卡保留在当前会话的仪表板上:
```json
{
"action": "widget_put",
"name": "session-progress",
"title": "Session progress",
"pluginKind": "session:progress",
"size": "md"
}
```
省略 `props.sessionKey` 以跟踪仪表板的会话。要显示另一个会话的卡片,请添加 `"props": { "sessionKey": "agent:main:release" }`。当前连接必须参与该会话;否则选择一个可访问的会话或更改其共享。
## 相关内容
- [工具概览](/tools)
- [`openclaw dashboard`](/cli/dashboard) — 从 CLI 打开 Control UI
- [Control UI URLs](/web/urls) — 在浏览器中到达 Control UI