Operational Steps
- 确认输入参数完整
- 执行核心操作(参考本目录下的 scripts/ 或 references/)
- 验证输出符合契约
- 保存结果并报告
Pitfalls
-
-
Verification
-
-
-
-
1. 2. 3.
IO_CONTRACT
- input:
error_msg: str, session_id: str, platform: str— 用户报告的错误、会话ID、平台 - output:
diagnosis: str— 问题根因 + 修复建议
触发条件
用户报告飞书消息无响应 / 报错 / API call failed / 404 / 发送失败。
诊断流程
Step 1: 区分错误来源
关键认知:Gateway 处理两种独立 session:
- CLI 会话:
agent:main:cli:xxx— 直接通过hermes命令行启动 - 飞书会话:
agent:main:feishu:dm:<chat_id>— 通过飞书 WebSocket 接收
两种 session 完全隔离,CLI 报错不影响飞书,反之亦然。
错误来源判断:
api call failed + 模型名 + base_url=http://X.X.X.X:8000 → vLLM 节点问题,非飞书
api call failed + open.feishu.cn → 飞书 API 网络问题
api call failed + api.deepseek.com → DeepSeek API 问题
Step 2: 追踪完整消息流
按时间顺序检查以下三处日志:
1. Gateway 日志(入口→出口):
tail -50 ~/.hermes/logs/gateway.log | grep -E "2026-06-20 21:2[5-9]|21:3"
关键行:
Received raw message— 飞书收到消息Inbound dm message received— 消息解析完成Flushing text batch agent:main:feishu:dm:...— 提交 agent 会话inbound message: platform=feishu— Gateway 确认收到response ready: platform=feishu time=X.Xs api_calls=N— 响应生成Sending response (X chars) to <chat_id>— 推送飞书
一条成功消息的完整时间线:
21:25:25 Received raw message → 飞书收到
21:25:32 Flushing text batch → 提交 agent (7s)
21:25:37 inbound message → 确认 (5s)
21:25:38 response ready time=1.2s → 模型响应 (0.6s)
21:25:39 Sending response → 推送飞书 (0.1s)
总耗时: ~14s (含网络延迟和模型推理)
2. Agent 日志(模型调用细节):
grep "<session_id>" ~/.hermes/logs/agent.log | grep "2026-06-20 <time>"
关键行:
conversation turn: session=<id> model=<model> provider=<provider> platform=feishu— 会话开始API call #N: model=<model> provider=<provider> in=<tokens> out=<tokens> latency=<X>s— 模型调用Turn ended: reason=text_response(finish_reason=stop)— 成功结束API call failed (attempt N/3)— 失败重试Non-retryable client error— 不可恢复错误
3. Errors 日志(所有警告/错误汇总):
tail -30 ~/.hermes/logs/errors.log
Step 3: 常见错误根因
vLLM 404 (最常见)
HTTP 404: Not found
provider=custom base_url=http://[T1_NODE_IP_1]:8000/v1 model=qwen3.6-35b-nvfp4
- 模型在该节点不存在(已删除/改名)
- 检查节点:
curl -s http://<ip>:8000/v1/models - 修复:从轮询配置移除该节点或修正模型名
DeepSeek 401
HTTP 401: Authentication Fails / Invalid API key
provider=deepseek base_url=https://api.deepseek.com/v1
- API Key 过期或错误
- 检查
.env中DEEPSEEK_API_KEY
网络问题
NameResolutionError: Failed to resolve 'open.feishu.cn'
HTTPSConnectionPool(host='open.feishu.cn', port=443): Max retries exceeded
- DNS 解析失败
- 检查 Tailscale / 网络路由
- 验证:
curl -s -o /dev/null -w "%{http_code}" https://open.feishu.cn
Stream 断开
RemoteProtocolError: peer closed connection without sending complete message body
http_status=200 bytes=0 chunks=0 elapsed=180.07s
- vLLM 服务超时(默认 180s)
- 模型响应过长或节点负载高
execute_code 超时
Script timed out after 300s and was killed
- 代码执行超时(默认 300s)
- 检查是否有阻塞操作
Step 4: 报告成功消息的典型响应
成功处理飞书消息时,响应通常是简洁的(50-182 chars),如:
- "Hello, I'm here. How can I help you today?"
- "Hello, what's up?"
如果用户报告的 "api call failed" 不是来自日志,请确认:
- 是在 CLI 还是飞书看到的?
- 是哪条消息报的错?
- 错误是立即出现还是延迟后出现?
排障清单
- Gateway 是否在运行?
ps aux | grep hermes-gateway - WebSocket 是否连接?
tail ~/.hermes/logs/gateway.log | grep "connected" - 飞书消息是否到达 Gateway?
tail ~/.hermes/logs/gateway.log | grep "Received raw message" - 是否提交到 agent session?
tail ~/.hermes/logs/gateway.log | grep "Flushing text batch" - Agent session 是否创建/恢复?
grep "conversation turn" ~/.hermes/logs/agent.log | tail - 模型调用是否成功?
grep "API call" ~/.hermes/logs/agent.log | tail - 响应是否返回 Gateway?
grep "response ready" ~/.hermes/logs/gateway.log | tail - 响应是否发送到飞书?
grep "Sending response" ~/.hermes/logs/gateway.log | tail
关键发现(2026-06-20)
- Gateway 日志是最高优先级:Gateway 完整记录了消息从接收→处理→回复的全链路,且只记录成功消息。失败会被捕获在 errors.log。
- 404 多数来自 vLLM 而非飞书:用户报告的 "404" 多数是模型节点返回的,不是飞书 API。需先检查
base_url指向哪个服务。 - CLI 和飞书 session 隔离:CLI 的
execute_code超时不会阻塞飞书会话。两个平台各自维护独立 session。
验证清单 · VERIFICATION
- 已识别错误来源的
base_url,区分 vLLM 节点 / DeepSeek API / 飞书 API,未将 404 误判为飞书问题(FEIS-001) - 已按时间顺序追踪 Gateway 日志全链路(Received raw → Flushing text batch → response ready → Sending response),定位具体断点(FEIS-002)
- vLLM 404 时已
curl /v1/models验证模型是否存在于该节点,并修正节点或模型名(FEIS-003) - 飞书 MEDIA 附件未收到时已检查文件 ≤10MB,超限用 Ghostscript 压缩后重发(FEIS-004)
- 发送文件前已
ls -la <路径>验证文件真实存在,未使用 /tmp/ 等不稳定路径(FEIS-005) - 已确认 session 前缀(
cli:vsfeishu:),排除 CLI 与飞书 session 隔离带来的跨平台干扰(FEIS-006) - Stream 断开/180s 超时时已判定为 vLLM 节点超时或负载过高,并检查节点状态(FEIS-007)
- 诊断结论可追溯至具体日志行(Gateway/agent/errors),未编造数据
核心原则 · PRINCIPLES
- 准确为先: 所有输出必须经过事实核查,不编造数据
- 证据驱动: 每个结论必须可追溯到具体证据或数据源
- 可复现性: 每一步操作必须可重复,结果可验证
Golden 集合 · GOLDEN SET
- Golden Input: 用户报告飞书消息无响应,提供 session_id=
agent:main:feishu:dm:<chat_id>、错误文本API call failed (404 Not Found)(FEIS-001/002) - Golden Output: 诊断指向 vLLM 节点(
base_url=http://<ip>:8000,非飞书),gateway.log 出现完整时间线 Received raw → Flushing text batch → response ready → Sending response,curl -s http://<ip>:8000/v1/models确认模型存在后重发成功(FEIS-002/003) - Golden Error:
RemoteProtocolError: peer closed connection without sending complete message body(http_status=200 bytes=0 elapsed=180.07s)→ 判定为 vLLM 180s 超时/负载过高(FEIS-007);或 MEDIA 附件 33MB>10MB 静默失败 → gs/screen压缩至 2.4MB 后重发成功(FEIS-004)
Golden 集合是测试的单一真理来源。所有改进必须通过 golden 测试。
违反任何原则的输出视为失败。原则优先级:准确 > 证据 > 可复现。
每项验证必须可执行、可记录、可复现。验证失败时记录原因和修复。
MEDIA 文件附件发送(Feishu 交付模式)
完整的 MD→PDF→Feishu 管线见 references/pdf-delivery-pipeline.md。
发送格式
在响应文本中直接包含 MEDIA:/absolute/path/to/file,运行时自动上传为附件。每行一个文件。
铁律
- 路径验证优先:发送前务必
ls -la /path/to/file确认文件真实存在。路径错误=静默失败。 - 避开 /tmp/:Hermes MEDIA 处理器可能无法访问 /tmp/ 目录。文件放 ~/ 或 /media/ 等稳定路径。
- 先回应再发:用户下达命令后,先回复「收到」确认,再执行操作。不无声执行。
- 复用成功案例:同类型任务(如发送PDF)的交付模式与之前成功案例一致的,直接照搬,不猜新花样。失败排查路径:用 search_files 查正确路径→确认文件存在→用已验证路径重发。
文件大小限制
飞书 MEDIA 附件 >10MB 会静默失败(不显示附件、不报错)。PPTX 转 PDF 后通常 30-80MB,必须压缩。
压缩流程(Ghostscript):
gs -sDEVICE=pdfwrite -dCompatibilityLevel=1.4 -dPDFSETTINGS=/screen -dNOPAUSE -dQUIET -dBATCH -sOutputFile=/path/to/output.pdf /path/to/input.pdf
典型效果:33MB → 2.4MB(screen 质量对文档可读性足够,图片/扫描件可能偏模糊)。
其他 PDFSETTINGS 级别:
/screen— 72dpi,最小文件(适合文档)/ebook— 150dpi,平衡质量/prepress— 300dpi,最大文件
排查流程
用户反馈没收到附件时:
ls -la <路径>确认文件存在- 检查文件大小 — 超过 10MB → 用 gs 压缩
- 压缩后确认新文件 ≤10MB
- 用新路径重新发送
- 若不存在 →
search_files(pattern='*文件名*', target='files')找正确路径 - 修正路径后重发
Feishu Gateway Debug---
Genes (策略基因)
紧凑策略表示。条件→策略。需要深度时参考完整文档。
- [FEIS-001] 用户报告 API 调用失败或 404 错误 → 优先检查
base_url指向的服务(vLLM/DeepSeek/飞书),区分是模型节点问题还是飞书网关问题 - [FEIS-002] 诊断消息流中断或无响应 → 按时间顺序追踪 Gateway 日志(接收→解析→提交→响应→发送)以定位具体断点
- [FEIS-003] 遇到 vLLM 节点返回 404 Not Found → 验证模型是否存在于该节点(
curl /v1/models),若不存在则移除节点或修正模型名 - [FEIS-004] 飞书 MEDIA 附件发送后用户未收到且无报错 → 检查文件大小是否超过 10MB,若超限则使用 Ghostscript 压缩至 10MB 以下后重发
- [FEIS-005] 发送文件附件前 → 必须执行
ls -la验证文件路径真实存在,避免路径错误导致静默失败 - [FEIS-006] 处理 CLI 与飞书平台的并发问题 → 识别 session ID 前缀(
cli:vsfeishu:),利用两者完全隔离的特性排除跨平台干扰 - [FEIS-007] 遇到 Stream 断开或 180s 超时错误 → 判定为 vLLM 服务超时或负载过高,需检查节点状态或调整超时配置
示例 · EXAMPLES
- 用户报告飞书消息 "API call failed (404 Not Found)" → 按 FEIS-001 检查 agent.log 中的
base_url:指向http://<node_ip>:8000即 vLLM 节点 404(非飞书);curl -s http://<ip>:8000/v1/models确认模型名存在(FEIS-003),不存在则从轮询配置移除该节点或修正模型名 → 验证:重发消息后 gateway.log 出现response ready+Sending response,错误不再复现。 - 用户反馈"发 PDF 后没收到附件、无报错" → 按 FEIS-005 先
ls -la确认文件存在且路径不在 /tmp/;发现 33MB 超限(FEIS-004),用 Ghostscript/screen压缩至 2.4MB 后以MEDIA:<稳定路径>重发 → 验证:附件在飞书正常显示且 ≤10MB,排障清单第 1-8 项全部通过。 - CLI 会话 execute_code 超时(300s)后,用户问飞书会话为何"卡住" → 按 FEIS-006 检查 session 前缀
cli:vsfeishu:dm:<chat_id>,确认两平台 session 完全隔离 → 验证:gateway.log 中agent:main:feishu:dm:*的消息时间线(Received raw → Flushing text batch → response ready → Sending response)完整无断点,CLI 超时未影响飞书会话。