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

April 22, 2026

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 在实际开发场景中的自驱动问题解决能力

  1. 主动诊断:无需用户详细描述,Agent 从症状自动追踪到根因
  2. 精准修复:使用代码工具进行最小化修改,保持风格一致
  3. 风险意识:用户提醒后立即评估升级兼容风险
  4. 流程自动化:Fork → Branch → Commit → PR 全流程自动化
  5. 持续跟进:设置监控任务,自动通知 PR 状态变化

关键启示:Agent 不是替代开发者,而是加速开发流程——让开发者专注于决策,Agent 执行细节。


案例发生时间:2026-04-22

PR 链接:https://github.com/NousResearch/hermes-agent/pull/13974