第二章:Octo v0.1.1:从「能用」到「好用」——终端 AI 聊天体验的全面升级

17 阅读4分钟

前言

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.0v0.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.0v0.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 生态)

项目源码:github.com/aethelgards…