当下,大模型(LLM)的部署模式主要以云端为中心,但越来越多的应用场景需要强大的离线优先能力,以保障隐私、降低延迟并提升可访问性。本文将探讨如何利用 Rust 和 Tauri 2.0 构建一个本地优先 AI 应用的技术蓝图,核心在于如何完全离线运行现代大模型。我们将深入研究一个名为 Message Mate 的本地 AI 写作助手,展示如何利用 Rust 强大的性能和 Tauri 的跨平台能力,打造一个高效、安全的离线 AI 解决方案。该方案采用量化的 LLM 推理引擎,能在资源有限的设备上流畅运行,为用户提供随时随地的智能服务,真正实现本地优先 AI。
架构概述:Rust 调解的 Sidecar 模式
Message Mate 采用了一种名为 “Rust 调解的 Sidecar 模式” 的架构,它将应用清晰地划分为三个层次,从而实现关注点分离:
- 前端 (Solid.js): 轻量级的用户界面客户端,负责渲染和处理用户输入。Solid.js 以其高性能和细粒度更新机制而闻名,能够快速响应用户操作,提供流畅的用户体验。
- Rust Mediator (Tauri 后端): 编排层,控制状态、进程并安全地处理业务逻辑。Rust 作为系统编程语言,拥有出色的内存安全性和并发性能,非常适合作为应用的 “大脑”,协调各个组件的工作。
- LLM Sidecar (candle-vllm): 一个独立的、高性能的二进制文件,运行量化的大模型。Sidecar 模式的关键在于,它将 LLM 引擎与主应用隔离开来,避免了单一故障点,提升了应用的稳定性和安全性。
这种设计确保了故障隔离(如果 LLM 崩溃,应用不会崩溃),简化了调试,并增强了模块化。例如,如果 LLM Sidecar 出现问题,前端依然可以正常运行,并提示用户稍后重试。这种架构使得应用更具弹性,更易于维护。
核心组件详解
1. 推理引擎:构建和捆绑 candle-vllm
Message Mate 的智能由 candle-vllm 提供支持,这是一个基于 Rust 的高性能服务器,用于执行 LLM 推理。与嵌入式库不同,candle-vllm 是一个独立的二进制文件,与 Tauri 应用捆绑在一起作为托管的 Sidecar。
要针对您的硬件进行优化,您必须使用适当的功能编译它。
🔧 如何构建 candle-vllm 二进制文件
-
对于 macOS (Apple Silicon — Metal 加速):
git clone https://github.com/EricLBuehler/candle-vllm.git cd candle-vllm cargo build --release --features metal cp target/release/candle-vllm-server ../your-app/src-tauri/bin/candle-vllm
-
对于 Linux (CUDA 或 OpenCL):
git clone https://github.com/EricLBuehler/candle-vllm.git cd candle-vllm cargo build --release --features cuda # or: --features opencl cp target/release/candle-vllm-server ../your-app/src-tauri/bin/candle-vllm
-
对于 Windows (仅 CPU):
git clone https://github.com/EricLBuehler/candle-vllm.git cd candle-vllm cargo build --release Copy-Item .\target\release\candle-vllm-server.exe ..\your-app\src-tauri\bin\candle-vllm.exe
不要忘记使用 Sidecar 路径更新您的 tauri.conf.json:
"sidecars": [
{
"name": "candle-vllm",
"path": "bin/candle-vllm"
}
]
有关更多硬件特定的选项,请参阅官方指南:🔗 github.com/EricLBuehler/candle-vllm
Tauri 权限:配置 default.json
为了安全地运行并与 candle-vllm 二进制文件通信,您需要在 src-tauri/capabilities/default.json
中定义一个功能范围。这确保了 Tauri 只允许执行经过批准的二进制文件和参数,这是 Tauri 2.0 的一项重要安全功能。
这是此项目中使用的配置:
{
"$schema": "../gen/schemas/desktop-schema.json",
"identifier": "default",
"description": "Capability for the main window",
"windows": ["main"],
"permissions": [
"core:default",
"core:path:default",
"opener:default",
"shell:default",
{
"identifier": "shell:allow-spawn",
"allow": [
{
"name": "candle-vllm",
"cmd": "candle-vllm-aarch64-apple-darwin",
"sidecar": true,
"args": [
"--port",
{ "validator": "\\d+" },
"--model-id",
{ "validator": ".+\\.gguf" },
"--weight-file",
{ "validator": ".+\\.gguf" },
"qwen3",
"--quant", "gguf",
"--temperature",
{ "validator": "[0-9]+(?:\\.[0-9]+)?" },
"--penalty",
{ "validator": "[0-9]+(?:\\.[0-9]+)?" }
]
}
]
},
{
"identifier": "http:default",
"allow": [{ "url": "http://127.0.0.1:*" }]
}
]
}
为什么这很重要: Tauri 对所有系统级操作强制执行细粒度的安全控制。此文件显式定义:
- 可以生成哪些二进制文件 (candle-vllm)
- 允许哪些参数(带有正则表达式验证)
- 允许前端调用哪些 URL(在本例中为 localhost)
确保 cmd 值与您的系统的 Sidecar 二进制文件名匹配(例如,Apple Silicon 的 candle-vllm-aarch64-apple-darwin
)。您也可以在构建步骤中相应地重命名二进制文件,或调整 Linux 或 Windows 的配置。
candle-vllm 作为一个高性能的推理引擎,支持多种量化技术,例如 GGUF,能够在 CPU 或 GPU 上高效运行大模型。通过量化,可以显著降低模型的大小和计算需求,使其能够在资源有限的设备上运行。 例如,一个原始的 LLM 可能需要数百 GB 的内存,而经过量化后,可能只需要几个 GB,甚至更少。 这使得离线运行大模型成为可能,为本地优先 AI 应用奠定了基础。
2. Rust Mediator:命令与控制
Rust 后端不仅仅是一个桥梁;它是应用程序的中心神经系统。
A. 启动和管理 LLM Sidecar
start_llm
命令使用经过验证的参数启动 AI 引擎:
// src-tauri/src/lib.rs (简化)
#[tauri::command]
async fn start_llm(app: AppHandle, state: State<'_, LlmServerState>) -> Result<(), String> {
// ... logic to find and validate an available port ...
let args = vec![
"--port".to_string(),
port_str,
"--model-id".to_string(),
"unsloth/Qwen3-4B-GGUF".to_string(),
"--weight-file".to_string(),
"Qwen3-4B-Q4_0.gguf".to_string(),
"qwen3".to_string(),
"--quant".to_string(),
"gguf".to_string(),
"--temperature".to_string(),
"0.0".to_string(),
"--penalty".to_string(),
"1.0".to_string(),
];
let (_rx, child) = app
.shell()
.sidecar("candle-vllm")
.expect("Sidecar definition not found")
.args(&args)
.spawn()?;
// Store the child process handle in a shared, thread-safe state
*state.child.lock().unwrap() = Some(child);
// Spawn a Tokio task to monitor sidecar stdout, stderr, and termination
// ...
Ok(())
}
Rust 后端负责启动和管理 LLM Sidecar 进程,并确保其稳定运行。它通过 Tauri 提供的 API 与 Sidecar 进程进行通信,并监控其状态。 例如,如果 Sidecar 进程意外崩溃,Rust 后端可以自动重启该进程,从而保证应用的可用性。
B. 有状态的消息传递和系统提示
AI 的角色是从系统提示常量初始化的。当用户发送提示时,它会插入到对话历史记录中:
// src-tauri/src/lib.rs (系统提示)
const PREAMBLE: &str = r#"You are Message Mate, a professional and efficient AI writing assistant..."#;
// src-tauri/src/lib.rs (命令逻辑)
#[tauri::command]
async fn ask_qwen(prompt: String, window: Window, state: State<'_, LlmServerState>) -> Result<String, String> {
// Step 1: Lock state and retrieve the history for the current window.
let payload_messages = {
let mut histories = state.histories.lock().unwrap();
let history = get_history(&mut histories, window.label());
// Step 2: Inject system prompt and user prompt into the history.
// ...
history.clone() // Release the lock before async operations.
};
// Step 3: Send the curated payload to the AI sidecar via HTTP.
// ...
// Step 4: Process the response, update state, and return.
Ok(content)
}
Rust 后端还负责管理对话历史记录,并维护 LLM 的状态。它将用户的输入和 LLM 的输出存储在内存中,以便 LLM 能够理解上下文并生成更相关的回复。系统提示(System Prompt)用于定义 LLM 的角色和行为,例如,将其设置为 “一个专业的写作助手”。 通过调整系统提示,可以定制 LLM 的行为,使其更符合用户的需求。
3. 前端:精简的 Solid.js 客户端
UI 是最小的,并将所有逻辑卸载到 Rust:
// src/App.jsx (简化)
async function handleSendMessage(e: Event) {
e.preventDefault();
setIsLoading(true);
try {
// The frontend sends only the new prompt, not the full context.
const response = await invoke("ask_qwen", { prompt: inputMessage() });
// Update the UI with the response from the Mediator.
setMessages(prev => [...prev, createAssistantMessage(response)]);
} catch (error) {
// ... error handling ...
} finally {
setIsLoading(false);
}
}
前端使用 Solid.js 构建,它是一个轻量级且高性能的 JavaScript 框架。前端只负责收集用户输入并将它们发送到 Rust 后端。 Rust 后端处理所有的业务逻辑,并将结果返回给前端。 这种设计使得前端非常简洁,易于维护,并能够快速响应用户操作。 由于所有的计算都在本地进行,因此用户可以享受极低的延迟和高度的隐私。
未来展望
这仅仅是个开始。该架构是有意开放式的。它可以接下来往这里发展:
- MCP 风格的工具使用: 存储推理步骤并链接诸如摘要器、计算器或计划器之类的工具。
- 矢量嵌入和 RAG: 添加内存中或持久矢量存储以启用文档检索和有根据的答案。
- 多角色切换: 通过配置文件添加用户定义的提示和动态身份切换。
- 离线优先 API 和上下文记忆: 持久化使用历史记录、注释或聊天状态以实现离线上下文感知。
- LLM 交换和动态配置: 添加一个配置菜单来加载不同的 GGUF 模型。
本地优先 AI 应用的未来充满潜力。通过结合 矢量嵌入和 RAG 技术,我们可以构建能够检索本地文档并生成有根据的答案的应用。 例如,我们可以构建一个能够回答用户关于本地法律法规问题的 AI 助手。 通过添加 多角色切换 功能,我们可以让 LLM 扮演不同的角色,例如,客户服务代表、技术支持专家或创意写作助手。 离线优先 API 和上下文记忆 功能可以让 LLM 在没有网络连接的情况下依然能够记住用户的偏好和历史记录,从而提供更个性化的服务。 最终,LLM 交换和动态配置 功能将允许用户根据自己的需求选择不同的 大模型,从而实现高度的定制化。
总结
Message Mate 项目证明了强大的 LLM 驱动的应用程序可以在经济实惠的硬件上本地运行,使用简单但强大的基于 Rust 的架构。 它展示了 本地优先 AI 的可行性,并在隐私、延迟和可访问性方面具有显著优势。随着 大模型 技术的不断发展和硬件性能的不断提升,我们相信 本地优先 AI 将在未来扮演越来越重要的角色,为用户提供更智能、更便捷、更安全的 AI 服务。
希望这篇文章能够帮助您了解如何使用 Rust 和 Tauri 构建 本地优先 AI 应用。 欢迎大家积极参与,共同探索 离线 大模型 应用的无限可能。