docs: 质量优化重构总方案与任务级实施计划 v1
Some checks failed
Nix / nix (macos-latest) (push) Has been cancelled
Nix / nix (ubuntu-latest) (push) Has been cancelled

基于全面代码分析输出:
- 质量优化重构总方案_v1.md:五维度总体方案
- 质量优化重构实施计划_任务级_v1.md:78个任务,10周详细安排

关键结果:
- 新增模型提供商支持(腾讯云Coding Plan、百度文心、火山引擎、Cohere)
- 四层架构设计 + EventBus 抽象
- CI lint/security/type 全线门禁
- 异常规范化 + 类型安全基线化
- God Object 拆分路线图

验收标准:Lint 0 错误、高危安全漏洞清零、启动时间 -50%、测试覆盖率 70%+
This commit is contained in:
Your Name
2026-04-22 07:10:08 +08:00
parent e171ee5019
commit e93cbd2933
2 changed files with 1152 additions and 0 deletions

View File

@@ -0,0 +1,878 @@
# Hermes Agent 立交桥项目 — 任务级详细实施计划 v1.0
> 基于《质量优化重构总方案_v1》确认后输出
> 精度:任务级(每个任务可独立分配/跟踪/验收)
> 总工期10 周 | 总任务数78 个
---
## 一、项目背景与目标
### 1.1 现状问题
| 维度 | 关键病症 | 数量级影响 |
|------|---------|-----------|
| 代码质量 | Lint错误 / 类型错误 / 安全漏洞 | 1,717 + 2,383 + 26高危 |
| 系统稳定 | God Object / 循环依赖 / 回调爆炸 | 4个 >10k行 / 5+循环 / 12+回调 |
| 运维简捷 | 缺少CI门禁 / 日志无结构 / 配置体量大 | CI无lint/type检查 / 纯文本日志 / 3,882行配置 |
| 性能 | 启动慢 / 内存无限增长 / 并发模型混乱 | 内联导入 / 消息无上限 / sync+async混用 |
| 架构 | 无分层 / 插件偶合 / 技能复制粘贴 | hermes_cli作全局库 / 工具导入CLI插件 / memory插件重复 |
| 模型生态 | 缺少国内主流厂商支持 | 缺少腾讯云Coding Plan / 百度文心 / 火山 / Cohere |
### 1.2 总体目标
1. **代码质量**Lint 0 错误,核心模块类型安全,高危安全漏洞清零
2. **系统稳定**:单模块 < 1,500 行,循环依赖清零,回调收敛到 EventBus
3. **运维简捷**CI 全线通过lint/type/sec/cov/complexityJSON 日志Pydantic 配置
4. **性能优化**:启动时间 -50%,消息历史 Token 硬上限,并发模型统一
5. **架构简洁**:四层架构落地,插件正交,技能抽象
6. **模型生态**新增腾讯云Coding Plan / 百度文心 / 火山引擎 / Cohere 等主流厂商
---
## 二、总体里程碑
```
M1 基线治理期 第1-3周 安全零 + Lint零 + 测试绿通 + CI门禁 + 类型基线化 + core/包创建
M2 引擎重构期 第4-6周 God Object 拆分 + 循环依赖清理 + EventBus + 导入优化
M3 架构收尾期 第7-9周 Plugin正交 + Skill抽象 + 可观测性 + 配置简化 + 模型生态扩展
M4 验收回归期 第10周 全量回归测试 + 性能基准 + 文档补全
```
---
## 三、任务级详细计划
### 第 1 周:安全清零 + Ruff 修复 + 测试绿通
#### W1-T1 修复 shell=True 注入漏洞
- **输入依赖**: 无
- **输出产物**: 安全修复 PR
- **验收标准**:
- `tui_gateway/server.py:2267,3078``shlex.split` + `shell=False`
- `cli.py:6077` 同上
- `tools/skills_hub.py` 5处修复
- `tools/environments/docker.py:541,560` 修复
- `tools/transcription_tools.py:355` 修复
- `bandit -r . -lll` 无 B602 高危
- **风险点**: `skills_hub.py` 命令拼接逻辑复杂,需逐行 review
- **工时**: 1d
#### W1-T2 修复弱哈希使用
- **输入依赖**: 无
- **输出产物**: 安全修复 PR
- **验收标准**:
- `agent/codex_responses_adapter.py:171` `hashlib.sha1(usedforsecurity=False)`
- `agent/context_compressor.py:466` `hashlib.md5(usedforsecurity=False)`
- `gateway/platforms/weixin.py:1787` 同上
- `bandit -r . -lll` 无 B324 高危
- **风险点**: 微信平台使用 SHA1 为协议约定,需确认 `usedforsecurity=False` 不破坏签名验证
- **工时**: 0.5d
#### W1-T3 修复 urlopen 和 trust_remote_code 风险
- **输入依赖**: 无
- **输出产物**: 安全修复 PR
- **验收标准**:
- `agent/anthropic_adapter.py:487,795` 增加 scheme 白名单校验
- `trajectory_compressor.py:366` 固定 revision + 校验哈希
- `bandit -r . -lll` 无 B310/B615 高危
- **工时**: 0.5d
#### W1-T4 Ruff 全线自动修复
- **输入依赖**: 无
- **输出产物**: 代码风格统一 PR
- **验收标准**:
- `ruff check --fix` 全部执行1,031 自动修复应清零
- 剩余 686 处分批人工 review先处理 F401/F841/F541
- CI 新增 `ruff check` 门禁步骤
- `ruff check` 通过 = 0 errors
- **风险点**: 大规模修复导致 merge conflict需一次性执行后立即合并通知全员 rebase
- **工时**: 1d
#### W1-T5 修复硬失败测试
- **输入依赖**: 无
- **输出产物**: 测试修复 PR
- **验收标准**:
- `tests/agent/test_model_metadata_local_ctx.py::test_passes_bearer_token_to_probe_requests` PASS
- `tests/agent/test_credential_pool.py::test_load_pool_seeds_qwen_oauth_via_cli_tokens` PASS
- `tests/agent/test_credential_pool.py::test_load_pool_seeds_copilot_via_gh_auth_token` PASS
- `tests/agent/test_insights.py::TestGatewayFormatting::test_gateway_format_hides_cost` PASS
- `scripts/run_tests.sh` 全通过
- **风险点**: credential_pool 测试可能涉及 OAuth token 模拟逻辑,需确认是模拟缺陷还是业务回归
- **工时**: 1d
#### W1-T6 清理测试中的未使用导入/变量
- **输入依赖**: W1-T4 完成
- **输出产物**: 测试清洁 PR
- **验收标准**:
- `tests/` 下 F401/F841 清零
- 注册 `pytest.mark.ssh` 等自定义 mark 到 `pyproject.toml`
- **工时**: 0.5d
---
### 第 2 周core/ 包创建 + hermes_cli 解耦启动 + CI 增强
#### W2-T1 新建 `core/` 包结构
- **输入依赖**: 无
- **输出产物**: `core/` 目录 + `__init__.py`
- **验收标准**:
- 创建目录结构:`core/config.py`, `core/paths.py`, `core/models.py`, `core/auth/__init__.py`
- `core/__init__.py` 仅暴露安全 API不导入重型模块
- `core/` 不依赖任何其他内部包
- **工时**: 0.5d
#### W2-T2 将 `hermes_cli/config.py` 中无 UI 依赖函数迁移至 `core/config.py`
- **输入依赖**: W2-T1
- **输出产物**: `core/config.py` + 迁移 PR
- **验收标准**:
- 迁移:`load_config()`, `save_config()`, `get_hermes_home()`, `display_hermes_home()`, `_apply_profile_override()`
- 保留 `hermes_cli/config.py` 为 re-export facade向后兼容 1 版本)
- `core/config.py` 单元测试 PASS
- `tests/hermes_cli/test_profiles.py` PASS
- **风险点**: 迁移过程中可能丢失配置版本迁移逻辑,需对比原文件 3,882 行逐行审计
- **工时**: 2d
#### W2-T3 将 `hermes_cli/auth.py` 中通用认证逻辑迁移至 `core/auth/`
- **输入依赖**: W2-T1
- **输出产物**: `core/auth/tokens.py`, `core/auth/oauth.py`, `core/auth/providers/` + 迁移 PR
- **验收标准**:
- 迁移API key 解析、token 刷新、加密存储
- 各 provider OAuth 流程保留在 `hermes_cli/auth.py`(因涉及 CLI 交互)
- `hermes_cli/auth.py` 保留 facade
- **工时**: 1.5d
#### W2-T4 更新所有 `from hermes_cli.config import ...` 为 `from core.config import ...`
- **输入依赖**: W2-T2
- **输出产物**: 全局导入修复 PR
- **验收标准**:
- `agent/`, `tools/`, `gateway/`, `tui_gateway/` 中所有 `from hermes_cli.config import` 替换
- `ruff check` PASS
- `pytest` 全通过
- **风险点**: 可能导致插件第三方远程 import 失败,需留兼容 shim
- **工时**: 1d
#### W2-T5 更新所有 `from hermes_cli.auth import ...` 非 UI 依赖
- **输入依赖**: W2-T3, W2-T4
- **输出产物**: 全局导入修复 PR
- **验收标准**:
- 非交互类认证导入替换为 `from core.auth import`
- `ruff check` PASS
- `pytest` 全通过
- **工时**: 0.5d
#### W2-T6 CI 增强:新增 lint 和 security 门禁
- **输入依赖**: W1-T1~T4 完成
- **输出产物**: `.github/workflows/tests.yml` 升级 PR
- **验收标准**:
- CI 新增 `ruff check` 步骤(门禁)
- CI 新增 `bandit -r agent/ tools/ gateway/ -lll` 步骤(门禁)
- CI 新增 `xenon --max-absolute B` 步骤(门禁,先开启不阻断)
- `uv pip install` 改为矩阵安装core / dev / messaging 分层)
- CI 增加 `~/.cache/uv` 缓存
- **工时**: 1d
#### W2-T7 CI 增强:新增测试覆盖率报告
- **输入依赖**: W2-T6
- **输出产物**: CI 升级 PR
- **验收标准**:
- CI 新增 `pytest --cov=agent --cov=tools --cov=gateway --cov-report=xml`
- 集成 codecov 或 PR comment 中显示覆盖率变化
- **工时**: 0.5d
---
### 第 3 周:类型安全基线化 + 异常规范 + 死代码清理
#### W3-T1 安装缺失 stub 包
- **输入依赖**: 无
- **输出产物**: 依赖增加 PR
- **验收标准**:
- 安装 `types-PyYAML`, `types-requests`
- `mypy agent/ tools/registry.py``import-untyped` 错误清零
- **工时**: 0.5d
#### W3-T2 治理隐式 Optional核心模块
- **输入依赖**: W3-T1
- **输出产物**: 类型修复 PR
- **验收标准**:
- 修复 `agent/context_engine.py:73`, `tools/file_operations.py:330`, `agent/trajectory.py:31`, `tools/checkpoint_manager.py:453`, `hermes_state.py:138`
- 统一使用 `Optional[T]``T | None` 语法
- `mypy --strict agent/` 不报隐式 Optional 错误
- **工时**: 1.5d
#### W3-T3 治理 Union-attr 和 incompatible assignment
- **输入依赖**: W3-T2
- **输出产物**: 类型修复 PR
- **验收标准**:
- 修复 `agent/copilot_acp_client.py:389` 等 Union-attr 错误
- 修复 `tools/file_operations.py:169-216` incompatible assignment
- `mypy --strict agent/ tools/registry.py` 不报 union-attr
- **工时**: 1.5d
#### W3-T4 异常处理规范化(第一批)
- **输入依赖**: 无
- **输出产物**: 异常规范化 PR
- **验收标准**:
- 高优先级模块 `tui_gateway/server.py`, `agent/auxiliary_client.py`, `tools/voice_mode.py` 中的裸 except 治理
- 每个 except 块必须携带 `logger.warning/error`
- 禁止空 `pass`
- `bandit -r .` 中 B110 数量显著下降
- **工时**: 1d
#### W3-T5 死代码清理Vulture 结果)
- **输入依赖**: W1-T4
- **输出产物**: 死代码清理 PR
- **验收标准**:
- 移除 `acp_adapter/server.py:314` `client_capabilities` 等未使用变量
- 移除 `agent/display.py:795` 未使用异常变量
- 移除 `gateway/platforms/slack.py` 4 处未使用 `say`
- `ruff check` PASS
- `pytest` 全通过
- **风险点**: 部分 "未使用"变量可能是用于调试的,需人工确认
- **工时**: 1d
#### W3-T6 异常规范化(第二批,全局)
- **输入依赖**: W3-T4
- **输出产物**: 异常规范化 PR
- **验收标准**:
- 全局 1,244 处 `except Exception: pass` → 明确异常类型
- 不能确定的场景使用 `except Exception as e: logger.warning(...)`
- `bandit -r .` B110 计数 = 0生产代码
- **工时**: 2d
---
### 第 4 周run_agent.py 拆分 + 导入优化 + TurnEngine 初始化
#### W4-T1 设计 `agent/loop/` 包结构
- **输入依赖**: 无
- **输出产物**: 设计文档 / ADR
- **验收标准**:
- 定义 `agent/loop/` 目录:`turn_engine.py`, `streaming.py`, `compression.py`, `retry_policy.py`, `checkpointing.py`
- 定义模块界面,确保无循环依赖
- 保留 `run_agent.py` facade 设计(`__getattr__` 延迟导入)
- **工时**: 0.5d
#### W4-T2 实现 `agent/loop/turn_engine.py`
- **输入依赖**: W4-T1
- **输出产物**: `agent/loop/turn_engine.py` + 单元测试
- **验收标准**:
-`run_agent.py` 抽取对话引擎核心API 调用、工具执行、消息管理)
- 支持 sync 模式,预留 async 接口
- 单元测试覆盖率 ≥ 80%
- `pytest` 全通过
- **风险点**: `run_conversation` 逻辑复杂,抽取时可能遗漏 edge case
- **工时**: 2d
#### W4-T3 实现 `agent/loop/streaming.py` 和 `compression.py`
- **输入依赖**: W4-T2
- **输出产物**: 两个模块 + 单元测试
- **验收标准**:
- `streaming.py`: 管理 SSE/stream 解析、delta 分发
- `compression.py`: 抽象 `ContextCompressor`,支持增量压缩策略
- 单元测试覆盖率 ≥ 80%
- **工时**: 1.5d
#### W4-T4 实现 `agent/loop/retry_policy.py` 和 `checkpointing.py`
- **输入依赖**: W4-T2
- **输出产物**: 两个模块 + 单元测试
- **验收标准**:
- `retry_policy.py`: 抽象 `RetryPolicy` dataclass统一重试逻辑
- `checkpointing.py`: 抽象检查点管理,支持 SQLite 归档
- 单元测试覆盖率 ≥ 80%
- **工时**: 1.5d
#### W4-T5 `run_agent.py` 改为 facade 并近似保留原 API
- **输入依赖**: W4-T2~T4
- **输出产物**: `run_agent.py` 重构 PR
- **验收标准**:
- `run_agent.py` 保留 `AIAgent` 类名和 `__init__` / `chat` / `run_conversation` 签名
- 内部实现转发到 `agent/loop/`
- `pytest tests/agent/` 全通过
- `ruff check` PASS
- **风险点**: facade 可能引入过渡层性能损耗,需基准测试
- **工时**: 1d
#### W4-T6 导入优化:工具注册懒加载
- **输入依赖**: 无
- **输出产物**: 懒加载 PR
- **验收标准**:
- `tools/*.py` 中顶层 `registry.register()` 改为延迟注册(首次调用时才执行网络/文件检查)
- 冷启动时间基准:`time python -c "import run_agent"` 记录当前值
- 目标:启动时间减少 ≥ 30%
- **工时**: 1d
#### W4-T7 `__init__.py` 减负
- **输入依赖**: W4-T6
- **输出产物**: `__init__.py` 优化 PR
- **验收标准**:
- 所有 `__init__.py` 中禁止导入重型模块(`run_agent`, `cli`, `model_tools`
- `time python -c "import run_agent"` 启动时间减少 ≥ 50%
- **工时**: 0.5d
---
### 第 5 周gateway/run.py 拆分 + 循环依赖清理 + 消息历史优化
#### W5-T1 设计 `gateway/` 拆分结构
- **输入依赖**: 无
- **输出产物**: 设计文档
- **验收标准**:
- 定义 `gateway/lifecycle.py`, `gateway/delivery_router.py`, `gateway/platform_coordinator.py`, `gateway/voice_manager.py`
- 保留 `gateway/run.py` facade
- **工时**: 0.5d
#### W5-T2 实现 `gateway/lifecycle.py`
- **输入依赖**: W5-T1
- **输出产物**: `gateway/lifecycle.py` + 测试
- **验收标准**:
- 管理 Gateway 启动/停止/重启/配置加载
- 单元测试覆盖率 ≥ 70%
- **工时**: 1.5d
#### W5-T3 实现 `gateway/delivery_router.py` 和 `platform_coordinator.py`
- **输入依赖**: W5-T2
- **输出产物**: 两个模块 + 测试
- **验收标准**:
- `delivery_router.py`: 消息路由、会话匹配、重试逻辑
- `platform_coordinator.py`: 多平台适配器管理
- 单元测试覆盖率 ≥ 70%
- **工时**: 1.5d
#### W5-T4 实现 `gateway/voice_manager.py`
- **输入依赖**: W5-T2
- **输出产物**: `gateway/voice_manager.py` + 测试
- **验收标准**:
- 管理语音模式、TTS/STT 生命周期
- 单元测试覆盖率 ≥ 70%
- **工时**: 1d
#### W5-T5 `gateway/run.py` 改为 facade
- **输入依赖**: W5-T2~T4
- **输出产物**: `gateway/run.py` 重构 PR
- **验收标准**:
- 保留 `GatewayRunner` 类名和核心方法签名
- 内部转发到各子模块
- `pytest tests/gateway/` 全通过
- **工时**: 1d
#### W5-T6 消息历史 Token 硬上限 + SQLite 归档
- **输入依赖**: W4-T2
- **输出产物**: `agent/loop/context_manager.py` + 测试
- **验收标准**:
- 实现 `TokenBudget` 类,硬上限默认 128k tokens可配置
- 超限消息自动归档到 SQLite`hermes_state.py` 扩展)
- 归档后支持检索(`/resume` 命令不受影响)
- 测试覆盖率 ≥ 80%
- **工时**: 1.5d
#### W5-T7 循环依赖清理(余留)
- **输入依赖**: W2-T4, W2-T5, W4-T5, W5-T5
- **输出产物**: 循环依赖解决 PR
- **验收标准**:
- `pydeps agent/ tools/ gateway/ hermes_cli/ tui_gateway/` 无包级循环
- 所有 `from hermes_cli.config import` 在非 CLI 代码中清零
- `pytest` 全通过
- **风险点**: 部分循环依赖可能需要更多中间层抽象
- **工时**: 1.5d
---
### 第 6 周cli.py 拆分 + AgentEventBus + 回调收敛
#### W6-T1 设计 `AgentEventBus` / `AgentObserver`
- **输入依赖**: 无
- **输出产物**: ADR
- **验收标准**:
- 定义 Protocol`AgentObserver`
- 定义 `AgentEventBus` 类,支持多观察者注册/取消/事件分发
- 定义事件类型:`ToolStartEvent`, `ToolProgressEvent`, `StreamDeltaEvent`, `ClarifyEvent`, ...
- **工时**: 0.5d
#### W6-T2 实现 `AgentEventBus`
- **输入依赖**: W6-T1
- **输出产物**: `agent/event_bus.py` + 测试
- **验收标准**:
- 实现同步/异步事件分发
- 单元测试覆盖率 ≥ 90%
- **工时**: 1d
#### W6-T3 将 `AIAgent` 12+ 回调改为 EventBus 模式
- **输入依赖**: W6-T2, W4-T5
- **输出产物**: 回调收敛 PR
- **验收标准**:
- `AIAgent.__init__` 从 50+ 参数 → `AgentConfig` + `AgentObserver` 参数
- `tool_progress_callback`, `thinking_callback`, `reasoning_callback` 等收敛为单一 `observer: AgentObserver`
- 保持向后兼容(旧回调参数映射为内部适配器)
- `pytest tests/agent/` 全通过
- **风险点**: 回调变化影响所有前端CLI/TUI/Gateway需逐一测试
- **工时**: 2d
#### W6-T4 设计 `cli/` 拆分结构
- **输入依赖**: 无
- **输出产物**: 设计文档
- **验收标准**:
- 定义 `cli/display_engine.py`, `cli/stream_renderer.py`, `cli/input_handler.py`, `cli/layout_manager.py`
- 保留 `cli.py` facade
- **工时**: 0.5d
#### W6-T5 实现 `cli/display_engine.py` 和 `stream_renderer.py`
- **输入依赖**: W6-T4
- **输出产物**: 两个模块 + 测试
- **验收标准**:
- `display_engine.py`: KawaiiSpinner、Rich 面板、品牌渲染
- `stream_renderer.py`: 流式输出、该理解笔、思考标签处理
- 单元测试覆盖率 ≥ 70%
- **工时**: 1.5d
#### W6-T6 实现 `cli/input_handler.py` 和 `layout_manager.py`
- **输入依赖**: W6-T5
- **输出产物**: 两个模块 + 测试
- **验收标准**:
- `input_handler.py`: 文件托拽、图片处理、输入历史
- `layout_manager.py`: TUI 布局、分隔符、窗口管理
- 单元测试覆盖率 ≥ 70%
- **工时**: 1.5d
#### W6-T7 `cli.py` 改为 facade
- **输入依赖**: W6-T5, W6-T6
- **输出产物**: `cli.py` 重构 PR
- **验收标准**:
- 保留 `HermesCLI` 类名和核心方法
- 内部转发到 `cli/` 子模块
- `pytest` 全通过
- **工时**: 1d
---
### 第 7 周:可观测性 + 配置 Pydantic 化 + hermes_cli/main.py 拆分
#### W7-T1 结构化日志JSON 模式)
- **输入依赖**: W2-T2
- **输出产物**: `hermes_logging.py` 升级 PR
- **验收标准**:
- `hermes_logging.py` 支持 `HERMES_LOG_FORMAT=json` 环境变量
- JSON 日志字段包含timestamp, level, logger, message, task_id, duration_ms
- 默认保持文本模式(向后兼容)
- `pytest` 全通过
- **工时**: 1d
#### W7-T2 指标埋点
- **输入依赖**: W4-T2
- **输出产物**: `agent/metrics.py` + 测试
- **验收标准**:
- 实现 `hermes_turn_latency_seconds` 计数器
- 实现 `hermes_tool_errors_total` 计数器
- 实现 `hermes_api_calls_total` 计数器
- 支持定时将指标写入文件(`/tmp/hermes_metrics.prom`
- 测试覆盖率 ≥ 80%
- **工时**: 1d
#### W7-T3 Gateway `/health` 和 `/ready` 端点
- **输入依赖**: W5-T2
- **输出产物**: 健康检查 PR
- **验收标准**:
- Gateway API 模式时增加 `/health`(基础健康)和 `/ready`(依赖就绪)
- `/ready` 检查 AI provider 连通性、数据库连接
- `pytest tests/gateway/` 通过
- **工时**: 0.5d
#### W7-T4 配置 Pydantic 化
- **输入依赖**: W2-T2
- **输出产物**: `core/config_models.py` + 测试
- **验收标准**:
-`DEFAULT_CONFIG` 和配置校验逻辑迁移为 Pydantic Settings 模型
- 支持环境变量自动映射
- 支持配置热重载SIGHUP 或文件监视)
- 配置版本迁移逻辑保留
- 测试覆盖率 ≥ 80%
- **风险点**: Pydantic 化可能引入新的默认值差异,需对比原逻辑
- **工时**: 2d
#### W7-T5 `hermes_cli/main.py` 拆分
- **输入依赖**: W6-T7, W7-T4
- **输出产物**: `hermes_cli/commands/` 目录 + facade PR
- **验收标准**:
- 创建 `hermes_cli/commands/chat.py`, `commands/gateway.py`, `commands/setup.py`, `commands/profile.py`
- `hermes_cli/main.py` 保留 facade向后兼容
- 每个新模块 < 1,500 行
- `pytest tests/hermes_cli/` 全通过
- **工时**: 2d
---
### 第 8 周Plugin 正交化 + Skill 抽象 + 模型生态扩展
#### W8-T1 提取 `PluginHost` Protocol 到 `agent/`
- **输入依赖**: 无
- **输出产物**: `agent/plugin_host.py` + ADR
- **验收标准**:
- 定义 `PluginHost` Protocol`on_session_start`, `on_tool_call`, `on_response` 等 hook
- 定义 `HookLifecycleManager` 类,统一调度 hook 执行
- 不依赖 `hermes_cli`
- **工时**: 1d
#### W8-T2 `hermes_cli/plugins.py` 实现 `PluginHost` Protocol
- **输入依赖**: W8-T1
- **输出产物**: `hermes_cli/plugins.py` 改造 PR
- **验收标准**:
- `hermes_cli/plugins.py` 实现 `PluginHost` Protocol
- `invoke_hook()` 改为 `HookLifecycleManager.dispatch()`
- `pytest` 全通过
- **工时**: 1d
#### W8-T3 `tools/` 解耦 `hermes_cli.plugins`
- **输入依赖**: W8-T2
- **输出产物**: 解耦 PR
- **验收标准**:
- `tools/skills_tool.py``from hermes_cli.plugins import invoke_hook``from agent.plugin_host import HookLifecycleManager`
- `tools/terminal_tool.py` 同理
- `ruff check` PASS
- `pytest` 全通过
- **工时**: 0.5d
#### W8-T4 抽象 `BaseMemoryPlugin`
- **输入依赖**: W8-T1
- **输出产物**: `plugins/base_memory.py` + 改造 PR
- **验收标准**:
- 定义 `BaseMemoryPlugin` ABC`store()`, `retrieve()`, `delete()`
-`plugins/memory/*` 下的复制粘贴模式改为继承 `BaseMemoryPlugin`
- 每个 memory backend 模块 < 300 行
- `pytest` 全通过
- **工时**: 1d
#### W8-T5 模型生态扩展:腾讯云 Coding Plan 支持
- **输入依赖**: 无
- **输出产物**: 模型支持 PR
- **验收标准**:
- 新增 ProviderEntry`ProviderEntry("tencent-coding", "Tencent Cloud Coding Plan", "Tencent Cloud Coding Plan (hunyuan models — coding plan API)")`
- 新增 HERMES_OVERLAY`"tencent-coding": HermesOverlay(transport="openai_chat", base_url_env_var="TENCENT_CODING_BASE_URL")`
- 新增 aliases`tencent`, `coding-plan`, `codingplan``tencent-coding`
- 新增环境变量:`TENCENT_CODING_API_KEY``.env.example`
- 新增默认模型列表:`tencent/hunyuan-coding`, `tencent/hunyuan-lite`
- 新增 setup 向导支持
- 测试覆盖:`tests/hermes_cli/test_models.py` 新增用例
- **工时**: 1d
#### W8-T6 模型生态扩展:百度文心一言
- **输入依赖**: 无
- **输出产物**: 模型支持 PR
- **验收标准**:
- 新增 ProviderEntry`ProviderEntry("baidu", "Baidu ERNIE", "Baidu ERNIE (ernie-bot models — direct API)")`
- HERMES_OVERLAY`transport="openai_chat"`, `base_url_env_var="BAIDU_BASE_URL"`
- aliases`ernie`, `wenxin``baidu`
- `.env.example` 新增 `BAIDU_API_KEY`
- 测试覆盖新增用例
- **工时**: 0.5d
#### W8-T7 模型生态扩展:火山引擎 / 豆包
- **输入依赖**: 无
- **输出产物**: 模型支持 PR
- **验收标准**:
- 新增 ProviderEntry`ProviderEntry("volcengine", "Volcano Engine / Doubao", "Volcano Engine Doubao (doubao models — direct API)")`
- HERMES_OVERLAY`transport="openai_chat"`, `base_url_env_var="VOLCENGINE_BASE_URL"`
- aliases`doubao`, `volcano``volcengine`
- `.env.example` 新增 `VOLCENGINE_API_KEY`
- 测试覆盖新增用例
- **工时**: 0.5d
#### W8-T8 模型生态扩展Cohere
- **输入依赖**: 无
- **输出产物**: 模型支持 PR
- **验收标准**:
- 新增 ProviderEntry`ProviderEntry("cohere", "Cohere", "Cohere (Command R+ models — direct API)")`
- HERMES_OVERLAY`transport="openai_chat"`, `base_url_env_var="COHERE_BASE_URL"`
- `.env.example` 新增 `COHERE_API_KEY`
- 测试覆盖新增用例
- **工时**: 0.5d
---
### 第 9 周:并发模型统一 + 上下文压缩优化 + 内存治理
#### W9-T1 并发模型设计
- **输入依赖**: W4-T2
- **输出产物**: ADR
- **验收标准**:
- Gateway 侧全异步
- CLI 侧同步 wrapper
- 底层共享 `asyncio` 事件循环
- 工具 handler 支持 `async def`
- **工时**: 0.5d
#### W9-T2 `agent/loop/` 支持 async 模式
- **输入依赖**: W9-T1, W4-T2
- **输出产物**: `agent/loop/async_turn_engine.py` + 测试
- **验收标准**:
- 实现 `AsyncTurnEngine`,复用 `turn_engine.py` 核心逻辑
- 工具调用支持 async handler
- 单元测试覆盖率 ≥ 80%
- **工时**: 1.5d
#### W9-T3 Gateway 移植到全异步
- **输入依赖**: W9-T2, W5-T5
- **输出产物**: Gateway async 移植 PR
- **验收标准**:
- `gateway/run.py` 中所有工具调用改为 `await`
- `environments/agent_loop.py` 中 ThreadPoolExecutor 改为 asyncio
- `pytest tests/gateway/` 全通过
- 压测 latency 不恶化
- **风险点**: 并发模型变化影响所有平台适配器,需逐一测试
- **工时**: 2d
#### W9-T4 上下文压缩增量优化
- **输入依赖**: W4-T3
- **输出产物**: `agent/loop/compression.py` 升级 PR
- **验收标准**:
- 实现增量压缩(只压缩新增消息)
- 实现压缩结果 LRU 缓存
- 新增 `compression_strategy` 配置:`speed` / `balanced` / `quality`
- 性能对比:压缩时间 -30%
- **工时**: 1d
#### W9-T5 内存治理:全局状态收敛
- **输入依赖**: W4-T2
- **输出产物**: 内存优化 PR
- **验收标准**:
- `_last_resolved_tool_names`, `_tool_loop`, `_worker_thread_local` 收敛到 `AgentContext`
- `trajectory_compressor.py` 中 tokenizer 改为 LRU 缓存maxsize=4支持显式清空
- 使用 `tracemalloc` 验证内存无泄漏
- **工时**: 1d
#### W9-T6 `environments/agent_loop.py` 与 `run_agent.py` 合并验证
- **输入依赖**: W9-T3
- **输出产物**: 合并验证报告
- **验收标准**:
- 确认 `environments/agent_loop.py` 逻辑已完全被 `agent/loop/` 覆盖
- 确认无逻辑 divergence
- 删除 `environments/agent_loop.py` 或改为 facade
- `pytest tests/environments/` 全通过
- **工时**: 0.5d
---
### 第 10 周:全量回归测试 + 性能基准 + 文档补全
#### W10-T1 全量回归测试
- **输入依赖**: 所有前期任务
- **输出产物**: 测试报告
- **验收标准**:
- `scripts/run_tests.sh` 全通过14,140 测试)
- 无回归失败
- 核心模块覆盖率 ≥ 70%
- **工时**: 1d
#### W10-T2 测试覆盖率提升
- **输入依赖**: W10-T1
- **输出产物**: 测试补充 PR
- **验收标准**:
- `agent/display.py` 45% → 70%
- `tools/file_operations.py` 53% → 75%
- 新增测试用例通过 CI
- **工时**: 1.5d
#### W10-T3 性能基准验收
- **输入依赖**: W4-T6~T7, W9-T4~T5
- **输出产物**: 性能报告
- **验收标准**:
- 启动时间:`time python -c "import run_agent"` 当前基准 → -50%
- 对话压测100 轮对话 latency / throughput / 错误率 不恶化
- 压缩对比:增量压缩时间 -30%
- 内存报告100 轮对话后内存增长 < 10MB
- **工时**: 1d
#### W10-T4 CI 全线通过验收
- **输入依赖**: 所有前期任务
- **输出产物**: CI 验收报告
- **验收标准**:
- `ruff check` 门禁通过 = 0 errors
- `mypy --strict agent/ tools/registry.py` 门禁通过 = 0 errors
- `bandit -r agent/ tools/ gateway/ -lll` 门禁通过 = 0 High
- `pytest` 全通过
- `xenon --max-absolute B` 无阻断(先记录)
- **工时**: 0.5d
#### W10-T5 架构图和模块依赖图更新
- **输入依赖**: 所有前期任务
- **输出产物**: 更新后的 `AGENTS.md` 架构部分
- **验收标准**:
- 更新 `AGENTS.md` 中的 File Dependency Chain
- 新增四层架构图
- 新增模块依赖规则说明
- 更新添加新工具/配置/命令的步骤说明
- **工时**: 0.5d
#### W10-T6 文档补全
- **输入依赖**: W10-T5
- **输出产物**: 更新后的文档
- **验收标准**:
- 新增《开发者迁移指南》(从旧模块到新模块的导入变化)
- 新增《新增模型提供商指南》
- 更新 README 中的模型支持列表
- 更新 RELEASE 文档
- **工时**: 0.5d
---
## 四、任务关联与依赖图
```
W1: T1-T6 独立并行
├→ W2-T6 (CI lint/security 门禁)
└→ W3-T5 (死代码清理需要 lint 完成)
W2: T1-T7 串行+并行
T1 → T2 → T4
T1 → T3 → T5
T2,T3,T4,T5 → W5-T7 (循环依赖清理)
T6 → W7-T4 (配置 Pydantic 化需 core/config)
W3: T1-T6 并行+串行
T1 → T2 → T3
T4 → T6
T2,T3 → W4-T5 (类型安全需要修复后才能参与 run_agent 拆分)
W4: T1-T7 并行+串行
T1 → T2 → T3,T4
T2,T3,T4 → T5
T6 → T7
T5 → W5-T6 (消息历史需要 TurnEngine)
T5 → W6-T3 (回调收敛需要新引擎)
T5 → W9-T2 (async 需要 TurnEngine)
W5: T1-T7 并行+串行
T1 → T2 → T3,T4
T2,T3,T4 → T5
T6 → W10-T3 (测试验收需要消息历史)
T5 → W7-T3 (health 端点需要 gateway 拆分)
T5 → W9-T3 (async 需要新 gateway)
W6: T1-T7 并行+串行
T1 → T2 → T3
T4 → T5,T6 → T7
T3 → W9-T3 (并发模型需要 EventBus)
W7: T1-T5 并行+串行
T1,T2 → W10-T3 (性能验收)
T4 → T5
W8: T1-T8 高度并行
T1 → T2 → T3
T1 → T4
T5-T8 独立
W9: T1-T6 并行+串行
T1 → T2 → T3
T4,T5,T6 独立
T3 → W10-T3 (性能验收)
W10: T1-T6 串行+并行
T1 → T2
T3,T4,T5,T6 独立
```
---
## 五、质量门禁与验收矩阵
### 5.1 CI 门禁(红线)
| 检查项 | 工具 | 门禁时机 | 阈值 | 责任人 |
|--------|------|---------|------|--------|
| Lint | ruff | 每次 push/PR | 0 errors | CI |
| 安全 | bandit | 每次 push/PR | 0 High/Medium | CI |
| 类型 | mypy | 每次 push/PR | 核心模块 0 errors | CI |
| 复杂度 | xenon | 每次 push/PR | 记录不阻断 | CI |
| 测试 | pytest | 每次 push/PR | 100% PASS | CI |
| 覆盖率 | pytest-cov | 每次 push/PR | 核心 ≥ 70% | CI |
### 5.2 代码审查规范
- 所有 PR 必须通过 CI 全部门禁
- God Object 拆分 PR 必须有单独的集成测试通过
- 安全修复 PR 必须有安全团队 review
- 架构变更 PR 必须更新 ADR 和 AGENTS.md
### 5.3 测试覆盖率路线图
| 模块 | 当前 | M1 目标 | M2 目标 | M4 目标 |
|------|------|---------|---------|---------|
| tools/registry.py | 85% | 85% | 90% | 95% |
| agent/context_references.py | 84% | 84% | 90% | 95% |
| agent/loop/* | N/A | 80% | 85% | 90% |
| agent/display.py | 45% | 50% | 60% | 70% |
| tools/file_operations.py | 53% | 55% | 65% | 75% |
| gateway/lifecycle.py | N/A | 70% | 75% | 80% |
---
## 六、风险应对与回退方案
### 6.1 风险登记簿
| ID | 风险描述 | 概率 | 影响 | 应对措施 | 回退方案 |
|----|---------|------|------|---------|--------|
| R1 | 拆分 God Object 引入回归 | 中 | 高 | 保留 facade每个拆分独立 PR增加集成测试 | facade 文件恢复原内实现 |
| R2 | hermes_cli→core 迁移破坏插件 | 中 | 高 | 提供兼容 shim灰度发布 | 恢复 hermes_cli 为全局库(技术债务增加) |
| R3 | Ruff 大规模修复 merge conflict | 高 | 低 | 一次性执行后立即合并;通知全员 rebase | 分批执行,每天一个目录 |
| R4 | Mypy 严格模式阻塞开发 | 中 | 中 | 分模块开启;允许 `type: ignore` 配额(每模块 5 个) | 降低 mypy 严格级别,先用 `--ignore-missing-imports` |
| R5 | 性能优化改变并发语义 | 低 | 高 | 压测对比;金丝雀发布 | 保留旧并发模型作为 fallback |
| R6 | 模型提供商接口变更 | 中 | 中 | 模型提供商支持独立 PR不阻断主线 | 移除该提供商支持,等待接口稳定 |
| R7 | 关键人员离岗 | 低 | 高 | 每个关键任务配备份责任人;文档完整 | 减少当周任务量,保持核心功能稳定 |
### 6.2 回退策略详细
- **代码级回退**:所有重构 PR 必须通过 `git revert` 可以在 5 分钟内完成
- **功能级回退**:新功能(如 async Gateway必须有特性开关默认关闭
- **配置级回退**:所有新配置必须有后向兼容的默认值
---
## 七、资源需求
### 7.1 人力
| 角色 | 人数 | 职责 |
|------|------|------|
| 架构负责人 | 1 | ADR 审查、架构门禁、技术决策 |
| 后端开发 | 2 | God Object 拆分、core/ 包、引擎重构 |
| 工具/配置开发 | 1 | CI 增强、配置 Pydantic 化、可观测性 |
| 安全/测试 | 1 | 安全漏洞修复、测试补充、回归测试 |
| 模型生态 | 1 | 新增模型提供商支持 |
| 总计 | **6 人** | |
### 7.2 工具链
| 工具 | 用途 | 版本要求 |
|------|------|---------|
| ruff | Lint + format | ≥ 0.9 |
| mypy | 类型检查 | ≥ 1.15 |
| bandit | 安全扫描 | ≥ 1.8 |
| pytest + pytest-xdist + pytest-cov | 测试 | ≥ 9.0 |
| xenon | 代码复杂度 | ≥ 0.9 |
| pydeps | 依赖分析 | 最新 |
| tracemalloc | 内存分析 | Python 内置 |
### 7.3 环境
- Python 3.11+ 开发环境
- GitHub Actions ubuntu-latest runner
- 本地测试机:至少 8GB RAMSSD
- 测试 API 键位置:项目提供测试帐号(高优先级提供商)
---
## 八、附录
### A. 术语对照表
| 本文档术语 | 对应工具/概念 |
|----------|------------|
| God Object | 超大模块(如 run_agent.py 12,048 行) |
| facade | 保持原有 API 签名,内部转发到新模块的兼容层 |
| EventBus | 事件总线,用于取代多个回调函数参数 |
| 四层架构 | Presentation → Application → Domain → Infrastructure |
| 金丝雀发布 | 小流量逐步切换,降低风险 |
| CI 门禁 | 持续集成中必须通过的检查步骤 |
### B. 相关文档
- `plans/质量优化重构总方案_v1.md` — 总体方案
- `AGENTS.md` — 当前架构说明
- `.github/workflows/tests.yml` — 当前 CI 配置
- `pyproject.toml` — 依赖管理
---
> 文档编号: PLAN-2026-0421-v1
> 最后更新: 2026-04-21
> 审批状态: 待用户最终确认

View File

@@ -0,0 +1,274 @@
# Hermes Agent 立交桥项目 — 全面质量优化重构方案 v1.0
> 项目名称隐喻:当前代码库如同一座年久失修的立交桥 —— 车道纵横交错(循环依赖)、
> 承重结构超重( God Object )、信号系统混乱(回调爆炸)、维护人员无从下手。
> 本方案旨在对其进行"结构性加固+交通流线重构+智能信号升级"。
---
## 一、项目全景诊断
### 1.1 规模画像
| 指标 | 数值 | 评级 |
|------|------|------|
| Python 源码文件 | 1,044 | 大型 |
| TypeScript/TSX 文件 | 276 | 中型 |
| 总代码行数 | ~535,704 | 超大型 |
| 测试数量 | 14,140 (669 文件) | 优秀 |
| 项目体积 | 1.1GB (venv 782MB) | 偏重 |
| 生产依赖 | 37+ 核心包 | 可控 |
### 1.2 技术债务热力图
| 维度 | 问题数量 | 严重度 |
|------|---------|--------|
| Lint 违规 (Ruff) | 1,717 (1,031 可自动修复) | 中高 |
| 类型错误 (Mypy) | ~2,383 | 高 |
| 高危安全漏洞 | 26 | **紧急** |
| 中危安全漏洞 | 575 | 高 |
| 裸 except Exception: pass | 1,244 | 中 |
| 循环依赖包对 | 5+ | **高** |
| 超 3,000 行 God Object | 4 个 | **高** |
| 测试硬失败 | 4 个 | 中 |
| 测试覆盖率洼地 | 45-53% | 中 |
---
## 二、五维度重构方案
### 维度 A代码质量 — 消除路面裂缝
#### A1. 静态分析基线化P0第 1 周)
- **Ruff 全线修复**`ruff check --fix` 自动修复 1,031 处;剩余 686 处按规则分批人工 review
- **F401 未使用导入专项**860 处未使用导入清理,减少模块加载时间 5-10%
- **F841 未使用变量**160 处,清理死代码,降低认知负担
#### A2. 类型安全加固P1第 2-3 周)
- **隐式 Optional 治理**PEP 484 违规(`def foo(x: int = None)`)全量修复,约 200+ 处
- **核心模块类型覆盖**:优先 `agent/`, `tools/registry.py`, `hermes_cli/config.py`
- **Stub 补全**:安装 `types-PyYAML`, `types-requests`,消除 `import-untyped` 噪音
- **Mypy 门禁**CI 新增 `mypy --strict agent/ tools/registry.py` 步骤,逐步扩大范围
#### A3. 安全漏洞清零P0第 1-2 周)
| 漏洞类型 | 文件位置 | 修复方案 |
|---------|---------|---------|
| B602 shell=True 注入 | `tui_gateway/server.py:2267,3078` | 改 `shlex.split` + `shell=False` |
| B602 shell=True 注入 | `cli.py:6077` | 同上 |
| B602 shell=True 注入 | `tools/skills_hub.py` (5处) | 参数化或改用 `subprocess.run([...])` |
| B602 shell=True 注入 | `tools/environments/docker.py:541,560` | 同上 |
| B324 弱哈希 | `agent/codex_responses_adapter.py:171` | `hashlib.sha1(usedforsecurity=False)` |
| B324 弱哈希 | `agent/context_compressor.py:466` | `hashlib.md5(usedforsecurity=False)` |
| B324 弱哈希 | `gateway/platforms/weixin.py:1787` | 同上 |
| B310 urlopen | `agent/anthropic_adapter.py:487,795` | 增加 scheme 校验白名单 |
| B615 trust_remote_code | `trajectory_compressor.py:366` | 固定 revision + 校验哈希 |
#### A4. 异常处理规范化P1第 3 周)
- **裸 except 治理**1,244 处 `except Exception: pass` → 明确异常类型
- **静默失败审计**:高优先级模块(`tui_gateway/server.py`, `agent/auxiliary_client.py`)首批治理
- **日志补偿**:所有 except 块必须携带 `logger.warning/error`,禁止空 pass
---
### 维度 B系统稳定 — 加固承重结构
#### B1. God Object 拆解P1-P2第 2-6 周)
当前 4 个超万行/近万行巨兽:
| 原文件 | 行数 | 拆分目标 |
|--------|------|---------|
| `run_agent.py` | 12,048 | `agent/loop/turn_engine.py` + `streaming.py` + `compression.py` + `retry_policy.py` + `checkpointing.py` |
| `gateway/run.py` | 11,043 | `gateway/lifecycle.py` + `delivery_router.py` + `platform_coordinator.py` + `voice_manager.py` |
| `cli.py` | 10,870 | `cli/display_engine.py` + `stream_renderer.py` + `input_handler.py` + `layout_manager.py` |
| `hermes_cli/main.py` | 8,707 | `commands/chat.py` + `commands/gateway.py` + `commands/setup.py` + `commands/profile.py` |
**拆分原则**
- 每个新模块 < 1,500 行
- 保留原文件为 facade向后兼容 1 个版本)
- 使用 `__getattr__` 延迟导入避免循环依赖
#### B2. 循环依赖解耦P1第 3-5 周)
核心问题:`hermes_cli` 既是 CLI 入口,又是全局配置/认证库。
**根治方案 — 提取 `core/` 层**
```
core/
├── config.py # 从 hermes_cli/config.py 提取纯配置逻辑
├── auth/
│ ├── providers/ # 各 provider OAuth 独立模块
│ ├── tokens.py
│ └── oauth.py
├── paths.py # get_hermes_home() 等路径工具
└── models.py # 模型元数据/目录
```
**迁移路径**
1. 新建 `core/` 包,将 `hermes_cli/config.py` 中无 UI 依赖的函数迁移
2. `hermes_cli/config.py` 改为 re-export facade
3. 逐文件替换 `from hermes_cli.config import ...``from core.config import ...`
4. 同理处理 `hermes_cli/auth.py``core/auth/`
#### B3. 核心对话引擎单一化P1第 4-5 周)
- **问题**`run_agent.py:run_conversation``environments/agent_loop.py` 逻辑重复
- **方案**:将 `environments/agent_loop.py` 的 ThreadPoolExecutor 模型合并到 `agent/loop/`
- **统一入口**`TurnEngine` 类,支持 sync/async 双模式,消除 divergence risk
#### B4. 回调爆炸收敛P2第 5-6 周)
- **现状**`AIAgent.__init__` 接收 12+ 个回调参数
- **方案**:引入 `AgentEventBus``AgentObserver` Protocol
```python
class AgentObserver(Protocol):
def on_tool_start(self, tool_name: str, args: dict): ...
def on_tool_progress(self, tool_name: str, delta: str): ...
def on_stream_delta(self, text: str): ...
# ... 统一收敛
```
---
### 维度 C运维简捷 — 智能信号系统
#### C1. CI/CD 增强P1第 2-3 周)
当前 `.github/workflows/tests.yml` 已覆盖 pytest但缺少
| 新增步骤 | 工具 | 阈值 |
|---------|------|------|
| Lint 门禁 | `ruff check` | 0 errors |
| 类型检查 | `mypy --strict` | 核心模块 0 errors |
| 安全扫描 | `bandit -r agent/ tools/ gateway/` | 无 High/Medium |
| 代码复杂度 | `xenon --max-absolute B` | 无 D/F 级模块 |
| 测试覆盖率 | `pytest --cov` | 核心模块 ≥ 70% |
**优化现有 CI**
- `tests.yml``uv pip install -e ".[all,dev]"` 过重 → 改为矩阵安装core / messaging / dev 分层)
- 增加缓存:`~/.cache/uv`, `.venv`
#### C2. 可观测性升级P2第 5-6 周)
- **结构化日志**`hermes_logging.py` 当前为文本日志,增加 JSON 模式(`HERMES_LOG_FORMAT=json`
- **指标埋点**:核心对话循环增加 `hermes_turn_latency_seconds`, `hermes_tool_errors_total` 等 Prometheus 风格指标
- **健康检查端点**Gateway 增加 `/health``/ready`FastAPI 模式时)
#### C3. 配置管理简化P2第 6 周)
- **统一配置 Schema**`hermes_cli/config.py` 3,882 行 → Pydantic Settings 模型
- **环境变量自文档**`.env.example` 已有,但缺少验证逻辑
- **配置热重载**Gateway 运行时不重启加载配置变更
#### C4. 依赖瘦身P2第 6-7 周)
- `uv.lock` 体积审计:找出只有一个文件使用的重型依赖
- `optional-dependencies` 已较好,但 `all` 安装过重 → 提供 `hermes-agent[slim]` 精简版
- 检查 `node_modules` 在 Docker 镜像中的残留
---
### 维度 D性能优化 — 拓宽车道、减少拥堵
#### D1. 启动加速P1第 3-4 周)
- **导入优化**`tools/*.py` 中大量顶层 `registry.register()` 触发网络/文件检查 → 改为延迟注册
- **__init__.py 减负**:禁止 `__init__.py` 中 import 重型模块
- **基准**:当前冷启动时间(`python -c "import run_agent"`)→ 目标减少 50%
#### D2. 内存优化P2第 5-6 周)
- **全局状态审计**`_last_resolved_tool_names`, `_tool_loop`, `_worker_thread_local` 等全局变量 → 注入 `AgentContext`
- **大对象生命周期**`trajectory_compressor.py` 中 HuggingFace tokenizer 全局缓存 → LRU + 显式释放
- **消息历史截断**:当前 `messages` 列表无限增长 → 实现 TokenBudget 硬上限,超限时归档到 SQLite
#### D3. 并发模型统一P2第 6 周)
- **现状**`run_agent.py` 同步循环,`gateway/run.py` 异步,`environments/agent_loop.py` ThreadPool
- **目标**Gateway 侧全异步CLI 侧同步 wrapper底层共享 `asyncio` 事件循环
- **工具执行**:当前工具在同步线程中跑 → 支持 `async def` 工具 handler
#### D4. 上下文压缩优化P2第 6 周)
- **现状**`ContextCompressor` 内联在对话循环中,每次 turn 都触发
- **优化**:增量压缩,只压缩新增消息;缓存压缩结果;提供 `compression_strategy` 配置speed/balanced/quality
---
### 维度 E架构简洁 — 重建交通流线
#### E1. 分层架构重构P2-P3第 6-10 周)
目标四层结构:
```
┌─────────────────────────────────────────┐
│ Presentation Layer │
│ cli.py / gateway/ / ui-tui / tui_gateway│
├─────────────────────────────────────────┤
│ Application Layer │
│ hermes_cli/commands.py / agent/loop/ │
├─────────────────────────────────────────┤
│ Domain Layer │
│ agent/ (prompt, context, compression) │
│ tools/ (registry, handlers) │
├─────────────────────────────────────────┤
│ Infrastructure Layer │
│ core/ (config, auth, paths, models) │
│ environments/ (docker, ssh, modal...) │
└─────────────────────────────────────────┘
```
**依赖规则**
- 上层可依赖下层,禁止反向
- `core/` 不依赖任何其他内部包
- `tools/` 不依赖 `hermes_cli/`, `gateway/`, `cli.py`
#### E2. Plugin 系统正交化P2第 6-7 周)
- **问题**`tools/skills_tool.py` 导入 `hermes_cli.plugins``tools/terminal_tool.py` 也导入
- **方案**:将 `PluginHost` Protocol 定义在 `agent/` 层,`hermes_cli/plugins.py` 实现该 Protocol
- **Hook 生命周期管理器**:从 `run_agent.py` 的硬编码 hook 调用 → `HookLifecycleManager` 统一调度
#### E3. Skill 系统去重P3第 8-9 周)
- **现状**`plugins/memory/*` 下多个插件复制粘贴相同 `__init__.py` 模式
- **方案**:抽象 `BaseMemoryPlugin`,统一生命周期;各 memory backend 只实现 `store()`/`retrieve()`/`delete()`
#### E4. 测试架构升级P1-P3贯穿全程
- **修复硬失败**`test_credential_pool.py`, `test_insights.py`, `test_model_metadata_local_ctx.py`
- **覆盖率提升**`agent/display.py` 45% → 70%`tools/file_operations.py` 53% → 75%
- **Mock 策略统一**:禁止测试中直接 `patch("run_agent.something")`,改用 `patch("agent.loop.turn_engine.something")`
- **并行测试稳定**:当前 `-n auto` 在 16+ 核机器上不稳定 → 固定 `-n 4`(已体现在 `scripts/run_tests.sh`
---
## 三、风险矩阵与回退策略
| 风险 | 概率 | 影响 | 缓解措施 |
|------|------|------|---------|
| 拆分 God Object 引入回归 | 中 | 高 | 保留 facade 文件 1 个版本;每个拆分独立 PR增加集成测试 |
| hermes_cli → core 迁移破坏插件 | 中 | 高 | 提供 `hermes_cli.config` 兼容 shim灰度发布 |
| Ruff 大规模修复导致 merge conflict | 高 | 低 | 一次性执行后立即合并;通知全员 rebase |
| Mypy 严格模式阻塞开发 | 中 | 中 | 分模块开启,先核心后外围;允许 `type: ignore` 配额 |
| 性能优化改变并发语义 | 低 | 高 | 压测对比( latency / throughput / 错误率 );金丝雀发布 |
---
## 四、预期收益
| 指标 | 当前基线 | 目标 | 测量方式 |
|------|---------|------|---------|
| 代码 Lint 错误 | 1,717 | 0 | `ruff check` |
| 类型错误 (核心模块) | ~800 | 0 | `mypy agent/ tools/registry.py` |
| 高危安全漏洞 | 26 | 0 | `bandit -lll` |
| 最大单文件行数 | 12,048 | < 1,500 | `find . -name "*.py" | xargs wc -l` |
| 冷启动导入时间 | 基线 TBD | -50% | `time python -c "import run_agent"` |
| 核心模块测试覆盖率 | 45-53% | ≥ 70% | `pytest --cov` |
| CI 全绿通过率 | 99.8% | 100% | GitHub Actions |
| 循环依赖包对 | 5+ | 0 | `pydeps` / 静态分析 |
---
## 五、实施节奏概览
```
第 1 周:安全清零 + Ruff 修复 + 测试修复
第 2 周core/ 包创建 + hermes_cli 解耦启动
第 3 周:类型安全基线化 + CI 增强
第 4 周run_agent.py 拆分启动 + 导入优化
第 5 周gateway/run.py 拆分 + 循环依赖清理
第 6 周cli.py 拆分 + AgentEventBus 落地
第 7 周:可观测性 + 配置 Pydantic 化
第 8 周Plugin 正交化 + Skill 抽象
第 9 周:并发模型统一 + 上下文压缩优化
第 10 周:全量回归测试 + 性能基准验收
```
---
> 下一步:与用户讨论确认本方案,细化各阶段任务粒度、责任人、验收标准,
> 形成可执行的《详细实施计划文档》。