<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    <title>踩坑宝典 on 世界一隅 | 认知能量工程</title>
    <link>/pitfalls/</link>
    <description>Recent content in 踩坑宝典 on 世界一隅 | 认知能量工程</description>
    <generator>Hugo -- gohugo.io</generator>
    <language>zh-cn</language>
    <lastBuildDate>Sat, 13 Jun 2026 00:00:00 +0000</lastBuildDate><atom:link href="/pitfalls/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>AstrBot 公众号被动回复 XML 二次包装导致微信无法解析</title>
      <link>/pitfalls/pit-astrbot-xml-double-wrap/</link>
      <pubDate>Sat, 13 Jun 2026 00:00:00 +0000</pubDate>
      
      <guid>/pitfalls/pit-astrbot-xml-double-wrap/</guid>
      <description>&lt;h2 id=&#34;症状&#34;&gt;症状&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;你看到什么？&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;AstrBot 微信公众号被动回复模式：AI 正常生成回复，日志显示 &lt;code&gt;wx buffer hit on trigger&lt;/code&gt; 和 &lt;code&gt;wx first window timeout&lt;/code&gt; 正常打印，&lt;code&gt;cached_xml&lt;/code&gt; 里有值。但用户手机端&lt;strong&gt;永远看不到回复&lt;/strong&gt;。无任何报错日志——微信静默丢弃了回复。&lt;/p&gt;
&lt;h2 id=&#34;根因&#34;&gt;根因&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;到底为什么出问题？&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;&lt;code&gt;callback&lt;/code&gt; 函数把 AI 结果用 &lt;code&gt;create_reply()&lt;/code&gt; 转成&lt;strong&gt;完整 XML&lt;/strong&gt; 存入 &lt;code&gt;cached_xml&lt;/code&gt;：&lt;/p&gt;
&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;&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# callback 函数中&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;reply_xml &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; str(create_reply(result, msg))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;state[&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;cached_xml&amp;#34;&lt;/span&gt;]&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;append(reply_xml)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;存储的内容已经是完整 XML：&lt;/p&gt;
&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;&#34;&gt;&lt;code class=&#34;language-xml&#34; data-lang=&#34;xml&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;xml&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;ToUserName&amp;gt;&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&amp;lt;![CDATA[ofqGA2NNjQOqZL3snP_mzNQrGQLM]]&amp;gt;&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;/ToUserName&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;FromUserName&amp;gt;&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&amp;lt;![CDATA[gh_bd189357a403]]&amp;gt;&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;/FromUserName&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;Content&amp;gt;&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&amp;lt;![CDATA[你好，我是AI助手]]&amp;gt;&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;/Content&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;/xml&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;但 &lt;code&gt;handle_callback&lt;/code&gt; 从 &lt;code&gt;cached_xml&lt;/code&gt; 取出后，又用 &lt;code&gt;_reply_text()&lt;/code&gt; &lt;strong&gt;再包装一次&lt;/strong&gt;：&lt;/p&gt;
&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;&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;def&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;_reply_text&lt;/span&gt;(text: str) &lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt; str:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    reply_obj &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; create_reply(text, msg)  &lt;span style=&#34;color:#75715e&#34;&gt;# 把完整 XML 当作文本再包装&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#f92672&#34;&gt;...&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;微信收到嵌套 XML → 无法解析 → 静默丢弃。&lt;/p&gt;
&lt;h2 id=&#34;修复&#34;&gt;修复&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;怎么做？&lt;/p&gt;</description>
    </item>
    
    <item>
      <title>Cloudreve 上传大文件超时：Cloudflare 免费版 100 秒限制</title>
      <link>/pitfalls/pit-cloudreve-upload-timeout-cloudflare/</link>
      <pubDate>Sat, 13 Jun 2026 00:00:00 +0000</pubDate>
      
      <guid>/pitfalls/pit-cloudreve-upload-timeout-cloudflare/</guid>
      <description>&lt;h2 id=&#34;症状&#34;&gt;症状&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;你看到什么？&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;Cloudreve 云盘通过 Cloudflare Tunnel 暴露到公网。上传一个 15MB 的文件，浏览器进度条走得很慢，大约 2 分钟后显示&amp;quot;上传失败&amp;quot;。Cloudreve 日志里看不到明显错误。&lt;/p&gt;
&lt;p&gt;换小文件（&amp;lt;5MB）上传正常。大文件必挂。&lt;/p&gt;
&lt;h2 id=&#34;根因&#34;&gt;根因&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;到底为什么出问题？&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;请求链路：&lt;/p&gt;



&lt;div class=&#34;goat svg-container &#34;&gt;
  
    &lt;svg
      xmlns=&#34;http://www.w3.org/2000/svg&#34;
      font-family=&#34;Menlo,Lucida Console,monospace&#34;
      
        viewBox=&#34;0 0 608 25&#34;
      &gt;
      &lt;g transform=&#39;translate(8,16)&#39;&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;0&#39; y=&#39;4&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;浏&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;8&#39; y=&#39;4&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;览&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;16&#39; y=&#39;4&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;器&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;32&#39; y=&#39;4&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;→&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;48&#39; y=&#39;4&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;C&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;56&#39; y=&#39;4&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;l&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;64&#39; y=&#39;4&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;o&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;72&#39; y=&#39;4&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;u&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;80&#39; y=&#39;4&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;d&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;88&#39; y=&#39;4&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;f&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;96&#39; y=&#39;4&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;l&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;104&#39; y=&#39;4&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;a&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;112&#39; y=&#39;4&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;r&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;120&#39; y=&#39;4&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;e&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;136&#39; y=&#39;4&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;C&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;144&#39; y=&#39;4&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;D&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;152&#39; y=&#39;4&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;N&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;168&#39; y=&#39;4&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;(&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;176&#39; y=&#39;4&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;1&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;184&#39; y=&#39;4&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;0&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;192&#39; y=&#39;4&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;0&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;200&#39; y=&#39;4&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;s&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;216&#39; y=&#39;4&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;超&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;224&#39; y=&#39;4&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;时&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;232&#39; y=&#39;4&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;)&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;248&#39; y=&#39;4&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;→&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;264&#39; y=&#39;4&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;c&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;272&#39; y=&#39;4&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;l&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;280&#39; y=&#39;4&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;o&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;288&#39; y=&#39;4&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;u&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;296&#39; y=&#39;4&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;d&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;304&#39; y=&#39;4&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;f&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;312&#39; y=&#39;4&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;l&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;320&#39; y=&#39;4&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;a&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;328&#39; y=&#39;4&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;r&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;336&#39; y=&#39;4&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;e&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;344&#39; y=&#39;4&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;d&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;360&#39; y=&#39;4&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;t&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;368&#39; y=&#39;4&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;u&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;376&#39; y=&#39;4&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;n&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;384&#39; y=&#39;4&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;n&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;392&#39; y=&#39;4&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;e&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;400&#39; y=&#39;4&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;l&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;416&#39; y=&#39;4&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;→&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;432&#39; y=&#39;4&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;D&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;440&#39; y=&#39;4&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;o&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;448&#39; y=&#39;4&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;c&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;456&#39; y=&#39;4&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;k&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;464&#39; y=&#39;4&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;e&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;472&#39; y=&#39;4&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;r&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;488&#39; y=&#39;4&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;C&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;496&#39; y=&#39;4&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;l&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;504&#39; y=&#39;4&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;o&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;512&#39; y=&#39;4&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;u&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;520&#39; y=&#39;4&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;d&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;528&#39; y=&#39;4&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;r&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;536&#39; y=&#39;4&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;e&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;544&#39; y=&#39;4&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;v&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;552&#39; y=&#39;4&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;e&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;560&#39; y=&#39;4&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;:&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;568&#39; y=&#39;4&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;5&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;576&#39; y=&#39;4&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;2&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;584&#39; y=&#39;4&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;1&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;592&#39; y=&#39;4&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;2&lt;/text&gt;
