【Hermes:Skill系统深度】21、Skill 调试与冲突解决:为什么没触发?怎么修复? —— Honcho 智能体排障完全手册

Skill 调试与冲突解决:为什么没触发?怎么修复? ------ Honcho 智能体排障完全手册

你精心编写的 Skill 怎么就是不触发?明明关键词匹配了,日志却一片空白?多个 Skill 互相"打架"谁都不干活?本文将带你系统掌握 Honcho Skill 的调试方法,从日志定位到冲突解决,手把手修复所有"不听话"的 Skill。

前言:Skill 是智能体的"肌肉记忆",但也会"抽筋"

在 Honcho 生态中,Skill(技能)是用户自定义的工作流------它告诉智能体:当满足某个条件时,执行一系列工具调用。Skill 让智能体从"每件事都要手动指挥"升级为"自动响应特定场景"。

但 Skill 并非永远可靠。你可能遇到过:

  • 输入了触发词,Skill 毫无反应
  • 明明只有一个 Skill 符合条件,却执行了另一个
  • Skill 执行到一半报错,不知道哪一步出了问题
  • 想修改 Skill 规则,却找不到在哪里编辑

这些问题本质上都是 Skill 调试与冲突 的范畴。本文将按照从易到难的顺序,带你掌握完整的排障流程。

全文包含 5 张 mermaid 流程图大量实战案例,确保你能够快速定位并修复任何 Skill 问题。


1. 查看已加载 Skill:指令查询

1.1 为什么需要查看?

在调试之前,首先要确认:你的 Skill 到底有没有被 Honcho 成功加载? 很多"不触发"问题,根源就是 Skill 根本没加载上。

1.2 查看方法

方法一:通过对话指令查询

如果你已经接入了 Telegram、Slack 或国内办公平台,可以直接向智能体发送查询命令:

复制代码
/list_skills

或者

复制代码
/技能列表

Honcho 会返回当前已加载的所有 Skill 名称、描述和触发条件(摘要)。示例输出:

复制代码
已加载 3 个 Skill:
1. weather_skill - 触发词:天气、气温、下雨
2. code_review - 触发词:review、检查代码、帮我看看这段代码
3. daily_report - 触发词:日报、今日总结
方法二:通过 API 查询

使用 curl 调用 Honcho 的 API:

bash 复制代码
curl -X GET "http://localhost:8080/v1/skills" \
  -H "Authorization: Bearer your_api_key"

返回 JSON 格式的 Skill 列表,包含每个 Skill 的完整定义。

方法三:直接查看文件系统

Skill 文件通常存储在 ~/.hermes/data/skills/ 目录下(取决于你的挂载配置)。每个 Skill 是一个 .yaml.json 文件:

bash 复制代码
ls -la ~/.hermes/data/skills/

你会看到类似:

复制代码
weather_skill.yaml
code_review.yaml
daily_report.yaml

1.3 确认 Skill 状态

如果查询结果中没有你的 Skill,说明加载失败。可能原因:

  • 文件格式错误(YAML 语法问题)
  • 文件放在错误的目录
  • 文件名不符合命名规范
  • Honcho 启动时未扫描该目录





用户发送 /list_skills
Honcho 处理
读取 skills 目录
Skill 文件存在?
解析每个 Skill
格式正确?
返回 Skill 列表
记录错误日志,跳过
返回空列表
用户看不到该 Skill


2. 日志定位:~/.hermes/logs

2.1 日志文件位置

Honcho 的日志默认输出到挂载的 logs 目录(参考第 11 篇 Docker 部署),通常是:

复制代码
~/.hermes/logs/hermes.log

如果使用 Docker 且未挂载日志目录,可以用 docker logs hermes 查看。

2.2 日志级别设置

config.yaml 中可以调整日志级别,调试时建议设为 debug

yaml 复制代码
logging:
  level: debug   # 可选: debug, info, warning, error
  output: /app/logs/hermes.log

重启 Honcho 后生效。

