快速开始
选择一种栈 —— Web 或 Desktop —— 约 10 分钟内让 Agent 回应你的第一条消息。
十分钟内,Agent 回应你的第一条消息
跟完这篇,你会有一套本地跑起来的 Zapvol —— 要么是跑在 localhost:8000 的 Web 应用(Hono API 服务器 + PostgreSQL),要么是 Desktop 应用(Electron + 本地 SQLite)—— 并且 Agent 能回应你的第一条消息。文档末尾的 BUA 可选小节对两种栈都适用。
前置要求
| 要求 | 版本 | 说明 |
|---|---|---|
| Node.js | >= 20 | 推荐 LTS 版本 |
| pnpm | >= 11 | 通过 corepack enable 安装 |
| PostgreSQL | >= 15 | 仅 Web 栈需要(Desktop 用 SQLite) |
可选:
- Redis — 仅 Web 栈;用于可恢复 SSE 恢复(长 Agent 运行经页面刷新后继续)
- Daytona / E2B API 密钥 — 两种栈均可;仅当你想用云端沙箱代替本地沙箱时所需
- Chrome / Chromium — 仅当你要开发 BUA 扩展时所需
获取代码
git clone https://github.com/zapvol/zapvol.git
cd zapvol
pnpm install
pnpm install 是两种栈共享的步骤 —— 它会引导整个 monorepo。
选择你的栈
不需要两个都装 —— 选一个适合你目标的:
| 你的目标 | 选择 |
|---|---|
| 贡献 Web 前端或 API 服务器 | Web |
| 把 Zapvol 部署成多用户服务 | Web |
| 把 Zapvol 当作个人 Agent 跑在自己机器上 | Desktop |
| 开发 Electron / SQLite / 单用户特性 | Desktop |
两种栈共享同一套 Agent 引擎、UI 组件和工具集,区别在于存储、认证、传输方式和配置面。
Web 栈
双进程结构:Vite dev server 服务前端 + tsx watcher 跑 API 服务器。状态存在 PostgreSQL,认证走 better-auth。
配置服务端 .env
cp apps/server/.env.example apps/server/.env
最低必需配置:
# 数据库
DATABASE_URL=postgresql://postgres:postgres@localhost:5432/zapvol
# 认证 —— 生成至少 32 字符的随机字符串
BETTER_AUTH_SECRET=your-secret-key-at-least-32-chars
BASE_URL=http://localhost:8001
# AI —— Gateway 是推荐路径,所有模型调用都经它路由
AI_GATEWAY_API_KEY=your-ai-gateway-key
# 沙箱 —— 默认本地 Node 沙箱
SANDBOX_TYPE=node
关于 AI 密钥:Zapvol 默认通过 AI
Gateway 统一路由不同模型提供商。如果你没有 Gateway 密钥,可以退回到直连提供商密钥(ANTHROPIC_API_KEY=... 或
OPENAI_API_KEY=...)。NODE_SANDBOX_WORKSPACE 有合理默认值,只在你想固定沙箱根目录时才需要设置。
完整可选环境变量
# OAuth 提供商 —— 启用社交登录
GOOGLE_CLIENT_ID=
GOOGLE_CLIENT_SECRET=
GITHUB_CLIENT_ID=
GITHUB_CLIENT_SECRET=
# MCP OAuth 提供商 —— 启用需要 OAuth 的 MCP 服务器
LINEAR_CLIENT_ID=
LINEAR_CLIENT_SECRET=
# 网络搜索工具
TAVILY_API_KEY=
EXA_API_KEY=
# 云端沙箱 —— 不想用本地 Node 沙箱时选其一
DAYTONA_API_URL=https://app.daytona.io/api
DAYTONA_API_KEY=
E2B_API_KEY=
# 对象存储 —— 启用上下文卸载和文件上传
R2_ACCOUNT_ID=
R2_ACCESS_KEY_ID=
R2_SECRET_ACCESS_KEY=
R2_BUCKET_NAME=
R2_PUBLIC_URL=
# Skills —— Agent 加载技能的目录
SKILLS_DIR=./skills
设置数据库
createdb zapvol
pnpm --filter=@zapvol/server run db:reset
pnpm --filter=@zapvol/server run db:seed
对于首次安装,db:reset + db:seed 是标准的“全新开始”动作 —— db:reset 重建表结构,db:seed
填充默认模型、Agent、层级配置和演示账号。之后再次运行 db:reset 会丢失数据,请谨慎使用。
启动
pnpm dev:app
会同时启动两个进程 —— Web 前端在 localhost:8000,API 服务器在 localhost:8001。
验证
- 在浏览器中打开 http://localhost:8000
- 注册账号,或使用预置的演示账号登录
- 创建任务并向 Agent 发送一条消息
- Agent 应该开始流式回复,并在需要时调用工具
故障速查
| 现象 | 可能原因 |
|---|---|
| 第一条消息后模型返回 401 | AI_GATEWAY_API_KEY 为空或无效;或者退回到直连提供商密钥 |
| 服务端启动崩溃 | DATABASE_URL 错误,或 PostgreSQL 未运行 |
| 登录失败 / 重定向死循环 | BASE_URL 与服务器实际监听地址不一致 |
| Web 页面打开但 API 调用 404 | 服务端未运行,或端口不是 8001 |
| Agent 能回复但不使用工具 | SANDBOX_TYPE 未配置,或沙箱初始化失败(检查服务端日志) |
| 端口 8000 / 8001 已被占用 | 停止占用进程,或在对应 dev 脚本中改端口 |
Desktop 栈
单一 Electron 进程 + 本地 SQLite 存储。没有 PostgreSQL、没有 better-auth、没有 OAuth —— 桌面应用使用一个硬编码的
local-user,数据存在操作系统的用户级 app data 目录里。认证相关环境变量完全不读。
配置 desktop .env
cp apps/desktop/.env.example apps/desktop/.env
文件很短:
ELECTRON_RENDERER_URL=http://localhost:8002
# AI Gateway 密钥 —— 想让 Agent 开箱即用就填这个
AI_GATEWAY_API_KEY=your-ai-gateway-key
AI 密钥的两条路径:
- Gateway(如上)—— 填入
AI_GATEWAY_API_KEY,首次启动 Agent 即可工作 - BYOK (Bring Your Own Key) —— 把环境变量留空,首次启动后在应用的设置 → API Keys
页里按提供商添加密钥(Anthropic / OpenAI 等,通过 Electron
safeStorage加密保存)
如果两者都设置了,对应模型提供商以 BYOK 优先。
启动
pnpm dev:desktop
会以开发模式启动 Electron,renderer 由 localhost:8002
提供。SQLite 数据库在首次启动时自动创建在操作系统的用户级 app-data 目录:
| 操作系统 | 路径 |
|---|---|
| Windows | %APPDATA%\zapvol\ |
| macOS | ~/Library/Application Support/zapvol |
| Linux | ~/.config/zapvol |
验证
- Electron 窗口自动打开
- (仅 BYOK)打开设置 → API Keys,添加一个提供商密钥
- 创建任务并向 Agent 发送一条消息
- Agent 应该开始流式回复并调用工具
故障速查
| 现象 | 可能原因 |
|---|---|
| 窗口打开了,但发消息时 Agent 失败 | AI_GATEWAY_API_KEY 和 BYOK 密钥都没设;在设置里添加一个 |
| 工具调用失败或没有出现 | 沙箱依赖缺失;检查主进程控制台(视图 → 切换开发者工具 → Main Process) |
| 白屏 / 渲染不出内容 | ELECTRON_RENDERER_URL 与 dev 端口 8002 不一致 |
| 应用启动了但数据是空的 | 首次启动状态 —— 创建一个任务即可触发 SQLite schema 建立 |
| 想重置本地数据 | 退出应用,删除用户级 app-data 目录,重新启动 |
(可选)配置 BUA 浏览器扩展
BUA (Browser Use Agent) 是一个 Chrome 扩展,让 Agent 在你已登录的浏览器中行动,按域名授权。两种栈都适用。
Dev 模式(推荐)
pnpm dev:ext
WXT 会启动一个全新的 Chromium dev profile,扩展自动加载并启用 HMR —— 不需要手动
chrome://extensions,那只是生产构建的用法。
生产构建(装入你日常使用的 Chrome)
pnpm build:ext
然后在 Chrome 中:
- 打开
chrome://extensions - 启用开发者模式
- 点击加载已解压的扩展程序,选择
apps/bua/.output/chrome-mv3/
配对
配对流程因栈而异:
- Web 栈 —— 扩展通过 Chrome 的
externally_connectable通道与 web 应用通信,从 web 应用的 BUA 设置页发起配对 - Desktop 栈 —— Electron 在本地启动 loopback WebSocket 服务(
127.0.0.1:48123),并保存按机器生成的 pairing token;从桌面端 设置 → Browser Extension 复制 token 到扩展的 Options 页
完整指南:BUA 开发指南。
常用脚本
pnpm lint # 对所有包运行 ESLint
pnpm format # 使用 Prettier 格式化
pnpm format:check # 检查格式化但不修改文件
生产构建:pnpm build,或按范围:pnpm build:web、pnpm build:server、pnpm build:desktop、pnpm build:ext。
如果你想一次性启动所有 dev 进程(Web + Server + Desktop + Browser Extension),用
pnpm dev。日常开发推荐使用上面按栈的命令 —— pnpm dev 比大多数工作流所需的更重。
下一步
刚跑起来,顺着「系统」这一 tab 继续往里走:
- Agent Engine — 你刚跑起来的那个执行循环:
runAgentLoop怎么转、状态机、子系统怎么接进来 - 仓库架构 — 你刚 clone 的这套 monorepo:包的边界、依赖图、“加一个平台只是写适配器”
- 运维 — 把本地这套跑上生产:可观测栈、部署、运行时健康
- BUA 概览 — 可选:让 Agent 在你已登录的浏览器里按域授权行动