&lt;/g&gt;

    &lt;/svg&gt;
  
&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Cloudflare 免费版 HTTP 代理有硬性 100 秒超时&lt;/strong&gt;。Cloudreve 默认分块大小较大（如 25MB），在网络慢的情况下，单块上传耗时 125 秒，超过 100 秒限制后 Cloudflare 直接切断连接。&lt;/p&gt;</description>
    </item>
    
    <item>
      <title>Excel COM wb.Save() 静默失败，必须用 SaveAs</title>
      <link>/pitfalls/pit-excel-com-save-silent-fail/</link>
      <pubDate>Sat, 13 Jun 2026 00:00:00 +0000</pubDate>
      
      <guid>/pitfalls/pit-excel-com-save-silent-fail/</guid>
      <description>&lt;h2 id=&#34;症状&#34;&gt;症状&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;你看到什么？&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;用 win32com 打开 Excel 文件，批量修改了几百个单元格的值和批注，调用 &lt;code&gt;wb.Save()&lt;/code&gt; 后无任何报错。打开文件一看——所有修改都没了，文件还是原来的样子。&lt;/p&gt;
&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;&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# 跑了半小时的修复脚本...&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;for&lt;/span&gt; row &lt;span style=&#34;color:#f92672&#34;&gt;in&lt;/span&gt; range(&lt;span style=&#34;color:#ae81ff&#34;&gt;2&lt;/span&gt;, &lt;span style=&#34;color:#ae81ff&#34;&gt;500&lt;/span&gt;):
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    ws&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;Cells(row, col)&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;Value &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; fix_value
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    ws&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;Cells(row, col)&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;AddComment(&lt;span style=&#34;color:#e6db74&#34;&gt;f&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;原值: &lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;{&lt;/span&gt;old&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt; → 修复: &lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;{&lt;/span&gt;fix&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;wb&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;Save()   &lt;span style=&#34;color:#75715e&#34;&gt;# ← 静默失败，半小时白干&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;wb&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;Close()
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;根因&#34;&gt;根因&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;到底为什么出问题？&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;Excel COM 的 &lt;code&gt;Save()&lt;/code&gt; 方法在以下情况下&lt;strong&gt;静默失败&lt;/strong&gt;（不抛异常、不返回错误码）：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;文件来自只读目录&lt;/strong&gt;：微信聊天目录 &lt;code&gt;D:\xwechat_files\...&lt;/code&gt; 下的文件，权限受限&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;网络路径/UNC 路径&lt;/strong&gt;：&lt;code&gt;\server\share\file.xlsx&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;文件被其他进程打开&lt;/strong&gt;：Excel 自己或其他程序持有文件锁&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;磁盘空间不足&lt;/strong&gt;：Save 写入失败但不报错&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;COM 接口的设计缺陷——&lt;code&gt;Save()&lt;/code&gt; 不返回 HRESULT，异常被吞掉。&lt;/p&gt;
&lt;h2 id=&#34;修复&#34;&gt;修复&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;具体步骤，能复制粘贴直接用。&lt;/p&gt;&lt;/blockquote&gt;
&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;&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;import&lt;/span&gt; os
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;import&lt;/span&gt; win32com.client
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;excel &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; win32com&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;client&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;Dispatch(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;Excel.Application&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;excel&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;Visible &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;False&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;excel&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;DisplayAlerts &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;False&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;wb &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; excel&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;Workbooks&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;Open(src_path)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;ws &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; wb&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;Worksheets(&lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# ... 做你的修改 ...&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# ✅ 正确做法：SaveAs 到可写目录&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;output &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; os&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;path&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;expanduser(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;~&amp;#39;&lt;/span&gt;) &lt;span style=&#34;color:#f92672&#34;&gt;+&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;r&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;\Desktop\output.xlsx&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;wb&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;SaveAs(output, FileFormat&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;51&lt;/span&gt;)   &lt;span style=&#34;color:#75715e&#34;&gt;# 51 = xlOpenXMLWorkbook (.xlsx)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;wb&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;Close(SaveChanges&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;False&lt;/span&gt;)        &lt;span style=&#34;color:#75715e&#34;&gt;# 已经 SaveAs 过了，不重复保存&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;excel&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;Quit()
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;关键参数&lt;/strong&gt;：&lt;/p&gt;</description>
    </item>
    
    <item>
      <title>Git push GitHub SSL 握手失败</title>
      <link>/pitfalls/pit-git-push-ssl-proxy-fix/</link>
      <pubDate>Sat, 13 Jun 2026 00:00:00 +0000</pubDate>
      
      <guid>/pitfalls/pit-git-push-ssl-proxy-fix/</guid>
      <description>&lt;h2 id=&#34;症状&#34;&gt;症状&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;你看到什么？&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;&lt;code&gt;git push&lt;/code&gt; 到 GitHub 报错：&lt;code&gt;fatal: unable to access &#39;https://github.com/...&#39;: SSL connection error&lt;/code&gt; 或 &lt;code&gt;TLS handshake failed&lt;/code&gt;。每次 push 都失败，ping 不通 GitHub。&lt;/p&gt;
&lt;h2 id=&#34;根因&#34;&gt;根因&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;真正的原因是什么？&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;Windows 环境下，Git 不会自动走系统代理（Clash/V2Ray）。之前只在单仓库设了 &lt;code&gt;http.proxy&lt;/code&gt;，其他仓库和全局 &lt;code&gt;.gitconfig&lt;/code&gt; 都没设，每次在新仓库 push 都重复踩坑。&lt;/p&gt;
&lt;h2 id=&#34;修复&#34;&gt;修复&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;具体怎么修的？&lt;/p&gt;&lt;/blockquote&gt;
&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;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;git config --global http.proxy http://127.0.0.1:7897
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;git config --global https.proxy http://127.0.0.1:7897
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;设完立刻生效，所有仓库自动走代理。当前 Clash 代理端口是 7897，如果你的代理端口不同需要改。&lt;/p&gt;
&lt;h2 id=&#34;怎么避免&#34;&gt;怎么避免&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;下次怎么不踩？&lt;/p&gt;&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;新机器/新系统第一件事：跑上面两行命令&lt;/li&gt;
&lt;li&gt;用 &lt;code&gt;git config --global --list | grep proxy&lt;/code&gt; 确认已设&lt;/li&gt;
&lt;li&gt;别用单仓库 &lt;code&gt;--local&lt;/code&gt;，那是坑的根源&lt;/li&gt;
&lt;/ul&gt;</description>
    </item>
    
    <item>
      <title>Gitee 已配镜像还手动 push gitee，做了多余操作</title>
      <link>/pitfalls/pit-gitee-mirror-dual-push/</link>
      <pubDate>Sat, 13 Jun 2026 00:00:00 +0000</pubDate>
      
      <guid>/pitfalls/pit-gitee-mirror-dual-push/</guid>
      <description>&lt;h2 id=&#34;症状&#34;&gt;症状&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;你看到什么？&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;每次 &lt;code&gt;git commit&lt;/code&gt; 后都跑 &lt;code&gt;git push origin master &amp;amp;&amp;amp; git push gitee master&lt;/code&gt;，两条命令都成功。实际上 Gitee 那边早已配置了从 GitHub 自动镜像同步，push origin 之后 Gitee 会自动拉取。手动再 push gitee 不仅多余，还可能在极端情况下导致冲突。&lt;/p&gt;
&lt;p&gt;更严重的是：&lt;code&gt;git remote&lt;/code&gt; 里 gitee 的 URL 硬编码了 token（&lt;code&gt;Zhaotianbibg1:cfe33...@gitee.com&lt;/code&gt;），每次 push 都明文传输。&lt;/p&gt;
&lt;h2 id=&#34;根因&#34;&gt;根因&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;到底为什么出问题？&lt;/p&gt;&lt;/blockquote&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;不知道镜像已配&lt;/strong&gt;：Gitee 后台配了 GitHub → Gitee 镜像后，没有删掉本地的 gitee remote&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;习惯性操作&lt;/strong&gt;：之前手动 push 两个 remote 形成习惯，没人提醒就一直做&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;没有&amp;quot;查 remote 列表 → 确认是否冗余&amp;quot;的检查步骤&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&#34;修复&#34;&gt;修复&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;怎么做？&lt;/p&gt;&lt;/blockquote&gt;
&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;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# 删掉 gitee remote（镜像自动同步，不需要手动 push）&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;git remote remove gitee
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# 确认只剩下 origin&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;git remote -v
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# origin  https://github.com/zhao818/claude-memory.git (fetch)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# origin  https://github.com/zhao818/claude-memory.git (push)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;以后只推 GitHub：&lt;/p&gt;</description>
    </item>
    
    <item>
      <title>Gitee 建仓库前没查已有仓库，建了重复仓库</title>
      <link>/pitfalls/pit-gitee-duplicate-repo-check/</link>
      <pubDate>Sat, 13 Jun 2026 00:00:00 +0000</pubDate>
      
      <guid>/pitfalls/pit-gitee-duplicate-repo-check/</guid>
      <description>&lt;h2 id=&#34;症状&#34;&gt;症状&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;你看到什么？&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;踩坑共享平台需要 Gitee 镜像。在 Gitee 上新建了 &lt;code&gt;pitfall-knowledge-base&lt;/code&gt; 仓库，配置了 GitHub → Gitee 镜像同步。后来发现用户早就有 &lt;code&gt;claude-memory&lt;/code&gt; 仓库，功能完全重叠——&lt;code&gt;claude-memory&lt;/code&gt; 本身就是踩坑知识库。&lt;/p&gt;
&lt;p&gt;结果：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;多了一个无用仓库，要手动删除&lt;/li&gt;
&lt;li&gt;镜像同步配置白做了&lt;/li&gt;
&lt;li&gt;概念混乱：哪个仓库才是真的？&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;根因&#34;&gt;根因&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;到底为什么出问题？&lt;/p&gt;&lt;/blockquote&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;不查就建&lt;/strong&gt;：建仓库前没跑 &lt;code&gt;gh repo list zhao818&lt;/code&gt; 或登录 Gitee 看已有仓库&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;命名冲动&lt;/strong&gt;：想了一个&amp;quot;好听的名字&amp;quot;就建了，没考虑是否和已有仓库功能重叠&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;平台不统一&lt;/strong&gt;：GitHub 一个名、Gitee 一个名，镜像对不齐&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;没有&amp;quot;先确认再行动&amp;quot;的肌肉记忆&lt;/strong&gt;：对平台操作的敬畏不够&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&#34;修复&#34;&gt;修复&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;具体步骤。&lt;/p&gt;&lt;/blockquote&gt;
&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;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# 1. 先查 GitHub 上已有的仓库&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;gh repo list zhao818 --limit &lt;span style=&#34;color:#ae81ff&#34;&gt;50&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# 2. 再查 Gitee 上已有的仓库&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# 浏览器打开 https://gitee.com/Zhaotianbibg1 → 看仓库列表&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# 3. 确认没有同名/同功能仓库后，再建&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# GitHub → Settings → Developer settings → Personal access tokens&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# Gitee → 设置 → 私人令牌&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# 4. 名称对齐：GitHub 和 Gitee 用同一个仓库名&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# GitHub: zhao818/claude-memory&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# Gitee:  Zhaotianbibg1/claude-memory  ← 对齐&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;删除多余仓库后，重新配置镜像：&lt;/p&gt;</description>
    </item>
    
    <item>
      <title>GNU sed a 命令中 
 被当字面量——假阳性验证导致以为修好实际没修</title>
      <link>/pitfalls/pit-sed-false-positive-verification/</link>
      <pubDate>Sat, 13 Jun 2026 00:00:00 +0000</pubDate>
      
      <guid>/pitfalls/pit-sed-false-positive-verification/</guid>
      <description>&lt;h2 id=&#34;症状&#34;&gt;症状&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;你看到什么？&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;用 &lt;code&gt;deploy_fix4.sh&lt;/code&gt; 部署修复到 AstrBot 后：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;sed 命令执行成功（exit 0）&lt;/li&gt;
&lt;li&gt;&lt;code&gt;grep -q &amp;quot;nonce = None&amp;quot;&lt;/code&gt; 验证通过（匹配到关键字）&lt;/li&gt;
&lt;li&gt;服务器重启后返回 &lt;strong&gt;500 错误&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;用户以为修好了，实际服务器崩了。&lt;/p&gt;
&lt;h2 id=&#34;根因&#34;&gt;根因&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;到底为什么出问题？&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;部署脚本用了 GNU sed 的 &lt;code&gt;a\&lt;/code&gt;（append）命令插入多行：&lt;/p&gt;
&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;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;sed -i &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;/match_line/a\            nonce = None\n            timestamp = None&amp;#34;&lt;/span&gt; target.py
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;在 GNU sed 的 &lt;code&gt;a\&lt;/code&gt; 命令中，&lt;code&gt;\n&lt;/code&gt; 被当作&lt;strong&gt;字面量&lt;/strong&gt;（反斜杠 + n），而非换行符。实际写入的是：&lt;/p&gt;
&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;&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;nonce &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;None&lt;/span&gt;\n            timestamp &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;None&lt;/span&gt;   &lt;span style=&#34;color:#75715e&#34;&gt;# ← 全在 1 行！Python 语法错误&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;但 &lt;code&gt;grep -q &amp;quot;nonce = None&amp;quot;&lt;/code&gt; 验证&lt;strong&gt;仍然匹配成功&lt;/strong&gt; → &lt;strong&gt;假阳性验证&lt;/strong&gt;。关键字在，代码是错的。&lt;/p&gt;
&lt;h2 id=&#34;修复&#34;&gt;修复&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;怎么做？&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;用 &lt;strong&gt;Python 做文件替换&lt;/strong&gt;，精确控制，不用 sed 多行命令：&lt;/p&gt;</description>
    </item>
    
    <item>
      <title>Hugo 手写单篇 HTML 跳过全量构建导致分类/列表页不更新</title>
      <link>/pitfalls/pit-hugo-skip-full-build/</link>
      <pubDate>Sat, 13 Jun 2026 00:00:00 +0000</pubDate>
      
      <guid>/pitfalls/pit-hugo-skip-full-build/</guid>
      <description>&lt;h2 id=&#34;症状&#34;&gt;症状&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;你看到什么？&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;新文章 URL 可以正常访问（&lt;code&gt;/posts/xxx/&lt;/code&gt; 能打开），但：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;分类页看不到这篇文章&lt;/li&gt;
&lt;li&gt;首页最新文章列表没有它&lt;/li&gt;
&lt;li&gt;所有聚合/列表页都不知道这篇文章存在&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;用户从分类入口进来找不到文章，以为没发布。&lt;/p&gt;
&lt;h2 id=&#34;根因&#34;&gt;根因&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;到底为什么出问题？&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;Hugo 是一个&lt;strong&gt;全量静态站点生成器&lt;/strong&gt;——每篇文章的交叉引用、分类聚合、列表渲染，都需要 &lt;code&gt;hugo -d docs/&lt;/code&gt; 重新计算。手写单篇 HTML 扔进 &lt;code&gt;docs/&lt;/code&gt; 相当于绕过了整个生成引擎：&lt;/p&gt;



&lt;div class=&#34;goat svg-container &#34;&gt;
  
    &lt;svg
      xmlns=&#34;http://www.w3.org/2000/svg&#34;
      font-family=&#34;Menlo,Lucida Console,monospace&#34;
      
        viewBox=&#34;0 0 480 41&#34;
      &gt;
      &lt;g transform=&#39;translate(8,16)&#39;&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;0&#39; y=&#39;4&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;❌&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;0&#39; y=&#39;20&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;✅&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;16&#39; y=&#39;4&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;手&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;16&#39; y=&#39;20&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;h&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;24&#39; y=&#39;4&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;写&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;24&#39; y=&#39;20&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;u&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;32&#39; y=&#39;20&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;g&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;40&#39; y=&#39;4&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;H&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;40&#39; y=&#39;20&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;o&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;48&#39; y=&#39;4&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;T&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;56&#39; y=&#39;4&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;M&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;56&#39; y=&#39;20&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;-&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;64&#39; y=&#39;4&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;L&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;64&#39; y=&#39;20&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;d&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;80&#39; y=&#39;4&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;→&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;80&#39; y=&#39;20&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;d&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;88&#39; y=&#39;20&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;o&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;96&#39; y=&#39;4&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;d&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;96&#39; y=&#39;20&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;c&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;104&#39; y=&#39;4&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;o&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;104&#39; y=&#39;20&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;s&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;112&#39; y=&#39;4&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;c&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;112&#39; y=&#39;20&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;/&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;120&#39; y=&#39;4&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;s&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;128&#39; y=&#39;4&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;/&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;136&#39; y=&#39;4&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;p&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;144&#39; y=&#39;4&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;o&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;152&#39; y=&#39;4&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;s&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;160&#39; y=&#39;4&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;t&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;168&#39; y=&#39;4&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;s&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;176&#39; y=&#39;4&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;/&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;184&#39; y=&#39;4&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;x&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;192&#39; y=&#39;4&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;x&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;200&#39; y=&#39;4&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;x&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;208&#39; y=&#39;4&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;/&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;216&#39; y=&#39;4&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;i&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;224&#39; y=&#39;4&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;n&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;232&#39; y=&#39;4&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;d&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;240&#39; y=&#39;4&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;e&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;248&#39; y=&#39;4&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;x&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;256&#39; y=&#39;4&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;.&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;264&#39; y=&#39;4&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;h&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;272&#39; y=&#39;4&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;t&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;280&#39; y=&#39;4&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;m&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;288&#39; y=&#39;4&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;l&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;320&#39; y=&#39;4&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;←&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;336&#39; y=&#39;4&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;文&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;336&#39; y=&#39;20&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;←&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;344&#39; y=&#39;4&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;章&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;352&#39; y=&#39;4&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;在&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;352&#39; y=&#39;20&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;所&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;360&#39; y=&#39;4&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;，&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;360&#39; y=&#39;20&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;有&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;368&#39; y=&#39;4&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;但&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;368&#39; y=&#39;20&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;页&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;376&#39; y=&#39;4&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;分&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;376&#39; y=&#39;20&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;面&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;384&#39; y=&#39;4&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;类&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;384&#39; y=&#39;20&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;同&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;392&#39; y=&#39;4&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;/&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;392&#39; y=&#39;20&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;步&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;400&#39; y=&#39;4&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;列&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;400&#39; y=&#39;20&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;重&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;408&#39; y=&#39;4&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;表&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;408&#39; y=&#39;20&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;建&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;416&#39; y=&#39;4&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;/&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;424&#39; y=&#39;4&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;首&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;432&#39; y=&#39;4&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;页&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;440&#39; y=&#39;4&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;从&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;448&#39; y=&#39;4&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;不&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;456&#39; y=&#39;4&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;更&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;464&#39; y=&#39;4&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;新&lt;/text&gt;
&lt;/g&gt;

    &lt;/svg&gt;
  
&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;这个错误已经犯过至少 3 次&lt;/strong&gt;。&lt;/p&gt;</description>
    </item>
    
    <item>
      <title>Python encoding=&#39;utf-8&#39; 不能自动处理 BOM</title>
      <link>/pitfalls/pit-python-utf8-bom-encoding/</link>
      <pubDate>Sat, 13 Jun 2026 00:00:00 +0000</pubDate>
      
      <guid>/pitfalls/pit-python-utf8-bom-encoding/</guid>
      <description>&lt;h2 id=&#34;症状&#34;&gt;症状&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;你看到什么？&lt;/p&gt;&lt;/blockquote&gt;
&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;&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;with&lt;/span&gt; open(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;config.txt&amp;#34;&lt;/span&gt;, encoding&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;utf-8&amp;#34;&lt;/span&gt;) &lt;span style=&#34;color:#66d9ef&#34;&gt;as&lt;/span&gt; f:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;for&lt;/span&gt; line &lt;span style=&#34;color:#f92672&#34;&gt;in&lt;/span&gt; f:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; line&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;startswith(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;GITEE_TOKEN=&amp;#34;&lt;/span&gt;):  &lt;span style=&#34;color:#75715e&#34;&gt;# ← 永远不匹配&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            token &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; line&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;strip()&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;split(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;=&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;)[&lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;文件明明以 &lt;code&gt;GITEE_TOKEN=cfe33...&lt;/code&gt; 开头，但 &lt;code&gt;startswith&lt;/code&gt; 永远返回 False，令牌读不到。打了 &lt;code&gt;print(repr(line))&lt;/code&gt; 才发现行首有 &lt;code&gt;﻿&lt;/code&gt;。&lt;/p&gt;
&lt;h2 id=&#34;根因&#34;&gt;根因&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;真正的原因是什么？&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;Windows 下某些工具（记事本、PowerShell &lt;code&gt;Out-File&lt;/code&gt;、部分 IDE）保存 UTF-8 文件时会在文件头加 BOM（Byte Order Mark，&lt;code&gt;﻿&lt;/code&gt;）。Python 的 &lt;code&gt;encoding=&#39;utf-8&#39;&lt;/code&gt; 不会自动跳过 BOM，它被当作第一个字符读进去。&lt;/p&gt;
&lt;h2 id=&#34;修复&#34;&gt;修复&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;具体怎么修的？&lt;/p&gt;&lt;/blockquote&gt;
&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;&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# ❌ 错误&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;with&lt;/span&gt; open(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;config.txt&amp;#34;&lt;/span&gt;, encoding&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;utf-8&amp;#34;&lt;/span&gt;) &lt;span style=&#34;color:#66d9ef&#34;&gt;as&lt;/span&gt; f:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# ✅ 正确——自动跳过 BOM&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;with&lt;/span&gt; open(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;config.txt&amp;#34;&lt;/span&gt;, encoding&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;utf-8-sig&amp;#34;&lt;/span&gt;) &lt;span style=&#34;color:#66d9ef&#34;&gt;as&lt;/span&gt; f:
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;一行之差，三天之坑。&lt;/p&gt;
&lt;h2 id=&#34;怎么避免&#34;&gt;怎么避免&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;下次怎么不踩？&lt;/p&gt;&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;读配置文件、.env、用户输入文件时，默认用 &lt;code&gt;utf-8-sig&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;调试编码问题第一招：&lt;code&gt;print(repr(line))&lt;/code&gt; 看原始字符&lt;/li&gt;
&lt;li&gt;如果不想改 encoding，可以手动 &lt;code&gt;line.lstrip(&#39;﻿&#39;)&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;</description>
    </item>
    
    <item>
      <title>Python 缩进错位导致 140 行被动回复代码完全跳过</title>
      <link>/pitfalls/pit-python-indentation-silent-skip/</link>
      <pubDate>Sat, 13 Jun 2026 00:00:00 +0000</pubDate>
      
      <guid>/pitfalls/pit-python-indentation-silent-skip/</guid>
      <description>&lt;h2 id=&#34;症状&#34;&gt;症状&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;你看到什么？&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;AstrBot 微信公众号适配器中，被动回复模式（&lt;code&gt;active_send_mode=False&lt;/code&gt;）完全不工作：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;用户发消息到公众号 → 无任何回复&lt;/li&gt;
&lt;li&gt;日志报 &lt;code&gt;TypeError: The response value returned by the view function cannot be None&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;调试器中 AI 回复正常，部署后就是不行&lt;/li&gt;
&lt;li&gt;检查了所有逻辑，没发现问题——代码&amp;quot;看起来&amp;quot;都在&lt;/li&gt;
&lt;/ul&gt;
&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;&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# handle_callback 方法的末尾&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; self&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;active_send_mode:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    result_xml &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;await&lt;/span&gt; self&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;callback(msg)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;not&lt;/span&gt; result_xml:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;success&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#f92672&#34;&gt;...&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#75715e&#34;&gt;# 以下 140 行被动回复代码...&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    from_user &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; str(getattr(msg, &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;source&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&amp;#34;&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    to_user &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; str(getattr(msg, &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;target&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&amp;#34;&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#75715e&#34;&gt;# ... 100+ 行逻辑 ...&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt; reply_xml
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# ← handle_callback 结束，但没有任何 return&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;根因&#34;&gt;根因&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;到底为什么出问题？&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;140 行被动回复代码的缩进是 &lt;strong&gt;12 个空格&lt;/strong&gt;，对应 3 级缩进（4+4+4），错误地放在了 &lt;code&gt;if self.active_send_mode:&lt;/code&gt; 块&lt;strong&gt;内部&lt;/strong&gt;。&lt;/p&gt;</description>
    </item>
    
    <item>
      <title>python-docx 表格跨页断开无法控制</title>
      <link>/pitfalls/pit-docx-table-page-break-cantsplit/</link>
      <pubDate>Sat, 13 Jun 2026 00:00:00 +0000</pubDate>
      
      <guid>/pitfalls/pit-docx-table-page-break-cantsplit/</guid>
      <description>&lt;h2 id=&#34;症状&#34;&gt;症状&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;你看到什么？&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;用 python-docx 生成的报告，表格在页面底部被 Word 自动劈成两半——表头在上页，数据在下页。读者看到断裂的表格，专业性大打折扣。手动在 Word 里调整也调不好。&lt;/p&gt;
&lt;h2 id=&#34;根因&#34;&gt;根因&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;真正的原因是什么？&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;python-docx 创建的表格行，默认没有设置 &lt;code&gt;&amp;lt;w:cantSplit/&amp;gt;&lt;/code&gt; 属性。Word 打开文档后，按自己的分页算法决定是否断开表格——如果表格行正好落在页面底部，Word 就会把它断开。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;这是 python-docx 的默认行为缺陷，不是 Word 的问题。&lt;/strong&gt;&lt;/p&gt;
&lt;h2 id=&#34;修复&#34;&gt;修复&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;具体怎么修的？&lt;/p&gt;&lt;/blockquote&gt;
&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;&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;from&lt;/span&gt; docx &lt;span style=&#34;color:#f92672&#34;&gt;import&lt;/span&gt; Document
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;from&lt;/span&gt; docx.oxml.ns &lt;span style=&#34;color:#f92672&#34;&gt;import&lt;/span&gt; qn
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;doc &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; Document()
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;table &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; doc&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;add_table(rows&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;5&lt;/span&gt;, cols&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;3&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# 关键：给每一行设 cantSplit，禁止跨页断开&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;for&lt;/span&gt; row &lt;span style=&#34;color:#f92672&#34;&gt;in&lt;/span&gt; table&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;rows:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    tr &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; row&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;_tr
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    trPr &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; tr&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;get_or_add_trPr()
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    cant_split &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; OxmlElement(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;w:cantSplit&amp;#39;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    trPr&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;append(cant_split)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;doc&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;save(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;output.docx&amp;#39;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;这样生成的表格不会在页面中间断开，Word 会把整行推到下一页。&lt;/p&gt;
&lt;h2 id=&#34;怎么避免&#34;&gt;怎么避免&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;下次怎么不踩？&lt;/p&gt;&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;生成 docx 表格时，所有行显式设 &lt;code&gt;cantSplit&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;目录（TOC）不要手动写，用 Word 域代码 &lt;code&gt;TOC \o &amp;quot;1-3&amp;quot;&lt;/code&gt; 生成&lt;/li&gt;
&lt;li&gt;参考 &lt;code&gt;~/claude-memory/global/tools/docx-patterns.md&lt;/code&gt; 的完整模式&lt;/li&gt;
&lt;/ul&gt;</description>
    </item>
    
    <item>
      <title>requests json= 参数导致公众号中文乱码</title>
      <link>/pitfalls/pit-wechat-chinese-garbled-requests-json/</link>
      <pubDate>Sat, 13 Jun 2026 00:00:00 +0000</pubDate>
      
      <guid>/pitfalls/pit-wechat-chinese-garbled-requests-json/</guid>
      <description>&lt;h2 id=&#34;症状&#34;&gt;症状&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;你看到什么？&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;公众号推送文章草稿后，读者看到的中文全部变成 &lt;code&gt;我是&lt;/code&gt; 这样的 Unicode 转义序列。微信后台预览正常，但推送后乱码。踩了 3 次才修好。&lt;/p&gt;
&lt;h2 id=&#34;根因&#34;&gt;根因&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;真正的原因是什么？&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;&lt;code&gt;requests.post(url, json=data)&lt;/code&gt; 内部调用 &lt;code&gt;json.dumps(data)&lt;/code&gt; 时，默认参数 &lt;code&gt;ensure_ascii=True&lt;/code&gt;，会把所有非 ASCII 字符转成 &lt;code&gt;\uXXXX&lt;/code&gt;。微信服务器收到后原样展示，不会反转义。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;这不是微信的 bug，是 requests 的默认行为。&lt;/strong&gt;&lt;/p&gt;
&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;&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# requests 内部等价于：&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;body &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; json&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;dumps(data, ensure_ascii&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;True&lt;/span&gt;)  &lt;span style=&#34;color:#75715e&#34;&gt;# 中文 → \uXXXX&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# 发送给微信：{&amp;#34;content&amp;#34;: &amp;#34;我是中文&amp;#34;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# 微信原样展示：我是中文&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;修复&#34;&gt;修复&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;具体怎么修的？&lt;/p&gt;&lt;/blockquote&gt;
&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;&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# ❌ 错误——中文变乱码&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;requests&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;post(url, json&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;data)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# ✅ 正确&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;import&lt;/span&gt; json
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;headers &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; {&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;Content-Type&amp;#39;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;application/json; charset=utf-8&amp;#39;&lt;/span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;requests&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;post(url, data&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;json&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;dumps(data, ensure_ascii&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;False&lt;/span&gt;)&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;encode(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;utf-8&amp;#39;&lt;/span&gt;), headers&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;headers)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;关键三步：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;code&gt;ensure_ascii=False&lt;/code&gt; — 中文保持原样&lt;/li&gt;
&lt;li&gt;&lt;code&gt;.encode(&#39;utf-8&#39;)&lt;/code&gt; — 转成字节&lt;/li&gt;
&lt;li&gt;手动设 &lt;code&gt;Content-Type: application/json; charset=utf-8&lt;/code&gt; — 告诉服务器编码&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&#34;怎么避免&#34;&gt;怎么避免&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;下次怎么不踩？&lt;/p&gt;</description>
    </item>
    
    <item>
      <title>TRIGGERS 多场景同时命中时只读第一条，漏了后续路由</title>
      <link>/pitfalls/pit-triggers-multi-match-merge/</link>
      <pubDate>Sat, 13 Jun 2026 00:00:00 +0000</pubDate>
      
      <guid>/pitfalls/pit-triggers-multi-match-merge/</guid>
      <description>&lt;h2 id=&#34;症状&#34;&gt;症状&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;你看到什么？&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;用户说&amp;quot;审计五件套&amp;quot;来审计一个 Excel 文件。这是一个&lt;strong&gt;数据录入项目&lt;/strong&gt;，TRIGGERS.md 有两条路由同时命中：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&amp;ldquo;审计五件套 / 跑审计&amp;rdquo; → 加载 &lt;code&gt;audit-four-piece.md&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&amp;ldquo;数据录入项目&amp;rdquo; → 加载 &lt;code&gt;audit-four-piece-data.md&lt;/code&gt;、&lt;code&gt;excel-com-audit.md&lt;/code&gt;、&lt;code&gt;data-cross-verify.md&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;但实际操作中只读了第一条（通用版），漏了数据版三条。用户提醒&amp;quot;我记得优化过你的记忆啊，为什么还做不到&amp;quot;——因为之前已经修过这个问题，但触发匹配逻辑没改彻底。&lt;/p&gt;
&lt;p&gt;后果：跑完审计流程后，数据特有的坑（收支=明细交叉验证、实发=应发检查、Excel COM 修复模式）全部没做。&lt;/p&gt;
&lt;h2 id=&#34;根因&#34;&gt;根因&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;到底为什么出问题？&lt;/p&gt;&lt;/blockquote&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;匹配策略是&amp;quot;命中即停&amp;quot;&lt;/strong&gt;：扫到第一个匹配行就停下来加载了，没继续往下扫&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;没有 OR → AND 的思维转换&lt;/strong&gt;：多条路由匹配同一任务时，取的文件应该是&lt;strong&gt;并集（AND）&lt;/strong&gt;，不是&lt;strong&gt;第一个命中（OR）&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;TRIGGERS 表设计有盲区&lt;/strong&gt;：通用路由和专用路由分开写，但加载逻辑没做合并&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;事后没自检&lt;/strong&gt;：加载完文件后没问自己&amp;quot;用户说的是审计+Excel，我有没有读 Excel 相关的路由？&amp;quot;&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&#34;修复&#34;&gt;修复&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;怎么做？&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;匹配策略改为&amp;quot;全量扫描 + AND 合并&amp;quot;&lt;/strong&gt;：&lt;/p&gt;



&lt;div class=&#34;goat svg-container &#34;&gt;
  
    &lt;svg
      xmlns=&#34;http://www.w3.org/2000/svg&#34;
      font-family=&#34;Menlo,Lucida Console,monospace&#34;
      
        viewBox=&#34;0 0 256 73&#34;
      &gt;
      &lt;g transform=&#39;translate(8,16)&#39;&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;0&#39; y=&#39;4&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;输&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;0&#39; y=&#39;20&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;匹&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;0&#39; y=&#39;36&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;合&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;0&#39; y=&#39;52&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;加&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;8&#39; y=&#39;4&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;入&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;8&#39; y=&#39;20&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;配&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;8&#39; y=&#39;36&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;并&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;8&#39; y=&#39;52&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;载&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;16&#39; y=&#39;4&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;：&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;16&#39; y=&#39;20&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;：&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;16&#39; y=&#39;36&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;：&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;16&#39; y=&#39;52&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;：&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;24&#39; y=&#39;4&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;用&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;24&#39; y=&#39;20&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;扫&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;24&#39; y=&#39;36&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;取&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;24&#39; y=&#39;52&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;读&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;32&#39; y=&#39;4&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;户&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;32&#39; y=&#39;20&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;描&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;32&#39; y=&#39;36&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;所&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;32&#39; y=&#39;52&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;全&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;40&#39; y=&#39;4&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;消&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;40&#39; y=&#39;36&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;有&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;40&#39; y=&#39;52&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;部&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;48&#39; y=&#39;4&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;息&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;48&#39; y=&#39;20&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;T&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;48&#39; y=&#39;36&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;匹&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;48&#39; y=&#39;52&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;匹&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;56&#39; y=&#39;4&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;关&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;56&#39; y=&#39;20&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;R&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;56&#39; y=&#39;36&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;配&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;56&#39; y=&#39;52&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;配&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;64&#39; y=&#39;4&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;键&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;64&#39; y=&#39;20&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;I&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;64&#39; y=&#39;36&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;路&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;64&#39; y=&#39;52&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;文&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;72&#39; y=&#39;4&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;词&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;72&#39; y=&#39;20&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;G&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;72&#39; y=&#39;36&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;由&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;72&#39; y=&#39;52&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;件&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;80&#39; y=&#39;20&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;G&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;80&#39; y=&#39;36&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;的&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;88&#39; y=&#39;20&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;E&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;88&#39; y=&#39;36&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;并&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;96&#39; y=&#39;20&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;R&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;96&#39; y=&#39;36&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;集&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;104&#39; y=&#39;20&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;S&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;112&#39; y=&#39;20&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;.&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;120&#39; y=&#39;20&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;m&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;128&#39; y=&#39;20&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;d&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;144&#39; y=&#39;20&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;全&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;152&#39; y=&#39;20&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;部&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;160&#39; y=&#39;20&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;行&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;168&#39; y=&#39;20&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;，&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;176&#39; y=&#39;20&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;收&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;184&#39; y=&#39;20&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;集&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;192&#39; y=&#39;20&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;所&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;200&#39; y=&#39;20&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;有&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;208&#39; y=&#39;20&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;匹&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;216&#39; y=&#39;20&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;配&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;224&#39; y=&#39;20&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;的&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;232&#39; y=&#39;20&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;路&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;240&#39; y=&#39;20&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;由&lt;/text&gt;
&lt;/g&gt;

    &lt;/svg&gt;
  
&lt;/div&gt;
&lt;p&gt;例如用户说&amp;quot;审计这个 Excel&amp;quot;：&lt;/p&gt;</description>
    </item>
    
    <item>
      <title>WSL 环境下 Claude Code Write 工具和 Bash 工具路径空间不一致</title>
      <link>/pitfalls/pit-wsl-write-tool-path-failure/</link>
      <pubDate>Sat, 13 Jun 2026 00:00:00 +0000</pubDate>
      
      <guid>/pitfalls/pit-wsl-write-tool-path-failure/</guid>
      <description>&lt;h2 id=&#34;症状&#34;&gt;症状&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;你看到什么？&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;用 &lt;code&gt;Write&lt;/code&gt; 工具写文件到 &lt;code&gt;~/claude-memory/pitfalls/xxx.md&lt;/code&gt;（或用绝对路径 &lt;code&gt;/home/zhaotianbing/claude-memory/...&lt;/code&gt;），工具报告成功，无报错。但 &lt;code&gt;ls ~/claude-memory/pitfalls/&lt;/code&gt; 看不到新文件。&lt;/p&gt;
&lt;p&gt;实际上本次会话就复现了：5 篇新踩坑用 Write 工具写完后，Bash 下全部找不到。最后用 Bash 重新写入才正确落盘。&lt;/p&gt;
&lt;h2 id=&#34;根因&#34;&gt;根因&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;到底为什么出问题？&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;核心矛盾：&lt;strong&gt;当前会话的 &lt;code&gt;$HOME&lt;/code&gt; 是 &lt;code&gt;/c/Users/zhaot&lt;/code&gt;（Windows 侧），但 &lt;code&gt;Write&lt;/code&gt; 工具把 &lt;code&gt;/home/zhaotianbing/&lt;/code&gt; 路径解析到了 WSL 原生 Linux 文件系统&lt;/strong&gt;。&lt;/p&gt;



&lt;div class=&#34;goat svg-container &#34;&gt;
  
    &lt;svg
      xmlns=&#34;http://www.w3.org/2000/svg&#34;
      font-family=&#34;Menlo,Lucida Console,monospace&#34;
      
        viewBox=&#34;0 0 656 41&#34;
      &gt;
      &lt;g transform=&#39;translate(8,16)&#39;&gt;
&lt;path d=&#39;M 216,16 L 224,0&#39; fill=&#39;none&#39; stroke=&#39;currentColor&#39;&gt;&lt;/path&gt;
&lt;circle cx=&#39;224&#39; cy=&#39;0&#39; r=&#39;6&#39; stroke=&#39;currentColor&#39; fill=&#39;#fff&#39;&gt;&lt;/circle&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;0&#39; y=&#39;4&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;B&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;0&#39; y=&#39;20&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;W&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;8&#39; y=&#39;4&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;a&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;8&#39; y=&#39;20&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;r&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;16&#39; y=&#39;4&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;s&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;16&#39; y=&#39;20&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;i&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;24&#39; y=&#39;4&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;h&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;24&#39; y=&#39;20&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;t&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;32&#39; y=&#39;20&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;e&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;40&#39; y=&#39;4&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;工&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;48&#39; y=&#39;4&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;具&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;48&#39; y=&#39;20&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;工&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;56&#39; y=&#39;4&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;：&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;56&#39; y=&#39;20&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;具&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;64&#39; y=&#39;4&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;$&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;64&#39; y=&#39;20&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;：&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;72&#39; y=&#39;4&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;H&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;72&#39; y=&#39;20&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;/&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;80&#39; y=&#39;4&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;O&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;80&#39; y=&#39;20&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;h&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;88&#39; y=&#39;4&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;M&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;88&#39; y=&#39;20&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;o&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;96&#39; y=&#39;4&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;E&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;96&#39; y=&#39;20&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;m&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;104&#39; y=&#39;20&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;e&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;112&#39; y=&#39;4&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;→&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;112&#39; y=&#39;20&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;/&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;120&#39; y=&#39;20&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;z&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;128&#39; y=&#39;4&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;/&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;128&#39; y=&#39;20&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;h&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;136&#39; y=&#39;4&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;c&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;136&#39; y=&#39;20&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;a&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;144&#39; y=&#39;4&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;/&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;144&#39; y=&#39;20&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;o&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;152&#39; y=&#39;4&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;U&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;152&#39; y=&#39;20&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;t&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;160&#39; y=&#39;4&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;s&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;160&#39; y=&#39;20&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;i&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;168&#39; y=&#39;4&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;e&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;168&#39; y=&#39;20&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;a&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;176&#39; y=&#39;4&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;r&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;176&#39; y=&#39;20&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;n&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;184&#39; y=&#39;4&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;s&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;184&#39; y=&#39;20&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;b&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;192&#39; y=&#39;4&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;/&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;192&#39; y=&#39;20&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;i&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;200&#39; y=&#39;4&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;z&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;200&#39; y=&#39;20&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;n&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;208&#39; y=&#39;4&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;h&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;208&#39; y=&#39;20&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;g&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;216&#39; y=&#39;4&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;a&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;224&#39; y=&#39;20&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;c&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;232&#39; y=&#39;4&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;t&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;232&#39; y=&#39;20&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;l&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;240&#39; y=&#39;20&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;a&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;248&#39; y=&#39;4&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;→&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;248&#39; y=&#39;20&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;u&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;256&#39; y=&#39;20&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;d&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;264&#39; y=&#39;4&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;~&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;264&#39; y=&#39;20&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;e&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;272&#39; y=&#39;4&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;/&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;272&#39; y=&#39;20&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;-&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;280&#39; y=&#39;4&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;c&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;280&#39; y=&#39;20&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;m&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;288&#39; y=&#39;4&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;l&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;288&#39; y=&#39;20&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;e&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;296&#39; y=&#39;4&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;a&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;296&#39; y=&#39;20&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;m&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;304&#39; y=&#39;4&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;u&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;304&#39; y=&#39;20&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;o&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;312&#39; y=&#39;4&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;d&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;312&#39; y=&#39;20&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;r&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;320&#39; y=&#39;4&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;e&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;320&#39; y=&#39;20&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;y&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;328&#39; y=&#39;4&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;-&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;336&#39; y=&#39;4&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;m&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;336&#39; y=&#39;20&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;→&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;344&#39; y=&#39;4&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;e&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;352&#39; y=&#39;4&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;m&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;352&#39; y=&#39;20&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;W&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;360&#39; y=&#39;4&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;o&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;360&#39; y=&#39;20&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;S&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;368&#39; y=&#39;4&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;r&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;368&#39; y=&#39;20&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;L&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;376&#39; y=&#39;4&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;y&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;384&#39; y=&#39;20&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;原&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;392&#39; y=&#39;4&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;→&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;392&#39; y=&#39;20&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;生&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;408&#39; y=&#39;4&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;/&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;408&#39; y=&#39;20&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;F&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;416&#39; y=&#39;4&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;c&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;416&#39; y=&#39;20&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;S&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;424&#39; y=&#39;4&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;/&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;432&#39; y=&#39;4&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;U&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;432&#39; y=&#39;20&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;→&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;440&#39; y=&#39;4&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;s&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;448&#39; y=&#39;4&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;e&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;448&#39; y=&#39;20&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;文&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;456&#39; y=&#39;4&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;r&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;456&#39; y=&#39;20&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;件&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;464&#39; y=&#39;4&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;s&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;464&#39; y=&#39;20&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;孤&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;472&#39; y=&#39;4&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;/&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;472&#39; y=&#39;20&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;立&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;480&#39; y=&#39;4&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;z&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;488&#39; y=&#39;4&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;h&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;488&#39; y=&#39;20&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;❌&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;496&#39; y=&#39;4&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;a&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;504&#39; y=&#39;4&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;o&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;512&#39; y=&#39;4&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;t&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;520&#39; y=&#39;4&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;/&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;528&#39; y=&#39;4&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;c&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;536&#39; y=&#39;4&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;l&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;544&#39; y=&#39;4&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;a&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;552&#39; y=&#39;4&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;u&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;560&#39; y=&#39;4&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;d&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;568&#39; y=&#39;4&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;e&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;576&#39; y=&#39;4&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;-&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;584&#39; y=&#39;4&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;m&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;592&#39; y=&#39;4&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;e&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;600&#39; y=&#39;4&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;m&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;608&#39; y=&#39;4&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;o&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;616&#39; y=&#39;4&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;r&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;624&#39; y=&#39;4&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;y&lt;/text&gt;
&lt;text text-anchor=&#39;middle&#39; x=&#39;640&#39; y=&#39;4&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;✅&lt;/text&gt;
&lt;/g&gt;

    &lt;/svg&gt;
  
&lt;/div&gt;
&lt;p&gt;两个工具的路径空间不一致 → Write 写入的位置和 Bash 读写的位置不同。Read 工具走了不同的解析路径所以能读到 Write 写的文件，但 Bash 看不到。&lt;/p&gt;</description>
    </item>
    
    <item>
      <title>公众号明文模式下 nonce/timestamp 非空导致回复被错误加密</title>
      <link>/pitfalls/pit-wechat-plaintext-falsely-encrypted/</link>
      <pubDate>Sat, 13 Jun 2026 00:00:00 +0000</pubDate>
      
      <guid>/pitfalls/pit-wechat-plaintext-falsely-encrypted/</guid>
      <description>&lt;h2 id=&#34;症状&#34;&gt;症状&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;你看到什么？&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;微信后台配置为「明文模式」。修复了 XML 二次包装后，日志无报错、AI 正常生成回复、&lt;code&gt;cached_xml&lt;/code&gt; 有值——但用户手机端仍然看不到任何自动回复。表现和 XML 嵌套完全一样，给排查造成极大困扰。&lt;/p&gt;
&lt;h2 id=&#34;根因&#34;&gt;根因&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;到底为什么出问题？&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;&lt;code&gt;_maybe_encrypt()&lt;/code&gt; 函数不关心当前模式，只检查 &lt;code&gt;nonce&lt;/code&gt; 和 &lt;code&gt;timestamp&lt;/code&gt; 是否存在：&lt;/p&gt;
&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;&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;def&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;_maybe_encrypt&lt;/span&gt;(self, xml, nonce, timestamp):
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; xml &lt;span style=&#34;color:#f92672&#34;&gt;and&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&amp;lt;Encrypt&amp;gt;&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;not&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;in&lt;/span&gt; xml &lt;span style=&#34;color:#f92672&#34;&gt;and&lt;/span&gt; nonce &lt;span style=&#34;color:#f92672&#34;&gt;and&lt;/span&gt; timestamp:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt; self&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;crypto&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;encrypt_message(xml, nonce, timestamp)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt; xml &lt;span style=&#34;color:#f92672&#34;&gt;or&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;success&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;微信在明文模式下的 POST 请求 URL 中仍然携带 &lt;code&gt;nonce&lt;/code&gt; 和 &lt;code&gt;timestamp&lt;/code&gt; 参数&lt;/strong&gt;（用于 URL 签名验证，不是加解密），所以条件 &lt;code&gt;nonce and timestamp&lt;/code&gt; 为真 → 执行加密 → 微信收到 &lt;code&gt;&amp;lt;Encrypt&amp;gt;&lt;/code&gt; 标签的密文 → 明文模式下无法解析 → 静默丢弃 → 用户永远看不到回复。&lt;/p&gt;
&lt;h2 id=&#34;修复&#34;&gt;修复&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;怎么做？&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;两层防护：&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;第一层&lt;/strong&gt;：明文模式分支中置空 nonce/timestamp：&lt;/p&gt;
&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;&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;not&lt;/span&gt; msg_signature:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    logger&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;info(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;明文模式，直接解析消息。&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    msg &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; parse_message(data&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;decode(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;utf-8&amp;#34;&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    nonce &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;None&lt;/span&gt;       &lt;span style=&#34;color:#75715e&#34;&gt;# ← 置空，跳过加密&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    timestamp &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;None&lt;/span&gt;   &lt;span style=&#34;color:#75715e&#34;&gt;# ← 置空，跳过加密&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;第二层&lt;/strong&gt;：增加类级别 &lt;code&gt;_is_encrypted&lt;/code&gt; 标志：&lt;/p&gt;</description>
    </item>
    
    <item>
      <title>长时间规划结束忘记 commit 丢失进度</title>
      <link>/pitfalls/pit-plan-lost-not-committed/</link>
      <pubDate>Sat, 13 Jun 2026 00:00:00 +0000</pubDate>
      
      <guid>/pitfalls/pit-plan-lost-not-committed/</guid>
      <description>&lt;h2 id=&#34;症状&#34;&gt;症状&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;你看到什么？&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;和 AI 协作做了一整套书籍架构规划（章节设计、字数分配、主题方向），会话正常结束。下次开工发现：规划文件没 commit，本地修改丢了（或被覆盖）。全部重来。&lt;/p&gt;
&lt;h2 id=&#34;根因&#34;&gt;根因&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;真正的原因是什么？&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;人的注意力在&amp;quot;思考规划内容&amp;quot;上，不在&amp;quot;保存规划结果&amp;quot;上。规划过程可能持续几十分钟到几小时，期间一直在输出和修改，但 &lt;code&gt;git commit&lt;/code&gt; 不在意识里。会话结束时，要么忘了 commit，要么会话异常退出导致未保存的修改丢失。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;本质：规划和保存是两个独立动作，大脑把&amp;quot;想完了&amp;quot;误认为&amp;quot;存好了&amp;quot;。&lt;/strong&gt;&lt;/p&gt;
&lt;h2 id=&#34;修复&#34;&gt;修复&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;具体怎么修的？&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;建立纪律：&lt;strong&gt;规划完成一个阶段 → 立刻 commit，10 秒的事。&lt;/strong&gt;&lt;/p&gt;
&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;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# 不要等到&amp;#34;全部做完&amp;#34;，每完成一个可独立交付的片段就：&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;git add projects/xxx.md
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;git commit -m &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;docs: xxx 架构初版完成——章节+字数分配&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;具体到 AI 协作场景：让 AI 在每次完成阶段性规划后主动 commit，不等人提醒。&lt;/p&gt;
&lt;h2 id=&#34;怎么避免&#34;&gt;怎么避免&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;下次怎么不踩？&lt;/p&gt;&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;铁律：规划做完立刻存仓库，不等会话结束&lt;/strong&gt;（已写入 &lt;code&gt;~/claude-memory/global/feedback/plan-must-commit-immediately.md&lt;/code&gt;）&lt;/li&gt;
&lt;li&gt;AI 协作时，要求 AI 主动 commit，不允许&amp;quot;等会话结束时再存&amp;quot;&lt;/li&gt;
&lt;li&gt;每完成一个可独立交付的片段就 commit，把 commit 当保存键用&lt;/li&gt;
&lt;/ul&gt;</description>
    </item>
    
  </channel>
</rss>