2.3 关键日志条目

当用户发送一条消息时,Honcho 会记录以下关键步骤:

日志内容示例 含义
DEBUG: Received message: "今天天气怎么样" 收到用户消息
DEBUG: Checking skills for message: "今天天气怎么样" 开始匹配 Skill
DEBUG: Skill 'weather_skill' trigger regex matched: '天气' 某个 Skill 正则匹配成功
DEBUG: Executing skill 'weather_skill' 开始执行 Skill
ERROR: Tool 'web_get' failed: timeout 工具调用失败
WARNING: Skill 'weather_skill' skipped due to missing param 参数缺失,Skill 被跳过

2.4 快速定位技巧

bash 复制代码
# 实时查看日志
tail -f ~/.hermes/logs/hermes.log

# 过滤出 Skill 相关日志
grep -i skill ~/.hermes/logs/hermes.log

# 查看最近 100 行错误
tail -100 ~/.hermes/logs/hermes.log | grep -i error

# 查看特定时间段的日志(需要日志带时间戳)
grep "2026-04-22 14:" ~/.hermes/logs/hermes.log

2.5 日志分析流程图

无匹配
有匹配
成功
失败
收到用户消息
日志: Received message
Skill 匹配阶段
日志: No skill matched
走默认 LLM 回复
日志: Skill X triggered
执行阶段
日志: Skill completed
日志: Error detail
分析错误类型


3. 触发失败常见原因

3.1 触发词/正则表达式问题

这是最常见的原因。Skill 的触发条件通常是一个正则表达式,用户消息必须匹配才能触发。

错误示例

yaml 复制代码
trigger: "天气"   # 只匹配完全等于"天气"的消息,不匹配"今天天气"

正确示例

yaml 复制代码
trigger: ".*天气.*"   # 匹配任何包含"天气"的消息

其他常见问题

  • 正则表达式写错(如未转义特殊字符)
  • 大小写敏感(. 不匹配换行符)
  • 中文标点与英文标点混用

3.2 Skill 被禁用

检查 Skill 定义中是否有 enabled: false 字段:

yaml 复制代码
name: weather_skill
enabled: false   # 这会导致 Skill 被忽略
trigger: "天气"

3.3 优先级被抢占

如果多个 Skill 的触发条件都匹配,Honcho 会根据优先级选择一个执行。如果优先级设置不当,你期望的 Skill 可能被另一个 Skill 抢走。

查看优先级

yaml 复制代码
name: weather_skill
priority: 10    # 数字越大优先级越高,默认 0

3.4 参数缺失或类型错误

Skill 可能需要从消息中提取参数(如城市名)。如果提取失败,Skill 可能被跳过。

yaml 复制代码
params:
  - name: city
    source: regex   # 从消息中提取
    pattern: "在(.*)的天气"

如果用户说"今天天气怎么样",没有匹配到"在X的天气",参数 city 提取失败,Skill 就不会执行。

3.5 工具调用失败

Skill 内部调用的工具(如 web_get, terminal)可能因为网络、权限等原因失败。这时 Skill 会中断,用户看不到完整回复。

3.6 上下文长度超限

Skill 执行过程中产生的中间结果过大,超出 LLM 上下文限制。这通常表现为"部分输出丢失"。

3.7 触发失败原因速查表

现象 可能原因 日志关键词
输入触发词,完全无反应 正则不匹配 / Skill 未加载 No skill matched
有时触发,有时不触发 正则边界问题 / 优先级冲突 Multiple skills matched
触发后报错"missing parameter" 参数提取失败 param .* not found
触发后报错"tool execution failed" 工具调用异常 Tool .* failed
触发后只输出了一部分内容 上下文超限 / 工具超时 token limit, timeout

4. 多 Skill 冲突处理

4.1 冲突场景

当多个 Skill 的触发条件同时满足时,Honcho 需要决定执行哪一个。这称为 Skill 冲突

