- 将项目品牌从nanobot重命名为Boardware Genius,更新所有相关文档、注释和日志输出 - 在web服务器中添加运行时环境变量同步功能,支持授权和后端身份配置 - 更新create-instance脚本以生成运行时环境文件 - 添加实例后端绑定功能到部署控制服务 - 修改入口脚本以加载运行时环境变量 - 更新前端和认证门户的相关描述文本
471 lines
12 KiB
Markdown
471 lines
12 KiB
Markdown
# Boardware Genius Backend
|
||
|
||
这是 `Boardware Genius` 的后端服务仓库;当前技术命令和包名仍沿用 `nanobot`,但产品品牌按 `Boardware Genius` 表述:
|
||
|
||
- `nanobot web`:单用户 FastAPI 后端,供独立前端或 `/docs` 调试使用
|
||
- `nanobot gateway`:常驻 worker,负责渠道接入、cron、heartbeat
|
||
- MCP 动态工具接入
|
||
- Outlook 集成:通过外部 `BW_Outlook_Mcp` 服务接入 Microsoft Graph / Exchange EWS
|
||
- 工作区文件、技能、插件、代理、MCP 管理等 Web API
|
||
|
||
如果你后续要把它打包成 Docker 丢到服务器,这份 README 就是给开发和部署同事看的执行文档。
|
||
|
||
## 这套仓库现在是什么
|
||
|
||
这不是一个自带前端静态页面的全栈仓库,而是后端仓库:
|
||
|
||
- Web 模式启动的是 FastAPI API 服务
|
||
- Gateway 模式启动的是常驻 agent / channel / cron 进程
|
||
- WhatsApp 相关逻辑依赖 `bridge/` 里的 Node 20 bridge
|
||
- Outlook 不是仓库内置模块,而是通过外部 `BW_Outlook_Mcp` 仓库接进来
|
||
|
||
更细的执行链路可以看 [workflow.md](./workflow.md)。
|
||
|
||
## 目录结构
|
||
|
||
```text
|
||
.
|
||
├── nanobot/ # Python 主体:CLI、agent、web、channels、config、MCP
|
||
├── bridge/ # WhatsApp bridge(Node 20)
|
||
├── tests/ # 测试
|
||
├── Dockerfile # 当前镜像构建文件
|
||
├── docker-compose.yml # 当前自带 compose 示例(偏 gateway / CLI)
|
||
└── workflow.md # 运行链路说明
|
||
```
|
||
|
||
## 运行模式
|
||
|
||
| 命令 | 用途 | 默认端口 | 适合谁 |
|
||
| --- | --- | --- | --- |
|
||
| `nanobot agent` | 本地单轮 / 交互调试 | 无 | 开发排查 |
|
||
| `nanobot web` | 启动 FastAPI 后端 | `18080` | 独立前端、接口调试、单用户使用 |
|
||
| `nanobot gateway` | 启动常驻 worker | 无固定 HTTP 入口 | Telegram/Slack/Email/cron/heartbeat |
|
||
| `nanobot status` | 查看配置和 provider 状态 | 无 | 开发、运维 |
|
||
|
||
注意:
|
||
|
||
- 如果你是给 Web 前端提供后端,请启动 `nanobot web`,不要误用 `gateway`
|
||
- `gateway` 当前不是对外 Web API 服务
|
||
- `web` 和 `gateway` 都会碰到同一份 workspace / cron / MCP 状态,通常不要在同一份数据目录上无脑同时跑两套
|
||
|
||
## 环境要求
|
||
|
||
- Python `>=3.11`
|
||
- 推荐使用 `uv`
|
||
- 如果要构建 WhatsApp bridge 或使用仓库自带 Dockerfile,需要 Node.js `20`
|
||
|
||
本地开发最省事的方式:
|
||
|
||
```bash
|
||
uv sync --extra dev
|
||
```
|
||
|
||
如果你不用 `uv`,也可以:
|
||
|
||
```bash
|
||
python3 -m venv .venv
|
||
. .venv/bin/activate
|
||
pip install -e ".[dev]"
|
||
```
|
||
|
||
## 本地快速启动
|
||
|
||
### 1. 初始化配置
|
||
|
||
```bash
|
||
nanobot onboard
|
||
```
|
||
|
||
初始化后默认会生成:
|
||
|
||
- 配置文件:`~/.nanobot/config.json`
|
||
- 工作区:`~/.nanobot/workspace`
|
||
|
||
### 2. 填最小配置
|
||
|
||
下面是一份适合服务器环境的最小示例,重点是:
|
||
|
||
- 用绝对路径的 workspace
|
||
- 建议打开 `restrictToWorkspace`
|
||
- 先用 API Key provider,少踩 OAuth 交互坑
|
||
|
||
```json
|
||
{
|
||
"agents": {
|
||
"defaults": {
|
||
"workspace": "/root/.nanobot/workspace",
|
||
"model": "openai/gpt-5"
|
||
}
|
||
},
|
||
"providers": {
|
||
"openai": {
|
||
"apiKey": "sk-xxxx"
|
||
}
|
||
},
|
||
"tools": {
|
||
"restrictToWorkspace": true
|
||
}
|
||
}
|
||
```
|
||
|
||
如果你不是跑在容器里,把 `/root/.nanobot/workspace` 换成你自己的绝对路径。
|
||
|
||
### 3. 检查配置
|
||
|
||
```bash
|
||
nanobot status
|
||
```
|
||
|
||
### 4. 本地调试 agent
|
||
|
||
```bash
|
||
nanobot agent -m "你好"
|
||
```
|
||
|
||
### 5. 启动 Web 后端
|
||
|
||
```bash
|
||
nanobot web --host 0.0.0.0 --port 18080
|
||
```
|
||
|
||
启动后可直接访问:
|
||
|
||
- `http://127.0.0.1:18080/docs`
|
||
- `http://127.0.0.1:18080/api/ping`
|
||
|
||
## Web API 能力概览
|
||
|
||
当前 `nanobot web` 提供的 API 大致包括:
|
||
|
||
- 聊天与流式输出
|
||
- 会话管理
|
||
- cron 任务管理
|
||
- skills / plugins / agents 管理
|
||
- 工作区文件浏览、上传、下载、删除
|
||
- MCP server 管理与测试
|
||
- Outlook 集成状态、连接测试、连接/断开、Overview、Message Detail
|
||
|
||
如果你有独立前端,这个后端就是给前端接的;如果没有前端,也可以直接走 `/docs` 调试。
|
||
|
||
## Outlook MCP 集成
|
||
|
||
这是当前仓库里最容易部署时踩坑的一块。
|
||
|
||
### 关系先说清楚
|
||
|
||
当前后端不会自己实现 Outlook 协议,它依赖外部仓库 `BW_Outlook_Mcp`:
|
||
|
||
- 后端代码位置:`nanobot/web/outlook.py`
|
||
- 默认查找逻辑:
|
||
1. 先看环境变量 `NANOBOT_OUTLOOK_MCP_ROOT`
|
||
2. 再看与本仓库同级目录的 `../BW_Outlook_Mcp`
|
||
3. 如果以上都没有,就尝试直接执行 PATH 里的 `bw-outlook-mcp`
|
||
|
||
也就是说,部署同事必须额外把 `BW_Outlook_Mcp` 这个仓库准备好,或者把它直接安装进镜像。
|
||
|
||
### 推荐的两种接法
|
||
|
||
#### 方案 A:把 `BW_Outlook_Mcp` 安装进同一个 Python 环境
|
||
|
||
这是生产环境更稳的方案。
|
||
|
||
部署同事需要:
|
||
|
||
```bash
|
||
git clone <你们的 BW_Outlook_Mcp 仓库地址> /srv/BW_Outlook_Mcp
|
||
cd /srv/BW_Outlook_Mcp
|
||
pip install -e .
|
||
```
|
||
|
||
安装完成后,容器或宿主机里能直接执行:
|
||
|
||
```bash
|
||
bw-outlook-mcp --help
|
||
```
|
||
|
||
这样 Boardware Genius 就会直接用 PATH 里的 `bw-outlook-mcp`,不依赖额外挂载路径。
|
||
|
||
#### 方案 B:把 `BW_Outlook_Mcp` 作为外部目录挂进来
|
||
|
||
这是开发或临时部署更方便的方案。
|
||
|
||
部署同事需要至少做到两件事:
|
||
|
||
1. 把 `BW_Outlook_Mcp` 仓库拉到服务器
|
||
2. 让这个目录里存在一个可执行的 `bw-outlook-mcp`
|
||
|
||
最简单的约定是:
|
||
|
||
```bash
|
||
git clone <你们的 BW_Outlook_Mcp 仓库地址> /srv/BW_Outlook_Mcp
|
||
cd /srv/BW_Outlook_Mcp
|
||
python3 -m venv .venv
|
||
. .venv/bin/activate
|
||
pip install -e .
|
||
```
|
||
|
||
然后给 Boardware Genius 设置:
|
||
|
||
```bash
|
||
export NANOBOT_OUTLOOK_MCP_ROOT=/srv/BW_Outlook_Mcp
|
||
```
|
||
|
||
因为当前后端会优先寻找:
|
||
|
||
```text
|
||
$NANOBOT_OUTLOOK_MCP_ROOT/.venv/bin/bw-outlook-mcp
|
||
```
|
||
|
||
如果你挂了仓库目录但里面没有 `.venv/bin/bw-outlook-mcp`,那就必须确保 `bw-outlook-mcp` 已经在容器 PATH 里。
|
||
|
||
### Outlook 的认证和配置
|
||
|
||
`BW_Outlook_Mcp` 本身支持两套后端:
|
||
|
||
- `graph`:Microsoft 365 / Exchange Online
|
||
- `ews`:本地或回迁后的 Exchange Server
|
||
|
||
#### Graph 登录
|
||
|
||
```bash
|
||
bw-outlook-mcp auth login-graph \
|
||
--workspace /root/.nanobot/workspace \
|
||
--client-id YOUR_CLIENT_ID \
|
||
--tenant-id YOUR_TENANT_ID
|
||
```
|
||
|
||
#### EWS 配置
|
||
|
||
```bash
|
||
bw-outlook-mcp auth setup-ews \
|
||
--workspace /root/.nanobot/workspace \
|
||
--email you@example.com \
|
||
--username your_username \
|
||
--domain example.com \
|
||
--server mail.example.com
|
||
```
|
||
|
||
如果你已经有固定 EWS URL,也可以改用:
|
||
|
||
```bash
|
||
bw-outlook-mcp auth setup-ews \
|
||
--workspace /root/.nanobot/workspace \
|
||
--email you@example.com \
|
||
--username your_username \
|
||
--service-endpoint https://mail.example.com/EWS/Exchange.asmx
|
||
```
|
||
|
||
#### 查看状态
|
||
|
||
```bash
|
||
bw-outlook-mcp auth status --workspace /root/.nanobot/workspace
|
||
```
|
||
|
||
### Outlook 状态文件会落在哪里
|
||
|
||
所有 Outlook 相关状态默认都落在 workspace 下:
|
||
|
||
```text
|
||
<workspace>/state/bw_outlook_mcp/
|
||
├── config.json
|
||
├── secrets.json
|
||
├── graph_token_cache.bin
|
||
├── delta_store.json
|
||
└── idempotency.sqlite3
|
||
```
|
||
|
||
所以 Docker 部署时,不要只挂配置文件;要把整份 `~/.nanobot` 或至少 workspace 做持久化。
|
||
|
||
### Nanobot 里如何注册 Outlook MCP
|
||
|
||
如果你通过 Web 接口完成 Outlook 连接,后端会自动把 MCP server 注册到配置里。
|
||
|
||
手工写配置时,结构类似这样:
|
||
|
||
```json
|
||
{
|
||
"tools": {
|
||
"mcpServers": {
|
||
"outlook": {
|
||
"command": "bw-outlook-mcp",
|
||
"args": ["serve", "--workspace", "/root/.nanobot/workspace"],
|
||
"sensitive": true,
|
||
"toolTimeout": 60
|
||
}
|
||
}
|
||
}
|
||
}
|
||
```
|
||
|
||
这里一定要用绝对路径,不要写 `~/.nanobot/workspace`。
|
||
|
||
### 可选的 Outlook 环境变量
|
||
|
||
| 变量 | 作用 |
|
||
| --- | --- |
|
||
| `NANOBOT_OUTLOOK_MCP_ROOT` | 指向外部 `BW_Outlook_Mcp` 仓库目录 |
|
||
| `NANOBOT_OUTLOOK_MCP_COMMAND` | 强制指定 `bw-outlook-mcp` 可执行文件 |
|
||
| `NANOBOT_OUTLOOK_MCP_EXTRA_ARGS` | 给 `bw-outlook-mcp serve` 追加参数 |
|
||
| `NANOBOT_OUTLOOK_DEFAULT_DOMAIN` | Web 连接表单的默认域名 |
|
||
| `NANOBOT_OUTLOOK_DEFAULT_EWS_URL` | Web 连接表单默认 EWS 地址 |
|
||
| `NANOBOT_OUTLOOK_DEFAULT_EWS_SERVER` | Web 连接表单默认 Exchange 主机 |
|
||
| `NANOBOT_OUTLOOK_DEFAULT_TIMEZONE` | Web 连接表单默认时区 |
|
||
| `NANOBOT_OUTLOOK_DEFAULT_AUTODISCOVER` | Web 连接表单默认是否启用 autodiscover |
|
||
|
||
## Docker 部署
|
||
|
||
### 先说结论
|
||
|
||
服务器部署时,最重要的是持久化这份目录:
|
||
|
||
```text
|
||
/root/.nanobot
|
||
```
|
||
|
||
因为它里面不只是 `config.json`,还包括:
|
||
|
||
- workspace
|
||
- sessions
|
||
- cron 状态
|
||
- Web 登录信息
|
||
- Outlook 状态与 token 缓存
|
||
|
||
### 构建镜像
|
||
|
||
```bash
|
||
docker build -t nanobot-backend:latest .
|
||
```
|
||
|
||
### 首次初始化
|
||
|
||
第一次跑容器时,先执行一次:
|
||
|
||
```bash
|
||
docker run --rm \
|
||
-v /srv/nanobot/data:/root/.nanobot \
|
||
nanobot-backend:latest \
|
||
onboard
|
||
```
|
||
|
||
然后去编辑宿主机上的:
|
||
|
||
```text
|
||
/srv/nanobot/data/config.json
|
||
```
|
||
|
||
或者先进去执行:
|
||
|
||
```bash
|
||
docker run --rm -it \
|
||
-v /srv/nanobot/data:/root/.nanobot \
|
||
nanobot-backend:latest \
|
||
status
|
||
```
|
||
|
||
### 作为 Web 后端启动
|
||
|
||
如果你是给前端项目配后端,推荐这样跑:
|
||
|
||
```bash
|
||
docker run -d \
|
||
--name nanobot-web \
|
||
-p 18080:18080 \
|
||
-v /srv/nanobot/data:/root/.nanobot \
|
||
-e NANOBOT_OUTLOOK_MCP_ROOT=/opt/BW_Outlook_Mcp \
|
||
-v /srv/BW_Outlook_Mcp:/opt/BW_Outlook_Mcp \
|
||
nanobot-backend:latest \
|
||
web --host 0.0.0.0 --port 18080
|
||
```
|
||
|
||
如果你已经把 `bw-outlook-mcp` 安装进镜像了,就不需要挂 `/srv/BW_Outlook_Mcp`,也不需要 `NANOBOT_OUTLOOK_MCP_ROOT`。
|
||
|
||
### 作为 Gateway/Worker 启动
|
||
|
||
如果你要接 Telegram / Slack / Email / cron 之类的常驻能力,再跑 gateway:
|
||
|
||
```bash
|
||
docker run -d \
|
||
--name nanobot-gateway \
|
||
-v /srv/nanobot/data:/root/.nanobot \
|
||
nanobot-backend:latest \
|
||
gateway
|
||
```
|
||
|
||
### 推荐的服务器 compose 片段
|
||
|
||
仓库自带的 [docker-compose.yml](./docker-compose.yml) 更偏本地 gateway/CLI 示例。
|
||
如果你是部署 Web 后端到服务器,更建议单独写成这样:
|
||
|
||
```yaml
|
||
services:
|
||
nanobot-web:
|
||
image: nanobot-backend:latest
|
||
container_name: nanobot-web
|
||
command: ["web", "--host", "0.0.0.0", "--port", "18080"]
|
||
restart: unless-stopped
|
||
ports:
|
||
- "18080:18080"
|
||
volumes:
|
||
- /srv/nanobot/data:/root/.nanobot
|
||
- /srv/BW_Outlook_Mcp:/opt/BW_Outlook_Mcp
|
||
environment:
|
||
NANOBOT_OUTLOOK_MCP_ROOT: /opt/BW_Outlook_Mcp
|
||
```
|
||
|
||
如果你想把 Outlook 依赖做得更稳,推荐直接把 `BW_Outlook_Mcp` 安装进镜像,而不是运行时挂载仓库。
|
||
|
||
## 部署给同事时,至少要交代这几件事
|
||
|
||
1. 这是后端仓库,不带前端静态页面,前端请单独部署
|
||
2. Web API 用 `nanobot web` 启动,不是 `gateway`
|
||
3. 数据目录必须持久化到 `/root/.nanobot`
|
||
4. 如果要 Outlook,必须额外拉取 `BW_Outlook_Mcp`
|
||
5. Outlook 有两种接法:装进镜像,或者挂外部仓库并设置 `NANOBOT_OUTLOOK_MCP_ROOT`
|
||
6. Outlook 的状态文件也在 workspace 里,删容器不挂卷就会丢
|
||
|
||
## 常用命令
|
||
|
||
```bash
|
||
nanobot onboard
|
||
nanobot status
|
||
nanobot agent -m "你好"
|
||
nanobot web --host 0.0.0.0 --port 18080
|
||
nanobot gateway
|
||
nanobot provider login openai-codex
|
||
```
|
||
|
||
## 开发备注
|
||
|
||
- `workflow.md` 记录了当前代码实际运行链路,和旧版 README 更接近“真实代码”
|
||
- `nanobot/web/outlook.py` 是当前 Outlook 集成入口
|
||
- `tests/` 里有 Web API、Email、Docker 相关测试
|
||
- 如果要上服务器,建议在配置里显式打开 `tools.restrictToWorkspace=true`
|
||
|
||
## 排错
|
||
|
||
### Web 启动了,但 Outlook 相关接口报错
|
||
|
||
优先检查:
|
||
|
||
- `bw-outlook-mcp` 是否能在当前容器里执行
|
||
- `NANOBOT_OUTLOOK_MCP_ROOT` 是否指向正确目录
|
||
- 如果走目录挂载模式,目录里是否真的有 `.venv/bin/bw-outlook-mcp`
|
||
|
||
### MCP 注册了,但工具没有出现
|
||
|
||
检查:
|
||
|
||
- `config.json` 里的 `tools.mcpServers`
|
||
- `nanobot web` 或 `nanobot agent` 启动时是否用了同一份 `~/.nanobot`
|
||
- Outlook MCP 是否能单独执行 `bw-outlook-mcp auth status --workspace ...`
|
||
|
||
### Docker 里配置改了没生效
|
||
|
||
优先检查你挂载的是不是整份:
|
||
|
||
```text
|
||
/srv/nanobot/data:/root/.nanobot
|
||
```
|
||
|
||
不是只挂了某一个文件。
|