问题现象
Hermes Desktop 客户端与 Gateway 存在配置双写冲突。用户通过 Desktop UI 切换模型后,config.yaml 出现矛盾状态(如 provider: dashscope + �ase_url: localhost:18080),导致模型切换失效。
环境
- Windows 11 Pro
- Desktop 客户端与 Gateway 运行在同一主机
- HERMES_HOME 指向 %LOCALAPPDATA%\hermes
根因分析
| 组件 |
写入方式 |
写入目标 |
| Desktop (setModelConfig → upsertBlockChild()) |
逐字段文本替换(正则匹配) |
%LOCALAPPDATA%\hermes\config.yaml |
| Gateway (save_config() → �tomic_yaml_write()) |
PyYAML 全量 dict 写回 |
同一文件 |
两个组件竞争写入同一文件,但机制完全不同:
- Desktop 的 setModelConfig() 仅替换 model 块中的 3 个字段(provider/default/base_url),不修改其他配置
- Gateway 的 save_config()(位于 hermes_cli/config.py:5073)在 _handle_set_model()(
un.py:11141)中被调用,将整个 config dict 全量写回磁盘——这会覆盖 Desktop 的修改和其他运行时状态
触发路径
- Desktop UI 点击模型切换 → IPC set-model-config → setModelConfig() 写入 config.yaml →
estartGateway() → POST /api/reload
- Gateway 在处理 reload 或内部模型切换时,_handle_set_model() 调用 save_config(cfg) 全量写入
- 问题:Gateway 内部的 config dict 可能包含过时值(如旧 provider),全量覆盖导致 Desktop 的修改丢失
本地权宜方案(已实施)
我们实施了 Config Watchdog 脚本(PowerShell),每 3 分钟检测 4 种矛盾状态并从 golden config 恢复:
- provider=dashscope + �ase_url=localhost → 矛盾
- provider=custom + �ase_url 指向云服务 → 矛盾
- 云模型名 + 非对应 provider → 不匹配
- GGUF 本地模型 + 非 custom provider → 不匹配
局限性:依赖外部定时任务,无法实时响应配置变更,无法彻底消除双写风险。
上游修复建议
P0(关键阻断):统一配置写入接口
�ash hermes config apply <key>=<value> # 统一写入接口 hermes config sync [desktop|gateway] # 选择性同步
所有配置变更强制通过此命令中转,弃用对 config.yaml 的直接写入。
P1(架构重组):Gateway 重构为 Config Observer 模式
- Gateway 订阅 Desktop 的配置变更事件,通过 MCP 协议或 WebSocket 实时同步
- 移除 Gateway 对 config.yaml 的直接写入能力(仅允许读取)
P2(基础设施):分布式配置管理
- 引入分布式锁防止多节点配置写入冲突
- 增加 config_diff 工具,检测变更并触发同步
P3(可视化):Dashboard 配置健康监控
- 配置一致性状态灯(绿/黄/红)、冲突配置实时告警与对比视图
P4(可追溯):版本控制集成
- git 记录 Golden Config 历史变更,支持 config rollback
实施优先级
| 优先级 |
修复项 |
预计工作量 |
| P0 |
统一配置写入接口 |
~2周 |
| P1 |
Gateway 重构为 Config Observer |
~4周 |
| P2 |
分布式配置管理模块 |
~6周 |
| P3 |
Dashboard 可视化 |
~2周 |
| P4 |
版本控制集成 |
~1周 |
风险提示
- P0 与 P1 涉及核心架构调整,需确保向后兼容性
- 配置变更的原子性是关键——建议使用写时复制(copy-on-write)机制
本报告由用户运维团队与 Hermes AI 协同分析生成
相关实现代码见 Desktop/hermes_config_watchdog.ps1
记忆系统记录见 hermes-agent/memories/MEMORY.md
问题现象
Hermes Desktop 客户端与 Gateway 存在配置双写冲突。用户通过 Desktop UI 切换模型后,config.yaml 出现矛盾状态(如 provider: dashscope + �ase_url: localhost:18080),导致模型切换失效。
环境
根因分析
两个组件竞争写入同一文件,但机制完全不同:
un.py:11141)中被调用,将整个 config dict 全量写回磁盘——这会覆盖 Desktop 的修改和其他运行时状态
触发路径
estartGateway() → POST /api/reload
本地权宜方案(已实施)
我们实施了 Config Watchdog 脚本(PowerShell),每 3 分钟检测 4 种矛盾状态并从 golden config 恢复:
局限性:依赖外部定时任务,无法实时响应配置变更,无法彻底消除双写风险。
上游修复建议
P0(关键阻断):统一配置写入接口
�ash hermes config apply <key>=<value> # 统一写入接口 hermes config sync [desktop|gateway] # 选择性同步所有配置变更强制通过此命令中转,弃用对 config.yaml 的直接写入。
P1(架构重组):Gateway 重构为 Config Observer 模式
P2(基础设施):分布式配置管理
P3(可视化):Dashboard 配置健康监控
P4(可追溯):版本控制集成
实施优先级
风险提示
本报告由用户运维团队与 Hermes AI 协同分析生成
相关实现代码见 Desktop/hermes_config_watchdog.ps1
记忆系统记录见 hermes-agent/memories/MEMORY.md