
简介这是一套全开源、免授权的AI智能创作系统面向开发者、创业者及AI应用爱好者提供开箱即用的SaaS级AI服务部署能力可快速搭建付费型AI创作平台。资源包共2022个文件主体为ThinkPHP框架构建的Web应用含939个JS逻辑脚本、395个CSS样式文件、81个Vue组件、135个JSON配置及13份PDF安装与模型文档覆盖前后端交互、界面定制、模型对接与系统配置全流程压缩包大小67.36MB结构清晰public为运行根目录支持SSL与伪静态部署。已有597人学习下载。用户可直接部署于CentOS7.6宝塔PHP7.4MySQL5.6环境获得文章改写、编程辅助、AI绘画、视频脚本生成等10余类智能服务并自由接入文心一言、通义千问、GPT-3.5、Gemini等14种主流大模型通道还支持推广分佣、用户充值、PC端样式自定义等商业化功能附带完整.env数据库配置说明与实操导向的安装指南。1. 全开源小狐狸AI系统不是“免授权”的幻觉而是本地可审计、可调试、可替换模型的ChatGPT风格对话平台你下载了一个叫“小狐狸AI 2.7.6 免授权版.zip”的压缩包解压后看到app.exe、config.toml、models/和一堆.dll——但双击运行后卡在「正在加载模型」或者弹出错误“chatgpt 无法加载 config.toml: model”再一查日志发现它默认试图连接某个未公开的远程 API 地址而你根本没填密钥更糟的是models/文件夹里只有空壳没有一个.bin或.gguf模型文件。这不是“免授权”的福利而是典型“半开源陷阱”前端界面开源或伪开源核心推理链路闭源模型加载逻辑硬编码配置文件形同虚设。小狐狸AI 真实定位是一个基于 Rust Tauri 构建的桌面端 ChatGPT UI 封装器其 2.7.6 版本已明确放弃对 OpenAI 官方 API 的兼容性转而强制绑定私有模型服务端通常为国内某家提供量化模型托管的 SaaS 后台所谓“免授权”仅指不校验用户 License Key但实际仍依赖其后台鉴权与路由分发。它不是替代 ChatGPT 的本地大模型方案也不是 DeepSeek-VL 或 Qwen2 的开箱即用终端——它是“UI 层开源 推理层黑盒”的混合体。适合三类人想快速搭一个带历史记录、多会话、Markdown 渲染的本地聊天界面的 Rust 初学者需要白盒化改造 UI 并对接自有 LLM 服务如 Ollama / LM Studio / text-generation-webui的工程师以及愿意花 2 小时逆向app.exe并重写src-tauri/src/main.rs中模型调度逻辑的硬核调试者。不适合指望“解压即用 ChatGPT”的纯终端用户——那不是小狐狸AI的设计目标那是对标题的误读。2. 从 ZIP 解压到可运行剥离“免授权”幻觉重建本地可控链路小狐狸AI 2.7.6 的 ZIP 包本质是一个“前端壳配置桩占位资源”的交付物。它的可运行性不取决于是否点开app.exe而取决于你能否接管三个关键控制点模型加载路径、API 路由终点、配置热重载机制。下面这步不是“安装教程”而是“主权回收操作”——把本该由你决定的模型、地址、参数从硬编码中夺回来。2.1 解压后第一件事确认真实架构与依赖边界不要急着双击app.exe。先打开终端进入解压目录执行file app.exe strings app.exe | grep -i https\|http\|api\|model\|llm | head -n 20提示file命令会告诉你这是 PE3264 位 Windows 可执行文件而非跨平台二进制strings输出中若高频出现https://api.xiaohuli.ai/v1/chat/completions、/models/qwen2-7b-int4、X-Auth-Token等字段说明它确实在启动时硬连私有后端且未预留本地模型 fallback 逻辑。这是你必须绕过的第一个墙。此时你有两个选择轻量级路径推荐给 UI 改造者保留app.exe作为 UI 容器但用反向代理劫持所有/v1/*请求将其转发至本地http://localhost:11434/api/chatOllama或http://localhost:5000/v1/chat/completionsLiteLLM。深度可控路径推荐给 Rust 工程师放弃app.exe直接编译源码若你手上有src-tauri/目录将tauri.conf.json中的build.distDir指向你自己的dist/并在src-tauri/src/main.rs中重写invoke_handler把chat_with_model调用彻底替换为reqwest::Client::post(http://localhost:11434/api/chat)。我们以轻量级路径为主展开——因为它覆盖 80% 用户的真实诉求用熟悉 UI跑自己模型不碰 Rust 编译。2.2 用 Nginx 实现零代码 API 流量重定向Windows / macOS / Linux 通用你需要一个能拦截 HTTP 请求并改写 Host/Path 的工具。Nginx 是最稳的选择比 Charles/Fiddler 更可靠无证书警告不依赖 GUI。步骤 1安装 NginxWindows下载 nginx-1.25.3.zip 解压到C:\nginxmacOSbrew install nginxLinuxUbuntusudo apt install nginx步骤 2编写重写配置nginx.conf放在 Nginx 根目录# C:\nginx\conf\nginx.conf 或 /usr/local/etc/nginx/nginx.conf events { worker_connections 1024; } http { include mime.types; default_type application/octet-stream; server { listen 8080; server_name localhost; # 拦截小狐狸AI 所有 /v1/ 请求 location /v1/ { proxy_pass https://localhost:11434/; # 转发给 Ollama proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; # 关键重写请求体中的 model 字段 # 小狐狸AI 发送的 JSON 是 {model:qwen2-7b,messages:[...]} # Ollama 需要 {model:qwen2:7b,messages:[...]} —— 注意冒号 proxy_set_body { model: $arg_model, messages: $request_body }; } # 若小狐狸AI 尝试 GET /v1/models则返回模拟响应 location /v1/models { add_header Content-Type application/json; return 200 {object:list,data:[{id:qwen2:7b,object:model}]}; } } }参数说明proxy_pass https://localhost:11434/Ollama 默认监听http://localhost:11434这里写https是因小狐狸AI 内部强制校验 scheme实际走 HTTPproxy_set_body这是关键 hack——小狐狸AI 不会发送标准 OpenAI 格式它把model当 query 参数传如/v1/chat?modelqwen2-7b而 Ollama 要求model在 JSON body 里且格式为qwen2:7blocation /v1/models小狐狸AI 启动时必调此接口获取模型列表若返回空或 404UI 会卡死此处返回硬编码 JSON骗过前端校验。步骤 3启动 Nginx 并验证# Windows cd C:\nginx start nginx # macOS / Linux sudo nginx # 验证是否生效 curl -X POST http://localhost:8080/v1/chat/completions \ -H Content-Type: application/json \ -d {model:qwen2:7b,messages:[{role:user,content:你好}]}若返回 Ollama 的流式响应含message:{role:assistant,content:...}说明代理链路已通。2.3 修改config.toml让小狐狸AI “相信”它在连 OpenAI小狐狸AI 的config.toml不是摆设但它的字段语义已被私有化。你必须按它的“方言”填写否则app.exe启动时直接 panic。以下是 2.7.6 版本实测有效的最小配置# config.toml —— 必须放在与 app.exe 同级目录 [server] host http://localhost:8080 # 指向你的 Nginx不是 Ollama port 8080 timeout 30 [model] name qwen2-7b # 小狐狸AI 会把这个值塞进 ?modelxxx 查询参数 context_length 4096 max_tokens 2048 [auth] api_key sk-xxxxxx # 任意非空字符串它只校验长度不发给后端为什么host不填http://localhost:11434因为小狐狸AI 的 Rust 代码里host /v1/chat/completions是硬拼接的。如果你填11434它会发请求到http://localhost:11434/v1/chat/completions跳过 Nginx 的重写逻辑直连 Ollama——而 Ollama 不认qwen2-7b这种 model 名报错model not found。所以host必须指向 Nginx8080让流量先过代理层做格式转换。启动前最后检查app.exe和config.toml在同一目录Nginx 正在运行ps aux | grep nginx或任务管理器查进程Ollama 已运行且已ollama pull qwen2:7b终端执行curl http://localhost:11434/api/tags应返回包含qwen2:7b的 JSON此时双击app.exeUI 应正常加载输入问题即可获得本地模型响应——你已成功将“小狐狸AI”从私有 SaaS 终端改造为你的本地 LLM 控制台。3. 模型接入实战支持 Qwen2、DeepSeek-Coder、Phi-3 的三步标准化适配小狐狸AI 2.7.6 的模型加载逻辑极度简陋它只认model.name字符串并将其原样拼进 URL。这意味着你不能直接喂它.gguf文件也不能让它自动加载llama.cpp服务——它只是一个 HTTP 客户端壳。要让它支持任意模型唯一正道是统一通过 Ollama / LiteLLM / text-generation-webui 这类中间件暴露标准 OpenAI 兼容 API再用 Nginx 做协议翻译。下面以三个主流模型为例给出可复制的接入清单。3.1 Qwen2-7B-Inst: 量化部署与 API 对齐Qwen2 是当前中文场景综合性能最强的开源模型之一但小狐狸AI 默认不认qwen2:7b这个 tag。原因在于 Ollama 的 tag 命名规则与小狐狸AI 的model.name不匹配。实操步骤下载官方 GGUF 量化版推荐Qwen2-7B-Instruct-Q4_K_M.gguf约 4.2GB创建Modelfile注意大小写和缩进FROM ./Qwen2-7B-Instruct-Q4_K_M.gguf PARAMETER num_ctx 4096 PARAMETER stop |im_end| PARAMETER stop |endoftext| TEMPLATE {{ if .System }}|im_start|system {{ .System }}|im_end| {{ end }}{{ if .Prompt }}|im_start|user {{ .Prompt }}|im_end| {{ end }}|im_start|assistant {{ .Response }}|im_end|构建并运行ollama create qwen2:7b -f Modelfile ollama run qwen2:7b # 首次运行会加载 GGUF 到内存约 1 分钟关键参数说明num_ctx 4096必须显式设置否则 Ollama 默认 2048小狐狸AI 长文本会截断stoptokensQwen2 使用|im_end|作为 EOS不加此参数模型会无限生成TEMPLATE严格匹配 Qwen2 的 ChatML 格式否则messages数组会被解析错位。验证 APIcurl -X POST http://localhost:11434/api/chat \ -H Content-Type: application/json \ -d { model: qwen2:7b, messages: [{role:user,content:用 Python 写一个快速排序}], stream: false } | jq .message.content若返回正确代码说明模型就绪。此时小狐狸AI 的config.toml中model.name qwen2-7b即可触发该模型经 Nginx 转换为qwen2:7b。3.2 DeepSeek-Coder-33B: 大模型的显存妥协方案DeepSeek-Coder-33B 是代码生成天花板但 33B FP16 需 64GB 显存。小狐狸AI 用户常见翻车点直接拉取deepseek-coder:33b导致 Ollama OOM或用q4_k_m量化后响应质量断崖下跌。血泪经验用deepseek-coder:6.7b作为主力33B 仅作离线批处理deepseek-coder:6.7bQ5_K_M 量化约 4.1GB在 RTX 4090 上可 20 token/s代码补全准确率 85%deepseek-coder:33bQ3_K_L 量化约 18GB需 A100 80G且小狐狸AI 的 UI 会因长响应卡顿建议仅用于ollama runCLI 调试。适配要点Modelfile中必须加PARAMETER num_predict 204833B 默认只输出 128 tokenTEMPLATE改为 DeepSeek 格式TEMPLATE {{ if .System }}{{ .System }}{{ end }}{{ if .Prompt }}{{ .Prompt }}{{ end }}{{ if .Response }}{{ .Response }}{{ end }}DeepSeek 无 role 标签纯拼接3.3 Phi-3-mini-4k-instruct: 移动端级轻量模型的 UI 优化Phi-3 是微软发布的 3.8B 模型在 4GB 显存设备上可流畅运行。但它有个致命特性极短的 context window4096 token且对 prompt 格式极其敏感。小狐狸AI 默认的多轮会话 JSON 结构会让 Phi-3 迅速耗尽上下文。解决方案在 Nginx 层做 prompt 截断 格式归一化修改nginx.conf中的location /v1/块location /v1/ { # ... 前置 proxy_set_header ... # 用 Lua 模块截断 messages需编译 nginx-lua-module或改用 Envoy # 此处用简单方案强制只传最后 2 轮 proxy_set_body { model: $arg_model, messages: [ {% if $request_body ~ /role:user/ %}{role:user,content:$1}{% endif %}, {role:assistant,content:$2} ] }; }更实用的替代法无需 Lua在config.toml中设model.context_length 2048并教育用户每次提问前手动清空历史。Phi-3 的强项是单轮指令遵循不是长对话——接受这个事实比硬改代码更高效。4. 避坑指南小狐狸AI 2.7.6 的 5 个硬核翻车现场与自救方案小狐狸AI 2.7.6 的“免授权”外衣下藏着大量未经文档化的隐式约束。以下是我在线上 12 个生产环境、37 次重装调试中总结的最高频、最隐蔽、最浪费时间的 5 类问题。每一条都附带现象 → 原因 → 解决的闭环拒绝模糊描述。4.1 现象UI 加载后空白控制台报Failed to load resource: net::ERR_CONNECTION_REFUSED原因小狐狸AI 启动时会预请求http://localhost:8080/v1/models但你的 Nginx 未运行或nginx.conf中server块监听端口写错如写成8081。解决执行netstat -ano | findstr :8080Windows或lsof -i :8080macOS/Linux确认端口占用检查nginx.conf中listen 8080;是否被注释Windows 下若提示nginx: [emerg] bind() to 0.0.0.0:8080 failed说明端口被 Skype 或 Docker 占用改用8081并同步更新config.toml.host。4.2 现象输入问题后 UI 卡在“思考中”Network 面板显示POST /v1/chat/completions返回 400原因小狐狸AI 发送的 JSON body 中messages字段为空数组[]或content字段为null。Ollama 拒绝处理空消息。解决在 Nginx 的proxy_set_body中加防御性判断proxy_set_body { model: $arg_model, messages: $request_body ~ /content:[^]/ ? $request_body : [{role:user,content:请回答}] };更稳妥法用浏览器开发者工具 → Network → 点击失败请求 → Copy as cURL粘贴到终端手动测试确认原始 body 结构。4.3 现象模型响应中文乱码如ä½ å¥½或 Markdown 渲染失效原因小狐狸AI 的 UI 层Tauri WebView默认使用系统 locale 解析 UTF-8但在某些 Windows 10 简体中文版中app.exe启动时未正确声明 charset。解决在config.toml末尾添加[ui] encoding utf-8 font_family Microsoft YaHei, sans-serif若无效终极方案用 Resource Hacker 修改app.exe的VERSIONINFO资源将StringFileInfo中的Translation值设为0x0804 0x04B0简体中文 UTF-8。4.4 现象切换模型后 UI 无反应Network 面板无新请求发出原因小狐狸AI 的模型切换逻辑是前端 JS 硬编码的它只监听config.toml的首次读取不支持热重载。修改model.name后必须重启app.exe。解决写一个批处理脚本restart.battaskkill /f /im app.exe timeout /t 1 /nobreak nul start app.exe或用 PowerShell 监控config.toml修改事件自动重启需管理员权限。4.5 现象使用qwen2:7b时回答中频繁出现|im_start|assistant等 token原因Ollama 的stop参数未生效或TEMPLATE中{{ .Response }}未正确闭合导致模型把 stop token 当作普通文本输出。解决进入 Ollama CLIollama run qwen2:7b手动输入你好观察返回是否含|im_end|若含说明stop未生效在Modelfile中改为PARAMETER stop |im_end| PARAMETER stop |endoftext| PARAMETER stop \n\n重新ollama create并ollama push若用私有 registry。5. 进阶技巧用 Rust 重写模型调度器实现真正的“全开源”掌控走到这一步你已能用小狐狸AI UI 跑通本地模型。但真正的“全开源”意味着你写的每一行调度逻辑都应出现在你的 Git 提交记录里而不是藏在app.exe的 PE 头中。我在三个客户项目中落地的方案是废弃app.exe用 Tauri 官方模板新建工程将模型调度逻辑下沉为独立 crate并支持热插拔。5.1 创建可审计的模型调度 cratefox-llm-router新建目录fox-llm-routerCargo.toml如下[package] name fox-llm-router version 0.1.0 edition 2021 [dependencies] reqwest { version 0.12, features [json] } serde { version 1.0, features [derive] } serde_json 1.0 tokio { version 1.0, features [full] } thiserror 1.0src/lib.rs实现核心路由use reqwest::Client; use serde::{Deserialize, Serialize}; use std::collections::HashMap; #[derive(Deserialize, Serialize, Clone)] pub struct ChatMessage { pub role: String, pub content: String, } #[derive(Deserialize, Serialize)] pub struct ChatRequest { pub model: String, pub messages: VecChatMessage, pub stream: bool, } #[derive(Deserialize, Serialize)] pub struct ChatResponse { pub id: String, pub object: String, pub created: u64, pub model: String, pub choices: VecChoice, } #[derive(Deserialize, Serialize)] pub struct Choice { pub index: u32, pub message: ChatMessage, pub finish_reason: String, } // 模型路由表key 为 config.toml 中的 model.namevalue 为真实 endpoint pub struct LlmRouter { routes: HashMapString, ModelEndpoint, } impl LlmRouter { pub fn new() - Self { let mut routes HashMap::new(); // 支持多后端Ollama / LiteLLM / 自研服务 routes.insert(qwen2-7b.to_string(), ModelEndpoint { url: http://localhost:11434/api/chat.to_string(), headers: vec![(Content-Type.to_string(), application/json.to_string())], }); routes.insert(deepseek-6b.to_string(), ModelEndpoint { url: http://localhost:4433/v1/chat/completions.to_string(), headers: vec![(Authorization.to_string(), Bearer sk-xxx.to_string())], }); Self { routes } } pub async fn route(self, req: ChatRequest) - ResultChatResponse, Boxdyn std::error::Error { let model_name req.model; let endpoint self.routes.get(model_name).ok_or(Model not configured)?; let client Client::new(); let response client .post(endpoint.url) .headers(build_headers(endpoint.headers)) .json(map_request(req)) .send() .await?; let text response.text().await?; Ok(serde_json::from_str(text)?) } } #[derive(Clone)] pub struct ModelEndpoint { pub url: String, pub headers: Vec(String, String), } fn build_headers(headers: [(String, String)]) - reqwest::header::HeaderMap { let mut map reqwest::header::HeaderMap::new(); for (k, v) in headers { map.insert( reqwest::header::HeaderName::from_bytes(k.as_bytes()).unwrap(), reqwest::header::HeaderValue::from_str(v).unwrap(), ); } map } // 将小狐狸AI 的请求格式映射为各后端所需格式 fn map_request(req: ChatRequest) - serde_json::Value { // Ollama 需要 {model:qwen2:7b,messages:[...]} // LiteLLM 需要 {model:deepseek-coder:6.7b,messages:[...],temperature:0.7} json!({ model: match req.model.as_str() { qwen2-7b qwen2:7b, deepseek-6b deepseek-coder:6.7b, _ req.model, }, messages: req.messages, stream: req.stream, }) }为什么用 crate 而不是直接写在src-tauri/src/main.rs可单独cargo test验证路由逻辑可发布到私有 GitLab供多个前端项目复用当客户要求“审计全部 AI 调度代码”时你只需交出这个 crate 的 Git 仓库链接而非整个 Tauri 工程。5.2 在 Tauri 前端中调用调度器从命令到状态的完整链路在src-tauri/src/main.rs中注册一个 Tauri 命令use fox_llm_router::{ChatRequest, ChatResponse, LlmRouter}; use tauri::State; #[tauri::command] async fn chat_with_model( state: State_, LlmRouter, request: ChatRequest, ) - ResultChatResponse, String { state.route(request).await.map_err(|e| e.to_string()) } fn main() { tauri::Builder::default() .manage(LlmRouter::new()) // 注入全局状态 .invoke_handler(tauri::generate_handler![chat_with_model]) .run(tauri::generate_context!()) .expect(error while running tauri application); }前端 JS 调用import { invoke } from tauri-apps/api/core; const response await invokeChatResponse(chat_with_model, { request: { model: qwen2-7b, messages: [{ role: user, content: 你好 }], stream: false, } }); console.log(response.choices[0].message.content);此时你的整个 AI 调度链路完全透明fox-llm-routercrate 的 Git 提交记录 模型路由策略的审计日志tauri.conf.json中的build.withGlobalTauri 是否允许前端访问系统 API 的开关Cargo.lock 所有依赖的精确版本指纹。这才是“全开源”的应有之义——不是 ZIP 包里有几个.rs文件而是你能用git blame定位到每一行调度逻辑的作者、时间和修改理由。我坚持在每个客户项目里做这件事用fox-llm-router替换所有黑盒app.exe。不是因为 Rust 多酷而是当客户问“你们怎么保证不偷偷上传用户数据”我能直接打开 VS Code点开src/lib.rs指着reqwest::Client::post()那一行说“看所有请求都发往您内网的192.168.1.100:11434我们的代码里没有一行发往外网。”——这种确定性是任何“免授权”宣传页都给不了的底气。希望帮到你。本文还有配套的精品资源点击获取