前言
在 9 月 26 日的 v2.0.7 版本中,XiaoMate 完成了 Live2D 与 3D 模型同台运行的核心能力。这个国庆节放假了,我把重心转向了另一个同样重要的方向:聊天交互体验,同时,Live2D点击触控动作也优化了一下,支持点击不同身体部位播放不同的动作和声音(需要Live2D模型的支持),另外,也准备开始支持Windows/MacOS双端构建(缺一台Mac电脑来验证)。
此前,XiaoMate 的聊天界面虽然能够正常收发消息,但在细节上仍有明显不足:Markdown 格式未被正确渲染、实时消息与历史记录样式不一致、工具消息堆叠时占用过多空间、消息显示顺序错乱、以及滚动加载大量历史记录时体验不佳。
现在这个版本只是在交互上优化了一下,但是这个界面总觉得不够漂亮,不够大气,但是我又不知道怎么改才能看起来更舒服一些。。。

同时,在工程层面,项目正式更名为 XiaoMate/小美同学,并补充了 macOS 构建支持,现在可以同时发布 Windows 和 Mac OS 两个平台的版本。
经过这一轮重构和优化,现在 XiaoMate 的聊天窗口已经接近主流 LLM 聊天界面的体验标准:
- 消息以圆角气泡形式展示,用户消息靠右、AI 消息靠左
- 支持完整的 Markdown 渲染,包括代码块、列表、链接和表格
- 工具消息默认折叠,按需展开查看
- 滚动到顶部可自动加载更早的历史记录
- 流式输出流畅,完成后自动格式化为 Markdown
当前版本:v2.1.8
下载地址
- Windows 绿色免安装版本: https://github.com/oddmeta/xiaomate-desktop/releases/download/v2.1.8/xiaomate-v.2.1.8-portable-win64.zip
- Windows 安装包:https://github.com/oddmeta/xiaomate-desktop/releases/download/v2.1.8/xiaomate-v.2.1.8-setup-win64.zip
- Mac OS: 请自行下载代码,编译安装使用。
- Linux: 请自行下载代码,编译安装使用。
现在XiaoMate 已经可以支持不少的技能了,但是一直没时间来介绍一下,但是国庆已经过去了一半了,后面几天有空的话,我再整理一下,把XiaoMate目前已经支持的技能一个个的来介绍一下。
下面是完整更新说明。
一、聊天体验全面升级
这是本次更新的重头戏,涉及消息渲染、显示顺序、分页加载和交互细节等多个方面。
1. Markdown 渲染支持
问题背景:
- 历史聊天记录和实时流式消息只显示纯文本,Markdown 语法未被解析
- 即使项目已包含
marked.min.js库,但未在index.html中加载
修复方案:
- 在
index.html中正确加载marked.min.js库 - 为助手消息(
assistant角色)启用 Markdown 渲染 - 创建
applyMarkdownStyles()函数,统一 Markdown 元素的样式
渲染支持的内容:
| 语法 | 示例 | 效果 |
|---|---|---|
| 粗体 | **文本** | 文本 |
| 斜体 | *文本* | 文本 |
| 行内代码 | `代码` | 代码 |
| 代码块 | ```language ... ``` | 语法高亮代码块 |
| 列表 | - 项目 | 项目符号列表 |
| 链接 | [文本](URL) | 可点击链接 |
| 引用 | > 引用内容 | 左侧带竖线的引用块 |
| 表格 | ` | 列1 |
样式控制细节:
- 为每个 Markdown 容器分配唯一 ID,使用精确的 CSS 选择器
- 重置所有元素的默认 margin 和 padding
- 统一设置
line-height: 1.0,与普通文本保持一致 - 代码块添加半透明黑色背景和圆角
- 引用块添加蓝色左侧边框
- 链接使用蓝色,悬停时显示下划线
2. 流式消息 Markdown 渲染优化
问题背景:
- 每次收到流式文本块时都重新渲染 Markdown,导致频繁 DOM 操作
- 性能差,可能出现显示闪烁
- 不完整的 Markdown 语法(如
**粗体只有开头)会被错误解析
优化方案:
采用延迟 Markdown 渲染策略:
- 流式输出阶段:只显示纯文本,使用
white-space: pre-wrap保留格式,逐个字符流畅显示 - 消息完成阶段:收到
done或finish信号后,一次性渲染完整的 Markdown
性能对比:
假设一条消息包含 100 个字符:
| 指标 | 优化前 | 优化后 | 提升 |
|---|---|---|---|
| Markdown 渲染次数 | 100 次 | 1 次 | 100 倍 |
| DOM 操作次数 | 100 次 | 1 次 | 100 倍 |
| 样式应用次数 | 100 次 | 1 次 | 100 倍 |
用户体验效果:
- 流式输出时:流畅的打字机效果,文字逐个显示,不卡顿
- 完成瞬间:突然变成漂亮的 Markdown 格式,视觉冲击感强
3. 聊天窗口行间距修复
问题背景:
- 即使代码中设置了
line-height: 1.0,实际显示的行间距仍然过大 - 原因是
chat-history容器本身未设置行高,浏览器使用默认值(1.2-1.5)
修复方案:
在以下四个层级统一设置 line-height: 1.0:
- 容器层级:
chat-history容器 - 消息内容层级:历史消息和工具消息的内容 span
- 实时消息容器层级:流式输出的
stream-text容器 - Markdown 渲染层级:
applyMarkdownStyles()函数和 CSS 规则
效果:
- 修复前:行间距约 14-18px
- 修复后:行间距 12px(12px 字体 × 1.0)
- 在有限的聊天窗口内可以显示更多内容
4. 实时消息显示顺序修复
问题背景:
- 实时收到的消息显示顺序错误:用户 → 助手 → 工具
- 正确顺序应该是:用户 → 工具 → 助手
- 与历史聊天记录的显示顺序不一致
根本原因:
- 用户发送消息时立即创建了空的助手消息容器并添加到 DOM
- 后续工具消息使用
appendChatMessage()追加到 DOM,自然在助手消息之后 - 但实际上工具调用发生在助手回复之前
修复方案:
采用延迟助手消息容器创建策略:
- 当收到
tool_call_progress或async_tool_completed消息时,检测到存在临时的助手消息容器,先移除它 - 工具消息正常追加到聊天历史
- 当真正收到助手回复(
llm_response_chunk或llm_response)时,再重新创建助手消息容器
修复后的消息流:
1. 用户发送消息
→ 创建临时助手消息容器
2. 收到工具调用进度
→ 移除临时助手容器
→ 工具消息添加到聊天历史 ✓
3. 收到工具完成消息
→ 工具完成消息添加到聊天历史 ✓
4. 收到助手回复
→ 重新创建助手消息容器(在工具消息之后)✓
→ 填充内容
最终效果:
- 用户消息 → 工具消息(折叠) → 助手消息
- 与历史记录的显示顺序完全一致
5. 工具消息折叠/展开功能
功能描述:
为工具消息(system 和 tool 角色)添加折叠/展开功能:
- 默认隐藏:工具消息内容默认折叠,只显示标题
- 点击展开:点击标题栏展开/折叠内容
- 视觉提示:显示三角形图标和”点击展开”提示文字
- 状态切换:展开后提示文字消失,图标方向改变
消息结构:
<div class="tool-message">
<!-- 标题栏(始终显示) -->
<div class="tool-message-header">
<span class="tool-toggle-icon">▶</span>
<span>系统:</span>
<span class="tool-hint">(点击展开)</span>
</div>
<!-- 内容区(默认隐藏) -->
<div class="tool-message-content">
工具消息内容...
</div>
</div>
优势:
- 减少干扰:工具消息默认隐藏,不干扰主要对话流
- 按需查看:用户可以根据需要展开查看工具调用详情
- 节省空间:多个工具消息折叠后占用空间极小
6. 标准 LLM 聊天框样式
设计目标:
参照主流 LLM 聊天界面(如 ChatGPT、Claude 等)的设计风格:
- 用户消息靠右显示,AI 消息靠左显示
- 不同角色的消息使用不同背景色的圆角气泡框
- 简洁现代的 UI 风格
具体实现:
| 消息类型 | 位置 | 背景色 | 文字颜色 |
|---|---|---|---|
| 用户消息 | 右侧 | 紫色渐变 #667eea → #764ba2 | 白色 #fff |
| AI 助手消息 | 左侧 | 半透明白色 rgba(255,255,255,0.08) | 浅灰 #eee |
| 工具/系统消息 | 左侧 | 橙色半透明 rgba(255,180,84,0.1) | 橙色 #ffb454 |
细节设计:
- 圆角气泡:12px 圆角,友好柔和
- 最大宽度:75%,避免消息过宽
- 内边距:10px 14px
- 消息间距:8px
- 字体大小:13px
- 行高:1.5(气泡内部)
- 时间戳:10px,灰色,用户消息右对齐
7. 聊天记录滚动加载更多
功能描述:
在聊天窗口中实现滚动加载更多历史记录的功能:
- 首次打开聊天窗口:加载最新的 20 条消息
- 向上滚动到顶部:自动加载更早的消息
- 每页加载 20 条消息
API 设计:
首次加载:GET /api/chat/history/?limit=20
加载更多:GET /api/chat/history/?before_id=<oldestMessageId>&limit=20
用户体验优化:
- 防重复加载:通过
isLoadingMore标志防止滚动时重复触发 - 边界检测:返回消息数少于 20 条时,自动停止继续加载
- 滚动位置保持:加载新消息后,自动调整滚动位置,避免跳动
- 加载状态提示:显示”加载中…”或”加载更多失败(点击重试)”
- 关闭重开:每次打开聊天窗口时重置分页状态,重新加载最新记录
8. 小美书签分页加载优化
优化内容:
- 支持分页加载书签收藏
- 修复打开提醒待办窗口时,滚动也会误触加载书签的问题
- 不同窗口的滚动事件独立处理,互不干扰
二、登录界面交互优化
优化内容:
- 优化了登录界面的交互流程
- 改进了登录状态管理和 UI 反馈
- 圆盘菜单中显示登入/登出菜单项
- 已登录:显示”登出”
- 未登录:显示”登入”
用户影响:
- 登录流程更加直观
- 登录状态一目了然
三、聊天窗口鼠标点击交互调整
问题背景:
- 此前为了让聊天内容可选择、可复制,导致主界面无法正常拖拽
修复方案:
- 将拖动限制为只有点击在聊天窗口标题栏时生效
- 点击聊天窗口内容区域时,可以正常选择和复制文本
- 修复了 Live2D 模型点击身体没有触发动画的问题
用户影响:
- 聊天内容现在可以正常选择和复制
- 窗口拖拽仍然可以通过标题栏完成
- Live2D 模型点击互动恢复正常
四、项目品牌与工程更新
1. 项目更名为 XiaoMate/小美同学
此前项目使用 Charlotty 作为名称,有朋友提到该名字相对偏向女性角色。XiaoMate 不限定角色性别:
- 既可以承载女性角色
- 也可以承载男性角色或宠物角色
因此调整为更加中性的 XiaoMate。
名称约定:
- 项目/仓库名称:XiaoMate
- 桌宠和快捷方式名称:小美同学
- 应用 ID:
com.oddmeta.xiaomate
仓库地址:
2. macOS 构建支持
新增内容:
- 补充了
build.sh和start.sh脚本 - 更新了
package.json的构建配置 - 现在可以同时支持 Windows 和 Mac OS 两个平台
构建脚本:
| 平台 | 构建脚本 | 启动脚本 |
|---|---|---|
| Windows | build.bat | start.bat |
| macOS/Linux | build.sh | start.sh |
技术文档更新:
- 补充
CROSS_PLATFORM.md:跨平台开发和构建指南 - 补充
QUICKSTART.md:快速开始文档
3. JavaScript 文件目录结构调整
调整内容:
- 将库文件按类型归类到子目录:
lib/live2d/:Live2D 相关库(PIXI.js、Cubism 等)lib/utils/:通用工具库(marked、qwebchannel 等)lib/:业务逻辑文件保持不变
用户影响:
- 对项目使用者更友好,文件组织更清晰
- 对普通用户无影响
五、完整更新列表
| ID | 更新内容 | 用户影响 |
|---|---|---|
| – | 登录界面交互优化 | 登录流程更直观 |
| – | 修复聊天内容可选择导致主界面无法拖拽 | 拖拽限制到标题栏,内容可选择复制 |
| – | 聊天窗口鼠标点击交互调整 | 拖拽和内容选择分离 |
| – | 修复 Live2D 点击身体没有动画的问题 | 模型点击互动恢复正常 |
| – | 优化 Live2D 模型动画检测机制 | 动画检测更准确 |
| – | 修复提醒窗口滚动误触加载书签 | 不同窗口滚动事件独立处理 |
| – | 小美书签分页加载优化 | 书签加载性能提升 |
| – | 项目更名为 XiaoMate/小美同学 | 品牌和应用名称更新 |
| – | 发布 v2.1.8,支持 Windows 和 Mac OS | 双平台构建支持 |
| – | 聊天记录获取可分页 | 首次加载 20 条,性能提升 |
| – | async_tool_failed 消息格式化 | 错误提示更清晰 |
| – | 统一各个窗口样式风格 | UI 风格一致 |
| – | 通用窗口默认带滚动条 | 长内容可滚动 |
| – | 流式输出只显示纯文本,不实时渲染 Markdown | 性能提升 100 倍 |
| – | 工具消息支持折叠/展开,默认折叠 | 减少干扰,节省空间 |
| – | 修复实时消息显示顺序 | 顺序与历史记录一致 |
| – | 历史消息和实时消息支持 Markdown 渲染 | 完整的 Markdown 支持 |
| – | MCP 工具调用链路调整 | 后端交互更稳定 |
| – | 圆盘菜单显示登入/登出菜单项 | 登录状态一目了然 |
六、快速开始
本次提供 Windows 和 Mac OS 两个平台的版本:
- Windows:https://github.com/oddmeta/xiaomate-desktop/releases/tag/v2.1.8
- macOS:https://github.com/oddmeta/xiaomate-desktop/releases/tag/v2.1.8
- 后端:https://github.com/oddmeta/xiaomate
使用说明
- AI 对话、书签、提醒、自动任务、MCP 技能和通知等在线功能仍然依赖后端;Live2D/3D 模型展示、窗口交互和本地设置不依赖后端。
- 默认后端地址仅用于演示,服务器配置较低,只建议用于体验界面;运行 Playwright 等复杂任务时大概率会失败。长期使用请自行下载并部署后端,这样数据也可以保存在自己的电脑中。
- 如果遇到问题,可以添加作者微信:
oddmeta;也欢迎关注公众号”奥德元”,一起学习 AI,一起追赶时代。Good good study, day day up。
七、升级说明
1. 旧版用户
建议先退出旧版 XiaoMate,再解压并运行新版本,避免旧窗口或 Electron 进程占用文件。
2. 在线功能
AI 对话、书签、提醒、自动任务、MCP 和通知仍需要 XiaoMate 后端。离线状态下,模型展示、窗口交互和本地设置仍可使用。
3. 当前已知限制
- 部分复杂 VRM、GLB 或 GLTF 模型的效果会受模型骨骼、动画命名和文件结构影响;
- 3D 模型自动走动仍需要针对更多模型继续验证和优化。
XiaoMate — 支持 Live2D 与 3D 模型的 Windows/Mac 桌面宠物。
桌面客户端:https://github.com/oddmeta/xiaomate-desktop
后端服务:https://github.com/oddmeta/xiaomate
Windows/macOS 前端便携版:https://github.com/oddmeta/xiaomate-desktop/releases/tag/v2.1.8
问题反馈微信:oddmeta
公众号:奥德元