前言
Octo 是一个基于 Go 语言构建的终端 AI 聊天工具,采用 Bubbletea 框架实现 TUI(终端用户界面),支持对接多种 LLM API(如 DeepSeek)。在 v0.1.0 版本中,Octo 实现了基础的流式对话功能——用户在终端输入问题,AI 实时输出回答。
v0.1.1 带来了一次体验层面的全面升级:思考过程可视化、Markdown 渲染、终端 UI 现代化。本文将从业务角度梳理这些变更,帮助读者理解每个改动背后的用户价值。
变更全景图
graph TB
A[Thinking 推理能力] --> A1[配置层: 支持开启/关闭]
A --> A2[模型层: 透传 reasoning_effort]
A --> A3[UI层: 展示思考过程]
B[TUI 体验升级] --> B1[Markdown 渲染]
B --> B2[Catppuccin 主题配色]
B --> B3[Viewport 滚动]
B --> B4[快捷键系统]
B --> B5[思考状态指示器]
C[配置增强] --> C1[ThinkingConfig 结构体]
C --> C2[reasoning_effort 校验]
style A fill:#f9f,stroke:#333
style B fill:#9cf,stroke:#333
style C fill:#9f9,stroke:#333
一、核心特性:Thinking 推理能力
1.1 背景
DeepSeek 等模型支持「思考链」(Chain of Thought)功能——模型在给出最终回答前,会先输出一段内部推理过程。这个过程对用户理解 AI 的回答逻辑非常有价值,但 v0.1.0 完全没有利用这个能力。
1.2 配置层设计
新增 ThinkingConfig 结构体,支持三个维度的配置:
llm:
thinking:
enabled: true # 是否开启思考
reasoning_effort: low # 推理力度: low / medium / high
show: false # 是否在 UI 中展示思考过程
flowchart LR
A[读取 config.yaml] --> B{thinking.enabled?}
B -- No --> C[跳过校验]
B -- Yes --> D{reasoning_effort 为空?}
D -- Yes --> E[报错: 必填]
D -- No --> F{值在 low/medium/high 范围内?}
F -- Yes --> G[校验通过]
F -- No --> H[报错: 仅支持 low/medium/high]
设计亮点:
reasoning_effort是条件必填——仅当enabled: true时才强制要求,避免不必要的配置负担- 使用枚举值校验(
low/medium/high),从源头防止用户误配
1.3 模型层透传
在 LLM 模型初始化时,将 Thinking 配置透传给 OpenAI 兼容 API:
if llmConfig.Thinking.Enabled {
extMap["thinking"] = map[string]string{"type": "enabled"}
if llmConfig.Thinking.ReasoningEffort != "" {
extMap["reasoning_effort"] = llmConfig.Thinking.ReasoningEffort
}
}
这是 DeepSeek 等模型的扩展字段,通过 ExtraFields 注入到 API 请求中,不影响其他 LLM 提供商。
1.4 流式响应中的推理内容
v0.1.0 的流式响应只处理 Content(最终回答)。v0.1.1 新增对 ReasoningContent(思考过程)的处理:
sequenceDiagram
participant U as 用户
participant TUI as 终端 UI
participant API as LLM API
U->>TUI: 输入消息
TUI->>API: 发送请求(含 thinking 配置)
loop 流式传输
API-->>TUI: reasoning_content: 让我分析一下...
Note over TUI: 累积思考内容
API-->>TUI: reasoning_content: 根据上下文...
Note over TUI: 显示 spinner + 思考中...
API-->>TUI: content: 最终回答...
Note over TUI: 停止 spinner,渲染 Markdown
end
TUI-->>U: 展示完整回答(含可选思考过程)
关键变更:streamMsg 结构体新增 reasoningContent 字段,OctoModel 新增 reasoning(当前思考)和 reasoningHistory(历史思考)两个状态。
二、TUI 体验全面升级
2.1 Markdown 渲染
v0.1.0 中,AI 的回答以纯文本形式展示——即使模型返回了 Markdown 格式的内容(代码块、标题、列表等),用户也只能看到原始标记符号。
v0.1.1 引入 glamour 库,实现了终端内的 Markdown 实时渲染:
| 元素 | v0.1.0 | v0.1.1 |
|---|---|---|
标题 ## Hello | 原样输出 ## Hello | 带颜色的 ## Hello |
| 代码块 | 原样输出反引号 | 语法高亮 + 背景色 |
| 列表 | 原样输出 - | 圆点符号 • |
| 引用 | 原样输出 > | 竖线符号 │ |
| 链接 | 原样输出 URL | 带下划线的可点击样式 |
2.2 Catppuccin Mocha 主题
新增 tui/style.go,定义了一套完整的 Catppuccin Mocha 配色方案:
graph LR
A[Blue - 用户消息标签] --> B[Green - AI 回答标签]
B --> C[Overlay1 - 思考过程文字]
C --> D[Yellow - H1 标题]
D --> E[Lavender - H2/H3 标题]
E --> F[Red - 行内代码]
style A fill:#6C70F0,stroke:#333,color:#fff
style B fill:#A6E3A1,stroke:#333,color:#333
style C fill:#BAC2DE,stroke:#333,color:#333
style D fill:#F9E2AF,stroke:#333,color:#333
style E fill:#B4BEFE,stroke:#333,color:#333
style F fill:#F38BA8,stroke:#333,color:#fff
设计理念:选择 Catppuccin Mocha 是因为它是目前终端社区最受欢迎的配色方案之一,色彩柔和、对比度适中,长时间使用不易疲劳。
2.3 终端布局重构
这是本次变更中改动量最大的部分。v0.1.0 的布局是简单的线性拼接,v0.1.1 引入了组件化的布局系统:
graph TB
Header[Header: ASCII Logo + 模型信息 + Thinking 状态]
Viewport[Viewport: 聊天内容区域 - 可滚动, 最大 30 行]
Spinner[Spinner: 思考中...]
Input[Input: 用户输入框]
Footer[Footer: 上下翻页 Enter 发送 Ctrl+L 清空 Ctrl+C 退出]
Header --> Viewport
Viewport --> Spinner
Spinner --> Input
Input --> Footer
style Header fill:#b4befe,stroke:#333
style Viewport fill:#a6e3a1,stroke:#333
style Spinner fill:#f9e2af,stroke:#333
style Input fill:#89b4fa,stroke:#333
style Footer fill:#bac2de,stroke:#333
核心改进:
| 能力 | v0.1.0 | v0.1.1 |
|---|---|---|
| 布局方式 | 字符串拼接 | 组件化(viewport + input + help) |
| 内容滚动 | ❌ 不支持 | ✅ 支持鼠标滚轮 + 键盘翻页 |
| 窗口自适应 | ❌ 固定宽度 | ✅ 响应式布局 |
| 快捷键 | 仅 Ctrl+C | 完整快捷键系统 |
| 空状态提示 | 无 | 「输入消息开始对话」 |
2.4 快捷键系统
graph LR
A[上翻] --> B[下翻]
B --> C[PgUp/PgDn 翻页]
C --> D[Enter 发送消息]
D --> E[Ctrl+L 清空对话]
E --> F[Ctrl+C 退出]
style A fill:#89b4fa,stroke:#333,color:#fff
style B fill:#89b4fa,stroke:#333,color:#fff
style C fill:#89b4fa,stroke:#333,color:#fff
style D fill:#a6e3a1,stroke:#333,color:#333
style E fill:#f9e2af,stroke:#333,color:#333
style F fill:#f38ba8,stroke:#333,color:#fff
新增的 keyMap 结构体不仅定义了按键绑定,还通过 help.Model 在界面底部实时展示可用快捷键——用户无需记忆,界面即文档。
2.5 思考状态指示器
当 AI 正在思考(尚未产出最终回答)时,界面会显示一个动态的 spinner 动画:
🐵 思考中...
使用 spinner.Monkey 样式(猴子 emoji),配合 Catppuccin Green 配色,给用户明确的「系统正在工作」反馈。
三、用户体验对比
3.1 整体交互流程
flowchart TB
A1[输入消息] --> B1[看到光标闪烁]
B1 --> C1[文本逐字出现]
C1 --> D1[纯文本展示]
A2[输入消息] --> B2[spinner 思考中...]
B2 --> C2[思考过程逐渐展开]
C2 --> D2[Markdown 渲染的回答]
D2 --> E2[可滚动回顾历史]
style A1 fill:#ddd,stroke:#333
style B1 fill:#ddd,stroke:#333
style C1 fill:#ddd,stroke:#333
style D1 fill:#ddd,stroke:#333
style A2 fill:#a6e3a1,stroke:#333
style B2 fill:#a6e3a1,stroke:#333
style C2 fill:#a6e3a1,stroke:#333
style D2 fill:#a6e3a1,stroke:#333
style E2 fill:#a6e3a1,stroke:#333
3.2 视觉体验
v0.1.0:
██████╗ ██████╗ ████████╗ ██████╗
...
Model deepseek-v4-flash
You: 什么是 Go 语言?
Assistant: Go 是一种静态类型的编译型编程语言...
(Ctrl+C 退出)
v0.1.1:
██████╗ ██████╗ ████████╗ ██████╗ ← Catppuccin 渐变色
...
Model deepseek-v4-flash | Thinking: enabled (low)
┌─ 聊天区域 ─────────────────────────┐
│ You: 什么是 Go 语言? │
│ │
│ Assistant: │
│ ## Go 语言简介 │ ← Markdown 渲染
│ │
│ Go 是一种**静态类型**的编译型编程语言 │ ← 粗体高亮
│ │
│ • 编译速度快 │ ← 列表符号
│ • 并发支持优秀 │
│ • 内置垃圾回收 │
└─────────────────────────────────────┘
↑↓ 上翻 | Enter 发送 | Ctrl+L 清空 | Ctrl+C 退出 ← 快捷键提示
四、技术选型
本次变更引入的关键依赖:
| 库 | 用途 | 选择理由 |
|---|---|---|
glamour/v2 | 终端 Markdown 渲染 | Charm 生态官方库,与 Bubbletea 无缝集成 |
chroma/v2 | 代码语法高亮 | glamour 的底层依赖,支持 200+ 语言 |
viewport | 可滚动内容区域 | Bubbletea 标准组件,鼠标+键盘支持完善 |
spinner | 加载状态指示 | Bubbletea 标准组件,多种动画样式 |
help | 快捷键提示栏 | Bubbletea 标准组件,自动适配布局 |
所有新增依赖均来自 Charm 生态(charm.land),保持了技术栈的一致性。
五、总结
v0.1.1 的核心价值可以用一句话概括:让终端 AI 聊天从「能用」变成「好用」。
mindmap
root((Octo v0.1.1))
Thinking 推理
配置灵活
enabled / effort / show 三维度
渐进式展示
思考过程 → 最终回答
API 兼容
DeepSeek 扩展字段透传
TUI 体验
视觉
Catppuccin 配色
Markdown 渲染
交互
组件化布局
快捷键系统
响应式窗口
反馈
Spinner 思考指示器
空状态提示
工程质量
配置校验
样式与逻辑分离
依赖统一(Charm 生态)