1. 这个项目是做什么的,为什么值得关注
1.1 AccessAI 的定位与这次更新的背景
AccessAI 是一个开源的 Web 端 AI 对话工具,你可以把它理解为「自己掌控数据和界面的 AI 聊天前端」。它本身不包含模型推理能力,而是把各家大模型 API,比如 OpenAI、DeepSeek、Claude,以及本地 Ollama 部署的模型,统一包装成一套对话服务。你只需要一个界面,就能在不同模型之间来回切换、管理历史会话、控制上下文长度,而且所有数据都保存在你自己的服务器或本地浏览器里。
这个项目最早其实只是我给自己用的小工具。当时我手上有好几个模型的 API key,也跑着本地模型,但每次对比答案都得打开好几个页面,复制粘贴来来回回,效率很低。后来陆续有一些朋友和网友看到我在社区分享的截图,问能不能开源,我就整理了一下代码放到了 GitHub 上。没想到关注的人比预期多,于是维护着维护着,就变成了一个持续迭代的开源项目。
这次发版算是项目从「能用」到「好用」的一个拐点。之前版本界面比较朴素,代码结构也是典型的「先跑通再说」:前端一个页面堆到底,后端接口里各种 if-else 判断模型名。用的人一多,问题就藏不住了。最多的一类反馈是「我想在 A 模型和 B 模型之间切换对比答案,但每次都要重新开对话」「聊到一半刷新,记录全没了」。这些问题指向同一个方向:AI 对话工具不该只是 API 的搬运工,它得能管理对话,而管理对话的前提是有好的界面容器、统一的多模型接入、可控的上下文窗口,以及可靠的历史存储。
1.2 这次更新的四个核心模块
这次更新的核心就是围绕上面那四个痛点展开的。第一是界面重构,从内到外换了一套组件化架构,支持深色模式、移动端适配,流式打字效果也重新做了。第二是多模型接入,后端抽象出一层统一的 Provider 接口,新增一个模型供应商不再需要复制粘贴大段代码,只需要实现接口。第三是对话上下文管理,引入 token 估算和滑动窗口机制,长对话不再动不动就报错。第四是历史管理,所有会话记录落到本地数据库,支持列表检索、重命名、归档、导出和跨标签页同步。
这篇文章主要面向两类读者:一类是想自己部署或者改造 AI 对话工具的人,另一类是想从零参与开源项目、想看看一个真实项目怎么做架构演进的人。我会把这次更新的设计思路、关键代码逻辑、踩过的坑都拆开讲,尽量还原我当时的决策过程。看完之后,你至少能知道一个合格的 AI 聊天前端应该具备哪些模块,以及每个模块在实现时有哪些容易被忽略的细节。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 新界面重构背后的几个关键决策
2.1 为什么选择整体重构而不是继续打补丁
在动手之前,我仔细盘了一下老代码的问题。老的界面用了一个全局 state 对象管理所有数据,消息列表渲染用的是 innerHTML 拼接字符串,当时觉得快,实际上遇到长对话就明显卡顿,尤其是流式输出的时候,每来一段增量文本就要把整个列表重新渲染一遍,用户体验很糟。加上深色模式、移动端适配这些需求,改起来牵扯面太大,最后还是决定推倒重来,换成组件化写法加 CSS 变量主题。
一个容易被忽略的点:重构前一定要把「用户实际使用路径」列清楚。对 AccessAI 来说,核心路径就三条:发起新对话、在对话中切换模型、回去翻历史记录。其他像设置页、关于页都是次要的。所以新界面的布局围绕这三条路径设计,聊天页永远是主界面,历史记录做成侧边栏抽屉,设置收进一个独立页面,不让它干扰主流程。
重构过程中我给自己定了一条规矩:不在重构的同时加新功能。新界面只能做到「跟旧功能等价甚至更好」,而不是借着重构的名义把功能范围越滚越大。这个规矩帮我避免了很多不必要的返工,也让老用户可以平滑迁移到新版本。
2.2 主题系统与组件拆分的落地
新界面采用 CSS 变量做主题系统,所有颜色、圆角、间距都定义在 :root 里,深色模式只需要切换一个 data-theme 属性。这么做的收益是:以后换品牌色、做高对比度模式都不用改组件代码,改变量就行。我甚至给用户留了自定义主题色的入口,虽然藏在设置页里,但确实有人用。
组件拆分上,我按消息维度拆成 MessageBubble、MessageList、MessageInput、ConversationList 等常见组件,每个组件只干一件事,状态通过 props 传递,数据流是单向的。特别注意了一个地方:AI 回复内容大部分是 Markdown 格式,直接渲染 Markdown 库没问题,但代码块需要单独处理,防止 XSS 风险。我的做法是先经过一个清洗函数,把危险的 HTML 标签过滤掉,再做 Markdown 渲染,代码高亮用的是 Prism
