---
url: /v6.2/cli-autopilot.md
---
# CLI 实时回显与 Autopilot

当你用 HENGSHI CLI、Agent 或脚本在浏览器外修改资源时，最常见的问题不是“命令有没有执行成功”，而是：

**这次变化什么时候会回到当前页面？**

Autopilot 就是这条“CLI / Agent 改动 → UI 回显”链路在前端的可视化状态提示。本页重点解释三件事：

1. Autopilot 能帮你判断什么
2. 哪些场景适合期待实时回显
3. 哪些场景其实仍然以同步执行或轮询为主

## 为什么 CLI 文档要单独讲 Autopilot

HENGSHI CLI 是浏览器外的统一命令入口；Autopilot 是浏览器内的实时连接提示。两者配合起来，才构成一条完整的交付闭环：

```text
CLI / Agent / Script
→ 服务端接受变更
→ SSE 推送相关资源更新
→ 当前页面收到回显
→ Autopilot 提示你连接是否仍然在线
```

所以，Autopilot 的价值不只是“页面上多了一个状态条”，而是帮你更快回答下面这些问题：

* 当前页面是不是还在接收实时更新
* 浏览器外刚发生的变更，是否有机会回到当前页面
* 当页面没有变化时，更像是连接问题、范围问题，还是页面本地状态本来就不适合被覆盖

## Autopilot 是什么，不是什么

### 它是什么

Autopilot 指示器是页面顶部的一段实时连接状态提示，用来告诉你当前页面是否仍在接收系统里的实时更新。

技术上，这条能力基于 SSE（Server-Sent Events）实现；但日常使用里，你通常只需要关注页面上的连接状态即可。

### 它不是什么

Autopilot 很有用，但它**不等于**下面这些东西：

* **不是“所有页面都会自动刷新”**
* **不是“所有后台动作都会立刻回到当前页面”**
* **不是“执行状态本身”**，它只表示实时连接是否在线，不替代任务状态、执行记录或日志
* **不是“强制覆盖本地编辑”**，当前页面有未保存修改时，外部更新不一定会直接合并进来

## SSE 系统开关与 Autopilot 显示

管理员可以在系统环境里通过 `GENERAL_CONFIG_ENABLE_SSE` 控制实例是否启用 SSE 实时推送；默认值是开启。这个系统环境值在前端系统偏好接口中会体现为 `enableSse` 字段。

这项开关会直接影响前端是否建立 SSE 长连接，以及 Autopilot UI 是否显示：

* **开启时**：支持的桌面页面会建立 `/api/sse/subscribe` 实时连接，并按页面边界显示 Autopilot 指示器
* **关闭时**：前端不会启动 SSE transport，Autopilot 指示器不会显示，也不应再期待基于这条链路的实时回显

当前公开文档里提到的 Autopilot 与实时回显范围，**都默认建立在 `GENERAL_CONFIG_ENABLE_SSE` 仍处于开启状态** 的前提上。

这项开关控制的是 **SSE / Autopilot 实时回显链路**，不等于 ChatBI / Agent 能力本身是否可用，也不代表所有页面都会自动刷新。

## 哪些场景最适合期待实时回显

在公开产品文档里，最值得优先强调的对象其实是**仪表盘 / 报表页面**，尤其是查看页和编辑页。

因为对大多数 CLI + Agent 交付场景来说，用户真正关心的通常不是“某个列表有没有刷新”，而是下面这些变化能不能及时回到当前画面：

* CLI / Agent 新建或更新了 dashboard / report
* 在浏览器外创建或更新了图表、筛选器、文本、按钮、图片、容器等元素
* 应用了 dashboard plan，想确认改动有没有回到当前画布

资源列表页、Notebook / Pipeline 这类 detail 页同样属于这条机制的覆盖范围，但它们更适合作为补充场景理解；Autopilot 在交付与验收阶段最有感知价值的，仍然是仪表盘 / 报表页面。

| 场景 | 更适合期待什么 | 典型例子 |
| --- | --- | --- |
| 仪表盘 / 报表查看页、编辑页 | 浏览器外的创建或更新结果回到当前画布或当前页面 | dashboard plan apply、chart/filter/text/container 变更、report 页面更新 |
| 列表页 | 浏览器外 create / delete / update 回到当前列表 | 应用、数据科学、数据集成等列表页 |
| 其他 detail 页 | 当前资源内部结构变化回到当前 detail 页 | Notebook 段落变更、Pipeline 节点增删改 |

