1. 项目概述:一个开源的AI聊天聚合平台
如果你和我一样,每天需要在ChatGPT、Claude、Bard以及本地部署的Ollama模型之间来回切换,那一定会对浏览器里开满的标签页和混乱的对话历史感到头疼。我一直在寻找一个能统一管理所有AI对话的“控制台”,直到我遇到了unsaged。
unsaged 是一个基于现代Web技术栈(Next.js + Supabase)构建的开源AI聊天套件。它的核心价值非常明确:让你在一个干净、统一的界面里,无缝地与来自不同提供商(OpenAI、Anthropic、Google、Azure乃至本地Ollama)的数十种大语言模型进行对话。这不仅仅是把几个API密钥填进去那么简单,它真正解决了多模型协作时的几个核心痛点:对话历史的管理与云同步、用户身份的快速切换、以及通过系统提示词和模板来定制化每一次交互的上下文。
简单来说,你可以把它想象成一个为你所有AI助手准备的“统一收件箱”和“指挥中心”。无论是工作时的代码审查用Claude,创意写作时切到GPT-4,还是临时查个资料用Google的PaLM 2,都不需要离开当前页面。所有对话记录都会通过Supabase实时同步到云端,在手机、平板、电脑上都能无缝衔接。对于开发者、研究人员或者重度AI使用者而言,这极大地提升了工作流的连贯性和效率。
2. 核心架构与设计思路拆解
2.1 为什么选择 Next.js + Supabase 这个组合?
unsaged 的技术选型非常典型,代表了当前全栈Web开发的最佳实践之一。我们来拆解一下这个选择背后的逻辑。
Next.js 作为前端框架:它不仅仅是一个React框架。对于unsaged这样的实时聊天应用,Next.js提供了至关重要的能力。首先是服务端渲染(SSR)和静态生成(SSG),这能确保应用首次加载速度极快,提升用户体验。更重要的是其API Routes功能,unsaged可以利用它在服务端安全地处理所有AI供应商的API调用。你的API密钥从前端发送到自己的Next.js服务端,再由服务端转发给OpenAI或Anthropic,这样密钥就不会暴露在浏览器中,安全性得到了保障。此外,Next.js内置的优化(如图像优化、字体优化)和日益完善的App Router,为构建高性能、可维护的应用提供了坚实基础。
Supabase 作为后端即服务(BaaS):这是项目的点睛之笔。Supabase提供了开箱即用的PostgreSQL数据库、实时订阅、身份认证和存储。对于unsaged来说:
- 数据库:用于存储用户信息、对话列表、消息记录。PostgreSQL的JSONB类型非常适合存储结构灵活的聊天消息。
- 身份认证:Supabase Auth支持多种登录方式(邮箱/密码、OAuth等),unsaged可以轻松实现多用户管理,每个用户的数据严格隔离。
- 实时同步:这是实现“多设备同步”的关键。Supabase的Realtime功能允许前端订阅数据库的特定变化。当你在手机A上发送一条消息,这条消息被插入数据库的
messages表,手机B前端因为订阅了该对话的变化,会立刻收到更新并渲染出新消息,实现了近乎零延迟的同步体验。 - 自托管友好:Supabase是开源的,你可以将其部署在自己的服务器上,实现数据的完全自主控制,这对于企业或注重隐私的用户至关重要。
这个组合避免了从零搭建后端服务的复杂性,让开发者能聚焦在核心业务逻辑——即AI聊天功能的整合与用户体验的优化上。
2.2 功能模块设计解析
unsaged的架构围绕几个核心实体展开:User(用户)、Conversation(对话)、Message(消息)、Model(模型)。其数据流大致如下:
- 用户发起请求:用户在界面中选择模型、输入提示词。
- 服务端代理:前端将请求(包含提示词、模型ID、对话历史等,但不含供应商API密钥)发送至Next.js API Route。
- 路由与转发:Next.js服务端根据模型ID判断供应商(如
openai、anthropic),从环境变量中读取对应的API密钥,按照该供应商的API格式重新组装请求,并转发。 - 流式响应处理:为了获得类似ChatGPT的打字机效果,服务端会处理供应商返回的流式响应(Streaming Response),并将其逐块(chunk)转发回前端。
- 数据持久化与同步:同时,服务端会将用户发送的消息和AI返回的消息存入Supabase的
messages表。由于前端订阅了该对话的变更,新消息会通过Supabase的实时通道立刻推送到所有在线设备上。
注意:这种“服务端代理”模式是此类应用的安全基石。永远不要将第三方服务的API密钥硬编码在客户端JavaScript中,否则极易被他人窃取,导致不必要的费用损失和安全风险。
3. 从零开始部署:详细实操指南
假设你有一台云服务器(如AWS EC2、DigitalOcean Droplet)或本地开发环境,并希望部署一个属于自己的unsaged实例。以下是基于官方文档和实践的详细步骤。
3.1 环境准备与依赖安装
首先,确保你的系统已安装Node.js(推荐18.x或以上版本)和npm/yarn/pnpm。然后,获取项目代码。
# 克隆仓库 git clone https://github.com/jorge-menjivar/unsaged.git cd unsaged # 安装依赖 (项目使用pnpm作为包管理器) # 如果你没有pnpm,先安装它:npm install -g pnpm pnpm install这一步会安装项目package.json中定义的所有依赖。由于unsaged已转变为Monorepo结构(包含apps/web主应用和apps/docs文档站),使用pnpm可以很好地处理工作区内的依赖关系。
3.2 配置 Supabase 项目
这是整个部署的核心环节。Supabase将充当你的数据库和用户系统。
- 创建Supabase项目:访问 supabase.com ,注册并登录。点击“New Project”,填写项目名称、数据库密码,选择离你用户较近的区域。创建完成后,进入项目概览页。
- 获取连接信息:在项目设置(Settings -> API)中,找到以下关键信息:
Project URL:你的Supabase实例地址。anon/publickey:用于前端与Supabase交互的密钥。service_rolekey:高度敏感,仅用于服务端执行高权限操作(如运行迁移脚本),切勿暴露给前端。Database Password:你创建项目时设置的密码。
- 初始化数据库表:unsaged的仓库中提供了SQL脚本来创建所需的表结构。你需要执行它。
- 在Supabase控制台左侧菜单,进入SQL Editor。
- 点击New query,将仓库中
apps/web/db/目录下的schema.sql文件内容复制粘贴到编辑器中。 - 点击Run执行。这将创建
profiles,conversations,messages等核心表。
3.3 配置环境变量与AI供应商API密钥
unsaged的配置主要通过环境变量完成。在项目根目录下,复制示例环境文件并填写你的真实信息。
# 进入web应用目录 cd apps/web # 复制环境变量示例文件 cp .env.example .env.local现在,用你喜欢的编辑器打开.env.local文件。你需要配置两大块内容:
A. Supabase 配置
NEXT_PUBLIC_SUPABASE_URL=你的Project URL NEXT_PUBLIC_SUPABASE_ANON_KEY=你的anon/public key SUPABASE_SERVICE_ROLE_KEY=你的service_role key DATABASE_URL=postgresql://postgres:[你的数据库密码]@db.[你的Project URL].supabase.co:5432/postgres实操心得:
DATABASE_URL的格式是固定的,[你的Project URL]部分需要去掉https://前缀。例如,如果你的URL是https://abc123.supabase.co,那么主机名就是db.abc123.supabase.co。
B. AI 供应商API密钥你需要为你计划使用的每个AI服务申请API密钥。
# OpenAI OPENAI_API_KEY=sk-... # Anthropic (Claude) ANTHROPIC_API_KEY=sk-ant-... # Google PaLM 2 (需通过Google AI Studio获取) GOOGLE_AI_API_KEY=... # Azure OpenAI (格式略有不同) AZURE_OPENAI_API_KEY=... AZURE_OPENAI_ENDPOINT=https://your-resource.openai.azure.com/ # 对于Azure,你还需要在界面上选择对应的“部署名”(Deployment Name) # Ollama (本地部署) OLLAMA_HOST=http://localhost:11434 # 默认地址,如果你的Ollama服务在其他地方,请修改重要提示:
.env.local文件绝不能提交到版本控制系统(它已在.gitignore中)。这些密钥是你的私密信息。
3.4 本地运行与构建
配置完成后,你就可以在本地启动开发服务器进行测试了。
# 确保在 apps/web 目录下 pnpm dev访问http://localhost:3000,你应该能看到unsaged的登录界面。首次使用,你可以用邮箱注册一个账户。登录后,在设置(Settings)中检查你配置的AI模型是否都已正确列出并可用。
如果一切正常,接下来可以构建用于生产环境的版本。
pnpm build pnpm startbuild命令会执行Next.js的优化构建。构建成功后,pnpm start会启动生产服务器。
3.5 部署到 Vercel (推荐)
对于生产环境部署,Vercel是与Next.js最配的平台,提供全球CDN、自动HTTPS和极简的部署流程。
- 将你的代码仓库推送到GitHub、GitLab或Bitbucket。
- 登录 Vercel ,点击“Add New...” -> “Project”,导入你的unsaged仓库。
- 关键配置:由于项目是Monorepo,你必须在Vercel项目的设置中,将Root Directory设置为
apps/web。这样Vercel才知道从哪个子目录构建。 - 在环境变量配置页,将你在
.env.local中配置的所有变量(NEXT_PUBLIC_SUPABASE_URL,OPENAI_API_KEY等)一一添加进去。 - 点击“Deploy”。部署完成后,Vercel会为你生成一个永久的访问域名(如
xxx.vercel.app)。
部署成功后,你的私有AI聊天聚合平台就正式上线了。
4. 核心功能深度使用与配置技巧
4.1 多模型切换与供应商管理
unsaged的模型列表是动态生成的,基于你在环境变量中配置的密钥。在界面的模型选择下拉框中,你会看到所有可用的模型。
使用技巧:
- 模型分组:界面通常会按供应商(OpenAI、Anthropic等)对模型进行分组,清晰明了。
- 参数预设:对于每个模型,unsaged可能会设置一些默认参数(如温度
temperature、最大令牌数max_tokens)。你可以在对话设置中根据需要进行调整。例如,创意写作时调高温度(如0.8-1.0)增加随机性,代码生成时调低温度(如0.2)确保确定性。 - 快速测试:新建一个对话,分别用GPT-4和Claude 2回答同一个复杂问题,对比两者的逻辑和风格差异,是快速了解模型特性的好方法。
4.2 系统提示词与对话模板的高级用法
这是发挥unsaged威力的关键功能,能让你将AI定制成专业的助手。
系统提示词:这定义了AI的“角色”和对话的上下文。例如:
- “你是一位资深的Python代码审查专家,请以严谨、清晰的方式指出代码中的问题,并提供改进建议。”
- “你是一位亲切的创意写作伙伴,擅长使用比喻和生动的描写。请用中文回复。”系统提示词会随着每条消息发送给AI,持续影响其回复风格。你可以在对话设置中随时修改。
消息模板:这是一个效率工具。你可以创建包含变量的模板。例如,创建一个名为“代码解释”的模板,内容为:
请解释以下代码片段:{code}重点关注其算法逻辑和潜在的性能瓶颈。
使用时,只需选择该模板,填入`{language}`(如python)和`{code}`变量,即可快速生成结构化的提问,无需每次手动输入格式。
4.3 多用户与会话管理
如果你与团队共享这个部署,或者想区分工作和个人用途,多用户功能就非常有用。
- 用户切换:在侧边栏顶部或设置中,可以快速注销当前用户并登录另一个账户。每个用户的对话、设置完全独立。
- 会话组织:你可以为不同的项目或主题创建不同的对话(Conversation),并为其命名(如“项目A-架构设计”、“学习笔记-机器学习”)。侧边栏的对话列表支持搜索和排序,方便管理大量历史记录。
- 数据隔离:得益于Supabase的行级安全策略,用户A绝对无法访问用户B的数据库记录,确保了隐私和安全。
4.4 云同步机制详解
云同步是“开箱即用”的。只要你使用同一个账户登录,在任何设备上进行的操作都会实时同步:
- 新建对话:在手机上新开一个对话,电脑上几秒内就会出现在侧边栏。
- 发送/接收消息:任一设备上的消息都会实时出现在所有设备的该对话中。
- 对话重命名/删除:操作也会同步。 其背后是Supabase Realtime在监听
conversations和messages表的INSERT、UPDATE、DELETE事件,并通过WebSocket推送给所有订阅的客户端。
5. 集成本地模型:Ollama配置指南
unsaged对Ollama的支持让你能将强大的本地模型纳入统一界面,这对于数据敏感或需要离线使用的场景至关重要。
5.1 安装与运行 Ollama
首先,在你的服务器或本地电脑上安装Ollama。访问 ollama.ai 下载对应操作系统的安装包,或使用命令行安装(Linux/macOS):
curl -fsSL https://ollama.ai/install.sh | sh安装完成后,启动Ollama服务(通常安装后会自动运行)。它默认会在http://localhost:11434提供API服务。
5.2 拉取并运行模型
Ollama支持众多开源模型。你可以通过命令行拉取需要的模型:
# 拉取一个较小的模型,如 Mistral 7B ollama pull mistral # 拉取一个代码模型,如 Codellama ollama pull codellama # 拉取一个更大的对话模型,如 Llama2 70B ollama pull llama2:70b拉取完成后,模型就已经准备就绪。Ollama服务会管理模型的加载和卸载。
5.3 配置 unsaged 连接 Ollama
在unsaged的环境变量(.env.local或Vercel环境变量)中,确保设置了:
OLLAMA_HOST=http://localhost:11434如果你的Ollama运行在其他机器上,则需填写对应的IP和端口,如http://192.168.1.100:11434。
重启unsaged应用后,在模型选择列表中,你应该能看到“Ollama”分组,下面列出了你本地已拉取的所有模型(如mistral,codellama,llama2:70b等)。
注意事项:
- 性能:运行大型本地模型(如70B参数)需要强大的GPU和足够的内存。请根据你的硬件条件选择合适的模型。
- 网络:如果unsaged(前端)和Ollama服务不在同一台机器,需确保网络连通,且Ollama所在机器的11434端口对unsaged服务器开放。
- 速度:本地模型的响应速度取决于你的硬件。首次加载模型可能需要一些时间。
6. 常见问题排查与维护心得
即使按照步骤操作,在实际部署和运行中也可能遇到一些问题。这里记录了一些常见坑点及其解决方案。
6.1 部署与启动问题
| 问题现象 | 可能原因 | 解决方案 |
|---|---|---|
pnpm build失败,提示TypeScript错误 | 依赖版本或Monorepo结构问题 | 1. 确保在项目根目录执行过pnpm install。2. 尝试删除 node_modules和pnpm-lock.yaml,然后重新运行pnpm install。3. 检查Node.js版本是否符合要求(>=18)。 |
| 应用能打开,但登录/注册失败,控制台报Supabase错误 | Supabase环境变量配置错误或数据库表未初始化 | 1. 仔细核对.env.local中的NEXT_PUBLIC_SUPABASE_URL和NEXT_PUBLIC_SUPABASE_ANON_KEY,确保没有多余空格或换行。2. 登录Supabase控制台,在SQL Editor中确认已成功运行 schema.sql脚本创建了所有表。 |
| Vercel部署成功,但访问页面显示空白或错误 | Root Directory未设置或环境变量未配置 | 1. 在Vercel项目设置的“Build & Development Settings”中,确认Root Directory设置为apps/web。2. 在Vercel的“Environment Variables”设置中,确认所有必要的环境变量都已添加(包括Supabase和各个AI API密钥)。 |
6.2 功能使用问题
| 问题现象 | 可能原因 | 解决方案 |
|---|---|---|
| 某个AI模型(如Claude)不可选或请求失败 | 对应的API密钥未配置或已失效 | 1. 检查环境变量中是否配置了正确的API密钥(例如ANTHROPIC_API_KEY)。2. 前往对应供应商平台(如Anthropic控制台),确认密钥有效且有额度。 3. 对于Azure OpenAI,还需检查 AZURE_OPENAI_ENDPOINT是否正确,以及在UI中选择的部署名是否与Azure门户中创建的一致。 |
| Ollama模型列表为空或连接失败 | OLLAMA_HOST配置错误或Ollama服务未运行 | 1. 在运行unsaged的服务器上,执行curl http://localhost:11434/api/tags,看是否能返回本地模型列表。如果不能,说明Ollama服务未运行。2. 确认 OLLAMA_HOST环境变量指向了正确的地址和端口。3. 如果Ollama在远程,检查防火墙是否放行了11434端口。 |
| 消息发送后长时间无响应或报超时错误 | AI供应商API超时或网络问题 | 1. 首先尝试一个简单的提示词,看是否是特定复杂请求导致。 2. 检查Next.js服务端日志(Vercel Logs或服务器控制台),看是否有更详细的错误信息。 3. 可能是供应商API暂时不稳定,稍后重试。对于本地Ollama,可能是模型首次加载或硬件不足导致响应慢。 |
| 多设备间消息同步延迟或不同步 | Supabase Realtime连接问题 | 1. 检查浏览器控制台是否有WebSocket连接错误。 2. 确认所有设备登录的是同一个Supabase项目( NEXT_PUBLIC_SUPABASE_URL一致)。3. 刷新页面重新建立连接。Supabase Realtime在弱网环境下会自动重连。 |
6.3 升级与数据迁移
unsaged项目仍在活跃开发中。当你想升级到新版本时:
- 拉取最新代码:
git pull origin main pnpm install # 更新依赖 - 检查数据库迁移:查看项目
apps/web/db/目录下是否有新的SQL迁移脚本(如UpgradeScript.sql)。官方会在发布重大更新时提供。如果有,需要登录Supabase控制台的SQL Editor,执行这些脚本来更新表结构。 - 重新构建与部署:
pnpm build # 然后重启服务或重新部署到Vercel
实操心得:在升级生产环境前,务必在测试环境(如本地或一个独立的Vercel预览部署)中先行测试,确保新版本与你的现有数据和配置兼容。
7. 安全与隐私考量
使用这样一个自托管平台,安全和隐私是需要你亲自负责的方面。
- API密钥安全:如前所述,所有供应商API密钥必须通过环境变量配置在服务端(Vercel或你的服务器),绝不在前端代码中暴露。定期在供应商平台轮换密钥是好的安全实践。
- Supabase安全:充分利用Supabase的行级安全策略。默认情况下,unsaged的Schema应该已经设置了合理的策略,只允许用户访问自己的数据。你可以定期审查
schema.sql中的策略以确保其严密性。 - 通信安全:确保你的unsaged访问地址使用HTTPS(Vercel默认提供)。这能防止中间人攻击窃听你和AI之间的对话内容。
- 数据备份:虽然Supabase提供了可靠性,但定期备份你的PostgreSQL数据库是明智之举。Supabase控制台提供了手动备份和设置自动备份的选项。
- 内容审查:如果你开放给团队或公众使用,请注意,用户可能通过AI生成各种内容。你需要建立相应的使用条款,并意识到作为平台托管方可能承担的责任。
unsaged作为一个工具,赋予了你对数据和流程的完全控制权。这份控制权也伴随着自己管理安全的责任。花时间正确配置和维护它,是享受其便利的前提。
经过几个月的深度使用,unsaged已经成了我日常工作流中不可或缺的一部分。它最大的价值不在于某个炫酷的功能,而在于将碎片化的AI交互体验整合成了一个连贯、可管理、可追溯的工作空间。从快速切换模型对比答案,到利用系统提示词打造专属的代码评审助手,再到在手机和电脑间无缝继续一个复杂的讨论,这些细节上的顺畅感累积起来,实实在在地提升了效率。
如果你也受困于多个AI平台间的切换成本,或者希望在一个更私密、可控的环境中使用大语言模型,那么投入一些时间部署和配置unsaged,绝对是值得的。它就像给你的数字大脑们建了一个统一的“作战室”,指挥起来,顺手多了。