典型冲突案例

  • Skill A:触发词 .*日报.*(任何包含"日报"的消息)
  • Skill B:触发词 .*提交日报.*(提交日报的特定场景)

用户说"帮我提交日报",两个 Skill 都匹配。如果优先级相同,Honcho 会选择最先匹配到的(顺序不确定),可能导致执行错误。

4.2 解决方案

方案一:调整优先级

将更具体的 Skill 设置更高优先级:

yaml 复制代码
# Skill B (更具体)
name: submit_daily_report
priority: 20
trigger: ".*提交日报.*"

# Skill A (更宽泛)
name: general_daily_report
priority: 10
trigger: ".*日报.*"

这样"提交日报"会优先匹配 Skill B。

方案二:使用互斥规则

在 Skill 定义中添加 exclusive 字段,表示当此 Skill 匹配时,不再检查其他 Skill:

yaml 复制代码
name: submit_daily_report
exclusive: true   # 匹配后停止继续匹配
方案三:合并 Skill

如果两个 Skill 逻辑相似,可以合并为一个,通过条件分支处理:

yaml 复制代码
name: daily_report_handler
trigger: ".*日报.*"
steps:
  - condition: "contains(user_message, '提交')"
    then: submit_report
  - else: general_report

4.3 冲突检测流程图

只有一个
多个
有最高优先级
优先级相同
用户消息
遍历所有启用的 Skill
收集所有匹配的 Skill
执行该 Skill
比较优先级
执行最高优先级
日志记录冲突
选择第一个匹配的

按加载顺序

4.4 查看冲突日志

当发生冲突时,debug 日志会记录:

复制代码
DEBUG: Multiple skills matched: ['skill_a', 'skill_b']
DEBUG: Selected skill 'skill_b' due to higher priority (15 > 10)

如果优先级相同:

复制代码
DEBUG: Multiple skills with same priority, selecting first: 'skill_a'

5. 手动编辑、禁用、删除 Skill

5.1 编辑 Skill

Skill 文件存储在 ~/.hermes/data/skills/ 目录下。直接编辑对应的 YAML 文件即可。

示例 Skill 文件weather_skill.yaml):

yaml 复制代码
name: weather_skill
description: "查询天气"
enabled: true
priority: 5
trigger: ".*天气.*"
params:
  - name: city
    source: regex
    pattern: "在?([^的]+)的天气"
steps:
  - tool: web_get
    params:
      url: "https://api.weather.com/{{city}}"
    output: weather_data
  - tool: llm_generate
    params:
      prompt: "根据天气数据{{weather_data}}生成友好回复"
    output: final_reply
  - tool: reply
    params:
      message: "{{final_reply}}"

编辑后如何生效?

  • 如果 Honcho 支持热加载(watch_skills: true),保存文件后自动生效。
  • 否则需要重启 Honcho:docker restart hermes

5.2 禁用 Skill

两种方式:

  1. 在 Skill 文件中设置 enabled: false,保存后(或重启)生效。
  2. 通过命令动态禁用(如果支持):/disable_skill weather_skill

5.3 删除 Skill

直接删除对应的 YAML 文件,然后重启 Honcho(或等待热加载)。

bash 复制代码
rm ~/.hermes/data/skills/weather_skill.yaml

5.4 批量管理

如果你有大量 Skill,可以使用脚本批量操作。以下是一个简单的 Python 脚本示例:

python 复制代码
import os
import yaml

skills_dir = os.path.expanduser("~/.hermes/data/skills/")

for filename in os.listdir(skills_dir):
    if not filename.endswith(".yaml"):
        continue
    path = os.path.join(skills_dir, filename)
    with open(path, 'r') as f:
        skill = yaml.safe_load(f)
    print(f"{filename}: enabled={skill.get('enabled', True)}")

6. 调试流程:一步一步定位

6.1 标准调试流程

当你的 Skill 不工作时,按照以下步骤操作:

第一步:确认 Skill 已加载

  • 发送 /list_skills 或在日志中搜索 Loading skill
  • 如果没加载,检查文件格式和存放路径

