<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>iwmei的博客</title><link>https://iwmei.top/</link><description>Recent content on iwmei的博客</description><generator>Hugo -- gohugo.io</generator><language>zh-cn</language><copyright>iwmei</copyright><lastBuildDate>Wed, 06 May 2026 00:00:00 +0000</lastBuildDate><atom:link href="https://iwmei.top/index.xml" rel="self" type="application/rss+xml"/><item><title>BilibiliContentFetcher 项目复盘：从单条演示到批处理闭环</title><link>https://iwmei.top/p/bilibilicontentfetcher-from-single-demo-to-batch-workflow/</link><pubDate>Wed, 06 May 2026 00:00:00 +0000</pubDate><guid>https://iwmei.top/p/bilibilicontentfetcher-from-single-demo-to-batch-workflow/</guid><description>&lt;img src="https://iwmei.top/p/bilibilicontentfetcher-from-single-demo-to-batch-workflow/cover.png" alt="Featured image of post BilibiliContentFetcher 项目复盘：从单条演示到批处理闭环" />&lt;p>这次复盘记录的是 &lt;code>BilibiliContentFetcher&lt;/code> 一次完整落地过程。&lt;/p>
&lt;p>我这次的目标不是做一条能看的演示链路，而是把批量生产链路做稳定，把输出质量做可控，把项目结构做可维护，把最终产物直接落到 Obsidian。&lt;/p>
&lt;p>我按真实时间线展开，尽量保留全过程细节。&lt;/p>
&lt;h2 id="1-起点目标">1. 起点目标
&lt;/h2>&lt;p>我在会话开始阶段先把目标重新收敛，避免中途跑偏。&lt;/p>
&lt;p>当时我给自己定了六个硬条件。&lt;/p>
&lt;ol>
&lt;li>主目标是批量稳定执行，不是单条效果展示。&lt;/li>
&lt;li>输出格式必须严格贴合根目录 &lt;code>Tempate.md&lt;/code>。&lt;/li>
&lt;li>必须使用 DeepSeek 思考模式，不接受本地替代。&lt;/li>
&lt;li>模块结构与链路逻辑要对齐 &lt;code>XHSContentFetcher&lt;/code>。&lt;/li>
&lt;li>最终笔记必须可直接出现在 Obsidian。&lt;/li>
&lt;li>最终代码要推送远程，并补全 CLI 命令文档。&lt;/li>
&lt;/ol>
&lt;p>这一组条件决定了后续所有取舍。&lt;/p>
&lt;h2 id="2-阶段-a">2. 阶段 A
&lt;/h2>&lt;p>这个阶段是质量回归和模板约束加固，时间段是 18 点 20 到 18 点 33。&lt;/p>
&lt;p>我先执行回归测试，确认基线可跑。&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-powershell" data-lang="powershell">&lt;span class="line">&lt;span class="cl">&lt;span class="n">pytest&lt;/span> &lt;span class="n">-q&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>结果是 &lt;code>5 passed&lt;/code>。&lt;/p>
&lt;p>这一步给了我一个清晰信号，当前代码有可用基础，但输出质量不够。&lt;/p>
&lt;p>我随后集中处理了四类问题。&lt;/p>
&lt;ol>
&lt;li>文本里有泛化表达，观点和结论过于笼统。&lt;/li>
&lt;li>有占位风格残留，章节质感不稳定。&lt;/li>
&lt;li>评论区覆盖不足，子评论利用率偏低。&lt;/li>
&lt;li>视频类笔记有明显模板痕迹。&lt;/li>
&lt;/ol>
&lt;h3 id="21-质量约束改造">2.1 质量约束改造
&lt;/h3>&lt;p>我在 &lt;code>src/bili_content_fetcher/ai_writer.py&lt;/code> 里加了完整质量栅栏。&lt;/p>
&lt;p>关键函数是：&lt;/p>
&lt;ul>
&lt;li>&lt;code>_validate_markdown_output&lt;/code>&lt;/li>
&lt;li>&lt;code>_repair_markdown_once&lt;/code>&lt;/li>
&lt;li>&lt;code>_ensure_quality&lt;/code>&lt;/li>
&lt;/ul>
&lt;p>这三步形成了质量闭环。&lt;/p>
&lt;ol>
&lt;li>先检查结构完整性。&lt;/li>
&lt;li>再执行自动修订。&lt;/li>
&lt;li>最后做二轮兜底，不通过就回退。&lt;/li>
&lt;/ol>
&lt;p>我把检查项写得很细，包含章节顺序、占位词、概念数量、问题数量、评论数量、图片内联要求。&lt;/p>
&lt;h3 id="22-评论区典型性改造">2.2 评论区典型性改造
&lt;/h3>&lt;p>我同时补了评论评分和代表性筛选。&lt;/p>
&lt;p>对应新增逻辑：&lt;/p>
&lt;ul>
&lt;li>&lt;code>_comment_score&lt;/code>&lt;/li>
&lt;li>&lt;code>_select_representative_comments&lt;/code>&lt;/li>
&lt;li>&lt;code>_comment_insight&lt;/code>&lt;/li>
&lt;/ul>
&lt;p>这组改动让评论区从堆数据变成可读观点层。&lt;/p>
&lt;p>我要求每条代表评论都要有我的提炼句，不再只贴原文。&lt;/p>
&lt;h3 id="23-阶段-a-实跑">2.3 阶段 A 实跑
&lt;/h3>&lt;p>我用单条链接做了一次实跑。&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-powershell" data-lang="powershell">&lt;span class="line">&lt;span class="cl">&lt;span class="nb">bili-note&lt;/span> &lt;span class="n">run&lt;/span> &lt;span class="n">https&lt;/span>&lt;span class="err">:&lt;/span>&lt;span class="p">//&lt;/span>&lt;span class="n">www&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="py">bilibili&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">com&lt;/span>&lt;span class="p">/&lt;/span>&lt;span class="n">opus&lt;/span>&lt;span class="p">/&lt;/span>&lt;span class="mf">1195483269038080034&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>结果是新笔记目录生成成功，结构可用，基础质量明显提升。&lt;/p>
&lt;h2 id="3-阶段-b">3. 阶段 B
&lt;/h2>&lt;p>这个阶段是切到 DeepSeek 真链路，时间段是 18 点 33 到 18 点 36。&lt;/p>
&lt;p>问题不是代码逻辑，而是配置状态。&lt;/p>
&lt;h3 id="31-deepseek-key-缺失">3.1 DeepSeek Key 缺失
&lt;/h3>&lt;p>我检查后确认当前项目没有可用 Key。&lt;/p>
&lt;ol>
&lt;li>项目 &lt;code>.env&lt;/code> 缺失。&lt;/li>
&lt;li>环境变量 &lt;code>DEEPSEEK_API_KEY&lt;/code> 为空。&lt;/li>
&lt;/ol>
&lt;p>我的处理方式是从 &lt;code>XHSContentFetcher&lt;/code> 读取可用配置，再写入当前项目 &lt;code>.env&lt;/code>。&lt;/p>
&lt;h3 id="32-vault-路径空值误解析">3.2 Vault 路径空值误解析
&lt;/h3>&lt;p>我还遇到了一个配置细节问题。&lt;/p>
&lt;p>&lt;code>OBSIDIAN_VAULT_PATH=&lt;/code> 空值被解析为当前目录，&lt;code>bili-note check&lt;/code> 显示默认 Vault 指向点目录。&lt;/p>
&lt;p>我删除了空值行，恢复为未配置状态，避免误写路径。&lt;/p>
&lt;h3 id="33-deepseek-真链路验证">3.3 DeepSeek 真链路验证
&lt;/h3>&lt;p>我重新执行带 DeepSeek 配置的运行命令。&lt;/p>
&lt;p>结果是模型链路跑通，真实生成成功。&lt;/p>
&lt;p>这个节点很关键，说明我已经从本地降级模式切回目标模式。&lt;/p>
&lt;h2 id="4-阶段-c">4. 阶段 C
&lt;/h2>&lt;p>这个阶段是方向纠偏，时间段是 18 点 36 到 18 点 56。&lt;/p>
&lt;p>核心变化只有一句话，批量优先替代单条打磨。&lt;/p>
&lt;p>我在这个阶段做了三件大事。&lt;/p>
&lt;ol>
&lt;li>新增批处理子命令。&lt;/li>
&lt;li>处理 Windows 编码崩溃。&lt;/li>
&lt;li>落地批处理汇总产物。&lt;/li>
&lt;/ol>
&lt;h3 id="41-批处理子命令落地">4.1 批处理子命令落地
&lt;/h3>&lt;p>我在 &lt;code>src/bili_content_fetcher/cli.py&lt;/code> 加了 &lt;code>batch&lt;/code> 子命令体系。&lt;/p>
&lt;p>支持参数包含：&lt;/p>
&lt;ul>
&lt;li>&lt;code>--max-items&lt;/code>&lt;/li>
&lt;li>&lt;code>--fail-fast&lt;/code>&lt;/li>
&lt;/ul>
&lt;p>并新增批处理汇总文件机制，输出 &lt;code>batch_summary_*.json&lt;/code>。&lt;/p>
&lt;p>我同时同步改了 &lt;code>README.md&lt;/code>，保证命令文档可直接执行。&lt;/p>
&lt;h3 id="42-windows-编码崩溃修复">4.2 Windows 编码崩溃修复
&lt;/h3>&lt;p>这一步是阶段 C 的关键故障。&lt;/p>
&lt;p>我当时遇到错误：&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-text" data-lang="text">&lt;span class="line">&lt;span class="cl">UnicodeEncodeError: &amp;#39;gbk&amp;#39; codec can&amp;#39;t encode character &amp;#39;\ufeff&amp;#39;
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>触发点是批量输入文件首行 BOM 加上控制台输出编码冲突。&lt;/p>
&lt;p>我按三步修复。&lt;/p>
&lt;ol>
&lt;li>&lt;code>_load_batch_inputs&lt;/code> 改成 &lt;code>utf-8-sig&lt;/code> 读取。&lt;/li>
&lt;li>输入行统一剥离 &lt;code>\ufeff&lt;/code> 前缀。&lt;/li>
&lt;li>控制台输出前做安全预览过滤，剔除不可编码字符。&lt;/li>
&lt;/ol>
&lt;p>修完后我马上复跑批量命令。&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-powershell" data-lang="powershell">&lt;span class="line">&lt;span class="cl">&lt;span class="nb">bili-note&lt;/span> &lt;span class="n">batch&lt;/span> &lt;span class="n">batch_links&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="py">txt&lt;/span> &lt;span class="p">-&lt;/span>&lt;span class="n">-max-items&lt;/span> &lt;span class="mf">2&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>结果是 &lt;code>2/2&lt;/code> 成功。&lt;/p>
&lt;p>并产出汇总文件：&lt;/p>
&lt;p>&lt;code>output/batch_summary_20260506_185559.json&lt;/code>&lt;/p>
&lt;h2 id="5-阶段-d">5. 阶段 D
&lt;/h2>&lt;p>这个阶段是视频笔记质量二次修复，时间段是 18 点 56 到 19 点 02。&lt;/p>
&lt;h3 id="51-英文噪声词进入概念区">5.1 英文噪声词进入概念区
&lt;/h3>&lt;p>我发现视频类笔记的概念区混入了 &lt;code>and&lt;/code> &lt;code>the&lt;/code> &lt;code>add&lt;/code> &lt;code>no&lt;/code> 这类词。&lt;/p>
&lt;p>这是明显质量缺陷。&lt;/p>
&lt;p>我做了三项补丁。&lt;/p>
&lt;ol>
&lt;li>增加英文停用词 &lt;code>EN_STOPWORDS&lt;/code>。&lt;/li>
&lt;li>增加英文术语白名单 &lt;code>EN_TERM_ALLOWLIST&lt;/code>。&lt;/li>
&lt;li>非股票场景的问题标题改成稳定框架，避免弱标题漂移。&lt;/li>
&lt;/ol>
&lt;h3 id="52-模型结果被回退过度覆盖">5.2 模型结果被回退过度覆盖
&lt;/h3>&lt;p>我还发现质量修订链有副作用。&lt;/p>
&lt;p>多轮修订后，较好的模型版本有时会被过度回退。&lt;/p>
&lt;p>我在 &lt;code>_ensure_quality&lt;/code> 里加了保留策略。&lt;/p>
&lt;p>当结构可用且占位残留已清空时，优先保留最后模型版本。&lt;/p>
&lt;p>这一步直接改善了成文自然度。&lt;/p>
&lt;h3 id="53-阶段-d-复跑">5.3 阶段 D 复跑
&lt;/h3>&lt;p>我用视频批处理单条做复验。&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-powershell" data-lang="powershell">&lt;span class="line">&lt;span class="cl">&lt;span class="nb">bili-note&lt;/span> &lt;span class="n">batch&lt;/span> &lt;span class="n">batch_video_only&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="py">txt&lt;/span> &lt;span class="p">-&lt;/span>&lt;span class="n">-max-items&lt;/span> &lt;span class="mf">1&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>结果是视频学习报告稳定生成，英文噪声问题消失。&lt;/p>
&lt;h2 id="6-阶段-e">6. 阶段 E
&lt;/h2>&lt;p>这个阶段是大改造，时间段是 19 点 02 到 19 点 28。&lt;/p>
&lt;p>目标很明确，把 Bili 项目和 XHS 项目做同构对齐。&lt;/p>
&lt;h3 id="61-同构基线">6.1 同构基线
&lt;/h3>&lt;p>我先对齐目标模块清单：&lt;/p>
&lt;ul>
&lt;li>cli&lt;/li>
&lt;li>config&lt;/li>
&lt;li>workflow&lt;/li>
&lt;li>fetcher&lt;/li>
&lt;li>media&lt;/li>
&lt;li>video_tools&lt;/li>
&lt;li>deepseek&lt;/li>
&lt;li>markdown_writer&lt;/li>
&lt;li>obsidian&lt;/li>
&lt;li>url_parser&lt;/li>
&lt;li>ocr_engine&lt;/li>
&lt;/ul>
&lt;h3 id="62-新增模块">6.2 新增模块
&lt;/h3>&lt;p>我新增了以下文件。&lt;/p>
&lt;ol>
&lt;li>&lt;code>src/bili_content_fetcher/url_parser.py&lt;/code>&lt;/li>
&lt;li>&lt;code>src/bili_content_fetcher/fetcher.py&lt;/code>&lt;/li>
&lt;li>&lt;code>src/bili_content_fetcher/media.py&lt;/code>&lt;/li>
&lt;li>&lt;code>src/bili_content_fetcher/video_tools.py&lt;/code>&lt;/li>
&lt;li>&lt;code>src/bili_content_fetcher/ocr_engine.py&lt;/code>&lt;/li>
&lt;li>&lt;code>src/bili_content_fetcher/deepseek.py&lt;/code>&lt;/li>
&lt;li>&lt;code>src/bili_content_fetcher/markdown_writer.py&lt;/code>&lt;/li>
&lt;li>&lt;code>src/bili_content_fetcher/obsidian.py&lt;/code>&lt;/li>
&lt;li>&lt;code>src/bili_content_fetcher/workflow.py&lt;/code>&lt;/li>
&lt;/ol>
&lt;h3 id="63-重构模块">6.3 重构模块
&lt;/h3>&lt;p>我重点重构了两个文件。&lt;/p>
&lt;ol>
&lt;li>&lt;code>config.py&lt;/code>
&lt;ul>
&lt;li>增加本地配置文件 &lt;code>~/.bili-content-fetcher/config.json&lt;/code>&lt;/li>
&lt;li>保留 &lt;code>.env&lt;/code> 兼容链路，兼容历史配置&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>&lt;code>cli.py&lt;/code>
&lt;ul>
&lt;li>从 Typer 切到 &lt;code>argparse&lt;/code>&lt;/li>
&lt;li>统一成与 XHS 对齐的 &lt;code>run&lt;/code> &lt;code>config&lt;/code> &lt;code>batch&lt;/code> 命令体系&lt;/li>
&lt;/ul>
&lt;/li>
&lt;/ol>
&lt;h3 id="64-文档和入口">6.4 文档和入口
&lt;/h3>&lt;p>我同步重写：&lt;/p>
&lt;ol>
&lt;li>&lt;code>README.md&lt;/code>&lt;/li>
&lt;li>&lt;code>pyproject.toml&lt;/code> 脚本入口，改为 &lt;code>bili_content_fetcher.cli:main&lt;/code>&lt;/li>
&lt;/ol>
&lt;h3 id="65-阶段-e-验收">6.5 阶段 E 验收
&lt;/h3>&lt;p>我执行整套验收。&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;span class="lnt">3
&lt;/span>&lt;span class="lnt">4
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-powershell" data-lang="powershell">&lt;span class="line">&lt;span class="cl">&lt;span class="n">pytest&lt;/span> &lt;span class="n">-q&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">python&lt;/span> &lt;span class="n">-m&lt;/span> &lt;span class="n">bili_content_fetcher&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nb">cli &lt;/span>&lt;span class="p">-&lt;/span>&lt;span class="n">-help&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">python&lt;/span> &lt;span class="n">-m&lt;/span> &lt;span class="n">bili_content_fetcher&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nb">cli &lt;/span>&lt;span class="n">run&lt;/span> &lt;span class="p">-&lt;/span>&lt;span class="n">-help&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">python&lt;/span> &lt;span class="n">-m&lt;/span> &lt;span class="n">bili_content_fetcher&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nb">cli &lt;/span>&lt;span class="n">batch&lt;/span> &lt;span class="p">-&lt;/span>&lt;span class="n">-help&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>结果：&lt;/p>
&lt;ol>
&lt;li>&lt;code>pytest -q&lt;/code> 变为 &lt;code>8 passed&lt;/code>&lt;/li>
&lt;li>CLI 帮助命令全部可用&lt;/li>
&lt;/ol>
&lt;p>随后我提交并推送。&lt;/p>
&lt;ul>
&lt;li>commit &lt;code>03ac851&lt;/code>&lt;/li>
&lt;li>message &lt;code>feat: align bili workflow with xhs architecture and add full batch CLI&lt;/code>&lt;/li>
&lt;li>push &lt;code>origin/main&lt;/code> 成功&lt;/li>
&lt;/ul>
&lt;h2 id="7-阶段-f">7. 阶段 F
&lt;/h2>&lt;p>这个阶段是最终验收，时间点约 20 点 02。&lt;/p>
&lt;p>目标只有一个，Obsidian 可见。&lt;/p>
&lt;p>我执行命令：&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-powershell" data-lang="powershell">&lt;span class="line">&lt;span class="cl">&lt;span class="n">python&lt;/span> &lt;span class="n">-m&lt;/span> &lt;span class="n">bili_content_fetcher&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nb">cli &lt;/span>&lt;span class="n">run&lt;/span> &lt;span class="s2">&amp;#34;&amp;lt;opus链接&amp;gt;&amp;#34;&lt;/span> &lt;span class="p">-&lt;/span>&lt;span class="n">-vault-dir&lt;/span> &lt;span class="s2">&amp;#34;C:\Users\yourp\Documents\Obsidian Vault&amp;#34;&lt;/span> &lt;span class="p">-&lt;/span>&lt;span class="n">-notes-folder&lt;/span> &lt;span class="s2">&amp;#34;BiliNotes&amp;#34;&lt;/span> &lt;span class="p">-&lt;/span>&lt;span class="n">-open-obsidian&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>验收结果：&lt;/p>
&lt;ol>
&lt;li>DeepSeek 生成成功&lt;/li>
&lt;li>图片 7&lt;/li>
&lt;li>评论 18&lt;/li>
&lt;li>OCR 7&lt;/li>
&lt;li>笔记写入 Vault 成功&lt;/li>
&lt;li>Obsidian 可直接查看&lt;/li>
&lt;/ol>
&lt;p>本次验收产物路径：&lt;/p>
&lt;p>&lt;code>C:\Users\yourp\Documents\Obsidian Vault\BiliNotes\ru-he-zai-5000jia-gu-piao-zhong-shai-xuan-chu-long-tou-gu-bi-li-bi-li\ru-he-zai-5000jia-gu-piao-zhong-shai-xuan-chu-long-tou-gu-bi-li-bi-li.md&lt;/code>&lt;/p>
&lt;h2 id="8-问题清单汇总">8. 问题清单汇总
&lt;/h2>&lt;p>我把全过程问题收敛成七类。&lt;/p>
&lt;ol>
&lt;li>笔记里有占位和模板痕迹。&lt;/li>
&lt;li>评论区代表性不足，回复利用不足。&lt;/li>
&lt;li>项目缺 DeepSeek 配置。&lt;/li>
&lt;li>批处理不是主链路。&lt;/li>
&lt;li>Windows BOM 和编码导致批处理崩溃。&lt;/li>
&lt;li>视频笔记出现英文噪声概念。&lt;/li>
&lt;li>项目结构和 XHS 不一致。&lt;/li>
&lt;/ol>
&lt;p>对应修复策略分别是：&lt;/p>
&lt;ol>
&lt;li>质量校验加自动重写加密度约束。&lt;/li>
&lt;li>评论评分筛选加逐条提炼。&lt;/li>
&lt;li>&lt;code>.env&lt;/code> 补齐加 CLI 缺 Key 明确报错。&lt;/li>
&lt;li>&lt;code>batch&lt;/code> 子命令加失败续跑和汇总。&lt;/li>
&lt;li>&lt;code>utf-8-sig&lt;/code> 加 BOM 剥离加安全输出。&lt;/li>
&lt;li>停用词加白名单加标题稳态框架。&lt;/li>
&lt;li>同构重构模块加统一 CLI 和配置体系。&lt;/li>
&lt;/ol>
&lt;h2 id="9-关键命令流水">9. 关键命令流水
&lt;/h2>&lt;h3 id="91-质量回归">9.1 质量回归
&lt;/h3>&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-powershell" data-lang="powershell">&lt;span class="line">&lt;span class="cl">&lt;span class="n">pytest&lt;/span> &lt;span class="n">-q&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;h3 id="92-单条链路">9.2 单条链路
&lt;/h3>&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-powershell" data-lang="powershell">&lt;span class="line">&lt;span class="cl">&lt;span class="nb">bili-note&lt;/span> &lt;span class="n">run&lt;/span> &lt;span class="s2">&amp;#34;&amp;lt;链接&amp;gt;&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">python&lt;/span> &lt;span class="n">-m&lt;/span> &lt;span class="n">bili_content_fetcher&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nb">cli &lt;/span>&lt;span class="n">run&lt;/span> &lt;span class="s2">&amp;#34;&amp;lt;链接&amp;gt;&amp;#34;&lt;/span> &lt;span class="p">...&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;h3 id="93-批量链路">9.3 批量链路
&lt;/h3>&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-powershell" data-lang="powershell">&lt;span class="line">&lt;span class="cl">&lt;span class="nb">bili-note&lt;/span> &lt;span class="n">batch&lt;/span> &lt;span class="n">links&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="py">txt&lt;/span> &lt;span class="p">-&lt;/span>&lt;span class="n">-max-items&lt;/span> &lt;span class="mf">2&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">python&lt;/span> &lt;span class="n">-m&lt;/span> &lt;span class="n">bili_content_fetcher&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nb">cli &lt;/span>&lt;span class="n">batch&lt;/span> &lt;span class="n">links&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="py">txt&lt;/span> &lt;span class="p">-&lt;/span>&lt;span class="n">-max-items&lt;/span> &lt;span class="mf">1&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;h3 id="94-配置检查">9.4 配置检查
&lt;/h3>&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-powershell" data-lang="powershell">&lt;span class="line">&lt;span class="cl">&lt;span class="nb">bili-note&lt;/span> &lt;span class="n">check&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">python&lt;/span> &lt;span class="n">-m&lt;/span> &lt;span class="n">bili_content_fetcher&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nb">cli &lt;/span>&lt;span class="n">config&lt;/span> &lt;span class="n">show&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;h3 id="95-版本管理">9.5 版本管理
&lt;/h3>&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-powershell" data-lang="powershell">&lt;span class="line">&lt;span class="cl">&lt;span class="n">git&lt;/span> &lt;span class="n">commit&lt;/span> &lt;span class="n">-m&lt;/span> &lt;span class="s2">&amp;#34;...&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">git&lt;/span> &lt;span class="n">push&lt;/span> &lt;span class="n">origin&lt;/span> &lt;span class="n">main&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;h2 id="10-最终状态">10. 最终状态
&lt;/h2>&lt;p>我在导出时间点确认的状态如下。&lt;/p>
&lt;ol>
&lt;li>代码已提交并推送到远程主分支。&lt;/li>
&lt;li>CLI 的 &lt;code>run&lt;/code> &lt;code>batch&lt;/code> &lt;code>config&lt;/code> 全量可用。&lt;/li>
&lt;li>DeepSeek 真链路实跑通过。&lt;/li>
&lt;li>Obsidian 实跑可见笔记。&lt;/li>
&lt;li>测试状态 &lt;code>8 passed&lt;/code>。&lt;/li>
&lt;/ol>
&lt;h2 id="11-我这次最关键的决策">11. 我这次最关键的决策
&lt;/h2>&lt;p>第一，先把批处理链路立成主线，单条只做回归样本。&lt;/p>
&lt;p>第二，把输出质量做成程序约束，不靠模型临场发挥。&lt;/p>
&lt;p>第三，把项目结构和 XHS 同构，换来后续维护和迁移的确定性。&lt;/p>
&lt;h2 id="12-下一步计划">12. 下一步计划
&lt;/h2>&lt;p>下一步我会继续补三组能力。&lt;/p>
&lt;ol>
&lt;li>断点续跑，降低长任务重跑成本。&lt;/li>
&lt;li>OCR 和 LLM 缓存，降低重复计算成本。&lt;/li>
&lt;li>结构化日志，细化阶段耗时和错误分类。&lt;/li>
&lt;/ol>
&lt;p>这次项目的核心结果不是某一条笔记写得好看。&lt;/p>
&lt;p>真正的结果是我把一条从抓取到笔记落地的链路做成了可批量执行、可定位故障、可重复验收的工程系统。&lt;/p></description></item><item><title>XHSContentFetcher 项目复盘：从空仓到可发布 CLI</title><link>https://iwmei.top/p/xhscontentfetcher-from-empty-repo-to-publishable-cli/</link><pubDate>Tue, 05 May 2026 00:00:00 +0000</pubDate><guid>https://iwmei.top/p/xhscontentfetcher-from-empty-repo-to-publishable-cli/</guid><description>&lt;img src="https://iwmei.top/p/xhscontentfetcher-from-empty-repo-to-publishable-cli/cover.png" alt="Featured image of post XHSContentFetcher 项目复盘：从空仓到可发布 CLI" />&lt;p>这篇是我的全过程复盘，不是摘要版。重点是把“从空仓到可发布版本”的真实路径写清楚。&lt;/p>
&lt;p>我会尽量保留操作细节，包括：&lt;/p>
&lt;ul>
&lt;li>我执行过的关键命令&lt;/li>
&lt;li>我遇到的报错&lt;/li>
&lt;li>我如何定位&lt;/li>
&lt;li>我具体改了什么&lt;/li>
&lt;li>我怎么复测&lt;/li>
&lt;/ul>
&lt;p>文中所有 Cookie / API Key 都是脱敏表达，不写明文。&lt;/p>
&lt;hr>
&lt;h2 id="0-起点与约束">0. 起点与约束
&lt;/h2>&lt;h3 id="01-初始仓库状态">0.1 初始仓库状态
&lt;/h3>&lt;p>项目路径是：&lt;/p>
&lt;p>&lt;code>F:\College\Activ_CodeProjects\PycharmProjects\XHSContentFetcher&lt;/code>&lt;/p>
&lt;p>我一开始先看目录：&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-powershell" data-lang="powershell">&lt;span class="line">&lt;span class="cl">&lt;span class="nb">Get-ChildItem&lt;/span> &lt;span class="n">-Force&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nb">Get-ChildItem&lt;/span> &lt;span class="n">-Recurse&lt;/span> &lt;span class="o">-File&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>当时可见文件基本只有：&lt;/p>
&lt;ul>
&lt;li>&lt;code>计划.md&lt;/code>&lt;/li>
&lt;li>&lt;code>LICENSE&lt;/code>&lt;/li>
&lt;li>&lt;code>venv/&lt;/code>&lt;/li>
&lt;li>&lt;code>.idea/&lt;/code>&lt;/li>
&lt;/ul>
&lt;p>也就是说，业务代码几乎是 0。&lt;/p>
&lt;h3 id="02-我给自己写死的目标来自-计划md">0.2 我给自己写死的目标，来自 &lt;code>计划.md&lt;/code>
&lt;/h3>&lt;ol>
&lt;li>输入小红书分享链接，支持图文和视频。&lt;/li>
&lt;li>抓取正文、评论、图片 / 视频。&lt;/li>
&lt;li>图片 OCR。&lt;/li>
&lt;li>视频关键帧抽取。&lt;/li>
&lt;li>调 DeepSeek 生成可用于 Obsidian 的学习笔记。&lt;/li>
&lt;li>全部做成 CLI，不做 GUI。&lt;/li>
&lt;li>最终产物是“能直接进 Obsidian”的笔记和素材。&lt;/li>
&lt;/ol>
&lt;h3 id="03-现实条件">0.3 现实条件
&lt;/h3>&lt;ol>
&lt;li>我手里有一个参考仓库，但不确定有没有可复用代码。&lt;/li>
&lt;li>我有图文和视频两条测试链接。&lt;/li>
&lt;li>我有开发阶段所需 Cookie 和 DeepSeek Key，后续代码和文档全部脱敏。&lt;/li>
&lt;/ol>
&lt;hr>
&lt;h2 id="1-预研阶段先确认抓取链路可行">1. 预研阶段：先确认抓取链路可行
&lt;/h2>&lt;p>我没有上来就写框架。我先做了 5 个预研动作。&lt;/p>
&lt;h3 id="11-动作一确认项目现状">1.1 动作一：确认项目现状
&lt;/h3>&lt;p>执行：&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-powershell" data-lang="powershell">&lt;span class="line">&lt;span class="cl">&lt;span class="nb">Get-ChildItem&lt;/span> &lt;span class="n">-Force&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nb">Get-ChildItem&lt;/span> &lt;span class="n">-Recurse&lt;/span> &lt;span class="o">-File&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>结论：&lt;/p>
&lt;ol>
&lt;li>仓库本体几乎没有业务代码。&lt;/li>
&lt;li>这次必须从零搭。&lt;/li>
&lt;/ol>
&lt;h3 id="12-动作二完整读取计划">1.2 动作二：完整读取计划
&lt;/h3>&lt;p>执行：&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-powershell" data-lang="powershell">&lt;span class="line">&lt;span class="cl">&lt;span class="nb">Get-Content&lt;/span> &lt;span class="n">-Raw&lt;/span> &lt;span class="n">-Encoding&lt;/span> &lt;span class="n">UTF8&lt;/span> &lt;span class="n">计划&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nb">md
&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>结论：&lt;/p>
&lt;ol>
&lt;li>技术目标很清楚：抓取 + OCR + 大模型 + Obsidian。&lt;/li>
&lt;li>文风要求也清楚：去 AI 味、逻辑分点、自然表达。&lt;/li>
&lt;/ol>
&lt;h3 id="13-动作三核查参考仓库">1.3 动作三：核查参考仓库
&lt;/h3>&lt;p>执行：&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;span class="lnt">3
&lt;/span>&lt;span class="lnt">4
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-powershell" data-lang="powershell">&lt;span class="line">&lt;span class="cl">&lt;span class="n">git&lt;/span> &lt;span class="nb">ls-remote&lt;/span> &lt;span class="n">https&lt;/span>&lt;span class="err">:&lt;/span>&lt;span class="p">//&lt;/span>&lt;span class="n">github&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">com&lt;/span>&lt;span class="p">/&lt;/span>&lt;span class="n">yourpapayouknow&lt;/span>&lt;span class="p">/&lt;/span>&lt;span class="n">XHSContentFetcher&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="py">git&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">git&lt;/span> &lt;span class="n">clone&lt;/span> &lt;span class="n">https&lt;/span>&lt;span class="err">:&lt;/span>&lt;span class="p">//&lt;/span>&lt;span class="n">github&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">com&lt;/span>&lt;span class="p">/&lt;/span>&lt;span class="n">yourpapayouknow&lt;/span>&lt;span class="p">/&lt;/span>&lt;span class="n">XHSContentFetcher&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="py">git&lt;/span> &lt;span class="n">_ref_repo&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nb">Get-ChildItem&lt;/span> &lt;span class="n">-Force&lt;/span> &lt;span class="n">_ref_repo&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nb">Get-ChildItem&lt;/span> &lt;span class="n">-Recurse&lt;/span> &lt;span class="o">-File&lt;/span> &lt;span class="n">_ref_repo&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>发现：&lt;/p>
&lt;ol>
&lt;li>仓库只有 &lt;code>LICENSE&lt;/code>，无可复用实现。&lt;/li>
&lt;/ol>
&lt;p>决策：&lt;/p>
&lt;ol>
&lt;li>我不再依赖这个仓库，直接独立实现。&lt;/li>
&lt;/ol>
&lt;h3 id="14-动作四抓取库选型">1.4 动作四：抓取库选型
&lt;/h3>&lt;p>执行：&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-powershell" data-lang="powershell">&lt;span class="line">&lt;span class="cl">&lt;span class="n">pip&lt;/span> &lt;span class="n">index&lt;/span> &lt;span class="n">versions&lt;/span> &lt;span class="nb">xiaohongshu-cli&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">python&lt;/span> &lt;span class="n">-m&lt;/span> &lt;span class="n">pip&lt;/span> &lt;span class="n">download&lt;/span> &lt;span class="nb">xiaohongshu-cli&lt;/span>&lt;span class="p">==&lt;/span>&lt;span class="mf">0.6&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="py">4&lt;/span> &lt;span class="n">-d&lt;/span> &lt;span class="n">_vendor&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>我后续做了 wheel 解包和源码检查，重点看：&lt;/p>
&lt;ul>
&lt;li>&lt;code>xhs_cli/client.py&lt;/code>&lt;/li>
&lt;li>&lt;code>xhs_cli/client_mixins.py&lt;/code>&lt;/li>
&lt;li>&lt;code>xhs_cli/html_parser.py&lt;/code>&lt;/li>
&lt;li>&lt;code>xhs_cli/formatter.py&lt;/code>&lt;/li>
&lt;li>&lt;code>xhs_cli/cookies.py&lt;/code>&lt;/li>
&lt;/ul>
&lt;p>我确认到的能力：&lt;/p>
&lt;ol>
&lt;li>&lt;code>get_note_detail&lt;/code>&lt;/li>
&lt;li>&lt;code>get_comments / get_sub_comments&lt;/code>&lt;/li>
&lt;li>&lt;code>get_note_from_html&lt;/code>，用于 HTML 回退&lt;/li>
&lt;li>现成签名流程，我不用自己逆向签名&lt;/li>
&lt;/ol>
&lt;h3 id="15-动作五用真实-cookie--真实链接做最小验证">1.5 动作五：用真实 Cookie + 真实链接做最小验证
&lt;/h3>&lt;p>我写了临时脚本，直接调 &lt;code>XhsClient&lt;/code>，分别验证图文和视频。&lt;/p>
&lt;p>关键验证结果：&lt;/p>
&lt;ol>
&lt;li>图文 &lt;code>note_card&lt;/code> 里有 &lt;code>image_list&lt;/code>、&lt;code>desc&lt;/code>、&lt;code>interact_info&lt;/code>。&lt;/li>
&lt;li>视频 &lt;code>note_card.video.media.stream.h264&lt;/code> 能取到可下载流地址。&lt;/li>
&lt;li>评论接口能正常返回。&lt;/li>
&lt;/ol>
&lt;p>到这里我才进入工程实现阶段。&lt;/p>
&lt;hr>
&lt;h2 id="2-工程搭建阶段从-0-到可执行-cli">2. 工程搭建阶段：从 0 到可执行 CLI
&lt;/h2>&lt;h3 id="21-基础文件落地">2.1 基础文件落地
&lt;/h3>&lt;p>我先建了最小工程骨架：&lt;/p>
&lt;ol>
&lt;li>&lt;code>pyproject.toml&lt;/code>&lt;/li>
&lt;li>&lt;code>.gitignore&lt;/code>&lt;/li>
&lt;li>&lt;code>src/xhs_content_fetcher/__init__.py&lt;/code>&lt;/li>
&lt;li>&lt;code>README.md&lt;/code>，初版&lt;/li>
&lt;/ol>
&lt;h3 id="22-模块化拆分第一版">2.2 模块化拆分，第一版
&lt;/h3>&lt;p>我按职责拆成 12 个模块：&lt;/p>
&lt;ol>
&lt;li>&lt;code>config.py&lt;/code>：配置持久化 + Cookie 解析&lt;/li>
&lt;li>&lt;code>utils.py&lt;/code>：通用工具函数&lt;/li>
&lt;li>&lt;code>url_parser.py&lt;/code>：链接解析，包含重定向处理&lt;/li>
&lt;li>&lt;code>fetcher.py&lt;/code>：详情 / 评论抓取 + 评论排序&lt;/li>
&lt;li>&lt;code>media.py&lt;/code>：图片和视频下载&lt;/li>
&lt;li>&lt;code>video_tools.py&lt;/code>：ffmpeg 调用、降采样、抽帧&lt;/li>
&lt;li>&lt;code>ocr_engine.py&lt;/code>：PaddleOCR 封装&lt;/li>
&lt;li>&lt;code>deepseek.py&lt;/code>：模型输入构造与调用&lt;/li>
&lt;li>&lt;code>markdown_writer.py&lt;/code>：Markdown 产物写入&lt;/li>
&lt;li>&lt;code>obsidian.py&lt;/code>：打开 Obsidian&lt;/li>
&lt;li>&lt;code>workflow.py&lt;/code>：端到端编排&lt;/li>
&lt;li>&lt;code>cli.py&lt;/code>：命令入口&lt;/li>
&lt;/ol>
&lt;h3 id="23-初始测试">2.3 初始测试
&lt;/h3>&lt;p>我建了 3 个单测：&lt;/p>
&lt;ol>
&lt;li>URL 解析测试&lt;/li>
&lt;li>Cookie 解析测试&lt;/li>
&lt;li>评论排序测试&lt;/li>
&lt;/ol>
&lt;p>执行：&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-powershell" data-lang="powershell">&lt;span class="line">&lt;span class="cl">&lt;span class="n">venv&lt;/span>&lt;span class="p">\&lt;/span>&lt;span class="n">Scripts&lt;/span>&lt;span class="p">\&lt;/span>&lt;span class="n">python&lt;/span> &lt;span class="n">-m&lt;/span> &lt;span class="n">pytest&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>结果：&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-text" data-lang="text">&lt;span class="line">&lt;span class="cl">6 passed
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;hr>
&lt;h2 id="3-首轮端到端联调先跑通图文--视频主链路">3. 首轮端到端联调：先跑通图文 / 视频主链路
&lt;/h2>&lt;p>我先把变量收敛，避免 LLM 和 OCR 抢占排错注意力。&lt;/p>
&lt;p>执行示意：&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-powershell" data-lang="powershell">&lt;span class="line">&lt;span class="cl">&lt;span class="n">python&lt;/span> &lt;span class="n">-m&lt;/span> &lt;span class="n">xhs_content_fetcher&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nb">cli &lt;/span>&lt;span class="n">run&lt;/span> &lt;span class="s2">&amp;#34;&amp;lt;图文链接&amp;gt;&amp;#34;&lt;/span> &lt;span class="p">-&lt;/span>&lt;span class="n">-cookie&lt;/span> &lt;span class="s2">&amp;#34;&amp;lt;脱敏&amp;gt;&amp;#34;&lt;/span> &lt;span class="p">-&lt;/span>&lt;span class="n">-skip-llm&lt;/span> &lt;span class="p">-&lt;/span>&lt;span class="n">-skip-ocr&lt;/span> &lt;span class="p">-&lt;/span>&lt;span class="n">-output-root&lt;/span> &lt;span class="n">output&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">python&lt;/span> &lt;span class="n">-m&lt;/span> &lt;span class="n">xhs_content_fetcher&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nb">cli &lt;/span>&lt;span class="n">run&lt;/span> &lt;span class="s2">&amp;#34;&amp;lt;视频链接&amp;gt;&amp;#34;&lt;/span> &lt;span class="p">-&lt;/span>&lt;span class="n">-cookie&lt;/span> &lt;span class="s2">&amp;#34;&amp;lt;脱敏&amp;gt;&amp;#34;&lt;/span> &lt;span class="p">-&lt;/span>&lt;span class="n">-skip-llm&lt;/span> &lt;span class="p">-&lt;/span>&lt;span class="n">-skip-ocr&lt;/span> &lt;span class="p">-&lt;/span>&lt;span class="n">-output-root&lt;/span> &lt;span class="n">output&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;h3 id="31-第一个关键故障api-error-code--1">3.1 第一个关键故障：&lt;code>API error: {&amp;quot;code&amp;quot;: -1}&lt;/code>
&lt;/h3>&lt;p>图文链路首次运行报错：&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-text" data-lang="text">&lt;span class="line">&lt;span class="cl">[ERROR] API error: {&amp;#34;code&amp;#34;: -1, &amp;#34;success&amp;#34;: false}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;h3 id="32-我的定位路径">3.2 我的定位路径
&lt;/h3>&lt;p>我没有直接改代码，而是先拆开验证：&lt;/p>
&lt;ol>
&lt;li>&lt;code>get_note_detail&lt;/code> 单独调，成功。&lt;/li>
&lt;li>&lt;code>get_comments&lt;/code> 单独调，成功。&lt;/li>
&lt;li>失败集中在“抓子评论”阶段，部分 &lt;code>get_sub_comments&lt;/code> 偶发异常。&lt;/li>
&lt;/ol>
&lt;h3 id="33-修复动作">3.3 修复动作
&lt;/h3>&lt;p>我在 &lt;code>fetcher.py&lt;/code> 里改 &lt;code>_fetch_sub_comments&lt;/code>：&lt;/p>
&lt;ol>
&lt;li>改成单条容错。&lt;/li>
&lt;li>单条失败就跳过。&lt;/li>
&lt;li>不让局部失败中断主流程。&lt;/li>
&lt;/ol>
&lt;p>修复后复测：&lt;/p>
&lt;ul>
&lt;li>图文链路跑通。&lt;/li>
&lt;li>视频链路跑通。&lt;/li>
&lt;/ul>
&lt;p>关键产物验证：&lt;/p>
&lt;ol>
&lt;li>视频下载成功，文件是 &lt;code>video_raw.mp4&lt;/code>。&lt;/li>
&lt;li>关键帧抽取成功，默认抽取 8 帧。&lt;/li>
&lt;li>评论抓取成功。&lt;/li>
&lt;/ol>
&lt;hr>
&lt;h2 id="4-媒体与-ocr-深度修复这部分最耗时">4. 媒体与 OCR 深度修复：这部分最耗时
&lt;/h2>&lt;h3 id="41-图片输出成-bin">4.1 图片输出成 &lt;code>.bin&lt;/code>
&lt;/h3>&lt;p>现象：&lt;/p>
&lt;ol>
&lt;li>图片文件变成 &lt;code>image_01.bin&lt;/code>。&lt;/li>
&lt;li>Obsidian 预览和 OCR 都受到影响。&lt;/li>
&lt;/ol>
&lt;p>根因：&lt;/p>
&lt;ol>
&lt;li>部分 CDN 响应缺失可靠 &lt;code>content-type&lt;/code>。&lt;/li>
&lt;/ol>
&lt;p>修复：&lt;/p>
&lt;p>我在 &lt;code>media.py&lt;/code> 加了魔数检测和扩展名回退顺序：&lt;/p>
&lt;ol>
&lt;li>先看内容头，覆盖 JPEG / PNG / GIF / BMP / WEBP / AVIF&lt;/li>
&lt;li>再看 &lt;code>Content-Type&lt;/code>&lt;/li>
&lt;li>再看 URL 后缀&lt;/li>
&lt;li>最后才用 &lt;code>.bin&lt;/code>&lt;/li>
&lt;/ol>
&lt;p>结果：&lt;/p>
&lt;ol>
&lt;li>图片稳定输出为 &lt;code>.webp/.jpg/...&lt;/code>。&lt;/li>
&lt;/ol>
&lt;h3 id="42-ocr-初始化失败缺底层依赖">4.2 OCR 初始化失败：缺底层依赖
&lt;/h3>&lt;p>现象：&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-text" data-lang="text">&lt;span class="line">&lt;span class="cl">dependency &amp;#39;paddlepaddle&amp;#39; is not installed
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>处理：&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-powershell" data-lang="powershell">&lt;span class="line">&lt;span class="cl">&lt;span class="n">venv&lt;/span>&lt;span class="p">\&lt;/span>&lt;span class="n">Scripts&lt;/span>&lt;span class="p">\&lt;/span>&lt;span class="n">python&lt;/span> &lt;span class="n">-m&lt;/span> &lt;span class="n">pip&lt;/span> &lt;span class="n">install&lt;/span> &lt;span class="n">paddleocr&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">venv&lt;/span>&lt;span class="p">\&lt;/span>&lt;span class="n">Scripts&lt;/span>&lt;span class="p">\&lt;/span>&lt;span class="n">python&lt;/span> &lt;span class="n">-m&lt;/span> &lt;span class="n">pip&lt;/span> &lt;span class="n">install&lt;/span> &lt;span class="n">paddlepaddle&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;h3 id="43-paddleocr-参数兼容问题">4.3 PaddleOCR 参数兼容问题
&lt;/h3>&lt;p>我遇到两个典型兼容问题：&lt;/p>
&lt;ol>
&lt;li>某些版本不接受 &lt;code>show_log&lt;/code>。&lt;/li>
&lt;li>新版在 OCR 参数里带 &lt;code>cls=True&lt;/code> 时会抛 &lt;code>unexpected keyword&lt;/code>。&lt;/li>
&lt;/ol>
&lt;p>修复策略：&lt;/p>
&lt;ol>
&lt;li>初始化参数做多套回退。&lt;/li>
&lt;li>OCR 调用失败后回退到不带 &lt;code>cls&lt;/code> 的方式。&lt;/li>
&lt;/ol>
&lt;h3 id="44-onednn--mkldnn-兼容报错">4.4 oneDNN / MKLDNN 兼容报错
&lt;/h3>&lt;p>现象：&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-text" data-lang="text">&lt;span class="line">&lt;span class="cl">ConvertPirAttribute2RuntimeAttribute not support ...
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>修复：&lt;/p>
&lt;ol>
&lt;li>在 &lt;code>ocr_engine.py&lt;/code> 设置兼容环境变量，禁用问题路径。&lt;/li>
&lt;/ol>
&lt;h3 id="45-中文路径导致-invalid-argument">4.5 中文路径导致 &lt;code>Invalid argument&lt;/code>
&lt;/h3>&lt;p>现象：&lt;/p>
&lt;ol>
&lt;li>Paddle 在部分中文路径下读取文件失败。&lt;/li>
&lt;/ol>
&lt;p>修复：&lt;/p>
&lt;ol>
&lt;li>OCR 前先复制到临时 ASCII 路径。&lt;/li>
&lt;li>识别完成后映射回原文件名。&lt;/li>
&lt;/ol>
&lt;h3 id="46-ocr-文本污染">4.6 OCR 文本污染
&lt;/h3>&lt;p>现象：&lt;/p>
&lt;ol>
&lt;li>OCR 结果混入临时路径字符串。&lt;/li>
&lt;/ol>
&lt;p>修复：&lt;/p>
&lt;ol>
&lt;li>过滤 &lt;code>xhs_ocr_&lt;/code>、盘符路径、tmp 路径行。&lt;/li>
&lt;/ol>
&lt;p>结果：&lt;/p>
&lt;ol>
&lt;li>OCR 文本可直接进入笔记。&lt;/li>
&lt;/ol>
&lt;h3 id="47-ocr-超时不是功能失败">4.7 OCR 超时不是功能失败
&lt;/h3>&lt;p>我实际还遇到过一次“超时中断”。&lt;/p>
&lt;p>这次不是逻辑错误，而是首次全量 OCR 跑 8 张图时加载和推理时间偏长。&lt;/p>
&lt;p>我采取的动作：&lt;/p>
&lt;ol>
&lt;li>放宽命令超时窗口。&lt;/li>
&lt;li>完整跑到底，再判断是否存在真实异常。&lt;/li>
&lt;/ol>
&lt;hr>
&lt;h2 id="5-提示词迭代从复述改到可读笔记">5. 提示词迭代：从“复述”改到“可读笔记”
&lt;/h2>&lt;p>链路跑通后，我回看产物，发现三个硬问题：&lt;/p>
&lt;ol>
&lt;li>文本复述多，知识点拆解不够。&lt;/li>
&lt;li>图片堆在文末，不是图文并茂。&lt;/li>
&lt;li>口吻不像我的笔记。&lt;/li>
&lt;/ol>
&lt;h3 id="51-第一次改造强化提示词约束">5.1 第一次改造：强化提示词约束
&lt;/h3>&lt;p>我在 &lt;code>deepseek.py&lt;/code> 做了三层调整：&lt;/p>
&lt;ol>
&lt;li>固定第一人称口吻。&lt;/li>
&lt;li>解释优先，要求按“是什么 / 为什么 / 怎么用 / 边界误区”拆解。&lt;/li>
&lt;li>禁止教学腔、禁止空泛总结。&lt;/li>
&lt;/ol>
&lt;p>同时在 &lt;code>workflow.py&lt;/code> 把素材相对路径直接喂模型：&lt;/p>
&lt;ul>
&lt;li>&lt;code>assets/images/...&lt;/code>&lt;/li>
&lt;li>&lt;code>assets/frames/...&lt;/code>&lt;/li>
&lt;li>&lt;code>assets/video/...&lt;/code>&lt;/li>
&lt;/ul>
&lt;p>目的很明确：模型必须内联引用，不允许文末堆图。&lt;/p>
&lt;h3 id="52-第二次改造模板优先禁用硬编码骨架">5.2 第二次改造：模板优先，禁用硬编码骨架
&lt;/h3>&lt;p>我后续把策略改成“模板优先”：&lt;/p>
&lt;ol>
&lt;li>优先读取根目录 &lt;code>Tempate.md&lt;/code>。&lt;/li>
&lt;li>兼容 &lt;code>Template.md&lt;/code> / &lt;code>template.md&lt;/code>。&lt;/li>
&lt;li>找不到模板就报错，不再自动生成章节骨架。&lt;/li>
&lt;li>占位符替换真实路径：
&lt;ul>
&lt;li>&lt;code>assets.images[*].path&lt;/code>&lt;/li>
&lt;li>&lt;code>assets.video_frames[*].path&lt;/code>&lt;/li>
&lt;/ul>
&lt;/li>
&lt;/ol>
&lt;p>这一步的意义是：我把结构控制权从模型拿回到模板。&lt;/p>
&lt;hr>
&lt;h2 id="6-url-解析事故discoveryitemid">6. URL 解析事故：&lt;code>discovery/item/&amp;lt;id&amp;gt;&lt;/code>
&lt;/h2>&lt;h3 id="61-故障现象">6.1 故障现象
&lt;/h3>&lt;p>新链接进入后，全链路失败：&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-text" data-lang="text">&lt;span class="line">&lt;span class="cl">[ERROR] 帖子详情为空，无法提取 note_card。
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;h3 id="62-我的定位过程">6.2 我的定位过程
&lt;/h3>&lt;p>我先用独立脚本验证，确认：&lt;/p>
&lt;ol>
&lt;li>&lt;code>XhsClient.get_note_detail&lt;/code> 能拿到 &lt;code>items&lt;/code>。&lt;/li>
&lt;li>我自己的 &lt;code>url_parser&lt;/code> 把 &lt;code>note_id&lt;/code> 解析错了，取成了 &lt;code>item&lt;/code>。&lt;/li>
&lt;/ol>
&lt;h3 id="63-修复方案">6.3 修复方案
&lt;/h3>&lt;p>我在 &lt;code>url_parser.py&lt;/code> 做三点修复：&lt;/p>
&lt;ol>
&lt;li>优先匹配 24 位 ID-like 片段。&lt;/li>
&lt;li>特判 &lt;code>discovery/item/&amp;lt;id&amp;gt;&lt;/code>。&lt;/li>
&lt;li>保留 &lt;code>explore/&amp;lt;id&amp;gt;&lt;/code> 和 &lt;code>item/&amp;lt;id&amp;gt;&lt;/code> 兼容逻辑。&lt;/li>
&lt;/ol>
&lt;p>复测结果：&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-text" data-lang="text">&lt;span class="line">&lt;span class="cl">7 passed
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;hr>
&lt;h2 id="7-obsidian-对接联调命令可用但编码有坑">7. Obsidian 对接联调：命令可用，但编码有坑
&lt;/h2>&lt;h3 id="71-cli-可用性验证">7.1 CLI 可用性验证
&lt;/h3>&lt;p>执行：&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-powershell" data-lang="powershell">&lt;span class="line">&lt;span class="cl">&lt;span class="n">obsidian&lt;/span> &lt;span class="p">-&lt;/span>&lt;span class="n">-help&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">obsidian&lt;/span> &lt;span class="n">vaults&lt;/span> &lt;span class="n">verbose&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>我确认：&lt;/p>
&lt;ol>
&lt;li>Obsidian CLI 可用。&lt;/li>
&lt;li>Vault 路径能识别到，例如 &lt;code>C:\Users\yourp\Documents\Obsidian Vault&lt;/code>。&lt;/li>
&lt;/ol>
&lt;h3 id="72-真机写入--自动打开">7.2 真机写入 + 自动打开
&lt;/h3>&lt;p>执行示意：&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-powershell" data-lang="powershell">&lt;span class="line">&lt;span class="cl">&lt;span class="nb">xhs-fetch&lt;/span> &lt;span class="n">run&lt;/span> &lt;span class="s2">&amp;#34;&amp;lt;链接&amp;gt;&amp;#34;&lt;/span> &lt;span class="p">-&lt;/span>&lt;span class="n">-vault-dir&lt;/span> &lt;span class="s2">&amp;#34;C:\Users\...\Obsidian Vault&amp;#34;&lt;/span> &lt;span class="p">-&lt;/span>&lt;span class="n">-open-obsidian&lt;/span> &lt;span class="p">...&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>结果：&lt;/p>
&lt;ol>
&lt;li>笔记写入成功。&lt;/li>
&lt;li>自动打开成功。&lt;/li>
&lt;/ol>
&lt;h3 id="73-unicodedecodeerror-修复">7.3 &lt;code>UnicodeDecodeError&lt;/code> 修复
&lt;/h3>&lt;p>现象：&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-text" data-lang="text">&lt;span class="line">&lt;span class="cl">UnicodeDecodeError: &amp;#39;gbk&amp;#39; codec can&amp;#39;t decode ...
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>根因：&lt;/p>
&lt;ol>
&lt;li>&lt;code>subprocess&lt;/code> 捕获 Obsidian 输出时发生编码读流问题。&lt;/li>
&lt;/ol>
&lt;p>修复：&lt;/p>
&lt;ol>
&lt;li>&lt;code>obsidian.py&lt;/code> 把 &lt;code>stdout/stderr&lt;/code> 改成 &lt;code>DEVNULL&lt;/code>。&lt;/li>
&lt;/ol>
&lt;p>复测后恢复正常。&lt;/p>
&lt;hr>
&lt;h2 id="8-我做过的回归验证清单">8. 我做过的回归验证清单
&lt;/h2>&lt;p>我不是“跑通一次就结束”，而是按层回归：&lt;/p>
&lt;ol>
&lt;li>单测回归：&lt;code>venv\Scripts\python -m pytest&lt;/code>&lt;/li>
&lt;li>图文链路回归：&lt;code>--skip-llm --skip-ocr&lt;/code>&lt;/li>
&lt;li>视频链路回归：&lt;code>--skip-llm --skip-ocr&lt;/code>&lt;/li>
&lt;li>OCR 层验证：单图 + 全量图&lt;/li>
&lt;li>DeepSeek 全链路验证：含模型调用产出&lt;/li>
&lt;li>产物检查：笔记、图片、关键帧、视频、路径引用&lt;/li>
&lt;/ol>
&lt;p>期间我还做过环境检查：&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-powershell" data-lang="powershell">&lt;span class="line">&lt;span class="cl">&lt;span class="nb">Get-Command&lt;/span> &lt;span class="n">ffprobe&lt;/span> &lt;span class="n">-ErrorAction&lt;/span> &lt;span class="n">SilentlyContinue&lt;/span> &lt;span class="p">|&lt;/span> &lt;span class="nb">Select-Object&lt;/span> &lt;span class="n">-ExpandProperty&lt;/span> &lt;span class="n">Source&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nb">Get-Command&lt;/span> &lt;span class="n">ffmpeg&lt;/span> &lt;span class="n">-ErrorAction&lt;/span> &lt;span class="n">SilentlyContinue&lt;/span> &lt;span class="p">|&lt;/span> &lt;span class="nb">Select-Object&lt;/span> &lt;span class="n">-ExpandProperty&lt;/span> &lt;span class="n">Source&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>这样可以先排除本机 ffmpeg 工具链问题。&lt;/p>
&lt;hr>
&lt;h2 id="9-文档清理与发布">9. 文档、清理与发布
&lt;/h2>&lt;h3 id="91-清理动作">9.1 清理动作
&lt;/h3>&lt;p>我按交付要求清理：&lt;/p>
&lt;ol>
&lt;li>&lt;code>output/&lt;/code>&lt;/li>
&lt;li>&lt;code>tests/&lt;/code>&lt;/li>
&lt;li>&lt;code>.pytest_cache/&lt;/code>&lt;/li>
&lt;li>全部 &lt;code>__pycache__/&lt;/code>&lt;/li>
&lt;/ol>
&lt;p>保留：&lt;/p>
&lt;ol>
&lt;li>&lt;code>Tempate.md&lt;/code>，后续生成结构依赖它&lt;/li>
&lt;/ol>
&lt;h3 id="92-readme-重写范围">9.2 README 重写范围
&lt;/h3>&lt;p>我把 README 改成简体中文，覆盖：&lt;/p>
&lt;ol>
&lt;li>功能全览&lt;/li>
&lt;li>安装与依赖&lt;/li>
&lt;li>配置方式&lt;/li>
&lt;li>模板机制&lt;/li>
&lt;li>Obsidian 对接&lt;/li>
&lt;li>常见问题排错&lt;/li>
&lt;/ol>
&lt;h3 id="93-git-提交和推送">9.3 Git 提交和推送
&lt;/h3>&lt;p>我执行：&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;span class="lnt">3
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-powershell" data-lang="powershell">&lt;span class="line">&lt;span class="cl">&lt;span class="n">git&lt;/span> &lt;span class="n">add&lt;/span> &lt;span class="p">.&lt;/span>&lt;span class="py">gitignore&lt;/span> &lt;span class="n">README&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nb">md &lt;/span>&lt;span class="n">Tempate&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nb">md &lt;/span>&lt;span class="n">pyproject&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="py">toml&lt;/span> &lt;span class="n">src&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">git&lt;/span> &lt;span class="n">commit&lt;/span> &lt;span class="n">-m&lt;/span> &lt;span class="s2">&amp;#34;feat: implement end-to-end xhs fetcher with obsidian integration&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">git&lt;/span> &lt;span class="n">push&lt;/span> &lt;span class="n">origin&lt;/span> &lt;span class="n">main&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>结果：&lt;/p>
&lt;ol>
&lt;li>提交：&lt;code>13f8545&lt;/code>&lt;/li>
&lt;li>分支：&lt;code>main&lt;/code>&lt;/li>
&lt;li>远程推送成功&lt;/li>
&lt;/ol>
&lt;p>安全处理：&lt;/p>
&lt;ol>
&lt;li>含敏感信息的 &lt;code>计划.md&lt;/code> 保持未跟踪，不进仓库。&lt;/li>
&lt;/ol>
&lt;hr>
&lt;h2 id="10-本次产出的最终代码结构">10. 本次产出的最终代码结构
&lt;/h2>&lt;p>核心目录：&lt;/p>
&lt;ol>
&lt;li>&lt;code>src/xhs_content_fetcher/cli.py&lt;/code>&lt;/li>
&lt;li>&lt;code>src/xhs_content_fetcher/workflow.py&lt;/code>&lt;/li>
&lt;li>&lt;code>src/xhs_content_fetcher/fetcher.py&lt;/code>&lt;/li>
&lt;li>&lt;code>src/xhs_content_fetcher/media.py&lt;/code>&lt;/li>
&lt;li>&lt;code>src/xhs_content_fetcher/video_tools.py&lt;/code>&lt;/li>
&lt;li>&lt;code>src/xhs_content_fetcher/ocr_engine.py&lt;/code>&lt;/li>
&lt;li>&lt;code>src/xhs_content_fetcher/deepseek.py&lt;/code>&lt;/li>
&lt;li>&lt;code>src/xhs_content_fetcher/markdown_writer.py&lt;/code>&lt;/li>
&lt;li>&lt;code>src/xhs_content_fetcher/obsidian.py&lt;/code>&lt;/li>
&lt;li>&lt;code>src/xhs_content_fetcher/url_parser.py&lt;/code>&lt;/li>
&lt;li>&lt;code>src/xhs_content_fetcher/config.py&lt;/code>&lt;/li>
&lt;li>&lt;code>src/xhs_content_fetcher/utils.py&lt;/code>&lt;/li>
&lt;/ol>
&lt;p>工程文件：&lt;/p>
&lt;ol>
&lt;li>&lt;code>pyproject.toml&lt;/code>&lt;/li>
&lt;li>&lt;code>.gitignore&lt;/code>&lt;/li>
&lt;li>&lt;code>README.md&lt;/code>&lt;/li>
&lt;li>&lt;code>Tempate.md&lt;/code>&lt;/li>
&lt;/ol>
&lt;hr>
&lt;h2 id="11-关键报错与修复对照">11. 关键报错与修复对照
&lt;/h2>&lt;table>
&lt;thead>
&lt;tr>
&lt;th>阶段&lt;/th>
&lt;th>报错 / 问题&lt;/th>
&lt;th>根因&lt;/th>
&lt;th>修复&lt;/th>
&lt;/tr>
&lt;/thead>
&lt;tbody>
&lt;tr>
&lt;td>抓取&lt;/td>
&lt;td>&lt;code>API error: {&amp;quot;code&amp;quot;: -1}&lt;/code>&lt;/td>
&lt;td>子评论接口偶发失败&lt;/td>
&lt;td>子评论单条容错，不阻断主流程&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>媒体&lt;/td>
&lt;td>图片输出 &lt;code>.bin&lt;/code>&lt;/td>
&lt;td>CDN 响应类型不稳定&lt;/td>
&lt;td>魔数识别 + 多级扩展名回退&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>OCR&lt;/td>
&lt;td>&lt;code>paddlepaddle not installed&lt;/code>&lt;/td>
&lt;td>只装了 &lt;code>paddleocr&lt;/code>&lt;/td>
&lt;td>补装 &lt;code>paddlepaddle&lt;/code>&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>OCR&lt;/td>
&lt;td>参数不兼容&lt;/td>
&lt;td>PaddleOCR 版本差异&lt;/td>
&lt;td>初始化 / 调用参数回退&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>OCR&lt;/td>
&lt;td>oneDNN 报错&lt;/td>
&lt;td>后端兼容问题&lt;/td>
&lt;td>兼容环境变量兜底&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>OCR&lt;/td>
&lt;td>&lt;code>Invalid argument&lt;/code>&lt;/td>
&lt;td>中文路径读取问题&lt;/td>
&lt;td>临时 ASCII 路径识别&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>解析&lt;/td>
&lt;td>&lt;code>note_id&lt;/code> 被解析为 &lt;code>item&lt;/code>&lt;/td>
&lt;td>URL 规则覆盖不足&lt;/td>
&lt;td>修复 &lt;code>discovery/item/&amp;lt;id&amp;gt;&lt;/code> 解析&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>Obsidian&lt;/td>
&lt;td>&lt;code>UnicodeDecodeError&lt;/code>&lt;/td>
&lt;td>子进程输出编码冲突&lt;/td>
&lt;td>&lt;code>stdout/stderr -&amp;gt; DEVNULL&lt;/code>&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;/table>
&lt;hr>
&lt;h2 id="12-命令流水节选">12. 命令流水节选
&lt;/h2>&lt;p>下面这组命令是我这次会话里反复执行的关键路径，按用途分组：&lt;/p>
&lt;h3 id="121-目录与文件检查">12.1 目录与文件检查
&lt;/h3>&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;span class="lnt">3
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-powershell" data-lang="powershell">&lt;span class="line">&lt;span class="cl">&lt;span class="nb">Get-ChildItem&lt;/span> &lt;span class="n">-Force&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nb">Get-ChildItem&lt;/span> &lt;span class="n">-Recurse&lt;/span> &lt;span class="o">-File&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nb">Get-Content&lt;/span> &lt;span class="n">-Raw&lt;/span> &lt;span class="n">-Encoding&lt;/span> &lt;span class="n">UTF8&lt;/span> &lt;span class="n">计划&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nb">md
&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;h3 id="122-抓取依赖验证">12.2 抓取依赖验证
&lt;/h3>&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;span class="lnt">3
&lt;/span>&lt;span class="lnt">4
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-powershell" data-lang="powershell">&lt;span class="line">&lt;span class="cl">&lt;span class="n">git&lt;/span> &lt;span class="nb">ls-remote&lt;/span> &lt;span class="n">https&lt;/span>&lt;span class="err">:&lt;/span>&lt;span class="p">//&lt;/span>&lt;span class="n">github&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">com&lt;/span>&lt;span class="p">/&lt;/span>&lt;span class="n">yourpapayouknow&lt;/span>&lt;span class="p">/&lt;/span>&lt;span class="n">XHSContentFetcher&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="py">git&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">git&lt;/span> &lt;span class="n">clone&lt;/span> &lt;span class="n">https&lt;/span>&lt;span class="err">:&lt;/span>&lt;span class="p">//&lt;/span>&lt;span class="n">github&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">com&lt;/span>&lt;span class="p">/&lt;/span>&lt;span class="n">yourpapayouknow&lt;/span>&lt;span class="p">/&lt;/span>&lt;span class="n">XHSContentFetcher&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="py">git&lt;/span> &lt;span class="n">_ref_repo&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">pip&lt;/span> &lt;span class="n">index&lt;/span> &lt;span class="n">versions&lt;/span> &lt;span class="nb">xiaohongshu-cli&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">python&lt;/span> &lt;span class="n">-m&lt;/span> &lt;span class="n">pip&lt;/span> &lt;span class="n">download&lt;/span> &lt;span class="nb">xiaohongshu-cli&lt;/span>&lt;span class="p">==&lt;/span>&lt;span class="mf">0.6&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="py">4&lt;/span> &lt;span class="n">-d&lt;/span> &lt;span class="n">_vendor&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;h3 id="123-本地构建与测试">12.3 本地构建与测试
&lt;/h3>&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;span class="lnt">3
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-powershell" data-lang="powershell">&lt;span class="line">&lt;span class="cl">&lt;span class="n">venv&lt;/span>&lt;span class="p">\&lt;/span>&lt;span class="n">Scripts&lt;/span>&lt;span class="p">\&lt;/span>&lt;span class="n">python&lt;/span> &lt;span class="n">-m&lt;/span> &lt;span class="n">pip&lt;/span> &lt;span class="n">install&lt;/span> &lt;span class="n">-e&lt;/span> &lt;span class="p">.&lt;/span> &lt;span class="n">pytest&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">venv&lt;/span>&lt;span class="p">\&lt;/span>&lt;span class="n">Scripts&lt;/span>&lt;span class="p">\&lt;/span>&lt;span class="n">python&lt;/span> &lt;span class="n">-m&lt;/span> &lt;span class="n">xhs_content_fetcher&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nb">cli &lt;/span>&lt;span class="p">-&lt;/span>&lt;span class="n">-help&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">venv&lt;/span>&lt;span class="p">\&lt;/span>&lt;span class="n">Scripts&lt;/span>&lt;span class="p">\&lt;/span>&lt;span class="n">python&lt;/span> &lt;span class="n">-m&lt;/span> &lt;span class="n">pytest&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;h3 id="124-图文--视频端到端">12.4 图文 / 视频端到端
&lt;/h3>&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-powershell" data-lang="powershell">&lt;span class="line">&lt;span class="cl">&lt;span class="n">venv&lt;/span>&lt;span class="p">\&lt;/span>&lt;span class="n">Scripts&lt;/span>&lt;span class="p">\&lt;/span>&lt;span class="n">python&lt;/span> &lt;span class="n">-m&lt;/span> &lt;span class="n">xhs_content_fetcher&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nb">cli &lt;/span>&lt;span class="n">run&lt;/span> &lt;span class="s2">&amp;#34;&amp;lt;图文链接&amp;gt;&amp;#34;&lt;/span> &lt;span class="p">-&lt;/span>&lt;span class="n">-cookie&lt;/span> &lt;span class="s2">&amp;#34;&amp;lt;脱敏&amp;gt;&amp;#34;&lt;/span> &lt;span class="p">-&lt;/span>&lt;span class="n">-skip-llm&lt;/span> &lt;span class="p">-&lt;/span>&lt;span class="n">-skip-ocr&lt;/span> &lt;span class="p">-&lt;/span>&lt;span class="n">-output-root&lt;/span> &lt;span class="n">output&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">venv&lt;/span>&lt;span class="p">\&lt;/span>&lt;span class="n">Scripts&lt;/span>&lt;span class="p">\&lt;/span>&lt;span class="n">python&lt;/span> &lt;span class="n">-m&lt;/span> &lt;span class="n">xhs_content_fetcher&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nb">cli &lt;/span>&lt;span class="n">run&lt;/span> &lt;span class="s2">&amp;#34;&amp;lt;视频链接&amp;gt;&amp;#34;&lt;/span> &lt;span class="p">-&lt;/span>&lt;span class="n">-cookie&lt;/span> &lt;span class="s2">&amp;#34;&amp;lt;脱敏&amp;gt;&amp;#34;&lt;/span> &lt;span class="p">-&lt;/span>&lt;span class="n">-skip-llm&lt;/span> &lt;span class="p">-&lt;/span>&lt;span class="n">-skip-ocr&lt;/span> &lt;span class="p">-&lt;/span>&lt;span class="n">-output-root&lt;/span> &lt;span class="n">output&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;h3 id="125-ocr-相关">12.5 OCR 相关
&lt;/h3>&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-powershell" data-lang="powershell">&lt;span class="line">&lt;span class="cl">&lt;span class="n">venv&lt;/span>&lt;span class="p">\&lt;/span>&lt;span class="n">Scripts&lt;/span>&lt;span class="p">\&lt;/span>&lt;span class="n">python&lt;/span> &lt;span class="n">-m&lt;/span> &lt;span class="n">pip&lt;/span> &lt;span class="n">install&lt;/span> &lt;span class="n">paddleocr&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">venv&lt;/span>&lt;span class="p">\&lt;/span>&lt;span class="n">Scripts&lt;/span>&lt;span class="p">\&lt;/span>&lt;span class="n">python&lt;/span> &lt;span class="n">-m&lt;/span> &lt;span class="n">pip&lt;/span> &lt;span class="n">install&lt;/span> &lt;span class="n">paddlepaddle&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;h3 id="126-obsidian-验证">12.6 Obsidian 验证
&lt;/h3>&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-powershell" data-lang="powershell">&lt;span class="line">&lt;span class="cl">&lt;span class="n">obsidian&lt;/span> &lt;span class="p">-&lt;/span>&lt;span class="n">-help&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">obsidian&lt;/span> &lt;span class="n">vaults&lt;/span> &lt;span class="n">verbose&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;h3 id="127-发布">12.7 发布
&lt;/h3>&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;span class="lnt">3
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-powershell" data-lang="powershell">&lt;span class="line">&lt;span class="cl">&lt;span class="n">git&lt;/span> &lt;span class="n">add&lt;/span> &lt;span class="p">.&lt;/span>&lt;span class="py">gitignore&lt;/span> &lt;span class="n">README&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nb">md &lt;/span>&lt;span class="n">Tempate&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nb">md &lt;/span>&lt;span class="n">pyproject&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="py">toml&lt;/span> &lt;span class="n">src&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">git&lt;/span> &lt;span class="n">commit&lt;/span> &lt;span class="n">-m&lt;/span> &lt;span class="s2">&amp;#34;feat: implement end-to-end xhs fetcher with obsidian integration&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">git&lt;/span> &lt;span class="n">push&lt;/span> &lt;span class="n">origin&lt;/span> &lt;span class="n">main&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;hr>
&lt;h2 id="13-我这次最值的三个决策">13. 我这次最值的三个决策
&lt;/h2>&lt;ol>
&lt;li>先做可用性验证，再做架构设计。&lt;/li>
&lt;li>把长链路做成“局部失败不拖垮全流程”。&lt;/li>
&lt;li>用模板约束生成结构，把质量控制权留在我手里。&lt;/li>
&lt;/ol>
&lt;h2 id="14-下一步优化计划">14. 下一步优化计划
&lt;/h2>&lt;ol>
&lt;li>断点续跑，减少长任务重跑成本。&lt;/li>
&lt;li>OCR / LLM 缓存，按 &lt;code>note_id + 素材 hash&lt;/code>。&lt;/li>
&lt;li>结构化日志，覆盖阶段耗时和错误分类。&lt;/li>
&lt;li>模板变量校验，缺失章节自动报错。&lt;/li>
&lt;li>“仅更新正文 / 仅更新评论”子命令。&lt;/li>
&lt;li>多模型路由与失败回退策略。&lt;/li>
&lt;/ol>
&lt;hr>
&lt;h2 id="15-最终复盘一句话">15. 最终复盘一句话
&lt;/h2>&lt;p>这次我真正做成的，不是一个“能跑演示”的脚本，而是一条可定位、可修复、可复测、可发布、可复用的工程链路。&lt;/p></description></item><item><title>PubArticle2MD 项目复盘：从“能跑”到“可交付”</title><link>https://iwmei.top/p/pubarticle2md-from-working-to-deliverable/</link><pubDate>Mon, 04 May 2026 00:00:00 +0000</pubDate><guid>https://iwmei.top/p/pubarticle2md-from-working-to-deliverable/</guid><description>&lt;img src="https://iwmei.top/p/pubarticle2md-from-working-to-deliverable/cover.png" alt="Featured image of post PubArticle2MD 项目复盘：从“能跑”到“可交付”" />&lt;p>这篇文章记录 &lt;code>PubArticle2MD&lt;/code> 的完整落地过程。&lt;/p>
&lt;p>项目目标不复杂：把公众号文章转成 Markdown 或 PDF，并且给出三种可用形态：&lt;/p>
&lt;ul>
&lt;li>在线可用（GitHub Pages）&lt;/li>
&lt;li>本地源码可跑&lt;/li>
&lt;li>桌面 EXE 可直接用&lt;/li>
&lt;/ul>
&lt;p>真正的难点不在“功能写出来”，而在“交付后别人也能稳定用”。下面按时间顺序展开。&lt;/p>
&lt;h2 id="1-项目目标">1. 项目目标
&lt;/h2>&lt;p>初始目标有 4 个：&lt;/p>
&lt;ol>
&lt;li>参考 &lt;code>wechat2pdf&lt;/code> 思路，实现公众号文章转 &lt;code>Markdown/PDF&lt;/code>。&lt;/li>
&lt;li>支持本地运行，尽量不把内容上传到第三方。&lt;/li>
&lt;li>提供 PWA 入口，发布到 GitHub Pages。&lt;/li>
&lt;li>争取提供普通用户可直接运行的 EXE。&lt;/li>
&lt;/ol>
&lt;p>测试文章：
&lt;code>https://mp.weixin.qq.com/s/5BOAnJ5H4seYxSbXWi5Ibg&lt;/code>&lt;/p>
&lt;h2 id="2-第一版实现先把主链路跑通">2. 第一版实现：先把主链路跑通
&lt;/h2>&lt;p>项目先拆成两层：&lt;/p>
&lt;ul>
&lt;li>前端（PWA）：输入链接、选择抓取模式、预览内容、下载文件。&lt;/li>
&lt;li>后端（Node API）：&lt;code>/api/health&lt;/code>、&lt;code>/api/parse&lt;/code>、&lt;code>/api/export/markdown&lt;/code>、&lt;code>/api/export/pdf&lt;/code>。&lt;/li>
&lt;/ul>
&lt;p>PDF 由 Playwright 在后端渲染，优先保证稳定性。&lt;/p>
&lt;p>核心代码位置：&lt;/p>
&lt;ul>
&lt;li>&lt;code>public/app.js&lt;/code>&lt;/li>
&lt;li>&lt;code>server/index.js&lt;/code>&lt;/li>
&lt;li>&lt;code>desktop/main.js&lt;/code>&lt;/li>
&lt;/ul>
&lt;p>第一版发布后，基本功能可用，但工程问题开始集中出现。&lt;/p>
&lt;h2 id="3-问题一github-pages-404">3. 问题一：GitHub Pages 404
&lt;/h2>&lt;h3 id="现象">现象
&lt;/h3>&lt;p>Pages 地址访问 404，页面提示：
&lt;code>There isn't a GitHub Pages site here.&lt;/code>&lt;/p>
&lt;h3 id="排查结果">排查结果
&lt;/h3>&lt;p>部署日志显示，问题不在前端资源，而在 Pages 发布状态。工作流存在，但站点链路没有完整激活。&lt;/p>
&lt;h3 id="处理方式">处理方式
&lt;/h3>&lt;ol>
&lt;li>检查仓库 Pages 配置。&lt;/li>
&lt;li>重新触发部署。&lt;/li>
&lt;li>部署后回测 URL。&lt;/li>
&lt;/ol>
&lt;p>恢复后的在线入口：
&lt;a class="link" href="https://yourpapayouknow.github.io/PubArticle2MD/" target="_blank" rel="noopener"
>https://yourpapayouknow.github.io/PubArticle2MD/&lt;/a>&lt;/p>
&lt;h2 id="4-问题二有-actions-不代表可直接使用">4. 问题二：有 Actions 不代表“可直接使用”
&lt;/h2>&lt;p>当时发现一个常见误区：流水线很多，但用户路径不清晰。&lt;/p>
&lt;p>后续做了收敛：&lt;/p>
&lt;ol>
&lt;li>&lt;code>CI&lt;/code> 负责基本检查。&lt;/li>
&lt;li>&lt;code>Deploy GitHub Pages&lt;/code> 只负责发布 &lt;code>public/&lt;/code>。&lt;/li>
&lt;li>README 只讲用户需要的路径，删掉不必要的流程噪音。&lt;/li>
&lt;/ol>
&lt;p>目标从“流程完整”改为“用户可用”。这一步很关键。&lt;/p>
&lt;h2 id="5-问题三核心问题exe-是前端壳不是完整应用">5. 问题三（核心问题）：EXE 是前端壳，不是完整应用
&lt;/h2>&lt;h3 id="现象-1">现象
&lt;/h3>&lt;p>桌面版运行后：&lt;/p>
&lt;ul>
&lt;li>选择本地 API 会报“当前环境没有本地 API 服务”。&lt;/li>
&lt;li>运行模式一直显示“纯前端模式（GitHub Pages）”。&lt;/li>
&lt;/ul>
&lt;h3 id="根因">根因
&lt;/h3>&lt;p>桌面进程只做了 &lt;code>loadFile(index.html)&lt;/code>，没有启动本地服务。&lt;/p>
&lt;p>前端会请求 &lt;code>./api/health&lt;/code> 判断本地 API 是否存在。服务没启动，检测自然失败，所以始终落在纯前端模式。&lt;/p>
&lt;h3 id="修复动作">修复动作
&lt;/h3>&lt;ol>
&lt;li>Electron 主进程直接启动本地 API。
&lt;ul>
&lt;li>&lt;code>host=127.0.0.1&lt;/code>&lt;/li>
&lt;li>&lt;code>port=0&lt;/code>（自动分配端口，避免冲突）&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>窗口优先加载本地 API URL；失败再降级到本地 HTML。&lt;/li>
&lt;li>在 &lt;code>before-quit&lt;/code> 里关闭 server，避免残留进程。&lt;/li>
&lt;li>&lt;code>/api/health&lt;/code> 增加 &lt;code>runtime&lt;/code> 字段，前端按运行态显示文案：
&lt;ul>
&lt;li>本地 API 模式（桌面 EXE 内置后端）&lt;/li>
&lt;li>本地 API 模式（Node 服务）&lt;/li>
&lt;li>纯前端模式（GitHub Pages）&lt;/li>
&lt;/ul>
&lt;/li>
&lt;/ol>
&lt;p>修复后，EXE 从“页面容器”变成了“前后端一体应用”。&lt;/p>
&lt;h2 id="6-问题四桌面版要稳定运行环境必须随包">6. 问题四：桌面版要稳定，运行环境必须随包
&lt;/h2>&lt;p>桌面版即使能启动，如果依赖没打进包，用户机器仍会失败。&lt;/p>
&lt;p>这里主要处理两件事：&lt;/p>
&lt;ol>
&lt;li>后端代码进包。&lt;/li>
&lt;li>Playwright Chromium 随包。&lt;/li>
&lt;/ol>
&lt;h3 id="对应改动">对应改动
&lt;/h3>&lt;ol>
&lt;li>&lt;code>package.json&lt;/code> 的 &lt;code>build.files&lt;/code> 增加 &lt;code>server/**/*&lt;/code>。&lt;/li>
&lt;li>新增脚本 &lt;code>scripts/ensure-playwright-browsers.js&lt;/code>：
&lt;ul>
&lt;li>打包前检查 &lt;code>.local-browsers&lt;/code>&lt;/li>
&lt;li>缺失时自动安装 Chromium&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>&lt;code>extraResources&lt;/code> 加入浏览器目录。&lt;/li>
&lt;li>启动时设置 &lt;code>PLAYWRIGHT_BROWSERS_PATH=resources/playwright-browsers&lt;/code>。&lt;/li>
&lt;li>排除 asar 内重复浏览器资源，避免包体翻倍。&lt;/li>
&lt;/ol>
&lt;p>这一步解决了“本机可用、别人不可用”的典型问题。&lt;/p>
&lt;h2 id="7-问题五windows-本地发布脚本首次失败">7. 问题五：Windows 本地发布脚本首次失败
&lt;/h2>&lt;h3 id="现象-2">现象
&lt;/h3>&lt;p>执行以下命令首次失败：&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">npm run release:local -- --tag v1.0.2
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>报错停在：&lt;code>npm.cmd run desktop:dist&lt;/code>。&lt;/p>
&lt;h3 id="根因-1">根因
&lt;/h3>&lt;p>Windows 下子进程执行 &lt;code>.cmd&lt;/code> 时，&lt;code>spawnSync&lt;/code> 的默认参数不稳定。&lt;/p>
&lt;h3 id="修复">修复
&lt;/h3>&lt;p>在 &lt;code>scripts/release-local.js&lt;/code> 中对 Windows 开启 &lt;code>shell: true&lt;/code>。&lt;/p>
&lt;p>随后发布链路跑通：&lt;/p>
&lt;ol>
&lt;li>本地构建 EXE&lt;/li>
&lt;li>创建 GitHub Release&lt;/li>
&lt;li>上传发布资产&lt;/li>
&lt;/ol>
&lt;p>版本地址：
&lt;a class="link" href="https://github.com/yourpapayouknow/PubArticle2MD/releases/tag/v1.0.2" target="_blank" rel="noopener"
>https://github.com/yourpapayouknow/PubArticle2MD/releases/tag/v1.0.2&lt;/a>&lt;/p>
&lt;h2 id="8-当前状态">8. 当前状态
&lt;/h2>&lt;p>项目目前可以对外稳定使用：&lt;/p>
&lt;ol>
&lt;li>Pages 在线版可用。&lt;/li>
&lt;li>EXE 内置本地 API，不再是前端壳。&lt;/li>
&lt;li>PDF 依赖环境已随包。&lt;/li>
&lt;li>本地打包和发布流程可复现。&lt;/li>
&lt;li>文档已按用户路径重写。&lt;/li>
&lt;/ol>
&lt;h2 id="9-使用方法">9. 使用方法
&lt;/h2>&lt;h3 id="91-在线版无需安装">9.1 在线版（无需安装）
&lt;/h3>&lt;p>地址：
&lt;a class="link" href="https://yourpapayouknow.github.io/PubArticle2MD/" target="_blank" rel="noopener"
>https://yourpapayouknow.github.io/PubArticle2MD/&lt;/a>&lt;/p>
&lt;p>步骤：&lt;/p>
&lt;ol>
&lt;li>输入公众号链接。&lt;/li>
&lt;li>直连失败时切换“代理 URL”或“粘贴 HTML”。&lt;/li>
&lt;li>点击解析。&lt;/li>
&lt;li>下载 Markdown ZIP 或 PDF。&lt;/li>
&lt;/ol>
&lt;p>示例链接：
&lt;code>https://mp.weixin.qq.com/s/5BOAnJ5H4seYxSbXWi5Ibg&lt;/code>&lt;/p>
&lt;h3 id="92-桌面-exe推荐">9.2 桌面 EXE（推荐）
&lt;/h3>&lt;ol>
&lt;li>打开 Release：
&lt;a class="link" href="https://github.com/yourpapayouknow/PubArticle2MD/releases/tag/v1.0.2" target="_blank" rel="noopener"
>https://github.com/yourpapayouknow/PubArticle2MD/releases/tag/v1.0.2&lt;/a>&lt;/li>
&lt;li>下载并运行 EXE。&lt;/li>
&lt;li>确认运行模式显示为“本地 API 模式（桌面 EXE 内置后端）”。&lt;/li>
&lt;/ol>
&lt;h3 id="93-本地源码运行">9.3 本地源码运行
&lt;/h3>&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;span class="lnt">3
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">npm install
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">npm run install:chromium
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">npm start
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>访问：&lt;code>http://127.0.0.1:8787&lt;/code>&lt;/p>
&lt;h3 id="94-命令行批量转换">9.4 命令行批量转换
&lt;/h3>&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">npm run convert -- --url &lt;span class="s2">&amp;#34;https://mp.weixin.qq.com/s/5BOAnJ5H4seYxSbXWi5Ibg&amp;#34;&lt;/span> --outdir outputs
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;h3 id="95-本机打包并发布">9.5 本机打包并发布
&lt;/h3>&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">gh auth login
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">npm run release:local -- --tag v1.0.2
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;h2 id="10-这次复盘的核心结论">10. 这次复盘的核心结论
&lt;/h2>&lt;p>这个项目最大的收获，不是“做完了一个工具”，而是把工具做成了可交付物。&lt;/p>
&lt;p>判断标准很直接：&lt;/p>
&lt;ul>
&lt;li>用户能在线用。&lt;/li>
&lt;li>用户能安装用。&lt;/li>
&lt;li>开发者能本地复现。&lt;/li>
&lt;li>版本能持续发布。&lt;/li>
&lt;/ul>
&lt;p>从结果看，真正推动项目跨过这道线的，往往不是新功能，而是对“不可用细节”的持续修复。&lt;/p></description></item><item><title>MP3 算法基本原理：从波形物理到心理声学</title><link>https://iwmei.top/p/mp3-psychoacoustic-encoding-principles/</link><pubDate>Sat, 04 Apr 2026 00:00:00 +0000</pubDate><guid>https://iwmei.top/p/mp3-psychoacoustic-encoding-principles/</guid><description>&lt;img src="https://iwmei.top/p/mp3-psychoacoustic-encoding-principles/cover.png" alt="Featured image of post MP3 算法基本原理：从波形物理到心理声学" />&lt;p>在数字音频讨论里，MP3 常被简单归类为“有损=音质差”。但在高码率（如 320kbps）场景下，很多听众在规范 ABX 测试中并不能稳定区分它和 44.1kHz/16bit 无损源。&lt;/p>
&lt;p>这背后的关键不是“MP3 做到了物理无损”，而是它把误差控制在人耳不敏感或被掩蔽的区域。换句话说，MP3 的核心思路不是尽量复制全部波形细节，而是优先保证主观可听质量。&lt;/p>
&lt;h2 id="核心前提心理声学与掩蔽">核心前提：心理声学与掩蔽
&lt;/h2>&lt;p>MP3 依赖两条基本事实：&lt;/p>
&lt;ol>
&lt;li>
&lt;p>绝对听阈（ATH）
人耳对不同频率敏感度不同。部分极低频、极高频或很弱的信号，即便客观存在，也可能不可闻。&lt;/p>
&lt;/li>
&lt;li>
&lt;p>掩蔽效应（Masking）
当某一频段存在强信号时，邻近频率的弱信号会变得更难被听见。编码器可以利用这点，把量化误差“放”进不易被察觉的区域。&lt;/p>
&lt;/li>
&lt;/ol>
&lt;h2 id="mp3-编码流水线简化版">MP3 编码流水线（简化版）
&lt;/h2>&lt;h3 id="1-双通路并行">1. 双通路并行
&lt;/h3>&lt;p>输入 PCM 后，编码器通常并行进行：&lt;/p>
&lt;ul>
&lt;li>数据通路：负责把信号变换到适合量化和编码的表示形式。&lt;/li>
&lt;li>心理声学通路：估计当前帧各频段的可闻阈值，给数据通路提供约束。&lt;/li>
&lt;/ul>
&lt;h3 id="2-子带分析polyphase-filter-bank">2. 子带分析（Polyphase Filter Bank）
&lt;/h3>&lt;p>先把宽频带信号切成 32 个子带，便于后续分频处理。这一步时间分辨率较好，但频率分辨率仍偏粗。&lt;/p>
&lt;h3 id="3-心理声学分析常用-fft-辅助">3. 心理声学分析（常用 FFT 辅助）
&lt;/h3>&lt;p>编码器通过频谱分析估计：&lt;/p>
&lt;ul>
&lt;li>哪些成分是强掩蔽音；&lt;/li>
&lt;li>各频段可容忍多少噪声；&lt;/li>
&lt;li>全局掩蔽阈值大致在哪里。&lt;/li>
&lt;/ul>
&lt;p>注意：这条通路主要提供“决策依据”，不是直接输出最终编码数据。&lt;/p>
&lt;h3 id="4-mdct-精细频域表示">4. MDCT 精细频域表示
&lt;/h3>&lt;p>对子带信号进一步做 MDCT，得到更细粒度的频域系数（长窗常见 576 线，瞬态短窗模式下结构会变化）。&lt;/p>
&lt;p>这些系数才是后续量化与码率分配的直接对象。&lt;/p>
&lt;h3 id="5-比特分配与量化质量和体积的平衡点">5. 比特分配与量化：质量和体积的平衡点
&lt;/h3>&lt;p>编码器需要同时满足两件事：&lt;/p>
&lt;ul>
&lt;li>噪声尽量低于掩蔽阈值；&lt;/li>
&lt;li>总比特数不超过目标码率预算。&lt;/li>
&lt;/ul>
&lt;p>一个常见参考量是信掩比：&lt;/p>
$$
SMR = E_{signal} - T_{mask}
$$&lt;p>其中 $E_{signal}$ 表示信号能量（通常以 dB 度量），$T_{mask}$ 表示该频段掩蔽阈值。&lt;/p>
&lt;p>实现上通常是迭代搜索：&lt;/p>
&lt;ul>
&lt;li>内层调整局部量化，控制各频段噪声；&lt;/li>
&lt;li>外层控制全局步长和总比特，保证码率目标。&lt;/li>
&lt;/ul>
&lt;h3 id="6-熵编码huffman">6. 熵编码（Huffman）
&lt;/h3>&lt;p>量化后大量系数变小或归零，再进行哈夫曼编码，用更短码字表示高频出现符号，进一步压缩数据体积。该步骤本身是无损的。&lt;/p>
&lt;h3 id="7-比特流封装">7. 比特流封装
&lt;/h3>&lt;p>将主数据、比例因子、侧信息、帧头等按标准格式打包，形成连续 MP3 帧。&lt;/p>
&lt;h2 id="小结">小结
&lt;/h2>&lt;p>MP3 的工程价值在于：它不是“简单删细节”，而是结合听觉模型做受控失真，让失真尽可能落在人耳不敏感区域。&lt;/p>
&lt;p>因此，高码率 MP3 往往能在体积和主观听感之间取得很高的性价比。它不是物理意义上的无损，但在很多实际聆听条件下可以达到接近透明的结果。&lt;/p></description></item><item><title>性快感的进化机制、神经基础与行为功能：跨物种比较视角</title><link>https://iwmei.top/p/evolution-neural-basis-and-function-of-sexual-pleasure/</link><pubDate>Sat, 04 Apr 2026 00:00:00 +0000</pubDate><guid>https://iwmei.top/p/evolution-neural-basis-and-function-of-sexual-pleasure/</guid><description>&lt;img src="https://iwmei.top/p/evolution-neural-basis-and-function-of-sexual-pleasure/cover.png" alt="Featured image of post 性快感的进化机制、神经基础与行为功能：跨物种比较视角" />&lt;h1 id="性快感的进化机制神经基础与行为功能跨物种比较视角">性快感的进化机制、神经基础与行为功能：跨物种比较视角
&lt;/h1>&lt;p>本文基于一组连续讨论，整理一个核心问题：&lt;/p>
&lt;p>&lt;code>性快感到底是“生殖副产物”，还是“被自然选择保留下来的行为引擎”？&lt;/code>&lt;/p>
&lt;p>结论先行：在大多数哺乳动物中，性快感至少是“强化交配行为”的底层机制；而在部分高社会复杂性物种里，它进一步被“升级”为维持关系、降低冲突、促进协作的社会工具。&lt;/p>
&lt;h2 id="一概念拆分同一个快感不同层级">一、概念拆分：同一个快感，不同层级
&lt;/h2>&lt;p>谈“性快感”时，常把两层机制混在一起：&lt;/p>
&lt;ol>
&lt;li>生理层：局部刺激 -&amp;gt; 神经传导 -&amp;gt; 奖赏系统激活（多巴胺、内啡肽等）。&lt;/li>
&lt;li>行为层：个体是否会在非生殖必要时段，主动重复并利用这种快感。&lt;/li>
&lt;/ol>
&lt;p>前者在许多动物中都存在，后者只在少数物种中表现得非常明显。&lt;/p>
&lt;h2 id="二跨物种观察从生殖驱动到社交驱动">二、跨物种观察：从“生殖驱动”到“社交驱动”
&lt;/h2>&lt;p>目前常被讨论的物种包括：&lt;/p>
&lt;ul>
&lt;li>倭黑猩猩（Bonobos）：大量非受孕导向性行为，常用于缓和冲突和建立联盟。&lt;/li>
&lt;li>宽吻海豚（Bottlenose dolphins）：存在与繁殖无直接关系的性接触行为，并可见较复杂的社交功能。&lt;/li>
&lt;li>日本猕猴（Japanese macaques）：可观察到与快感相关的行为与生理反应模式。&lt;/li>
&lt;li>部分蝙蝠等非灵长类：存在会影响交配效率与时长的相关行为。&lt;/li>
&lt;/ul>
&lt;p>可粗略看成一个连续谱：&lt;/p>
&lt;table>
&lt;thead>
&lt;tr>
&lt;th>类型&lt;/th>
&lt;th>行为特征&lt;/th>
&lt;th>典型结果&lt;/th>
&lt;/tr>
&lt;/thead>
&lt;tbody>
&lt;tr>
&lt;td>严格生殖型&lt;/td>
&lt;td>高度受发情周期限制&lt;/td>
&lt;td>行为短促、目标单一&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>过渡型&lt;/td>
&lt;td>非发情期也有少量相关行为&lt;/td>
&lt;td>兼具生殖与减压功能&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>高社会化型&lt;/td>
&lt;td>全年可出现非受孕导向行为&lt;/td>
&lt;td>快感成为“社交粘合剂”&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;/table>
&lt;h2 id="三神经基础为什么快感会被保留">三、神经基础：为什么快感会被保留
&lt;/h2>&lt;p>从演化角度看，交配是高成本行为（耗能、受伤、被捕食风险）。&lt;/p>
&lt;p>因此自然选择倾向于把“即时奖励”绑定在交配相关行为上：&lt;/p>
&lt;ul>
&lt;li>奖赏回路（多巴胺系统）提供“值得做”的主观价值。&lt;/li>
&lt;li>催产素等系统在部分物种中强化亲密与信任。&lt;/li>
&lt;li>强化学习让个体更可能重复有收益的行为。&lt;/li>
&lt;/ul>
&lt;p>这使得“个体并不理解后代逻辑，也会愿意去交配”。&lt;/p>
&lt;h2 id="四关键区分生理反射-vs-心理预期">四、关键区分：生理反射 vs. 心理预期
&lt;/h2>&lt;p>很多争论点都在这里。&lt;/p>
&lt;p>以犬类为例：&lt;/p>
&lt;ul>
&lt;li>在非发情期，局部刺激也可能引发勃起或排精，这说明“快感硬件”存在。&lt;/li>
&lt;li>但是否能稳定转化为“主动、计划性、社交化的追求”，取决于认知能力、社会结构、学习机会与生态成本。&lt;/li>
&lt;/ul>
&lt;p>换句话说，不是“有没有快感”，而是“快感在该物种行为系统里的权限有多高”。&lt;/p>
&lt;h2 id="五实验视角外部刺激能否重塑行为">五、实验视角：外部刺激能否重塑行为？
&lt;/h2>&lt;p>经典奖赏实验（如啮齿类自我刺激研究）表明：&lt;/p>
&lt;ul>
&lt;li>只要奖赏反馈足够直接、稳定，动物可快速形成“行为 -&amp;gt; 奖励”的强化闭环。&lt;/li>
&lt;li>在实验室环境中，这种闭环甚至能压过进食、休息等行为。&lt;/li>
&lt;/ul>
&lt;p>这提示两点：&lt;/p>
&lt;ol>
&lt;li>奖赏系统非常强大。&lt;/li>
&lt;li>自然环境中的行为表达，常被捕食压力、资源约束与社会结构“上锁”。&lt;/li>
&lt;/ol>
&lt;h2 id="六人类处境优势与代价并存">六、人类处境：优势与代价并存
&lt;/h2>&lt;p>人类的特殊性在于：&lt;/p>
&lt;ul>
&lt;li>性行为较大程度脱离固定发情窗口。&lt;/li>
&lt;li>快感可被记忆、想象和文化规则反复重构。&lt;/li>
&lt;/ul>
&lt;p>这带来双重结果：&lt;/p>
&lt;ul>
&lt;li>优势：强化亲密关系、社会协作、群体稳定。&lt;/li>
&lt;li>代价：在现代“超常刺激”环境下，可能出现注意力挤占、成瘾倾向、风险行为增加等问题。&lt;/li>
&lt;/ul>
&lt;h2 id="结语">结语
&lt;/h2>&lt;p>从跨物种角度看，性快感不是单一现象，而是一套分层系统：&lt;/p>
&lt;ul>
&lt;li>底层是神经奖励机制。&lt;/li>
&lt;li>中层是强化学习。&lt;/li>
&lt;li>高层才是社交与文化功能。&lt;/li>
&lt;/ul>
&lt;p>因此，与其问“哪些动物有性快感”，不如问：&lt;/p>
&lt;p>&lt;code>在不同生态和社会条件下，快感被允许承担了多大的行为功能？&lt;/code>&lt;/p>
&lt;p>这或许才是理解该议题最有解释力的框架。&lt;/p></description></item><item><title>本地项目上传github的坑点与正确姿势</title><link>https://iwmei.top/p/all-git-push-the-right-way/</link><pubDate>Mon, 16 Mar 2026 00:00:00 +0000</pubDate><guid>https://iwmei.top/p/all-git-push-the-right-way/</guid><description>&lt;img src="https://iwmei.top/p/all-git-push-the-right-way/cover.png" alt="Featured image of post 本地项目上传github的坑点与正确姿势" />&lt;h1 id="本地项目上传github的坑点与正确姿势">本地项目上传github的坑点与正确姿势
&lt;/h1>&lt;ul>
&lt;li>首先，无论是什么IDE或者编辑器（VS、VScode、Pycharm、Idea、Clion等等），统统不要先在本地创建仓库。&lt;/li>
&lt;/ul>
&lt;h2 id="一些坑点">一些坑点
&lt;/h2>&lt;ol>
&lt;li>要先绑定github远程仓库，可能出现各种奇怪的问题；&lt;/li>
&lt;li>git创建的本地仓库，分支名字是 &lt;code>master&lt;/code> ，而github是 &lt;code>main&lt;/code> ，直接上传会导致不同分支，不好看；&lt;/li>
&lt;li>如果是使用IDE内的版本管理操作的，写完项目再创建仓库，添加文件是会出现困难，重新加 &lt;code>.gitignore&lt;/code> 太麻烦了，还可能有各种报错；&lt;/li>
&lt;li>仓库间文件不统一， 即使使用了 &lt;code>git pull&lt;/code> 也还是会报各种错误；&lt;/li>
&lt;li>可能因为各种权限问题导致被拒绝push。&lt;/li>
&lt;/ol>
&lt;h2 id="建议的正确姿势">建议的正确姿势
&lt;/h2>&lt;ol>
&lt;li>
&lt;p>进入github主页，点击 &lt;code>New&lt;/code> 创建同名的仓库；&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-link" data-lang="link">&lt;span class="line">&lt;span class="cl">&lt;span class="err">https://github.com/&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;ul>
&lt;li>点击左上角的绿色按钮，按照提示填即可。&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>
&lt;p>创建完毕后，cd到项目存放地，使用 &lt;code>git clone&lt;/code> 命令把仓库克隆过来；&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-link" data-lang="link">&lt;span class="line">&lt;span class="cl">&lt;span class="err">git&lt;/span> &lt;span class="err">clone&lt;/span> &lt;span class="err">https://github.com/yourname/yourdepository&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;ul>
&lt;li>请在预存放项目的地方打开终端，执行上面的link，后面的仓库地址可以直接从仓库页面下的浏览器链接栏里面复制。&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>
&lt;p>将你要上传的所有文件全部复制进clone下来的文件夹里面；&lt;/p>
&lt;ul>
&lt;li>注意，超过100MB的文件无法上传github；&lt;/li>
&lt;li>注意使用AI添加一个 &lt;code>.gitignore&lt;/code> 文件，把有的没的的路径都放进去。&lt;/li>
&lt;/ul>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;span class="lnt">3
&lt;/span>&lt;span class="lnt">4
&lt;/span>&lt;span class="lnt">5
&lt;/span>&lt;span class="lnt">6
&lt;/span>&lt;span class="lnt">7
&lt;/span>&lt;span class="lnt">8
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-link" data-lang="link">&lt;span class="line">&lt;span class="cl">&lt;span class="err">__pycache__/&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err">*.pyc&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err">.env&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err">venv/&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err">.idea/&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err">.vscode/&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err">dist/&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err">build/&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;/li>
&lt;li>
&lt;p>在终端中依次执行以下命令：&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;span class="lnt">3
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-link" data-lang="link">&lt;span class="line">&lt;span class="cl">&lt;span class="err">git&lt;/span> &lt;span class="err">add&lt;/span> &lt;span class="err">.&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err">git&lt;/span> &lt;span class="err">commit&lt;/span> &lt;span class="err">-m&lt;/span> &lt;span class="err">&amp;#34;init&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err">git&lt;/span> &lt;span class="err">push&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;/li>
&lt;li>
&lt;p>后续的操作就转移到这个项目目录下进行即可，在IDE中图形化操作即可。&lt;/p>
&lt;/li>
&lt;/ol>
&lt;h2 id="总结">总结
&lt;/h2>&lt;p>请下次写项目前，先创建仓库别直接开写好吗 /smile&lt;/p></description></item><item><title>M芯片Mac 配置oMLX遇到的问题相关解决</title><link>https://iwmei.top/p/mac-omlx-configuration/</link><pubDate>Sat, 14 Mar 2026 00:00:00 +0000</pubDate><guid>https://iwmei.top/p/mac-omlx-configuration/</guid><description>&lt;img src="https://iwmei.top/p/mac-omlx-configuration/cover.png" alt="Featured image of post M芯片Mac 配置oMLX遇到的问题相关解决" />&lt;h1 id="m芯片mac配置omlx遇到的问题相关解决">M芯片Mac配置oMLX遇到的问题相关解决
&lt;/h1>&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-fallback" data-lang="fallback">&lt;span class="line">&lt;span class="cl">https://github.com/jundot/omlx
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-fallback" data-lang="fallback">&lt;span class="line">&lt;span class="cl">https://zhuanlan.zhihu.com/p/2014650251089302644
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;h2 id="建议使用homebrew安装">建议使用Homebrew安装
&lt;/h2>&lt;ul>
&lt;li>
&lt;p>Homebrew是Mac和Linux上的一款包管理，很多应用通过Homebrew分发；&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-fallback" data-lang="fallback">&lt;span class="line">&lt;span class="cl"> [Homebrew官网](https://brew.sh/)
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;ul>
&lt;li>要像流畅使用homebrew，建议提前准备科学上网环境。&lt;/li>
&lt;/ul>
&lt;/li>
&lt;/ul>
&lt;ol>
&lt;li>使用Homebrew安装的oMLX，可以在终端直接使用命令** omlx * **；&lt;/li>
&lt;li>请遵循项目地址中readme.md的 &lt;strong>Install.Homebrew&lt;/strong> 这一节来安装，由于涉及到下载与编译，需要等待较长时间（接近1GB的大小）；&lt;/li>
&lt;li>下载完毕后，通过 &lt;strong>Quickstart.Homebrew Service&lt;/strong> 这一节教程来启动，以默认设置启动。&lt;/li>
&lt;/ol>
&lt;h2 id="配置-omlxsettingsjson">配置 ~/.omlx/settings.json
&lt;/h2>&lt;ol>
&lt;li>
&lt;p>打开访达，进入下载文件夹，按住option键，点击左下角的&lt;strong>Macintosh HD&lt;/strong>，依次点击User\mac，找到.omlx文件夹后进入；&lt;/p>
&lt;/li>
&lt;li>
&lt;p>打开&lt;strong>settings.json&lt;/strong>，找到&amp;quot;api_key&amp;quot;这一项，修改或填入为&lt;strong>任意短字符串&lt;/strong>，例如&lt;strong>omlx&lt;/strong>&lt;/p>
&lt;ul>
&lt;li>注意，此处为一个坑点，如果此处填写32或者48字符的长字符串，将会导致无法被外部认证，请务必填写短字符串。&lt;/li>
&lt;li>如果填写长apikey，在一键接入openclaw时，会提示 &lt;strong>run omlx serve first&lt;/strong> 的报错，这个是一个bug。&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>
&lt;p>下载模型&lt;strong>文件夹&lt;/strong>放入 ~/.omlx/models 中&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-link" data-lang="link">&lt;span class="line">&lt;span class="cl">&lt;span class="err">https://huggingface.co/Qwen/Qwen3-4B-MLX-4bit&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;ul>
&lt;li>注意，模型文件一定是&lt;strong>整个文件夹&lt;/strong>；&lt;/li>
&lt;li>模型一定是要带 &lt;strong>MLX&lt;/strong> 字样的，否则无法被正常调用；&lt;/li>
&lt;li>拉取推荐使用 &lt;strong>git clone&lt;/strong> 和 &lt;strong>git lfs pull&lt;/strong>，详情询问AI。&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>
&lt;p>使用brew命令重启omlx服务&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-link" data-lang="link">&lt;span class="line">&lt;span class="cl">&lt;span class="err">brew&lt;/span> &lt;span class="err">services&lt;/span> &lt;span class="err">restart&lt;/span> &lt;span class="err">omlx&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;/li>
&lt;li>
&lt;p>进入管理GUI，察看状态&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-link" data-lang="link">&lt;span class="line">&lt;span class="cl">&lt;span class="err">http://127.0.0.1:8000/admin&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;ul>
&lt;li>注意要加admin进入二级页。&lt;/li>
&lt;li>点击菜单栏中最右边的Chat，看看是否可以正常聊天。如果不可以，则重新尝试，或者打开活动监视器，检查内存是否够用（MAc的机载RAM最少16G）；&lt;/li>
&lt;li>如果提示 request timeout，调小上下文长度，在 &lt;strong>Settings&lt;/strong> 栏里面。&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>
&lt;p>接入openclaw&lt;/p>
&lt;ul>
&lt;li>在终端中键入 &lt;strong>openclaw onboard&lt;/strong> 配置模型提供商；&lt;/li>
&lt;/ul>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-fallback" data-lang="fallback">&lt;span class="line">&lt;span class="cl">http://127.0.0.1:8000/v1
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-fallback" data-lang="fallback">&lt;span class="line">&lt;span class="cl">omlx # 如果你按我的来，就是这个，在本地运行不用担心泄露问题
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;ul>
&lt;li>按部就班填写即可。&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>
&lt;p>配置完毕，切换模型后，请使用 &lt;strong>openclaw gateway restart&lt;/strong> 重启以应用更改（旧版），新版则直接在openclaw GUI中修改即可。&lt;/p>
&lt;/li>
&lt;/ol></description></item><item><title>🎵 数字音频与 Hi-Fi 系统硬核指南</title><link>https://iwmei.top/p/hifi-system-guide/</link><pubDate>Sun, 08 Mar 2026 00:00:00 +0000</pubDate><guid>https://iwmei.top/p/hifi-system-guide/</guid><description>&lt;img src="https://iwmei.top/p/hifi-system-guide/cover.png" alt="Featured image of post 🎵 数字音频与 Hi-Fi 系统硬核指南" />&lt;h1 id="-数字音频与-hi-fi-系统硬核指南">🎵 数字音频与 Hi-Fi 系统硬核指南
&lt;/h1>&lt;h2 id="一-音频规格与听感本质">一、 音频规格与听感本质
&lt;/h2>&lt;h3 id="1-6mbps-与-hi-res-音频">1. 6Mbps 与 Hi-Res 音频
&lt;/h3>&lt;p>你目前通过网线传输的 &lt;strong>6Mbps&lt;/strong> 属于极高规格的无损音频流，通常对应 &lt;strong>24-bit / 96kHz&lt;/strong> 或更高的母带级音源。&lt;/p>
&lt;ul>
&lt;li>&lt;strong>网线传输的优势&lt;/strong>：带宽远超蓝牙（LDAC 最高仅 990 Kbps），能确保高规格数据流不被压缩、不卡顿。&lt;/li>
&lt;/ul>
&lt;table>
&lt;thead>
&lt;tr>
&lt;th>&lt;strong>音质等级&lt;/strong>&lt;/th>
&lt;th>&lt;strong>典型码率&lt;/strong>&lt;/th>
&lt;th>&lt;strong>规格参数&lt;/strong>&lt;/th>
&lt;/tr>
&lt;/thead>
&lt;tbody>
&lt;tr>
&lt;td>&lt;strong>标准流媒体&lt;/strong>&lt;/td>
&lt;td>320 Kbps&lt;/td>
&lt;td>MP3 / AAC&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;strong>CD 级无损&lt;/strong>&lt;/td>
&lt;td>~1.4 Mbps&lt;/td>
&lt;td>16-bit / 44.1kHz&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;strong>Hi-Res 高解析&lt;/strong>&lt;/td>
&lt;td>4.6 - 9.2 Mbps&lt;/td>
&lt;td>&lt;strong>24-bit / 96kHz&lt;/strong>&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;/table>
&lt;h3 id="2-听感的两大维度位深与采样率">2. 听感的两大维度：位深与采样率
&lt;/h3>&lt;ul>
&lt;li>&lt;strong>位深 (Bit Depth) 决定“动态与底噪”&lt;/strong>：从 16-bit 升级到 24-bit，理论动态范围从 96dB 提升至 144dB。这带来了极其深邃的“黑背景”，让你能听清极微弱的乐器余音，起伏更加从容。&lt;/li>
&lt;li>&lt;strong>采样率 (Sample Rate) 决定“空间感与相位”&lt;/strong>：96kHz 保留了大量极高频泛音（Overtones）和录音室的微小反射声。同时，高采样率让抗混叠滤波器（Anti-aliasing Filter）的介入更平缓，保证了高频的时间/相位准确度。大脑正是通过这些高频的时间差来建立**“空间感”&lt;strong>和&lt;/strong>“结像定位”**的。&lt;/li>
&lt;/ul>
&lt;h3 id="3-历史冷知识441khz-的由来">3. 历史冷知识：44.1kHz 的由来
&lt;/h3>&lt;p>早期数字音频没有大容量硬盘存储，工程师只能将其伪装成“视频信号”录在录像带上。为了同时兼容 NTSC（30帧/525行）和 PAL（25帧/625行）两种电视制式，算出了 44,100 Hz 这个完美公约数。&lt;/p>
&lt;hr>
&lt;h2 id="二-信号的翻译与放大-dac-与功放">二、 信号的翻译与放大 (DAC 与功放)
&lt;/h2>&lt;h3 id="1-dac-数模转换器精密的调味师">1. DAC (数模转换器)：精密的“调味师”
&lt;/h3>&lt;p>负责将 0 和 1 的数字包翻译成连续的模拟微电压信号。&lt;/p>
&lt;ul>
&lt;li>&lt;strong>评判好坏的标准&lt;/strong>：
&lt;ul>
&lt;li>&lt;strong>时钟精度&lt;/strong>：顶级 DAC 使用飞秒时钟消除“抖动（Jitter）”，确保时间轴上的绝对精准，否则声音会发干、毛刺。&lt;/li>
&lt;li>&lt;strong>噪底控制&lt;/strong>：优秀的数字滤波和极低的量化噪声。&lt;/li>
&lt;li>&lt;strong>模拟输出级&lt;/strong>：运放（Op-amp）的用料决定了声音最终的色调与质感。&lt;/li>
&lt;/ul>
&lt;/li>
&lt;/ul>
&lt;h3 id="2-前级-运放-vs-后级-功放">2. 前级 (运放) vs 后级 (功放)
&lt;/h3>&lt;ul>
&lt;li>&lt;strong>DAC+运放（前级）处理“电压”&lt;/strong>：它们处理信号级别的能量，负责完美还原声音的波形（乐谱），功率极小。&lt;/li>
&lt;li>&lt;strong>功放（后级）处理“电流”&lt;/strong>：它负责能量放大，为微弱的电压信号注入强大的电流，从而产生足够的物理驱动力去推响沉重的音箱振膜（执行力）。&lt;/li>
&lt;li>&lt;em>注意&lt;/em>：放大信号必然放大底噪。高端功放的核心技术在于&lt;strong>提供巨大推力的同时，维持极高的信噪比 (SNR)&lt;/strong>。&lt;/li>
&lt;/ul>
&lt;hr>
&lt;h2 id="三-发声的物理学电压电流与电容">三、 发声的物理学：电压、电流与电容
&lt;/h2>&lt;h3 id="1-电压与电流的分工">1. 电压与电流的分工
&lt;/h3>&lt;p>在驱动音箱/耳机时：&lt;/p>
&lt;ul>
&lt;li>&lt;strong>电压 (V) 是“信使”&lt;/strong>：代表了音乐波形的形状和高低起伏，决定振膜“该往哪走、走多远”。&lt;/li>
&lt;li>&lt;strong>电流 (I) 是“苦力”&lt;/strong>：根据洛伦兹力公式 &lt;strong>F = B * I * L&lt;/strong>，电流大小直接决定了推动振膜的&lt;strong>物理力道&lt;/strong>。&lt;/li>
&lt;/ul>
&lt;h3 id="2-瞬态失真与削波-clipping">2. 瞬态失真与削波 (Clipping)
&lt;/h3>&lt;p>根据欧姆定律 V = I * R：&lt;/p>
&lt;p>当音乐出现大动态（如定音鼓重击），线圈瞬间需要极大的电流 $I$。如果功放供电不足（给不出足够的电流），系统的实际输出电压 V 就会被迫下垂（Voltage Sag）。&lt;/p>
&lt;ul>
&lt;li>&lt;strong>后果&lt;/strong>：原本圆滑的波形顶部被“削平”，产生奇次谐波失真。听感上就是低音发软、高音撕裂、声音糊成一团。&lt;/li>
&lt;/ul>
&lt;h3 id="3-大电容的作用水压储水罐">3. 大电容的作用：“水压储水罐”
&lt;/h3>&lt;p>为了防止上述的削波失真，功放电路中会配备硕大的储能电容。&lt;/p>
&lt;ul>
&lt;li>&lt;strong>运作逻辑&lt;/strong>：基于公式 Q = C * V。在音乐平缓时，变压器为电容充电（储蓄电荷 Q）。在大动态瞬间，电容作为离晶体管最近的“水塔”，瞬间向电路&lt;strong>释放电荷&lt;/strong>，从而&lt;strong>稳住电压 (V) 不下垂&lt;/strong>，并&lt;strong>提供爆发性的电流 (I)&lt;/strong>。&lt;/li>
&lt;li>&lt;em>结论&lt;/em>：电容的容量和响应速度（超低 ESR）直接决定了音响系统“拳拳到肉”的瞬态爆发力。&lt;/li>
&lt;/ul>
&lt;hr>
&lt;h2 id="四-耳机的阻抗博弈">四、 耳机的阻抗博弈
&lt;/h2>&lt;h3 id="高阻抗耳机的意义">高阻抗耳机的意义
&lt;/h3>&lt;ul>
&lt;li>&lt;strong>物理设计&lt;/strong>：采用极细、极轻的导线绕制极多圈数的线圈。轻量化的音圈带来了无与伦比的“瞬态响应”（起停极其干脆）。&lt;/li>
&lt;li>&lt;strong>驱动逻辑（高压小电流）&lt;/strong>：基于功率公式 P = V^2 / R。为了达到相同功率，高阻抗耳机主动提升阻抗 $R$，从而允许输入更高的电压 V，同时将电流 I 压制在极低水平。&lt;/li>
&lt;li>&lt;strong>优势&lt;/strong>：避免了大电流带来的大发热和线圈烧毁风险，极大降低了输出端的非线性失真，且对线材和接口的接触电阻完全免疫。&lt;/li>
&lt;/ul>
&lt;blockquote>
&lt;p>&lt;strong>关于蓝牙耳机响度的误区&lt;/strong>：蓝牙耳机连不同设备（如 iPad vs iPhone）听感响度不同，并非因为设备的“推力”不同（蓝牙自身内置功放），而是源于系统的&lt;strong>音量归一化策略&lt;/strong>或&lt;strong>绝对音量控制协议&lt;/strong>差异。&lt;/p>&lt;/blockquote></description></item><item><title>Windows 上有关 Torch 的版本管理问题</title><link>https://iwmei.top/p/windows-torch-management/</link><pubDate>Sun, 08 Mar 2026 00:00:00 +0000</pubDate><guid>https://iwmei.top/p/windows-torch-management/</guid><description>&lt;img src="https://iwmei.top/p/windows-torch-management/cover.png" alt="Featured image of post Windows 上有关 Torch 的版本管理问题" />&lt;h1 id="windows上有关torch的版本管理问题">Windows上有关Torch的版本管理问题
&lt;/h1>&lt;h2 id="不要完全相信ai的话">不要完全相信AI的话
&lt;/h2>&lt;ul>
&lt;li>AI在此领域的资料有&lt;strong>明显滞后性&lt;/strong>；&lt;/li>
&lt;li>AI处理环境问题显得非常力不从心，容易陷入&lt;strong>思维定势&lt;/strong>；&lt;/li>
&lt;li>一旦AI然你&lt;strong>重新配置环境&lt;/strong>，立刻放弃继续询问AI。&lt;/li>
&lt;/ul>
&lt;h2 id="配置环境的正确步骤">配置环境的正确步骤
&lt;/h2>&lt;ol>
&lt;li>
&lt;p>如果你使用Nvidia显卡，请务必仔细；&lt;/p>
&lt;/li>
&lt;li>
&lt;p>打开Pytorch官网链接：&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-link" data-lang="link">&lt;span class="line">&lt;span class="cl">&lt;span class="err">[https://pytorch.org/get-started/locally/](https://pytorch.org/get-started/locally/)&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;/li>
&lt;li>
&lt;p>在页面中选择与自身机器匹配的版本：&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-link" data-lang="link">&lt;span class="line">&lt;span class="cl">&lt;span class="err">nvidia-smi&lt;/span> &lt;span class="c"># 在终端执行此命令，查看CUDA版本，若为非Nvidia显卡，则忽略此条&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-link" data-lang="link">&lt;span class="line">&lt;span class="cl">&lt;span class="err">pip3&lt;/span> &lt;span class="err">install&lt;/span> &lt;span class="err">torch&lt;/span> &lt;span class="err">torchaudio&lt;/span> &lt;span class="err">torchvision&lt;/span> &lt;span class="err">--index-url&lt;/span> &lt;span class="err">[https://download.pytorch.org/whl/cu130](https://download.pytorch.org/whl/cu130)&lt;/span> &lt;span class="c"># 根据我的电脑来的，pip3 可换成 pip 或 uv pip&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;/li>
&lt;li>
&lt;p>如果有&lt;strong>torchcodec&lt;/strong>的需求：&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-link" data-lang="link">&lt;span class="line">&lt;span class="cl">&lt;span class="na">[https://github.com/meta-pytorch/torchcodec?tab&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s">readme-ov-file#installing-torchcodec](https://github.com/meta-pytorch/torchcodec?tab=readme-ov-file#installing-torchcodec)&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;ul>
&lt;li>在这里查看与所安装的torch相匹配的版本。&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>
&lt;p>在环境目录下的终端中，运行安装命令。&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-link" data-lang="link">&lt;span class="line">&lt;span class="cl">&lt;span class="err">uv&lt;/span> &lt;span class="err">pip&lt;/span> &lt;span class="err">install&lt;/span> &lt;span class="err">torch&lt;/span> &lt;span class="err">torchaudio&lt;/span> &lt;span class="err">torchvision&lt;/span> &lt;span class="err">--index-url&lt;/span> &lt;span class="err">[https://download.pytorch.org/whl/cu130](https://download.pytorch.org/whl/cu130)&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-link" data-lang="link">&lt;span class="line">&lt;span class="cl">&lt;span class="na">conda install -c conda-forge &amp;#34;torchcodec&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s">*=*cuda*&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;ul>
&lt;li>注意，windows下的torchcodec需要在conda环境下安装，以支持调用cuda加速。&lt;/li>
&lt;/ul>
&lt;/li>
&lt;/ol></description></item><item><title>为什么ISO都100了，噪点还是爆炸？</title><link>https://iwmei.top/p/%E4%B8%BA%E4%BB%80%E4%B9%88iso%E9%83%BD100%E4%BA%86%E5%99%AA%E7%82%B9%E8%BF%98%E6%98%AF%E7%88%86%E7%82%B8/</link><pubDate>Mon, 09 Jun 2025 00:00:00 +0000</pubDate><guid>https://iwmei.top/p/%E4%B8%BA%E4%BB%80%E4%B9%88iso%E9%83%BD100%E4%BA%86%E5%99%AA%E7%82%B9%E8%BF%98%E6%98%AF%E7%88%86%E7%82%B8/</guid><description>&lt;img src="https://iwmei.top/p/%E4%B8%BA%E4%BB%80%E4%B9%88iso%E9%83%BD100%E4%BA%86%E5%99%AA%E7%82%B9%E8%BF%98%E6%98%AF%E7%88%86%E7%82%B8/cover.png" alt="Featured image of post 为什么ISO都100了，噪点还是爆炸？" />&lt;h1 id="前情提要">前情提要
&lt;/h1>&lt;pre>&lt;code>然思齐是一名摄影小白，使用Z30相机在网上自学摄影。他知道，ISO很影响噪点，因此他一直保持ISO100-400。有一次，他和朋友晚上去公园拍摄，即使环境很暗，也坚持400的ISO。回家后导入电脑一看，发现照片有很多噪点，尤其是暗部，密集的彩色噪点极大影响了照片质量。因此他很苦恼，想了解为什么会变成这样。
&lt;/code>&lt;/pre>
&lt;h1 id="噪点的分类">噪点的分类
&lt;/h1>&lt;pre>&lt;code>对于一幅图像上的噪点，可以分为三类：**读出噪声**、**光子散粒噪声**、**热噪声**。
**读出噪声**
&lt;/code>&lt;/pre>
&lt;h2 id="读出噪声">读出噪声
&lt;/h2></description></item><item><title>总览</title><link>https://iwmei.top/%E6%80%BB%E8%A7%88/</link><pubDate>Tue, 28 May 2019 00:00:00 +0000</pubDate><guid>https://iwmei.top/%E6%80%BB%E8%A7%88/</guid><description/></item><item><title/><link>https://iwmei.top/p/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://iwmei.top/p/</guid><description>&lt;h1 id="博客润色固定规范">博客润色固定规范
&lt;/h1>&lt;p>本文件用于约束 &lt;code>content/post&lt;/code> 下文章的润色方式。
后续本线程内提交的每一篇文稿，默认按本规范执行。&lt;/p>
&lt;h2 id="1-目标">1. 目标
&lt;/h2>&lt;ul>
&lt;li>降低 AI 生成痕迹。&lt;/li>
&lt;li>降低与原始稿件的表面相似度。&lt;/li>
&lt;li>保留原文关键信息、观点和结论，不改变事实。&lt;/li>
&lt;li>输出风格符合学术写作基本规范，术语准确，标点规范，逻辑清楚。&lt;/li>
&lt;/ul>
&lt;h2 id="2-语言风格">2. 语言风格
&lt;/h2>&lt;ul>
&lt;li>以直白、准确、自然为主。&lt;/li>
&lt;li>少用修辞，少用夸张表达，避免堆叠形容词。&lt;/li>
&lt;li>避免空泛套话，避免模板化段落开头与结尾。&lt;/li>
&lt;li>语气可口语化，但不随意，不失专业性。&lt;/li>
&lt;li>叙述视角固定为我的第一人称口吻，不使用助手视角或对用户说明式口吻。&lt;/li>
&lt;/ul>
&lt;h2 id="3-句式规则">3. 句式规则
&lt;/h2>&lt;ul>
&lt;li>优先短句，减少长复合句和多层从句。&lt;/li>
&lt;li>一句只承载一个核心信息点。&lt;/li>
&lt;li>允许灵活变换语序，避免整段句式过于工整。&lt;/li>
&lt;li>控制连接词密度，避免首先其次最后反复出现。&lt;/li>
&lt;/ul>
&lt;h2 id="4-结构与信息">4. 结构与信息
&lt;/h2>&lt;ul>
&lt;li>不删减关键事实、数据、限定条件、前提假设。&lt;/li>
&lt;li>不引入原文没有的新结论。&lt;/li>
&lt;li>对重复信息做合并，但保留必要解释链条。&lt;/li>
&lt;li>专业术语保留准确写法，首次出现时可补最短说明。&lt;/li>
&lt;li>若原文是过程记录，优先保留可证明执行过程的细节，包含关键命令、典型报错、定位步骤、修复动作、复测结果。&lt;/li>
&lt;/ul>
&lt;h2 id="5-标点与格式">5. 标点与格式
&lt;/h2>&lt;ul>
&lt;li>中文语境下统一使用中文标点。&lt;/li>
&lt;li>禁止用括号补充说明、编者注或版本标签，不写对读者无增益的元信息。&lt;/li>
&lt;li>减少连续破折号和感叹号堆叠等痕迹化写法。&lt;/li>
&lt;li>段落长度自然，不机械对齐。&lt;/li>
&lt;li>列表仅在确有并列信息时使用，不强行列表化。&lt;/li>
&lt;/ul>
&lt;h2 id="6-每次润色执行清单">6. 每次润色执行清单
&lt;/h2>&lt;ul>
&lt;li>动笔前先通读本规范并按条执行。&lt;/li>
&lt;li>检查是否有 AI 套话，如空泛总结、过度平衡句。&lt;/li>
&lt;li>检查形容词和副词是否过多，能删则删。&lt;/li>
&lt;li>检查长句是否可拆分，拆后是否更清楚。&lt;/li>
&lt;li>检查术语、事实、数字是否与原文一致。&lt;/li>
&lt;li>检查全文语气是否自然统一。&lt;/li>
&lt;li>检查是否全程为我的叙述角度，避免出现用户、我方、助手等第三方代写痕迹词。&lt;/li>
&lt;/ul>
&lt;h2 id="7-默认工作方式">7. 默认工作方式
&lt;/h2>&lt;ul>
&lt;li>你提供原稿后，我直接给出润色稿。&lt;/li>
&lt;li>如你未特别说明，我会在保留原意的前提下进行中等强度改写。&lt;/li>
&lt;li>如你要求，我可切换为轻度改写，最小改动，或重度改写，更大幅度重写表达。&lt;/li>
&lt;/ul>
&lt;h2 id="8-生效范围">8. 生效范围
&lt;/h2>&lt;ul>
&lt;li>本规则对本仓库后续所有博客润色任务持续生效，直至你明确要求修改或废止。&lt;/li>
&lt;/ul></description></item><item><title>关于</title><link>https://iwmei.top/%E5%85%B3%E4%BA%8E/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://iwmei.top/%E5%85%B3%E4%BA%8E/</guid><description>&lt;p>This is a test page for i18n support.&lt;/p></description></item><item><title>快速链接</title><link>https://iwmei.top/%E5%BF%AB%E9%80%9F%E9%93%BE%E6%8E%A5/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://iwmei.top/%E5%BF%AB%E9%80%9F%E9%93%BE%E6%8E%A5/</guid><description/></item><item><title>设计令牌</title><link>https://iwmei.top/%E8%AE%BE%E8%AE%A1%E4%BB%A4%E7%89%8C/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://iwmei.top/%E8%AE%BE%E8%AE%A1%E4%BB%A4%E7%89%8C/</guid><description>&lt;h2 id="svg图标">SVG图标
&lt;/h2>&lt;div class="iconlib-grid">
&lt;a class="iconlib-card" href="https://github.com/mingcute-design/mingcute-icons" target="_blank" rel="noopener">
&lt;div class="iconlib-logo">&lt;img src="mingcute.png" alt="MingCute Icons" loading="lazy">&lt;/div>
&lt;div class="iconlib-details">
&lt;h2>MingCute Icons&lt;/h2>
&lt;p>精心设计的开源图标库，提供1663个核心图标，覆盖常规与实心两种风格。&lt;/p>
&lt;/div>
&lt;/a>
&lt;a class="iconlib-card" href="https://github.com/saoudi-h/solar-icons" target="_blank" rel="noopener">
&lt;div class="iconlib-logo">&lt;img src="solar.png" alt="Solar Icons" loading="lazy">&lt;/div>
&lt;div class="iconlib-details">
&lt;h2>Solar Icons&lt;/h2>
&lt;p>1451个图标的统一目录，六种风格同源输出，适配主流框架与设计工具。&lt;/p>
&lt;/div>
&lt;/a>
&lt;a class="iconlib-card" href="https://github.com/iconoir-icons/iconoir" target="_blank" rel="noopener">
&lt;div class="iconlib-logo">&lt;img src="iconoir.png" alt="Iconoir" loading="lazy">&lt;/div>
&lt;div class="iconlib-details">
&lt;h2>Iconoir&lt;/h2>
&lt;p>基于24像素网格的1600余个SVG图标，风格克制，覆盖Web与移动端场景。&lt;/p>
&lt;/div>
&lt;/a>
&lt;/div>
&lt;h2 id="色卡">色卡
&lt;/h2>&lt;p>待上传&lt;/p>
&lt;h2 id="ui布局">UI布局
&lt;/h2>&lt;p>待上传&lt;/p></description></item><item><title>搜索</title><link>https://iwmei.top/%E6%90%9C%E7%B4%A2/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://iwmei.top/%E6%90%9C%E7%B4%A2/</guid><description/></item></channel></rss>