
Hermes WebUI 的 Agent 源码边界挂载契约、导入耦合清单与解耦路径【免费下载链接】hermes-webuiHermes WebUI: The best way to use Hermes Agent from the web or from your phone!项目地址: https://gitcode.com/GitHub_Trending/he/hermes-webui本篇技术指南围绕 Hermes WebUI 仓库中的 RFC 文档 docs/rfcs/agent-source-boundary.md 展开。该文档定义了 WebUI 与 Hermes Agent 源码之间的边界契约为什么多容器部署中挂载hermes-agent-src只算兼容桥梁而非长期 API 契约、当前有哪些 WebUI 能力仍直接 import Agent 内部模块、以及每条依赖应迁移到何种版本化的 Agent API 之后才能最终移除源码挂载。读完本文你可以完整复现该边界的 Docker 安全防护链路只读挂载、chown剪枝、启动告警、理解八项源码依赖清单每一行的现状与目标契约并知道回归测试是如何把这套文档钉死防止其退化的。背景一个看起来隔离的多容器部署在本地安装中WebUI 之所以能调用 Hermes Agent 的能力是因为工作区旁边恰好存在一份 Agent 源码 checkoutPython 可以直接import其中的run_agent、hermes_cli、agent等模块。在多容器 Docker 部署中同样的假设被显式化为一个共享卷Agent 容器把自己的源码放在/opt/hermes并通过命名卷hermes-agent-src暴露出去WebUI 容器把同一个卷挂到/home/hermeswebui/.hermes/hermes-agent单卷双用途。两个 compose 文件都采用这一结构且 WebUI 侧挂载带:ro后缀docker-compose.two-container.yml 中 Agent 服务声明- hermes-agent-src:/opt/hermes可写WebUI 服务声明- hermes-agent-src:/home/hermeswebui/.hermes/hermes-agent:ro只读docker-compose.three-container.yml 采用相同的卷布局。RFC 的核心论断是这个源码挂载是兼容桥梁不是期望的长期契约。即使 WebUI 侧是只读挂载它依然把 WebUI 的版本发布耦合到了 Hermes Agent 的内部模块布局上——Agent 侧任何一次模块改名、移动或签名变化都可能让 WebUI 的 import 在运行时失败。因此多容器部署看起来更隔离实际上在文件系统/源码兼容层面并没有真正隔离。docs/docker.md 的安全边界一节也明确复述了这一点只读挂载意味着被入侵的 WebUI 无法改写 Agent 源码但它仍然会执行来自该卷的代码即信任边界只防改写、不防执行。当前安全姿态safety postureRFC 记录了三条当前已落地、可验证的防护措施1. Compose 默认只读挂载如上所述两个容器 compose 文件中 WebUI 服务对hermes-agent-src的挂载默认是只读的:roAgent 服务保留可写权限以完成自身运行。2.docker_init.bash把 Agent 源码子树从chown中剪枝只读挂载会给启动脚本带来一个实际问题entrypoint 在 root 初始化阶段需要对/home/hermeswebui做属主对齐chown而:ro卷内任何chown都会返回EROFS在set -e下直接杀掉启动流程。仓库的解法见 docker_init.bash 中的chown_home_hermeswebui()函数find /home/hermeswebui \ -path /home/hermeswebui/.hermes/hermes-agent -prune \ -o -name .git -prune \ -o -exec chown -h ${WANTED_UID}:${WANTED_GID} {} 即整棵 Agent 源码路径被prune掉chown只在其余 home 目录上执行。源码注释解释了动因WebUI 从不写 Agent 源码只读或部分只读挂载不应破坏其余 home 目录的属主对齐同时覆盖 macOS Docker 将 git object pack 暴露为只读文件的场景issue #2237。3. 可写挂载触发启动告警而非直接失败如果运维人员覆写 compose 文件、给 WebUI 侧挂了一个可写的 Agent 源码路径启动逻辑会发出醒目的告警但不阻止启动——因为本地开发 checkout 和某些自定义部署确实有意需要可写。这段逻辑同样在 docker_init.bash 的依赖安装分支里if [ -w $_agent_src ]; then echo !! WARNING: hermes-agent source mount is writable from the WebUI container. echo !! Path: $_agent_src echo !! The multi-container compose defaults use a read-only mount for defence-in-depth. echo !! If this is not an intentional local development checkout, switch the WebUI echo !! agent source volume/bind mount to read-only. See docs/rfcs/agent-source-boundary.md. fi告警文本直接指向本 RFC形成文档—启动脚本—回归测试三者互相印证闭环。源码访问清单八项仍依赖 Agent 源码的 WebUI 能力这是 RFC 的主体。每一行代表一项今天仍依赖 Agent 源码或hermes_cli/agent模块可导入的 WebUI 能力以及它应该迁移到的目标 API/契约。下表完整继承原 RFC 清单并在现状佐证列给出仓库内可核验的导入点WebUI 能力当前依赖目标 API / 契约现状佐证仓库内导入点浏览器聊天执行api/streaming.py链路导入run_agent.AIAgentRun 生命周期 APIstart、observe、status、cancel、approval、clarify、final usageapi/agent_runtime.py 内from run_agent import AIAgentL417 附近由流式执行链路调用运行时事件渲染WebUI 侧围绕 Agent token/reasoning/tool 事件的回调token、reasoning、progress、tool 生命周期、approval、clarify、error、final usage 的稳定事件包络现有 run-adapter RFC 已描述浏览器侧形态见 docs/rfcs/hermes-run-adapter-contract.mdAgent 侧仍需一个可持久承诺的生产者契约Profile 列表/创建/删除/seedapi/profiles.py依赖hermes_cli.profilesProfile 管理 APIprofile 元数据、env/runtime 上下文、seed/delete 操作、校验错误api/profiles.py 内 importhermes_cli.profilesWebUI 对部分操作有回退的文件系统处理但功能对齐仍跟随 Hermes CLI 内部实现Goal 命令状态api/goals.py依赖hermes_cli.goalsGoal CRUD/控制 APIget、save、pause/resume/clear、statusapi/goals.py 顶部from hermes_cli.goals import ...及save_goal导入需在保留/goalWebUI 现有行为的前提下消除直接模块导入斜杠命令注册表与插件命令api/commands.py依赖hermes_cli.commands与hermes_cli.plugins按当前 profile 作用域划分的命令/插件能力发现 APIapi/commands.py 中COMMAND_REGISTRY、get_plugin_commands等导入WebUI 应改为从稳定的能力响应渲染命令帮助Provider/auth/模型目录api/config.py依赖hermes_cli.models、hermes_cli.auth、agent.credential_poolProvider 注册表、模型目录、认证状态、OAuth/credential-pool 状态 APIapi/config.py 中可见hermes_cli.models_PROVIDER_MODELS、provider_model_ids等、hermes_cli.authPROVIDER_REGISTRY、get_auth_status、agent.credential_poolload_pool等多处导入WebUI 有静态回退但精确对齐与自定义 provider 状态来自 Agent 内部脱敏redaction助手对齐api/helpers.py依赖agent.redact.redact_sensitive_text带签名/版本兼容承诺的脱敏服务或库契约api/helpers.py 中from agent.redact import redact_sensitive_text由于该 import 历史上变化过WebUI 保留了一个回退脱敏器CLI/Gateway 会话桥接侧边栏/会话助手读取 Agentstate.db模式与 gateway 元数据面向非 WebUI 来源会话的会话列表/transcript/元数据 API仓库内state.db的读取分散在 api/agent_sessions.py、api/session_discoverability.py、api/route_session_list_cache.py 等模块直接 SQLite/模式耦合应随时间收窄尤其是 messaging/email/gateway 会话两点值得强调事件渲染一行与 run-adapter 迁移的边界浏览器聊天执行一行的备注说明其已被 issue #1925 的 runtime-adapter 迁移覆盖但今天仍是源码支撑的——即迁移路径已立项对应 docs/rfcs/hermes-run-adapter-contract.md 所定义的事件/控制契约但契约尚未由 Agent 侧以稳定 API 形式兑现。README.md的口径一致README.md 明确说明在 #1925 / #2491 的稳定边界工作落地之前运行不匹配的旧/新组合是未经测试且不支持的原因是 WebUI 直接导入 Agent 模块并直接读取 Agent 状态布局版本漂移会导致 import 或行为漂移。解耦任务清单RFC 给出的六步任务列表是这份清单从文档走向实施的操作顺序保持 Docker 默认安全两个与三个容器 compose 文件中WebUI 侧的hermes-agent-src维持只读。诚实记录边界持续在文档中说明多容器部署隔离的是进程、网络与资源而非文件系统/源码兼容性。可写挂载必须大声告警当 WebUI 容器看到可写的 Agent 源码挂载时因为那会削弱纵深防御姿态启动时必须显著告警已由docker_init.bash实现并被测试锁定见下文。运行时执行优先走 #1925 的 RuntimeAdapter 路径新增能力不再增加直接 import而是经由 runtime-adapter 契约迁移。清单逐行立项为清单中每一行建立或关联后续 issue先定义 Agent API 的响应形态再替换 import。在条件满足前不得宣称可移除挂载聊天执行、provider 目录/认证状态、profiles、goals、commands/plugins、redaction、导入的 Agent/Gateway 会话——在以上全部拥有稳定替代契约之前不能宣称源码挂载可以移除。明确的非目标non-goals为避免这份文档-only的清单被误读为立即行动项RFC 列出四条边界约束不移除HERMES_WEBUI_AGENT_DIR不破坏本地源码 checkout 的开发方式不因 Agent 源码可写而使启动直接失败只告警不在本清单切片内替换 runtime adapter 或 Hermes Agent API。这也解释了为什么告警而非报错可写挂载在本地开发中是合法的策略上选择显式化弱化而不是强制拒绝。回归测试文档如何被钉住这份 RFC 不是普通的散文仓库用 tests/test_issue2453_agent_source_boundary.py 对其做了三重锁定防止文档退化成没有后续任务列表的模糊安全提示test_agent_source_boundary_rfc_inventories_import_coupling断言 RFC 文件存在且必须包含全部关键耦合符号run_agent.AIAgent、hermes_cli.profiles、hermes_cli.goals、hermes_cli.commands、hermes_cli.plugins、hermes_cli.models、hermes_cli.auth、agent.credential_pool、agent.redact.redact_sensitive_text、state.db以及五个目标契约短语Run lifecycle API、Profile management API、Command/plugin capability discovery API、Provider registry, model catalog, auth status、Session listing/transcript/metadata API。任何从清单中删掉一行的 PR 都会直接红。test_docker_startup_warns_when_agent_source_mount_is_writable对 docker_init.bash 做文本断言要求包含agent source mount is writable、read-only mount、$_agent_src及-w $_agent_src探测逻辑确保第 3 条任务清单的实现不会被无意回退。test_docker_docs_link_source_boundary_inventory断言 docs/docker.md 必须引用agent-source-boundary.md并含 source/API boundary inventory 与 issue 号保证运维文档入口不丢失。这个RFC 文本断言回归的组合是该仓库处理架构边界问题的典型模式文档本身成为可测试的契约工件。为什么只读挂载不能算解耦把整份 RFC 压缩成一句话就是挂载模式的收紧ro解决的是防御纵深问题而 import 清单解决的是版本契约问题两者不能互相替代。只读挂载保证 WebUI 无法篡改 Agent 源码但 WebUI 启动时仍会从该卷执行uv pip install -e注意 docker_init.bash 为此把源码暂存到可写的/app/hermes-agent-src再做 editable 安装因为 setuptools 的egg_info构建步骤会在源树内写元数据在:ro上直接 EROFS 失败运行时WebUI 仍从这份源码 import 八个类别的内部模块上表清单因此真正的解除条件是清单第六项所有能力都获得稳定替代契约。在那之前docs/docker.md 给出的运维建议也对应着这一姿态——自定义 compose/bind mount 时保持 WebUI 侧 Agent 源码挂载只读除非你在做有意为之的本地开发。小结docs/rfcs/agent-source-boundary.mdissue #2453 追踪状态 Proposed为 Hermes WebUI 与 Hermes Agent 之间的源码耦合建立了一份可执行的账目当前安全姿态compose 只读默认、chown剪枝、可写挂载告警、八行能力 → 当前 import → 目标 API的迁移清单、六步解耦任务顺序、四条非目标约束以及由 tests/test_issue2453_agent_source_boundary.py 保证的文档完整性。它的价值不在于立即移除任何挂载而在于让WebUI 何时可以不再需要 Agent 源码这个问题从一句口号变成一张有测试守护的清单。【免费下载链接】hermes-webuiHermes WebUI: The best way to use Hermes Agent from the web or from your phone!项目地址: https://gitcode.com/GitHub_Trending/he/hermes-webui创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考