前言
Octo 是一个基于 Go 语言构建的终端 AI 聊天工具,采用 Bubbletea 框架实现 TUI(终端用户界面),支持对接多种 LLM API(如 DeepSeek)。在 v0.1.0 版本中,Octo 实现了基础的流式对话功能------用户在终端输入问题,AI 实时输出回答。
v0.1.1 带来了一次体验层面的全面升级:思考过程可视化 、Markdown 渲染 、终端 UI 现代化。本文将从业务角度梳理这些变更,帮助读者理解每个改动背后的用户价值。
变更全景图
一、核心特性:Thinking 推理能力
1.1 背景
DeepSeek 等模型支持「思考链」(Chain of Thought)功能------模型在给出最终回答前,会先输出一段内部推理过程。这个过程对用户理解 AI 的回答逻辑非常有价值,但 v0.1.0 完全没有利用这个能力。
1.2 配置层设计
新增 ThinkingConfig 结构体,支持三个维度的配置:
yaml
llm:
thinking:
enabled: true # 是否开启思考
reasoning_effort: low # 推理力度: low / medium / high
show: false # 是否在 UI 中展示思考过程
设计亮点:
reasoning_effort是条件必填 ------仅当enabled: true时才强制要求,避免不必要的配置负担- 使用枚举值校验(
low/medium/high),从源头防止用户误配
1.3 模型层透传
在 LLM 模型初始化时,将 Thinking 配置透传给 OpenAI 兼容 API:
go
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(思考过程)的处理:
关键变更 :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 配色方案:
设计理念:选择 Catppuccin Mocha 是因为它是目前终端社区最受欢迎的配色方案之一,色彩柔和、对比度适中,长时间使用不易疲劳。
2.3 终端布局重构
这是本次变更中改动量最大的部分。v0.1.0 的布局是简单的线性拼接,v0.1.1 引入了组件化的布局系统:
核心改进:
| 能力 | v0.1.0 | v0.1.1 |
|---|---|---|
| 布局方式 | 字符串拼接 | 组件化(viewport + input + help) |
| 内容滚动 | ❌ 不支持 | ✅ 支持鼠标滚轮 + 键盘翻页 |
| 窗口自适应 | ❌ 固定宽度 | ✅ 响应式布局 |
| 快捷键 | 仅 Ctrl+C | 完整快捷键系统 |
| 空状态提示 | 无 | 「输入消息开始对话」 |
2.4 快捷键系统
新增的 keyMap 结构体不仅定义了按键绑定,还通过 help.Model 在界面底部实时展示可用快捷键------用户无需记忆,界面即文档。
2.5 思考状态指示器
当 AI 正在思考(尚未产出最终回答)时,界面会显示一个动态的 spinner 动画:
bash
🐵 思考中...
使用 spinner.Monkey 样式(猴子 emoji),配合 Catppuccin Green 配色,给用户明确的「系统正在工作」反馈。
三、用户体验对比
3.1 整体交互流程
3.2 视觉体验
v0.1.0:
bash
██████╗ ██████╗ ████████╗ ██████╗
...
Model deepseek-v4-flash
You: 什么是 Go 语言?
Assistant: Go 是一种静态类型的编译型编程语言...
(Ctrl+C 退出)
v0.1.1:
bash
██████╗ ██████╗ ████████╗ ██████╗ ← 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 聊天从「能用」变成「好用」。