Skip to content

Gemini 思维链非标准格式泄漏到 Telegram:...N>thought 变种未被过滤

问题

使用 Gemini 模型(包括 Gemini 3.1)时,思维链内容以非标准格式泄漏到 Telegram 等消息渠道:

...94>thought CRITICAL INSTRUCTION 1:...

现有的正则过滤(THINKING_TAG_SCAN_RE)只匹配标准 XML 格式的 <thinking><thought> 标签,无法覆盖这种变种。该问题在 silent 响应路径和 heartbeat 路径下均可复现,在 OpenClaw 2026.4.2 中已确认存在。

解决方案

临时规避(等待官方 PR 合并):

使用 message:preprocessedmessage:sent hook 在发送前清理该变种内容:

typescript
// hooks/filter-gemini-thought/handler.ts
const GEMINI_THOUGHT_VARIANT_RE = /\.\.\.\d+>\s*thought\s+[A-Z_]+:?[^\n]*/gi;

const handler = async (event) => {
  if (event.type !== "message" || event.action !== "preprocessed") return;
  
  if (event.context.bodyForAgent) {
    event.context.bodyForAgent = event.context.bodyForAgent.replace(
      GEMINI_THOUGHT_VARIANT_RE, 
      ""
    );
  }
};

export default handler;

参考 PR:官方修复追踪在 PR #48593(当前未完全覆盖此变种)。

另一个保守方案(事后清理,在输出最终化阶段):

javascript
// 移除所有残留 thinking 相关内容
const AFTER_THINKING_CLEANUP_RE = /\.\.\.\d+>(?:thought|think(?:ing)?)[^\n]*/gi;
output = output.replace(AFTER_THINKING_CLEANUP_RE, "").trim();

根本原因src/agents/pi-embedded-subscribe.ts 中的 THINKING_TAG_SCAN_RE 正则为:

javascript
const THINKING_TAG_SCAN_RE = /<\s*(\/?)\s*(?:think(?:ing)?|thought|antthinking)\s*>/gi;

该正则只处理标准 XML 格式,需要额外覆盖 ...N>thought ... 非标准变种。

社区补充方法

&lt;final&gt; 和自闭合 <final/> 标签泄漏(#65867,v2026.4.15)

Gemini 模型还存在另一种变种:&lt;final&gt;<final/> 标签泄漏到 Control UI 及 Telegram 等渠道消息中。根因相同:pi-embedded-subscribe.ts 中的 streaming subscriber 和用户侧文本净化器使用了更窄的正则 /<\s*\/?\s*final\s*>/gi,无法匹配自闭合 <final/> 形式,且 enforcement-mode 将 <final/> 误判为开启标签。

修复方案(PR #66225,等待合并):将 streaming subscriber 和净化器的正则对齐为 reasoning-tags.ts 中已有的更宽泛模式,同时修复 <final/> 的 enforcement-mode 处理逻辑。

临时缓解(等待合并期间):手动应用以下正则在消息发送前清理 &lt;final&gt; 相关标签:

javascript
const FINAL_TAG_CLEANUP_RE = /<\s*\/?\s*final\s*\/?>/gi;
output = output.replace(FINAL_TAG_CLEANUP_RE, "").trim();