更准确地说，Autopilot 最擅长帮助你验证的是：

1. 当前打开的**仪表盘 / 报表页面**，是否正好就是这次外部变更的目标页面
2. 当前页面和浏览器外变更，是不是针对同一个资源
3. 当前页面是不是属于已经接入实时回显的页面
4. 当前连接是不是仍然可用

## 当前页面支持边界

下面这张表把两件事情拆开来看：

* **Autopilot 指示器会不会出现**
* **当前页面有没有明确接入资源级回显**

这两件事并不总是等价。页面上看得到指示器，不代表当前页面就一定已经接上了这类资源的实时刷新。

另外，这张表默认假设系统环境里的 `GENERAL_CONFIG_ENABLE_SSE` 没有被关闭；如果实例级 SSE 已禁用，那么下面这些页面也不会再显示 Autopilot 指示器。

| 页面类型 | Autopilot 指示器 | 当前已明确接入的回显 | 说明 |
| --- | --- | --- | --- |
| 桌面常规页面（主头部显示） | 支持 | 取决于页面自身是否接入实时回显 | 常见例子包括应用 / 文件夹列表、数据集列表、仪表盘列表、数据科学列表、数据集成列表等 |
| 仪表盘 / 报表查看页、编辑页（自有头部） | 支持 | 支持仪表盘资源级回显 | 这是当前最核心的交付场景；发布态、分享态、预览态和嵌入容器不在这层边界内 |
| 数据科学 Notebook 详情页 | 依赖页面主头部 | 支持 notebook 资源级回显 | 本地 paragraph 有未保存修改时，外部变化会先排队，不直接覆盖 |
| 数据集成 Pipeline 详情页 | 依赖页面主头部 | 支持 pipeline 资源级回显 | 节点增删改已接入；本地图编辑未保存时，外部变化会先排队 |
| Kanban 顶层页面 | 不属于当前这批独立顶栏提示页面 | 支持 kanban 资源级回显 | draft / analysis / share / ChatBI / screenshot 等派生形态不在当前订阅边界内 |
| 执行记录 / DAG / 日志类页面 | 可能看到指示器 | 不建议按 SSE-first 理解 | 这类页面当前更常见的是同步等待或轮询 |
| 移动端 / 浮层页面 | 不保证支持 | 不应默认期待 | 移动端不显示指示器；Kanban、业务指标、ChatBI 等浮层页面不在当前独立顶栏提示范围内 |

如果把范围再说得更具体一点，**截至当前版本**，可以明确写进这张表的页面至少包括：

* 应用 / 文件夹列表（含 `app`、`public`、`datamart` 的根列表与 folder 路径）
* 数据集列表
* 仪表盘 / page / report 列表
* 数据科学列表
* 数据科学 Notebook 详情页
* 数据集成列表
* 数据集成 Pipeline 详情页
* 仪表盘 / 报表查看页、编辑页

这张表的重点不是承诺“所有这些页面都会自动刷新一切”，而是帮助你先判断：**当前页面到底在不在 Autopilot 与实时回显的已知边界里。**

## 哪些场景不该把它当成主通道

下面这些场景，即使页面上有 Autopilot，也不应该把“有没有 SSE 推送”当成第一判断标准。

### 1. 执行类动作

以数据集成为例，详情页里的“立即执行”更接近**同步执行路径**：前端发起执行后，会等待后端返回当前这次执行的状态，而不是只打一枪再完全依赖 SSE 推送。

这意味着：

* 执行按钮能否返回结果，优先看执行本身是否成功
* 不应该把“没有立刻看到实时推送”直接判断成执行失败

### 2. 执行记录 / DAG / 日志类页面

这一类页面当前更常见的是**轮询刷新**，而不是把 Autopilot 当成主刷新机制。

例如：

* 执行记录页
* DAG 页
* 部分日志 / 历史记录页

这类页面即使能看到状态变化，也更可能来自同步等待或轮询，而不是当前资源详情页那种直接的实时回显。

### 3. 本地存在未保存编辑的页面

如果当前页面已经有未保存的本地修改，外部更新通常不会被粗暴覆盖。

这是一个保护机制，不是实时回显失效。对这类页面，更应该先区分：

