
能自己托管、能塞进手机浏览器、又能对外提供 API 的免费 AI 聊天引擎其实比想象中更难得。这次完成的手机端就是把原本只能在电脑上操作的聊天引擎重新包了一层适合移动端的 Web 界面同一套后端手机和电脑都能访问多轮对话、历史会话、批量任务都可以在手机上发起。如果你正在找一个“免费 手机端可访问 可扩展接口”的聊天引擎方案这篇可以直接收藏。这个项目的核心能力可以归纳成四个点免费开源不依赖商业平台账号可以自己部署。手机端不是简单“缩小页面”而是专门做过触屏、安全区、虚拟键盘和移动端滚动布局适配。支持多轮对话和会话持久化手机端刷新页面后能恢复历史消息。后端可以当 API 服务用批量对话任务也能通过接口触发适合做产品原型或个人工具。这篇文章会带你完整过一遍手机端 AI 聊天引擎的技术路径包括核心能力、部署启动方式、手机端适配关键技术、多轮对话与批量任务接口调用、资源占用观察方法以及常见问题的排查清单。1. 核心能力速览能力项说明项目类型免费 AI 聊天引擎 手机端 Web 界面核心功能多轮对话、会话持久化、移动端访问、API 接入、批量对话任务手机端形态移动浏览器直接访问支持 PWA 方式添加到桌面后端能力对话服务、会话管理、批量任务队列、接口服务通信方式HTTP/HTTPS 接口调用可通过局域网或公网访问硬件门槛纯 API 模式对机器要求很低若本地加载模型需按模型尺寸单独评估启动方式命令行启动后端服务手机端通过 IP 地址访问是否支持批量任务支持可以按 prompt 列表排队执行是否提供接口 API聊天、会话、批量任务都可以通过 HTTP 接口调用适合场景自建聊天入口、移动端产品原型、私有知识库助手、自动化测试从上面的表格能看出来这个项目的定位不是“重模型”而是“轻入口”。如果你已经有可用的模型 API手机端就是一个完整的前端壳如果你想完全本地化只需要把模型推理服务接到后端再通过手机端访问。2. 手机端 AI 聊天引擎适用场景与使用边界2.1 适合谁用第一类是想给自己做一个专用聊天工具的开发者。很多 AI 产品在电脑端用起来很顺手但一到手机上就要开 App、登录账号数据和会话还被平台管着。自建手机端之后私有数据、自定义系统提示词、批量测试脚本都可以完全掌控。第二类是正在做产品原型的人。不需要急着开发原生 App直接用手机端 Web 界面验证对话流程、交互逻辑和接口稳定性成本比原生客户端低得多。第三类是自动化任务使用者。手机端只是入口之一背后真正有价值的是聊天接口和批量任务队列。比如批量生成文案、批量质检对话、压力测试都可以通过接口触发。2.2 不适合什么场景如果要求零维护、开箱即用这个方案并不合适。自建服务需要你自己管理依赖、模型或 API Key、端口、证书和备份。如果要求大规模公网商用也不能直接裸奔。至少要对接口做身份认证、限流、内容过滤和操作审计否则很容易被刷接口或产生违规内容。2.3 使用边界与合规要求这属于通用开发实践凡是涉及对话生成、隐私数据、用户输入的内容都需要注意三条红线用户对话内容必须加密传输不能在日志里明文保存敏感信息。如果手机端素材包含人脸、声音、商标、版权文本等内容使用前必须确认授权。对话结果生成后发布或商用前要做人工复核不能直接无审核对外输出。3. 整体架构与手机端关键技术点3.1 架构分层从实现角度看整个系统可以分成三层模型接入层负责对接大模型 API 或本地推理服务统一输入输出格式。后端服务层提供对话接口、会话管理、批量任务队列、历史记录存储。手机端展示层负责移动端聊天界面、会话列表、设置页面、PWA 离线能力。手机端和后端之间走 HTTP 接口。手机端没有直接调用模型而是把用户输入发到后端由后端决定调用哪个模型、是否启用上下文、是否过滤内容。这样做的好处是以后换模型服务时手机端代码不用动。3.2 移动端适配的几个硬指标这次做手机端真正花时间的地方不是对话气泡而是移动端的几个基础问题viewport 必须正确设置否则手机浏览器会按 980px 宽度渲染页面。输入框不能被手机虚拟键盘遮挡。聊天列表滚动要顺滑不能出现整页缩放。需要处理刘海屏、挖孔屏的安全区域。PWA 添加到桌面后状态栏颜色和启动画面要协调。下面是一段基础移动端 HTML 模板适配了安全区域和禁止双击缩放!DOCTYPE html html langzh-CN head meta charsetUTF-8 meta nameviewport contentwidthdevice-width, initial-scale1.0, maximum-scale1.0, user-scalableno, viewport-fitcover meta nametheme-color content#1f2937 meta nameapple-mobile-web-app-capable contentyes meta nameapple-mobile-web-app-status-bar-style contentblack-translucent titleAI Chat Mobile/title style html, body { margin: 0; height: 100%; background: #111827; color: #f9fafb; font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, sans-serif; } #app { height: 100vh; height: 100dvh; padding-top: env(safe-area-inset-top); padding-bottom: env(safe-area-inset-bottom); display: flex; flex-direction: column; } .message-list { flex: 1; overflow-y: auto; -webkit-overflow-scrolling: touch; padding: 16px; overscroll-behavior: contain; } .input-bar { display: flex; gap: 8px; padding: 12px; padding-bottom: calc(12px env(safe-area-inset-bottom)); border-top: 1px solid rgba(255, 255, 255, 0.1); } .input-bar textarea { flex: 1; resize: none; border: none; outline: none; background: rgba(255, 255, 255, 0.08); color: #fff; border-radius: 12px; padding: 12px; font-size: 16px; min-height: 44px; max-height: 120px; } /style /head body div idapp div idmessages classmessage-list/div div classinput-bar textarea idinput rows1 placeholder输入消息/textarea button idsend发送/button /div /div /body /html上面这段代码里重点不是样式而是三个细节viewport-fitcover配合env(safe-area-inset-top/bottom)解决刘海屏和底部横条遮挡问题。height: 100dvh适配手机浏览器地址栏收起和展开时的高度变化。-webkit-overflow-scrolling: touch保证 iOS 上长列表滚动位置正确。如果你在移动端开发时遇到“手机端页面被放大缩小”“状态栏颜色不对”“输入框被键盘顶上去”这类问题通常就是上面几个属性没处理好。4. 环境准备与前置条件手机端只是界面真正要跑起来的是后端服务。下面是一份通用环境检查清单具体版本按实际项目调整。4.1 软件环境依赖项建议要求说明操作系统Windows 10/11、Ubuntu 20.04、macOS 12跨平台但推荐在 Linux 服务器上长期运行Python3.10多数聊天后端框架的通用要求Node.js18如果手机端需要单独构建打包包管理工具pip / npm分别管理 Python 依赖和前端依赖数据库SQLite 起步生产建议 PostgreSQL用于保存会话和消息记录4.2 硬件环境如果后端只转发第三方模型 API普通 4 核 8G 内存的机器就够CPU 占用很低。如果要在本地加载开源对话模型就要根据模型体积准备显存或内存。比如轻量对话模型在 6G 显存上可以运行但具体占用需要按实际模型测试。部署前建议先用小模型跑通再逐步切换到大模型。4.3 目录规划建议建议项目按下面结构组织ai-chat-engine/ ├── backend/ │ ├── app.py │ ├── requirements.txt │ └── config.py ├── mobile/ │ ├── index.html │ ├── manifest.json │ └── sw.js ├── data/ │ ├── sessions.db │ └── logs/ ├── scripts/ │ ├── batch_chat.py │ └── export_history.py └── models/ └── README.md把后端、手机端、数据、脚本、模型分开后续做备份、更新、批量任务时不会互相干扰。5. 手机端部署与一键启动方式这个项目不需要太复杂的启动流程本质上就是“启动后端服务 手机访问地址”。5.1 后端启动示例先进入后端目录安装依赖再启动服务cd backend pip install -r requirements.txt # 启动服务监听局域网地址让手机端可以访问 python app.py --host 0.0.0.0 --port 7860启动后服务默认会在http://0.0.0.0:7860上运行。电脑端打开http://127.0.0.1:7860验证服务正常。5.2 手机端访问方式手机和电脑连接同一个局域网在手机浏览器输入电脑的局域网 IP比如http://192.168.1.100:7860手机端会加载聊天界面。如果你用的是 Windows查看局域网 IP 可以用ipconfig如果你用的是 Linux可以用hostname -I这里有一个容易踩的坑手机访问时不要把地址填成127.0.0.1因为手机上的 127.0.0.1 指向手机自己而不是电脑。5.3 通过 PWA 添加到手机桌面如果手机端提供了manifest.json和sw.js就可以用 PWA 方式把聊天页面“安装”到手机桌面。一个简单的manifest.json示例如下{ name: AI Chat Engine, short_name: AI Chat, start_url: /, display: standalone, background_color: #111827, theme_color: #1f2937, icons: [ { src: /icons/icon-192.png, sizes: 192x192, type: image/png }, { src: /icons/icon-512.png, sizes: 512x512, type: image/png } ] }在 HTML 的head里引入link relmanifest href/manifest.json用 Chrome 或 Safari 打开页面后菜单里会出现“添加到主屏幕”或“安装应用”选项。PWA 的优势是打开后没有浏览器地址栏全屏体验更像原生 App。5.4 HTTPS 与远程访问如果手机不在局域网想在外面访问不建议直接把服务端口暴露到公网。稳妥做法是使用反向代理加 HTTPS。Nginx 反向代理配置示例server { listen 443 ssl; server_name chat.example.com; ssl_certificate /etc/nginx/ssl/chat.pem; ssl_certificate_key /etc/nginx/ssl/chat.key; location / { proxy_pass http://127.0.0.1:7860; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-Proto $scheme; } }这里要注意配置 HTTPS 之前先确认手机端对话内容里有敏感信息。没有 HTTPS 的情况下手机和服务器之间传输的数据是明文存在被中间人截获的风险。6. 手机端功能测试与效果验证部署完成后重点测试五个维度多轮对话、手机端界面适配、会话持久化、接口稳定性和批量任务。6.1 多轮对话测试测试目标确认后端能维护上下文而不是每次请求都当成新对话。操作步骤手机端输入第一句“你好我叫小明。”等待返回。继续输入“我叫什么名字”判断返回是否包含“小明”。如果第二次回答正确说明上下文传递正常。如果回答“我不知道你的名字”要先检查前端有没有传session_id或conversation_id。后端接口设计参考{ session_id: abc-123, messages: [ { role: user, content: 你好我叫小明。 }, { role: assistant, content: 你好小明有什么可以帮你 }, { role: user, content: 我叫什么名字 } ] }前端每次发送新消息时把所有历史消息一起提交由后端拼上下文。这种方式简单但会越来越长后续可以改成后端只保存最近 N 条消息。6.2 手机端界面适配测试测试目标确认聊天页面在不同尺寸手机上都不变形、不误触、不遮挡。建议按下面清单测试测试项预期结果打开页面时是否整页缩小不能出现页面缩成手机宽度一列的情况点输入框时虚拟键盘是否遮挡当前输入框应自动滚动到可视区域iOS 底部横条是否遮挡发送按钮发送按钮要上移 safe-area 距离从桌面 PWA 图标打开无浏览器地址栏状态栏颜色正常快速上下滑动长对话列表流畅不能白屏或跳动手机横竖屏切换布局不崩溃输入框不脱离底部这些测试看起来不涉及 AI但在实际使用中一个小问题就会让用户放弃整个工具。6.3 会话持久化测试测试目标聊天记录刷新后不丢。操作步骤手机端进入会话发送几条消息。刷新页面。检查会话列表里是否有历史记录。点击历史会话确认消息完整。如果刷新后记录丢失优先检查后端是否保存了消息前端是否在初始化时拉取会话列表。不要只在 localStorage 里存聊天记录那样换设备或清缓存就丢了。6.4 接口调用测试手机端页面只是接口的调用者。接口才是真正可以复用的部分。用 Python 或 curl 直接测试聊天接口能确认问题出在前端还是后端。import requests url http://127.0.0.1:7860/api/chat payload { session_id: test-session-001, message: 用一句话介绍你自己 } response requests.post(url, jsonpayload, timeout60) print(response.status_code) print(response.json())正常的返回结构可以设计成{ session_id: test-session-001, reply: 我是一个可以私有化部署的 AI 聊天助手。, created_at: 2025-01-01T12:00:00Z }这里需要注意接口返回的字段名要以实际项目为准。如果没有reply字段可能叫answer、text或content先看后端接口文档。6.5 批量任务测试批量任务的价值在于不需要在手机端一条条手动输入。只要后端提供任务接口手机端可以上传一批 prompt然后定时查询进度。测试思路准备 5 条 prompt。批量提交任务。轮询任务状态。任务完成后拉取结果。如果批量任务卡住优先检查任务队列是否启动、有没有异常日志、是不是并发数太高导致显存或内存被打满。7. 批量对话任务与接口 API 实现思路7.1 批量任务设计批量任务和普通聊天请求的区别在于“异步”。普通聊天是用户发一条后端回一条立即返回。批量任务则是先提交任务列表后端排队执行前端或脚本轮询进度。一个简单的任务状态流程待执行 - 执行中 - 完成 / 失败任务表可以设计成task_id prompt_text status result created_at updated_at批量任务接口可以这样设计接口作用POST /api/batch/create提交批量 prompt 列表GET /api/batch/status查询任务进度GET /api/batch/result获取单条结果GET /api/batch/export导出全部结果7.2 批量任务调用示例下面是一个 Python 批量提交示例import requests import csv import time base_url http://127.0.0.1:7860 prompts [ 给产品写一句广告语, 给这篇文章写一个摘要, 把这句话翻译成英文, 模拟用户反馈问题并生成回复, 生成 5 个短视频标题 ] # 1. 创建批量任务 create_resp requests.post( f{base_url}/api/batch/create, json{prompts: prompts}, timeout30 ) task_id create_resp.json().get(task_id) print(task_id:, task_id) # 2. 轮询状态 while True: status_resp requests.get( f{base_url}/api/batch/status, params{task_id: task_id}, timeout30 ) data status_resp.json() print(status:, data[status], progress:, data[progress]) if data[status] in (completed, failed): break time.sleep(2) # 3. 导出结果 if data[status] completed: result_resp requests.get( f{base_url}/api/batch/export, params{task_id: task_id}, timeout60 ) items result_resp.json()[items] with open(batch_result.csv, w, newline, encodingutf-8) as f: writer csv.writer(f) writer.writerow([index, prompt, result]) for item in items: writer.writerow([item[index], item[prompt], item[result]]) print(结果已导出到 batch_result.csv)批量任务要注意两点任务列表不能无限往内存里塞建议先读 CSV 或 JSONL 文件。任务失败后要记录错误信息并提供重跑机制不能卡在“执行中”状态。7.3 在手机端发起批量任务手机端不需要长驻后台执行任务只需要做到“提交任务 - 显示进度 - 查看结果”。所以手机端更适合做控制器而不是执行器。手机端界面可以增加一个“批量任务”入口用户上传 CSV 文件前端解析出 prompt 列表调用create接口然后每隔几秒查询状态并显示进度条。任务结束后把结果导出为 CSV 下载到手机。这也回应了手机端开发中常见的“开发 app 时 CLI 与手机端版本不同”问题手机端只负责任务输入和展示实际逻辑统一放在后端服务里可以避免各个端逻辑不一致。8. 资源占用与性能观察方法8.1 观察哪些资源运行手机端聊天引擎时主要看四个指标指标观察方法重点CPU 占用top/ 任务管理器请求量增大时是否飙升内存占用free -h/ 任务管理器会话是否被不断缓存磁盘占用查看 data 目录日志和数据库是否增长过快网络带宽iftop/ 路由器管理页手机端是否频繁请求大体积消息8.2 降低资源占用的手段会话历史只保留最近 20 条不无限拼接。批量任务设置最大并发数比如同时最多执行 2 个。聊天接口返回结果后立即释放引用避免占用内存。日志按天切分避免单个日志文件无限增长。PWA 离线缓存只缓存静态资源不缓存对话数据。8.3 手机端能耗与流量手机端本身不做推理能耗和流量消耗主要在页面渲染和接口请求。如果要降低流量可以在后端开启流式输出而不是等整段回答生成完一次性返回。流式输出时手机端逐字显示体感也更快。如果接口返回速度比较慢手机端最好加 loading 状态和超时提示。常见做法是把请求超时时间设置到 60 秒以上并在界面显示“正在生成中”。9. 常见问题与排查方法手机端聊天引擎踩坑最多的不是模型而是网络、适配和缓存。问题现象可能原因排查方式解决方案手机浏览器打不开电脑服务地址未监听 0.0.0.0或防火墙拦截检查启动日志和防火墙后端绑定0.0.0.0放行对应端口页面打开后整体缩小缺少 viewport 或缩放冲突查看 HTML head 是否正确显式设置widthdevice-width, initial-scale1发送按钮被虚拟键盘遮挡未适配动态视口高度在浏览器调试台查看元素位置使用100dvh并监听visualViewport变化会话刷新后丢失后端未持久化或前端只存 localStorage查看数据库表是否有记录后端保存消息前端启动时拉取历史批量任务一直停在执行中并发数过高或异常未捕获查看后端日志增加任务超时机制和失败重试PWA 图标打开后白屏Service Worker 缓存了旧版本清缓存并强制刷新更新 SW 时使用skipWaiting端口被占用上一次服务未退出使用lsof -i:7860或netstat -ano换端口或结束残留进程显存不足本地模型体积超过显存查看 CUDA 报错信息减小模型、降低上下文长度、使用 CPU 模式接口请求超时模型响应过慢或网络中断查看后端时间戳和错误日志增加超时时间使用流式接口手机端下载 PDF 或导出 CSV 失败后端未设置正确的下载响应头用 Postman 模拟请求设置Content-Disposition并确认 MIME 类型9.1 启动后页面打不开优先看后端日志。大多数情况下是端口被占用或监听地址错误。# 查看端口占用 lsof -i:7860如果端口被占用就换一个启动端口例如python app.py --host 0.0.0.0 --port 7861同时确认防火墙是否放行端口。Windows 用户在首次运行时会被弹窗询问是否允许访问网络不要直接点取消。9.2 手机端页面滑动卡顿先检查消息列表是不是有大量图片或高精度头像。聊天列表建议用纯文本和简单背景色。列表如果上千条消息要做虚拟滚动或分页加载不能一次性渲染全部历史消息。9.3 状态栏颜色不一致PWA 模式下theme_color决定状态栏颜色。如果设置了apple-mobile-web-app-status-bar-styleiOS 上的表现会不同。建议先用真机测试不要只看模拟器。10. 最佳实践与合规建议10.1 先小规模验证再批量执行第一次部署时先用最简单的配置跑通一个“你好”请求确认接口、页面和存储都正常再上批量任务。不要把批量任务和真实用户请求混在同一个队列否则一个卡住的任务会把后面的请求全部堵住。10.2 保留一套最小可运行配置项目目录里建议保留一份requirements.txt、一份config.example.yaml和一页说明文档。这样换电脑部署时不用靠记忆恢复环境。配置示例server: host: 0.0.0.0 port: 7860 debug: false chat: session_max_messages: 20 default_timeout: 60 batch: max_concurrency: 2 retry_limit: 3 storage: database: data/sessions.db log_dir: data/logs10.3 接口服务要做权限控制手机端页面可以通过局域网直接访问但接口不能随便让任何人调用。建议在服务前加一层访问令牌import requests url http://127.0.0.1:7860/api/chat headers { Authorization: Bearer your-access-token } payload { session_id: app-test-001, message: 你好 } response requests.post(url, jsonpayload, headersheaders, timeout60) print(response.json())后端校验Authorization头。没有令牌的请求直接返回 401。这样即使端口被扫到接口也不会被滥用。10.4 数据备份与清理聊天记录属于重要数据建议每天备份数据库文件。同时设置日志轮转避免日志文件把磁盘占满。如果清理完日志后发现问题变少说明之前的问题可能和磁盘空间不足有关。10.5 合规使用手机端 AI 聊天引擎在真实场景中使用时需要明确告知用户对话内容会被记录并用于生成回复。如果产品面向公众必须在显著位置展示隐私说明。对于生成式内容建议增加关键词过滤和人工抽检机制。涉及第三方的文字、图片、声音、人脸等素材使用前必须确认授权不能在未授权的情况下生成或传播相关内容。11. 总结与下一步这个免费 AI 聊天引擎最值得尝试的地方是把“后端对话能力”和“手机端操作入口”完整串了起来。你不需要等一个现成的 App只需要启动一个后端服务手机扫码或输入 IP 就能开始聊天而且会话记录、批量任务、API 接口都可以在同一个项目里复用。最先要验证的功能很简单多轮对话是否连贯手机端刷新后历史消息还在不在。这两个功能通过之后整个引擎的骨架就已经稳定了。最容易踩的坑有三个手机端想通过127.0.0.1访问电脑服务、页面缺少 viewport 导致整体缩小、批量任务没有超时机制卡在“执行中”。后面可以继续扩展的方向包括多用户登录和会话隔离、把普通聊天接口升级为流式输出、把批量任务导出格式改成 JSONL、增加手机端通知推送以及把静态文件放到 Nginx 或 CDN 上提升访问速度。如果你正在规划自己的 AI 聊天工具先把手机端跑通再用接口接业务这个路线会比直接开发原生 App 更快验证想法。建议收藏备用动手部署时直接照着操作即可。