纯前端零后端大模型工作台:本地部署与API接入完全指南
如果你也跟我一样天天跟各种大模型工具打交道应该能发现一个很现实的问题聊天工具越来越重了。要么得注册某个平台的服务要么必须在本地折腾一套后端环境配置数据库、写接口、处理鉴权其实我只是想安安静静地跟模型聊个天、对比一下不同模型的回答风格而已。最近我一直在用一个纯前端、零后端的本地优先开源大模型工作台项目名就叫 lab我一般叫它“实验室工作台”它能同时接 DeepSeek、Qwen、Ollama、Claude 这几类主流模型打开浏览器就能用所有对话记录和配置都存在本地部署方式就是一条静态服务器命令。这篇文章我就把这个项目从原理到实操完整拆给你看。先说清楚它能做什么、适合谁。如果你有 DeepSeek 或 Qwen 的 API Key想找一个干净、清爽、没广告的聊天界面它合适如果你本机装了 Ollama想给本地模型套一个好用的 Web 界面它更合适如果你想折腾 Claude 但不想把 Key 交给第三方平台它也合适。它不需要数据库不需要 Redis不需要 Nginx 反代一个纯静态目录就能跑得飞起。对于刚接触大模型的初学者来说这是理解“前端到底怎么跟大模型 API 交互”的最佳样本对于老手来说这是日常测试模型、做 prompt 对比的趁手工具。1. 这到底是个什么项目核心思路与选型拆解1.1 纯前端 本地优先意味着什么现在的 AI 应用基本分两种形态一种是像 ChatGPT 官网那样前端页面 后端 API 数据库数据全都存在平台的服务器上另一种是桌面客户端 本地/云端模型接口但很多桌面端依然要捆绑一个本地服务进程。lab 走的是第三条路纯静态页面直接跑在浏览器里通过前端 JavaScript 直接调用各家的模型 API数据默认只存在浏览器的本地存储里。“本地优先”这四个字是精髓。它不只是说数据存在本地而是整个应用的架构思路都以本地为第一优先级。没有服务器意味着没有账号体系你不需要注册、不需要登录、不需要找回密码打开页面就能用。没有后端意味着没有额外的运维成本你不会遇到某个接口突然 502、数据库连不上、磁盘写满这类问题。这样的架构有一个天然的好处隐私边界非常清晰。你的对话内容、历史记录、包括 API Key 的存储位置全都由你自己控制。你关掉浏览器数据就留在你本地你清掉站点数据世界就干干净净。对于喜欢折腾但又有一定隐私洁癖的人来说这是很舒服的状态。1.2 为什么零后端仍然能跑大模型多模型接入的架构思路很多人第一次听到“纯前端跑大模型”都会疑惑大模型的 API 调用不是需要后端代理来保护 Key 吗前端直接调用不会暴露 Key 吗这里要说得直白一点lab 默认就是前端直连。浏览器里发的请求会带上你的 API Key这个 Key 在网络请求里是可见的。所以它更适合“你一个人在自己电脑上用”或者“部署在内网几个人用”的场景而不适合做成公开网站给大家用。但好处也很明显——零后端、零代理、零中间层只要模型厂商支持跨域调用页面就能直接跑起来。它的多模型接入架构其实是围绕“一个统一的对话框架 多个 provider 适配器”来设计的。你先在设置里填好各家模型的 API Key 和 Base URL然后新建会话时选择一个模型lab 会把你的消息整理成各家模型各自要求的请求格式发出去之后再把返回结果转成一个统一的流式输出。整个过程完全是浏览器里的前端逻辑没有消息队列没有任务调度请求直接发、响应直接收。这就像是给不同型号的打印机做了几个不同的驱动程序上层界面统一按“打印”按钮就行。DeepSeek 有 DeepSeek 的驱动Ollama 有 Ollama 的驱动Claude 有 Claude 的驱动但它们对外暴露出来的体验是一致的。2. 快速跑起来本地部署与配置实操2.1 环境准备与项目初始化先把前提条件说清楚。跑这个项目只需要三样东西Node.js 环境如果你只是用打包好的静态文件连这个都不需要一个支持现代浏览器的电脑Chrome 或 Edge 都行至少一个可用的模型接入渠道API Key 或本地 Ollama第一步是从 GitHub 拉取源码。我用的是 ssh 方式git clone https://github.com/你的用户名/lab.git cd lab npm install npm run dev如果你是下载的 zip 包解压之后同样执行 npm install 就能把依赖装好。依赖装完 npm run dev 会起一个本地开发服务器浏览器打开提示的地址就能看到工作台界面。这里有一个容易踩的小坑如果你在国内网络环境下 npm install 很慢可以先把 npm 的 registry 切到国内镜像源npm config set registry https://registry.npmmirror.com但我个人更推荐用 pnpm 或 yarn 来装依赖。pnpm 的硬链接机制在这个项目上表现得非常稳安装速度快磁盘占用也小。如果你机器上没有 pnpm可以先执行 npm install -g pnpm然后再用 pnpm install 替代上面的 npm install。如果你想直接部署到线上项目根目录其实提供了一个 Dockerfile但我说实话不太推荐为这种纯静态应用去套一层容器杀鸡用牛刀了。直接用静态托管更简单npm run buildbuild 之后 dist 目录就是完整的静态产物你可以扔到 Nginx、Caddy、GitHub Pages、Vercel 或者任何静态文件服务器上。2.2 接入 DeepSeek / Qwen / Ollama / Claude 的具体配置项目跑起来之后别急着聊天先去设置页面把模型渠道配上。下面我把几类模型的配置方式逐一拆开说。DeepSeek 的接入方式DeepSeek 现在提供的是 OpenAI 兼容的 API 接口所以配置起来非常顺滑。进入设置界面后选择新增一个 Provider类型选 OpenAI Compatible然后填写API Base URLhttps://api.deepseek.com/v1API Key你自己的 DeepSeek Key模型 IDdeepseek-chat也可以填deepseek-reasoner作为推理模型填完保存新建会话时选择对应的模型就能用了。这里要强调一下Base URL 结尾的/v1不要漏掉很多模型厂商兼容 OpenAI 接口时都会要求这个路径前缀。我第一次配置的时候漏了/v1报了一天的 404后来仔细看文档才反应过来。阿里的 Qwen 千问接入Qwen通义千问的接入方式和 DeepSeek 几乎一样也是 OpenAI 兼容接口API Base URLhttps://dashscope.aliyuncs.com/compatible-mode/v1API KeyDashScope 的 API Key模型 IDqwen-turbo或qwen-plus或qwen-maxDashScope 的 Key 要到阿里云百炼平台去申请新用户一般有一些免费额度日常测试完全够用。qwen-turbo 响应快、便宜qwen-max 质量更高、稍贵一点没有特殊要求的话 qwen-plus 是性价比最均衡的选择。Ollama 本地模型的接入如果你本机装了 Ollama这一步非常简单。Ollama 启动后默认监听 11434 端口lab 里新增 Provider 时选 Ollama 类型然后填Base URLhttp://localhost:11434模型 IDllama3.2或你本地已经拉取的其他模型名需要注意如果你在浏览器里用 lab 访问 Ollama浏览器直接向http://localhost:11434发请求会碰到一个关键问题——CORS 跨域拦截。Ollama 默认没有开启跨域允许解决办法有两个最简单的是把环境变量OLLAMA_ORIGINS设置成允许的来源比如# macOS / Linux OLLAMA_ORIGINShttp://localhost:5173 ollama serve # Windows set OLLAMA_ORIGINShttp://localhost:5173 ollama serve这里的 5173 是 Vite 开发服务器的默认端口如果你部署在别的端口要自己改成对应的地址。另一个办法是在本地起一个轻量代理转发请求但既然我们用 lab 就是为了不要后端我更推荐直接改环境变量。如果你只是本地自己用其实还有个更省事的办法把 lab 部署到http://localhost的某个端口再让 Ollama 允许该来源即可。Claude 的接入Claude 的接入方式跟 DeepSeek、Qwen 这类 OpenAI 兼容接口的稍微不同lab 里专门针对 Anthropic 的/v1/messages接口做了适配。填配置时Base URLhttps://api.anthropic.comAPI KeyAnthropic 的 API Key模型 IDclaude-sonnet-4-20250514或claude-opus-4-20250514这里有一个值得注意的点Claude 原版 API 的请求格式跟 OpenAI 完全不同它要求请求体里带anthropic-version请求头模型参数名也有差异。lab 在内部做了转换所以你只需要在界面上选模型和填 Key 就行不用关心协议差异。如果你没有 Anthropic 官方 Key国内外有很多中转服务也提供 Claude 模型Base URL 换成中转地址通常就行。2.3 本地模型Ollama的联动配置细节Ollama 现在基本是本地大模型的事实标准lab 对它的支持也很用心。这里我多说几个细节。首先是模型拉取的问题。如果你还没有下载任何模型可以在终端里执行ollama pull llama3.2拉一个 3B 的小模型来试水。实测下来3B 模型在普通笔记本上跑得还挺顺畅回答短问题基本是秒回。如果你的机器配置不错32G 内存起步建议直接上qwen2.5:14b或llama3.1:8b日常对话的质量会有明显提升。其次是并发问题。Ollama 默认对单个模型只会跑一个推理实例如果 lab 同时开了多个会话可能会出现“上一个请求还在生成下一个请求排队等待”的情况。这其实是正常现象老版本 Ollama 甚至还会因为内存不足直接杀掉进程。如果你的机器内存不算宽裕建议同时只开一个会话跟本地模型交流。还有一个比较实用的配置局域网联动。如果你有两台电脑一台配置高跑 Ollama一台日常办公想用 lab 聊天完全可以不用在办公电脑上装 Ollama。只需要确保两台机器在同一个局域网内然后 lab 的 Ollama Base URL 填http://主机IP:11434注意这台带 Ollama 的机器要设置OLLAMA_HOST0.0.0.0让它监听所有网卡。跨设备的好处是高配机器安安静静放在角落当推理服务器你用笔记本优雅地远程访问体验很接近“私有云大模型”。3. 核心机制与界面背后的实现逻辑3.1 流式输出的实现与体验优化用过 ChatGPT 的人都习惯了“字一个一个蹦出来”的流式效果。这个项目里流式输出是通过浏览器的fetch流式读取实现的原理并不复杂但细节里藏着不少优化空间。大模型 API 在收到你的请求后如果设置了 stream 模式会通过 SSEServer-Sent Events服务器推送事件的方式不断把增量数据推给前端。前端拿到的是一个个data: {...}格式的文本块需要自己解析拼接。在 lab 的代码里它用一个ReadableStream配合TextDecoder逐块读取响应const response await fetch(url, options); const reader response.body.getReader(); const decoder new TextDecoder(); while (true) { const { done, value } await reader.read(); if (done) break; const chunk decoder.decode(value, { stream: true }); // 解析 SSE 数据提取增量内容 const delta parseSSE(chunk); updateMessageContent(delta); }这里有一个很重要的细节decoder.decode必须传{ stream: true }否则多字节字符比如中文在分片边界处可能被切断导致最后拼出来的文本出现乱码。这个坑我在其他项目里踩过很多次好在 lab 的处理是到位的。另外流式输出期间界面上的“停止生成”按钮对应的是reader.cancel()方法。点了停止之后前端会主动断开读取流模型服务端感知到连接断开就不再继续生成了。这个逻辑虽然简单但用户体验上很关键——跑偏了想让它闭嘴结果还得默默等它说完的感觉太难受了。3.2 本地数据存储设计会话、消息、配置怎么存纯前端应用的数据存储方案基本就那么几种localStorage、sessionStorage、IndexedDB。lab 的做法是“分情况使用”。会话列表和设置项这类轻量数据用的是 localStorage因为它同步读取、API 简单、写起来方便适合保存用户偏好。而每条会话的具体消息记录如果用 localStorage 来存存到几兆就会出现性能问题所以它用的是 IndexedDB。IndexedDB 是浏览器内置的异步数据库可以存储大量结构化数据非常适合消息这种持续追加的数据。你可以打开浏览器开发者工具的 Application 面板能看到 IndexedDB 里建了几个对象仓库object store分别存会话元数据、消息列表、配置文件。这种拆分的思路很清晰会话列表需要快速读取所以走 localStorage消息记录数据量大所以走 IndexedDB配置跟隐私相关所以单独存。有一点要提醒你既然数据都存在浏览器里那么换浏览器、换电脑或者清了站点数据对话记录就会全部消失。如果你有长期保存对话的需求labs 一般在设置里提供了导出/导入功能可以定期把数据备份成一个 JSON 文件。我自己的习惯是每周导出一份备份到网盘或移动硬盘这样换电脑迁移也很轻松。3.3 前端直连 API 与数据安全边界刚才说了lab 是前端直连各家模型 APIAPI Key 会暴露在浏览器请求里。很多人第一次听到这个会有点慌这里我想把安全边界说得清楚一点。如果你把 lab 部署在公网让别人也能访问你的这个工作台那别人打开页面就能在设置里看到你配置的 API Key。这是非常危险的事情等于把你账户的钥匙插在门锁上还给每个路过的人发了张门禁卡。所以使用场景一定要控制在自己电脑或信任的内网环境。但如果你是自己在电脑上本地跑安全性其实还好。浏览器请求虽然能通过开发者工具看到 Key但这个 Key 只会暴露在你自己面前跟把 Key 存在本地配置文件里没有本质区别。我自己的使用习惯是本机开发环境用真实 Key部署到局域网或测试环境用代理方式后面会讲到部署到公网就直接换一个受限 Key 或者干脆不部署。对于想部署到局域网多设备访问的场景lab 也支持通过配置环境变量来开启一个简单的静态服务同时建议前面挂一层 Caddy 或 Nginx加上 Basic Auth 做基础访问控制。这样虽然依然是前端直连 API但至少不会让所有人都能打开页面。4. 避坑指南常见问题与排查实录4.1 跨域CORS问题排查这是纯前端调用第三方 API 时最恶心的问题。你在浏览器里 F12 打开控制台看到一个大大的红色报错No Access-Control-Allow-Origin header is present基本就是撞上了 CORS 的墙。原因很简单浏览器出于安全策略不允许一个源比如你的 lab 运行在 localhost:5173随便向另一个源比如https://api.deepseek.com发请求除非对方服务器明确允许。DeepSeek、Qwen、Claude 官方 API 都允许了浏览器跨域调用所以一般不会出问题容易出问题的是自建的 Ollama 或其他私有网关默认没有返回 CORS 响应头。排查思路按顺序来先看服务端是否配置了允许的来源。如果是 Ollama按前面说的设置OLLAMA_ORIGINS环境变量并重启服务如果是自建网关检查反向代理配置里有没有加add_header Access-Control-Allow-Origin。实在搞不定就开一个无代理的临时浏览器会话做验证把问题定位到“到底是浏览器拦截还是服务端就不能访问”。4.2 API Key 与模型名踩坑配置没问题、网络也通但对话框里模型就是不回话或者报一个 400 错误先别急着怀疑项目有 bug大概率是 Key 或模型名不对。首先是 API Key 的格式。DeepSeek 的 Key 一般以sk-开头但有些平台的 Key 前缀是Bearer或随机字符串确认一下你有没有把 Key 值完整复制进去不要带多余的空格和换行。其次是模型 ID。很多平台在网页控制台里显示的是“产品名”但 API 请求里要求的是“模型标识符”。比如 DeepSeek 官网控制台会写“DeepSeek Chat”但 API 的模型参数必须是deepseek-chat阿里百炼控制台里的“通义千问-Turbo”API 里就是qwen-turbo。模型 ID 填错服务端返回的通常是invalid request或model not found。另外注意区分“模型上下文长度”和“API 参数名”。如果你的请求里带了 lab 默认传给 OpenAI 系列的参数比如max_tokens、temperature换到其他协议时有些参数名不通用可能出现报错。遇到这种问题去设置页面检查一下当前会话使用的模型对应的是什么 API 类型不要张冠李戴。4.3 流式中断、空回复等疑难杂症我在重度使用过程中遇到过几个比较隐蔽的问题单独拎出来讲。第一个是流式输出到一半突然中断。这种情况在 DeepSeek 和 Claude 上偶尔出现多半是长响应时服务器端连接被重置或者网络环境不稳定。lab 里的处理方式是比较保守的——命令中断则保留已生成的部分不覆盖不重试。这其实是好事至少不会把你已经看到的内容清掉。如果想避免中断可以检查网络代理设置有些拦截软件会把 SSE 长连接掐断需要把 API 域名加入白名单。第二个是模型回了一个空回复页面看起来像卡住了。这通常是返回的内容被过滤了或者请求参数里有个别字段服务端不识别服务端返回了空内容但状态码是 200。遇到这种情况建议开一个浏览器控制台手动在 Network 面板里看响应体能直接看到服务端到底返回了什么。第三个是 Ollama 拉取模型超时。国内网络下ollama pull经常卡在“等待中”这是因为模型文件托管在海外 CDN。解决办法是设置国内模型镜像地址Ollama 的OLLAMA_BASE_URL或OLLAMA_HOST跟拉取模型是两码事真正生效的是 registry 配置可以通过设置环境变量来切到国内可用的镜像源。具体方法搜索“ollama 国内镜像”就能找到我这里不展开背具体地址原则就是换源后重新 pull速度能快不少。4.4 部署到线上 / 局域网使用的注意事项如果你确实想把 lab 分享给朋友或部署到局域网服务器有几个事情一定要处理好。第一API Key 不能裸奔在公共页面。这时候前端直连就不合适了Lab 目前也支持一种“代理模式”——你可以在本地环境里配一个小型代理服务比如 Cloudflare Worker 或 Vercel Serverless Function前端把请求发给代理代理再去调模型 APIKey 放在代理的环境变量里。这样“纯前端”变成了“前端 一个轻量代理”但代码逻辑基本不用改只是把 API 地址替换成代理地址。从定位上说它依然比传统后端方案轻得多没有数据库没有状态属于“半后端”的妥协方案。第二启用 HTTPS。如果你的页面部署在一个 HTTPS 域名上但调用的模型 API 是 HTTP 或证书不受信任的地址浏览器会直接拦截所有请求。局域网内自签名证书也可能导致混入“不安全内容”而被切断需要格外注意。第三控制访问权限。最简单有效的方式是在 Nginx 层加上 Basic Auth让访问者先输入密码才能打开页面。Nginx 配置里加一段 auth_basic 指令就行几十秒搞定但能拦住绝大多数好奇的人。5. 一点个人经验与扩展想法这个项目我已经用了两个多月DAU 是自己体验一直很稳定。我最常用的组合是日常闲聊用 Ollama 上的 qwen2.5:14b写代码和技术问题切到 DeepSeek偶尔需要长篇写作再调到 Claude。因为会话之间切换模型非常快我没事就喜欢针对同一个 prompt 让不同模型轮流回答一遍对比风格差异这个用法在传统聊天工具里很难实现得这么轻快。最后分享一个小技巧因为是纯前端应用你可以把构建出来的 dist 目录直接放到 U 盘或者移动硬盘里随身带着当一个“便携式 AI 工作台”。随便找一台有浏览器的电脑把 dist 目录用 Python 的python -m http.server 8080或随便哪个静态文件服务器一开打开页面就是一个完整的大模型工作台。它不会在电脑上留下痕迹不会装任何软件非常适合出差、共享电脑等场景。如果你想要更进一步这个项目还可以扩展成一个家庭实验室的入口在设置里把 Ollama 指向一台专门的推理服务器把 lab 部署到家庭内网的主机上再接上内网 DNS全家所有人都可以访问一个“私有 AI 助手”。我目前就在往这个方向折腾等把权限和模型调度理顺了应该会很有意思。不管是想找个趁手的模型聊天工具还是想研究前端与大模型 API 的交互细节lab 都值得你花一个下午试试。