* 页面是不是故意阻止外部变化覆盖本地草稿
* 还是当前连接本身已经断开

## 常见状态

Autopilot 常见状态包括：

| 状态 | 含义 |
| --- | --- |
| `Autopilot 连接中` | 正在建立实时连接 |
| `Autopilot 已连接` | 当前页面可接收实时更新 |
| `Autopilot 重连中` | 连接中断后正在尝试恢复 |
| `Autopilot 已断开` | 当前没有可用连接，需要人工关注 |

当指示器处于断开状态时，页面通常会提供重试入口。

## 推荐的验证顺序

当你在验证“CLI / Agent 改动是否已经回到 UI”时，建议按这个顺序判断：

1. **先看命令本身是否真的成功**
   * 优先看 CLI 返回值、结构化输出和报错
   * 不要一上来只盯浏览器
2. **再看当前页面是不是同一个资源**
   * 当前列表或 detail 页是否正好覆盖这次改动的资源
3. **再看 Autopilot 是否已连接**
   * 如果连接本身已断开，页面落后是合理现象
4. **区分这次动作属于“资源变更”还是“执行过程”**
   * 资源变更更适合期待实时回显
   * 执行过程、执行记录、DAG 更常见的是同步等待或轮询
5. **最后才判断是连接问题、范围问题，还是本地草稿保护**

这样排障会比“命令一成功就立刻怀疑 UI 异常”更快。

## 环境与代理要求

如果你的实例前面有 Nginx、Ingress、TongWeb 或其他反向代理，`/api/sse/subscribe` 这条链路需要额外关注。最常见的问题不是业务逻辑错误，而是**长连接被代理提前切断，或被缓冲后失去实时性**。

至少需要保证：

* SSE 路径允许长时间保持连接
* 关闭代理层的 response buffering / proxy buffering
* 不要缓存 SSE 响应
* 读写超时不要太短

如果是多节点集群，或实例前面还有 Nginx 负载均衡，建议单独为 SSE 路径配置完整的 `location`。当 Autopilot 一直停在“连接中”时，优先检查这里是否仍然有压缩、缓冲、缓存或过短超时。

推荐的 Nginx 反向代理配置可以参考：

```nginx
location /api/sse/subscribe {
  gzip off;
  proxy_buffering off;
  proxy_cache off;

  proxy_connect_timeout 300s;
  proxy_read_timeout 300s;
  proxy_send_timeout 300s;

  add_header X-Accel-Buffering no always;
  add_header Cache-Control no-cache always;
  add_header Pragma no-cache always;

  proxy_pass http://<chatbi_upstream>/api/sse/subscribe;
  proxy_http_version 1.1;
  proxy_set_header Connection "";
  proxy_set_header Host $host;
  proxy_set_header X-Real-IP $remote_addr;
  proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
  proxy_set_header X-Forwarded-Proto $scheme;
  proxy_redirect default;
}
```

这里的 `<chatbi_upstream>` 需要替换为实际的 ChatBI / HENGSHI 服务 upstream。超时时间不建议低于 300 秒；如果网络设备或网关策略更容易中断空闲连接，可以按现场策略继续放大。

SSE 不是 WebSocket，不要求额外设置 `Upgrade`。如果现场 Nginx 模板里已经统一带有 `proxy_set_header Upgrade $http_upgrade;`，通常可以保留；但 `Connection` 不要被强制设置为 `close` 或 `upgrade`，建议按上面的示例置空。

如果你使用的是 ingress-nginx、TongWeb 或其他网关，也需要配置**等价能力**：长连接、关闭缓冲、放宽超时。

下面这些现象通常都值得优先检查代理层：

* Autopilot 一直停在“重连中”或频繁断开
* CLI 明明成功了，但页面始终收不到任何实时变化
* 同一页面在直连环境正常，走网关后失去实时回显

## 页面示意

下面是本地示例环境里“应用集市”页面顶栏上的 Autopilot 指示器：

![Autopilot indicator](/images/cli/cli-autopilot-indicator.png)

## 一句话记忆

可以把这页内容压缩成一句话：

> **Autopilot 负责告诉你“实时连接还在不在”，不是替你判断“所有页面都会自动刷新”。**

如果你想继续排查“为什么看不到实时变化”，请直接看 [排障与 FAQ](cli-faq.md)。
