wartzar-bee/enclave

GitHub: wartzar-bee/enclave

一个安全优先、支持多模型接入的自托管 AI Agent 运行时,通过容器隔离和细粒度权限管控在本地安全运行自主智能体。

Stars: 1 | Forks: 1

# Enclave **一个安全优先、与大脑无关的 agent runtime。** 在一个加固的 container 中运行一个拥有受限凭证和本地 web 聊天的自主 agent —— 使用 `docker compose up`,然后在你的 浏览器中与它对话。 **在此处“受限”的准确定义**(在信任它执行任何操作之前请阅读此内容): - **架构层面,始终开启** — agent 运行时带有 `--cap-drop=ALL --security-opt=no-new-privileges` 并且没有入站端口;它仅读取你赋予它的挂载目录以及一个 **只读** 的 `secrets/`。它 无法看到你磁盘的其余部分,而且 prompt 注入也不会改变这一点。 - **策略层面,默认仅报告** — 出站白名单 (`platform/agentd/hooks/policies/default-egress.json`)默认仅**记录**被禁止的主机,而 不是拦截它们,直到你设置了 **`GUARD_EGRESS_ENFORCE=1`**。我们将其默认关闭,以免首次运行 以你无法诊断的方式失败;对于任何真实的操作,请将其**开启**。验证你处于哪种模式: `grep enforce home/state/egress-policy.log`。 因此:container 边界由内核强制执行,而*网络*边界仅在你 开启时才被强制执行。 ## 要求 - **Docker** (Desktop 或 Engine) — 正在**运行**。agent 在 container 中运行。(`enclave run`/`console` 会检查这一点并告诉你是否未运行。) - **Python 3** — 运行 `bin/enclave`。**Git**。 - 大脑凭证:`BRAIN=claude` → **`claude` CLI** (`init` 向导会运行 `claude setup-token`) + Claude 订阅 · `api` → 兼容 OpenAI 的密钥 (例如 OpenRouter) · `local` → 宿主机上的模型服务器 (Ollama/MLX)。 ## 快速开始 ``` git clone https://github.com/wartzar-bee/enclave.git enclave && cd enclave ./bin/enclave init # wizard: name, brain, model, port, paste your credential ./bin/enclave run # build + start, then opens the chat in your browser ``` `init` 会填充 `home/`(agent 挂载的 `/agent`:任务、runtime 配置、工作队列、知识 wiki),`secrets/`(你的只读凭证)和 `.env`。`run` 会启动技术栈并自动打开 `http://127.0.0.1:8888/`。非交互式 (CI): ``` ./bin/enclave init --yes --name my-agent --brain claude --model claude-sonnet-4-6 --cred "$TOKEN" ./bin/enclave run --no-open ``` 新来此处?**[docs/QUICKSTART.md](docs/QUICKSTART.md)** 将引导你在 5 分钟内从克隆代码到一个正在运行的、专为特定目的构建的 agent —— 从 9 个[模板](templates/README.md)中选择一个,给它一个任务,并与它对话。 ## 日常操作 所有操作都通过部署文件夹中的 `./bin/enclave` 进行: | 想要… | 命令 | |----------|---------| | 启动 / 打开聊天 | `enclave run` (如有需要会构建,并打开浏览器) | | 打开仪表板 (所有 agent) | `enclave console` (自动配置;打开浏览器) | | 停止 agent | `enclave stop` | | 查看 runner 日志 | `enclave logs` | | 健康状态 + 最近活动 | `enclave status` | | 向工作队列发送任务 | `enclave send "…"` | | 切换大脑 (保留记忆) | `enclave brain ` | | 更新 runtime 到最新版本并重新构建 | `enclave update` (git clone) · `enclave update --from ` (任意) · `enclave update --pull` (预构建镜像) | | 立即提交记忆库 | `enclave snapshot ["msg"]` (也会在每个 tick 自动运行) | **切换大脑** — 就地更改模式 (重写 `agent.env` + `.env`,在需要时运行 `optimize` 池 向导) 并重新创建 container。**记忆/收件箱/工作内容不受影响** (与重新运行 `init` 不同)。首次切换到新模式会重新构建镜像 (runtime 是内置的);之后添加 `--no-build` 即可进行仅针对环境变量的即时重新创建。 ``` enclave brain optimize # prompts for your LLM pools, seeds policy.json + secrets, rebuilds enclave brain optimize --yes # seed the documented default pools instead of prompting enclave brain optimize --reconfigure # re-run the pool wizard even if policy.json already exists enclave brain claude --no-build # fast switch back, no rebuild (image already has the mode) enclave brain api --model deepseek/deepseek-chat ``` `optimize` 大脑 (Claude 优先,根据成本感知回退到任何兼容 OpenAI 的池 —— xAI / OpenAI / Groq / OpenRouter / 本地) 配置在 `home/policy.json` 中;完整指南:**`docs/OPTIMIZE-BRAIN.md`**。 只想在**非 Claude 模型**上运行 enclave (OpenRouter / NVIDIA / Groq / 本地 Ollama) — 只需一条命令,自带你的密钥?请参阅 **[docs/BRING-YOUR-OWN-MODEL.md](docs/BRING-YOUR-OWN-MODEL.md)**。 **更新到最新的 runtime** — 克隆的代码*就是*部署,所以拉取并重新构建: ``` git pull # get the latest platform/ + bin/enclave enclave run # rebuilds both images (docker compose up -d --build) and recreates the container ``` `run`/`brain` 默认会进行构建;被更改的 `COPY platform/agentd/` 层正是将新的 runtime 代码 拉入镜像的关键。如果重新构建后运行的是过时代码,请强制构建: `docker compose build --no-cache agent chat && docker compose up -d`。 ## 成本控制 (运行一个集群而不耗尽模型额度) 在前沿模型上运行持久的集群会快速消耗订阅/API 额度 —— 在集群规模下,这是核心制约因素。有两层机制可以在不降低判断质量的前提下保持低成本,均通过环境变量标志启用: - **模型分层路由** (`platform/agentd/route_tier.py`, `ROUTER=on`) — 例行维护的心跳和纯机械性指令 (发布 / 衡量 / 记录 / 提交) 在更便宜的模型上运行 (`MODEL_ROUTINE`,例如 `claude-sonnet-4-6`),将顶级的 `MODEL` (例如 `claude-opus`) 预留给判断性任务 (决策 / 设计 / 审查 / 裁定)。**默认安全:** 任何模糊不清的任务 —— 或任何上游错误 —— 都会交由顶级模型处理。带有 `[tier:top]`/`[tier:cheap]` 标签的指令会按消息覆盖模型;已完成的 `- [ ]` 收件箱项目 (带有 `done:` 子行的项目) 不再计为待处理,因此过时的指令无法锁定顶级模型。 - **委派** (`platform/agentd/delegate.py` + `delegation_guard` PreToolUse hook) — 当 `BRAIN=claude` 时,一个能力出众的管理器会被*强制*将大量代码编写工作交给一个廉价/本地的工作器 (WORKER_MODE 下的 `local_agent.py`),而不是将前沿的 token 花费在敲击键盘上:工作器在验证门控下编写代码 (偏离任务的编辑会被回滚) 并且只返回 JSON 摘要。管理器负责计划 + 审查;工作器负责执行劳动。此守卫会自动适配为 `BRAIN=claude` — 对于 `api`/`local` 大脑来说是无操作,因为它们本身*已经是*那个廉价的工作器了。请参阅 `docs/DELEGATION.md`。 ## 管理集群 (多个 agent) 每个部署都是独立的,但你可以在一个地方管理它们 —— 无需为每个 agent 单独操心。 - **`enclave fleet`** — 通过 CLI 控制平面管理宿主机上的*所有*部署 (通过 `docker compose ls` 发现):`fleet list` (状态 / 大脑 / 模型 / 聊天端口 / 进行中的工作 / 存活状态,按 管理器分组),`fleet up|down|restart|logs|send `,`fleet open `。每一次修改都会经过验证 (id 和 compose 文件必须位于 `ENCLAVE_STACKS_ROOTS` 下) 并被写入仅追加的审计日志中。 - **`enclave console`** — 一个 web 面板,**通过一条命令完全串联起来**:它还会启动其按钮所需的后台 服务 (create-agent、apply-fix、health monitor),因此你不需要手动运行任何 daemon。每个 agent 包含:**聊天 · 状态 · 诊断** (成本/上下文/工具/模型,异常情况 — 适用于 **所有大脑**:`local`/`api` agent 会发出与 Claude 路径相同的每 tick 的 `events.jsonl`/`usage.jsonl` 遥测数据) **· 配置** (大脑/模式,以及实时编辑 agent 的任务/CLAUDE.md) **· 技能 · 日志**,左侧的 **rail** 按 管理器分组并显示实时状态,每个 agent 都有一个 **blocker strip**,一个集群 **Monitor** (检测→原因→修复,支持一键 Apply / Automate),以及一个 **+ New Agent** 表单。仅绑定 `127.0.0.1` (针对 远程访问请使用 tunnel);可选的 `CONSOLE_TOKEN` 门控;每一次修改都会经过验证过的 `fleet` 助手,绝不 直接调用 docker。Flags:`--no-watchers` (仅控制台),`--no-monitor`。Agent 会在 `ENCLAVE_STACKS_ROOTS` 下被发现 (默认值:此代码库的父目录 — 即 `enclave new` 放置同级目录的地方)。设计 说明:`docs/FLEET-CONSOLE-PLAN.md`。 ## 同时运行多个 agent 每个部署都由其 **agent 名称** (`AGENT_ID`) 标识,而不是其文件夹 —— compose 项目、 container 名称和命名卷都由此派生,因此无论你将它们放在哪里,部署都不会发生冲突。只需一条命令即可在它自己的文件夹中启动另一个 agent: ``` ./bin/enclave new support-bot # → ../support-bot/ , AGENT_ID=support-bot, a free port picked for you ./bin/enclave new analyst --dir ~/agents/analyst # choose the folder explicitly cd ../support-bot && ./bin/enclave run ``` `new` 会将产品复制 (减去你的 `home/`·`secrets/`·`.env`) 到新文件夹中,并在那里使用该名称 + 一个自动选择的空闲端口 (8888, 8889, …) 运行 `init`。你需要同时命名 **container** 和 文件夹;隔离 (home、secrets、工作、聊天会话、端口) 是自动完成的。 **无需本地构建 (预构建镜像):** 维护者只需发布一次 — `./bin/enclave publish --registry ghcr.io/` (在执行 `docker login ghcr.io` 之后) — 然后团队成员在 `.env` 中设置 `ENCLAVE_AGENT_IMAGE`/`ENCLAVE_CHAT_IMAGE` 并运行 `./bin/enclave run --pull` (无需 5 分钟的构建)。 默认情况下,`publish` 仅为**维护者的架构**进行构建。对于混合集群 (Apple-silicon + x86),请发布 **multi-arch**:`./bin/enclave publish --registry ghcr.io/ --platform linux/amd64,linux/arm64` (使用 buildx + QEMU;模拟架构的构建速度较慢,但任一架构上的队友随后都可以干净地执行 `run --pull`)。 ## 工作保存在哪里 — home (大脑) vs `/work` (项目) 两个挂载点保存了 agent 的工作: - **`home/` → `/agent`** — agent 的**大脑**:`CLAUDE.md`,`memory/`,`skills/`,`inbox.md`, `work.json`,`state/`。一个受扫描门控的 git 仓库 (持久化且对 secrets 安全)。 - **`WORK_DIR` → `/work`** — agent 的**工作文件夹**:它操作并 **保存工作内容** (读写) 的真实项目树。在 `.env` 中将 `WORK_DIR` 设置为任何宿主机路径即可使该树成为工作 文件夹;留空则默认使用 `home/work` (在保险库内)。`enclave init` 会提示你输入 (`--work-dir /abs/path` 可用于非交互式操作)。 保存的工作通过对 **`/work` 建立索引**来保持可搜索 — 宿主机的 qmd 网关会按计时器重新对其进行 embedding (或者 使用容器化的 `qmd`/`codegraph` profiles),因此 agent 自身的输出会在几分钟内反馈到它的记忆中。 agent 可以自由写入文件;它不能使用 `git` (被守卫拦截) — 由你掌握提交。 ## 聊天 (claude.ai 风格,`platform/agentd/web_chat.py`,纯标准库) 这是浏览器中真正的 Claude-Code 对话 — 只是 UI 有所不同: - **连续的,多对话** — 一个可折叠的左侧边栏 (**New chat · Search chats · 聊天列表**, 每个都有一个 "…" 菜单用于 **加星/删除**)。每个线程都是在 agent 自己的模型上的 **可恢复的 Claude Code 会话** (不是降级的辅助模型) — 它会记住包括工具调用在内的整个线程。 线程位于 `state/chat/.jsonl` 中;**会话可以在镜像重建后持久存在** (位于 `~/.claude` 的命名卷中)。新聊天 = 一个新的会话;agent 的持久记忆会在所有会话中延续。 - **斜命令** — 输入 `/` 获取 agent **技能** (`/ps-op-support`,`/ps-data`,…, 子字符串搜索) 以及 UI 命令 `/clear`,`/retry` (重新发送你的最后一条消息),`/export` (将 聊天下载为 markdown),`/help` 的菜单。技能在会话中运行;UI 命令在本地运行。 - **导出** — `/export` 或聊天的 "…" 菜单 → **Export markdown** 下载整个对话。 - **停止** — 发送按钮在回合运行时会翻转为 ⏹,并终止运行中的回合。 - **键盘快捷键 + 移动端** — ⌘/Ctrl-K 新建聊天,Esc 停止运行中的回合 (否则关闭菜单);在手机上 侧边栏会作为覆盖层滑入,聊天界面为全屏宽度。 - **文件下载** — agent 将交付内容写入 `/agent/outputs/` 并将它们链接为 `[name](/download?path=name)`;聊天界面会渲染一个 ⬇ 下载按钮 (CSV、报告、导出文件)。 - **富渲染** — markdown → HTML (表格、列表、标题、链接);围栏代码保持原样。 - **自动话题标题** — 每个对话按话题命名,而不是按逐字的首条消息。 - **从纠正中学习** — 当你纠正它或教给它一个持久的事实时,它会验证它所能验证的内容,并 自动将其保存到持久记忆中,并盖上一个**置信度等级** (`unverified` → `plausible` → `verified` → `strongly-verified`) + 来源印记,并链接到知识图谱中。它会 用一句话告诉你它保存了什么以及处于哪个等级;随着新证据的出现,等级会被提升/降低。这会在所有未来的聊天和工作 tick 中延续 (不仅仅是当前的线程)。 - **图片附件** (回形针/粘贴/拖放 → `home/uploads/`),**语音输入/输出** (浏览器 Web Speech, 或通过 `TRANSCRIBE_URL`/`TTS_URL` 的服务端语音 — 请参阅 `docs/VOICE-BACKEND.md`),以及一个 **实时的模型选择器**。 - **是对话,而非工作 tick** — 默认情况下,聊天回合是**只读的** (它可以读取文件 + 搜索, 但不允许使用 Bash/Write/Edit),因此 "status?" 会返回答案,而不是让 agent 去执行一个 漫长的构建。通过**工作平面** (`inbox.md` + `enclave send` / Telegram) 请求*操作*;或者设置 `CHAT_ALLOW_WRITES=1` 让聊天执行操作。运行在 agent 的大脑上:`claude` = 一个可恢复的会话; `api`/`local` = 在该大脑自己的 endpoint 上进行单次运行。 - 可调参数:`CHAT_MODEL` (聊天模型),`CHAT_BASE` (在比工作 大脑 *不同/更快* 的 endpoint 上运行聊天 — 例如,一个 `local` agent 在 NVIDIA 上聊天,这样它就不会和工作 tick 争夺 GPU),`CHAT_ALLOW_WRITES`, `CHAT_RESPONDER=off`。**完整参考:`docs/CHAT.md`。** ## 为什么它是安全的 (通过阅读代码来验证,而不是信任我们) - **容器隔离** — `--cap-drop=ALL --security-opt=no-new-privileges`;agent 上没有入站端口。 - **PreToolUse 守卫** (`platform/agentd/hooks/guard.py`) — 即使在 `--dangerously-skip-permissions` 下也会触发; 拦截 `git`、读取外部 secrets 以及 (可选 profiles) 云端写入 / 生产环境修改。 - **受限的 secrets** — 一个只读的 `./secrets/` 挂载;agent 无法访问其他任何内容。 - **受限的知识** — 语义搜索由一个带有集合白名单的每个 agent 独立的网关作为前端。 - **与大脑无关** — `BRAIN=claude | api | local | optimize`;相同的 container,相同的守卫,仅通过一个环境变量控制。 `optimize` 是自适应成本路由器:当 5小时/7天 的额度还有余量时,它会运行 Claude (边际上免费),然后切换到 `policy.json` 中最便宜的*可达*池 — 任何兼容 OpenAI 的 提供商 (xAI / OpenAI / Groq / OpenRouter / 本地 mlx-ollama 服务器),只需编辑一个文件即可添加。 ## 布局 ``` Dockerfile.agent lean agent image (python + node + claude CLI; opt-in codegraph) Dockerfile.chat/.relay web-chat + telegram sidecars (stdlib, tiny) Dockerfile.qmd/.codegraph optional memory-accelerator images (off by default — compose profiles) docker-compose.yml the stack (+ opt-in `qmd` / `codegraph` / `telegram` profiles) bin/enclave CLI: new / init / brain / run / publish / snapshot / vault-encrypt|decrypt / send / chat / status / stop / logs platform/agentd/ the runtime: agentloop, runtime.sh, guard + delegation_guard hooks, route_tier (model-tier router), delegate.py + local_agent.py (manager→worker delegation), memory (memory.py + wiki.py), vault_snapshot.py, web_chat, chat_responder, qmd + codegraph gateways, rlm.py tools/gcloud/ optional multi-tenant, read-only gcloud bridge (per-agent credential isolation) tools/bridge-template/ a WORKING bridge to copy — the extension point for host capabilities templates/ starter agent homes (ops, support, analyst) — all wired with guard + delegation_guard docs/ design notes — CHAT (the chat plane + per-brain endpoints + tunables), BRIDGES (give an agent a host capability — the contribution surface), DELEGATION (manager→worker), OPTIMIZE-BRAIN, WORK-DIR (working folder + indexing), WIKI-LAYER, MEMORY-PROVIDERS, MEMORY-MODES, CODE-MEMORY, WASM-SANDBOX, VETTING (dependency security passes), ROADMAP ``` ## 记忆 — 一个链接的、持久化的、对 secrets 安全的大脑 agent 的记忆是 **一个链接的保险库**,全部是 markdown 文件,全部可由 git 跟踪,可作为图谱浏览: - **存储 (默认,无需基础设施)** — 一个由 LLM 维护的 markdown **wiki** (`home/knowledge/`) *加上* 操作性记忆 (`home/memory/` 事实/决策/经验教训 + `home/skills/`)。它们是一个图谱: `wiki.py graph --brain` 会遍历所有内容中的反向链接/相邻节点/k-hop/路径。无需 DB/GPU/服务。 请参阅 `docs/WIKI-LAYER.md`。 - **检索 (可选)** — `qmd` 混合语义搜索,宿主机或容器化 (`--profile qmd`, 默认 CPU)。请参阅 `docs/MEMORY-PROVIDERS.md` / `docs/MEMORY-MODES.md`。 - **代码记忆 (可选)** — 基于代码库语料的 **codegraph** 符号/调用/依赖图,提供三种方式: in-agent (stdio)、共享索引或网络 HTTP bridge (`--profile codegraph`)。请参阅 `docs/CODE-MEMORY.md`。 - **对庞大上下文进行推理** — `rlm` 分块 → map → tree-reduce,适用于太大而无法完整读取的 blob。 - _我们评估了一个通用的图谱引擎 (Cognee) 但**拒绝**了它 (遥测 + 127 个依赖项);wiki 图 + codegraph 已经涵盖了实际需求。请参阅 `docs/VETTING.md`。_ **持久化且对 secrets 安全:** `enclave init` 会使 `home/` 成为其自己的 git 保险库;runtime 会在 每次 tick 后**自动生成快照**,以便即使在机器擦除后记忆也能存活。每个快照都是**受扫描门控、失败即关闭**的 — 粘贴到记忆中的 凭证会**阻止提交** (git 历史是永久的),而且 pre-commit hook 也会阻止 手动提交。`enclave vault-encrypt` 会写入一个 AES-256 归档文件 (密钥位于 `secrets/` 中,从不提交),因此异地副本是密文。agent 不能使用 `git` (被守卫拦截) — 由 runtime 掌握提交。 ## 已知的差距 (坦诚说明) - **出站强制执行默认是关闭的** — 请参阅此 README 的顶部。`GUARD_EGRESS_ENFORCE=1` 将白名单从日志转变为边界。附带的默认列表是有意保持最简的 (模型 API、包注册表、源码、镜像);其他所有内容 — 发布、邮件、搜索、 云端、代理 — 都是 `platform/agentd/hooks/policies/examples/` 下的可选文件。 - **宿主机功能 (bridges) 未包含在内** — 浏览器自动化、转录、TTS 和 类似功能作为宿主机服务存在于 container *之外*。Enclave 提供的是**模式**,而不是 服务:`docs/BRIDGES.md` + 一个可用的 `tools/bridge-template/`。开箱即用时,agent 可以 思考、读取、写入文件和调用 API;在你搭建起 bridge 之前,它无法驱动浏览器。 - **仅限 macOS + Linux,且依赖 Docker** — 在 macOS (Apple silicon) 和 Linux 上开发。 Windows 未经测试;WSL2 可能是可行的途径,但尚未有人验证。欢迎报告反馈。 - **预构建镜像** — `enclave-agent`/`enclave-chat` 发布到 ghcr (`run --pull`);默认是单架构,按需通过 `publish --platform linux/amd64,linux/arm64` 支持 **multi-arch**。可选的 `qmd`/`codegraph` 加速器镜像仍需在首次 `--profile … up` 时在本地构建。 - **WASM 工具沙箱** — 策略和一个带标记的路由 hook 已提供;`wasmtime` runtime (经验证是安全的) 尚未连接到执行器。这是纵深防御,而非阻碍因素。请参阅 `docs/WASM-SANDBOX.md`。 - **透明的静态加密** — openssl 归档文件已提供;`age`/`git-crypt` (按文件, 透明) 在安装后可作为直接替换方案。 有关威胁模型请参阅 `SECURITY.md`,有关设计说明请参阅 `docs/`。 ## wartzar-bee 工具包的一部分 enclave 在内部应用的相同的成本控制 (模型分层路由,manager→worker 委派) 也作为两个独立的工具发布,你可以在任何项目中使用它们: - **[tokenscope](https://github.com/wartzar-bee/tokenscope)** (`npm i -g @wartzar-bee/tokenscope`) — 一个 CLI,用于衡量提示词、文件和 diff 的 token 成本,让你在支付费用*之前*就能看到更改的成本。 - **[ci-guardrail](https://github.com/wartzar-bee/ci-guardrail)** (`uses: wartzar-bee/ci-guardrail@v1`) — 一个 GitHub Action,用于预测 pull request 的 token 成本增量,对相关文件发表评论, 并且可以在成本回归时使构建失败。 ## 贡献 最有用的贡献是一个 **bridge** — agent 可以通过狭窄的、 经过审计的接口调用的宿主机功能。请从 `docs/BRIDGES.md` 和 `tools/bridge-template/` 开始。包含 `enclave status` 输出和相关 `home/logs/runner.log` 行的错误报告,比不包含这些内容的报告有价值十倍。 ## 许可证 Apache-2.0 — 请参阅 `LICENSE` 和 `NOTICE`。贡献需遵循相同的许可证。
标签:Docker, 安全运行时, 安全防御评估, 容器隔离, 文档结构分析, 沙箱环境, 版权保护, 自主代理, 请求拦截, 逆向工具