开源AI工作流:轻量级多租户Agent路由器 是 AI Skill Hub 本期精选Agent工作流之一。综合评分 7.5 分,整体质量较高。我们推荐使用将其纳入你的 AI 工具库,帮助提升工作效率。
轻量级多租户Agent路由器,开源AI工作流,简化AI应用部署和管理
开源AI工作流:轻量级多租户Agent路由器 是一套完整的 AI Agent 自动化工作流方案。通过可视化的节点编排,将复杂的多步骤任务拆解为清晰的自动化流程,实现全程无人值守的智能处理。支持与数百种外部服务和 API 无缝集成,适合构建数据处理管线、业务自动化和 AI 辅助决策系统。
轻量级多租户Agent路由器,开源AI工作流,简化AI应用部署和管理
开源AI工作流:轻量级多租户Agent路由器 是一套完整的 AI Agent 自动化工作流方案。通过可视化的节点编排,将复杂的多步骤任务拆解为清晰的自动化流程,实现全程无人值守的智能处理。支持与数百种外部服务和 API 无缝集成,适合构建数据处理管线、业务自动化和 AI 辅助决策系统。
# 方式一:pip 安装(推荐)
pip install agent-stack
# 方式二:虚拟环境安装(推荐生产环境)
python -m venv .venv
source .venv/bin/activate # Windows: .venv\Scripts\activate
pip install agent-stack
# 方式三:从源码安装(获取最新功能)
git clone https://github.com/JoursBleu/agent-stack
cd agent-stack
pip install -e .
# 验证安装
python -c "import agent_stack; print('安装成功')"
# 命令行使用
agent-stack --help
# 基本用法
agent-stack input_file -o output_file
# Python 代码中调用
import agent_stack
# 示例
result = agent_stack.process("input")
print(result)
# agent-stack 配置文件示例(config.yml) app: name: "agent-stack" debug: false log_level: "INFO" # 运行时指定配置文件 agent-stack --config config.yml # 或通过环境变量配置 export AGENT_STACK_API_KEY="your-key" export AGENT_STACK_OUTPUT_DIR="./output"
Multi-tenant, multi-backend agent runtime exposing an OpenAI-compatible HTTP surface aggregated across several agent runtimes (OpenClaw, Hermes Agent, HKUDS nanobot, …).
A lightweight alternative to "OpenWebUI + many sidecar containers": one router, one tiny SPA, per-user Docker-spawned agent runtimes that auto-stop when idle, conversation history stored cloud-side.
- Per (user, backend) Docker container — one runner per user per backend kind, spawned on demand. - Idle reaper — runners are docker stop+rm-ed (truly stopped, not paused) once idle exceeds a user-configurable threshold. - Cold-start progress — /api/runners/<backend>/progress SSE stream, rendered as a progress bar in the SPA. - OpenAI compat — POST /v1/chat/completions is routed by model to the correct runner. - Cloud conversations — chats and messages persist in the router's sqlite DB; switch devices, history follows. - Three-tier upstream key — admin's web-UI Global value (optionally shared with all users) + each user's own global override + each user's per-backend override. The router never reads upstream LLM creds from .env / process env. Toggling shares is live — no router restart. - JWT cookie auth with optional invite-code signup and bootstrap admin. - Single-admin invariant — exactly one user has role='admin' (the bootstrap one). The UI/API refuse to create, promote, demote or delete in a way that would break this. - Single-binary frontend — vanilla JS + nginx, zero build step.
The router never reads LLM_BASE_URL / LLM_API_KEY / LLM_MODEL from .env. After logging in as the bootstrap admin:
1. Click the gear icon (lower-left) → Backend API keys. 2. In the LLM_BASE_URL card, set the Global value to your OpenAI-compatible base URL (e.g. https://api.openai.com/v1). 3. In the LLM_API_KEY card, set the Global value to your key. 4. In the LLM_MODEL card, set the Global value to the upstream model id (e.g. gpt-5-mini, qwen3-72b-instruct). This is what hermes / openclaw will pass to the upstream /v1/chat/completions. 5. (Optional) Toggle "Share my Global value with other users" on each card so non-admin users inherit the same value. Without this toggle, every user has to fill their own key in their own settings.
Equivalent REST (admin's own session cookie):
```bash BASE=http://<host>:18000 JAR=/tmp/admin.jar
DATA=$(grep ^HOST_STACK_ROOT .env | cut -d= -f2) sudo mkdir -p "$DATA" && sudo chown $USER "$DATA"
docker pull ghcr.io/openclaw/openclaw:latest docker pull nousresearch/hermes-agent:latest
docker compose up -d --build docker compose logs -f agent-stack-router
If you need OpenClaw's browser plugin to drive a real desktop Chromium, build the overlay and point backends.json at it:
```bash cd images/openclaw docker build -t openclaw-with-chromium:latest .
```bash cd agent-stack docker compose down # stop router + frontend
Requirements: Linux host, Docker 24+, ports 18000 (frontend) and 18080 (router) free. The router connects to the local docker.sock to spawn backend containers.
```bash git clone https://github.com/JoursBleu/agent-stack.git cd agent-stack
If LLM_BASE_URL points at another container on the same Docker host (e.g. an openai-compat-proxy listening on its own bridge network), the spawned per-user runner needs to be on that network — `network_mode: host` only applies to the router/frontend, not to backend runners.
// backends.json
{
"name": "openclaw",
"image": "ghcr.io/openclaw/openclaw:latest",
"extra_networks": ["my-llm-proxy_default"],
"extra_env": {
// resolved by the proxy container's DNS name on that bridge:
"LLM_BASE_URL": "http://openai-compat-proxy:8080/v1"
}
}
The router writes a row in the docker network's container table, so inside the runner getent hosts openai-compat-proxy resolves and curl http://openai-compat-proxy:8080/v1/models works. Without extra_networks, every spawned runner lands on the default bridge network and can't reach any sidecar by name (only public DNS endpoints work).


The default image: value already matches; just make sure you ran docker pull (Quick start step 4):
docker pull ghcr.io/openclaw/openclaw:latest
The image lives on GHCR; it is not mirrored to Docker Hub, so docker pull openclaw/openclaw will 404. See openclaw/openclaw for tags and build matrix.
| Var | Default | Purpose |
|---|---|---|
HOST_STACK_ROOT | ./data | host path bind-mounted into the router as STACK_DATA_ROOT; holds backends.json, seeds/, users/, router.db |
JWT_SECRET | — | random hex; **change before deploy** |
COOKIE_SECURE | false | set true behind HTTPS |
ALLOW_SIGNUP | true | allow public signup |
INVITE_CODE | empty | optional invite token; required if non-empty |
BOOTSTRAP_ADMIN_* | — | seed an admin on first boot |
DEFAULT_IDLE_SECONDS | 600 | per-runner idle TTL |
REAPER_INTERVAL_SECONDS | 30 | reaper sweep period |
BACKEND_PORT_START..END | 19000..19999 | host port pool for runner publish |
BACKEND_STARTUP_TIMEOUT | 90 | seconds to wait for ready_path |
Upstream LLM credentials (LLM_BASE_URL,LLM_API_KEY,LLM_MODEL) are intentionally not in.env. The bootstrap admin saves them in Settings → Backend API keys on first login (see Quick start above).
GET /api/me/env-overrides — list (values masked)PUT /api/me/env-overrides/{var} — {value}; empty string deletesDELETE /api/me/env-overrides/{var}Changing LLM_BASE_URL / LLM_API_KEY / LLM_MODEL in the UI updates the DB immediately, but the per-user backend container that's already running was started with the old values baked into its rendered seed files. The router only re-renders templated_files on the next ensure() call, and ensure() is a no-op when a runner exists. To force it:
BASE=http://127.0.0.1:18000
curl -s -X DELETE -b $JAR $BASE/api/runners/openclaw # stop+remove
curl -s -X POST -b $JAR $BASE/api/runners/openclaw/start # respawn
Or wait for the idle reaper (DEFAULT_IDLE_SECONDS, default 600s).
docker image rm agent-stack-router:latest agent-stack-frontend:latest ```
All endpoints under /api/* and /v1/* require a session (cookie set by POST /auth/login).
The ${LLM_MODEL} placeholder in the seed files only declares one upstream model. To expose more (e.g. let users switch between a fast and a slow model in the OpenClaw UI), edit the seed file directly:
- OpenClaw: seeds/openclaw-home/openclaw.json → add more entries under models.providers.upstream.models[]. - Hermes: seeds/hermes-home/config.yaml has a single ${LLM_MODEL} per sub-component (vision, web_extract, compression, ...); replace any of them with a literal id (or another env placeholder) if you want sub-components on different upstream models.
After editing, git pull && docker compose up -d is enough to push the template into the router container, but already-spawned per-user runners keep their previously rendered seed. Force a re-render by recycling the user's runner (next section).
router.db is sqlite + WAL, so the on-disk file is normally accompanied by router.db-wal and router.db-shm containing un-checkpointed transactions. Do not copy router.db alone for backup; either docker compose stop agent-stack-router first, or use:
sqlite3 "$HOST_STACK_ROOT/router.db" ".backup /tmp/router-$(date +%F).db"
For full removal:
| Symptom | Likely cause | Where to look |
|---|---|---|
pull access denied for openclaw/openclaw | Wrong registry. The image is on GHCR. | docker pull ghcr.io/openclaw/openclaw:latest |
runner not ready: Connection refused after a few seconds | The spawned backend container exited during startup (bad seed config, missing image, OOM, ...). | docker logs agstack-<backend>-<user-slug> |
Spawn works but /v1/chat/completions returns 404 / 400 from upstream | The ${LLM_MODEL} value isn't a model id the upstream actually serves. | curl -H 'Authorization: Bearer $LLM_API_KEY' $LLM_BASE_URL/models and reset the override in *Settings → Backend API keys*. |
| Two checkouts on the same host fight for the same container | Old hard-coded container_name. We removed it; on upgrade make sure your docker-compose.yml no longer pins container_name:. | git diff docker-compose.yml |
Router refuses to start with JWT_SECRET looks like the placeholder | .env still has CHANGE_ME_TO_RANDOM_HEX. | sed -i "s|^JWT_SECRET=.*|JWT_SECRET=$(openssl rand -hex 48)|" .env |
First POST /api/runners/<backend>/start times out at ~90 s with runner not ready | docker compose up does **not** auto-pull backend images (they aren't compose services), and a 1-2 GB image pull blows past BACKEND_STARTUP_TIMEOUT. | Run docker pull for every image in backends.json once, or set BACKEND_PREPULL_AT_STARTUP=true in .env to make the router pre-pull on boot. |
Backend runner cannot reach LLM_BASE_URL even though curl from the host works | The runner container is on the default bridge network; same-host sidecars are only reachable by container DNS name when both are on the same user-defined network. | Add the sidecar's network to extra_networks in backends.json (see "Sidecar example" above) and restart the router. |
| Backend runner stays "running" in the SPA after it crashed | Status is refreshed by the idle reaper (REAPER_INTERVAL_SECONDS, default 30 s). | Wait ≤30 s, or curl DELETE /api/runners/<backend> to force-clean. |
BACKEND_PREPULL_AT_STARTUP=true but first spawn still times out | One of the images failed to pre-pull (typo in backends.json, registry 404, no internet, no creds). | curl -fsS http://127.0.0.1:18080/healthz \| jq .prepull_status shows per-image outcome (ok / present / failed: ...). |
agent-stack 是一个多租户、支持多后端的 Agent 运行时管理平台。它通过聚合 OpenClaw、Hermes Agent、HKUDS nanobot 等多种 Agent 运行时,对外提供统一且兼容 OpenAI 标准的 HTTP 接口。相比于“OpenWebUI + 多个 Sidecar 容器”的繁重架构,agent-stack 更加轻量化:它采用单路由(Router)+ 轻量级 SPA 前端的设计,并能为每个用户按需通过 Docker 启动独立的 Agent 运行时,且在闲置时自动停���以节省资源,对话历史则存储在云端。
本项目具备以下核心特性:首先是基于 Docker 的隔离机制,为每个用户与后端的组合(user, backend)动态创建独立的容器;其次是智能 Idle reaper 功能,当容器闲置超过用户设定的阈值时,会自动执行 docker stop 和 rm,实现真正的资源释放而非简单的暂停;此外,针对冷启动问题,系统通过 SSE 流提供 /api/runners/<backend>/progress 接口,在 SPA 前端实时渲染进度条;最后,系统完全兼容 OpenAI API 规范,支持通过 POST /v1/chat/completions 进行交互。
在开始使用前,请确保已准备好上游 LLM 的 API Key。需要注意的是,Router 自身不会从 .env 文件中读取 LLM_BASE_URL、LLM_API_KEY 或 LLM_MODEL。首次启动后,您必须以 bootstrap admin 身份登录,通过 Web UI 左下角的齿轮图标进入 Backend API keys 页面,在 LLM_BASE_URL 卡片中将 Global 值设置为您的模型服务地址,完成初始化配置。
安装过程非常简单。首先通过 git clone 获取源码,然后使用 docker compose 进行部署。请注意,由于部分后端镜像托管在 GHCR 而非 Docker Hub,直接使用 docker pull openclaw/openclaw 可能会导致 404,建议手动执行 docker pull ghcr.io/openclaw/openclaw:latest 等命令拉取正确的镜像。在部署前,请确保已正确配置 .env 文件并创建了必要的数据存储目录,并使用 sudo chown 授予当前用户权限。
快速上手指南:请确保您的 Linux 主机已安装 Docker 24+,且 18000(前端)和 18080(Router)端口未被占用。Router 会通过连接本地的 docker.sock 来调度后端容器。如果您需要配置 Sidecar 模式(例如后端需要访问同一宿主机上的 LLM Proxy 容器),请务必在 backends.json 中配置 extra_networks,因为 network_mode: host 仅适用于 Router 和前端,并不直接应用于后端 Runner。
配置说明:系统核心配置通过 .env 文件管理,若 JWT_SECRET 未设置,Router 将拒绝启动。管理员可以通过 Web UI 安全地保存和管理 API 密钥。此外,系统支持权限管理,管理员可以将特定的环境变量(如 LLM_BASE_URL)通过 API 共享给非管理员用户,实现配置的灵活分发与权限控制。
所有的 API 接口均分为 /api/* 和 /v1/* 两大类。请注意,所有请求都必须包含有效的 Session(通过 POST /auth/login 获取并由 Cookie 携带),否则会被拦截。Router 遵循解耦设计,不会从环境变量中读取 LLM ��置,所有的模型调用参数均通过 API 动态传递。
工作流与模块定制:本项目允许开发者对上游模型列表进行深度定制。默认情况下,seed 文件中的 ${LLM_MODEL} 仅声明单个模型。如果您希望在 OpenClaw UI 中实现模型切换功能(例如在快速模型与慢速模型间切换),可以直接编辑对应的 seed 文件(如 seeds/openclaw-home/openclaw.json),手动添加更多模型定义。
常见问题排查:如果您在拉取镜像时遇到 'pull access denied',通常是因为镜像仓库地址错误,请检查是否应使用 GHCR 路径;如果后端容器在启动几秒后出现 'runner not ready: Connection refused',通常是由于容器在初始化阶段异常退出,建议检查后端日志或网络配置;此外,请确保 Docker 权限配置正确,以便 Router 能顺利操作 docker.sock。
该项目提供了一个轻量级的多租户Agent路由器,开源AI工作流,简化AI应用部署和管理。值得关注。
AI Skill Hub 为第三方内容聚合平台,本页面信息基于公开数据整理,不对工具功能和质量作任何法律背书。
建议在沙箱或测试环境中充分验证后,再部署至生产环境,并做好必要的安全评估。
✅ MIT 协议 — 最宽松的开源协议之一,可自由商用、修改、分发,仅需保留版权声明。
经综合评估,开源AI工作流:轻量级多租户Agent路由器 在Agent工作流赛道中表现稳健,质量良好。如果你已有明确的使用需求,可以直接上手体验;如果还在评估阶段,建议对比同类工具后再做决策。
| 原始名称 | agent-stack |
| 原始描述 | 开源AI工作流:Lightweight multi-tenant Agent router.。⭐8 · Python |
| Topics | workflowai-agentdockerfastapihermes-agentmulti-tenantpython |
| GitHub | https://github.com/JoursBleu/agent-stack |
| License | MIT |
| 语言 | Python |
收录时间:2026-05-17 · 更新时间:2026-05-18 · License:MIT · AI Skill Hub 不对第三方内容的准确性作法律背书。
选择 Agent 类型,复制安装指令后粘贴到对应客户端