OpenJarvis 原生 Windows 部署指南:无需 WSL2 与 Docker 的 PowerShell 安装与服务化
2026/9/24 15:53:13 网站建设 项目流程

OpenJarvis 原生 Windows 部署指南:无需 WSL2 与 Docker 的 PowerShell 安装与服务化

【免费下载链接】OpenJarvisPersonal AI, On Personal Devices项目地址: https://gitcode.com/gh_mirrors/op/OpenJarvis

OpenJarvis 是一个"Personal AI, On Personal Devices"的个人 AI 项目。本文面向 Windows 用户,完整讲解如何在原生 Windows 上通过 PowerShell 安装 OpenJarvis、将其注册为开机自启的 Windows 计划任务服务,并安全地决定是仅限本机(loopback)还是暴露到局域网(LAN)。文章以 deploy/windows/README.md 为主线,并结合 deploy/windows/install.ps1、deploy/windows/jarvis-service.ps1 以及系统级服务定义文件,给出源码级佐证。读完本文,你将掌握:一条命令完成安装、计划任务服务的注册/查询/卸载、以及"loopback 默认免密钥 / 局域网暴露必须配 API Key"的完整安全模型。

背景:为什么需要原生 Windows 部署

OpenJarvis 在 Linux 和 macOS 上分别通过 systemd(deploy/systemd/openjarvis.service)与 launchd(deploy/launchd/com.openjarvis.plist)来管理常驻的 API 服务进程。Windows 侧的部署是其原生支持(Native-Windows Support RFC)的 Phase-1,目标是在不依赖 WSL2、不依赖 Docker、不依赖 MSYS2的前提下,用 PowerShell 提供与 Linux/macOS 对等的"安装 → 服务化 → 自启 → 守护"体验。

从 deploy/windows/install.ps1 的头部注释可以确认,它是 Linux/macOS 安装脚本 scripts/install/install.sh 的 PowerShell 对等实现,二者保持相同的步骤骨架(环境检查、依赖安装、仓库克隆、依赖同步、启动模型拉取、服务注册),只是把"systemd unit / launchd plist"替换为"Windows 计划任务(Scheduled Task)"。

一、一行命令安装(One-liner install)

普通或管理员权限的 PowerShell 中执行:

irm https://open-jarvis.github.io/OpenJarvis/install.ps1 | iex

其中irmInvoke-RestMethod的别名,iexInvoke-Expression的别名:先远程下载脚本内容,再直接在当前会话中执行。

安装脚本执行的 7 个步骤

