修改了nanobot,往Hermes agent的风格走,进度1/3
470
app-instance/backend-old/README.md
Normal file
@ -0,0 +1,470 @@
|
||||
# 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
|
||||
```
|
||||
|
||||
不是只挂了某一个文件。
|
||||
|
Before Width: | Height: | Size: 12 MiB After Width: | Height: | Size: 12 MiB |
|
Before Width: | Height: | Size: 5.6 MiB After Width: | Height: | Size: 5.6 MiB |
|
Before Width: | Height: | Size: 6.8 MiB After Width: | Height: | Size: 6.8 MiB |
|
Before Width: | Height: | Size: 6.0 MiB After Width: | Height: | Size: 6.0 MiB |
799
app-instance/backend-old/change.md
Normal file
@ -0,0 +1,799 @@
|
||||
# Beaver Backend 重构蓝图
|
||||
|
||||
## 命名说明
|
||||
|
||||
当前项目正式名称已经不是 `nanobot`,而是 `beaver`。
|
||||
|
||||
这份文档里如果出现 `nanobot/...`,一律表示“当前仓库里还没迁走的历史代码路径 / 现状实现位置”,不代表目标命名。
|
||||
|
||||
后续重构目标应统一收敛到:
|
||||
|
||||
1. 产品名、项目名、运行时内核名统一按 `beaver` 表达。
|
||||
2. `nanobot` 只作为迁移期遗留路径存在,最终应逐步退出目录、模块和文档命名。
|
||||
3. 新增目录、新增模块、新增文档都应优先使用 `beaver` 命名,而不是继续扩散 `nanobot`。
|
||||
|
||||
## 1. 这次重构到底要解决什么
|
||||
|
||||
当前后端已经不是“功能不够”,而是“能力已经长出来了,但结构还停留在早期阶段”。
|
||||
|
||||
现在项目里同时存在这些事实:
|
||||
|
||||
1. `AgentLoop` 已经承担了太多职责,既管主 agent 对话,又管工具、委派、MCP、会话、事件、memory。
|
||||
2. `web/server.py` 已经变成超大文件,FastAPI app factory、chat API、session、文件、skills、cron、A2A、Outlook 都放在一起。
|
||||
3. `agent_team` 已经接上了 `swarms`,但目前更像“业务层直接借用第三方 runtime”,不是“我们自己的多智能体平台”。
|
||||
4. `skills` 已经有加载、安装、审核,但本质还是 Markdown 说明书,不是可学习、可演化、可评估的能力对象。
|
||||
5. 项目里已经隐约出现了三个方向,但还没有被统一成一个完整架构:
|
||||
- `swarms` 提供多智能体架构能力
|
||||
- `hermes-agent` 提供 skill 生命周期与长期演进思路
|
||||
- `OpenHarness` 提供模块化的 harness 设计方法
|
||||
|
||||
所以这次重构不是简单“整理目录”,而是把项目从“围绕一个 CLI 主 agent 生长出来的系统”升级成“所有 agent 共享同一内核的自有 agent harness 平台”。
|
||||
|
||||
## 2. 我是怎么想的
|
||||
|
||||
我的核心判断是:我们不能继续把第三方库、业务流程、执行控制、UI/API 接口揉在一起,而是应该先定义我们自己的稳定边界,再让第三方能力挂进来。
|
||||
|
||||
换句话说,目标不是“把仓库改得更像 swarms / hermes / OpenHarness”,而是:
|
||||
|
||||
1. 用 `swarms` 的强项来解决“团队编排”。
|
||||
2. 用 `hermes-agent` 的强项来解决“skills 怎么创建、维护、学习、沉淀”。
|
||||
3. 用 `OpenHarness` 的强项来解决“工程边界、模块职责、可维护性”。
|
||||
4. 最终收口成我们自己的抽象和目录,而不是长期让第三方结构反向塑造我们。
|
||||
|
||||
这意味着后续所有设计都应遵守四条原则:
|
||||
|
||||
### 2.1 我们要有自己的抽象
|
||||
|
||||
不能让业务代码直接依赖:
|
||||
|
||||
- `third_party/swarms` 的导入路径
|
||||
- `SwarmRouter` 的参数细节
|
||||
- 某个第三方 skill 文件格式
|
||||
- 某个第三方 runtime 的副作用
|
||||
|
||||
我们应该先定义自己的核心对象,例如:
|
||||
|
||||
- `AgentDescriptor`
|
||||
- `SkillSpec`
|
||||
- `SkillVersion`
|
||||
- `TeamSpec`
|
||||
- `ExecutionPlan`
|
||||
- `ProcedureRecord`
|
||||
- `RunRecord`
|
||||
- `BridgeResult`
|
||||
|
||||
第三方库只能作为 adapter / backend 存在。
|
||||
|
||||
### 2.2 所有 agent 共享同一套运行内核
|
||||
|
||||
后面不应该再保留“CLI 单 agent”和“其他 agent 另一套执行方式”这种概念分叉。
|
||||
|
||||
正确做法应该是:
|
||||
|
||||
1. 所有 agent 都复用同一个 `AgentLoop` / engine。
|
||||
2. 主 agent、subagent、team member、A2A local specialist 都只是不同的运行配置和上下文。
|
||||
3. tools、skills、memory、permissions、MCP、delegation 都在同一套内核里装载。
|
||||
4. CLI 只是一个 interface,作用是把用户输入送进内核,而不是代表一种单独的 agent 类型。
|
||||
|
||||
这样做的意义是:
|
||||
|
||||
1. 所有 agent 的能力边界一致。
|
||||
2. 不会再出现“这个能力只在 CLI 主 agent 可用,子 agent 不一致”的问题。
|
||||
3. agent 的差异只存在于 profile / policy / prompt / runtime context,而不是存在于不同执行栈里。
|
||||
|
||||
### 2.3 Harness 和业务要分开
|
||||
|
||||
当前很多逻辑混在一起:既有“平台级能力”,也有“具体产品接入”。
|
||||
|
||||
后面应该分成两层:
|
||||
|
||||
1. Harness 层
|
||||
- tool use
|
||||
- skills
|
||||
- memory
|
||||
- delegation
|
||||
- orchestration
|
||||
- governance
|
||||
2. Product / Interface 层
|
||||
- web API
|
||||
- gateway
|
||||
- channel adapters
|
||||
- Outlook / WhatsApp / 外部服务接入
|
||||
|
||||
这样平台能力才能稳定,接入层才能随产品变化而变化。
|
||||
|
||||
### 2.4 多智能体是平台能力,不是工具技巧
|
||||
|
||||
现在 `spawn_agent_team` 已经存在,但在结构上还像“一个高级工具”。
|
||||
|
||||
后面应该把 multi-agent 当成正式 runtime 能力:
|
||||
|
||||
- 有 plan 层 (计划)
|
||||
- 有 strategy 层 (策略)
|
||||
- 有 execution backend 层 (执行后端)
|
||||
- 有 result normalization 层 (结果归一化)
|
||||
- 有 memory / procedure reuse 层 (内存/过程重用)
|
||||
- 有 governance / safety / skill constraints (治理/安全/技能限制)
|
||||
|
||||
这里要特别说明 `2.4` 和 `2.5` 的关系:
|
||||
|
||||
1. multi-agent 不是独立于 skills 的第二套指导系统。
|
||||
2. 我们仍然保留之前的群组讨论机制,也就是“探索式协作 + 流程化执行”两种能力都保留。
|
||||
3. 但无论是探索式 group discussion,还是流程化 sequential / rearrange / hierarchy,都必须受 skills 指引和约束。
|
||||
4. 也就是说,skills 决定“应该如何思考、遵守什么边界、优先采用什么方法”,而 multi-agent 负责“由几个人、以什么结构去执行”。
|
||||
|
||||
所以后续正确关系应是:
|
||||
|
||||
`skills -> 约束与方法指导`
|
||||
`multi-agent -> 在 skills 约束下进行探索、讨论、流程化执行`
|
||||
|
||||
### 2.5 skills 必须变成生命周期系统
|
||||
|
||||
现在的 skills 更像可读文档包,适合“手工维护”,不适合“自动学习”。
|
||||
|
||||
如果以后要做到自动创建、自动修订、自动推荐、自动淘汰,skills 必须具备:
|
||||
|
||||
- 结构化元数据
|
||||
- 版本号
|
||||
- 来源与 lineage
|
||||
- 审核状态
|
||||
- 效果统计
|
||||
- 与 procedure 的映射关系
|
||||
- 可回滚、可禁用、可发布
|
||||
|
||||
并且这里的 `skills` 不应只服务于“工具使用技巧”,而应成为整个 agent 系统的统一指引层,包括:
|
||||
|
||||
1. 主 agent 如何规划和执行
|
||||
2. subagent / team member 如何行动
|
||||
3. memory 如何参与判断
|
||||
4. procedure reuse 如何被触发和约束
|
||||
5. multi-agent 讨论时允许采用哪些方法、角色分工和输出习惯
|
||||
|
||||
换句话说:
|
||||
|
||||
1. memory / procedure reuse 不是独立于 skills 的平行系统。
|
||||
2. 但 memory 的实现标准要以 `hermes-agent` 为准,而不是继续沿用当前偏自由发挥的记忆模型。
|
||||
3. skills 提供全局行为指引;memory 只保存跨会话仍然有价值的稳定事实;session_search 负责找回历史细节;procedure 只作为可选优化层。
|
||||
|
||||
这里要明确四者分工:
|
||||
|
||||
1. `skills`
|
||||
- 指导“怎么做”
|
||||
- 约束工具使用、讨论方式、流程化执行方式
|
||||
2. `memory`
|
||||
- 保存 durable facts
|
||||
- 例如用户偏好、环境事实、项目约定、工具 quirks
|
||||
3. `session_search`
|
||||
- 检索历史会话细节
|
||||
- 不把大量过程细节直接塞进 memory
|
||||
4. `procedure`
|
||||
- 作为 coordinator 内部的复用优化
|
||||
- 不是主 memory 契约,也不是主要 prompt 注入来源
|
||||
|
||||
## 3. 现有项目现在是咋样的
|
||||
|
||||
### 3.1 当前的主结构
|
||||
|
||||
从代码上看,`app-instance/backend` 当前大致是这几块。
|
||||
|
||||
注意:下面这些路径仍写作 `nanobot/...`,是因为这里描述的是“现状代码位置”,不是目标命名。
|
||||
|
||||
1. 启动与装配
|
||||
- `nanobot/cli/commands.py`
|
||||
- `nanobot/__main__.py`
|
||||
2. agent 运行时
|
||||
- `nanobot/agent/loop.py`
|
||||
- `nanobot/agent/context.py`
|
||||
- `nanobot/agent/tools/*`
|
||||
- `nanobot/session/*`
|
||||
- `nanobot/providers/*`
|
||||
3. 多 agent / 委派
|
||||
- `nanobot/agent/delegation.py`
|
||||
- `nanobot/agent_team/*`
|
||||
- `nanobot/a2a/*`
|
||||
4. Web / Gateway / Channels
|
||||
- `nanobot/web/server.py`
|
||||
- `nanobot/channels/*`
|
||||
- `bridge/`
|
||||
5. 技能与插件
|
||||
- `nanobot/skills/*`
|
||||
- `nanobot/agent/skills.py`
|
||||
- `nanobot/agent/plugins.py`
|
||||
6. 外部运行时耦合点
|
||||
- 当前主要是 vendored `swarms`
|
||||
|
||||
### 3.2 当前已经有的优点
|
||||
|
||||
这套代码不是没基础,相反已经有几个很有价值的雏形:
|
||||
|
||||
1. 已经有 `AgentRegistry`、`DelegationManager`、`agent_team`,说明“统一委派层”思路已经出现。
|
||||
2. 已经有 `ProcedureMemory` 和 `RunMemory`,说明“从执行中学习”的基础数据层已经出现。
|
||||
3. 已经有 `skills` 的加载、安装、审核,说明“受控扩展机制”已经存在。
|
||||
4. 已经有 `SwarmsBridge`、`SwarmsPolicy`、`SwarmsRunPlanner`,说明多智能体桥接已经不是空白。
|
||||
|
||||
所以这次重构不是推倒重来,而是把这些散落的雏形收敛成一个完整架构。
|
||||
|
||||
### 3.3 当前最主要的问题
|
||||
|
||||
#### 问题一:装配逻辑散落
|
||||
|
||||
同一个后端能力,在 CLI、Web、Gateway 中经常重复装配,甚至行为已经开始漂移。
|
||||
|
||||
这会导致:
|
||||
|
||||
1. 同样的配置在不同入口行为不同。
|
||||
2. 改一个入口容易漏另一个入口。
|
||||
3. 测试覆盖变难。
|
||||
|
||||
#### 问题二:`AgentLoop` 太重,但又没有成为唯一内核
|
||||
|
||||
`AgentLoop` 已经不是纯 loop,而是“半个 runtime 内核”。
|
||||
|
||||
这会导致:
|
||||
|
||||
1. 主 agent 与其他 agent 的边界不清。
|
||||
2. tool、memory、delegation、session、events 相互缠绕。
|
||||
3. 很多能力只能靠继续往 `AgentLoop` 里塞。
|
||||
4. 同时又没有真正做到“所有 agent 都统一复用它”。
|
||||
|
||||
#### 问题三:`swarms` 接入边界不干净,而且 `third_party` 目录本身会持续恶化维护成本
|
||||
|
||||
当前 `agent_team` 虽然有 bridge,但仍然直接依赖:
|
||||
|
||||
1. `sys.path` 注入 vendored `swarms`
|
||||
2. 顶层 `swarms` 包导入副作用
|
||||
3. `SwarmRouter` 的参数细节
|
||||
4. `AutoSwarmBuilder` 自己的 LLM 栈
|
||||
|
||||
这意味着现在不是“我们调度 swarms”,而是“我们的平台有一部分被 swarms runtime 反向定义了”。
|
||||
|
||||
另外,`third_party/` 这种目录在这个项目里不应该长期存在。它会带来两个问题:
|
||||
|
||||
1. 仓库边界不清,到底哪些代码是我们的,哪些不是,很难维护。
|
||||
2. 一旦改动第三方源码,升级、回滚、排障都会变得更脆弱。
|
||||
|
||||
#### 问题四:skills 还是静态文档包
|
||||
|
||||
现在的 skill 系统适合:
|
||||
|
||||
- 展示
|
||||
- 人工安装
|
||||
- prompt 注入
|
||||
|
||||
但不适合:
|
||||
|
||||
- 自动学习
|
||||
- 自动合并
|
||||
- 自动评估
|
||||
- 版本回滚
|
||||
- 基于效果做选择
|
||||
|
||||
#### 问题五:接口层和核心层耦合过深
|
||||
|
||||
`web/server.py` 过大说明一个事实:
|
||||
|
||||
平台内核与外部 API、外部接入、外部服务没有完成分层。
|
||||
|
||||
## 4. 后面应该怎么改
|
||||
|
||||
## 4.1 先把系统改成 OpenHarness 风格的能力分组
|
||||
|
||||
这里我建议明确参考 OpenHarness 那种“按能力分组、核心目录更扁平”的结构,而不是继续按历史演化路径堆目录。
|
||||
|
||||
核心思路是:
|
||||
|
||||
1. 用 `engine` 作为唯一运行内核。
|
||||
2. 用 `coordinator` 负责委派和多 agent 编排。
|
||||
3. 用 `tools`、`skills`、`memory`、`permissions` 作为独立能力层。
|
||||
4. 用 `interfaces` 只放 CLI / Web / Gateway / Channels 这类入口。
|
||||
5. 用 `integrations` 放外部协议和外部系统适配。
|
||||
|
||||
这样拆完之后,模块关系应变成:
|
||||
|
||||
`interfaces -> engine/coordinator/tools/skills/memory -> foundation`
|
||||
|
||||
而不是像现在这样互相横穿。
|
||||
|
||||
## 4.2 彻底去掉 `third_party/`,把 `swarms` 改造成可替换 backend
|
||||
|
||||
### 当前状态
|
||||
|
||||
现在的 `agent_team` 已经接通:
|
||||
|
||||
- `GroupChat`
|
||||
- `SequentialWorkflow`
|
||||
- `ConcurrentWorkflow`
|
||||
- `AgentRearrange`
|
||||
- `MixtureOfAgents`
|
||||
- `HierarchicalSwarm`
|
||||
|
||||
但这些能力还不是“平台正式能力集合”,而是“当前 bridge 恰好能跑通的一部分 swarms 类型”。
|
||||
|
||||
更重要的是,当前它们依赖 `third_party/swarms` 这个 vendored 目录,这是后续必须去掉的。
|
||||
|
||||
### 目标状态
|
||||
|
||||
后续应该先定义我们自己的团队执行抽象:
|
||||
|
||||
```text
|
||||
TeamSpec
|
||||
-> TeamPlanner
|
||||
-> ExecutionPlan
|
||||
-> StrategyBackend
|
||||
-> NormalizedResult
|
||||
```
|
||||
|
||||
然后:
|
||||
|
||||
1. `SwarmsBackend` 只是 `StrategyBackend` 的一个实现。
|
||||
2. 平台对外暴露的是自己的策略名和能力矩阵。
|
||||
3. `swarms` 只负责执行,不再负责定义平台边界。
|
||||
4. 仓库内不再保留 `third_party/`。
|
||||
5. `swarms` 要么作为外部依赖安装,要么把真正需要的最小能力内聚到我们自己的 backend 模块中。
|
||||
|
||||
### 具体改法
|
||||
|
||||
1. 抽出 `coordinator/backends/base.py`
|
||||
- 定义统一 backend 接口
|
||||
2. 抽出 `coordinator/backends/swarms/`
|
||||
- 把 `swarms_adapter.py`
|
||||
- `swarms_bridge.py`
|
||||
- `swarms_policy.py`
|
||||
- `swarms_planner.py` 中 swarms 相关逻辑收进去
|
||||
3. 在平台层定义正式支持的 strategy
|
||||
- `group_chat`
|
||||
- `sequential`
|
||||
- `concurrent`
|
||||
- `rearrange`
|
||||
- `mixture`
|
||||
- `hierarchical`
|
||||
- 后续预留 `graph`
|
||||
- 后续预留 `heavy`
|
||||
4. 所有 strategy 的输入输出都转成我们的统一模型
|
||||
|
||||
### 结果
|
||||
|
||||
改完之后:
|
||||
|
||||
1. `third_party/` 目录消失。
|
||||
2. 上层不再知道 `third_party/swarms` 这个路径。
|
||||
3. 对上层透明的是 `SwarmsBackend`,不是 vendored 源码目录。
|
||||
|
||||
## 4.3 把 `skills` 从静态文档升级成能力生命周期系统
|
||||
|
||||
### 当前状态
|
||||
|
||||
现在 skill 基本等于:
|
||||
|
||||
- 一个目录
|
||||
- 一个 `SKILL.md`
|
||||
- 一点 frontmatter
|
||||
- 一点审核流程
|
||||
|
||||
### 目标状态
|
||||
|
||||
后续 skill 至少要分成三类对象:
|
||||
|
||||
1. `SkillDraft`
|
||||
- 自动生成或人工创建
|
||||
- 还没发布
|
||||
2. `SkillVersion`
|
||||
- 某个稳定版本
|
||||
- 可启用/禁用/回滚
|
||||
3. `SkillRuntimeView`
|
||||
- 当前对模型暴露的生效版本
|
||||
|
||||
同时 skill 应该带这些元信息:
|
||||
|
||||
- `id`
|
||||
- `name`
|
||||
- `version`
|
||||
- `summary`
|
||||
- `usage_rules`
|
||||
- `inputs`
|
||||
- `outputs`
|
||||
- `dependencies`
|
||||
- `source`
|
||||
- `derived_from_procedure`
|
||||
- `review_status`
|
||||
- `metrics`
|
||||
|
||||
### 自动学习建议
|
||||
|
||||
不要直接让 agent 在线改 live skills。
|
||||
|
||||
正确链路应该是:
|
||||
|
||||
`run result -> procedure candidate -> skill draft -> review -> publish -> runtime use`
|
||||
|
||||
这比“自动改 `SKILL.md`”安全得多,也更适合生产环境。
|
||||
|
||||
### 结果
|
||||
|
||||
改完之后,skills 不再只是 prompt 资源,而是平台知识层的一等对象。
|
||||
|
||||
## 4.4 以 `hermes-agent` 的 memory 模型为基线重做 memory 层
|
||||
|
||||
这里要明确:新的 memory 设计不再以当前 `ProcedureMemory` 为中心,而是以 `hermes-agent` 的 memory 模型为准。
|
||||
|
||||
### 主 memory 契约
|
||||
|
||||
新的主 memory 契约应是:
|
||||
|
||||
1. 一个统一的 `memory` tool
|
||||
2. 三个核心动作:
|
||||
- `add`
|
||||
- `replace`
|
||||
- `remove`
|
||||
3. 两个目标存储:
|
||||
- `memory`:agent 的环境事实、项目约定、工具经验
|
||||
- `user`:用户画像、偏好、习惯、纠正记录
|
||||
|
||||
它的行为应对齐 Hermes:
|
||||
|
||||
1. `add`
|
||||
- 追加新条目
|
||||
- 精确重复时跳过
|
||||
- 超限时返回当前条目和占用情况
|
||||
2. `replace`
|
||||
- 用 `old_text` 的短语义片段匹配条目并整体替换
|
||||
- 多条匹配时要求更精确的 `old_text`
|
||||
3. `remove`
|
||||
- 也是通过 `old_text` 的语义片段删除
|
||||
- 多条匹配时同样要求更精确匹配
|
||||
|
||||
这里要采用“子串匹配”而不是 UUID,因为这更符合 LLM 的操作习惯。
|
||||
|
||||
### 写入安全与并发安全
|
||||
|
||||
新的 memory 层应保留 Hermes 这几个关键约束:
|
||||
|
||||
1. 写入前扫描注入/渗透模式
|
||||
2. 在锁内重新从磁盘加载目标文件
|
||||
3. 做重复检测和字符上限检测
|
||||
4. 通过临时文件 + `os.replace()` 做原子写入
|
||||
|
||||
也就是说,并发安全的关键不是“先读后写”,而是:
|
||||
|
||||
`scan -> lock -> reload -> validate -> atomic write`
|
||||
|
||||
### 冻结快照模式
|
||||
|
||||
新的 memory 层必须采用 frozen snapshot,而不是“每次 memory 写入都改 system prompt”。
|
||||
|
||||
规则是:
|
||||
|
||||
1. 会话开始时,从磁盘加载 `memory` 和 `user`
|
||||
2. 立刻冻结成 system prompt snapshot
|
||||
3. 会话中写入 memory 时,只更新磁盘上的 live state
|
||||
4. 当前会话里的 system prompt 保持不变
|
||||
5. 下一个会话开始时,再重新加载最新 memory
|
||||
|
||||
### session_search 取代“把所有过程细节塞进 memory”
|
||||
|
||||
大量过程细节不应继续塞进 `memory`。
|
||||
|
||||
因此新后端应该明确区分:
|
||||
|
||||
1. `memory`
|
||||
- 保存小而精的、跨会话稳定有效的事实
|
||||
2. `session_search`
|
||||
- 检索历史会话
|
||||
- 支持“无 query 浏览最近会话”和“有 query 的全文搜索 + 摘要”
|
||||
|
||||
这个能力后续应在 Beaver 中落成:
|
||||
|
||||
- `beaver/memory/curated/*`
|
||||
- `beaver/memory/search/*`
|
||||
- `beaver/tools/builtins/memory.py`
|
||||
- `beaver/tools/builtins/session_search.py`
|
||||
|
||||
### `ProcedureMemory` 的新定位
|
||||
|
||||
这不表示 `ProcedureMemory` 没价值,而是它的地位要下降:
|
||||
|
||||
1. `ProcedureMemory` 不再是主 memory 契约
|
||||
2. 它不应该直接承担“跨会话记忆”职责
|
||||
3. 它更适合作为 coordinator 内部的流程复用与路由优化层
|
||||
|
||||
新的优先级应是:
|
||||
|
||||
1. 用户偏好、纠正、环境事实 -> `memory`
|
||||
2. 历史会话细节 -> `session_search`
|
||||
3. 稳定方法论和工作法 -> `skills`
|
||||
4. 团队/流程复用优化 -> `ProcedureMemory`
|
||||
|
||||
## 4.5 CLI 不再代表单 agent 模式,只保留为薄入口
|
||||
|
||||
当前入口层太厚,后续应该改成:
|
||||
|
||||
1. CLI 只做参数解析与 runtime 启动
|
||||
2. Web 只做 API 与 request/response 映射
|
||||
3. Gateway 只做渠道接入与消息转发
|
||||
|
||||
所有核心能力都由统一的 application services 提供,例如:
|
||||
|
||||
- `ChatApplicationService`
|
||||
- `DelegationApplicationService`
|
||||
- `TeamRunApplicationService`
|
||||
- `SkillApplicationService`
|
||||
- `MemoryApplicationService`
|
||||
|
||||
同时要明确一条原则:
|
||||
|
||||
CLI 不是“单 agent 专用模式”。
|
||||
|
||||
它只是这些 interface 之一:
|
||||
|
||||
- CLI
|
||||
- Web
|
||||
- Gateway
|
||||
- Channel
|
||||
|
||||
无论从哪个入口进来,最终都进入同一套 `AgentLoop` / engine。
|
||||
|
||||
这样就不会再出现“CLI 一套 agent,其他入口另一套 agent”的问题。
|
||||
|
||||
## 5. 具体改动后会是什么样
|
||||
|
||||
## 5.1 所有 agent 共用同一套 engine
|
||||
|
||||
### 现在
|
||||
|
||||
`CLI/Web/Gateway -> 各自装配一套 AgentLoop 或相关依赖`
|
||||
|
||||
### 之后
|
||||
|
||||
`CLI/Web/Gateway/Channel -> AgentEntryService -> AgentLoop(engine) -> tools/skills/memory/permissions/delegation`
|
||||
|
||||
结果是:
|
||||
|
||||
1. 主 agent、subagent、team member 复用同一套 engine。
|
||||
2. 装载逻辑只在 engine 内统一处理一次。
|
||||
3. 不再保留“CLI 单 agent 概念”。
|
||||
4. 测试可以直接测 engine 和 service,而不是分别测入口分支。
|
||||
|
||||
## 5.2 多 agent 场景
|
||||
|
||||
### 现在
|
||||
|
||||
`spawn_agent_team -> DelegationManager -> AgentTeamOrchestrator -> SwarmsPlanner/Bridge -> SwarmRouter`
|
||||
|
||||
### 之后
|
||||
|
||||
`spawn_agent_team`
|
||||
`-> DelegationService`
|
||||
`-> TeamApplicationService`
|
||||
`-> TeamPlanner`
|
||||
`-> ExecutionPlan`
|
||||
`-> StrategyBackendRegistry`
|
||||
`-> SwarmsBackend`
|
||||
`-> NormalizedTeamResult`
|
||||
|
||||
结果是:
|
||||
|
||||
1. 团队能力不再绑定某个第三方 runtime 结构。
|
||||
2. 可以逐步增加第二种 backend,而不推翻平台层。
|
||||
3. `swarms` 只是其中一个可插拔执行器。
|
||||
|
||||
## 5.3 skill 场景
|
||||
|
||||
### 现在
|
||||
|
||||
`SkillsLoader -> 读 SKILL.md -> 摘要注入 / 手动审核安装`
|
||||
|
||||
### 之后
|
||||
|
||||
`SkillCatalog`
|
||||
`-> SkillDraftStore`
|
||||
`-> SkillReviewService`
|
||||
`-> SkillPublisher`
|
||||
`-> SkillRuntimeResolver`
|
||||
|
||||
结果是:
|
||||
|
||||
1. skill 可以有版本。
|
||||
2. skill 可以从 procedure 生成。
|
||||
3. skill 可以审核和回滚。
|
||||
4. skill 可以做效果分析和推荐。
|
||||
|
||||
## 5.4 运行学习场景
|
||||
|
||||
### 现在
|
||||
|
||||
`Run details 混在 session / memory / procedure 中`
|
||||
|
||||
### 之后
|
||||
|
||||
`Run transcript`
|
||||
`-> session_search index`
|
||||
|
||||
`Durable fact`
|
||||
`-> memory(add/replace/remove)`
|
||||
|
||||
`Stable method / workaround / reusable workflow`
|
||||
`-> SkillCandidateGenerator`
|
||||
`-> SkillDraft`
|
||||
`-> Review`
|
||||
`-> Publish`
|
||||
|
||||
`Repeated execution pattern`
|
||||
`-> optional ProcedureMemory`
|
||||
|
||||
结果是:
|
||||
|
||||
1. durable facts、历史细节、稳定方法三类信息终于分层。
|
||||
2. 自动学习不会把临时过程污染到主 memory。
|
||||
3. skills 仍是最高层指导系统,而 memory 变成受控 CRUD 系统。
|
||||
|
||||
## 6. 分阶段落地建议
|
||||
|
||||
这次重构不应该一次性推翻,建议分四期做。
|
||||
|
||||
### 第一期:边界清理
|
||||
|
||||
目标:
|
||||
|
||||
1. 把入口装配统一掉
|
||||
2. 把 `web/server.py` 开始拆分
|
||||
3. 把 swarms 相关代码聚到单独 backend 目录
|
||||
|
||||
交付物:
|
||||
|
||||
- 统一 app factory / service wiring
|
||||
- 初步拆分 web routes
|
||||
- `orchestration/backends/swarms/`
|
||||
|
||||
### 第二期:平台抽象固化
|
||||
|
||||
目标:
|
||||
|
||||
1. 定义 team / skill / memory / session_search 的正式模型
|
||||
2. 让上层只依赖平台模型
|
||||
|
||||
交付物:
|
||||
|
||||
- `TeamSpec`
|
||||
- `SkillSpec`
|
||||
- `ExecutionPlan`
|
||||
- `MemoryEntry`
|
||||
- `MemorySnapshot`
|
||||
- `SessionSearchResult`
|
||||
- `SkillDraft`
|
||||
- `SkillVersion`
|
||||
|
||||
### 第三期:skills 生命周期
|
||||
|
||||
目标:
|
||||
|
||||
1. 从“文档技能”升级到“版本化能力”
|
||||
2. 打通“稳定方法 -> SkillDraft”
|
||||
3. 按 Hermes 基线完成 memory CRUD、frozen snapshot、session_search
|
||||
|
||||
交付物:
|
||||
|
||||
- skill catalog
|
||||
- review/publish flow
|
||||
- runtime resolver
|
||||
- memory tool
|
||||
- session search tool
|
||||
|
||||
### 第四期:高级多智能体能力
|
||||
|
||||
目标:
|
||||
|
||||
1. 放开更多正式支持的 strategy
|
||||
2. 评估 `GraphWorkflow`、`HeavySwarm`
|
||||
3. 增加 fallback / retry / policy routing
|
||||
|
||||
交付物:
|
||||
|
||||
- 完整 strategy registry
|
||||
- 多 backend 能力矩阵
|
||||
- team execution fallback
|
||||
|
||||
## 7. 重构后的推荐目录
|
||||
|
||||
下面这个目录我已经按你说的方向收紧了:
|
||||
|
||||
1. 不保留 `third_party/`
|
||||
2. 不保留“CLI 单 agent”这类结构暗示
|
||||
3. 尽量参考 OpenHarness 那种按能力分组、观感更规整的布局
|
||||
4. 每个目录后面都加中文说明
|
||||
|
||||
```text
|
||||
app-instance/backend/
|
||||
├── change.md # 这份重构蓝图
|
||||
├── README.md # 后端总说明
|
||||
├── workflow.md # 运行链路说明
|
||||
├── docs/ # 架构文档和迁移文档
|
||||
│ ├── architecture/ # 核心架构说明
|
||||
│ └── migration/ # 分阶段迁移计划
|
||||
├── beaver/
|
||||
│ ├── foundation/ # 最底层公共设施:配置、模型、事件、错误、工具函数
|
||||
│ │ ├── config/ # 配置定义与加载
|
||||
│ │ ├── models/ # 全局共享数据模型
|
||||
│ │ ├── events/ # 统一事件模型与事件派发
|
||||
│ │ ├── errors/ # 统一错误类型
|
||||
│ │ └── utils/ # 通用工具函数
|
||||
│ ├── engine/ # 统一 agent 内核,所有 agent 都复用这里
|
||||
│ │ ├── loop.py # AgentLoop 主循环与执行入口
|
||||
│ │ ├── loader.py # tools、skills、memory、permissions 的统一装载
|
||||
│ │ ├── context/ # 上下文拼装
|
||||
│ │ ├── session/ # 会话状态与持久化
|
||||
│ │ ├── providers/ # LLM provider 适配
|
||||
│ │ └── runtime/ # 运行时辅助对象与执行上下文
|
||||
│ ├── tools/ # 工具系统
|
||||
│ │ ├── registry/ # 工具注册与发现
|
||||
│ │ ├── builtins/ # 内置工具
|
||||
│ │ ├── mcp/ # MCP 工具适配
|
||||
│ │ └── policies/ # 工具权限与调用约束
|
||||
│ ├── skills/ # 技能系统
|
||||
│ │ ├── builtin/ # 内置技能内容
|
||||
│ │ ├── catalog/ # 技能目录、索引与查询
|
||||
│ │ ├── drafts/ # 自动生成或待审核的 skill draft
|
||||
│ │ ├── reviews/ # 技能审核流
|
||||
│ │ ├── publisher/ # 技能发布与版本切换
|
||||
│ │ └── resolver/ # 运行时技能解析与注入
|
||||
│ ├── memory/ # 记忆与经验沉淀系统
|
||||
│ │ ├── curated/ # Hermes 风格的 MEMORY / USER 持久记忆
|
||||
│ │ ├── search/ # session_search 与历史会话检索
|
||||
│ │ ├── runs/ # 单次执行记录
|
||||
│ │ ├── procedures/ # 可选的流程复用优化层
|
||||
│ │ └── stores/ # 底层存储与原子写实现
|
||||
│ ├── permissions/ # 权限、沙箱、治理规则
|
||||
│ │ ├── policies/ # 权限策略
|
||||
│ │ ├── guards/ # 执行前检查
|
||||
│ │ └── profiles/ # 不同 agent 运行权限画像
|
||||
│ ├── coordinator/ # 多 agent 协调层,参考 OpenHarness 的 coordinator 风格
|
||||
│ │ ├── delegation/ # 委派与任务分发
|
||||
│ │ ├── registry/ # agent registry 与 agent descriptor
|
||||
│ │ ├── planner/ # 团队 planning 与 execution plan 生成
|
||||
│ │ ├── execution/ # 执行控制、fallback、聚合
|
||||
│ │ ├── backends/ # 可替换的多 agent backend
|
||||
│ │ │ ├── base.py # backend 抽象接口
|
||||
│ │ │ └── swarms/ # swarms backend 封装,不再直接暴露第三方目录
|
||||
│ │ └── team/ # team 级模型与编排对象
|
||||
│ ├── services/ # application services,对外提供统一能力入口
|
||||
│ │ ├── agent_service.py # 统一 agent 运行入口
|
||||
│ │ ├── team_service.py # 多 agent 执行入口
|
||||
│ │ ├── skill_service.py # 技能管理入口
|
||||
│ │ ├── memory_service.py # memory 查询与写入入口
|
||||
│ │ └── admin_service.py # 平台管理入口
|
||||
│ ├── interfaces/ # 薄入口层,不承载核心业务
|
||||
│ │ ├── cli/ # CLI 入口,只负责把请求送进 services/engine
|
||||
│ │ ├── web/ # FastAPI 接口层
|
||||
│ │ │ ├── app.py # Web app factory
|
||||
│ │ │ ├── routes/ # 路由拆分
|
||||
│ │ │ ├── schemas/ # Web 请求/响应模型
|
||||
│ │ │ └── deps.py # Web 依赖装配
|
||||
│ │ ├── gateway/ # 常驻 worker / gateway 入口
|
||||
│ │ └── channels/ # Telegram/Slack/Email 等渠道入口
|
||||
│ ├── integrations/ # 外部系统与协议集成
|
||||
│ │ ├── a2a/ # A2A 协议与 client
|
||||
│ │ ├── mcp/ # MCP 连接与管理
|
||||
│ │ ├── outlook/ # Outlook 集成
|
||||
│ │ ├── whatsapp/ # WhatsApp bridge 适配
|
||||
│ │ └── providers/ # 外部 provider 特定集成
|
||||
│ ├── plugins/ # 插件系统
|
||||
│ │ ├── loader.py # 插件发现与装载
|
||||
│ │ ├── registry.py # 插件注册表
|
||||
│ │ └── hooks.py # 插件 hooks
|
||||
│ └── templates/ # 默认模板、system prompt 模板、内置文本资源
|
||||
├── tests/ # 测试
|
||||
│ ├── unit/ # 单元测试
|
||||
│ ├── integration/ # 集成测试
|
||||
│ ├── e2e/ # 端到端测试
|
||||
│ └── fixtures/ # 测试数据与夹具
|
||||
└── bridge/ # 独立 Node/bridge 代码,作为外部桥接层保留
|
||||
```
|
||||
|
||||
## 8. 最终结论
|
||||
|
||||
这次重构的本质不是“把代码拆小一点”,而是完成三件事:
|
||||
|
||||
1. 把当前项目从“围绕 `AgentLoop` 生长的单体系统”升级成“所有 agent 共用一个 engine 的可维护 harness 平台”。
|
||||
2. 把 `swarms` 从“放在 `third_party/` 里的深耦合运行时”降级成“可替换的多智能体 backend”。
|
||||
3. 把 `skills` 从“静态 Markdown 包”升级成“可学习、可审核、可发布、可回滚的能力系统”。
|
||||
|
||||
如果这三件事做成了,后面再扩多智能体架构、自动学习、插件生态、外部接入,代码就不会继续失控。
|
||||