Agent 自驱动代码修复实践:从发现 Hermes Bug 到提交 PR 的完整过程

案例类型:Agent 自驱动 Bug 修复
项目:Hermes Agent (NousResearch/hermes-agent)
PR:#13974
耗时:约 10 分钟(从发现问题到提交 PR)
人工介入:仅需确认关键决策(是否提交 PR)
一、案例背景
用户正在配置 Hermes Agent 的模型切换功能,希望添加火山引擎 Coding Plan 的多个模型(glm-5.1, kimi-k2-6, minimax-m2-7)到 /model 命令的可选列表中。
配置完成后,用户发现问题:/model 命令只显示 glm-5.1,不显示其他添加的模型。
二、Agent 诊断流程
2.1 配置检查
Agent 首先检查用户配置文件,发现两个关键配置项:
| 配置项 | 作用 | /model 显示 |
|---|---|---|
fallback_providers | 主模型失败时的备用链 | ❌ 不显示 |
custom_providers | 用户自定义的 provider | ✅ 显示 |
用户的新模型被添加到了 fallback_providers,但 custom_providers 的配置也存在问题——只显示默认模型。
2.2 源码追踪
Agent 追踪到 hermes_cli/model_switch.py 中的 list_authenticated_providers() 函数,这是 /model 命令的模型列表生成器。
函数分为 4 个 Section:
Section 1: Hermes-mapped providers (models.dev catalog) Section 2: Hermes-only providers (nous, openai-codex, copilot, opencode-go) Section 2b: Cross-check canonical provider list Section 3: User-defined endpoints from config ← 正确处理 models 字典 Section 4: Saved custom providers from config ← ❌ Bug 所在
2.3 Bug 定位
Agent 发现 Section 4 的代码逻辑存在明显缺陷:
# model_switch.py 第 1083-1085 行
default_model = (entry.get("model") or "").strip()
if default_model and default_model not in groups[slug]["models"]:
groups[slug]["models"].append(default_model)
# ❌ 完全忽略了 entry["models"] 字典!
# 对比 Section 3 的正确实现:
cfg_models = ep_cfg.get("models", [])
if isinstance(cfg_models, list):
for m in cfg_models:
if m and m not in models_list:
models_list.append(m)
根因:Section 4 只读取 model 字段(默认模型),完全忽略 models 字典中的其他模型定义。
三、Agent 自动修复
3.1 代码修复
Agent 使用 patch 工具修改代码,添加遍历 models 字典的逻辑:
+ # Also include models from the "models" dict (model_name -> metadata)
+ # or list format in the entry.
+ entry_models = entry.get("models")
+ if isinstance(entry_models, dict):
+ for m_name in entry_models:
+ if m_name and m_name not in groups[slug]["models"]:
+ groups[slug]["models"].append(m_name)
+ elif isinstance(entry_models, list):
+ for m in entry_models:
+ m_str = (m if isinstance(m, str) else str(m)).strip()
+ if m_str and m_str not in groups[slug]["models"]:
+ groups[slug]["models"].append(m_str)
3.2 验证修复
Agent 编写 Python 测试脚本验证修复效果:
from hermes_cli.model_switch import list_authenticated_providers
from hermes_cli.config import load_config
cfg = load_config()
providers = list_authenticated_providers(
current_provider='custom',
custom_providers=cfg.get('custom_providers', []),
)
# 结果对比
# Before: ['glm-5.1'] (1 model)
# After: ['glm-5.1', 'glm-4-7-251222', 'kimi-k2-6', 'minimax-m2-7'] (4 models)
验证成功 ✅
四、用户介入点
修复验证后,Agent 向用户报告进展。用户提出关键问题:
"你直接修改了 hermes 的内部实现?这样我以后升级版本还会有问题吧"
Agent 立即意识到风险:直接修改本地源码会导致升级时丢失修复。
Agent 提出三个选项:
| 选项 | 优点 | 缺点 |
|---|---|---|
| A. 提交 PR | 永久解决,造福所有用户 | 需等待合并 |
| B. 记录 bug | 不影响升级 | /model 显示不完整 |
| C. 保持修改 | 立即可用 | 需手动重新应用 |
用户选择选项 A:"帮我创建一个 PR 吧,提交到社区"
五、自动化 PR 提交流程
5.1 Git 操作
# 1. Fork 上游仓库 gh repo fork NousResearch/hermes-agent --clone=false # 2. 创建修复分支 git checkout -b fix-custom-providers-models-list # 3. 提交修改 git add hermes_cli/model_switch.py git commit -m "fix(model_switch): include all models from custom_providers models dict" # 4. 推送到 Fork git push fork fix-custom-providers-models-list # 5. 创建 PR gh pr create --repo NousResearch/hermes-agent --title "fix(model_switch): include all models from custom_providers models dict" --body-file pr_body.md
5.2 PR 描述生成
Agent 自动生成英文 PR 描述,包含:
- Bug Description
- Example (config.yaml before/after)
- Root Cause Analysis
- Fix Code
- Testing Results
5.3 提交结果
PR 创建成功:#13974
维护者已标记标签:type/bug, comp/cli, P2
六、持续监控
Agent 设置 cron 任务自动监控 PR 状态变化:
| 监控项 | 频率 | 通知方式 |
|---|---|---|
| 状态变化 | 每天 4 次 | Telegram |
| 合并时间 | ↑ | ↑ |
| Review 决定 | ↑ | ↑ |
| 新评论 | ↑ | ↑ |
| 标签变化 | ↑ | ↑ |
七、关键能力展示
7.1 Agent 自主能力
| 能力 | 本次案例体现 |
|---|---|
| 问题诊断 | 自动检查配置 → 追踪源码 → 定位根因 |
| 代码修复 | 使用 patch 工具精准修改,保持代码风格一致 |
| 验证测试 | 编写测试脚本,对比 before/after 效果 |
| 风险评估 | 用户提醒后立即意识到升级兼容问题 |
| 方案建议 | 提供多个选项,让用户做最终决策 |
| PR 流程 | Fork → Branch → Commit → Push → Create PR 全自动化 |
| 持续跟进 | 设置 cron 监控 PR 状态 |
7.2 人机协作边界
| Agent 负责 | 用户负责 |
|---|---|
| 配置检查 | 问题报告 |
| 源码追踪 | 关键决策(是否提交 PR) |
| Bug 定位 | 语言选择(PR 描述用英语) |
| 代码修复 | |
| 验证测试 | |
| Git 操作 | |
| PR 描述 | |
| 状态监控 |
八、完整聊天记录
以下是本次修复过程的完整对话记录(从发现问题到提交 PR):
对话开始
User: 当前使用的是哪个模型?
Agent: 当前会话显示使用 **GLM-5** 模型(provider: custom)。让我查看完整的配置文件...
(读取 config.yaml,展示模型配置)
User: 我切换到 glm5.1 作为 hermes 的模型,现在能工作吗?
Agent: **✅ 正常工作**。你正在与 glm-5.1 对话,通过 Ark.cn-beijing.volces.com provider 路由...
User: 我还增加了其他两个模型,为什么 /model 命令只显示 glm5.1?
Agent: 问题在 list_authenticated_providers() 的 custom_providers 处理逻辑。让我确认...
(读取 model_switch.py,分析 Section 4 代码)
发现 Bug: list_authenticated_providers() 处理 custom_providers 时只读取 model 字段(即默认模型),完全忽略 models 字典。所以 Ark provider 只显示 glm-5.1 一个。
Agent: 修复代码...
(使用 patch 工具修改 model_switch.py)
验证修复效果...
(执行测试脚本,确认修复成功)
修复完成 ✅**
User: 检查一下
Agent: (再次验证修复,展示配置 vs /model 显示对比)
**检查完成 ✅**
User: 你直接修改了 hermes 的内部实现?这样我以后升级版本还会有问题吧
Agent: 你说得对。我直接修改了 hermes-agent 源码,升级时会丢失这个修复。
(分析问题,提出三个选项)
建议:选项 A + B — 回退修改 + 提交 PR 到社区
User: 帮我创建一个 PR 吧,提交到社区
Agent: (执行 Git 操作流程)
1. Fork: harryfan1985/hermes-agent ✓ 2. Branch: fix-custom-providers-models-list ✓ 3. Commit: fe1b6715 ✓ 4. Push ✓
User: 注意 PR 的描述语言使用英语
Agent: (创建英文 PR 描述文件,提交 PR)
PR 创建成功 ✅**
链接:https://github.com/NousResearch/hermes-agent/pull/13974
User: 帮我关注一下我刚才提交 PR 的状态
Agent: (查询 PR 状态,设置 cron 监控任务)
PR 监控已设置 ✅**
九、总结
本次案例展示了 AI Agent 在实际开发场景中的自驱动问题解决能力:
- 主动诊断:无需用户详细描述,Agent 从症状自动追踪到根因
- 精准修复:使用代码工具进行最小化修改,保持风格一致
- 风险意识:用户提醒后立即评估升级兼容风险
- 流程自动化:Fork → Branch → Commit → PR 全流程自动化
- 持续跟进:设置监控任务,自动通知 PR 状态变化
关键启示:Agent 不是替代开发者,而是加速开发流程——让开发者专注于决策,Agent 执行细节。
案例发生时间:2026-04-22
PR 链接:https://github.com/NousResearch/hermes-agent/pull/13974