第二步:开启 Debug 日志

  • 设置 logging.level: debug,重启 Honcho

第三步:发送测试消息,实时观察日志

bash 复制代码
tail -f ~/.hermes/logs/hermes.log

第四步:根据日志定位问题阶段










发送测试消息
日志中出现

'Received message'?
消息未到达 Honcho

检查网关配置
日志中出现

'Checking skills'?
Skill 匹配模块未运行

检查配置
日志中出现

'Skill X triggered'?
触发条件不匹配

检查正则/大小写
日志中出现

'Executing skill'?
Skill 被禁用或优先级问题
日志中出现错误?
根据错误类型修复
Skill 执行成功但无输出

检查回复步骤

6.2 调试案例

案例 :用户说"北京天气",但 weather_skill 没触发。

步骤

  1. /list_skills → 确认 weather_skill 在列表中 ✅

  2. 开启 debug 日志,再次发送"北京天气"

  3. 查看日志:

    DEBUG: Received message: "北京天气"
    DEBUG: Checking skills...
    DEBUG: Skill 'weather_skill' trigger regex '.天气.' matched: True
    DEBUG: Extracting param 'city' with pattern '在?([^的]+)的天气'
    DEBUG: Param 'city' extraction failed, skipping skill

  4. 问题定位:参数提取正则不匹配"北京天气"。用户没有说"在北京的天气"。

  5. 修复:修改正则或让 city 参数可选。

6.3 调试工具箱

工具/命令 用途
/list_skills 查看已加载 Skill
/enable_skill <name> 启用 Skill(如果支持)
/disable_skill <name> 禁用 Skill
tail -f ~/.hermes/logs/hermes.log 实时查看日志
grep -i skill logs 过滤 Skill 相关日志
curl -X GET /v1/skills API 获取 Skill 列表

7. 常见错误模板与修复

7.1 YAML 语法错误

错误现象 :Skill 文件无法加载,日志显示 YAML parsing error

常见错误

yaml 复制代码
steps:
  - tool: web_get
    params:
      url: "https://example.com"   # 这里少了一个空格?缩进不对

修复 :使用 YAML 校验工具(如 yamllint)检查。

7.2 正则表达式错误

错误trigger: "天气?" → 问号是量词,匹配"天"或"天气",但可能误匹配。

修复 :使用明确的正则:trigger: ".*天气.*"

7.3 工具参数引用错误

错误

yaml 复制代码
steps:
  - tool: web_get
    params:
      url: "https://api.com/{{city_name}}"   # city_name 未定义

修复 :确保变量名与 params 中定义的名称一致。

7.4 循环引用

两个 Skill 互相调用导致无限循环。Honcho 有最大步数限制(默认 10 步),超限会中断。

修复 :检查 Skill 的 steps 中是否调用了另一个 Skill,而另一个 Skill 又调回了它。

7.5 工具超时

错误日志Tool 'web_get' timeout after 30s

修复

  • 增加超时时间:timeout: 60
  • 或优化工具调用(如使用更快的 API)

7.6 参数类型不匹配

错误:工具期望整数,但传入了字符串。

修复:在 Skill 中添加类型转换步骤,或使用模板过滤器。

7.7 常见错误速查表

错误日志关键词 可能原因 修复方法
YAML parsing error 语法错误 检查缩进、冒号、引号
Skill not found 文件名与 name 不一致 确保文件名与 Skill 的 name 字段一致
param .* not found 参数提取失败 调整正则或设置默认值
tool .* not registered 工具名称错误 检查工具名拼写,确认工具已启用
max steps exceeded 循环或过长链式调用 增加 max_steps 或简化逻辑
timeout 工具执行超时 增加超时时间或优化调用
permission denied 工具权限不足 检查 config.yaml 中的工具白名单

8. 总结:快速排障指南

