AccessAI 这个项目我维护了一年多,最初只是给自己拼的一个聚合查询小工具,把不同模型厂商的 API 塞到一个页面里,省得来回切网页。后来陆续有人找到我,说也想用这种一站式的对话工具,我干脆把它拆成了开源项目。这轮更新算是我自己最满意的一次:界面整体重做,模型接入从单模型变成多模型,对话上下文和会话历史也都补上了,项目从"能用"迈到了"好用"的阶段。
先说清楚 AccessAI 是什么。它是一个开源的 AI 对话聚合应用,提供 Web 界面,能统一接入 OpenAI、Anthropic Claude、Google Gemini、DeepSeek、通义千问等大模型服务。你在一个对话框里可以随时切换不同模型,多轮对话的上下文会自动带上,所有的会话记录都会存到本地数据库里,随时翻查、导出。这次更新解决的核心痛点有三个:一是原来那种"每个模型一个网页"的使用方式太零碎,二是切换模型后上下文经常丢失,三是聊过的内容关了浏览器就没了。
如果你也在做类似的 AI 对话项目,或者你想本地搭一个可以自由切换多模型、能保存历史的对话工具,这篇更新记录应该对你有点用。下面我会把新界面、多模型接入、上下文维护、历史管理这几块的设计思路和实现细节都拆开讲,包括我踩过的坑和排查方法。
1. 这次更新到底做了什么
1.1 项目定位与要解决的问题
AccessAI 从立项开始就不是奔着做一个"ChatGPT 套壳站"去的,我更想把它做成本地私有化的模型网关加对话工作台。周围不少朋友用 ChatGPT 用得好好的,但公司项目里要求数据不能出内网,或者有的人订阅了多个 AI 服务,每个月交好几份钱,实际只用到其中一两个。AccessAI 的定位就是让这些人在同一个界面里,按需调用自己已经有的 API,密钥自己保管,数据存在本地,不依赖任何第三方平台。
这次更新之前,项目的状态挺尴尬的:界面是 Bootstrap 拼的,模型写死了一个,对话没有上下文,刷新页面就失忆。从实际使用的角度来看,这几个缺失很致命。没有上下文,意味着每次提问都要把背景资料重新贴一遍,多轮对话完全没法做;没有历史管理,意味着你无法回头检索之前聊过的重要内容。所以这次更新我把"新界面、多模型、对话上下文、历史管理"四个点作为一个整体来设计,因为它们互相之间是有依赖关系的。
界面的价值在于降低多模型的切换成本,上下文的价值在于让切换模型之后还能接得上话,而历史管理的价值在于让所有对话沉淀下来,变成可检索的知识库。在设计时我没有把它们当成四个独立功能去堆,而是梳理成一条主线:用户发起对话 -> 系统根据当前会话组织上下文 -> 调用当前选中的模型 -> 流式返回结果 -> 结果连同上下文一起写入会话历史。
1.2 整体架构调整
这轮更新的架构分成三层。最上层是前端界面,采用 Vue 3 加 Element Plus 重写,负责对话展示、模型切换、流式输出渲染和会话管理。中间层是 API 服务,基于 FastAPI 实现,对外提供会话和消息相关的 REST 接口,对内统一封装不同模型厂商的调用逻辑。最底层是存储层,使用 PostgreSQL 保存用户、会话和消息数据,Redis 做临时缓存和流式输出的缓冲。
选择 FastAPI 有几个实际原因。一是异步支持天然适合大模型场景,流式输出不会阻塞其他请求;二是 Pydantic 做参数校验非常方便,不同模型厂商的参数差异可以在序列化时就规范掉;三是自动生成 OpenAPI 文档,前端对接起来明确。存储层为什么不用 SQLite?主要是因为会话和消息的写入频率不低,SQLite 在并发写入时会有锁竞争问题,多用户场景下体验不好。PostgreSQL 在这个量级下完全够用,而且支持全文检索,后面做历史消息搜索的时候可以直接用。
后端 API 的路径设计围绕会话和消息两条线展开:
text复制GET /api/v1/conversations 获取会话列表
POST /api/v1/conversations 创建新会话
GET /api/v1/conversations/{id} 获取某个会话的详情
DELETE /api/v1/conversations/{id} 删除会话
POST /api/v1/conversations/{id}/messages 发送消息
GET /api/v1/conversations/{id}/messages 获取消息列表
GET /api/v1/models 获取可用模型列表
GET /api/v1/models/{provider} 获取某个厂商的模型配置
这套接口设计遵循一个原则:前端不直接感知模型厂商的差异,只和会话、消息打交道。至于当前会话用的是哪个模型,是存在会话对象里的一个普通字段。这样后续加新模型,前端几乎不用改。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 新界面:从能用变成好用
2.1 为什么重写前端
旧版界面最大的问题不是丑,而是交互逻辑混乱。模型切换需要进设置页改配置,保存之后还要刷新页面才生效;聊天记录只能看到当前浏览器会话的,没有一个统一的入口去管理。与其继续打补丁,不如直接重写。
前端我选了 Vue 3 组合式 API,配合 Element Plus 组件库。选型上没太多纠结,Vue 在国内社区生态成熟,Element Plus 的表单、按钮、下拉菜单这些基础组件够用,对话界面里的气泡、输入框、侧边栏都可以基于它快速搭建。状态管理用的 Pinia,主要管理三个全局状态:当前会话对象、当前选中的模型配置、系统设置信息。
界面布局参考了主
