<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
	<channel>
		<title>调试 on 魔都水滴</title>
		<link>https://blog.margrop.net/tag/%E8%B0%83%E8%AF%95/</link>
		<description>Recent content in 调试 on 魔都水滴</description>
		<generator>Hugo</generator>
		<language>zh-CN</language>
		
		
		
		
			<lastBuildDate>Sun, 31 May 2026 08:00:00 +0800</lastBuildDate>
		
			<atom:link href="https://blog.margrop.net/tag/%E8%B0%83%E8%AF%95/index.xml" rel="self" type="application/rss+xml" />
			<item>
				<title>HermesAgent 为什么一直不回微信和企业微信？我最后排到的根因居然是本地 relay 的 3 秒超时</title>
				<link>https://blog.margrop.net/post/hermesagent-wechat-wecom-relay-timeout-debugging/</link>
				<pubDate>Sun, 31 May 2026 08:00:00 +0800</pubDate>
				<guid>https://blog.margrop.net/post/hermesagent-wechat-wecom-relay-timeout-debugging/</guid>
				<description>&lt;h2 id=&#34;先说结论&#34;&gt;先说结论&lt;/h2&gt;&#xA;&lt;p&gt;这次故障看起来像“模型不行”或者“微信通道坏了”，但真正把消息链路掐断的，是我本地那层 &lt;code&gt;relay&lt;/code&gt; 的超时设置。它把整条上游请求的等待窗口限制成了 3 秒，而真实的 WeChat / WeCom 消息 turn 往往需要更久才能从新 API 网关拿到完整回复。结果就是：relay 先断开，HermesAgent 只能看到 &lt;code&gt;Connection error&lt;/code&gt;、&lt;code&gt;RemoteProtocolError&lt;/code&gt;，然后主模型和 fallback 一起被耗尽。&lt;/p&gt;&#xA;&lt;p&gt;更准确地说，这不是 HermesAgent 核心代码的问题，也不是模型名的问题，而是一个本地外置组件的连接策略问题。把 &lt;code&gt;connect timeout&lt;/code&gt; 和 &lt;code&gt;response wait&lt;/code&gt; 混成同一个超时，等于给长请求做了一个错误的截止时间。修复方式也不复杂：连接阶段保留短超时，连接成功后把 socket 切回阻塞等待；同时把 relay 做成独立、可持续启动的服务，不再把它绑死在临时 shell 里。&lt;/p&gt;&#xA;&lt;p&gt;&lt;img src=&#34;https://blog.margrop.net/post-images/hermesagent-wechat-wecom-relay-timeout-debugging/cover.png&#34; alt=&#34;HermesAgent relay 调试封面&#34;&gt;&lt;/p&gt;&#xA;&lt;h2 id=&#34;问题背景&#34;&gt;问题背景&lt;/h2&gt;&#xA;&lt;p&gt;HermesAgent 这条链路不是单机脚本，而是一条完整的消息生产线。用户从微信或企业微信发出一句话，消息会先进入 Hermes 的通道层，再进入 Gateway，接着经过本地 relay 转发到自建的 NewAPI 网关，最后才到模型服务。模型回来的内容还要经过 Hermes 的消息整理、工具调用处理、最终拼接，再发回原始通道。&lt;/p&gt;&#xA;&lt;p&gt;这种结构的好处是灵活，坏处也很现实：任何一层都可能制造“看起来像模型故障”的表象。你看到的是“没有回复”或者“Connection error”，但根因可能在更外层的 relay、socket、超时、代理或者会话路由里。&lt;/p&gt;&#xA;&lt;p&gt;这次我一开始也走了老路，先怀疑模型配置。因为从表象看，主模型和 fallback 都失败了，日志里反复出现：&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Primary model failed&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;switching to fallback&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;API failed after 1 retries&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Connection error&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Max retries exhausted&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;如果你只看这一段，很容易得出“模型端不稳定”的结论。但这类结论通常太早。因为同一批模型在别的入口上是能正常工作的，&lt;code&gt;/v1/models&lt;/code&gt; 也能返回，简单的 health check 也没有异常。真正出问题的是“真实消息 turn”。&lt;/p&gt;</description>
			</item>
	</channel>
</rss>