8.1 核心原则

  1. 日志是上帝:95% 的问题都能从 debug 日志中找到线索。
  2. 先确认加载,再检查触发:Skill 没加载,一切都是白搭。
  3. 正则要宽松,但不要过宽.* 能匹配大部分,但可能与其他 Skill 冲突。
  4. 优先级解决冲突:具体场景用高优先级,通用场景用低优先级。
  5. 小步迭代:每次修改一个 Skill 后立即测试,不要积攒多个改动。

8.2 快速排障流程图











Skill 不触发
/list_skills 能看到?
检查文件路径/格式

重启 Honcho
Debug 日志有匹配记录?
检查 trigger 正则

注意大小写/中文标点
日志显示参数提取成功?
检查 params 中的正则

设置默认值
日志显示工具调用成功?
检查工具名称/网络/权限
最终有回复吗?
检查 reply 步骤

确认输出变量
问题解决

8.3 最佳实践建议

  1. 为 Skill 添加 description:帮助自己和其他开发者理解用途。
  2. 使用明确的优先级:避免依赖默认的加载顺序。
  3. 记录版本 :在 Skill 文件中添加 version 字段,方便回滚。
  4. 单元测试:编写简单的测试消息集,每次修改后批量验证。
  5. 定期清理:删除不再使用的 Skill,减少冲突可能。

8.4 Skill 模板示例(含调试友好字段)

yaml 复制代码
name: example_skill
version: "1.0"
description: "这是一个示例 Skill"
enabled: true
priority: 10
trigger: ".*示例.*"
params:
  - name: keyword
    source: regex
    pattern: "示例(.*)"
    default: "默认值"      # 设置默认值,避免提取失败
steps:
  - tool: log
    params:
      message: "开始执行 example_skill,keyword={{keyword}}"
  - tool: llm_generate
    params:
      prompt: "用户提到了{{keyword}},请友好回应"
    output: reply_text
  - tool: reply
    params:
      message: "{{reply_text}}"
timeout: 30
max_steps: 10

8.5 一句话总结

Skill 不触发时,遵循"加载→匹配→参数→工具→回复"的五步调试法,配合 debug 日志,90% 的问题可以在 10 分钟内定位并修复。

下一步:掌握了调试技巧后,你可以尝试编写更复杂的 Skill------比如多步骤条件分支、循环调用、用户确认交互等。调试能力越强,你能实现的自动化场景就越丰富。


附录:常用正则表达式参考

需求 正则示例
包含关键词 .*天气.*
以关键词开头 ^天气.*
以关键词结尾 .*天气$
提取城市名(中文) 在?(.*?)的天气
提取数字 \d+
匹配多种说法 `(天气
忽略大小写 (?i)weather
匹配任意字符(包括换行) [\s\S]*

版权声明:本文为原创技术博客,采用 CC BY-NC-SA 4.0 许可。欢迎转载,请保留出处。如有 Skill 调试问题,欢迎评论区交流。

相关推荐
袖手蹲1 小时前
把 Claude 的愚人节彩蛋跑在 行空板K10上:BLE 应用与 ASCII 宠物动画实战
人工智能·自动化·宠物
春风有信1 小时前
【DM】DDPM与DDIM的数学原理
人工智能·深度学习·机器学习
ShareCreators1 小时前
洞见 | 数字化
人工智能·汽车·blueberry
财迅通Ai1 小时前
百通能源:2026年一季度营收稳步增长,资产结构持续优化
大数据·人工智能·能源·百通能源
风落无尘1 小时前
第二章《概率与生存》完整学习资料
人工智能·矩阵·概率论
迪娜学姐1 小时前
ChatGPT image 2 科研绘图实测分享
人工智能·chatgpt
千匠网络1 小时前
数智全链赋能,千匠网络钢铁能源供应链平台解决方案
大数据·人工智能
小超同学你好1 小时前
论文精读:《Indirect Prompt Injection》—— 当AI助手成为别人的“提线木偶“
人工智能·prompt
wuxinyan1231 小时前
大模型学习之路03:提示工程从入门到精通(第三篇)
人工智能·python·学习