---
title: "03 · 终端 TUI 工作流"
description: "理解 OpenCode 的 TUI：文件引用、shell 命令、斜杠命令、Plan/Build 双模式、会话、压缩与 attach。"
verifiedAt: "2026-05-09"
---

OpenCode 的主战场是终端 TUI（terminal UI，文本界面）。TUI 不是把网页聊天框搬进终端，而是让 agent 站在你的项目目录里，能读文件、跑命令、看输出、继续会话、撤销改动。

这一篇不背快捷键清单，而是讲日常工作流：什么时候用 `@` 给上下文，什么时候用 `!` 跑命令，什么时候用 `/` 控制会话，什么时候按 **Tab** 切 Plan / Build 模式，什么时候压缩上下文，什么时候 attach 到 server。

> [!NOTE]
> **这一篇解决什么问题**：把 TUI 理解成“任务控制台”。读完你应该能在一个真实项目里完成：限定文件阅读、运行测试、查看工具详情、压缩长会话、撤销误操作，并知道哪些命令不能随便交给 agent。

## 1. TUI 不是聊天框，是控制台

你在 TUI 里做的不是“问一句，等一句”。更准确的动作链是：

```mermaid
flowchart LR
    Ask["描述任务"] --> Context["指定上下文"]
    Context --> Act["允许读文件 / 跑命令 / 改文件"]
    Act --> Inspect["看工具详情和 diff"]
    Inspect --> Decide["继续 / 修正 / 撤销 / 压缩"]

    style Context fill:#dbeafe,stroke:#3b82f6
    style Inspect fill:#fef3c7,stroke:#f59e0b
    style Decide fill:#fee2e2,stroke:#ef4444
```

这个链条里最重要的是两个控制点：

- 你要主动给上下文，不要让模型在大项目里乱猜。
- 你要主动看工具执行结果，不要只看最终回复。

> [!IMPORTANT]
> **TUI 的核心能力是可观察**：你能看到它读了什么、跑了什么、改了什么。第一次上手时，先把 `/details` 打开，习惯看工具细节。

## 2. 用 `@` 明确上下文

OpenCode 支持在消息中用 `@` 引用文件。官方文档说明，`@` 会在当前工作目录里做 fuzzy file search，并把文件内容加入对话。

```text
解释 @src/server.ts 的启动流程，并指出配置从哪里读取。
```

不要把上下文管理完全交给模型猜。尤其是 monorepo、大型前端项目、后端服务和多语言项目，显式引用文件会大幅降低跑偏。

更稳的写法是把“文件、目标、动作顺序”一起写清楚：

```text
只阅读 @src/auth.ts 和 @src/routes/login.ts。
判断登录失败时错误是在哪里被吞掉的。
先解释，不要修改。
```

这条提示词同时做了三层限制：

| 限制 | 作用 |
| --- | --- |
| 只阅读两个文件 | 降低无关上下文 |
| 判断一个具体问题 | 防止泛泛解释代码 |
| 先解释，不要修改 | 保持第一轮只读 |

## 3. 用 `!` 把命令输出带回对话

在 TUI 里，消息以 `!` 开头可以运行 shell 命令。命令输出会作为工具结果进入上下文。

```bash
!git status --short
!pnpm test
!pnpm run lint
```

这让 agent 不只是“猜测测试是否通过”，而是能看到真实输出再继续判断。

适合用 `!` 的命令：

- `git status`、`git diff`、`git log` 这类只读 Git 命令。
- 测试、类型检查、lint、format check。
- 项目自带诊断脚本。
- 查看目录和配置的只读命令。

不适合直接交给 agent 自由运行的命令：

| 命令类型 | 风险 |
| --- | --- |
| `rm -rf`、删除目录 | 数据不可恢复 |
| `git reset --hard`、强制 checkout | 可能回滚用户改动 |
| 全仓库格式化 | 淹没真实 diff |
| 修改全局配置 | 影响当前项目外的环境 |
| deploy / publish / push | 进入发布边界 |
| 生产数据库写操作 | 可能造成真实损失 |

> [!WARNING]
> **新手坑**：不要用“帮我排障，随便跑你需要的命令”。更好的写法是“先列出你准备运行的命令和原因，我确认后再跑会修改环境的命令”。

