moooff/HermitUI

GitHub: moooff/HermitUI

一个零依赖的单文件本地 AI 聊天 Web 界面,专为隐私保护和受限环境设计,可连接任意 OpenAI 兼容的推理端点。

Stars: 2 | Forks: 1

hermitui-logo

A lightweight, modern, and ephemeral single-page web interface for local AI models.

License: AGPL v3 Vanilla JS Zero Install

🌐 Online DemoUse CasesFeaturesQuick StartTroubleshootingBuilt WithArchitectureRoadmap

![HermitUI 截图](https://raw.githubusercontent.com/moooff/HermitUI/main/docs/screenshot.png)
Try the Live Online Demo

Works entirely in your browser. Just connect it to your local AI server!

HermitUI 是一个高度响应式的 Web 界面,专为与本地 AI 模型交互而设计。它以**单个、独立的 `.html` 文件**形式发布,仅使用纯 HTML、CSS 和 JavaScript 构建。在开发过程中,源代码被拆分为 `src/index.html`、`src/style.css` 和 `src/script.js` 以提高可维护性,并由 `build.py` 将它们组装成独立的单文件交付物。 无需后端,无需安装——只需在浏览器中打开该文件即可开始聊天! ## 🎯 理想使用场景 * **严格受控环境:** 非常适合限制软件安装的企业或政府网络,但可以访问安全的本地或远程推理 endpoint。 * **气隙系统:** 可以通过 USB 轻松分发,并在只能访问局域网 LLM 服务器的未连接互联网的系统上运行。 * **临时自助服务终端和共享终端:** 不保存任何聊天记录,从而确保隐私,使其对于公共或共享工作站(尤其是共享办公桌环境)非常安全。 ## ✨ 功能 * **📦 零依赖设置:** 默认的 `index.html` 文件将所有外部库(Marked.js、DOMPurify、Highlight.js)和 Inter 字体直接打包在其中。用户无需安装或构建。(使用 CDN 的开发者版本可在 `dist/hermit-ui-cdn.html` 中找到)。 * **🔒 隐私优先且会话即逝:** 在设计上,没有本地保存(`localStorage`、`IndexedDB` 或 cookies),也没有跨会话存储的对话历史记录。您的数据完全是临时的。 * **🧠 思考模型支持:** 内置解析器可以完美地格式化由高级推理模型原生流式传输的 ``、`` 和 `` 标签。 * **🖼️ 图像与视觉支持:** 直接将图像上传、拖放或粘贴(Ctrl+V)到输入框中,以供支持视觉的模型使用。根据 OpenAI schema,附件作为 `image_url` 内容发送,并具有自动的视觉模型检测功能。 * **🎭 人格预设:** 通过下拉菜单即时切换预设的 system prompt,以立即重塑助手的行为。 * **📎 上下文附件:** 拖放或上传文本文件,将其内容作为上下文直接注入到您的 prompt 中。 * **✏️ 编辑与重新生成:** 编辑任何之前的消息或重新生成助手的最后一次回复,而无需重新开始对话。 * **🎛️ 高级采样控制:** 在“设置”中的可折叠面板内调节 `temperature`、`max_tokens`、`top_p`、`presence_penalty`、`frequency_penalty` 和 `seed`。仅在设置时发送参数,从而保持 payload 与最小化的后端兼容。 * **🎨 现代 UI/UX:** 干净、响应式的设计,具有流畅的微动画、用于轻松主题化的全面 CSS 变量、语法高亮和高级的毛玻璃效果。 * **⚡ 实时流式传输:** 实时观看生成的回复,体验堪比 ChatGPT。 * **📊 实时性能统计:** 内置仪表板,用于监控 Prompt Tokens、Completion Tokens、生成速度(Tokens/秒)和总持续时间。 * **📝 Markdown 与代码支持:** 渲染丰富的 Markdown,并为代码块提供一键“复制”按钮。 * **🧮 数学渲染:** LaTeX 数学公式(`$…$`、`$$…$$`、`\(…\)`、`\[…\]`)通过 KaTeX 渲染为原生浏览器 MathML —— 无需 webfonts 或额外的 CSS,并且支持在流式传输过程中和完全离线状态下工作。像“$5 and $10”这样的货币金额将保持原样。 * **📈 Mermaid 图表:** 一旦消息完成流式传输,` ```mermaid ` 代码块就会变成渲染的图表(流程图、时序图、饼图等)。Mermaid 引擎以 gzip 压缩形式嵌入到单文件构建中,并且仅在图表首次实际出现时才解压,因此对于没有图表的聊天没有任何成本。 * **💾 聊天导出:** 轻松将您的整个对话历史记录下载为格式化的 Markdown 文件以供保存。 * **⚙️ 可自定义设置:** 通过页面上的设置覆盖层快速调整 API URL、模型名称、API Key 和 System Prompt。 ## 🚀 快速开始 1. **启动您的本地 AI 服务器:** 确保您正在运行提供与 OpenAI 兼容的 API endpoint 的本地 AI 服务器。 * *示例:* [LM Studio](https://lmstudio.ai/)、[Ollama](https://ollama.com/)(具有 OpenAI 兼容性)或 [vLLM](https://github.com/vllm-project/vllm)。 * *默认的预期 endpoint:* `http://localhost:1234/v1/chat/completions`(LM Studio 默认值)。 2. **打开 HermitUI:** 只需双击 `index.html` 文件,即可在任何现代 Web 浏览器中打开它。 3. **配置(如果需要):** 点击右上角的 **⚙️ 设置** 按钮,更新 API URL、模型名称或默认的 System Prompt,以匹配您的本地设置。 ## 💡 设置示例 以下是基于流行的本地 AI 服务器的几个快速配置示例: ### 使用 LM Studio(默认) 1. 启动 LM Studio 并启动 **Local Server**。 2. **API URL:** `http://localhost:1234/v1/chat/completions` 3. **模型名称:** 留空,或设置为您加载的特定模型标识符。 4. *提示:* 确保在 LM Studio 设置中启用了 CORS。 ### 使用 Ollama 1. 从终端启动您的 Ollama 服务器,确保启用 CORS: OLLAMA_ORIGINS="*" ollama serve 2. **API URL:** `http://localhost:11434/v1/chat/completions` 3. **模型名称:** 您拉取的模型的名称(例如 `llama3`、`mistral`、`deepseek-coder`)。 ### 使用 vLLM 1. 使用兼容 OpenAI 的 endpoint 启动您的 vLLM 服务器: python -m vllm.entrypoints.openai.api_server --model meta-llama/Llama-2-7b-chat-hf --cors-allowed-origins "*" 2. **API URL:** `http://localhost:8000/v1/chat/completions` 3. **模型名称:** 您在命令中指定的模型名称(例如 `meta-llama/Llama-2-7b-chat-hf`)。 ### 使用云端模型(OpenRouter、OpenAI、Groq 等) 您不仅限于本地模型!HermitUI 可与任何提供与 OpenAI 兼容的 API endpoint 的云服务提供商完美配合。 1. **API URL:** 提供商的聊天补全 endpoint(例如 `https://openrouter.ai/api/v1/chat/completions` 或 `https://api.openai.com/v1/chat/completions`)。 2. **模型名称:** 您想要使用的特定模型(例如 `anthropic/claude-3.5-sonnet`、`gpt-4o`)。 3. **API Key:** 在设置菜单中输入您的提供商的 API key。 ## 🔧 故障排除(CORS) 如果 HermitUI 无法连接到您的本地 AI 服务器(例如,收到“网络错误”),这很可能是由于 **CORS(跨域资源共享)** 限制。因为 HermitUI 作为本地文件(`file://`)运行,现代浏览器会阻止其向 `http://localhost` 发出的请求,除非服务器明确允许。 **如何修复:** * **LM Studio:** 转到“Local Server”选项卡,找到“CORS”开关,并确保其处于 **开启** 状态。 * **Ollama:** 您必须在启动 Ollama 之前设置 `OLLAMA_ORIGINS` 环境变量。例如:`OLLAMA_ORIGINS="*" ollama serve`。 * **vLLM:** 使用 `--cors-allowed-origins` 标志启动您的服务器。例如:`--cors-allowed-origins "*"`。 ## 🏗️ 架构与理念 HermitUI 实施了严格的架构约束,以保持轻量级和易访问性: * **单文件约束:** 最终产品必须始终是单个独立的 `.html` 文件。`src/` 目录仅作为蓝图;即使在开发过程中将 CSS 或 JS 重构为单独的文件,`dist/` 目录和根目录 `index.html` 中的最终输出也将始终保持为完全集成的单文件。 * **在线版本:** 您可以尝试托管在 GitHub Pages 上的实时版本:[https://moooff.github.io/HermitUI](https://moooff.github.io/HermitUI) * **仅限原生:** 没有 React、Vue、Angular 或复杂的前端框架。 * **无构建工具:** 没有 `package.json`、`npm`、Webpack 或 Vite。 * **无 CSS 框架:** 纯原生 CSS,没有 Tailwind 或 Bootstrap。 * **安全性:** 所有渲染的 AI 回复都使用 `DOMPurify` 进行严格清理,以防止 XSS 攻击。 ## 📦 构建与开发 默认情况下,根目录下的 `index.html` 文件(`dist/hermit-ui-standalone.html` 的副本)是一个完全离线、独立的版本。Web 字体和图像采用 base64 编码,而外部 JS/CSS 库直接注入到文件中。它非常适合气隙环境。 如果您希望修改源代码,请编辑 `src/` 中的模块化源文件 —— `index.html`、`style.css` 和 `script.js`(为了方便本地开发,它们通过 CDN 引用外部库)—— 然后运行构建脚本以重新生成独立的根文件: ``` python build.py ``` 这将在 `dist/hermit-ui-standalone.html` 生成独立构建,将其复制到根目录 `index.html` 以供 GitHub Pages 使用,并在 `dist/` 目录中创建备选构建。独立版本和 CDN 变体(`dist/hermit-ui-standalone.html`、`dist/hermit-ui-cdn.html`)已被提交(可在 GitHub 上浏览);本地变体 `dist/hermit-ui-local.html` 和下载的 `libs/` 仅用于生成,并保持被 gitignored。 ## 🛠️ 构建所用技术 * **原生 HTML5 / CSS3 / ES6 JavaScript** * [Marked.js](https://marked.js.org/) - 用于解析 Markdown * [DOMPurify](https://github.com/cure53/DOMPurify) - 用于清理 HTML 并防止 XSS * [Highlight.js](https://highlightjs.org/) - 用于代码语法高亮 * [KaTeX](https://katex.org/) - 用于 LaTeX 数学渲染(MathML 输出) * [Mermaid](https://mermaid.js.org/) - 用于从 ```` ```mermaid ```` 代码块渲染图表 * [Google Fonts (Inter)](https://fonts.google.com/specimen/Inter) - 用于简洁、现代的排版 ## 🗺️ 路线图 HermitUI 正在积极开发中。以下是正在进行和即将推出的内容。 ### 🧪 浏览器内推理(wllama 构建) HermitUI 可以**完全在浏览器中运行真正的离线推理** —— 无需本地服务器或兼容 OpenAI 的 endpoint。它由 [wllama](https://github.com/ngxson/wllama)(编译为 WebAssembly 的 llama.cpp,带有可选的 WebGPU 加速)提供支持:您加载一个 `.gguf` 模型文件,并直接在页面上与之聊天。 它以专用的构建输出形式提供,即 **`dist/hermit-ui-wllama.html`** —— 常规的独立应用程序加上设置中的 **Backend Mode** 开关(`Remote / Local API` ↔ `True Offline (Wllama GGUF)`)。主要构建保持精简:该功能在构建时被剥离。功能亮点: * **🔌 真正的零网络:** wllama 引擎(JS + WASM)在构建时直接嵌入到文件中(gzip 压缩,通过原生 `DecompressionStream` API 在浏览器中解压),因此约 5 MB 的文件**完全不需要网络访问** —— 非常适合通过 USB 闪存盘分发给气隙机器。模型文件永远不会离开您的机器。 * **📂 本地 GGUF 加载:** 选择一个 `.gguf` 文件并通过 WebAssembly 完全在客户端运行它,带有可选的 **WebGPU** 切换以进行硬件加速。 * **🔗 通过 URL / Hugging Face 加载:** 粘贴直接的 `.gguf` 链接、Hugging Face 的 `/blob/` 页面 URL(自动重写为 `/resolve/`)或 `hf:user/repo/file.gguf` 简写,然后点击加载。模型**直接流入内存**,并带有实时进度条 —— 真正践行了临时性承诺,没有任何内容被写入浏览器存储,因此每次会话都会重新下载。 * **🎚️ 可配置的推理:** 每次回复具有可调节的 **context window**n_ctx`) 和 **max output tokens**;常规设置中的 temperature、top-p 和 seed 也同样适用。 * **🧩 分层 chat-template 处理:** 存在时使用模型自己嵌入的 `tokenizer.chat_template`,否则从模型架构(ChatML、Llama 3、Mistral、Gemma、Phi-3、Zephyr、Alpaca 等)自动检测合理的格式,并带有手动覆盖功能。 * **🐛 Quake 风格的调试控制台:** 具有分级 **verbosity 级别**(Off → Errors → Warnings → Info → Debug)的下拉控制台,可显示引擎初始化、下载/加载进度、模型元数据、发送的确切 prompt 以及原生的 llama.cpp 日志。 * **⏱️ 实时 tokens/s:** 在模型流式传输时提供实时的生成速度读数。 #### 在 60 秒内试用 1. 在浏览器中打开 [`dist/hermit-ui-wllama.html`](dist/hermit-ui-wllama.html)(首先下载原始文件)。 2. 设置 → Backend Mode → **True Offline (Wllama GGUF)**,然后粘贴到 URL 字段中:`hf:Qwen/Qwen2.5-0.5B-Instruct-GGUF/qwen2.5-0.5b-instruct-q4_k_m.gguf` 3. 点击 **⬇️ 加载**(下载约 400 MB)并开始聊天 —— 无需服务器,无需安装,且不会保留任何内容。 #### 浏览器支持与模型大小限制 您可以加载的模型有多大——以及它运行的速度有多快——取决于您浏览器的两项 WebAssembly/GPU 功能,wllama 会在加载时检测它们: | 功能 | 它启用的内容 | Chrome / Edge | Firefox | |---|---|---|---| | **JSPI** (`WebAssembly.Suspending`) | 将 GGUF 直接流入引擎,而不是将其完整复制到 WASM 堆中 → 模型大小仅受您的 RAM/VRAM 限制 | ✅ Chrome 137+ | ✅ 仅限 Firefox **153+** | | **WebGPU**(在 worker 中) | 硬件加速推理 | ✅ 成熟 | ⚠️ 较新 / 可能无法初始化 → 回退到 CPU | 在实际操作中: * **Chrome / Edge:** 多 GB 模型(7B+ 量化版本)可以在 WebGPU 加速下完美加载和运行。限制在于您的实际 RAM/VRAM。 * **153 之前的 Firefox:** 没有 JSPI,wllama 会回退到将**整个模型文件复制到 4 GiB 的 WASM 堆中**。大于约 ~3 GB 的模型会因隐晦的错误 `source array is too long`(wllama 内部未检查的内存分配失败)而失败。**修复:更新到 Firefox 153+**,这会默认启用 JSPI。您可以通过在 DevTools 控制台中输入 `!!WebAssembly.Suspending` 来验证支持情况 —— 它必须打印 `true`。 * **Firefox 速度:** 即使有 JSPI,Firefox 的 WebGPU 支持也比 Chrome 新得多,并且可能无法在 wllama worker 内部初始化,从而将推理降至单线程 CPU WASM —— 在同一台机器上明显慢于 Chrome。检查调试控制台(verbosity 为 **Debug**,然后重新加载模型),查看是选择了 WebGPU 设备还是 CPU 后端。如果 WebGPU 表现不佳,尝试取消选中 WebGPU 切换 —— 一个干净的 CPU 运行可能会胜过损坏的 GPU 路径。 ### 🔭 正在考虑中 * 为 URL 加载器提供 Split-GGUF(`-00001-of-000NN.gguf`)支持。 ## 📄 许可证 该项目是开源的,并受 **GNU AGPL v3** 条款的约束。请参阅包含的 [LICENSE](LICENSE) 文件以获取全文。
标签:Vanilla JS, 人工智能, 前端工具, 后端开发, 本地大模型, 用户模式Hook绕过, 网络安全, 聊天界面, 逆向工具, 隐私保护