对照 deploy/windows/install.ps1 的源码,安装过程依次完成:

  1. 拒绝非 Windows 主机与过老系统:通过$PSVersionTable.Platform -ne 'Win32NT'判断平台;通过[System.Environment]::OSVersion.Version.Build校验系统版本,要求Windows 10 1809(build 17763)或更新
  2. 检查 Python 3.10 – 3.13:优先探测python3,回退到python;若未安装,会用 winget 自动安装Python.Python.3.13。值得注意:Python 3.14 目前不被支持(因为 numpy 尚未提供 cp314 Windows wheels,见源码中的#432注释)。
  3. 检查git是否在 PATH:缺失时用 winget 安装Git.Git
  4. 检查/安装uv:若uv不在 PATH,脚本会调用 Astral 官方 PowerShell 安装脚本(https://astral.sh/uv/install.ps1),并手动把%USERPROFILE%\.local\bin追加到当前会话 PATH,以便后续步骤立即使用。
  5. 克隆仓库到%LOCALAPPDATA%\OpenJarvis:实际源码目录为%LOCALAPPDATA%\OpenJarvis\src,可通过$env:OPENJARVIS_HOME覆盖安装根目录。若目录已存在,脚本会跳过克隆(-Force时改为git pull --ff-only更新)。
  6. 执行uv sync --extra desktop --group desktop-native:安装 FastAPI 服务端、语音后端(faster-whisper、sounddevice 等)以及原生扩展。关于--group desktop-native的语义,见 pyproject.toml:openjarvis-rust(PyO3 原生扩展)被放在 PEP 735 依赖组而非desktopextra 中,因此只有显式--group desktop-native才会从本地 Rust workspace 源码构建,而pip install openjarvis[desktop]不会尝试从 PyPI 解析它。
  7. 可选地注册计划任务:注册一个登录时自动启动jarvis serve的计划任务(详见第三节)。

此外,安装脚本还会做两件 README 未展开讲但源码中明确存在的事:

  • 自动安装并启动 Ollama、拉取入门模型:若ollama不在 PATH,会下载官方OllamaSetup.exe(约 150 MB)并以 NSIS 静默参数/S安装;随后轮询等待 Ollama 守护进程就绪(最多 60 秒,期间若 5 秒仍未就绪会自动以ollama serve兜底启动),再拉取入门模型qwen3.5:2b(约 1.5 GB),保证首次运行jarvis即可对话。
  • 生成jarvis.cmdshim:在%LOCALAPPDATA%\OpenJarvis\bin\jarvis.cmd写入自定位 shim(内容为uv run --project "%~dp0..\src" jarvis %*),并把bin目录追加到用户级 PATH,使任何新开的 PowerShell 都能直接敲jarvis命令。

安装完成后,脚本会提示:模型拉取成功则直接运行jarvis,失败则运行jarvis doctor查看进度。

安装结束后的 PATH 注意事项

安装脚本会把bin目录写入用户级PATH,但当前已打开的 PowerShell 进程不会立即感知(Windows 进程环境继承自父 shell)。因此安装完成后请新开一个 PowerShell 窗口再执行jarvis

二、安装参数:Flags 与环境变量双通道

由于irm | iex的管道方式无法把param()参数传入脚本字符串,install.ps1 提供了两套控制方式,见 deploy/windows/install.ps1 的参数解析逻辑:

Flag(直接运行脚本文件时)作用
-Service无条件注册计划任务(不弹交互式询问)
-SkipService不询问、不注册计划任务
-Force即使已完成也重新执行所有步骤(含重新git pull

环境变量通道irm | iex时生效,与 Flag 同名语义一一对应):

环境变量等效 Flag说明
OPENJARVIS_SKIP_SERVICE=1-SkipService跳过服务注册
OPENJARVIS_SERVICE=1-Service强制注册服务
OPENJARVIS_FORCE=1-Force强制重跑

源码中明确:"Any explicit -switch wins; env vars only fill in the gaps",即显式 Flag 优先,环境变量仅在 Flag 未给出时兜底。典型用法:

$env:OPENJARVIS_SKIP_SERVICE = '1' irm https://open-jarvis.github.io/OpenJarvis/install.ps1 | iex

如果需要对安装过程做更细粒度的控制(例如组合-Force-SkipService),建议先把脚本保存到本地再执行:

irm https://open-jarvis.github.io/OpenJarvis/install.ps1 -OutFile install.ps1 .\install.ps1 -Force -SkipService

交互式提示的判定细节

当用户既没给-Service也没给-SkipService时,脚本只在"存在真实键盘会话"([Environment]::UserInteractive为真且 stdin 未被重定向)时才弹出Register OpenJarvis as a Windows scheduled task (auto-start at logon, loopback only)? [y/N]。对于非交互环境(如 CI、管道),会自动跳过服务注册并打印后续手动注册的提示。同时脚本会预先检查管理员权限——Register-ScheduledTask需要提升权限,若用户显式要求-Service但当前 PowerShell 未提升,会直接报错退出,避免"询问后再因 Access Denied 失败"的糟糕体验。

三、计划任务服务:jarvis-service.ps1

若安装时跳过了服务注册,或后续需要查看/删除服务,可使用 deploy/windows/jarvis-service.ps1 手动管理。该脚本是 Windows 侧对 systemd unit 与 launchd plist 的对等实现,通过子命令驱动:

$srv = "$env:LOCALAPPDATA\OpenJarvis\src\deploy\windows\jarvis-service.ps1" # 安装(幂等——已存在则替换) powershell -ExecutionPolicy Bypass -File $srv install # 查询状态 powershell -ExecutionPolicy Bypass -File $srv status # 卸载 powershell -ExecutionPolicy Bypass -File $srv uninstall

install 的参数

install子命令支持三个参数(见 jarvis-service.ps1):

参数默认值说明
-InstallRoot%LOCALAPPDATA%\OpenJarvis(或$env:OPENJARVIS_HOME源码根目录,须先运行过 install.ps1
-ListenHost127.0.0.1绑定地址;仅当设置了OPENJARVIS_API_KEY时才允许0.0.0.0
-ListenPort8000监听端口

计划任务的运行语义

从 Install-Task 函数 可以看出任务的关键配置:

  • 触发方式New-ScheduledTaskTrigger -AtLogOn -User $env:USERNAME,即登录时启动;
  • 执行主体uv run jarvis serve --host <ListenHost> --port <ListenPort>,工作目录为src目录;
  • 失败重启-RestartCount 3 -RestartInterval (New-TimeSpan -Minutes 1)——最多重启 3 次,间隔 1 分钟;
  • 无执行时限-ExecutionTimeLimit (New-TimeSpan -Seconds 0),即任务可无限期运行;
  • 错过补跑-StartWhenAvailable,登录被跳过时下次机会到来即补跑;
  • 最低权限:Principal 使用LogonType Interactive+RunLevel Limited,以当前用户身份、受限权限运行;
  • 电池友好-AllowStartIfOnBatteries-DontStopIfGoingOnBatteries,笔记本在电池供电下也能保持服务。

install是幂等的:若任务已存在,会先Unregister-ScheduledTask再重新注册。status子命令会输出任务状态(State)、上次运行时间(LastRun)、上次结果(LastRes,十六进制错误码)与下次运行时间(NextRun)。

提示:任务注册后立即手动启动可用Start-ScheduledTask -TaskName OpenJarvis

四、Loopback 与 LAN 暴露:安全模型

默认行为:仅本机可访问

默认情况下,计划任务把服务绑定到127.0.0.1,仅本机可访问,无需 API Key。这与 macOS launchd 的对等配置一致——deploy/launchd/com.openjarvis.plist 同样默认--host 127.0.0.1,并在注释中写明:绑定本机回环地址即可免去 API Key 的负担。

暴露到局域网:必须先生成 API Key

要在局域网内访问,需要两步:

# 1. 生成 API Key。服务端拒绝在未配置 Key 的情况下绑定 0.0.0.0。 $env:OPENJARVIS_API_KEY = (uv run jarvis auth generate-key) # 2. 以 -ListenHost 0.0.0.0 重新注册任务。 powershell -ExecutionPolicy Bypass -File $srv install -ListenHost 0.0.0.0

这条强制规则的底层实现可以精确追溯到源码:

  • 服务端在 src/openjarvis/cli/serve.py 启动前调用check_bind_safety(bind_host, api_key=api_key)
  • src/openjarvis/server/auth_middleware.py 中check_bind_safety的实现:当绑定地址不是 loopback(ipaddress.ip_address(host).is_loopback为假)且 API Key 为空时,直接打印错误并以SystemExit(1)拒绝启动,提示语即为Run: jarvis auth generate-key
  • 同理,systemd 侧通过 deploy/systemd/openjarvis.service 的EnvironmentFile=/etc/openjarvis/env强制要求存在包含OPENJARVIS_API_KEY的环境文件,缺失则 unit 启动失败——三者(Windows / launchd / systemd)在"非回环必须鉴权"这一安全边界上完全对齐。

在 jarvis-service.ps1 中还有第二道防线:install -ListenHost 0.0.0.0若发现$env:OPENJARVIS_API_KEY未设置,会直接失败并给出指引,而不是注册一个"每次登录都会因无密钥而拒绝启动"的坏任务。

一个关键的 Windows 平台细节:计划任务不继承环境变量

jarvis-service.ps1 的注释解释了 Windows 特有的坑:计划任务启动的进程不会继承注册时会话的环境变量。因此若你设置了OPENJARVIS_API_KEY来绑定0.0.0.0,脚本会额外把该 Key 持久化写入用户级环境变量[System.Environment]::SetEnvironmentVariable(..., 'User')),确保登录会话中的任务能读到它。这是只写回环地址时不需要、但 LAN 暴露时必须处理的步骤。

五、与 systemd / launchd 的对等关系(Parity Table)

关注点systemd(Linux)launchd(macOS)Windows
服务定义deploy/systemd/openjarvis.servicedeploy/launchd/com.openjarvis.plistdeploy/windows/jarvis-service.ps1(cmdlet 驱动)
默认绑定0.0.0.0(配 API Key)127.0.0.1(无 API Key)127.0.0.1(无 API Key)
失败重启Restart=on-failure RestartSec=5KeepAlive=trueRestartCount=3 RestartInterval=PT1M
自动启动multi-user.targetRunAtLoad=trueAtLogOn触发器

从上表可以看到一个有趣的设计差异:systemd 默认绑定0.0.0.0但强制要求 API KeyEnvironmentFile缺失则失败),而 launchd 与 Windows 默认回环绑定、无密钥即可用。三者的共同底线是:任何非回环暴露都必须有鉴权,只是"默认是否暴露"的取向不同。systemd 的 unit 还额外带了一套沙箱加固(ProtectSystem=strictPrivateTmp=trueNoNewPrivileges=true等,见 openjarvis.service),Windows 侧则以"受限权限计划任务"作为对应。

六、更新 OpenJarvis

两种更新方式任选其一:

方式一:git 手动更新

cd "$env:LOCALAPPDATA\OpenJarvis\src" git pull --ff-only uv sync --extra desktop --group desktop-native

--ff-only保证只做快进合并,避免本地改动导致更新失败。

方式二:重跑安装器并加-Force

irm https://open-jarvis.github.io/OpenJarvis/install.ps1 | iex # 再以文件方式重跑并传 -Force: # irm ... -OutFile install.ps1; .\install.ps1 -Force

-Force会强制重新执行所有步骤,包括git pull --ff-only与重新uv sync(依赖变化会在此生效)。注意更新后若服务依赖的命令或环境有变,建议重新执行一次jarvis-service.ps1 install以刷新计划任务。

七、卸载

powershell -ExecutionPolicy Bypass -File "$env:LOCALAPPDATA\OpenJarvis\src\deploy\windows\jarvis-service.ps1" uninstall Remove-Item -Recurse -Force "$env:LOCALAPPDATA\OpenJarvis"

卸载分两步:先通过uninstall子命令停止并注销计划任务(源码中会先Stop-ScheduledTaskUnregister-ScheduledTask),再删除整个安装目录。需要特别说明的是:卸载不会移除uv——它是独立工具,可能被你的其他 Python 项目共用;同理,Ollama 及其拉取的模型也不在卸载范围内,如需清理请另行处理。

八、常见问题与排障

  • jarvis命令找不到:安装脚本将bin目录写入了用户 PATH,但当前会话不生效。请新开 PowerShell 窗口;若仍不行,手动确认%LOCALAPPDATA%\OpenJarvis\bin\jarvis.cmd存在且 PATH 中包含该目录。
  • 首次对话失败:大概率是入门模型qwen3.5:2b未拉取完成。运行jarvis doctor查看模型与后台编排器(bg-orchestrator)的重试进度。
  • install -ListenHost 0.0.0.0报错:请先执行$env:OPENJARVIS_API_KEY = (uv run jarvis auth generate-key),再重试。服务端与脚本的双重防线都不允许无密钥的非回环绑定。
  • 任务启动后立刻退出且日志显示拒绝绑定:检查用户环境变量中是否持久化了OPENJARVIS_API_KEY(LAN 场景必需),以及jarvis serve依赖的引擎(如 Ollama)是否在运行。
  • Python 版本不符:当前仅支持 3.10–3.13(3.14 因 numpy 无 Windows wheels 暂不支持)。可通过winget install Python.Python.3.13安装后重跑安装器。

【免费下载链接】OpenJarvisPersonal AI, On Personal Devices项目地址: https://gitcode.com/gh_mirrors/op/OpenJarvis

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询