## 4. 用 `/` 控制会话和系统动作

斜杠命令是 TUI 的控制面。常用命令不需要全背，先按用途分组记：

- **连接和初始化**：`/connect` 添加 provider 和 API key，`/init` 创建或更新 `AGENTS.md`。
- **模型和观察**：`/models` 查看可用模型，`/details` 开关工具执行详情，`/thinking` 切换是否显示模型推理过程。
- **上下文和会话**：`/compact`（别名 `/summarize`）压缩当前会话，`/sessions`（别名 `/resume` `/continue`）查看和切换会话，`/new`（别名 `/clear`）开新会话。
- **变更控制**：`/undo` / `/redo` 撤销或重做上一轮消息和文件改动。
- **分享**：`/share` / `/unshare` 分享或取消分享会话。
- **导出和退出**：`/export` 把当前对话导出为 Markdown 并打开 `EDITOR`，`/exit`（别名 `/quit` `/q`）退出 OpenCode。
- **输入、外观和帮助**：`/editor` 调外部编辑器写长消息，`/themes` 切换主题，`/help` 查看可用命令。

多数命令还有以 `ctrl+x` 为 leader 的快捷键（如 `/compact` 是 `ctrl+x c`、`/undo` 是 `ctrl+x u`、`/new` 是 `ctrl+x n`），完整映射看 [Keybinds 官方页](https://opencode.ai/docs/keybinds)；`/editor` 和 `/export` 调用的编辑器由系统环境变量 `EDITOR` 决定（如 `export EDITOR="code --wait"`）。

三条实用建议：

1. 第一次调试任务，先开 `/details`，把工具调用细节看明白再继续。
2. 长提示词用 `/editor`，不要在终端里写到一半丢失。
3. 涉及源码和内部信息，默认不要 `/share`——分享出去的链接公开可访问，详见 08 安全篇。

## 5. 用 **Tab** 切换 Plan / Build 双模式

OpenCode 与同类终端 AI 编程工具最直观的差异之一，是 **Plan mode 和 Build mode 双模式**。在 TUI 任意位置按 **Tab** 键就能切换，TUI 右下角会显示当前模式。

| 模式 | 模型行为 | 何时用 |
| --- | --- | --- |
| **Plan mode** | 只输出"准备怎么做"，不调用 edit / write 工具改文件 | 第一次面对陌生任务、要先看方案的复杂改动、跨多文件重构 |
| **Build mode** | 默认模式，可以读、改、跑命令 | 已看过计划、改动范围明确的小步任务 |

推荐工作流：

```text
按 Tab 进 Plan
  ↓ 描述任务，让它先列出"我准备改哪些文件、为什么"
看完计划，必要时反馈或补条件
  ↓ 等它输出最终计划
按 Tab 切回 Build
  ↓ 让它按计划改
```

这条路径与第 1 节"TUI 不是聊天框，是控制台"互为表里——Plan mode 把"先看方案"做成一个键，让"先看再改"成为日常习惯，而不是每次都靠提示词约束。

> [!TIP]
> Plan mode 不是只读模式。它仍然能读文件、跑只读命令（如 `git status`），所以适合让模型边看真实代码边写计划，而不是闭眼空想。

## 6. `/undo` 不是魔法，要依赖 Git

官方 TUI 文档说明，`/undo` 会撤销上一条用户消息、后续响应以及文件改动；文件改动的撤销内部依赖 Git，所以项目需要是 Git 仓库。

这件事很重要。OpenCode 的安全基线不是“反正能 undo”，而是：

```text
真实项目必须先有 Git 状态
  ↓
每轮任务前看 git status
  ↓
每轮任务后看 diff
  ↓
不满意再 undo 或手动回滚
```

第一轮写任务前，先让它跑：

```bash
!git status --short
```

如果工作区本来就是脏的，不要让 agent 直接大改。先让它只读解释现状，明确哪些改动是用户已有改动，哪些是本轮可动范围。

## 7. 长任务前先准备压缩快照

长任务会遇到上下文膨胀。OpenCode 提供 `/compact`，也有 `/summarize` 别名，用于压缩当前 session。

压缩不是“自动安全”。压缩前最好让 agent 写一份状态快照：

```text
在压缩前，先按这 5 点总结当前状态：
1. 已经读过哪些关键文件。
2. 已经修改哪些文件，每个文件改了什么。
3. 哪些用户已有改动不能碰。
4. 仍未解决的问题是什么。
5. 下一步必须先运行哪些检查命令。
```

这样压缩后继续任务时，关键约束不容易丢。

> [!TIP]
> **通俗讲**：压缩像把桌上资料收进文件夹。收之前先贴标签，否则下次打开还是乱。

## 8. 什么时候用 `opencode run`

TUI 适合交互式工作；`opencode run` 适合短任务和自动化。

```bash
opencode run "Explain the use of context in Go"
```

`run` 支持指定模型、agent、文件、输出格式、session、attach 等参数。它适合：

- 批量解释文件。
- 生成简单报告。
- 在脚本里做只读检查。
- 连接已有 server 减少冷启动。

但第一次修 bug、重构、排障时，不建议一上来用 `run`。你需要看它读了什么、跑了什么、改了什么，TUI 更合适。

## 9. attach 与 server 的边界

OpenCode 可以把 TUI attach 到已经运行的 backend server。官方 CLI 文档给出的典型例子是先启动 web/server，再用 TUI 连接：

```bash
opencode web --port 4096 --hostname 0.0.0.0
opencode attach http://10.20.30.40:4096
```

这对远程机器、局域网访问或 Web 界面很有用。但只要绑定到 `0.0.0.0` 或让局域网能访问，就不能当普通网页服务处理。

最低要求：

- 设置 `OPENCODE_SERVER_PASSWORD` 或对应 basic auth。
- 不暴露到公网。
- 不在包含真实密钥或客户数据的项目里随便开。
- 结束后确认服务已关闭。

> [!IMPORTANT]
> **coding agent server = 项目读写入口**。它不是一个普通文档站，也不是临时预览页面。

## 10. 一条推荐 TUI 任务模板

把下面这段作为日常任务起手式：

```text
你先只读分析，不要修改文件。
目标：{写清楚问题}
优先阅读：@{关键文件1} @{关键文件2}
请先输出：
1. 你理解的问题边界。
2. 你还需要看的文件或命令。
3. 你准备怎么验证。
等我确认后，再进入修改。
```

这个模板把 OpenCode 从“自由发挥”拉回“受控协作”。等任务稳定后，再把它沉淀成 command。

## 11. 本章自检

- `@` 文件引用解决什么问题？为什么在 monorepo / 大项目里特别关键？
- 哪些命令适合用 `!` 直接跑，哪些必须先让模型列计划再确认？
- Plan mode 和 Build mode 的边界在哪？什么任务先按 Tab 进 Plan？
- 为什么 `/undo` 不能替代每轮前后的 `git status` 和 diff 检查？
- attach 到远程 server 时，最少要满足哪几条安全条件？

> [!TIP]
> **过关标准**：你能用 TUI 完成一次“按 Tab 进 Plan → 明确上下文 → 看完计划 → 切回 Build → 限定修改 → 看工具详情 → 检查 diff → 必要时 `/undo`”的完整闭环。

## 接下来去哪

<Cards>
  <Card title="使用 TUI" description="回到官方 TUI 页，查看 `@`、`!`、`/`、`/undo`、`/editor` 和 `tui.json` 的细节。" href="/docs/opencode/official/00-getting-started/tui" />
  <Card title="使用 CLI" description="继续理解 TUI、run、serve、web、attach 和 auth/models 的边界。" href="/docs/opencode/official/00-getting-started/cli" />
  <Card title="配置、Rules 与命令" description="当同一类提示词说了三次，就该沉淀进 rules 或 command。" href="/docs/opencode/understanding/04-config-rules-commands" />
  <Card title="分享会话" description="如果要把 TUI 会话发给别人，先理解公开链接和敏感信息边界。" href="/docs/opencode/official/00-getting-started/share" />
</Cards>

## 官方资料

- OpenCode TUI：[https://opencode.ai/docs/tui](https://opencode.ai/docs/tui)
- OpenCode CLI：[https://opencode.ai/docs/cli](https://opencode.ai/docs/cli)
- OpenCode Share：[https://opencode.ai/docs/share](https://opencode.ai/docs/share)
- OpenCode Server：[https://opencode.ai/docs/server](https://opencode.ai/docs/server)
