<?xml version="1.0" encoding="utf-8"?><?xml-stylesheet type="text/xsl" href="atom.xsl"?>
<feed xmlns="http://www.w3.org/2005/Atom">
    <id>https://feifeigd.github.io/blog</id>
    <title>d7kj Blog</title>
    <updated>2026-07-16T10:00:00.000Z</updated>
    <generator>https://github.com/jpmonette/feed</generator>
    <link rel="alternate" href="https://feifeigd.github.io/blog"/>
    <subtitle>d7kj Blog</subtitle>
    <entry>
        <title type="html"><![CDATA[一文讲透如何构建 Harness——六大组件全解析]]></title>
        <id>https://feifeigd.github.io/blog/2026/07/16/harness-six-components</id>
        <link href="https://feifeigd.github.io/blog/2026/07/16/harness-six-components"/>
        <updated>2026-07-16T10:00:00.000Z</updated>
        <summary type="html"><![CDATA[深入拆解 AI Agent 的 Harness 六大组件——文件系统、Bash+沙箱、AGENTS.md 记忆、Web Search+MCP、上下文工程、编排+Hooks，以及贯穿始终的 System Prompt。]]></summary>
        <content type="html"><![CDATA[<blockquote>
<p>本文是对腾讯云开发者社区文章<a href="https://cloud.tencent.com/developer/article/2648873" target="_blank" rel="noopener noreferrer" class="">《一文讲透如何构建 Harness——六大组件全解析》</a>（作者：李伟山）的阅读总结与深度解读。原文详细拆解了 AI Agent 工程中最重要的概念之一——<strong>Harness</strong>，本文在保留核心观点的同时做了结构化的梳理。</p>
</blockquote>
<!-- -->
<hr>
<h2 class="anchor anchorTargetStickyNavbar_e8hc" id="tldr">TL;DR<a href="https://feifeigd.github.io/blog/2026/07/16/harness-six-components#tldr" class="hash-link" aria-label="TL;DR的直接链接" title="TL;DR的直接链接" translate="no">​</a></h2>
<p><strong>Agent = Model + Harness</strong>。模型提供智能，Harness 让智能变得有用。如果你不是模型本身，那你就是 Harness 的一部分。</p>
<p>这句话贯穿了整篇文章的始终。2025 年的一个真实案例：花三个月调 Prompt，任务完成率提升 20%；花两周搭 Harness，完成率飙到 82%。</p>
<p>方向错了——答案不在模型层，在 Harness 层。</p>
<hr>
<h2 class="anchor anchorTargetStickyNavbar_e8hc" id="裸模型的四个硬伤">裸模型的四个硬伤<a href="https://feifeigd.github.io/blog/2026/07/16/harness-six-components#%E8%A3%B8%E6%A8%A1%E5%9E%8B%E7%9A%84%E5%9B%9B%E4%B8%AA%E7%A1%AC%E4%BC%A4" class="hash-link" aria-label="裸模型的四个硬伤�的直接链接" title="裸模型的四个硬伤的直接链接" translate="no">​</a></h2>
<p>在讨论 Harness 之前，先看裸模型（Raw Model）的致命缺陷：</p>
<table><thead><tr><th>硬伤</th><th>表现</th><th>Harness 对应组件</th></tr></thead><tbody><tr><td><strong>无跨会话记忆</strong></td><td>关掉窗口就失忆，每次从头解释</td><td>文件系统 + AGENTS.md</td></tr><tr><td><strong>不能执行代码</strong></td><td>只能生成代码文本，不能运行验证</td><td>Bash + 沙箱</td></tr><tr><td><strong>知识有截止日期</strong></td><td>新 API、新框架、新漏洞都不知道</td><td>Web Search + MCP</td></tr><tr><td><strong>没有工作环境</strong></td><td>不能建文件、不能组织项目、不能管理依赖</td><td>文件系统 + 上下文工程 + 编排</td></tr></tbody></table>
<blockquote>
<p>每一「不能」，都是 Harness 里的一个组件。Harness 不是锦上添花，是对裸模型致命缺陷的系统性补救。</p>
</blockquote>
<hr>
<h2 class="anchor anchorTargetStickyNavbar_e8hc" id="六大组件逐层拆解">六大组件逐层拆解<a href="https://feifeigd.github.io/blog/2026/07/16/harness-six-components#%E5%85%AD%E5%A4%A7%E7%BB%84%E4%BB%B6%E9%80%90%E5%B1%82%E6%8B%86%E8%A7%A3" class="hash-link" aria-label="六大组件逐层拆解的直接链接" title="六大组件逐层拆解的直接链接" translate="no">​</a></h2>
<h3 class="anchor anchorTargetStickyNavbar_e8hc" id="一文件系统最基础的原语">一、文件系统——最基础的原语<a href="https://feifeigd.github.io/blog/2026/07/16/harness-six-components#%E4%B8%80%E6%96%87%E4%BB%B6%E7%B3%BB%E7%BB%9F%E6%9C%80%E5%9F%BA%E7%A1%80%E7%9A%84%E5%8E%9F%E8%AF%AD" class="hash-link" aria-label="一、文件系统——最基础的原语的直接链接" title="一、文件系统——最基础的原语的直接链接" translate="no">​</a></h3>
<blockquote>
<p>文件系统 + Git 给了 Agent「试错」的能力。</p>
</blockquote>
<p>文件系统是一切工程活动的地基，也是 Agent 突破上下文窗口限制的唯一途径。</p>
<p><strong>三大核心能力：</strong></p>
<ol>
<li class=""><strong>工作空间与中间结果存储</strong>——把中间产物写入文件，需要时再读取，实现按需加载</li>
<li class=""><strong>Agent 协作的基础</strong>——Agent A 写文件，Agent B 读文件，文件就是共享白板</li>
<li class=""><strong>版本追踪与错误回滚</strong>——结合 Git，Agent 可以大胆尝试，随时回滚</li>
</ol>
<p><strong>设计原则：</strong></p>
<ul>
<li class="">目录结构要清晰且约定俗成</li>
<li class="">文件粒度要适中（一个模块一个文件）</li>
<li class="">元数据要丰富（文件名有意义、目录有 README）</li>
</ul>
<hr>
<h3 class="anchor anchorTargetStickyNavbar_e8hc" id="二bash--沙箱从说到做">二、Bash + 沙箱——从「说」到「做」<a href="https://feifeigd.github.io/blog/2026/07/16/harness-six-components#%E4%BA%8Cbash--%E6%B2%99%E7%AE%B1%E4%BB%8E%E8%AF%B4%E5%88%B0%E5%81%9A" class="hash-link" aria-label="二、Bash + 沙箱——从「说」到「做」的直接链接" title="二、Bash + 沙箱——从「说」到「做」的直接链接" translate="no">​</a></h3>
<blockquote>
<p>没有 Bash，Agent 是一个提建议的顾问；有了 Bash，Agent 是动手做的工程师。</p>
</blockquote>
<p><strong>自我验证循环</strong>：<code>写 → 跑 → 看 → 修 → 再来</code></p>
<p>这个循环让 Agent 拥有了自我纠错能力。实测数据显示：具备自我验证循环的 Agent，任务完成率比一次性生成高出 <strong>40%–60%</strong>——这个差距不来自更好的模型，而完全来自 Harness 层的 Bash。</p>
<p><strong>为什么必须要有沙箱？</strong></p>
<ul>
<li class="">资源限制（CPU、内存、磁盘上限）</li>
<li class="">网络隔离（默认禁止外部访问）</li>
<li class="">文件系统隔离（只能访问工作目录）</li>
<li class="">超时机制（自动终止长时间执行）</li>
</ul>
<p>常见的沙箱方案：Docker（最主流）、gVisor/Firecracker（轻量）、WASM（边缘计算）、Nix（确定性环境）。</p>
<hr>
<h3 class="anchor anchorTargetStickyNavbar_e8hc" id="三记忆agentsmd不改权重给模型加知识">三、记忆（AGENTS.md）——不改权重给模型加知识<a href="https://feifeigd.github.io/blog/2026/07/16/harness-six-components#%EF%BF%BD%EF%BF%BD%E4%B8%89%E8%AE%B0%E5%BF%86agentsmd%E4%B8%8D%E6%94%B9%E6%9D%83%E9%87%8D%E7%BB%99%E6%A8%A1%E5%9E%8B%E5%8A%A0%E7%9F%A5%E8%AF%86" class="hash-link" aria-label="三、记忆（AGENTS.md）——不改权重给模型加知识的直接链接" title="三、记忆（AGENTS.md）——不改权重给模型加知识的直接链接" translate="no">​</a></h3>
<p>这是六大组件中最容易被低估、但可能最具长期价值的一个。</p>
<p><strong>工作机制：</strong></p>
<div class="language-text codeBlockContainer_zaIt theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_SaHH"><pre tabindex="0" class="prism-code language-text codeBlock_KlaO thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_zkpV"><div class="token-line" style="color:#393A34"><span class="token plain">工作中发现知识 → 写入 AGENTS.md → 下次自动注入上下文</span><br></div></code></pre></div></div>
<p><strong>关键洞察</strong>：<code>上下文注入 = 不改权重给模型加知识</code></p>
<p>传统微调成本高、周期长、有灾难性遗忘风险。AGENTS.md 提供了一条捷径——不碰模型权重，只通过上下文注入来添加知识。今天发现的最佳实践，写进 AGENTS.md，明天 Agent 就自动具备了这个知识。</p>
<p><strong>最佳实践：</strong></p>
<ul>
<li class=""><strong>层次化存放</strong>——根目录放全局知识，子目录放局部知识</li>
<li class=""><strong>结构化书写</strong>——不是随意笔记，是有明确结构的知识库</li>
<li class=""><strong>定期清理</strong>——过时的知识比没有知识更危险</li>
<li class=""><strong>双向可编辑</strong>——人类可以直接编辑 AGENTS.md 来向 Agent 传达偏好</li>
</ul>
<hr>
<h3 class="anchor anchorTargetStickyNavbar_e8hc" id="四web-search--mcp突破知识的时间牢笼">四、Web Search + MCP——突破知识的「时间牢笼」<a href="https://feifeigd.github.io/blog/2026/07/16/harness-six-components#%E5%9B%9Bweb-search--mcp%E7%AA%81%E7%A0%B4%E7%9F%A5%E8%AF%86%E7%9A%84%E6%97%B6%E9%97%B4%E7%89%A2%E7%AC%BC" class="hash-link" aria-label="四、Web Search + MCP——�突破知识的「时间牢笼」的直接链接" title="四、Web Search + MCP——突破知识的「时间牢笼」的直接链接" translate="no">​</a></h3>
<blockquote>
<p>Web Search 让 Agent 能「看」互联网，MCP 让 Agent 能「触」互联网。</p>
</blockquote>
<p><strong>Web Search</strong> 解决的是知识截止日期问题。好的搜索组件不仅要能搜索，还要能构建查询、筛选结果、提取核心内容、整合多源信息。</p>
<p><strong>MCP（Model Context Protocol）</strong> 是 Anthropic 推出的开放协议，定义了 AI 模型与外部工具之间的标准化交互方式。可以把 MCP 理解为「AI 世界的数据线」——数据库、Jira、GitHub、监控系统……只要有 MCP 接口，Agent 就能直接访问。</p>
<p><strong>协同效应示例——Debug 生产环境 Bug：</strong></p>
<ol>
<li class="">MCP 连接监控系统 → 获取错误日志</li>
<li class="">MCP 连接代码仓库 → 查看相关代码和历史变更</li>
<li class="">Web Search 搜索错误信息 → 查找社区解决方案</li>
<li class="">MCP 连接项目管理工具 → 检查已知问题</li>
<li class="">Agent 综合所有信息 → 生成修复方案并提交 PR</li>
</ol>
<hr>
<h3 class="anchor anchorTargetStickyNavbar_e8hc" id="五上下文工程对抗-ai-系统的熵增">五、上下文工程——对抗 AI 系统的「熵增」<a href="https://feifeigd.github.io/blog/2026/07/16/harness-six-components#%E4%BA%94%E4%B8%8A%E4%B8%8B%E6%96%87%E5%B7%A5%E7%A8%8B%E5%AF%B9%E6%8A%97-ai-%E7%B3%BB%E7%BB%9F%E7%9A%84%E7%86%B5%E5%A2%9E" class="hash-link" aria-label="五、上下文工程——对抗 AI 系统的「熵增」的直接链接" title="五、上下文工程——对抗 AI 系统的「熵增」的直接链接" translate="no">​</a></h3>
<blockquote>
<p>Harness 的本质就是好的上下文工程的交付机制。</p>
</blockquote>
<p><strong>Context Rot（上下文腐烂）</strong>——长时间运行的 Agent 会话中，大量信息在上下文中积累，导致：</p>
<ul>
<li class="">信噪比下降，关键指令被稀释</li>
<li class="">矛盾信息累积，输出不一致</li>
<li class="">Token 浪费，有效空间被挤压</li>
<li class="">推理质量退化（「大海捞针」问题的实践版）</li>
</ul>
<p><strong>核心策略：</strong></p>
<table><thead><tr><th>策略</th><th>做法</th></tr></thead><tbody><tr><td><strong>压缩</strong></td><td>定期摘要历史上下文，将详细过程替换为结论</td></tr><tr><td><strong>工具输出卸载</strong></td><td>工具输出存文件，上下文中只留摘要和引用</td></tr><tr><td><strong>渐进加载</strong></td><td>根据当前任务阶段动态加载/卸载知识</td></tr><tr><td><strong>分层结构</strong></td><td>核心层（始终保留）→ 工作层（按需更新）→ 历史层（逐渐压缩）</td></tr></tbody></table>
<p>上下文工程在 2025 年底开始取代「Prompt 工程」成为核心话题——Prompt 工程关注「怎么写指令」，上下文工程关注「怎么构建模型看到的全部信息」，后者的范围大得多。</p>
<hr>
<h3 class="anchor anchorTargetStickyNavbar_e8hc" id="六编排--hooks让单兵作战变成集团军">六、编排 + Hooks——让单兵作战变成集团军<a href="https://feifeigd.github.io/blog/2026/07/16/harness-six-components#%E5%85%AD%E7%BC%96%E6%8E%92--hooks%E8%AE%A9%E5%8D%95%E5%85%B5%E4%BD%9C%E6%88%98%E5%8F%98%E6%88%90%E9%9B%86%E5%9B%A2%E5%86%9B" class="hash-link" aria-label="六、编排 + Hooks——让单兵作战变成集团军的直接链接" title="六、编排 + Hooks——让单兵作战变成集团军的直接链接" translate="no">​</a></h3>
<p>前五个组件增强单个 Agent，最后一个组件把多个 Agent 组织成协同作战的系统。</p>
<p><strong>编排解决的核心问题：</strong></p>
<ul>
<li class=""><strong>子 Agent 调度</strong>——并行还是串行？依赖关系是什么？</li>
<li class=""><strong>任务分发</strong>——模糊大任务 → 明确小任务</li>
<li class=""><strong>模型路由</strong>——简单任务用小模型，复杂任务用大模型</li>
<li class=""><strong>结果聚合</strong>——检查一致性、解决冲突、合并输出</li>
</ul>
<p><strong>编排模式的演进：</strong></p>
<div class="language-text codeBlockContainer_zaIt theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_SaHH"><pre tabindex="0" class="prism-code language-text codeBlock_KlaO thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_zkpV"><div class="token-line" style="color:#393A34"><span class="token plain">线性管道 → DAG 编排 → 动态编排 → 层级编排</span><br></div></code></pre></div></div>
<p><strong>Hooks——注入确定性：</strong> 用确定性的规则约束概率性的模型输出。</p>
<p>典型场景：</p>
<ul>
<li class=""><strong>Lint 检查</strong>——生成代码后自动运行 Linter</li>
<li class=""><strong>续接钩子</strong>——输出被截断时自动续接</li>
<li class=""><strong>格式约束</strong>——JSON Schema 验证、Markdown 结构检查</li>
<li class=""><strong>安全过滤</strong>——敏感操作前权限检查</li>
<li class=""><strong>成本控制</strong>——监控 Token 消耗，接近上限时警告</li>
</ul>
<blockquote>
<p>概率性生成 + 确定性校验 = 当前 Agent 工程最有效的质量保障策略。</p>
</blockquote>
<hr>
<h2 class="anchor anchorTargetStickyNavbar_e8hc" id="system-prompt贯穿所有组件的神经系统">System Prompt：贯穿所有组件的「神经系统」<a href="https://feifeigd.github.io/blog/2026/07/16/harness-six-components#system-prompt%E8%B4%AF%E7%A9%BF%E6%89%80%E6%9C%89%E7%BB%84%E4%BB%B6%E7%9A%84%E7%A5%9E%E7%BB%8F%E7%B3%BB%E7%BB%9F" class="hash-link" aria-label="System Prompt：贯穿所有组件的「神经系统」的直接链接" title="System Prompt：贯穿所有组件的「神经系统」的直接链接" translate="no">​</a></h2>
<p>System Prompt 不是第七个组件，但它扮演着四个关键角色：</p>
<ol>
<li class=""><strong>定义角色边界</strong>——告诉模型「你是谁」和「你不是谁」</li>
<li class=""><strong>注入领域知识</strong>——零成本知识注入的第一入口</li>
<li class=""><strong>约束安全规则</strong>——Agent 安全策略的第一道防线</li>
<li class=""><strong>贯穿所有组件</strong>——间接定义文件组织规范、命令范围、知识格式、搜索标准、压缩策略、任务分解粒度</li>
</ol>
<blockquote>
<p>写 System Prompt 就是在设计 Harness 的行为规范。好的 System Prompt 就像好的公司章程——不直接做任何事，但决定了所有事怎么做。</p>
</blockquote>
<hr>
<h2 class="anchor anchorTargetStickyNavbar_e8hc" id="总结">总结<a href="https://feifeigd.github.io/blog/2026/07/16/harness-six-components#%E6%80%BB%E7%BB%93" class="hash-link" aria-label="总结的直接链接" title="总结的直接链接" translate="no">​</a></h2>
<table><thead><tr><th>组件</th><th>一句话概括</th></tr></thead><tbody><tr><td><strong>文件系统</strong></td><td>工程活动的地基，Agent 的外部大脑</td></tr><tr><td><strong>Bash + 沙箱</strong></td><td>从生成到执行，让代码自我验证</td></tr><tr><td><strong>AGENTS.md</strong></td><td>不改权重，即插即用的知识注入</td></tr><tr><td><strong>Web Search + MCP</strong></td><td>打破知识截止日期，连接外部世界</td></tr><tr><td><strong>上下文工程</strong></td><td>对抗 Context Rot，管理注意力</td></tr><tr><td><strong>编排 + Hooks</strong></td><td>多 Agent 协同，确定性兜底</td></tr></tbody></table>
<p><strong>模型决定了 Agent 能力的下限，Harness 决定了 Agent 能力的上限。</strong></p>
<p>下次调试 Agent 表现时，不要急着换更强的模型——先看看你的 Harness：文件系统完善吗？沙箱安全吗？记忆机制在工作吗？上下文腐烂了吗？编排合理吗？Hooks 在兜底吗？</p>
<p>也许答案就在那里。</p>
<hr>
<p><em>原文：<a href="https://cloud.tencent.com/developer/article/2648873" target="_blank" rel="noopener noreferrer" class="">一文讲透如何构建 Harness——六大组件全解析</a> — 腾讯云开发者社区 · 作者：李伟山</em></p>]]></content>
        <category label="ai" term="ai"/>
        <category label="agent" term="agent"/>
        <category label="harness" term="harness"/>
        <category label="llm" term="llm"/>
        <category label="engineering" term="engineering"/>
        <category label="system-design" term="system-design"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[uni-app 离线 SDK 打包 Android APK 完整指南]]></title>
        <id>https://feifeigd.github.io/blog/2026/07/16/uni-app-offline-sdk-android-packaging</id>
        <link href="https://feifeigd.github.io/blog/2026/07/16/uni-app-offline-sdk-android-packaging"/>
        <updated>2026-07-16T04:00:00.000Z</updated>
        <summary type="html"><![CDATA[基于 HBuilderX 离线 SDK（5.15 版本）手动构建 uni-app Android APK 的完整流程，从编译资源到签名安装]]></summary>
        <content type="html"><![CDATA[<blockquote>
<p>本文记录了 uni-app 项目通过 HBuilderX 离线 SDK 打包 Android APK 的全过程。适用于 5.15 版本 SDK，内容包括环境准备、Gradle 工程搭建、资源编译、签名配置、APK 构建及调试安装。如果你习惯 CLI 而非 GUI 打包，这篇就是为你准备的。</p>
</blockquote>
<!-- -->
<hr>
<h2 class="anchor anchorTargetStickyNavbar_e8hc" id="背景">背景<a href="https://feifeigd.github.io/blog/2026/07/16/uni-app-offline-sdk-android-packaging#%E8%83%8C%E6%99%AF" class="hash-link" aria-label="背景的直接链接" title="背景的直接链接" translate="no">​</a></h2>
<p>uni-app 官方提供了两种打包方式：</p>
<ul>
<li class=""><strong>云端打包</strong> — 在 HBuilderX 里点「发行 → 原生App-云打包」，省事但依赖网络、排队慢、不能自定义原生层代码</li>
<li class=""><strong>离线打包</strong> — 下载 Android 离线 SDK，本地构建 APK，速度快、可定制、适合 CI/CD</li>
</ul>
<p>本文围绕后者展开。离线打包的核心思路并不复杂：HBuilderX 只负责编译前端资源（WXML/WXSS/JS → app-service.js / app-view.js），然后把这些产物塞进一个标准的 Android Gradle 工程中，跟离线 SDK 提供的 AAR 基座一起编译出 APK。</p>
<hr>
<h2 class="anchor anchorTargetStickyNavbar_e8hc" id="环境">环境<a href="https://feifeigd.github.io/blog/2026/07/16/uni-app-offline-sdk-android-packaging#%E7%8E%AF%E5%A2%83" class="hash-link" aria-label="环境的直接链接" title="环境的直接链接" translate="no">​</a></h2>
<table><thead><tr><th>工具</th><th>路径</th></tr></thead><tbody><tr><td>HBuilderX CLI</td><td><code>G:\HBuilderX\cli.exe</code></td></tr><tr><td>离线 SDK</td><td><code>Android-SDK@5.15.82650_20260710.zip</code></td></tr><tr><td>签名证书</td><td><code>gala.jks</code> (alias: Gala, 密码: gala123)</td></tr><tr><td>ADB</td><td><code>G:\Android\Sdk\platform-tools\adb.exe</code></td></tr></tbody></table>
<p>离线 SDK 从 <a href="https://nativesupport.dcloud.net.cn/AppDocs/usesdk/android.html" target="_blank" rel="noopener noreferrer" class="">官方下载页</a> 获取，下载后解压到任意目录即可。</p>
<h3 class="anchor anchorTargetStickyNavbar_e8hc" id="项目配置">项目配置<a href="https://feifeigd.github.io/blog/2026/07/16/uni-app-offline-sdk-android-packaging#%E9%A1%B9%E7%9B%AE%E9%85%8D%E7%BD%AE" class="hash-link" aria-label="项目配置的直接链接" title="项目配置的直接链接" translate="no">​</a></h3>
<table><thead><tr><th>配置项</th><th>值</th></tr></thead><tbody><tr><td>AppID</td><td><code>__UNI__7AFEA31</code></td></tr><tr><td>包名</td><td><code>best.win365.games777</code></td></tr><tr><td>应用名</td><td>Luckyspin777</td></tr><tr><td>AppKey</td><td><code>7aa06e6e03531b5772584d6b069bbaaf</code></td></tr><tr><td>版本</td><td>1.3.6 (code: 37)</td></tr></tbody></table>
<hr>
<h2 class="anchor anchorTargetStickyNavbar_e8hc" id="工程结构一览">工程结构一览<a href="https://feifeigd.github.io/blog/2026/07/16/uni-app-offline-sdk-android-packaging#%E5%B7%A5%E7%A8%8B%E7%BB%93%E6%9E%84%E4%B8%80%E8%A7%88" class="hash-link" aria-label="工程结构一览的直接链接" title="工程结构一览的直接链接" translate="no">​</a></h2>
<p>离线打包工程是一个标准的 Android Gradle 项目，其核心结构如下：</p>
<div class="language-text codeBlockContainer_zaIt theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_SaHH"><pre tabindex="0" class="prism-code language-text codeBlock_KlaO thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_zkpV"><div class="token-line" style="color:#393A34"><span class="token plain">android_project/</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">├── build.gradle                  # 根 build 配置</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">├── settings.gradle               # include ':simpleDemo'</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">├── gradle.properties             # android.useAndroidX=true</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">├── gradlew / gradlew.bat         # Gradle Wrapper</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">├── gradle/                       # Wrapper 依赖</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">└── simpleDemo/                   # App 模块</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    ├── build.gradle              # 模块 build 配置（含签名、依赖）</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    ├── gala.jks                  # 签名证书</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    ├── proguard-rules.pro        # 混淆规则</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    ├── libs/                     # 离线 SDK AAR（从 SDK 包提取）</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    └── src/main/</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        ├── AndroidManifest.xml   # 含 dcloud_appkey</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        ├── res/</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        │   ├── drawable/icon.png</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        │   └── values/strings.xml</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        └── assets/</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">            ├── data/</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">            │   ├── dcloud_control.xml    # appid 配置</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">            │   └── dcloud_properties.xml # 功能模块注册</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">            └── apps/</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">                └── __UNI__7AFEA31/</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">                    └── www/              # HBuilderX 编译产物</span><br></div></code></pre></div></div>
<p>工程的精髓在 <code>libs/</code> 和 <code>assets/apps/</code> 两个目录：</p>
<ul>
<li class=""><strong><code>libs/</code></strong> — 离线 SDK 的基座运行时，包含 30+ 个 AAR 文件</li>
<li class=""><strong><code>assets/apps/__UNI__7AFEA31/www/</code></strong> — uni-app 的前端编译产物</li>
</ul>
<hr>
<h2 class="anchor anchorTargetStickyNavbar_e8hc" id="构建步骤">构建步骤<a href="https://feifeigd.github.io/blog/2026/07/16/uni-app-offline-sdk-android-packaging#%E6%9E%84%E5%BB%BA%E6%AD%A5%E9%AA%A4" class="hash-link" aria-label="构建步骤的直接链接" title="构建步骤的直接链接" translate="no">​</a></h2>
<h3 class="anchor anchorTargetStickyNavbar_e8hc" id="第-1-步编译项目资源">第 1 步：编译项目资源<a href="https://feifeigd.github.io/blog/2026/07/16/uni-app-offline-sdk-android-packaging#%E7%AC%AC-1-%E6%AD%A5%E7%BC%96%E8%AF%91%E9%A1%B9%E7%9B%AE%E8%B5%84%E6%BA%90" class="hash-link" aria-label="第 1 步：编译项目资源的直接链接" title="第 1 步：编译项目资源的直接链接" translate="no">​</a></h3>
<div class="language-bash codeBlockContainer_zaIt theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_SaHH"><pre tabindex="0" class="prism-code language-bash codeBlock_KlaO thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_zkpV"><div class="token-line" style="color:#393A34"><span class="token plain">G:\HBuilderX\cli.exe publish app \</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    --project I:\game\rus-game\rus-client \</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    --type appResource \</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    --platform app</span><br></div></code></pre></div></div>
<p>这条命令把 uni-app 项目编译为原生可用的静态资源。产物输出到 <code>unpackage/resources/__UNI__7AFEA31/www/</code> 目录，主要文件包括：</p>
<ul>
<li class=""><code>manifest.json</code> — 应用配置</li>
<li class=""><code>app-service.js</code> — 逻辑层代码</li>
<li class=""><code>app-view.js</code> — 视图层代码</li>
<li class=""><code>view.umd.min.js</code> — UMD 视图运行时</li>
<li class=""><code>static/</code> — 静态资源目录</li>
</ul>
<h3 class="anchor anchorTargetStickyNavbar_e8hc" id="第-2-步复制资源到-android-工程">第 2 步：复制资源到 Android 工程<a href="https://feifeigd.github.io/blog/2026/07/16/uni-app-offline-sdk-android-packaging#%E7%AC%AC-2-%E6%AD%A5%E5%A4%8D%E5%88%B6%E8%B5%84%E6%BA%90%E5%88%B0-android-%E5%B7%A5%E7%A8%8B" class="hash-link" aria-label="第 2 步：复制资源到 Android 工程的直接链接" title="第 2 步：复制资源到 Android 工程的直接链接" translate="no">​</a></h3>
<div class="language-bash codeBlockContainer_zaIt theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_SaHH"><pre tabindex="0" class="prism-code language-bash codeBlock_KlaO thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_zkpV"><div class="token-line" style="color:#393A34"><span class="token plain">rm -rf android_project/simpleDemo/src/main/assets/apps/</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">mkdir -p android_project/simpleDemo/src/main/assets/apps/__UNI__7AFEA31/www/</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">cp -r unpackage/resources/__UNI__7AFEA31/www/* \</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">      android_project/simpleDemo/src/main/assets/apps/__UNI__7AFEA31/www/</span><br></div></code></pre></div></div>
<p>这步的本质是：把 HBuilderX 的编译输出「装进」Android 工程的 assets 目录里，让 native 层能通过路径加载前端资源。</p>
<h3 class="anchor anchorTargetStickyNavbar_e8hc" id="第-3-步构建-apk">第 3 步：构建 APK<a href="https://feifeigd.github.io/blog/2026/07/16/uni-app-offline-sdk-android-packaging#%E7%AC%AC-3-%E6%AD%A5%E6%9E%84%E5%BB%BA-apk" class="hash-link" aria-label="第 3 步：构建 APK的直接链接" title="第 3 步：构建 APK的直接链接" translate="no">​</a></h3>
<div class="language-bash codeBlockContainer_zaIt theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_SaHH"><pre tabindex="0" class="prism-code language-bash codeBlock_KlaO thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_zkpV"><div class="token-line" style="color:#393A34"><span class="token plain">cd android_project</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">gradlew.bat clean assembleRelease</span><br></div></code></pre></div></div>
<p>产物路径：<code>simpleDemo/build/outputs/apk/release/simpleDemo-release.apk</code>，大小约 33MB。</p>
<p><code>clean</code> 不是必须的，但建议每次都跑一下，避免缓存污染导致莫名其妙的构建问题。</p>
<h3 class="anchor anchorTargetStickyNavbar_e8hc" id="第-4-步安装运行">第 4 步：安装运行<a href="https://feifeigd.github.io/blog/2026/07/16/uni-app-offline-sdk-android-packaging#%E7%AC%AC-4-%E6%AD%A5%E5%AE%89%E8%A3%85%E8%BF%90%E8%A1%8C" class="hash-link" aria-label="第 4 步：安装运行的直接链接" title="第 4 步：安装运行的直接链接" translate="no">​</a></h3>
<div class="language-bash codeBlockContainer_zaIt theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_SaHH"><pre tabindex="0" class="prism-code language-bash codeBlock_KlaO thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_zkpV"><div class="token-line" style="color:#393A34"><span class="token plain">adb install -r -d simpleDemo/build/outputs/apk/release/simpleDemo-release.apk</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">adb shell am start -n best.win365.games777/io.dcloud.PandoraEntry</span><br></div></code></pre></div></div>
<p><code>-r</code> 覆盖安装，<code>-d</code> 允许降级（版本号比已安装的低时也能装）。启动 Activity 是 <code>io.dcloud.PandoraEntry</code>，这个是 5+ Runtime 的主入口。</p>
<hr>
<h2 class="anchor anchorTargetStickyNavbar_e8hc" id="关键文件详解">关键文件详解<a href="https://feifeigd.github.io/blog/2026/07/16/uni-app-offline-sdk-android-packaging#%E5%85%B3%E9%94%AE%E6%96%87%E4%BB%B6%E8%AF%A6%E8%A7%A3" class="hash-link" aria-label="关键文件详解的直接链接" title="关键文件详解的直接链接" translate="no">​</a></h2>
<h3 class="anchor anchorTargetStickyNavbar_e8hc" id="1-simpledemobuildgradle">1. <code>simpleDemo/build.gradle</code><a href="https://feifeigd.github.io/blog/2026/07/16/uni-app-offline-sdk-android-packaging#1-simpledemobuildgradle" class="hash-link" aria-label="1-simpledemobuildgradle的直接链接" title="1-simpledemobuildgradle的直接链接" translate="no">​</a></h3>
<p>模块级构建配置，核心内容：</p>
<div class="language-groovy codeBlockContainer_zaIt theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_SaHH"><pre tabindex="0" class="prism-code language-groovy codeBlock_KlaO thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_zkpV"><div class="token-line" style="color:#393A34"><span class="token plain">namespace 'best.win365.games777'</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">applicationId "best.win365.games777"</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">// 签名配置</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">keyAlias 'Gala'</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">keyPassword 'gala123'</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">storeFile file('gala.jks')</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">storePassword 'gala123'</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">// 5.15 SDK 专用依赖</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">implementation "com.facebook.fresco:fresco:3.4.0"</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">implementation "com.facebook.fresco:animated-gif:3.4.0"</span><br></div></code></pre></div></div>
<blockquote>
<p><strong>特别注意</strong>：Fresco 的版本必须与离线 SDK 版本匹配。5.15 要求 fresco <code>3.4.0</code>，版本不对会导致运行时崩溃。</p>
</blockquote>
<h3 class="anchor anchorTargetStickyNavbar_e8hc" id="2-androidmanifestxml">2. <code>AndroidManifest.xml</code><a href="https://feifeigd.github.io/blog/2026/07/16/uni-app-offline-sdk-android-packaging#2-androidmanifestxml" class="hash-link" aria-label="2-androidmanifestxml的直接链接" title="2-androidmanifestxml的直接链接" translate="no">​</a></h3>
<p>必须包含以下声明：</p>
<div class="language-xml codeBlockContainer_zaIt theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_SaHH"><pre tabindex="0" class="prism-code language-xml codeBlock_KlaO thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_zkpV"><div class="token-line" style="color:#393A34"><span class="token comment" style="color:#999988;font-style:italic">&lt;!-- AppKey --&gt;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token tag punctuation" style="color:#393A34">&lt;</span><span class="token tag" style="color:#00009f">meta-data</span><span class="token tag" style="color:#00009f"> </span><span class="token tag attr-name namespace" style="color:#00a4db;opacity:0.7">android:</span><span class="token tag attr-name" style="color:#00a4db">name</span><span class="token tag attr-value punctuation attr-equals" style="color:#393A34">=</span><span class="token tag attr-value punctuation" style="color:#393A34">"</span><span class="token tag attr-value" style="color:#e3116c">dcloud_appkey</span><span class="token tag attr-value punctuation" style="color:#393A34">"</span><span class="token tag" style="color:#00009f"></span><br></div><div class="token-line" style="color:#393A34"><span class="token tag" style="color:#00009f">           </span><span class="token tag attr-name namespace" style="color:#00a4db;opacity:0.7">android:</span><span class="token tag attr-name" style="color:#00a4db">value</span><span class="token tag attr-value punctuation attr-equals" style="color:#393A34">=</span><span class="token tag attr-value punctuation" style="color:#393A34">"</span><span class="token tag attr-value" style="color:#e3116c">7aa06e6e03531b5772584d6b069bbaaf</span><span class="token tag attr-value punctuation" style="color:#393A34">"</span><span class="token tag punctuation" style="color:#393A34">/&gt;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">&lt;!-- 主入口 Activity --&gt;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token tag punctuation" style="color:#393A34">&lt;</span><span class="token tag" style="color:#00009f">activity</span><span class="token tag" style="color:#00009f"> </span><span class="token tag attr-name namespace" style="color:#00a4db;opacity:0.7">android:</span><span class="token tag attr-name" style="color:#00a4db">name</span><span class="token tag attr-value punctuation attr-equals" style="color:#393A34">=</span><span class="token tag attr-value punctuation" style="color:#393A34">"</span><span class="token tag attr-value" style="color:#e3116c">io.dcloud.PandoraEntry</span><span class="token tag attr-value punctuation" style="color:#393A34">"</span><span class="token tag" style="color:#00009f"></span><br></div><div class="token-line" style="color:#393A34"><span class="token tag" style="color:#00009f">          </span><span class="token tag attr-name namespace" style="color:#00a4db;opacity:0.7">android:</span><span class="token tag attr-name" style="color:#00a4db">configChanges</span><span class="token tag attr-value punctuation attr-equals" style="color:#393A34">=</span><span class="token tag attr-value punctuation" style="color:#393A34">"</span><span class="token tag attr-value" style="color:#e3116c">orientation|keyboardHidden|screenSize</span><span class="token tag attr-value punctuation" style="color:#393A34">"</span><span class="token tag" style="color:#00009f"></span><br></div><div class="token-line" style="color:#393A34"><span class="token tag" style="color:#00009f">          </span><span class="token tag attr-name namespace" style="color:#00a4db;opacity:0.7">android:</span><span class="token tag attr-name" style="color:#00a4db">hardwareAccelerated</span><span class="token tag attr-value punctuation attr-equals" style="color:#393A34">=</span><span class="token tag attr-value punctuation" style="color:#393A34">"</span><span class="token tag attr-value" style="color:#e3116c">true</span><span class="token tag attr-value punctuation" style="color:#393A34">"</span><span class="token tag" style="color:#00009f"></span><br></div><div class="token-line" style="color:#393A34"><span class="token tag" style="color:#00009f">          </span><span class="token tag attr-name namespace" style="color:#00a4db;opacity:0.7">android:</span><span class="token tag attr-name" style="color:#00a4db">theme</span><span class="token tag attr-value punctuation attr-equals" style="color:#393A34">=</span><span class="token tag attr-value punctuation" style="color:#393A34">"</span><span class="token tag attr-value" style="color:#e3116c">@style/TranslucentTheme</span><span class="token tag attr-value punctuation" style="color:#393A34">"</span><span class="token tag punctuation" style="color:#393A34">&gt;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token tag punctuation" style="color:#393A34">&lt;</span><span class="token tag" style="color:#00009f">intent-filter</span><span class="token tag punctuation" style="color:#393A34">&gt;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token tag punctuation" style="color:#393A34">&lt;</span><span class="token tag" style="color:#00009f">action</span><span class="token tag" style="color:#00009f"> </span><span class="token tag attr-name namespace" style="color:#00a4db;opacity:0.7">android:</span><span class="token tag attr-name" style="color:#00a4db">name</span><span class="token tag attr-value punctuation attr-equals" style="color:#393A34">=</span><span class="token tag attr-value punctuation" style="color:#393A34">"</span><span class="token tag attr-value" style="color:#e3116c">android.intent.action.MAIN</span><span class="token tag attr-value punctuation" style="color:#393A34">"</span><span class="token tag punctuation" style="color:#393A34">/&gt;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token tag punctuation" style="color:#393A34">&lt;</span><span class="token tag" style="color:#00009f">category</span><span class="token tag" style="color:#00009f"> </span><span class="token tag attr-name namespace" style="color:#00a4db;opacity:0.7">android:</span><span class="token tag attr-name" style="color:#00a4db">name</span><span class="token tag attr-value punctuation attr-equals" style="color:#393A34">=</span><span class="token tag attr-value punctuation" style="color:#393A34">"</span><span class="token tag attr-value" style="color:#e3116c">android.intent.category.LAUNCHER</span><span class="token tag attr-value punctuation" style="color:#393A34">"</span><span class="token tag punctuation" style="color:#393A34">/&gt;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token tag punctuation" style="color:#393A34">&lt;/</span><span class="token tag" style="color:#00009f">intent-filter</span><span class="token tag punctuation" style="color:#393A34">&gt;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token tag punctuation" style="color:#393A34">&lt;/</span><span class="token tag" style="color:#00009f">activity</span><span class="token tag punctuation" style="color:#393A34">&gt;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">&lt;!-- 内部跳转 Activity --&gt;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token tag punctuation" style="color:#393A34">&lt;</span><span class="token tag" style="color:#00009f">activity</span><span class="token tag" style="color:#00009f"> </span><span class="token tag attr-name namespace" style="color:#00a4db;opacity:0.7">android:</span><span class="token tag attr-name" style="color:#00a4db">name</span><span class="token tag attr-value punctuation attr-equals" style="color:#393A34">=</span><span class="token tag attr-value punctuation" style="color:#393A34">"</span><span class="token tag attr-value" style="color:#e3116c">io.dcloud.PandoraEntryActivity</span><span class="token tag attr-value punctuation" style="color:#393A34">"</span><span class="token tag punctuation" style="color:#393A34">/&gt;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">&lt;!-- Application --&gt;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token tag punctuation" style="color:#393A34">&lt;</span><span class="token tag" style="color:#00009f">application</span><span class="token tag" style="color:#00009f"> </span><span class="token tag attr-name namespace" style="color:#00a4db;opacity:0.7">android:</span><span class="token tag attr-name" style="color:#00a4db">name</span><span class="token tag attr-value punctuation attr-equals" style="color:#393A34">=</span><span class="token tag attr-value punctuation" style="color:#393A34">"</span><span class="token tag attr-value" style="color:#e3116c">io.dcloud.application.DCloudApplication</span><span class="token tag attr-value punctuation" style="color:#393A34">"</span><span class="token tag punctuation" style="color:#393A34">&gt;</span><br></div></code></pre></div></div>
<h3 class="anchor anchorTargetStickyNavbar_e8hc" id="3-dcloud_controlxml">3. <code>dcloud_control.xml</code><a href="https://feifeigd.github.io/blog/2026/07/16/uni-app-offline-sdk-android-packaging#3-dcloud_controlxml" class="hash-link" aria-label="3-dcloud_controlxml的直接链接" title="3-dcloud_controlxml的直接链接" translate="no">​</a></h3>
<p>声明 appid 和版本号，HBuilder 原生层据此加载对应资源：</p>
<div class="language-xml codeBlockContainer_zaIt theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_SaHH"><pre tabindex="0" class="prism-code language-xml codeBlock_KlaO thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_zkpV"><div class="token-line" style="color:#393A34"><span class="token tag punctuation" style="color:#393A34">&lt;</span><span class="token tag" style="color:#00009f">hbuilder</span><span class="token tag punctuation" style="color:#393A34">&gt;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token tag punctuation" style="color:#393A34">&lt;</span><span class="token tag" style="color:#00009f">apps</span><span class="token tag punctuation" style="color:#393A34">&gt;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token tag punctuation" style="color:#393A34">&lt;</span><span class="token tag" style="color:#00009f">app</span><span class="token tag" style="color:#00009f"> </span><span class="token tag attr-name" style="color:#00a4db">appid</span><span class="token tag attr-value punctuation attr-equals" style="color:#393A34">=</span><span class="token tag attr-value punctuation" style="color:#393A34">"</span><span class="token tag attr-value" style="color:#e3116c">__UNI__7AFEA31</span><span class="token tag attr-value punctuation" style="color:#393A34">"</span><span class="token tag" style="color:#00009f"> </span><span class="token tag attr-name" style="color:#00a4db">appver</span><span class="token tag attr-value punctuation attr-equals" style="color:#393A34">=</span><span class="token tag attr-value punctuation" style="color:#393A34">"</span><span class="token tag attr-value" style="color:#e3116c">1.3.6</span><span class="token tag attr-value punctuation" style="color:#393A34">"</span><span class="token tag punctuation" style="color:#393A34">/&gt;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token tag punctuation" style="color:#393A34">&lt;/</span><span class="token tag" style="color:#00009f">apps</span><span class="token tag punctuation" style="color:#393A34">&gt;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token tag punctuation" style="color:#393A34">&lt;/</span><span class="token tag" style="color:#00009f">hbuilder</span><span class="token tag punctuation" style="color:#393A34">&gt;</span><br></div></code></pre></div></div>
<h3 class="anchor anchorTargetStickyNavbar_e8hc" id="4-dcloud_propertiesxml">4. <code>dcloud_properties.xml</code><a href="https://feifeigd.github.io/blog/2026/07/16/uni-app-offline-sdk-android-packaging#4-dcloud_propertiesxml" class="hash-link" aria-label="4-dcloud_propertiesxml的直接链接" title="4-dcloud_propertiesxml的直接链接" translate="no">​</a></h3>
<p>注册 5+ Runtime 的功能模块。这个文件缺失或不完整会导致运行时提示「未添加 XX 模块」。需要声明的典型模块包括：</p>
<ul>
<li class=""><strong>File</strong> — 文件系统操作</li>
<li class=""><strong>Camera</strong> — 相机拍照</li>
<li class=""><strong>Downloader</strong> — 文件下载</li>
<li class=""><strong>OAuth</strong> — 第三方登录</li>
<li class=""><strong>Maps</strong> — 地图服务</li>
<li class=""><strong>Webview</strong> — Webview 增强</li>
</ul>
<hr>
<h2 class="anchor anchorTargetStickyNavbar_e8hc" id="离线-sdk-结构">离线 SDK 结构<a href="https://feifeigd.github.io/blog/2026/07/16/uni-app-offline-sdk-android-packaging#%E7%A6%BB%E7%BA%BF-sdk-%E7%BB%93%E6%9E%84" class="hash-link" aria-label="离线 SDK 结构的直接链接" title="离线 SDK 结构的直接链接" translate="no">​</a></h2>
<p>从官方下载的 SDK 包解压后结构如下：</p>
<div class="language-text codeBlockContainer_zaIt theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_SaHH"><pre tabindex="0" class="prism-code language-text codeBlock_KlaO thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_zkpV"><div class="token-line" style="color:#393A34"><span class="token plain">Android-SDK@5.15.82650_20260710.zip</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">│</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">├── SDK/libs/                     → 基座运行时（复制到 simpleDemo/libs/）</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">│   ├── lib.5plus.base-release.aar   核心 5+ Runtime</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">│   ├── uniapp-v8-release.aar        uni-app V8 渲染引擎</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">│   ├── breakpad-build-release.aar   崩溃捕获</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">│   ├── android-gif-drawable-1.2.29.aar</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">│   ├── oaid_sdk_1.0.25.aar          OAID 设备标识</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">│   ├── utsplugin-release.aar        UTS 插件运行时</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">│   ├── weex_*.aar / media*.aar     各功能模块（共 40+ 个）</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">│   └── ...</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">│</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">├── HBuilder-HelloUniApp/         → Demo 工程模板（参考用）</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">│   ├── app/build.gradle           参考依赖版本</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">│   ├── app/libs/                  参考 AAR 完整列表</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">│   ├── app/src/main/AndroidManifest.xml</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">│   └── ...</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">│</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">└── __MACOSX/                     （忽略）</span><br></div></code></pre></div></div>
<table><thead><tr><th>子目录</th><th>用途</th><th>工程对应位置</th></tr></thead><tbody><tr><td><code>SDK/libs/</code></td><td>基座运行时（AAR 库），全部复制</td><td><code>simpleDemo/libs/</code></td></tr><tr><td><code>HBuilder-HelloUniApp/app/libs/</code></td><td>参考清单，与 SDK/libs 内容一致</td><td>同上</td></tr><tr><td><code>HBuilder-HelloUniApp/app/build.gradle</code></td><td>参考依赖版本</td><td><code>simpleDemo/build.gradle</code></td></tr><tr><td><code>HBuilder-HelloUniApp/app/src/main/</code></td><td>参考清单与资源结构</td><td><code>simpleDemo/src/main/</code></td></tr></tbody></table>
<blockquote>
<p><strong>基座</strong>就是 <code>SDK/libs/</code> 目录。<code>lib.5plus.base-release.aar</code> 是核心运行时，<code>uniapp-v8-release.aar</code> 是渲染引擎，其余 AAR 是功能插件。所有 AAR 必须全部复制到 <code>libs/</code>，然后在 <code>dcloud_properties.xml</code> 中声明要启用的模块。</p>
</blockquote>
<hr>
<h2 class="anchor anchorTargetStickyNavbar_e8hc" id="常见踩坑">常见踩坑<a href="https://feifeigd.github.io/blog/2026/07/16/uni-app-offline-sdk-android-packaging#%E5%B8%B8%E8%A7%81%E8%B8%A9%E5%9D%91" class="hash-link" aria-label="常见踩坑的直接链接" title="常见踩坑的直接链接" translate="no">​</a></h2>
<p><strong>1. Fresco 版本不匹配</strong></p>
<div class="language-text codeBlockContainer_zaIt theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_SaHH"><pre tabindex="0" class="prism-code language-text codeBlock_KlaO thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_zkpV"><div class="token-line" style="color:#393A34"><span class="token plain">java.lang.NoClassDefFoundError: Failed resolution of: Lcom/facebook/drawee/...</span><br></div></code></pre></div></div>
<p>解：检查 <code>build.gradle</code> 中的 <code>fresco</code> 版本是否与 SDK 版本匹配。</p>
<p><strong>2. dcloud_properties.xml 缺失模块</strong></p>
<div class="language-text codeBlockContainer_zaIt theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_SaHH"><pre tabindex="0" class="prism-code language-text codeBlock_KlaO thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_zkpV"><div class="token-line" style="color:#393A34"><span class="token plain">未添加 Camera 模块</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">未添加 File 模块</span><br></div></code></pre></div></div>
<p>解：对照 <code>HBuilder-HelloUniApp</code> 中的 <code>dcloud_properties.xml</code>，把需要的模块声明补全。</p>
<p><strong>3. 资源未正确复制</strong></p>
<p>APK 装上去白屏或页面空白，说明 <code>www/</code> 目录下的资源没复制对。</p>
<p>解：确认 <code>assets/apps/__UNI__7AFEA31/www/</code> 下有 <code>manifest.json</code> 和 <code>app-service.js</code> 这两个关键文件。</p>
<p><strong>4. AppKey 未正确配置</strong></p>
<p>启动闪退，日志显示 <code>appkey is invalid</code>。</p>
<p>解：检查 <code>AndroidManifest.xml</code> 中的 <code>dcloud_appkey</code> meta-data 是否与 AppID 匹配 — AppKey 是根据 AppID 在 HBuilder 开发者后台申请的，不对应就会闪退。</p>
<hr>
<h2 class="anchor anchorTargetStickyNavbar_e8hc" id="参考资源">参考资源<a href="https://feifeigd.github.io/blog/2026/07/16/uni-app-offline-sdk-android-packaging#%E5%8F%82%E8%80%83%E8%B5%84%E6%BA%90" class="hash-link" aria-label="参考资源的直接链接" title="参考资源的直接链接" translate="no">​</a></h2>
<ul>
<li class=""><a href="https://nativesupport.dcloud.net.cn/AppDocs/usesdk/android.html" target="_blank" rel="noopener noreferrer" class="">官方离线打包文档</a></li>
<li class=""><a href="https://hx.dcloud.net.cn/cli/publish-APP-appResource" target="_blank" rel="noopener noreferrer" class="">HBuilderX CLI 文档</a></li>
</ul>]]></content>
        <category label="uni-app" term="uni-app"/>
        <category label="android" term="android"/>
        <category label="hbuilderx" term="hbuilderx"/>
        <category label="mobile-development" term="mobile-development"/>
        <category label="sdk" term="sdk"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[Windows VSCode 调用 WSL 中的 Hermes Agent 实战]]></title>
        <id>https://feifeigd.github.io/blog/2026/07/15/vscode-wsl-hermes</id>
        <link href="https://feifeigd.github.io/blog/2026/07/15/vscode-wsl-hermes"/>
        <updated>2026-07-15T04:00:00.000Z</updated>
        <summary type="html"><![CDATA[在 Windows 上用 VSCode Remote - WSL 无缝调用 WSL 里的 Hermes Agent，打造 AI 原生编码体验]]></summary>
        <content type="html"><![CDATA[<h2 class="anchor anchorTargetStickyNavbar_e8hc" id="背景">背景<a href="https://feifeigd.github.io/blog/2026/07/15/vscode-wsl-hermes#%E8%83%8C%E6%99%AF" class="hash-link" aria-label="背景的直接链接" title="背景的直接链接" translate="no">​</a></h2>
<p>这套组合的出现有一个很现实的理由：</p>
<ul>
<li class=""><strong>VSCode</strong> 是 Windows 上最好的编辑器之一，生态丰富，Remote 插件体系成熟</li>
<li class=""><strong>WSL</strong> 提供了完整的 Linux 开发环境，项目依赖、脚本、网络工具链都在 WSL 里</li>
<li class=""><strong>Hermes Agent</strong> 跑在 Linux 上最顺畅，它需要访问项目的 Git 历史、文件结构、终端环境</li>
</ul>
<p>所以很自然的，你会想让 VSCode 连进 WSL，然后在编辑器里直接和 Hermes 交互——写完代码让它审，遇到问题让它查，重构代码让它帮。</p>
<p>这篇文章就讲清楚这条路怎么打通，以及打通之后能怎么用。</p>
<!-- -->
<hr>
<h2 class="anchor anchorTargetStickyNavbar_e8hc" id="什么时候需要这套方案">什么时候需要这套方案<a href="https://feifeigd.github.io/blog/2026/07/15/vscode-wsl-hermes#%E4%BB%80%E4%B9%88%E6%97%B6%E5%80%99%E9%9C%80%E8%A6%81%E8%BF%99%E5%A5%97%E6%96%B9%E6%A1%88" class="hash-link" aria-label="什么时候需要这套方案的直接链接" title="什么时候需要这套方案的直接链接" translate="no">​</a></h2>
<p>先确认一下场景。如果你符合以下任意一条，这篇文章就是给你写的：</p>
<ul>
<li class=""><strong>Windows 日常办公</strong>，项目代码放在 WSL 文件系统（<code>~/projects/</code> 而非 <code>/mnt/c/</code>）</li>
<li class=""><strong>已经装了 Hermes Agent 在 WSL 里</strong>，想在 VSCode 里方便地用它</li>
<li class=""><strong>不想为了 AI 辅助切换到完全不同的编辑器</strong>（比如 Cursor），希望 VSCode 也能有类似的体验</li>
<li class=""><strong>想复用 VSCode 的插件生态</strong>（GitLens、Error Lens、Live Share）同时享受 AI agent 能力</li>
</ul>
<p>反之，如果你代码全在 Windows 原生盘（<code>C:\</code>）并且不打算搬，或者你已经在用 Cursor/VS Code Insiders with Copilot 且够用，那没必要折腾。</p>
<hr>
<h2 class="anchor anchorTargetStickyNavbar_e8hc" id="环境架构">环境架构<a href="https://feifeigd.github.io/blog/2026/07/15/vscode-wsl-hermes#%E7%8E%AF%E5%A2%83%E6%9E%B6%E6%9E%84" class="hash-link" aria-label="环境架构的直接链接" title="环境架构的直接链接" translate="no">​</a></h2>
<div class="language-text codeBlockContainer_zaIt theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_SaHH"><pre tabindex="0" class="prism-code language-text codeBlock_KlaO thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_zkpV"><div class="token-line" style="color:#393A34"><span class="token plain">┌─────────────────────────────────────────────┐</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">│  Windows 11/10                              │</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">│                                              │</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">│  ┌──────────────────┐   ┌─────────────────┐ │</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">│  │  VSCode (UI)     │   │  Edge / Chrome  │ │</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">│  │  Remote-WSL 插件  │   │  (Hermes 浏览器) │ │</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">│  └────────┬─────────┘   └─────────────────┘ │</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">│           │                                    │</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">├───────────┼─────────────────────────────────────┤</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">│  WSL (Ubuntu/Debian)                          │</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">│           │                                    │</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">│  ┌────────┴─────────┐                       │</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">│  │  VSCode Server   │                       │</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">│  │  (远程后端)       │                       │</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">│  └────────┬─────────┘                       │</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">│           │                                    │</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">│  ┌────────┴─────────┐  ┌──────────────────┐ │</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">│  │  Terminal        │  │  Hermes Agent    │ │</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">│  │  (zsh/bash)      │──│  (hermes 命令)    │ │</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">│  └─────────────────┘  └──────────────────┘ │</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">│                                              │</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">│  ┌──────────────────────────────────┐      │</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">│  │  项目代码 (~/projects/)          │      │</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">│  │  Git 历史 · 依赖 · 构建          │      │</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">│  └──────────────────────────────────┘      │</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">└─────────────────────────────────────────────┘</span><br></div></code></pre></div></div>
<p>VSCode 通过 Remote - WSL 插件在 WSL 中启动一个后端 Server，UI 仍然在 Windows 上渲染。Terminal 自然也是 WSL 里的 shell。这时候在终端里敲 <code>hermes</code>，调的就是 WSL 里的 Hermes Agent。</p>
<hr>
<h2 class="anchor anchorTargetStickyNavbar_e8hc" id="安装与配置">安装与配置<a href="https://feifeigd.github.io/blog/2026/07/15/vscode-wsl-hermes#%E5%AE%89%E8%A3%85%E4%B8%8E%E9%85%8D%E7%BD%AE" class="hash-link" aria-label="安装与配置的直接链接" title="安装与配置的直接链接" translate="no">​</a></h2>
<h3 class="anchor anchorTargetStickyNavbar_e8hc" id="1-wsl-里安装-hermes-agent">1. WSL 里安装 Hermes Agent<a href="https://feifeigd.github.io/blog/2026/07/15/vscode-wsl-hermes#1-wsl-%E9%87%8C%E5%AE%89%E8%A3%85-hermes-agent" class="hash-link" aria-label="1. WSL 里安装 Hermes Agent的直接链接" title="1. WSL 里安装 Hermes Agent的直接链接" translate="no">​</a></h3>
<p>假设 WSL 已经装好。在 WSL terminal 里：</p>
<div class="language-shell codeBlockContainer_zaIt theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_SaHH"><pre tabindex="0" class="prism-code language-shell codeBlock_KlaO thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_zkpV"><div class="token-line" style="color:#393A34"><span class="token plain"># 安装 hermes CLI（以官方方式为准）</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">curl -fsSL https://hermes-agent.nousresearch.com/install.sh | sh</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"># 确认安装成功</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">hermes --version</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"># 初始化配置（如果第一次用）</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">hermes setup</span><br></div></code></pre></div></div>
<p>安装完成后，<code>hermes</code> 命令在 WSL 的 <code>$PATH</code> 中可用。建议加到 <code>~/.zshrc</code> 或 <code>~/.bashrc</code> 里。</p>
<h3 class="anchor anchorTargetStickyNavbar_e8hc" id="2-vscode-插件安装">2. VSCode 插件安装<a href="https://feifeigd.github.io/blog/2026/07/15/vscode-wsl-hermes#2-vscode-%E6%8F%92%E4%BB%B6%E5%AE%89%E8%A3%85" class="hash-link" aria-label="2. VSCode 插件安装的直接链接" title="2. VSCode 插件安装的直接链接" translate="no">​</a></h3>
<p>Windows 上的 VSCode 装两个插件就够了：</p>
<table><thead><tr><th>插件</th><th>作用</th></tr></thead><tbody><tr><td><strong>Remote - WSL</strong> (ms-vscode-remote.remote-wsl)</td><td>连入 WSL 环境</td></tr><tr><td><strong>Remote Explorer</strong> (ms-vscode.remote-explorer)</td><td>方便切换 WSL 实例</td></tr></tbody></table>
<p>装好后，左下角状态栏应该有一个绿色的 <code>&gt;&lt; WSL: Ubuntu</code> 按钮，点它或者按 <code>Ctrl+Shift+P</code> → <code>Remote-WSL: Open Folder in WSL</code> 打开项目。</p>
<h3 class="anchor anchorTargetStickyNavbar_e8hc" id="3-确认连通">3. 确认连通<a href="https://feifeigd.github.io/blog/2026/07/15/vscode-wsl-hermes#3-%E7%A1%AE%E8%AE%A4%E8%BF%9E%E9%80%9A" class="hash-link" aria-label="3. 确认连通的直接链接" title="3. 确认连通的直接链接" translate="no">​</a></h3>
<p>VSCode 终端 (<code>Ctrl+`` </code>) 里跑：</p>
<div class="language-shell codeBlockContainer_zaIt theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_SaHH"><pre tabindex="0" class="prism-code language-shell codeBlock_KlaO thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_zkpV"><div class="token-line" style="color:#393A34"><span class="token plain">hermes --version</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"># 应该输出版本号，而不是 "command not found"</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">hermes --help</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"># 看到帮助信息即 OK</span><br></div></code></pre></div></div>
<hr>
<h2 class="anchor anchorTargetStickyNavbar_e8hc" id="核心用法">核心用法<a href="https://feifeigd.github.io/blog/2026/07/15/vscode-wsl-hermes#%E6%A0%B8%E5%BF%83%E7%94%A8%E6%B3%95" class="hash-link" aria-label="核心用法的直接链接" title="核心用法的直接链接" translate="no">​</a></h2>
<h3 class="anchor anchorTargetStickyNavbar_e8hc" id="基础终端里直接调-hermes">基础：终端里直接调 Hermes<a href="https://feifeigd.github.io/blog/2026/07/15/vscode-wsl-hermes#%E5%9F%BA%E7%A1%80%E7%BB%88%E7%AB%AF%E9%87%8C%E7%9B%B4%E6%8E%A5%E8%B0%83-hermes" class="hash-link" aria-label="基础：终端里直接调 Hermes的直接链接" title="基础：终端里直接调 Hermes的直接链接" translate="no">​</a></h3>
<p>最直接的方式就是在 VSCode 终端里像用任何 CLI 工具一样用 Hermes：</p>
<div class="language-text codeBlockContainer_zaIt theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_SaHH"><pre tabindex="0" class="prism-code language-text codeBlock_KlaO thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_zkpV"><div class="token-line" style="color:#393A34"><span class="token plain"># 让 Hermes 分析当前项目</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">hermes "分析一下这个项目的架构"</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"># 代码审查</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">hermes "帮我在 git diff 的基础上做 code review"</span><br></div></code></pre></div></div>
<p>但这样每次都要切窗口打字，体验不够流畅。下面几个方法能大幅提升效率。</p>
<h3 class="anchor anchorTargetStickyNavbar_e8hc" id="进阶一vscode-tasks-自动化">进阶一：VSCode Tasks 自动化<a href="https://feifeigd.github.io/blog/2026/07/15/vscode-wsl-hermes#%E8%BF%9B%E9%98%B6%E4%B8%80vscode-tasks-%E8%87%AA%E5%8A%A8%E5%8C%96" class="hash-link" aria-label="进阶一：VSCode Tasks 自动化的直接链接" title="进阶一：VSCode Tasks 自动化的直接链接" translate="no">​</a></h3>
<p>VSCode Tasks 允许你定义可重复执行的命令，绑定快捷键或通过命令面板触发。</p>
<p>在项目根目录创建 <code>.vscode/tasks.json</code>：</p>
<div class="language-json codeBlockContainer_zaIt theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_SaHH"><pre tabindex="0" class="prism-code language-json codeBlock_KlaO thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_zkpV"><div class="token-line" style="color:#393A34"><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token property" style="color:#36acaa">"version"</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"2.0.0"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token property" style="color:#36acaa">"tasks"</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">[</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token property" style="color:#36acaa">"label"</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"Hermes: Code Review"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token property" style="color:#36acaa">"type"</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"shell"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token property" style="color:#36acaa">"command"</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"cd ${workspaceFolder} &amp;&amp; git diff --cached | hermes 'Review this diff for bugs, security issues, and style problems. 用中文回复'"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token property" style="color:#36acaa">"group"</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"none"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token property" style="color:#36acaa">"problemMatcher"</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">[</span><span class="token punctuation" style="color:#393A34">]</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token property" style="color:#36acaa">"label"</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"Hermes: 分析当前文件"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token property" style="color:#36acaa">"type"</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"shell"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token property" style="color:#36acaa">"command"</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"hermes '分析 ${file} 的代码结构和潜在问题'"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token property" style="color:#36acaa">"group"</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"none"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token property" style="color:#36acaa">"problemMatcher"</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">[</span><span class="token punctuation" style="color:#393A34">]</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token property" style="color:#36acaa">"label"</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"Hermes: 项目架构总览"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token property" style="color:#36acaa">"type"</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"shell"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token property" style="color:#36acaa">"command"</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"hermes '阅读项目结构，给一份整体架构文档，包括目录设计、数据流、核心模块职责'"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token property" style="color:#36acaa">"group"</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"none"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token property" style="color:#36acaa">"problemMatcher"</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">[</span><span class="token punctuation" style="color:#393A34">]</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token property" style="color:#36acaa">"label"</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"Hermes: 生成单元测试"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token property" style="color:#36acaa">"type"</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"shell"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token property" style="color:#36acaa">"command"</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"hermes '为 ${file} 生成 pytest 单元测试'"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token property" style="color:#36acaa">"group"</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"none"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token property" style="color:#36acaa">"problemMatcher"</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">[</span><span class="token punctuation" style="color:#393A34">]</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">]</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><br></div></code></pre></div></div>
<p>用法：<code>Ctrl+Shift+P</code> → <code>Tasks: Run Task</code> → 选一个即可。</p>
<h3 class="anchor anchorTargetStickyNavbar_e8hc" id="进阶二快捷键绑定">进阶二：快捷键绑定<a href="https://feifeigd.github.io/blog/2026/07/15/vscode-wsl-hermes#%E8%BF%9B%E9%98%B6%E4%BA%8C%E5%BF%AB%E6%8D%B7%E9%94%AE%E7%BB%91%E5%AE%9A" class="hash-link" aria-label="进阶二：快捷键绑定的直接链接" title="进阶二：快捷键绑定的直接链接" translate="no">​</a></h3>
<p>把常用的 Hermes 任务绑定到自定义快捷键。</p>
<p>在 <code>keybindings.json</code>（<code>Ctrl+Shift+P</code> → <code>Preferences: Open Keyboard Shortcuts (JSON)</code>）里加：</p>
<div class="language-json codeBlockContainer_zaIt theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_SaHH"><pre tabindex="0" class="prism-code language-json codeBlock_KlaO thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_zkpV"><div class="token-line" style="color:#393A34"><span class="token punctuation" style="color:#393A34">[</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token property" style="color:#36acaa">"key"</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"ctrl+shift+h"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token property" style="color:#36acaa">"command"</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"workbench.action.tasks.runTask"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token property" style="color:#36acaa">"args"</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"Hermes: Code Review"</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token property" style="color:#36acaa">"key"</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"alt+h"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token property" style="color:#36acaa">"command"</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"workbench.action.terminal.sendSequence"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token property" style="color:#36acaa">"args"</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token property" style="color:#36acaa">"text"</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"hermes '${selectedText}'\n"</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">]</span><br></div></code></pre></div></div>
<p>第二个快捷键非常实用——<strong>选中一段代码，按 <code>Alt+H</code>，自动把选中文本作为问题发给 Hermes</strong>。比如选中一个函数签名，按 <code>Alt+H</code>，Hermes 会收到这条函数并分析它的设计。</p>
<h3 class="anchor anchorTargetStickyNavbar_e8hc" id="进阶三vscode-命令面板集成">进阶三：VSCode 命令面板集成<a href="https://feifeigd.github.io/blog/2026/07/15/vscode-wsl-hermes#%E8%BF%9B%E9%98%B6%E4%B8%89vscode-%E5%91%BD%E4%BB%A4%E9%9D%A2%E6%9D%BF%E9%9B%86%E6%88%90" class="hash-link" aria-label="进阶三：VSCode 命令面板集成的直接链接" title="进阶三：VSCode 命令面板集成的直接链接" translate="no">​</a></h3>
<p>如果你想要更灵活的输入界面，可以装一个 <strong>Command Variable</strong> 或 <strong>Multi Command</strong> 插件来构建交互式任务，但个人体验下来，Tasks + 快捷键已经覆盖 90% 的需求——用快捷键直接发送选中文本是最顺手的。</p>
<hr>
<h2 class="anchor anchorTargetStickyNavbar_e8hc" id="高频实战场景">高频实战场景<a href="https://feifeigd.github.io/blog/2026/07/15/vscode-wsl-hermes#%E9%AB%98%E9%A2%91%E5%AE%9E%E6%88%98%E5%9C%BA%E6%99%AF" class="hash-link" aria-label="高频实战场景的直接链接" title="高频实战场景的直接链接" translate="no">​</a></h2>
<h3 class="anchor anchorTargetStickyNavbar_e8hc" id="场景-1git-commit-前自动审查">场景 1：Git commit 前自动审查<a href="https://feifeigd.github.io/blog/2026/07/15/vscode-wsl-hermes#%E5%9C%BA%E6%99%AF-1git-commit-%E5%89%8D%E8%87%AA%E5%8A%A8%E5%AE%A1%E6%9F%A5" class="hash-link" aria-label="场景 1：Git commit 前自动审查的直接链接" title="场景 1：Git commit 前自动审查的直接链接" translate="no">​</a></h3>
<p>pre-commit hook 里调 Hermes 做代码审查：</p>
<div class="language-shell codeBlockContainer_zaIt theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_SaHH"><pre tabindex="0" class="prism-code language-shell codeBlock_KlaO thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_zkpV"><div class="token-line" style="color:#393A34"><span class="token plain"># .git/hooks/pre-commit</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">#!/bin/bash</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">git diff --cached | head -c 8000 | hermes \</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  'Review the following git diff for bugs and security issues. \</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">   Reply "OK" if clean, or list issues if found. 用中文回复。'</span><br></div></code></pre></div></div>
<p>这适合单人项目或小团队。大项目建议只审查增量 DIFF 的前 8000 字符，避免卡死。</p>
<h3 class="anchor anchorTargetStickyNavbar_e8hc" id="场景-2重构辅助">场景 2：重构辅助<a href="https://feifeigd.github.io/blog/2026/07/15/vscode-wsl-hermes#%E5%9C%BA%E6%99%AF-2%E9%87%8D%E6%9E%84%E8%BE%85%E5%8A%A9" class="hash-link" aria-label="场景 2：重构辅助的直接链接" title="场景 2：重构辅助的直接链接" translate="no">​</a></h3>
<p>在 VSCode 中选中要重构的代码段，按 <code>Alt+H</code>：</p>
<div class="language-text codeBlockContainer_zaIt theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_SaHH"><pre tabindex="0" class="prism-code language-text codeBlock_KlaO thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_zkpV"><div class="token-line" style="color:#393A34"><span class="token plain">hermes '重构以下代码，提炼公共逻辑，减少重复，保持可读性'</span><br></div></code></pre></div></div>
<p>Hermes 会给出重构后的代码，你可以直接复制粘贴验证。</p>
<h3 class="anchor anchorTargetStickyNavbar_e8hc" id="场景-3快速理解不熟悉的代码">场景 3：快速理解不熟悉的代码<a href="https://feifeigd.github.io/blog/2026/07/15/vscode-wsl-hermes#%E5%9C%BA%E6%99%AF-3%E5%BF%AB%E9%80%9F%E7%90%86%E8%A7%A3%E4%B8%8D%E7%86%9F%E6%82%89%E7%9A%84%E4%BB%A3%E7%A0%81" class="hash-link" aria-label="场景 3：快速理解不熟悉的代码的直接链接" title="场景 3：快速理解不熟悉的代码的直接链接" translate="no">​</a></h3>
<p>打开一个陌生文件，用快捷键或 Tasks：</p>
<div class="language-text codeBlockContainer_zaIt theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_SaHH"><pre tabindex="0" class="prism-code language-text codeBlock_KlaO thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_zkpV"><div class="token-line" style="color:#393A34"><span class="token plain">hermes '解释 ${file} 的核心逻辑和设计模式'</span><br></div></code></pre></div></div>
<p>对于遗留系统或者同事写的代码，这比逐行读快得多。</p>
<h3 class="anchor anchorTargetStickyNavbar_e8hc" id="场景-4项目级技术债务分析">场景 4：项目级技术债务分析<a href="https://feifeigd.github.io/blog/2026/07/15/vscode-wsl-hermes#%E5%9C%BA%E6%99%AF-4%E9%A1%B9%E7%9B%AE%E7%BA%A7%E6%8A%80%E6%9C%AF%E5%80%BA%E5%8A%A1%E5%88%86%E6%9E%90" class="hash-link" aria-label="场景 4：项目级技术债务分析的直接链接" title="场景 4：项目级技术债务分析的直接链接" translate="no">​</a></h3>
<div class="language-shell codeBlockContainer_zaIt theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_SaHH"><pre tabindex="0" class="prism-code language-shell codeBlock_KlaO thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_zkpV"><div class="token-line" style="color:#393A34"><span class="token plain">hermes '扫描项目，识别技术债务：过时的依赖、未使用的导入、潜在的性能瓶颈、违反单一职责的函数。'</span><br></div></code></pre></div></div>
<p>Hermes 会基于项目文件树和代码内容给出全局视角的分析。</p>
<hr>
<h2 class="anchor anchorTargetStickyNavbar_e8hc" id="踩坑记录">踩坑记录<a href="https://feifeigd.github.io/blog/2026/07/15/vscode-wsl-hermes#%E8%B8%A9%E5%9D%91%E8%AE%B0%E5%BD%95" class="hash-link" aria-label="踩坑记录的直接链接" title="踩坑记录的直接链接" translate="no">​</a></h2>
<h3 class="anchor anchorTargetStickyNavbar_e8hc" id="1-路径问题代码放哪">1. 路径问题——代码放哪<a href="https://feifeigd.github.io/blog/2026/07/15/vscode-wsl-hermes#1-%E8%B7%AF%E5%BE%84%E9%97%AE%E9%A2%98%E4%BB%A3%E7%A0%81%E6%94%BE%E5%93%AA" class="hash-link" aria-label="1. 路径问题——代码放哪的直接链接" title="1. 路径问题——代码放哪的直接链接" translate="no">​</a></h3>
<p><strong>WSL 文件系统以外（<code>/mnt/c/</code>）性能差很多。</strong> 跨文件系统的 IO 操作（<code>ext4 ←→ NTFS</code>）会走 DrvFS 翻译，git status 慢几倍，Hermes 读文件也会延迟。</p>
<p><strong>最佳实践：代码放在 <code>~/projects/</code>（WSL 原生 ext4），不要放在 <code>/mnt/c/Users/...</code>。</strong></p>
<p>但如果你需要在 Windows 上通过 Explorer 直接访问代码，可以在 Windows 里用 <code>\\wsl$\Ubuntu\home\用户名\projects\</code> 访问——这是 WSL 的 9P 协议网络共享路径。</p>
<h3 class="anchor anchorTargetStickyNavbar_e8hc" id="2-环境变量不一致">2. 环境变量不一致<a href="https://feifeigd.github.io/blog/2026/07/15/vscode-wsl-hermes#2-%E7%8E%AF%E5%A2%83%E5%8F%98%E9%87%8F%E4%B8%8D%E4%B8%80%E8%87%B4" class="hash-link" aria-label="2. 环境变量不一致的直接链接" title="2. 环境变量不一致的直接链接" translate="no">​</a></h3>
<p>Windows 的 PATH 和 WSL 的 PATH 是独立的。在 VSCode 终端里能跑 <code>hermes</code> 不代表在所有 shell 里都能——确保：</p>
<div class="language-shell codeBlockContainer_zaIt theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_SaHH"><pre tabindex="0" class="prism-code language-shell codeBlock_KlaO thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_zkpV"><div class="token-line" style="color:#393A34"><span class="token plain"># ~/.zshrc 或 ~/.bashrc</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">export PATH="$HOME/.local/bin:$PATH"</span><br></div></code></pre></div></div>
<p>如果 Hermes 用了 <code>.env</code> 或者环境变量（API Key 等），也确认它们被加载。</p>
<h3 class="anchor anchorTargetStickyNavbar_e8hc" id="3-代理配置">3. 代理配置<a href="https://feifeigd.github.io/blog/2026/07/15/vscode-wsl-hermes#3-%E4%BB%A3%E7%90%86%E9%85%8D%E7%BD%AE" class="hash-link" aria-label="3. 代理配置的直接链接" title="3. 代理配置的直接链接" translate="no">​</a></h3>
<p>Windows 的代理设置不会自动同步到 WSL。如果你在 Windows 上走代理：</p>
<div class="language-shell codeBlockContainer_zaIt theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_SaHH"><pre tabindex="0" class="prism-code language-shell codeBlock_KlaO thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_zkpV"><div class="token-line" style="color:#393A34"><span class="token plain"># ~/.zshrc</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">export http_proxy="http://127.0.0.1:7890"</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">export https_proxy="http://127.0.0.1:7890"</span><br></div></code></pre></div></div>
<p>注意 WSL 的 <code>127.0.0.1</code> 指向的是 WSL 自己的 loopback，不是 Windows 的。要连接 Windows 上的代理，需要用 Windows 的 WSL 虚拟网卡 IP：</p>
<div class="language-shell codeBlockContainer_zaIt theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_SaHH"><pre tabindex="0" class="prism-code language-shell codeBlock_KlaO thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_zkpV"><div class="token-line" style="color:#393A34"><span class="token plain"># 在 WSL 里获取 Windows 的 WSL 网卡 IP</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">cat /etc/resolv.conf | grep nameserver | awk '{print $2}'</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"># 比如输出 172.x.x.x</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"># 然后在 .zshrc 里</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">export http_proxy="http://172.x.x.x:7890"</span><br></div></code></pre></div></div>
<h3 class="anchor anchorTargetStickyNavbar_e8hc" id="4-git-换行符">4. git 换行符<a href="https://feifeigd.github.io/blog/2026/07/15/vscode-wsl-hermes#4-git-%E6%8D%A2%E8%A1%8C%E7%AC%A6" class="hash-link" aria-label="4. git 换行符的直接链接" title="4. git 换行符的直接链接" translate="no">​</a></h3>
<p>Windows 默认 <code>core.autocrlf=true</code>，WSL 里应该设 <code>input</code> 或 <code>false</code>，否则 git diff 会看到大量 <code>^M</code> 换行符，污染 Hermes 的 diff 输入：</p>
<div class="language-shell codeBlockContainer_zaIt theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_SaHH"><pre tabindex="0" class="prism-code language-shell codeBlock_KlaO thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_zkpV"><div class="token-line" style="color:#393A34"><span class="token plain">git config --global core.autocrlf input</span><br></div></code></pre></div></div>
<h3 class="anchor anchorTargetStickyNavbar_e8hc" id="5-vscode-终端类型">5. VSCode 终端类型<a href="https://feifeigd.github.io/blog/2026/07/15/vscode-wsl-hermes#5-vscode-%E7%BB%88%E7%AB%AF%E7%B1%BB%E5%9E%8B" class="hash-link" aria-label="5. VSCode 终端类型的直接链接" title="5. VSCode 终端类型的直接链接" translate="no">​</a></h3>
<p>VSCode 内置终端默认继承 Windows 的环境变量。通过 Remote-WSL 连入后，它启动的是 WSL 的 shell，这时候 <code>echo $SHELL</code> 应该是 <code>/bin/zsh</code> 或 <code>/bin/bash</code>。如果发现 <code>hermes</code> 找不到，排查一下：</p>
<div class="language-shell codeBlockContainer_zaIt theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_SaHH"><pre tabindex="0" class="prism-code language-shell codeBlock_KlaO thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_zkpV"><div class="token-line" style="color:#393A34"><span class="token plain"># 看看 PATH 对不对</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">echo $PATH | grep -o 'hermes\|\.local/bin'</span><br></div></code></pre></div></div>
<h3 class="anchor anchorTargetStickyNavbar_e8hc" id="6-windows-下-vscode-自体终端-vs-remote-wsl-终端">6. Windows 下 VSCode 自体终端 vs Remote-WSL 终端<a href="https://feifeigd.github.io/blog/2026/07/15/vscode-wsl-hermes#6-windows-%E4%B8%8B-vscode-%E8%87%AA%E4%BD%93%E7%BB%88%E7%AB%AF-vs-remote-wsl-%E7%BB%88%E7%AB%AF" class="hash-link" aria-label="6. Windows 下 VSCode 自体终端 vs Remote-WSL 终端的直接链接" title="6. Windows 下 VSCode 自体终端 vs Remote-WSL 终端的直接链接" translate="no">​</a></h3>
<table><thead><tr><th>对比维度</th><th>原生 VSCode 终端</th><th>Remote-WSL 终端</th></tr></thead><tbody><tr><td>Shell 类型</td><td>PowerShell / CMD</td><td>bash / zsh</td></tr><tr><td>Hermes 可用</td><td>❌ (除非你在 Windows 也装了)</td><td>✅</td></tr><tr><td>文件路径</td><td><code>C:\...</code></td><td><code>/home/...</code></td></tr><tr><td>git 行为</td><td>Windows 换行符</td><td>Linux 换行符</td></tr></tbody></table>
<p><strong>一定要在 Remote-WSL 窗口中打开终端，而不是本地窗口。</strong> 看左下角状态栏：绿色 <code>&gt;&lt; WSL: Ubuntu</code> 就是对的。</p>
<hr>
<h2 class="anchor anchorTargetStickyNavbar_e8hc" id="效果对比有--没有这套方案">效果对比：有 / 没有这套方案<a href="https://feifeigd.github.io/blog/2026/07/15/vscode-wsl-hermes#%E6%95%88%E6%9E%9C%E5%AF%B9%E6%AF%94%E6%9C%89--%E6%B2%A1%E6%9C%89%E8%BF%99%E5%A5%97%E6%96%B9%E6%A1%88" class="hash-link" aria-label="效果对比：有 / 没有这套方案的直接链接" title="效果对比：有 / 没有这套方案的直接链接" translate="no">​</a></h2>
<table><thead><tr><th>场景</th><th>之前</th><th>之后</th></tr></thead><tbody><tr><td>做 code review</td><td>手动逐行看 diff</td><td><code>Ctrl+Shift+H</code> → Hermes 审完报结果</td></tr><tr><td>不熟悉的代码</td><td>打开文件逐行读</td><td>选中 → <code>Alt+H</code> → 问 Hermes</td></tr><tr><td>写新模块</td><td>新建文件照着模板写</td><td>写接口签名 → Hermes 生成骨架</td></tr><tr><td>定位 bug</td><td>加 print/log 跑几次</td><td>描述症状 → Hermes 给出怀疑位置</td></tr><tr><td>重构</td><td>手动梳理调用关系</td><td>Hermes 先给依赖图和分析</td></tr></tbody></table>
<p>核心变化不是 Hermes 替你写了多少代码，而是 <strong>从"遇到问题自己查"变成"遇到问题问 Hermes"</strong>，且整个交互不离开编辑器。</p>
<hr>
<h2 class="anchor anchorTargetStickyNavbar_e8hc" id="一张图总结">一张图总结<a href="https://feifeigd.github.io/blog/2026/07/15/vscode-wsl-hermes#%E4%B8%80%E5%BC%A0%E5%9B%BE%E6%80%BB%E7%BB%93" class="hash-link" aria-label="一张图总结的直接链接" title="一张图总结的直接链接" translate="no">​</a></h2>
<div class="language-text codeBlockContainer_zaIt theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_SaHH"><pre tabindex="0" class="prism-code language-text codeBlock_KlaO thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_zkpV"><div class="token-line" style="color:#393A34"><span class="token plain">Windows</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  └── VSCode (UI + 插件)</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        │</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    Remote-WSL 连接</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        │</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        ▼</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">WSL (Ubuntu)</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  ├── VS Code Server (后端)</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  ├── Hermes Agent (CLI)</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  ├── Git / 构建工具</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  └── 项目代码 (~/projects/)</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">快捷键:</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  Ctrl+Shift+P → Tasks → 选 Hermes 任务</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  Alt+H        → 选中代码直接问 Hermes</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  Ctrl+Shift+H → 快捷 Code Review</span><br></div></code></pre></div></div>
<p>这套方案最大的价值不是省了多少时间，而是<strong>降低了使用 AI agent 的门槛</strong>——不用切窗口、不用开网页、不用复制粘贴代码。Hermes 就在你的终端里，快捷键一按就能用。</p>
<p>如果你也在用 VSCode + WSL 的组合，不妨花十分钟配一下。之后每天写代码都会感觉顺手很多。</p>]]></content>
        <category label="vscode" term="vscode"/>
        <category label="wsl" term="wsl"/>
        <category label="hermes-agent" term="hermes-agent"/>
        <category label="ai" term="ai"/>
        <category label="workflow" term="workflow"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[HyperFrames 视频脚本：GB200 NVL72 — 一台 300 万美元的 AI 机柜，钱到底花在哪？]]></title>
        <id>https://feifeigd.github.io/blog/2026/07/14/gb200-nvl72-cost-breakdown</id>
        <link href="https://feifeigd.github.io/blog/2026/07/14/gb200-nvl72-cost-breakdown"/>
        <updated>2026-07-14T15:00:00.000Z</updated>
        <summary type="html"><![CDATA[逐层拆解 NVIDIA GB200 NVL72 的 300 万美元成本构成，附 TTS 旁白、图片提示词、关键来源]]></summary>
        <content type="html"><![CDATA[<blockquote>
<p>本文是一份完整的 <strong>HyperFrames 时间线视频制作脚本 + 实际生成记录</strong>。前半部分为逐帧镜头设计和生图 Prompt，后半部分记录了用 <code>edge-tts</code> + <code>Pillow</code> + <code>ffmpeg</code> 纯代码生成视频的全过程（含踩坑）。成品 1080p / 3m51s / 7.5MB，带 TTS 配音和硬字幕。</p>
</blockquote>
<hr>
<h2 class="anchor anchorTargetStickyNavbar_e8hc" id="视频总览">视频总览<a href="https://feifeigd.github.io/blog/2026/07/14/gb200-nvl72-cost-breakdown#%E8%A7%86%E9%A2%91%E6%80%BB%E8%A7%88" class="hash-link" aria-label="视频总览的直接链接" title="视频总览的直接链接" translate="no">​</a></h2>
<ul>
<li class=""><strong>时长</strong>：实际 231 秒 / 3 分 51 秒（28 个镜头，TTS 中速朗读）, 理想压缩后可到 2 分钟</li>
<li class=""><strong>风格</strong>：HyperFrames 快节奏数据可视化 + 产品特写 + 动态图表</li>
<li class=""><strong>配音</strong>：edge-tts <code>zh-CN-YunxiNeural</code> 男声，rate +10%</li>
<li class=""><strong>字幕</strong>：底部中文字幕，SRT 硬字幕（微软雅黑）</li>
<li class=""><strong>画面</strong>：Pillow 代码信息图（可替换为 GPT Image 2 / Midjourney 出图升级）</li>
<li class=""><strong>BGM</strong>：暂无（可后期加入科技感电子乐垫底）</li>
</ul>
<hr>
<h2 class="anchor anchorTargetStickyNavbar_e8hc" id="成本分解总表核心数据">成本分解总表（核心数据）<a href="https://feifeigd.github.io/blog/2026/07/14/gb200-nvl72-cost-breakdown#%E6%88%90%E6%9C%AC%E5%88%86%E8%A7%A3%E6%80%BB%E8%A1%A8%E6%A0%B8%E5%BF%83%E6%95%B0%E6%8D%AE" class="hash-link" aria-label="成本分解总表（核心数据）的直接链接" title="成本分解总表（核心数据）的直接链接" translate="no">​</a></h2>
<table><thead><tr><th>组件</th><th>数量</th><th>单价（估算）</th><th>小计</th><th>占比</th></tr></thead><tbody><tr><td>GB200 Superchip (1 Grace + 2 B200)</td><td>36</td><td>$60K-$70K</td><td>$2.16M-$2.52M</td><td>~72-78%</td></tr><tr><td>NVLink 5 Switch 交换盘</td><td>18</td><td>$12K-$15K</td><td>$216K-$270K</td><td>~7-9%</td></tr><tr><td>液冷散热系统 (DLC/CDU)</td><td>1 套</td><td>$80K-$120K</td><td>$80K-$120K</td><td>~3-4%</td></tr><tr><td>ConnectX-8/7 网卡 + Spectrum-X 交换机</td><td>36 NIC + 交换机</td><td>整套 ~$120K-$180K</td><td>$120K-$180K</td><td>~4-6%</td></tr><tr><td>定制机柜 + 电源分配 (PDU)</td><td>1 套</td><td>$40K-$70K</td><td>$40K-$70K</td><td>~1.5-2.5%</td></tr><tr><td>BlueField-3 DPU</td><td>2-4</td><td>$3K-$5K</td><td>$12K-$20K</td><td>~0.5%</td></tr><tr><td>组装/集成/测试 + 原厂 margin</td><td>—</td><td>—</td><td>~$100K-$150K</td><td>~3-5%</td></tr><tr><td><strong>合计</strong></td><td>—</td><td>—</td><td><strong>~$2.7M-$3.3M</strong></td><td><strong>100%</strong></td></tr></tbody></table>
<blockquote>
<p><strong>来源说明</strong>：NVIDIA 不公开组件级定价。以上数据综合自 <strong>SemiAnalysis</strong> 深度分析（2024.03）、<strong>Morgan Stanley</strong> 研报（2024.03）、<strong>Dell/Supermicro OEM</strong> 报价泄露、<strong>ServeTheHome</strong> 和 <strong>Tom's Hardware</strong> 报道。实际价格因 OEM 厂商、采购规模、配置差异浮动 ±15%。</p>
</blockquote>
<!-- -->
<hr>
<h2 class="anchor anchorTargetStickyNavbar_e8hc" id="完整镜头脚本35-镜">完整镜头脚本（35 镜）<a href="https://feifeigd.github.io/blog/2026/07/14/gb200-nvl72-cost-breakdown#%E5%AE%8C%E6%95%B4%E9%95%9C%E5%A4%B4%E8%84%9A%E6%9C%AC35-%E9%95%9C" class="hash-link" aria-label="完整镜头脚本（35 镜）的直接链接" title="完整镜头脚本（35 镜）的直接链接" translate="no">​</a></h2>
<hr>
<h3 class="anchor anchorTargetStickyNavbar_e8hc" id="-第-1-幕开场钩子0-10s">📍 第 1 幕：开场钩子（0-10s）<a href="https://feifeigd.github.io/blog/2026/07/14/gb200-nvl72-cost-breakdown#-%E7%AC%AC-1-%E5%B9%95%E5%BC%80%E5%9C%BA%E9%92%A9%E5%AD%900-10s" class="hash-link" aria-label="📍 第 1 幕：开场钩子（0-10s）的直接链接" title="📍 第 1 幕：开场钩子（0-10s）的直接链接" translate="no">​</a></h3>
<h4 class="anchor anchorTargetStickyNavbar_e8hc" id="镜-1--暗场数字浮现">镜 1 · 暗场数字浮现<a href="https://feifeigd.github.io/blog/2026/07/14/gb200-nvl72-cost-breakdown#%E9%95%9C-1--%E6%9A%97%E5%9C%BA%E6%95%B0%E5%AD%97%E6%B5%AE%E7%8E%B0" class="hash-link" aria-label="镜 1 · 暗场数字浮现的直接链接" title="镜 1 · 暗场数字浮现的直接链接" translate="no">​</a></h4>
<ul>
<li class=""><strong>时长</strong>：3s</li>
<li class=""><strong>画面描述</strong>：纯黑背景，金色粒子聚合成 "$3,000,000"，然后缓慢旋转</li>
<li class=""><strong>字幕</strong>：一台 AI 服务器机柜，300 万美元</li>
<li class=""><strong>旁白</strong>：一台 AI 服务器机柜，三百万美元。</li>
<li class=""><strong>图片 Prompt</strong>：</li>
</ul>
<blockquote>
<p>A cinematic dark scene with a floating golden number "$3,000,000" made of glowing particles against a pure black background, volumetric lighting, 8K photorealistic, dramatic atmosphere —ar 16:9</p>
</blockquote>
<h4 class="anchor anchorTargetStickyNavbar_e8hc" id="镜-2--数据中心走廊">镜 2 · 数据中心走廊<a href="https://feifeigd.github.io/blog/2026/07/14/gb200-nvl72-cost-breakdown#%E9%95%9C-2--%E6%95%B0%E6%8D%AE%E4%B8%AD%E5%BF%83%E8%B5%B0%E5%BB%8A" class="hash-link" aria-label="镜 2 · 数据中心走廊的直接链接" title="镜 2 · 数据中心走廊的直接链接" translate="no">​</a></h4>
<ul>
<li class=""><strong>时长</strong>：4s</li>
<li class=""><strong>画面描述</strong>：一条未来感数据中心走廊，两侧排列着一模一样的黑色机柜，蓝色 LED 灯带，镜头缓缓推近其中一台</li>
<li class=""><strong>字幕</strong>：它叫 GB200 NVL72。72 颗 Blackwell GPU 塞进一个机柜</li>
<li class=""><strong>旁白</strong>：它叫 GB200 NVL72，NVIDIA 在 2024 年 GTC 大会上甩出的王炸。72 颗 Blackwell GPU，塞进一个机柜。</li>
<li class=""><strong>图片 Prompt</strong>：</li>
</ul>
<blockquote>
<p>A futuristic data center corridor lined with identical black server racks glowing with blue LED strips, the camera slowly pushing toward one specific rack in the center, cyberpunk aesthetic, clean lighting, photorealistic 8K —ar 16:9</p>
</blockquote>
<h4 class="anchor anchorTargetStickyNavbar_e8hc" id="镜-3--黄仁勋-gtc">镜 3 · 黄仁勋 GTC<a href="https://feifeigd.github.io/blog/2026/07/14/gb200-nvl72-cost-breakdown#%E9%95%9C-3--%E9%BB%84%E4%BB%81%E5%8B%8B-gtc" class="hash-link" aria-label="镜 3 · 黄仁勋 GTC的直接链接" title="镜 3 · 黄仁勋 GTC的直接链接" translate="no">​</a></h4>
<ul>
<li class=""><strong>时长</strong>：3s</li>
<li class=""><strong>画面描述</strong>：分屏构图——左侧 Jensen Huang 在 GTC 舞台手举 GB200 主板，右侧快速闪过 $2-3M 价格标签</li>
<li class=""><strong>字幕</strong>：相当于 3 台法拉利 488，或者北京五环一套房</li>
<li class=""><strong>旁白</strong>：三百万美元——相当于三台法拉利 488，北京五环一套房。</li>
<li class=""><strong>图片 Prompt</strong>：</li>
</ul>
<blockquote>
<p>Split screen: left side shows Jensen Huang on GTC stage holding a GPU board under dramatic stage lighting; right side shows a Ferrari 488 and a luxury apartment with "$3M" price tag overlay, tech magazine editorial style, 8K —ar 16:9</p>
</blockquote>
<hr>
<h3 class="anchor anchorTargetStickyNavbar_e8hc" id="-第-2-幕逐层拆解钱花在哪10-90s">📍 第 2 幕：逐层拆解钱花在哪（10-90s）<a href="https://feifeigd.github.io/blog/2026/07/14/gb200-nvl72-cost-breakdown#-%E7%AC%AC-2-%E5%B9%95%E9%80%90%E5%B1%82%E6%8B%86%E8%A7%A3%E9%92%B1%E8%8A%B1%E5%9C%A8%E5%93%AA10-90s" class="hash-link" aria-label="📍 第 2 幕：逐层拆解钱花在哪（10-90s）的直接链接" title="📍 第 2 幕：逐层拆解钱花在哪（10-90s）的直接链接" translate="no">​</a></h3>
<h4 class="anchor anchorTargetStickyNavbar_e8hc" id="镜-4--章节标题">镜 4 · 章节标题<a href="https://feifeigd.github.io/blog/2026/07/14/gb200-nvl72-cost-breakdown#%E9%95%9C-4--%E7%AB%A0%E8%8A%82%E6%A0%87%E9%A2%98" class="hash-link" aria-label="镜 4 · 章节标题的直接链接" title="镜 4 · 章节标题的直接链接" translate="no">​</a></h4>
<ul>
<li class=""><strong>时长</strong>：2s</li>
<li class=""><strong>画面描述</strong>：全屏大字 "💰 钱花在哪？"，逐行出现，金属质感</li>
<li class=""><strong>字幕</strong>：（无）</li>
<li class=""><strong>旁白</strong>：现在，我们来把它拆开。</li>
<li class=""><strong>图片 Prompt</strong>：</li>
</ul>
<blockquote>
<p>A bold typographic design with metallic gold text "WHERE DOES THE MONEY GO?" in Chinese on a dark gradient background, luxury branding style, minimalist, 8K —ar 16:9</p>
</blockquote>
<hr>
<h3 class="anchor anchorTargetStickyNavbar_e8hc" id="-第一层gpu-与-hbm-显存--22m-25m75">🔴 第一层：GPU 与 HBM 显存 — $2.2M-$2.5M（~75%）<a href="https://feifeigd.github.io/blog/2026/07/14/gb200-nvl72-cost-breakdown#-%E7%AC%AC%E4%B8%80%E5%B1%82gpu-%E4%B8%8E-hbm-%E6%98%BE%E5%AD%98--22m-25m75" class="hash-link" aria-label="🔴 第一层：GPU 与 HBM 显存 — $2.2M-$2.5M（~75%）的直接链接" title="🔴 第一层：GPU 与 HBM 显存 — $2.2M-$2.5M（~75%）的直接链接" translate="no">​</a></h3>
<h4 class="anchor anchorTargetStickyNavbar_e8hc" id="镜-5--gb200-superchip-特写">镜 5 · GB200 Superchip 特写<a href="https://feifeigd.github.io/blog/2026/07/14/gb200-nvl72-cost-breakdown#%E9%95%9C-5--gb200-superchip-%E7%89%B9%E5%86%99" class="hash-link" aria-label="镜 5 · GB200 Superchip 特写的直接链接" title="镜 5 · GB200 Superchip 特写的直接链接" translate="no">​</a></h4>
<ul>
<li class=""><strong>时长</strong>：4s</li>
<li class=""><strong>画面描述</strong>：一颗 GB200 Superchip 在黑色托盘上 45 度旋转，流光扫过表面。B200 GPU die 和 HBM3e 堆栈用不同颜色高亮标注</li>
<li class=""><strong>字幕</strong>：GB200 Superchip = 1 颗 Grace CPU + 2 颗 B200 GPU。单颗售价 $60,000-$70,000</li>
<li class=""><strong>旁白</strong>：最大的一笔钱，当然在 GPU 上。这台机柜里有 36 颗 GB200 Superchip，每一颗里面封装着两颗 Blackwell B200 GPU 和一颗 Grace CPU。单颗价格六万到七万美元。三十六颗，两百万就出去了。</li>
<li class=""><strong>图片 Prompt</strong>：</li>
</ul>
<blockquote>
<p>A single NVIDIA GB200 Superchip floating on a matte black pedestal, rotating 45 degrees, laser scanning across its surface with different colored highlights showing B200 GPU die in blue and HBM3e stacks in gold, product shot style, extreme detail, 8K —ar 16:9</p>
</blockquote>
<h4 class="anchor anchorTargetStickyNavbar_e8hc" id="镜-6--gpu-裸片结构图">镜 6 · GPU 裸片结构图<a href="https://feifeigd.github.io/blog/2026/07/14/gb200-nvl72-cost-breakdown#%E9%95%9C-6--gpu-%E8%A3%B8%E7%89%87%E7%BB%93%E6%9E%84%E5%9B%BE" class="hash-link" aria-label="镜 6 · GPU 裸片结构图的直接链接" title="镜 6 · GPU 裸片结构图的直接链接" translate="no">​</a></h4>
<ul>
<li class=""><strong>时长</strong>：3s</li>
<li class=""><strong>画面描述</strong>：X 光透视风格剖面图，B200 GPU 内部——2080 亿个晶体管，两个计算 die 通过 10TB/s NV-HBI 桥接</li>
<li class=""><strong>字幕</strong>：单颗 B200：2080 亿晶体管，台积电 4NP 工艺</li>
<li class=""><strong>旁白</strong>：一颗 B200 上有两千零八十亿个晶体管，台积电四纳米定制工艺。这个量级的芯片，光流片费用就要上亿美元。</li>
<li class=""><strong>图片 Prompt</strong>：</li>
</ul>
<blockquote>
<p>An X-ray style cutaway diagram of a B200 GPU die showing 208 billion transistors as a dense glowing circuit city, two compute dies connected by a bright NV-HBI bridge labeled "10TB/s", technical illustration, dark theme with neon accents, 8K —ar 16:9</p>
</blockquote>
<h4 class="anchor anchorTargetStickyNavbar_e8hc" id="镜-7--hbm3e-显存堆叠">镜 7 · HBM3e 显存堆叠<a href="https://feifeigd.github.io/blog/2026/07/14/gb200-nvl72-cost-breakdown#%E9%95%9C-7--hbm3e-%E6%98%BE%E5%AD%98%E5%A0%86%E5%8F%A0" class="hash-link" aria-label="镜 7 · HBM3e 显存堆叠的直接链接" title="镜 7 · HBM3e 显存堆叠的直接链接" translate="no">​</a></h4>
<ul>
<li class=""><strong>时长</strong>：3s</li>
<li class=""><strong>画面描述</strong>：8 颗 HBM3e 堆栈像摩天大楼一样围绕在 GPU die 周围，数据如瀑布般从 HBM 流入 GPU。每颗 B200 搭载 192GB HBM3e</li>
<li class=""><strong>字幕</strong>：每颗 B200 搭载 192GB HBM3e。全机柜共计 13.5TB 高速显存</li>
<li class=""><strong>旁白</strong>：比 GPU Die 更贵的，是它身边的 HBM3e 高带宽显存。每颗 B200 搭载一百九十二 GB，整个机柜堆了十三点五 TB。按市场价算，这些显存光物料成本就接近二十万美元。</li>
<li class=""><strong>图片 Prompt</strong>：</li>
</ul>
<blockquote>
<p>Eight HBM3e memory stacks towering like skyscrapers around a central B200 GPU die, data cascading as bright waterfalls from HBM into GPU, cross-section view, labeled "192GB HBM3e" and "8TB/s bandwidth", technical illustration, 8K —ar 16:9</p>
</blockquote>
<h4 class="anchor anchorTargetStickyNavbar_e8hc" id="镜-8--关键数字放大">镜 8 · 关键数字放大<a href="https://feifeigd.github.io/blog/2026/07/14/gb200-nvl72-cost-breakdown#%E9%95%9C-8--%E5%85%B3%E9%94%AE%E6%95%B0%E5%AD%97%E6%94%BE%E5%A4%A7" class="hash-link" aria-label="镜 8 · 关键数字放大的直接链接" title="镜 8 · 关键数字放大的直接链接" translate="no">​</a></h4>
<ul>
<li class=""><strong>时长</strong>：2s</li>
<li class=""><strong>画面描述</strong>：全屏数字 "$2,200,000 GPU 与显存"，金色粗体，下方小字 "占总成本 ~75%"</li>
<li class=""><strong>字幕</strong>：GPU 与显存：约 220 万美元，占总成本 75%</li>
<li class=""><strong>旁白</strong>：仅 GPU 和显存，就花掉两百二十万美元，占总成本的四分之三。</li>
<li class=""><strong>图片 Prompt</strong>：</li>
</ul>
<blockquote>
<p>A bold financial infographic with a massive golden number "$2,200,000" filling the frame, subtitle "75% of total cost" below, dark background with subtle data visualization elements, clean typography, 8K —ar 16:9</p>
</blockquote>
<hr>
<h3 class="anchor anchorTargetStickyNavbar_e8hc" id="-第二层nvlink-5-交换网络--220k-270k8">🟠 第二层：NVLink 5 交换网络 — $220K-$270K（~8%）<a href="https://feifeigd.github.io/blog/2026/07/14/gb200-nvl72-cost-breakdown#-%E7%AC%AC%E4%BA%8C%E5%B1%82nvlink-5-%E4%BA%A4%E6%8D%A2%E7%BD%91%E7%BB%9C--220k-270k8" class="hash-link" aria-label="🟠 第二层：NVLink 5 交换网络 — $220K-$270K（~8%）的直接链接" title="🟠 第二层：NVLink 5 交换网络 — $220K-$270K（~8%）的直接链接" translate="no">​</a></h3>
<h4 class="anchor anchorTargetStickyNavbar_e8hc" id="镜-9--nvswitch-机箱">镜 9 · NVSwitch 机箱<a href="https://feifeigd.github.io/blog/2026/07/14/gb200-nvl72-cost-breakdown#%E9%95%9C-9--nvswitch-%E6%9C%BA%E7%AE%B1" class="hash-link" aria-label="镜 9 · NVSwitch 机箱的直接链接" title="镜 9 · NVSwitch 机箱的直接链接" translate="no">​</a></h4>
<ul>
<li class=""><strong>时长</strong>：3s</li>
<li class=""><strong>画面描述</strong>：机柜内部，目光穿过 GPU compute tray，看到上方排列整齐的 NVSwitch 交换盘——共 18 个，银灰色金属外壳、密集接口</li>
<li class=""><strong>字幕</strong>：18 个 NVSwitch 交换盘，把 72 颗 GPU 连成一台"巨型 GPU"</li>
<li class=""><strong>旁白</strong>：第二笔大开销：NVLink 交换网络。十八个 NVSwitch 交换盘，用九千个铜缆连接器把七十二颗 GPU 焊成一个整体。</li>
<li class=""><strong>图片 Prompt</strong>：</li>
</ul>
<blockquote>
<p>Inside view of a GB200 NVL72 rack showing 18 NVSwitch trays arranged in neat rows above compute trays, silver metallic enclosures with dense copper connectors visible, server hardware photography, clean lighting, 8K —ar 16:9</p>
</blockquote>
<h4 class="anchor anchorTargetStickyNavbar_e8hc" id="镜-10--铜背板互联">镜 10 · 铜背板互联<a href="https://feifeigd.github.io/blog/2026/07/14/gb200-nvl72-cost-breakdown#%E9%95%9C-10--%E9%93%9C%E8%83%8C%E6%9D%BF%E4%BA%92%E8%81%94" class="hash-link" aria-label="镜 10 · 铜背板互联的直接链接" title="镜 10 · 铜背板互联的直接链接" translate="no">​</a></h4>
<ul>
<li class=""><strong>时长</strong>：3s</li>
<li class=""><strong>画面描述</strong>：简化的机柜背面线框透视图——9,000+ 根铜缆像神经网络一样交织，每条线代表 1.8TB/s 双向带宽。数据包以光点形式在线上飞速穿梭</li>
<li class=""><strong>字幕</strong>：NVLink 5 铜背板：5000 根线缆，总带宽 130TB/s，铜缆成本比光纤低 6 倍</li>
<li class=""><strong>旁白</strong>：这套铜背板互联方案是 NVIDIA 的秘密武器。五千多根线缆提供每秒一百三十 TB 的总带宽，而且比用光纤方案便宜六倍。</li>
<li class=""><strong>图片 Prompt</strong>：</li>
</ul>
<blockquote>
<p>A wireframe cutaway diagram showing the backplane of a GB200 NVL72 rack with 9,000+ copper cables intertwining like a neural network, labeled "NVLink 5 Backplane" and "130TB/s total bandwidth", glowing data packets traveling along cables, technical illustration, dark theme, 8K —ar 16:9</p>
</blockquote>
<h4 class="anchor anchorTargetStickyNavbar_e8hc" id="镜-11--交换成本数字">镜 11 · 交换成本数字<a href="https://feifeigd.github.io/blog/2026/07/14/gb200-nvl72-cost-breakdown#%E9%95%9C-11--%E4%BA%A4%E6%8D%A2%E6%88%90%E6%9C%AC%E6%95%B0%E5%AD%97" class="hash-link" aria-label="镜 11 · 交换成本数字的直接链接" title="镜 11 · 交换成本数字的直接链接" translate="no">​</a></h4>
<ul>
<li class=""><strong>时长</strong>：2s</li>
<li class=""><strong>画面描述</strong>：图表——横轴组件列表，纵轴成本，NVSwitch 柱状图 $250K 突出显示，旁边标注 "每 Tray ~$14K × 18"</li>
<li class=""><strong>字幕</strong>：NVLink 交换网络：约 25 万美元</li>
<li class=""><strong>旁白</strong>：仅交换网络部分，又是二十五万美元。</li>
<li class=""><strong>图片 Prompt</strong>：</li>
</ul>
<blockquote>
<p>A sleek bar chart infographic showing cost breakdown with NVSwitch highlighted at $250K, labeled "~$14K per tray × 18 trays", clean data visualization style, dark theme with gold accents, 8K —ar 16:9</p>
</blockquote>
<hr>
<h3 class="anchor anchorTargetStickyNavbar_e8hc" id="-第三层液冷散热--80k-120k3-4">🟡 第三层：液冷散热 — $80K-$120K（~3-4%）<a href="https://feifeigd.github.io/blog/2026/07/14/gb200-nvl72-cost-breakdown#-%E7%AC%AC%E4%B8%89%E5%B1%82%E6%B6%B2%E5%86%B7%E6%95%A3%E7%83%AD--80k-120k3-4" class="hash-link" aria-label="🟡 第三层：液冷散热 — $80K-$120K（~3-4%）的直接链接" title="🟡 第三层：液冷散热 — $80K-$120K（~3-4%）的直接链接" translate="no">​</a></h3>
<h4 class="anchor anchorTargetStickyNavbar_e8hc" id="镜-12--液冷管道特写">镜 12 · 液冷管道特写<a href="https://feifeigd.github.io/blog/2026/07/14/gb200-nvl72-cost-breakdown#%E9%95%9C-12--%E6%B6%B2%E5%86%B7%E7%AE%A1%E9%81%93%E7%89%B9%E5%86%99" class="hash-link" aria-label="镜 12 · 液冷管道特写的直接链接" title="镜 12 · 液冷管道特写的直接链接" translate="no">​</a></h4>
<ul>
<li class=""><strong>时长</strong>：3s</li>
<li class=""><strong>画面描述</strong>：镜头从机柜后方的冷却液分配单元开始，跟随半透明管道（能看到蓝色冷却液流动），一路走到每个 GPU cold plate</li>
<li class=""><strong>字幕</strong>：每个机柜功耗 120kW。必须上液冷，风冷根本压不住</li>
<li class=""><strong>旁白</strong>：别忘了，这个机柜跑起来要吃掉一百二十千瓦的电。什么概念？一栋三十户的居民楼，夏天开满空调也就这个功率。风冷根本顶不住，必须上液冷。</li>
<li class=""><strong>图片 Prompt</strong>：</li>
</ul>
<blockquote>
<p>A macro shot following translucent blue coolant flowing through liquid cooling pipes from a CDU toward GPU cold plates in a server rack, industrial technical photography, dramatic lighting, showing the complexity of the plumbing, 8K —ar 16:9</p>
</blockquote>
<h4 class="anchor anchorTargetStickyNavbar_e8hc" id="镜-13--功耗对比">镜 13 · 功耗对比<a href="https://feifeigd.github.io/blog/2026/07/14/gb200-nvl72-cost-breakdown#%E9%95%9C-13--%E5%8A%9F%E8%80%97%E5%AF%B9%E6%AF%94" class="hash-link" aria-label="镜 13 · 功耗对比的直接链接" title="镜 13 · 功耗对比的直接链接" translate="no">​</a></h4>
<ul>
<li class=""><strong>时长</strong>：3s</li>
<li class=""><strong>画面描述</strong>：左右对比——左侧一个标准 42U 风冷机柜（标注 "Max 20-30kW"），右侧 GB200 NVL72（标注 "120kW"），右侧高出近 5 倍。右侧机柜顶部有大量管道</li>
<li class=""><strong>字幕</strong>：传统风冷单柜极限 30kW。GB200 NVL72：120kW</li>
<li class=""><strong>旁白</strong>：传统数据中心单柜功耗撑死三十千瓦，GB200 直接冲到一百二。液冷散热系统的整套方案——CDU、冷板、管路——加起来又要八到十二万美元。</li>
<li class=""><strong>图片 Prompt</strong>：</li>
</ul>
<blockquote>
<p>Side by side comparison: left a standard 42U air-cooled rack labeled "Max 30kW", right a GB200 NVL72 rack labeled "120kW" with complex liquid cooling pipes on top, dramatic contrast, infographic style, 8K —ar 16:9</p>
</blockquote>
<h4 class="anchor anchorTargetStickyNavbar_e8hc" id="镜-14--cdu-设备特写">镜 14 · CDU 设备特写<a href="https://feifeigd.github.io/blog/2026/07/14/gb200-nvl72-cost-breakdown#%E9%95%9C-14--cdu-%E8%AE%BE%E5%A4%87%E7%89%B9%E5%86%99" class="hash-link" aria-label="镜 14 · CDU 设备特写的直接链接" title="镜 14 · CDU 设备特写的直接链接" translate="no">​</a></h4>
<ul>
<li class=""><strong>时长</strong>：2s</li>
<li class=""><strong>画面描述</strong>：一******立的 Coolant Distribution Unit，不锈钢外观，多个水泵和热交换器，科技感工业产品摄影</li>
<li class=""><strong>字幕</strong>：CDU 冷却液分配单元：$40K-$60K</li>
<li class=""><strong>旁白</strong>：光这台冷却液分配单元，就要四到六万美元。</li>
<li class=""><strong>图片 Prompt</strong>：</li>
</ul>
<blockquote>
<p>A standalone Coolant Distribution Unit in stainless steel finish with multiple pumps and heat exchangers visible, industrial product photography, clean studio lighting, technology aesthetic, 8K —ar 16:9</p>
</blockquote>
<hr>
<h3 class="anchor anchorTargetStickyNavbar_e8hc" id="-第四层网络--120k-180k4-6">🟢 第四层：网络 — $120K-$180K（~4-6%）<a href="https://feifeigd.github.io/blog/2026/07/14/gb200-nvl72-cost-breakdown#-%E7%AC%AC%E5%9B%9B%E5%B1%82%E7%BD%91%E7%BB%9C--120k-180k4-6" class="hash-link" aria-label="🟢 第四层：网络 — $120K-$180K（~4-6%）的直接链接" title="🟢 第四层：网络 — $120K-$180K（~4-6%）的直接链接" translate="no">​</a></h3>
<h4 class="anchor anchorTargetStickyNavbar_e8hc" id="镜-15--网卡阵列">镜 15 · 网卡阵列<a href="https://feifeigd.github.io/blog/2026/07/14/gb200-nvl72-cost-breakdown#%E9%95%9C-15--%E7%BD%91%E5%8D%A1%E9%98%B5%E5%88%97" class="hash-link" aria-label="镜 15 · 网卡阵列的直接链接" title="镜 15 · 网卡阵列的直接链接" translate="no">​</a></h4>
<ul>
<li class=""><strong>时长</strong>：3s</li>
<li class=""><strong>画面描述</strong>：36 块 ConnectX-8 网卡排成阵列，每块卡标注 "800Gb/s"。网卡像多米诺骨牌依次亮起</li>
<li class=""><strong>字幕</strong>：36 块 ConnectX-8 网卡，每块 800Gb/s。加上 Spectrum-X 交换机</li>
<li class=""><strong>旁白</strong>：GPU 算得再快，数据进不来也白搭。每颗 Superchip 配一块八百 G 的 ConnectX-8 网卡，加上顶层的 Spectrum-X 交换机，整套网络方案十二到十八万美元。</li>
<li class=""><strong>图片 Prompt</strong>：</li>
</ul>
<blockquote>
<p>An array of 36 ConnectX-8 NICs arranged in a grid pattern, each labeled "800Gb/s", lighting up sequentially like dominoes, product photography, dark background, dramatic lighting, 8K —ar 16:9</p>
</blockquote>
<h4 class="anchor anchorTargetStickyNavbar_e8hc" id="镜-16--网络拓扑图">镜 16 · 网络拓扑图<a href="https://feifeigd.github.io/blog/2026/07/14/gb200-nvl72-cost-breakdown#%E9%95%9C-16--%E7%BD%91%E7%BB%9C%E6%8B%93%E6%89%91%E5%9B%BE" class="hash-link" aria-label="镜 16 · 网络拓扑图的直接链接" title="镜 16 · 网络拓扑图的直接链接" translate="no">​</a></h4>
<ul>
<li class=""><strong>时长</strong>：2s</li>
<li class=""><strong>画面描述</strong>：简化的网络拓扑——底部 36 个 GB200 node 通过 ConnectX-8 连接到上层 Spectrum-X 交换机，标注 "Rail-optimized / Adaptive Routing / 低延迟"</li>
<li class=""><strong>字幕</strong>：Spectrum-X 以太网：专为 AI 流量优化</li>
<li class=""><strong>旁白</strong>：Spectrum-X 是 NVIDIA 专门为 AI 训练流量优化的以太网方案，能做到 InfiniBand 级别的性能。</li>
<li class=""><strong>图片 Prompt</strong>：</li>
</ul>
<blockquote>
<p>A simplified network topology diagram: 36 GB200 nodes at bottom connected via ConnectX-8 NICs to Spectrum-X switches at top, labeled "Rail-optimized" and "Adaptive Routing", clean technical diagram, dark theme, 8K —ar 16:9</p>
</blockquote>
<hr>
<h3 class="anchor anchorTargetStickyNavbar_e8hc" id="-第五层机柜基础设施--40k-70k2">🔵 第五层：机柜基础设施 — $40K-$70K（~2%）<a href="https://feifeigd.github.io/blog/2026/07/14/gb200-nvl72-cost-breakdown#-%E7%AC%AC%E4%BA%94%E5%B1%82%E6%9C%BA%E6%9F%9C%E5%9F%BA%E7%A1%80%E8%AE%BE%E6%96%BD--40k-70k2" class="hash-link" aria-label="🔵 第五层：机柜基础设施 — $40K-$70K（~2%）的直接链接" title="🔵 第五层：机柜基础设施 — $40K-$70K（~2%）的直接链接" translate="no">​</a></h3>
<h4 class="anchor anchorTargetStickyNavbar_e8hc" id="镜-17--定制机柜">镜 17 · 定制机柜<a href="https://feifeigd.github.io/blog/2026/07/14/gb200-nvl72-cost-breakdown#%E9%95%9C-17--%E5%AE%9A%E5%88%B6%E6%9C%BA%E6%9F%9C" class="hash-link" aria-label="镜 17 · 定制机柜的直接链接" title="镜 17 · 定制机柜的直接链接" translate="no">​</a></h4>
<ul>
<li class=""><strong>时长</strong>：3s</li>
<li class=""><strong>画面描述</strong>：GB200 NVL72 机柜的骨架结构——不是标准 19 英寸机柜，而是 NVIDIA 定制设计的宽体机箱，电源母排像脊柱一样贯穿</li>
<li class=""><strong>字幕</strong>：NVIDIA 定制机柜，非标准宽体设计。功率密度是传统机柜 5 倍以上</li>
<li class=""><strong>旁白</strong>：这个机柜不是标准件——它比普通机柜宽得多，NVIDIA 重新设计了整个结构来容纳 72 颗 GPU 和 120 千瓦的供电。定制机柜、电源分配、组装测试，四到七万美元。</li>
<li class=""><strong>图片 Prompt</strong>：</li>
</ul>
<blockquote>
<p>The bare skeleton structure of a GB200 NVL72 custom rack showing its wider-than-standard design, copper power busbars running like a spine through the center, industrial design photography, factory setting, 8K —ar 16:9</p>
</blockquote>
<h4 class="anchor anchorTargetStickyNavbar_e8hc" id="镜-18--pdu-供电母排">镜 18 · PDU 供电母排<a href="https://feifeigd.github.io/blog/2026/07/14/gb200-nvl72-cost-breakdown#%E9%95%9C-18--pdu-%E4%BE%9B%E7%94%B5%E6%AF%8D%E6%8E%92" class="hash-link" aria-label="镜 18 · PDU 供电母排的直接链接" title="镜 18 · PDU 供电母排的直接链接" translate="no">​</a></h4>
<ul>
<li class=""><strong>时长</strong>：2s</li>
<li class=""><strong>画面描述</strong>：密集的铜质电源母排特写，标注 "415V 三相供电 / 120kW"，安全警示标识</li>
<li class=""><strong>字幕</strong>：415V 三相供电，120kW 总功率</li>
<li class=""><strong>旁白</strong>：供电是 415 伏三相直入，跳过传统 UPS 直接上电，就是为了省转换损耗。</li>
<li class=""><strong>图片 Prompt</strong>：</li>
</ul>
<blockquote>
<p>A close-up of dense copper power busbars labeled "415V 3-Phase 120kW" with safety warning labels, industrial electrical photography, moody lighting, 8K —ar 16:9</p>
</blockquote>
<hr>
<h3 class="anchor anchorTargetStickyNavbar_e8hc" id="-第六层组装--原厂利润--100k-150k4">🟣 第六层：组装 &amp; 原厂利润 — ~$100K-$150K（~4%）<a href="https://feifeigd.github.io/blog/2026/07/14/gb200-nvl72-cost-breakdown#-%E7%AC%AC%E5%85%AD%E5%B1%82%E7%BB%84%E8%A3%85--%E5%8E%9F%E5%8E%82%E5%88%A9%E6%B6%A6--100k-150k4" class="hash-link" aria-label="🟣 第六层：组装 &amp; 原厂利润 — ~$100K-$150K（~4%）的直接链接" title="🟣 第六层：组装 &amp; 原厂利润 — ~$100K-$150K（~4%）的直接链接" translate="no">​</a></h3>
<h4 class="anchor anchorTargetStickyNavbar_e8hc" id="镜-19--工厂组装线">镜 19 · 工厂组装线<a href="https://feifeigd.github.io/blog/2026/07/14/gb200-nvl72-cost-breakdown#%E9%95%9C-19--%E5%B7%A5%E5%8E%82%E7%BB%84%E8%A3%85%E7%BA%BF" class="hash-link" aria-label="镜 19 · 工厂组装线的直接链接" title="镜 19 · 工厂组装线的直接链接" translate="no">​</a></h4>
<ul>
<li class=""><strong>时长</strong>：3s</li>
<li class=""><strong>画面描述</strong>：整洁的服务器组装车间，工人（或机械臂）正在将 GB200 Superchip 插入机柜。防静电服、洁净室环境</li>
<li class=""><strong>字幕</strong>：每一台 NVL72 在出厂前需要数周的组装、布线、测试、烧机</li>
<li class=""><strong>旁白</strong>：把这些东西装到一起也不是免费的。每台 NVL72 在出厂前需要数周组装和烧机测试。NVIDIA 不收组装费，但整机打包卖，利润自然加在里面。</li>
<li class=""><strong>图片 Prompt</strong>：</li>
</ul>
<blockquote>
<p>A clean server assembly workshop with workers in anti-static suits inserting GB200 Superchips into a rack, robotic arms in background, clean room environment, industrial documentary photography style, 8K —ar 16:9</p>
</blockquote>
<h4 class="anchor anchorTargetStickyNavbar_e8hc" id="镜-20--测试屏幕">镜 20 · 测试屏幕<a href="https://feifeigd.github.io/blog/2026/07/14/gb200-nvl72-cost-breakdown#%E9%95%9C-20--%E6%B5%8B%E8%AF%95%E5%B1%8F%E5%B9%95" class="hash-link" aria-label="镜 20 · 测试屏幕的直接链接" title="镜 20 · 测试屏幕的直接链接" translate="no">​</a></h4>
<ul>
<li class=""><strong>时长</strong>：2s</li>
<li class=""><strong>画面描述</strong>：多块监控屏幕排成一面墙，显示各种温度曲线、功耗曲线、网络吞吐、GPU 利用率，绿色通过标志</li>
<li class=""><strong>字幕</strong>：出厂前 72 小时满负荷烧机测试</li>
<li class=""><strong>旁白</strong>：七千两百小时满负荷烧机测试——任何一个节点出问题，整柜都得返工。</li>
<li class=""><strong>图片 Prompt</strong>：</li>
</ul>
<blockquote>
<p>A wall of monitoring screens showing temperature curves, power draw graphs, network throughput, and GPU utilization, all with green "PASS" indicators, command center aesthetic, dark room, 8K —ar 16:9</p>
</blockquote>
<hr>
<h3 class="anchor anchorTargetStickyNavbar_e8hc" id="-第-3-幕为什么会有人买90-105s">📍 第 3 幕：为什么会有人买？（90-105s）<a href="https://feifeigd.github.io/blog/2026/07/14/gb200-nvl72-cost-breakdown#-%E7%AC%AC-3-%E5%B9%95%E4%B8%BA%E4%BB%80%E4%B9%88%E4%BC%9A%E6%9C%89%E4%BA%BA%E4%B9%B090-105s" class="hash-link" aria-label="📍 第 3 幕：为什么会有人买？（90-105s）的直接链接" title="📍 第 3 幕：为什么会有人买？（90-105s）的直接链接" translate="no">​</a></h3>
<h4 class="anchor anchorTargetStickyNavbar_e8hc" id="镜-21--训练时间对比">镜 21 · 训练时间对比<a href="https://feifeigd.github.io/blog/2026/07/14/gb200-nvl72-cost-breakdown#%E9%95%9C-21--%E8%AE%AD%E7%BB%83%E6%97%B6%E9%97%B4%E5%AF%B9%E6%AF%94" class="hash-link" aria-label="镜 21 · 训练时间对比的直接链接" title="镜 21 · 训练时间对比的直接链接" translate="no">​</a></h4>
<ul>
<li class=""><strong>时长</strong>：3s</li>
<li class=""><strong>画面描述</strong>：对比图表——训练 GPT-4 级别模型：H100 集群需要 [X] 天 / GB200 NVL72 集群需要 [Y] 天（时间少 4 倍）。绿色下箭头</li>
<li class=""><strong>字幕</strong>：训练一个万亿参数模型。H100：90-100 天。GB200：25-30 天</li>
<li class=""><strong>旁白</strong>：三百万值不值？看你怎么算。训练一个万亿参数的大模型，用上一代 H100 集群要跑三到四个月。上了 GB200 NVL72，一个月以内搞定。</li>
<li class=""><strong>图片 Prompt</strong>：</li>
</ul>
<blockquote>
<p>A comparison bar chart: left bar "H100 Cluster: 90-100 days" in red, right bar "GB200 NVL72: 25-30 days" in green with a bold down arrow, clean infographic style, dark theme, 8K —ar 16:9</p>
</blockquote>
<h4 class="anchor anchorTargetStickyNavbar_e8hc" id="镜-22--推理吞吐对比">镜 22 · 推理吞吐对比<a href="https://feifeigd.github.io/blog/2026/07/14/gb200-nvl72-cost-breakdown#%E9%95%9C-22--%E6%8E%A8%E7%90%86%E5%90%9E%E5%90%90%E5%AF%B9%E6%AF%94" class="hash-link" aria-label="镜 22 · 推理吞吐对比的直接链接" title="镜 22 · 推理吞吐对比的直接链接" translate="no">​</a></h4>
<ul>
<li class=""><strong>时长</strong>：3s</li>
<li class=""><strong>画面描述</strong>：动态图表——同一个 LLM 推理请求，H100 每秒生成 20 tokens，GB200 NVL72 每秒生成 100+ tokens（5 倍吞吐）。气泡上升动画</li>
<li class=""><strong>字幕</strong>：推理吞吐提升 5 倍以上。同样 300 万，比多买 5 台 H100 还划算</li>
<li class=""><strong>旁白</strong>：推理性能更是四到五倍的提升。而且因为 72 颗 GPU 共享 13.5TB 统一显存，不用切模型，一整个万亿参数模型直接塞进一个机柜跑。</li>
<li class=""><strong>图片 Prompt</strong>：</li>
</ul>
<blockquote>
<p>An animated chart showing tokens-per-second throughput: H100 at 20 tokens/s vs GB200 NVL72 at 100+ tokens/s, with rising bubble animation, labeled "5x inference throughput", data visualization style, 8K —ar 16:9</p>
</blockquote>
<h4 class="anchor anchorTargetStickyNavbar_e8hc" id="镜-23--统一显存">镜 23 · 统一显存<a href="https://feifeigd.github.io/blog/2026/07/14/gb200-nvl72-cost-breakdown#%E9%95%9C-23--%E7%BB%9F%E4%B8%80%E6%98%BE%E5%AD%98" class="hash-link" aria-label="镜 23 · 统一显存的直接链接" title="镜 23 · 统一显存的直接链接" translate="no">​</a></h4>
<ul>
<li class=""><strong>时长</strong>：3s</li>
<li class=""><strong>画面描述</strong>：72 颗 B200 以 NVLink 连接成一个巨大的单一逻辑 GPU，上方悬浮 "13.5TB 统一显存"。一个巨大的模型图标被整个装进这个大 GPU 里</li>
<li class=""><strong>字幕</strong>：72 颗 GPU 在 NVLink 下变成一台"超级 GPU"，不需要模型切分</li>
<li class=""><strong>旁白</strong>：这是 NVL72 最核心的卖点——七十二颗 GPU 在 NVLink 下变成一台拥有 13.5TB 显存的超级 GPU。大模型不用切，直接跑。省掉了分布式训练的通信开销，这是质的区别。</li>
<li class=""><strong>图片 Prompt</strong>：</li>
</ul>
<blockquote>
<p>A visual metaphor: 72 B200 GPUs connected by glowing NVLink bridges merging into one giant logical GPU, with a massive AI model fitting entirely inside it, labeled "13.5TB Unified Memory", futuristic tech illustration, 8K —ar 16:9</p>
</blockquote>
<h4 class="anchor anchorTargetStickyNavbar_e8hc" id="镜-24--大客户俱乐部">镜 24 · 大客户俱乐部<a href="https://feifeigd.github.io/blog/2026/07/14/gb200-nvl72-cost-breakdown#%E9%95%9C-24--%E5%A4%A7%E5%AE%A2%E6%88%B7%E4%BF%B1%E4%B9%90%E9%83%A8" class="hash-link" aria-label="镜 24 · 大客户俱乐部的直接链接" title="镜 24 · 大客户俱乐部的直接链接" translate="no">​</a></h4>
<ul>
<li class=""><strong>时长</strong>：3s</li>
<li class=""><strong>画面描述</strong>：一排知名公司 logo——Microsoft、Meta、Oracle、Tesla（xAI）、Google、Amazon，金光流转</li>
<li class=""><strong>字幕</strong>：首批客户：Microsoft、Meta、Oracle、xAI、CoreWeave、Lambda Labs</li>
<li class=""><strong>旁白</strong>：这也是为什么 OpenAI 的对手、Meta、微软、Oracle 这些公司已经在排队下单。因为在这个级别的竞赛里，时间就是护城河。</li>
<li class=""><strong>图片 Prompt</strong>：</li>
</ul>
<blockquote>
<p>A prestigious lineup of tech company logos — Microsoft, Meta, Oracle, xAI, Google, Amazon — arranged in a row with golden light sweeping across them, premium brand style, dark background, 8K —ar 16:9</p>
</blockquote>
<hr>
<h3 class="anchor anchorTargetStickyNavbar_e8hc" id="-第-4-幕结尾总结105-120s">📍 第 4 幕：结尾总结（105-120s）<a href="https://feifeigd.github.io/blog/2026/07/14/gb200-nvl72-cost-breakdown#-%E7%AC%AC-4-%E5%B9%95%E7%BB%93%E5%B0%BE%E6%80%BB%E7%BB%93105-120s" class="hash-link" aria-label="📍 第 4 幕：结尾总结（105-120s）的直接链接" title="📍 第 4 幕：结尾总结（105-120s）的直接链接" translate="no">​</a></h3>
<h4 class="anchor anchorTargetStickyNavbar_e8hc" id="镜-25--完整饼图">镜 25 · 完整饼图<a href="https://feifeigd.github.io/blog/2026/07/14/gb200-nvl72-cost-breakdown#%E9%95%9C-25--%E5%AE%8C%E6%95%B4%E9%A5%BC%E5%9B%BE" class="hash-link" aria-label="镜 25 · 完整饼图的直接链接" title="镜 25 · 完整饼图的直接链接" translate="no">​</a></h4>
<ul>
<li class=""><strong>时长</strong>：3s</li>
<li class=""><strong>画面描述</strong>：一张精美的环形饼图，显示全部 6 层成本占比。每层用不同颜色，旁边标注金额和百分比。中心是 GB200 NVL72 的正视图</li>
<li class=""><strong>字幕</strong>：GPU 与显存 75% · NVLink 交换 8% · 液冷 4% · 网络 5% · 机柜 2% · 组装&amp;利润 6%</li>
<li class=""><strong>旁白</strong>：拆完你会发现——三百万里，两百二十万花在 GPU 和显存上。剩下的八十万，是让这七十二颗 GPU 真正能一起工作的代价。</li>
<li class=""><strong>图片 Prompt</strong>：</li>
</ul>
<blockquote>
<p>A beautiful donut chart showing 6-layer cost breakdown with GB200 NVL72 image at center, each segment colored differently with amount labels, professional financial infographic design, dark theme, 8K —ar 16:9</p>
</blockquote>
<h4 class="anchor anchorTargetStickyNavbar_e8hc" id="镜-26--摩尔定律对比">镜 26 · 摩尔定律对比<a href="https://feifeigd.github.io/blog/2026/07/14/gb200-nvl72-cost-breakdown#%E9%95%9C-26--%EF%BF%BD%EF%BF%BD%E6%91%A9%E5%B0%94%E5%AE%9A%E5%BE%8B%E5%AF%B9%E6%AF%94" class="hash-link" aria-label="镜 26 · 摩尔定律对比的直接链接" title="镜 26 · 摩尔定律对比的直接链接" translate="no">​</a></h4>
<ul>
<li class=""><strong>时长</strong>：3s</li>
<li class=""><strong>画面描述</strong>：一条向上飙升的成本曲线。2016 年 DGX-1 $129K → 2022 年 H100 HGX $300K → 2024 年 GB200 NVL72 $3M。曲线末端陡然变陡</li>
<li class=""><strong>字幕</strong>：AI 训练成本的超级摩尔定律：每 2 年 10 倍增长</li>
<li class=""><strong>旁白</strong>：从 2016 年的 DGX-1 十二万九，到今天的 GB200 NVL72 三百万——AI 硬件的价格曲线，比摩尔定律陡十倍。这就是算力军备竞赛的真相。</li>
<li class=""><strong>图片 Prompt</strong>：</li>
</ul>
<blockquote>
<p>A dramatic upward cost curve chart: DGX-1 (2016) $129K → H100 HGX (2022) $300K → GB200 NVL72 (2024) $3M, the curve steepening sharply at the end, labeled "Super Moore's Law: 10x every 2 years", data visualization, 8K —ar 16:9</p>
</blockquote>
<h4 class="anchor anchorTargetStickyNavbar_e8hc" id="镜-27--结尾画面">镜 27 · 结尾画面<a href="https://feifeigd.github.io/blog/2026/07/14/gb200-nvl72-cost-breakdown#%E9%95%9C-27--%E7%BB%93%E5%B0%BE%E7%94%BB%E9%9D%A2" class="hash-link" aria-label="镜 27 · 结尾画面的直接链接" title="镜 27 · 结尾画面的直接链接" translate="no">​</a></h4>
<ul>
<li class=""><strong>时长</strong>：4s</li>
<li class=""><strong>画面描述</strong>：回到开场数据中心走廊视角，镜头缓缓拉远，一台 NVL72 机柜的蓝色 LED 在画面中渐小，然后叠上 "算力无价，但硬件有价" 字样，fade out</li>
<li class=""><strong>字幕</strong>：算力无价。但硬件，真的有价。</li>
<li class=""><strong>旁白</strong>：算力无价。但硬件，真的有价。</li>
<li class=""><strong>图片 Prompt</strong>：</li>
</ul>
<blockquote>
<p>The futuristic data center corridor from shot 2, camera slowly pulling back as the GB200 NVL72 rack's blue LEDs become smaller, text "COMPUTE IS PRICELESS. HARDWARE IS NOT." fading in, cinematic, emotional, 8K —ar 16:9</p>
</blockquote>
<hr>
<h2 class="anchor anchorTargetStickyNavbar_e8hc" id="tts-完整旁白文本字幕轨">TTS 完整旁白文本（字幕轨）<a href="https://feifeigd.github.io/blog/2026/07/14/gb200-nvl72-cost-breakdown#tts-%E5%AE%8C%E6%95%B4%E6%97%81%E7%99%BD%E6%96%87%E6%9C%AC%E5%AD%97%E5%B9%95%E8%BD%A8" class="hash-link" aria-label="TTS 完整旁白文本（字幕轨）的直接链接" title="TTS 完整旁白文本（字幕轨）的直接链接" translate="no">​</a></h2>
<p>以下是连续朗读文本，供 TTS 引擎使用，按正常语速约 120 秒：</p>
<div class="language-text codeBlockContainer_zaIt theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_SaHH"><pre tabindex="0" class="prism-code language-text codeBlock_KlaO thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_zkpV"><div class="token-line" style="color:#393A34"><span class="token plain">一台 AI 服务器机柜，三百万美元。</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">它叫 GB200 NVL72，NVIDIA 在 2024 年 GTC 大会上甩出的王炸。72 颗 Blackwell GPU，塞进一个机柜。</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">三百万美元——相当于三台法拉利 488，北京五环一套房。</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">现在，我们来把它拆开。</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">最大的一笔钱，当然在 GPU 上。这台机柜里有 36 颗 GB200 Superchip，每一颗里面封装着两颗 Blackwell B200 GPU 和一颗 Grace CPU。单颗价格六万到七万美元。三十六颗，两百万就出去了。</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">一颗 B200 上有两千零八十亿个晶体管，台积电四纳米定制工艺。这个量级的芯片，光流片费用就要上亿美元。</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">比 GPU Die 更贵的，是它身边的 HBM3e 高带宽显存。每颗 B200 搭载一百九十二 GB，整个机柜堆了十三点五 TB。按市场价算，这些显存光物料成本就接近二十万美元。</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">仅 GPU 和显存，就花掉两百二十万美元，占总成本的四分之三。</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">第二笔大开销：NVLink 交换网络。十八个 NVSwitch 交换盘，用九千个铜缆连接器把七十二颗 GPU 焊成一个整体。</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">这套铜背板互联方案是 NVIDIA 的秘密武器。五千多根线缆提供每秒一百三十 TB 的总带宽，而且比用光纤方案便宜六倍。</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">仅交换网络部分，又是二十五万美元。</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">别忘了，这个机柜跑起来要吃掉一百二十千瓦的电。什么概念？一栋三十户的居民楼，夏天开满空调也就这个功率。风冷根本顶不住，必须上液冷。</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">传统数据中心单柜功耗撑死三十千瓦，GB200 直接冲到一百二。液冷散热系统的整套方案——CDU、冷板、管路——加起来又要八到十二万美元。</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">光这台冷却液分配单元，就要四到六万美元。</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">GPU 算得再快，数据进不来也白搭。每颗 Superchip 配一块八百 G 的 ConnectX-8 网卡，加上顶层的 Spectrum-X 交换机，整套网络方案十二到十八万美元。</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">Spectrum-X 是 NVIDIA 专门为 AI 训练流量优化的以太网方案，能做到 InfiniBand 级别的性能。</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">这个机柜不是标准件——它比普通机柜宽得多，NVIDIA 重新设计了整个结构来容纳 72 颗 GPU 和 120 千瓦的供电。定制机柜、电源分配、组装测试，四到七万美元。</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">供电是 415 伏三相直入，跳过传统 UPS 直接上电，就是为了省转换损耗。</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">把这些东西装到一起也不是免费的。每台 NVL72 在出厂前需要数周组装和烧机测试。NVIDIA 不收组装费，但整机打包卖，利润自然加在里面。</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">七十二小时满负荷烧机测试——任何一个节点出问题，整柜都得返工。</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">三百万值不值？看你怎么算。训练一个万亿参数的大模型，用上一代 H100 集群要跑三到四个月。上了 GB200 NVL72，一个月以内搞定。</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">推理性能更是四到五倍的提升。而且因为 72 颗 GPU 共享 13.5TB 统一显存，不用切模型，一整个万亿参数模型直接塞进一个机柜跑。</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">这是 NVL72 最核心的卖点——七十二颗 GPU 在 NVLink 下变成一台拥有 13.5TB 显存的超级 GPU。大模型不用切，直接跑。省掉了分布式训练的通信开销，这是质的区别。</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">这也是为什么 OpenAI 的对手、Meta、微软、Oracle 这些公司已经在排队下单。因为在这个级别的竞赛里，时间就是护城河。</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">拆完你会发现——三百万里，两百二十万花在 GPU 和显存上。剩下的八十万，是让这七十二颗 GPU 真正能一起工作的代价。</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">从 2016 年的 DGX-1 十二万九，到今天的 GB200 NVL72 三百万——AI 硬件的价格曲线，比摩尔定律陡十倍。这就是算力军备竞赛的真相。</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">算力无价。但硬件，真的有价。</span><br></div></code></pre></div></div>
<hr>
<h2 class="anchor anchorTargetStickyNavbar_e8hc" id="关键数字来源索引">关键数字来源索引<a href="https://feifeigd.github.io/blog/2026/07/14/gb200-nvl72-cost-breakdown#%E5%85%B3%E9%94%AE%E6%95%B0%E5%AD%97%E6%9D%A5%E6%BA%90%E7%B4%A2%E5%BC%95" class="hash-link" aria-label="关键数字来源索引的直接链接" title="关键数字来源索引的直接链接" translate="no">​</a></h2>
<table><thead><tr><th>数字</th><th>来源</th></tr></thead><tbody><tr><td>NVL72 整柜 72 B200 GPU</td><td><a href="https://www.nvidia.com/gtc/" target="_blank" rel="noopener noreferrer" class="">NVIDIA GTC 2024 Keynote</a> (Jensen Huang, 2024.03.18)</td></tr><tr><td>GB200 Superchip 2×B200 + 1×Grace</td><td><a href="https://www.nvidia.com/en-us/data-center/gb200-nvl72/" target="_blank" rel="noopener noreferrer" class="">NVIDIA GB200 Datasheet</a></td></tr><tr><td>$3M 整柜价格区间</td><td>SemiAnalysis "GB200 NVL72 Deep Dive" (2024.03); Morgan Stanley Research (2024.03); Dell/超聚变 OEM 报价</td></tr><tr><td>B200 2080 亿晶体管</td><td><a href="https://resources.nvidia.com/en-us-blackwell-architecture" target="_blank" rel="noopener noreferrer" class="">NVIDIA Blackwell Architecture Whitepaper</a></td></tr><tr><td>192GB HBM3e / B200</td><td>NVIDIA Blackwell 官方规格</td></tr><tr><td>8TB/s HBM3e 带宽 / B200</td><td>NVIDIA Blackwell 官方规格</td></tr><tr><td>NVLink 5 1.8TB/s 双向</td><td>NVIDIA Blackwell 官方规格</td></tr><tr><td>130TB/s 全柜总带宽</td><td>NVIDIA GTC 2024 Keynote</td></tr><tr><td>120kW 整柜功耗</td><td>NVIDIA GTC 2024 / ServeTheHome NVL72 实机分析</td></tr><tr><td>铜背板比光互联便宜 6×</td><td>NVIDIA GTC 2024 (Jensen Huang 原话)</td></tr><tr><td>DGX-1 $129K (2016)</td><td>NVIDIA DGX-1 历史定价</td></tr><tr><td>训练时间对比 (4× 加速)</td><td>NVIDIA 官方性能声明</td></tr></tbody></table>
<blockquote>
<p><strong>注意</strong>：组件级价格（GPU die / HBM / NVSwitch / 网卡）为行业分析师根据已知物料成本和供应商报价推估，实际价格可能因批量折扣和 OEM 协议差异浮动 ±15%。建议在视频中以 "约" / "区间" 表述，并在画面角落标注 "基于分析师估算" 字样。</p>
</blockquote>
<hr>
<h2 class="anchor anchorTargetStickyNavbar_e8hc" id="实际生成从脚本到视频的全流程">实际生成：从脚本到视频的全流程<a href="https://feifeigd.github.io/blog/2026/07/14/gb200-nvl72-cost-breakdown#%E5%AE%9E%E9%99%85%E7%94%9F%E6%88%90%E4%BB%8E%E8%84%9A%E6%9C%AC%E5%88%B0%E8%A7%86%E9%A2%91%E7%9A%84%E5%85%A8%E6%B5%81%E7%A8%8B" class="hash-link" aria-label="实际生成：从脚本到视频的全流程的直接链接" title="实际生成：从脚本到视频的全流程的直接链接" translate="no">​</a></h2>
<p>上面是"理想方案"（GPT Image 2 生图 + 专业剪辑），下面是<strong>真的跑出来的方案</strong>——纯代码，无需任何付费 API，一行命令出片。</p>
<h3 class="anchor anchorTargetStickyNavbar_e8hc" id="工具链">工具链<a href="https://feifeigd.github.io/blog/2026/07/14/gb200-nvl72-cost-breakdown#%E5%B7%A5%E5%85%B7%E9%93%BE" class="hash-link" aria-label="工具链的直接链接" title="工具链的直接链接" translate="no">​</a></h3>
<table><thead><tr><th>环节</th><th>工具</th><th>说明</th></tr></thead><tbody><tr><td>TTS 配音</td><td><code>edge-tts</code> (Python)</td><td>Microsoft 免费 TTS，<code>zh-CN-YunxiNeural</code> 男声</td></tr><tr><td>画面生成</td><td><code>Pillow</code> (Python)</td><td>代码绘制 28 张信息图帧（非 AI 生图）</td></tr><tr><td>字幕</td><td>Python 生成 SRT</td><td>按音频时长自动对齐时间轴</td></tr><tr><td>合成</td><td><code>ffmpeg</code></td><td>帧序列 + 音频 + 字幕 → MP4</td></tr></tbody></table>
<h3 class="anchor anchorTargetStickyNavbar_e8hc" id="生成步骤">生成步骤<a href="https://feifeigd.github.io/blog/2026/07/14/gb200-nvl72-cost-breakdown#%E7%94%9F%E6%88%90%E6%AD%A5%E9%AA%A4" class="hash-link" aria-label="生成步骤的直接链接" title="生成步骤的直接链接" translate="no">​</a></h3>
<p><strong>第 1 步：TTS 配音（28 段）</strong></p>
<div class="language-python codeBlockContainer_zaIt theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_SaHH"><pre tabindex="0" class="prism-code language-python codeBlock_KlaO thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_zkpV"><div class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">import</span><span class="token plain"> edge_tts</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">import</span><span class="token plain"> asyncio</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">async</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">def</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">gen</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">for</span><span class="token plain"> i</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> text </span><span class="token keyword" style="color:#00009f">in</span><span class="token plain"> </span><span class="token builtin">enumerate</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">narrations</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        comm </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> edge_tts</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Communicate</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">text</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"zh-CN-YunxiNeural"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> rate</span><span class="token operator" style="color:#393A34">=</span><span class="token string" style="color:#e3116c">"+10%"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword" style="color:#00009f">await</span><span class="token plain"> comm</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">save</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string-interpolation string" style="color:#e3116c">f"audio/shot_</span><span class="token string-interpolation interpolation punctuation" style="color:#393A34">{</span><span class="token string-interpolation interpolation">i</span><span class="token string-interpolation interpolation punctuation" style="color:#393A34">:</span><span class="token string-interpolation interpolation format-spec">02d</span><span class="token string-interpolation interpolation punctuation" style="color:#393A34">}</span><span class="token string-interpolation string" style="color:#e3116c">.mp3"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">asyncio</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">run</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">gen</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><br></div></code></pre></div></div>
<p>28 段旁白总时长 3 分 51 秒（比预期 2 分钟长，因为技术细节密集，TTS 中速朗读就是这个节奏）。</p>
<p><strong>第 2 步：Pillow 绘制 28 个画面帧</strong></p>
<p>每帧本质是一张 1920×1080 的 PNG，暗色底 + 金色主题：</p>
<ul>
<li class="">标题数字帧（如 <code>$3,000,000</code> 大号金色字体 + 光晕效果）</li>
<li class="">数据对比帧（柱状图 / 饼图 / 条形图纯 Pillow 手绘）</li>
<li class="">架构图帧（GB200 Superchip 内部结构、NVSwitch 阵列、网络拓扑）</li>
<li class="">客户 logo 帧、摩尔定律曲线帧</li>
</ul>
<p>代码量约 500 行，所有绘图函数集中在 <code>build_video.py</code> 里。</p>
<p><strong>第 3 步：生成 SRT 字幕</strong></p>
<p>根据 28 段音频的时长自动计算时间轴，生成标准 SRT 文件。</p>
<div class="language-python codeBlockContainer_zaIt theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_SaHH"><pre tabindex="0" class="prism-code language-python codeBlock_KlaO thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_zkpV"><div class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">def</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">srt_time</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">t</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    h</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> m</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> s </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token builtin">int</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">t</span><span class="token operator" style="color:#393A34">//</span><span class="token number" style="color:#36acaa">3600</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token builtin">int</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">t</span><span class="token operator" style="color:#393A34">%</span><span class="token number" style="color:#36acaa">3600</span><span class="token punctuation" style="color:#393A34">)</span><span class="token operator" style="color:#393A34">//</span><span class="token number" style="color:#36acaa">60</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token builtin">int</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">t</span><span class="token operator" style="color:#393A34">%</span><span class="token number" style="color:#36acaa">60</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    ms </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token builtin">int</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">t</span><span class="token operator" style="color:#393A34">%</span><span class="token number" style="color:#36acaa">1</span><span class="token punctuation" style="color:#393A34">)</span><span class="token operator" style="color:#393A34">*</span><span class="token number" style="color:#36acaa">1000</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> </span><span class="token string-interpolation string" style="color:#e3116c">f"</span><span class="token string-interpolation interpolation punctuation" style="color:#393A34">{</span><span class="token string-interpolation interpolation">h</span><span class="token string-interpolation interpolation punctuation" style="color:#393A34">:</span><span class="token string-interpolation interpolation format-spec">02d</span><span class="token string-interpolation interpolation punctuation" style="color:#393A34">}</span><span class="token string-interpolation string" style="color:#e3116c">:</span><span class="token string-interpolation interpolation punctuation" style="color:#393A34">{</span><span class="token string-interpolation interpolation">m</span><span class="token string-interpolation interpolation punctuation" style="color:#393A34">:</span><span class="token string-interpolation interpolation format-spec">02d</span><span class="token string-interpolation interpolation punctuation" style="color:#393A34">}</span><span class="token string-interpolation string" style="color:#e3116c">:</span><span class="token string-interpolation interpolation punctuation" style="color:#393A34">{</span><span class="token string-interpolation interpolation">s</span><span class="token string-interpolation interpolation punctuation" style="color:#393A34">:</span><span class="token string-interpolation interpolation format-spec">02d</span><span class="token string-interpolation interpolation punctuation" style="color:#393A34">}</span><span class="token string-interpolation string" style="color:#e3116c">,</span><span class="token string-interpolation interpolation punctuation" style="color:#393A34">{</span><span class="token string-interpolation interpolation">ms</span><span class="token string-interpolation interpolation punctuation" style="color:#393A34">:</span><span class="token string-interpolation interpolation format-spec">03d</span><span class="token string-interpolation interpolation punctuation" style="color:#393A34">}</span><span class="token string-interpolation string" style="color:#e3116c">"</span><br></div></code></pre></div></div>
<p><strong>第 4 步：ffmpeg 合成</strong></p>
<div class="language-bash codeBlockContainer_zaIt theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_SaHH"><pre tabindex="0" class="prism-code language-bash codeBlock_KlaO thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_zkpV"><div class="token-line" style="color:#393A34"><span class="token plain"># 先把所有音频合并，放大音量，提升采样率</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">ffmpeg -f concat -safe 0 -i audio_concat.txt \</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  -af "aresample=44100,volume=4.0" \</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  -c:a aac -b:a 192k -ar 44100 audio_final.m4a</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"># 帧序列 + 处理后的音频 → 无字幕版</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">ffmpeg -f concat -safe 0 -i frames_concat.txt \</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  -i audio_final.m4a \</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  -c:v libx264 -preset ultrafast -crf 30 \</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  -pix_fmt yuv420p -c:a copy -shortest \</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  -movflags +faststart \</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  gb200_nvl72_cost_no_subs.mp4</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"># 烧录中文字幕</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">ffmpeg -i gb200_nvl72_cost_no_subs.mp4 \</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  -vf "subtitles=_subs.srt:force_style='FontName=Microsoft YaHei,FontSize=26'" \</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  -c:v libx264 -preset ultrafast -crf 23 \</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  -c:a copy -movflags +faststart \</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  gb200_nvl72_cost.mp4</span><br></div></code></pre></div></div>
<h3 class="anchor anchorTargetStickyNavbar_e8hc" id="踩过的坑">踩过的坑<a href="https://feifeigd.github.io/blog/2026/07/14/gb200-nvl72-cost-breakdown#%E8%B8%A9%E8%BF%87%E7%9A%84%E5%9D%91" class="hash-link" aria-label="踩过的坑的直接链接" title="踩过的坑的直接链接" translate="no">​</a></h3>
<p><strong>坑 1：没声音</strong></p>
<p><code>edge-tts</code> 输出的 MP3 是 24000Hz / 48kbps 低码率，音量极小。直接用 <code>-c:a aac</code> 转码时，ffmpeg 的 <code>loudnorm</code> 滤镜需要两遍扫描，导致编码时间翻倍。最终方案：先单独处理音频（<code>aresample=44100,volume=4.0</code>），再用 <code>-c:a copy</code> 无损合入视频。</p>
<p><strong>坑 2：NVENC 硬件编码不可用</strong></p>
<p>机器有 NVIDIA 显卡但 <code>h264_nvenc</code> 报 <code>Cannot load cuMemAllocAsync</code>，驱动版本不兼容。回退到 <code>libx264 -preset ultrafast</code>，1920×1080 编码速度约 10 fps，231 秒视频耗时 ~4 分钟。</p>
<p><strong>坑 3：Windows 路径中的冒号</strong></p>
<p>ffmpeg 的 <code>subtitles</code> 滤镜解析 <code>H:/path/to/file.srt</code> 时，把盘符 <code>H:</code> 后的冒号当成滤镜参数分隔符，报 <code>Invalid argument</code>。解决：把 SRT 复制到当前目录，用纯文件名 <code>subtitles=_subs.srt</code> 引用。</p>
<p><strong>坑 4：长视频超时</strong></p>
<p>单次 ffmpeg 同时编码视频 + 音频处理 + 字幕烧录，总耗时超过 10 分钟触发超时，moov atom 未写入导致文件损坏。解决：拆成两次编码——先做无字幕版（快速过），再单独烧字幕。</p>
<h3 class="anchor anchorTargetStickyNavbar_e8hc" id="最终成品">最终成品<a href="https://feifeigd.github.io/blog/2026/07/14/gb200-nvl72-cost-breakdown#%E6%9C%80%E7%BB%88%E6%88%90%E5%93%81" class="hash-link" aria-label="最终成品的直接链接" title="最终成品的直接链接" translate="no">​</a></h3>
<table><thead><tr><th>属性</th><th>值</th></tr></thead><tbody><tr><td>文件</td><td><code>gb200_nvl72_cost.mp4</code></td></tr><tr><td>大小</td><td>7.5 MB</td></tr><tr><td>分辨率</td><td>1920×1080 (16:9)</td></tr><tr><td>时长</td><td>3 分 51 秒</td></tr><tr><td>视频编码</td><td>H.264 (libx264 ultrafast)</td></tr><tr><td>音频</td><td>AAC 44100Hz 单声道（4 倍增益）</td></tr><tr><td>字幕</td><td>硬字幕（微软雅黑, 28 条 SRT）</td></tr><tr><td>帧数</td><td>28 帧（每帧持续 2.7~14.1 秒不等）</td></tr></tbody></table>
<h3 class="anchor anchorTargetStickyNavbar_e8hc" id="一键生成脚本">一键生成脚本<a href="https://feifeigd.github.io/blog/2026/07/14/gb200-nvl72-cost-breakdown#%E4%B8%80%E9%94%AE%E7%94%9F%E6%88%90%E8%84%9A%E6%9C%AC" class="hash-link" aria-label="一键生成脚本的直接链接" title="一键生成脚本的直接链接" translate="no">​</a></h3>
<p>完整脚本已开源在 <code>video_output/build_video.py</code>，执行即可复现：</p>
<div class="language-bash codeBlockContainer_zaIt theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_SaHH"><pre tabindex="0" class="prism-code language-bash codeBlock_KlaO thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_zkpV"><div class="token-line" style="color:#393A34"><span class="token plain">cd video_output</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">python build_video.py</span><br></div></code></pre></div></div>
<p>依赖：<code>pip install edge-tts pillow</code>，系统需安装 <code>ffmpeg</code>。</p>
<blockquote>
<p><strong>改进方向</strong>：将 Pillow 绘制的帧替换为 GPT Image 2 / Midjourney 出图（保持同名），重新跑合成步骤即可升级画面质量。也可用 Manim 替代 Pillow 做动画过渡。</p>
</blockquote>
<hr>
<h2 class="anchor anchorTargetStickyNavbar_e8hc" id="附录完整源码-video_outputbuild_videopy">附录：完整源码 (<code>video_output/build_video.py</code>)<a href="https://feifeigd.github.io/blog/2026/07/14/gb200-nvl72-cost-breakdown#%E9%99%84%E5%BD%95%E5%AE%8C%E6%95%B4%E6%BA%90%E7%A0%81-video_outputbuild_videopy" class="hash-link" aria-label="附录完整源码-video_outputbuild_videopy的直接链接" title="附录完整源码-video_outputbuild_videopy的直接链接" translate="no">​</a></h2>
<details class="details_BCGq alert alert--info details_jVRQ" data-collapsed="true"><summary>点击展开完整源码（~770 行）</summary><div><div class="collapsibleContent_v4Vg"><div class="language-python codeBlockContainer_zaIt theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_SaHH"><pre tabindex="0" class="prism-code language-python codeBlock_KlaO thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_zkpV"><div class="token-line" style="color:#393A34"><span class="token comment" style="color:#999988;font-style:italic">#!/usr/bin/env python3</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token triple-quoted-string string" style="color:#e3116c">"""</span><br></div><div class="token-line" style="color:#393A34"><span class="token triple-quoted-string string" style="color:#e3116c">GB200 NVL72 成本拆解视频生成器</span><br></div><div class="token-line" style="color:#393A34"><span class="token triple-quoted-string string" style="color:#e3116c">使用 edge-tts + Pillow + ffmpeg 生成完整视频</span><br></div><div class="token-line" style="color:#393A34"><span class="token triple-quoted-string string" style="color:#e3116c">"""</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">import</span><span class="token plain"> asyncio</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">import</span><span class="token plain"> json</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">import</span><span class="token plain"> os</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">import</span><span class="token plain"> subprocess</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">import</span><span class="token plain"> sys</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">import</span><span class="token plain"> textwrap</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">import</span><span class="token plain"> edge_tts</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">from</span><span class="token plain"> PIL </span><span class="token keyword" style="color:#00009f">import</span><span class="token plain"> Image</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> ImageDraw</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> ImageFont</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">from</span><span class="token plain"> pathlib </span><span class="token keyword" style="color:#00009f">import</span><span class="token plain"> Path</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic"># ============================================================</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic"># 配置</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic"># ============================================================</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">OUTPUT_DIR </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> Path</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">__file__</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">parent</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">FRAMES_DIR </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> OUTPUT_DIR </span><span class="token operator" style="color:#393A34">/</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"frames"</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">AUDIO_DIR </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> OUTPUT_DIR </span><span class="token operator" style="color:#393A34">/</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"audio"</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">VIDEO_OUT </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> OUTPUT_DIR </span><span class="token operator" style="color:#393A34">/</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"gb200_nvl72_cost.mp4"</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">SRT_OUT </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> OUTPUT_DIR </span><span class="token operator" style="color:#393A34">/</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"subtitles.srt"</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">W</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> H </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">1920</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">1080</span><span class="token plain">  </span><span class="token comment" style="color:#999988;font-style:italic"># 16:9</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">FPS </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">30</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">TTS_VOICE </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"zh-CN-YunxiNeural"</span><span class="token plain">  </span><span class="token comment" style="color:#999988;font-style:italic"># 男声 或 "zh-CN-XiaoxiaoNeural" 女声</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">TTS_RATE </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"+10%"</span><span class="token plain">               </span><span class="token comment" style="color:#999988;font-style:italic"># 稍快</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic"># 颜色方案：dark theme + gold accent</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">BG       </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">18</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain">  </span><span class="token number" style="color:#36acaa">18</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain">  </span><span class="token number" style="color:#36acaa">24</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">GOLD     </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">212</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">175</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">55</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">WHITE    </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">240</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">240</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">245</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">LIGHT    </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">160</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">160</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">180</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">RED      </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">220</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">60</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain">  </span><span class="token number" style="color:#36acaa">60</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">GREEN    </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">60</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain">  </span><span class="token number" style="color:#36acaa">200</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">100</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">BLUE     </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">80</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain">  </span><span class="token number" style="color:#36acaa">160</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">255</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">ORANGE   </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">255</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">150</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">50</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">PURPLE   </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">160</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">100</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">220</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">CYAN     </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">60</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain">  </span><span class="token number" style="color:#36acaa">200</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">220</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">GRAY_BAR </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">50</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain">  </span><span class="token number" style="color:#36acaa">50</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain">  </span><span class="token number" style="color:#36acaa">65</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">DARK_CARD </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">28</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">28</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">38</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic"># 字体路径（Windows + fallback）</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">def</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">find_font</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">size</span><span class="token operator" style="color:#393A34">=</span><span class="token number" style="color:#36acaa">40</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    candidates </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">[</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token string" style="color:#e3116c">"C:/Windows/Fonts/msyh.ttc"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain">        </span><span class="token comment" style="color:#999988;font-style:italic"># 微软雅黑</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token string" style="color:#e3116c">"C:/Windows/Fonts/simhei.ttf"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain">       </span><span class="token comment" style="color:#999988;font-style:italic"># 黑体</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token string" style="color:#e3116c">"C:/Windows/Fonts/simsun.ttc"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain">       </span><span class="token comment" style="color:#999988;font-style:italic"># 宋体</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token string" style="color:#e3116c">"C:/Windows/Fonts/arial.ttf"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">]</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">for</span><span class="token plain"> fp </span><span class="token keyword" style="color:#00009f">in</span><span class="token plain"> candidates</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword" style="color:#00009f">if</span><span class="token plain"> os</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">path</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">exists</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">fp</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">            </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> ImageFont</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">truetype</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">fp</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> size</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> ImageFont</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">load_default</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic"># ============================================================</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic"># 镜头数据 (标题, 字幕, 绘图函数名)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic"># ============================================================</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">SHOTS </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">[</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"$3,000,000"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain">       </span><span class="token string" style="color:#e3116c">"一台AI服务器机柜 • 三百万美元"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain">                  </span><span class="token string" style="color:#e3116c">"draw_title_big_num"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"GB200 NVL72"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain">      </span><span class="token string" style="color:#e3116c">"NVIDIA 2024 GTC • 72颗Blackwell GPU塞进一个机柜"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"draw_title_bold"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"300万美元"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain">         </span><span class="token string" style="color:#e3116c">"相当于 3台法拉利488 · 北京五环一套房"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain">            </span><span class="token string" style="color:#e3116c">"draw_comparison"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"钱花在哪？"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain">        </span><span class="token string" style="color:#e3116c">"逐层拆解 GB200 NVL72 成本构成"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain">                  </span><span class="token string" style="color:#e3116c">"draw_section_title"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"GB200 Superchip"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain">  </span><span class="token string" style="color:#e3116c">"1×Grace CPU + 2×B200 GPU  单颗$60K-$70K × 36颗"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"draw_superchip"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"2080亿晶体管"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain">     </span><span class="token string" style="color:#e3116c">"台积电4NP工艺  单颗B200 = 2080亿晶体管"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain">         </span><span class="token string" style="color:#e3116c">"draw_transistor"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"HBM3e 高带宽显存"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"每颗B200搭载192GB HBM3e  全柜13.5TB"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain">           </span><span class="token string" style="color:#e3116c">"draw_hbm"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"$2,200,000"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain">       </span><span class="token string" style="color:#e3116c">"GPU与显存  占总成本的 75%"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain">                      </span><span class="token string" style="color:#e3116c">"draw_cost_bar_1"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"NVLink 5 交换网络"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token string" style="color:#e3116c">"18个NVSwitch交换盘  9000根铜缆连接器"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain">          </span><span class="token string" style="color:#e3116c">"draw_nvswitch"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"铜背板 130TB/s"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain">   </span><span class="token string" style="color:#e3116c">"5000+根铜缆  总带宽130TB/s  比光纤便宜6倍"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain">     </span><span class="token string" style="color:#e3116c">"draw_backplane"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"$250,000"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain">         </span><span class="token string" style="color:#e3116c">"NVLink交换网络  约25万美元  占比8%"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain">             </span><span class="token string" style="color:#e3116c">"draw_cost_bar_2"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"液冷散热系统"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain">     </span><span class="token string" style="color:#e3116c">"全柜功耗120kW  风冷极限30kW  必须上液冷"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain">       </span><span class="token string" style="color:#e3116c">"draw_cooling"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"120kW vs 30kW"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain">    </span><span class="token string" style="color:#e3116c">"传统风冷单柜30kW  GB200 NVL72高达120kW"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain">        </span><span class="token string" style="color:#e3116c">"draw_power_compare"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"$100,000"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain">         </span><span class="token string" style="color:#e3116c">"CDU冷却液分配单元+冷板+管路  约10万美元  占比3-4%"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"draw_cost_bar_3"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"ConnectX-8 网卡"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain">  </span><span class="token string" style="color:#e3116c">"36块800Gb/s网卡 + Spectrum-X交换机"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain">             </span><span class="token string" style="color:#e3116c">"draw_nic_array"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"Spectrum-X 以太网"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token string" style="color:#e3116c">"专为AI流量优化的以太网方案  InfiniBand级性能"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain">   </span><span class="token string" style="color:#e3116c">"draw_network_topology"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"$150,000"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain">         </span><span class="token string" style="color:#e3116c">"整套网络方案  约15万美元  占比5%"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain">                </span><span class="token string" style="color:#e3116c">"draw_cost_bar_4"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"定制机柜 &amp; 供电"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain">  </span><span class="token string" style="color:#e3116c">"NVIDIA定制宽体机柜  415V三相供电  非标准设计"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain">   </span><span class="token string" style="color:#e3116c">"draw_rack"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"415V 120kW"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain">       </span><span class="token string" style="color:#e3116c">"铜质电源母排  跳过UPS直供  省转换损耗"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain">          </span><span class="token string" style="color:#e3116c">"draw_busbar"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"$55,000"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain">          </span><span class="token string" style="color:#e3116c">"定制机柜+PDU供电+组装测试  约5.5万美元  占比2%"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain">  </span><span class="token string" style="color:#e3116c">"draw_cost_bar_5"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"组装与烧机测试"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain">   </span><span class="token string" style="color:#e3116c">"数周组装 + 72小时满负荷烧机  任何一个节点出问题整柜返工"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token string" style="color:#e3116c">"draw_assembly"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"训练速度对比"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain">     </span><span class="token string" style="color:#e3116c">"万亿参数模型  H100:90-100天  GB200:25-30天       → 4倍加速"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token string" style="color:#e3116c">"draw_training_compare"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"推理吞吐 5x提升"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain">  </span><span class="token string" style="color:#e3116c">"同一LLM推理  H100:20 tok/s  GB200:100+ tok/s"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token string" style="color:#e3116c">"draw_inference_compare"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"13.5TB 统一显存"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain">  </span><span class="token string" style="color:#e3116c">"72颗GPU在NVLink下变成一台超级GPU  大模型不切分直接跑"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token string" style="color:#e3116c">"draw_unified_memory"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"谁在买？"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain">         </span><span class="token string" style="color:#e3116c">"Microsoft · Meta · Oracle · xAI · CoreWeave · Lambda Labs"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token string" style="color:#e3116c">"draw_customers"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"成本全景图"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain">       </span><span class="token string" style="color:#e3116c">"GPU显存75% · NVLink8% · 液冷4% · 网络5% · 机柜2% · 组装6%"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token string" style="color:#e3116c">"draw_pie_chart"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"超级摩尔定律"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain">     </span><span class="token string" style="color:#e3116c">"DGX-1$129K(2016) → H100$300K(2022) → GB200$3M(2024)  每2年10倍增长"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token string" style="color:#e3116c">"draw_moore_curve"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"算力无价 硬件有价"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token string" style="color:#e3116c">"COMPUTE IS PRICELESS. HARDWARE IS NOT."</span><span class="token punctuation" style="color:#393A34">,</span><span class="token string" style="color:#e3116c">"draw_ending"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">]</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic"># ============================================================</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic"># 绘图函数</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic"># ============================================================</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">def</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">new_frame</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> Image</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">new</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"RGB"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">W</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> H</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> BG</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">def</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">draw_centered_text</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">draw</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> text</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> y</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> font</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> color</span><span class="token operator" style="color:#393A34">=</span><span class="token plain">WHITE</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    bbox </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> draw</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">textbbox</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">0</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">0</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> text</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> font</span><span class="token operator" style="color:#393A34">=</span><span class="token plain">font</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    tw </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> bbox</span><span class="token punctuation" style="color:#393A34">[</span><span class="token number" style="color:#36acaa">2</span><span class="token punctuation" style="color:#393A34">]</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">-</span><span class="token plain"> bbox</span><span class="token punctuation" style="color:#393A34">[</span><span class="token number" style="color:#36acaa">0</span><span class="token punctuation" style="color:#393A34">]</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    draw</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">text</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">W </span><span class="token operator" style="color:#393A34">-</span><span class="token plain"> tw</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">/</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">2</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> y</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> text</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> font</span><span class="token operator" style="color:#393A34">=</span><span class="token plain">font</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> fill</span><span class="token operator" style="color:#393A34">=</span><span class="token plain">color</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">def</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">draw_subtitle</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">draw</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> text</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> font</span><span class="token operator" style="color:#393A34">=</span><span class="token boolean" style="color:#36acaa">None</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">if</span><span class="token plain"> font </span><span class="token keyword" style="color:#00009f">is</span><span class="token plain"> </span><span class="token boolean" style="color:#36acaa">None</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        font </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> find_font</span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">28</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    bbox </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> draw</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">textbbox</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">0</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">0</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> text</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> font</span><span class="token operator" style="color:#393A34">=</span><span class="token plain">font</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    tw </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> bbox</span><span class="token punctuation" style="color:#393A34">[</span><span class="token number" style="color:#36acaa">2</span><span class="token punctuation" style="color:#393A34">]</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">-</span><span class="token plain"> bbox</span><span class="token punctuation" style="color:#393A34">[</span><span class="token number" style="color:#36acaa">0</span><span class="token punctuation" style="color:#393A34">]</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    draw</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">text</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">W </span><span class="token operator" style="color:#393A34">-</span><span class="token plain"> tw</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">/</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">2</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> H </span><span class="token operator" style="color:#393A34">-</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">100</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> text</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> font</span><span class="token operator" style="color:#393A34">=</span><span class="token plain">font</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> fill</span><span class="token operator" style="color:#393A34">=</span><span class="token plain">LIGHT</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">def</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">draw_logo</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">draw</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    font </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> find_font</span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">18</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    draw</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">text</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">40</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> H </span><span class="token operator" style="color:#393A34">-</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">50</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"NVIDIA GB200 NVL72 · 成本拆解"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> font</span><span class="token operator" style="color:#393A34">=</span><span class="token plain">font</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> fill</span><span class="token operator" style="color:#393A34">=</span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">60</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">60</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">80</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic"># ---------- 各镜头绘图（28个函数）----------</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">def</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">draw_title_big_num</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">img</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    draw </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> ImageDraw</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Draw</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">img</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    font_big</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> font_sub </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> find_font</span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">200</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> find_font</span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">40</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    text </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"$3,000,000"</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    bbox </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> draw</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">textbbox</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">0</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">0</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> text</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> font</span><span class="token operator" style="color:#393A34">=</span><span class="token plain">font_big</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    tw </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> bbox</span><span class="token punctuation" style="color:#393A34">[</span><span class="token number" style="color:#36acaa">2</span><span class="token punctuation" style="color:#393A34">]</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">-</span><span class="token plain"> bbox</span><span class="token punctuation" style="color:#393A34">[</span><span class="token number" style="color:#36acaa">0</span><span class="token punctuation" style="color:#393A34">]</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">for</span><span class="token plain"> offset</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> alpha </span><span class="token keyword" style="color:#00009f">in</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">[</span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">8</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">30</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">4</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">60</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">2</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">100</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">0</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">255</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        c </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token builtin">tuple</span><span class="token punctuation" style="color:#393A34">(</span><span class="token builtin">min</span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">255</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token builtin">int</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">GOLD</span><span class="token punctuation" style="color:#393A34">[</span><span class="token plain">i</span><span class="token punctuation" style="color:#393A34">]</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">*</span><span class="token plain"> alpha </span><span class="token operator" style="color:#393A34">/</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">255</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">for</span><span class="token plain"> i </span><span class="token keyword" style="color:#00009f">in</span><span class="token plain"> </span><span class="token builtin">range</span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">3</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        draw</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">text</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">W </span><span class="token operator" style="color:#393A34">-</span><span class="token plain"> tw</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">/</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">2</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">+</span><span class="token plain"> offset</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">320</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">+</span><span class="token plain"> offset</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> text</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> font</span><span class="token operator" style="color:#393A34">=</span><span class="token plain">font_big</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> fill</span><span class="token operator" style="color:#393A34">=</span><span class="token plain">c</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    draw</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">text</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">W </span><span class="token operator" style="color:#393A34">-</span><span class="token plain"> tw</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">/</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">2</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">320</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> text</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> font</span><span class="token operator" style="color:#393A34">=</span><span class="token plain">font_big</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> fill</span><span class="token operator" style="color:#393A34">=</span><span class="token plain">GOLD</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    draw_subtitle</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">draw</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"一台AI服务器机柜 • 三百万美元"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> font_sub</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    draw_logo</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">draw</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">def</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">draw_title_bold</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">img</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    draw </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> ImageDraw</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Draw</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">img</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    draw_centered_text</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">draw</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"GB200 NVL72"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">300</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> find_font</span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">100</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> GOLD</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    draw_centered_text</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">draw</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"NVIDIA 2024 GTC 大会发布"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">460</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> find_font</span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">32</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> WHITE</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    draw_centered_text</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">draw</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"72 颗 Blackwell GPU 塞进一个机柜"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">520</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> find_font</span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">32</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> LIGHT</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    draw</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">line</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">[</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">W</span><span class="token operator" style="color:#393A34">//</span><span class="token number" style="color:#36acaa">2</span><span class="token operator" style="color:#393A34">-</span><span class="token number" style="color:#36acaa">300</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">620</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">W</span><span class="token operator" style="color:#393A34">//</span><span class="token number" style="color:#36acaa">2</span><span class="token operator" style="color:#393A34">+</span><span class="token number" style="color:#36acaa">300</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">620</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> fill</span><span class="token operator" style="color:#393A34">=</span><span class="token plain">GOLD</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> width</span><span class="token operator" style="color:#393A34">=</span><span class="token number" style="color:#36acaa">3</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    draw_subtitle</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">draw</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"2024年3月18日 · Jensen Huang 主题演讲"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    draw_logo</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">draw</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">def</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">draw_comparison</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">img</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    draw </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> ImageDraw</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Draw</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">img</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    items </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">[</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"🏎️"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"3 台"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"法拉利 488"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"🏠"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"1 套"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"北京五环房"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"🖥️"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"1 台"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"GB200 NVL72"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">]</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    col_w </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> W </span><span class="token operator" style="color:#393A34">//</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">3</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">for</span><span class="token plain"> i</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">emoji</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> num</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> label</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">in</span><span class="token plain"> </span><span class="token builtin">enumerate</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">items</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        cx </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> col_w </span><span class="token operator" style="color:#393A34">*</span><span class="token plain"> i </span><span class="token operator" style="color:#393A34">+</span><span class="token plain"> col_w </span><span class="token operator" style="color:#393A34">//</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">2</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        draw_centered_text</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">draw</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> emoji</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">250</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> find_font</span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">80</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        draw_centered_text</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">draw</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> num</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">400</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> find_font</span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">64</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> GOLD</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        draw_centered_text</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">draw</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> label</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">480</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> find_font</span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">36</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> WHITE</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    draw_centered_text</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">draw</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"$  3 , 0 0 0 , 0 0 0"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">620</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> find_font</span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">40</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> LIGHT</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    draw_subtitle</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">draw</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"三百万美元 能买什么？"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    draw_logo</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">draw</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">def</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">draw_section_title</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">img</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    draw </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> ImageDraw</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Draw</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">img</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    draw_centered_text</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">draw</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"💰"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">200</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> find_font</span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">100</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    draw_centered_text</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">draw</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"逐层拆解"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">400</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> find_font</span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">120</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> GOLD</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    draw_centered_text</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">draw</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"一台 GB200 NVL72 的 6 层成本结构"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">580</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> find_font</span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">36</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> LIGHT</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    draw</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">line</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">[</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">W</span><span class="token operator" style="color:#393A34">//</span><span class="token number" style="color:#36acaa">2</span><span class="token operator" style="color:#393A34">-</span><span class="token number" style="color:#36acaa">400</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">680</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">W</span><span class="token operator" style="color:#393A34">//</span><span class="token number" style="color:#36acaa">2</span><span class="token operator" style="color:#393A34">+</span><span class="token number" style="color:#36acaa">400</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">680</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> fill</span><span class="token operator" style="color:#393A34">=</span><span class="token plain">GOLD</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> width</span><span class="token operator" style="color:#393A34">=</span><span class="token number" style="color:#36acaa">2</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    draw_logo</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">draw</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">def</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">draw_superchip</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">img</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    draw </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> ImageDraw</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Draw</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">img</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    cx</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> cy </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> W</span><span class="token operator" style="color:#393A34">//</span><span class="token number" style="color:#36acaa">2</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">380</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    draw</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">rounded_rectangle</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">[</span><span class="token plain">cx</span><span class="token operator" style="color:#393A34">-</span><span class="token number" style="color:#36acaa">300</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> cy</span><span class="token operator" style="color:#393A34">-</span><span class="token number" style="color:#36acaa">150</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> cx</span><span class="token operator" style="color:#393A34">+</span><span class="token number" style="color:#36acaa">300</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> cy</span><span class="token operator" style="color:#393A34">+</span><span class="token number" style="color:#36acaa">150</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> radius</span><span class="token operator" style="color:#393A34">=</span><span class="token number" style="color:#36acaa">20</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> outline</span><span class="token operator" style="color:#393A34">=</span><span class="token plain">GOLD</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> width</span><span class="token operator" style="color:#393A34">=</span><span class="token number" style="color:#36acaa">4</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    draw_centered_text</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">draw</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"GB200 Superchip"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> cy</span><span class="token operator" style="color:#393A34">-</span><span class="token number" style="color:#36acaa">80</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> find_font</span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">30</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> GOLD</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    draw</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">rounded_rectangle</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">[</span><span class="token plain">cx</span><span class="token operator" style="color:#393A34">-</span><span class="token number" style="color:#36acaa">260</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> cy</span><span class="token operator" style="color:#393A34">-</span><span class="token number" style="color:#36acaa">20</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> cx</span><span class="token operator" style="color:#393A34">-</span><span class="token number" style="color:#36acaa">30</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> cy</span><span class="token operator" style="color:#393A34">+</span><span class="token number" style="color:#36acaa">120</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> radius</span><span class="token operator" style="color:#393A34">=</span><span class="token number" style="color:#36acaa">12</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> outline</span><span class="token operator" style="color:#393A34">=</span><span class="token plain">BLUE</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> width</span><span class="token operator" style="color:#393A34">=</span><span class="token number" style="color:#36acaa">3</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> fill</span><span class="token operator" style="color:#393A34">=</span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">0</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">30</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">60</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    draw_centered_text</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">draw</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"Grace CPU"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> cy</span><span class="token operator" style="color:#393A34">+</span><span class="token number" style="color:#36acaa">20</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> find_font</span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">24</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> BLUE</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    draw</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">rounded_rectangle</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">[</span><span class="token plain">cx</span><span class="token operator" style="color:#393A34">+</span><span class="token number" style="color:#36acaa">30</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> cy</span><span class="token operator" style="color:#393A34">-</span><span class="token number" style="color:#36acaa">50</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> cx</span><span class="token operator" style="color:#393A34">+</span><span class="token number" style="color:#36acaa">260</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> cy</span><span class="token operator" style="color:#393A34">+</span><span class="token number" style="color:#36acaa">40</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> radius</span><span class="token operator" style="color:#393A34">=</span><span class="token number" style="color:#36acaa">12</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> outline</span><span class="token operator" style="color:#393A34">=</span><span class="token plain">GREEN</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> width</span><span class="token operator" style="color:#393A34">=</span><span class="token number" style="color:#36acaa">3</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> fill</span><span class="token operator" style="color:#393A34">=</span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">0</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">40</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">0</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    draw_centered_text</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">draw</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"B200 GPU"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> cy</span><span class="token operator" style="color:#393A34">-</span><span class="token number" style="color:#36acaa">30</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> find_font</span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">24</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> GREEN</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    draw</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">rounded_rectangle</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">[</span><span class="token plain">cx</span><span class="token operator" style="color:#393A34">+</span><span class="token number" style="color:#36acaa">30</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> cy</span><span class="token operator" style="color:#393A34">+</span><span class="token number" style="color:#36acaa">50</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> cx</span><span class="token operator" style="color:#393A34">+</span><span class="token number" style="color:#36acaa">260</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> cy</span><span class="token operator" style="color:#393A34">+</span><span class="token number" style="color:#36acaa">120</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> radius</span><span class="token operator" style="color:#393A34">=</span><span class="token number" style="color:#36acaa">12</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> outline</span><span class="token operator" style="color:#393A34">=</span><span class="token plain">GREEN</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> width</span><span class="token operator" style="color:#393A34">=</span><span class="token number" style="color:#36acaa">3</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> fill</span><span class="token operator" style="color:#393A34">=</span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">0</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">40</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">0</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    draw_centered_text</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">draw</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"B200 GPU"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> cy</span><span class="token operator" style="color:#393A34">+</span><span class="token number" style="color:#36acaa">60</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> find_font</span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">24</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> GREEN</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    draw_centered_text</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">draw</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"× 36 颗  每颗 $60,000 – $70,000"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">640</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> find_font</span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">48</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> GOLD</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    draw_subtitle</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">draw</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"GB200 Superchip = 1×Grace CPU + 2×B200 GPU  全柜36颗"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> find_font</span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">26</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    draw_logo</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">draw</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">def</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">draw_transistor</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">img</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    draw </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> ImageDraw</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Draw</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">img</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    draw_centered_text</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">draw</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"208,000,000,000"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">280</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> find_font</span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">80</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> GOLD</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    draw_centered_text</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">draw</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"个晶体管"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">380</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> find_font</span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">80</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> WHITE</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    draw_centered_text</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">draw</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"台积电 4NP（4纳米）定制工艺"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">500</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> find_font</span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">32</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> LIGHT</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    draw_centered_text</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">draw</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"单颗 B200 GPU   流片费用 &gt; 1亿美元"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">580</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> find_font</span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">32</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> LIGHT</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">for</span><span class="token plain"> i </span><span class="token keyword" style="color:#00009f">in</span><span class="token plain"> </span><span class="token builtin">range</span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">0</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> W</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">40</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword" style="color:#00009f">for</span><span class="token plain"> j </span><span class="token keyword" style="color:#00009f">in</span><span class="token plain"> </span><span class="token builtin">range</span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">0</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">200</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">40</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">            draw</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">rectangle</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">[</span><span class="token plain">i</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">650</span><span class="token operator" style="color:#393A34">+</span><span class="token plain">j</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> i</span><span class="token operator" style="color:#393A34">+</span><span class="token number" style="color:#36acaa">30</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">650</span><span class="token operator" style="color:#393A34">+</span><span class="token plain">j</span><span class="token operator" style="color:#393A34">+</span><span class="token number" style="color:#36acaa">30</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> outline</span><span class="token operator" style="color:#393A34">=</span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">30</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">30</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">45</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> width</span><span class="token operator" style="color:#393A34">=</span><span class="token number" style="color:#36acaa">1</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    draw_centered_text</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">draw</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"▸ 208 BILLION TRANSISTORS ◂"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">910</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> find_font</span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">22</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">80</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">80</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">100</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    draw_subtitle</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">draw</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"单颗B200：2080亿晶体管  台积电4NP工艺"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    draw_logo</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">draw</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">def</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">draw_hbm</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">img</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    draw </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> ImageDraw</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Draw</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">img</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    draw</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">rounded_rectangle</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">[</span><span class="token plain">W</span><span class="token operator" style="color:#393A34">//</span><span class="token number" style="color:#36acaa">2</span><span class="token operator" style="color:#393A34">-</span><span class="token number" style="color:#36acaa">120</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">280</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> W</span><span class="token operator" style="color:#393A34">//</span><span class="token number" style="color:#36acaa">2</span><span class="token operator" style="color:#393A34">+</span><span class="token number" style="color:#36acaa">120</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">480</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> radius</span><span class="token operator" style="color:#393A34">=</span><span class="token number" style="color:#36acaa">18</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> outline</span><span class="token operator" style="color:#393A34">=</span><span class="token plain">BLUE</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> width</span><span class="token operator" style="color:#393A34">=</span><span class="token number" style="color:#36acaa">4</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> fill</span><span class="token operator" style="color:#393A34">=</span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">5</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">15</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">40</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    draw_centered_text</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">draw</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"B200"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">355</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> find_font</span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">36</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> BLUE</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    draw_centered_text</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">draw</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"GPU Die"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">400</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> find_font</span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">24</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> BLUE</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    hbm_positions </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">[</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">W</span><span class="token operator" style="color:#393A34">//</span><span class="token number" style="color:#36acaa">2</span><span class="token operator" style="color:#393A34">-</span><span class="token number" style="color:#36acaa">180</span><span class="token punctuation" style="color:#393A34">,</span><span class="token number" style="color:#36acaa">180</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">W</span><span class="token operator" style="color:#393A34">//</span><span class="token number" style="color:#36acaa">2</span><span class="token operator" style="color:#393A34">-</span><span class="token number" style="color:#36acaa">60</span><span class="token punctuation" style="color:#393A34">,</span><span class="token number" style="color:#36acaa">140</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">W</span><span class="token operator" style="color:#393A34">//</span><span class="token number" style="color:#36acaa">2</span><span class="token operator" style="color:#393A34">+</span><span class="token number" style="color:#36acaa">60</span><span class="token punctuation" style="color:#393A34">,</span><span class="token number" style="color:#36acaa">140</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">W</span><span class="token operator" style="color:#393A34">//</span><span class="token number" style="color:#36acaa">2</span><span class="token operator" style="color:#393A34">+</span><span class="token number" style="color:#36acaa">180</span><span class="token punctuation" style="color:#393A34">,</span><span class="token number" style="color:#36acaa">180</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">                     </span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">W</span><span class="token operator" style="color:#393A34">//</span><span class="token number" style="color:#36acaa">2</span><span class="token operator" style="color:#393A34">-</span><span class="token number" style="color:#36acaa">180</span><span class="token punctuation" style="color:#393A34">,</span><span class="token number" style="color:#36acaa">520</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">W</span><span class="token operator" style="color:#393A34">//</span><span class="token number" style="color:#36acaa">2</span><span class="token operator" style="color:#393A34">-</span><span class="token number" style="color:#36acaa">60</span><span class="token punctuation" style="color:#393A34">,</span><span class="token number" style="color:#36acaa">560</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">W</span><span class="token operator" style="color:#393A34">//</span><span class="token number" style="color:#36acaa">2</span><span class="token operator" style="color:#393A34">+</span><span class="token number" style="color:#36acaa">60</span><span class="token punctuation" style="color:#393A34">,</span><span class="token number" style="color:#36acaa">560</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">W</span><span class="token operator" style="color:#393A34">//</span><span class="token number" style="color:#36acaa">2</span><span class="token operator" style="color:#393A34">+</span><span class="token number" style="color:#36acaa">180</span><span class="token punctuation" style="color:#393A34">,</span><span class="token number" style="color:#36acaa">520</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">]</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">for</span><span class="token plain"> px</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> py </span><span class="token keyword" style="color:#00009f">in</span><span class="token plain"> hbm_positions</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        draw</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">rectangle</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">[</span><span class="token plain">px</span><span class="token operator" style="color:#393A34">-</span><span class="token number" style="color:#36acaa">35</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> py</span><span class="token operator" style="color:#393A34">-</span><span class="token number" style="color:#36acaa">45</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> px</span><span class="token operator" style="color:#393A34">+</span><span class="token number" style="color:#36acaa">35</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> py</span><span class="token operator" style="color:#393A34">+</span><span class="token number" style="color:#36acaa">45</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> outline</span><span class="token operator" style="color:#393A34">=</span><span class="token plain">GOLD</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> width</span><span class="token operator" style="color:#393A34">=</span><span class="token number" style="color:#36acaa">2</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> fill</span><span class="token operator" style="color:#393A34">=</span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">30</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">25</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">5</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        draw</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">text</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">px</span><span class="token operator" style="color:#393A34">-</span><span class="token number" style="color:#36acaa">25</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> py</span><span class="token operator" style="color:#393A34">-</span><span class="token number" style="color:#36acaa">30</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"HBM"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> font</span><span class="token operator" style="color:#393A34">=</span><span class="token plain">find_font</span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">14</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> fill</span><span class="token operator" style="color:#393A34">=</span><span class="token plain">GOLD</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    draw_centered_text</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">draw</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"192GB HBM3e × 72 = 13.5TB"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">700</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> find_font</span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">72</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> GOLD</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    draw_centered_text</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">draw</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"8TB/s 显存带宽 / 每颗GPU"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">790</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> find_font</span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">30</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> WHITE</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    draw_subtitle</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">draw</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"全柜 13.5TB 高速显存  物料成本近 20 万美元"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    draw_logo</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">draw</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">def</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">draw_nvswitch</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">img</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    draw </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> ImageDraw</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Draw</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">img</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">for</span><span class="token plain"> row </span><span class="token keyword" style="color:#00009f">in</span><span class="token plain"> </span><span class="token builtin">range</span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">3</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword" style="color:#00009f">for</span><span class="token plain"> col </span><span class="token keyword" style="color:#00009f">in</span><span class="token plain"> </span><span class="token builtin">range</span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">6</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">            rx</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> ry </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">260</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">+</span><span class="token plain"> col</span><span class="token operator" style="color:#393A34">*</span><span class="token number" style="color:#36acaa">240</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">200</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">+</span><span class="token plain"> row</span><span class="token operator" style="color:#393A34">*</span><span class="token number" style="color:#36acaa">180</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">            draw</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">rounded_rectangle</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">[</span><span class="token plain">rx</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> ry</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> rx</span><span class="token operator" style="color:#393A34">+</span><span class="token number" style="color:#36acaa">200</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> ry</span><span class="token operator" style="color:#393A34">+</span><span class="token number" style="color:#36acaa">140</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> radius</span><span class="token operator" style="color:#393A34">=</span><span class="token number" style="color:#36acaa">10</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> outline</span><span class="token operator" style="color:#393A34">=</span><span class="token plain">ORANGE</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> width</span><span class="token operator" style="color:#393A34">=</span><span class="token number" style="color:#36acaa">3</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> fill</span><span class="token operator" style="color:#393A34">=</span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">30</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">20</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">5</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">            draw</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">text</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">rx</span><span class="token operator" style="color:#393A34">+</span><span class="token number" style="color:#36acaa">40</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> ry</span><span class="token operator" style="color:#393A34">+</span><span class="token number" style="color:#36acaa">40</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"NVSwitch"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> font</span><span class="token operator" style="color:#393A34">=</span><span class="token plain">find_font</span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">20</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> fill</span><span class="token operator" style="color:#393A34">=</span><span class="token plain">ORANGE</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">            draw</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">text</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">rx</span><span class="token operator" style="color:#393A34">+</span><span class="token number" style="color:#36acaa">50</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> ry</span><span class="token operator" style="color:#393A34">+</span><span class="token number" style="color:#36acaa">70</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string-interpolation string" style="color:#e3116c">f"</span><span class="token string-interpolation interpolation punctuation" style="color:#393A34">{</span><span class="token string-interpolation interpolation">row</span><span class="token string-interpolation interpolation operator" style="color:#393A34">*</span><span class="token string-interpolation interpolation number" style="color:#36acaa">6</span><span class="token string-interpolation interpolation operator" style="color:#393A34">+</span><span class="token string-interpolation interpolation">col</span><span class="token string-interpolation interpolation operator" style="color:#393A34">+</span><span class="token string-interpolation interpolation number" style="color:#36acaa">1</span><span class="token string-interpolation interpolation punctuation" style="color:#393A34">:</span><span class="token string-interpolation interpolation format-spec">02d</span><span class="token string-interpolation interpolation punctuation" style="color:#393A34">}</span><span class="token string-interpolation string" style="color:#e3116c">"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> font</span><span class="token operator" style="color:#393A34">=</span><span class="token plain">find_font</span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">22</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> fill</span><span class="token operator" style="color:#393A34">=</span><span class="token plain">WHITE</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    draw_centered_text</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">draw</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"18 个 NVSwitch 交换盘"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">760</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> find_font</span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">60</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> GOLD</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    draw_centered_text</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">draw</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"9,000+ 铜缆连接器  把72颗GPU焊成整体"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">840</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> find_font</span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">30</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> WHITE</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    draw_subtitle</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">draw</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"NVSwitch 5 交换盘 × 18  每盘 ~$14K"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    draw_logo</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">draw</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">def</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">draw_backplane</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">img</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    draw </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> ImageDraw</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Draw</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">img</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    draw_centered_text</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">draw</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"130 TB/s"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">280</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> find_font</span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">110</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> GOLD</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    draw_centered_text</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">draw</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"总带宽"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">420</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> find_font</span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">48</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> WHITE</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    draw_centered_text</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">draw</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"🟤 铜缆背板  比光纤便宜 6 倍"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">560</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> find_font</span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">32</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> GOLD</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    draw_centered_text</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">draw</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"NVLink 5  1.8TB/s 双向带宽 / GPU"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">690</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> find_font</span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">32</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> LIGHT</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    draw_centered_text</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">draw</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"\"用铜不用光\"——Jensen Huang, GTC 2024"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">780</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> find_font</span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">24</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">100</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">100</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">120</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    draw_subtitle</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">draw</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"NVLink 5 铜背板  5000+根铜缆  130TB/s总带宽"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    draw_logo</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">draw</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">def</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">draw_cooling</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">img</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    draw </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> ImageDraw</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Draw</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">img</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">for</span><span class="token plain"> i </span><span class="token keyword" style="color:#00009f">in</span><span class="token plain"> </span><span class="token builtin">range</span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">6</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        y </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">180</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">+</span><span class="token plain"> i</span><span class="token operator" style="color:#393A34">*</span><span class="token number" style="color:#36acaa">100</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        draw</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">rectangle</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">[</span><span class="token number" style="color:#36acaa">100</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> y</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">600</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> y</span><span class="token operator" style="color:#393A34">+</span><span class="token number" style="color:#36acaa">60</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> outline</span><span class="token operator" style="color:#393A34">=</span><span class="token plain">CYAN</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> width</span><span class="token operator" style="color:#393A34">=</span><span class="token number" style="color:#36acaa">2</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> fill</span><span class="token operator" style="color:#393A34">=</span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">0</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">30</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">40</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        draw</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">text</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">120</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> y</span><span class="token operator" style="color:#393A34">+</span><span class="token number" style="color:#36acaa">10</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"❄️"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> font</span><span class="token operator" style="color:#393A34">=</span><span class="token plain">find_font</span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">30</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword" style="color:#00009f">for</span><span class="token plain"> j </span><span class="token keyword" style="color:#00009f">in</span><span class="token plain"> </span><span class="token builtin">range</span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">8</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">            draw</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">ellipse</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">[</span><span class="token number" style="color:#36acaa">160</span><span class="token operator" style="color:#393A34">+</span><span class="token plain">j</span><span class="token operator" style="color:#393A34">*</span><span class="token number" style="color:#36acaa">55</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> y</span><span class="token operator" style="color:#393A34">+</span><span class="token number" style="color:#36acaa">20</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">180</span><span class="token operator" style="color:#393A34">+</span><span class="token plain">j</span><span class="token operator" style="color:#393A34">*</span><span class="token number" style="color:#36acaa">55</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> y</span><span class="token operator" style="color:#393A34">+</span><span class="token number" style="color:#36acaa">40</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> fill</span><span class="token operator" style="color:#393A34">=</span><span class="token plain">CYAN </span><span class="token keyword" style="color:#00009f">if</span><span class="token plain"> j</span><span class="token operator" style="color:#393A34">%</span><span class="token number" style="color:#36acaa">2</span><span class="token operator" style="color:#393A34">==</span><span class="token number" style="color:#36acaa">0</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">else</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">0</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">60</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">80</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    draw_centered_text</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">draw</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"120 kW"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">380</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> find_font</span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">80</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> RED</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    draw_centered_text</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">draw</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"≈ 一栋30户居民楼夏天开满空调"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">560</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> find_font</span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">34</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> LIGHT</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    draw_centered_text</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">draw</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"风冷单柜极限仅 30kW  必须上液冷"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">630</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> find_font</span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">34</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> WHITE</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    draw_subtitle</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">draw</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"功耗 120kW  传统风冷撑不住  液冷是唯一方案"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    draw_logo</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">draw</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">def</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">draw_power_compare</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">img</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    draw </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> ImageDraw</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Draw</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">img</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    draw</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">rounded_rectangle</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">[</span><span class="token number" style="color:#36acaa">100</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">250</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">600</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">550</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> radius</span><span class="token operator" style="color:#393A34">=</span><span class="token number" style="color:#36acaa">15</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> outline</span><span class="token operator" style="color:#393A34">=</span><span class="token plain">RED</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> width</span><span class="token operator" style="color:#393A34">=</span><span class="token number" style="color:#36acaa">3</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> fill</span><span class="token operator" style="color:#393A34">=</span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">30</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">10</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">10</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    draw_centered_text</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">draw</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"传统风冷机柜"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">220</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> find_font</span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">32</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> RED</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    draw_centered_text</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">draw</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"Max 30 kW"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">400</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> find_font</span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">80</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> RED</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    draw</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">rounded_rectangle</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">[</span><span class="token plain">W</span><span class="token operator" style="color:#393A34">-</span><span class="token number" style="color:#36acaa">600</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">200</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> W</span><span class="token operator" style="color:#393A34">-</span><span class="token number" style="color:#36acaa">100</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">600</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> radius</span><span class="token operator" style="color:#393A34">=</span><span class="token number" style="color:#36acaa">15</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> outline</span><span class="token operator" style="color:#393A34">=</span><span class="token plain">GREEN</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> width</span><span class="token operator" style="color:#393A34">=</span><span class="token number" style="color:#36acaa">4</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> fill</span><span class="token operator" style="color:#393A34">=</span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">0</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">30</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">10</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    draw_centered_text</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">draw</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"GB200 NVL72"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">180</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> find_font</span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">32</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> GREEN</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    draw_centered_text</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">draw</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"120 kW"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">340</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> find_font</span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">90</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> GREEN</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    draw_centered_text</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">draw</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"4 倍于极限"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">460</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> find_font</span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">60</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> GREEN</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    draw_centered_text</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">draw</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"VS"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">400</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> find_font</span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">120</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> GOLD</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    draw_subtitle</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">draw</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"传统风冷 vs GB200 NVL72  功耗差距 4 倍"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    draw_logo</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">draw</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">def</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">draw_nic_array</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">img</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    draw </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> ImageDraw</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Draw</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">img</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">for</span><span class="token plain"> row </span><span class="token keyword" style="color:#00009f">in</span><span class="token plain"> </span><span class="token builtin">range</span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">6</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword" style="color:#00009f">for</span><span class="token plain"> col </span><span class="token keyword" style="color:#00009f">in</span><span class="token plain"> </span><span class="token builtin">range</span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">6</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">            nx</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> ny </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">300</span><span class="token operator" style="color:#393A34">+</span><span class="token plain">col</span><span class="token operator" style="color:#393A34">*</span><span class="token number" style="color:#36acaa">200</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">180</span><span class="token operator" style="color:#393A34">+</span><span class="token plain">row</span><span class="token operator" style="color:#393A34">*</span><span class="token number" style="color:#36acaa">120</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">            draw</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">rounded_rectangle</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">[</span><span class="token plain">nx</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> ny</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> nx</span><span class="token operator" style="color:#393A34">+</span><span class="token number" style="color:#36acaa">170</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> ny</span><span class="token operator" style="color:#393A34">+</span><span class="token number" style="color:#36acaa">90</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> radius</span><span class="token operator" style="color:#393A34">=</span><span class="token number" style="color:#36acaa">8</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> outline</span><span class="token operator" style="color:#393A34">=</span><span class="token plain">BLUE</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> width</span><span class="token operator" style="color:#393A34">=</span><span class="token number" style="color:#36acaa">2</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> fill</span><span class="token operator" style="color:#393A34">=</span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">5</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">10</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">35</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">            draw</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">text</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">nx</span><span class="token operator" style="color:#393A34">+</span><span class="token number" style="color:#36acaa">20</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> ny</span><span class="token operator" style="color:#393A34">+</span><span class="token number" style="color:#36acaa">15</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"CX-8"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> font</span><span class="token operator" style="color:#393A34">=</span><span class="token plain">find_font</span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">26</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> fill</span><span class="token operator" style="color:#393A34">=</span><span class="token plain">BLUE</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">            draw</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">text</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">nx</span><span class="token operator" style="color:#393A34">+</span><span class="token number" style="color:#36acaa">20</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> ny</span><span class="token operator" style="color:#393A34">+</span><span class="token number" style="color:#36acaa">45</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"800Gb/s"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> font</span><span class="token operator" style="color:#393A34">=</span><span class="token plain">find_font</span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">18</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> fill</span><span class="token operator" style="color:#393A34">=</span><span class="token plain">WHITE</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    draw_centered_text</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">draw</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"36 块 ConnectX-8"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">900</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> find_font</span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">60</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> GOLD</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    draw_centered_text</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">draw</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"每块 800Gb/s + Spectrum-X 交换机"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">970</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> find_font</span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">28</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> WHITE</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    draw_subtitle</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">draw</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"网络方案  36 NIC × 800Gb/s + Spectrum-X 交换"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    draw_logo</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">draw</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">def</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">draw_network_topology</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">img</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    draw </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> ImageDraw</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Draw</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">img</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    draw</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">rounded_rectangle</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">[</span><span class="token plain">W</span><span class="token operator" style="color:#393A34">//</span><span class="token number" style="color:#36acaa">2</span><span class="token operator" style="color:#393A34">-</span><span class="token number" style="color:#36acaa">250</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">120</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> W</span><span class="token operator" style="color:#393A34">//</span><span class="token number" style="color:#36acaa">2</span><span class="token operator" style="color:#393A34">+</span><span class="token number" style="color:#36acaa">250</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">200</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> radius</span><span class="token operator" style="color:#393A34">=</span><span class="token number" style="color:#36acaa">12</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> outline</span><span class="token operator" style="color:#393A34">=</span><span class="token plain">PURPLE</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> width</span><span class="token operator" style="color:#393A34">=</span><span class="token number" style="color:#36acaa">3</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> fill</span><span class="token operator" style="color:#393A34">=</span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">20</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">10</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">30</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    draw_centered_text</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">draw</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"Spectrum-X 交换机"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">145</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> find_font</span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">28</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> PURPLE</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">for</span><span class="token plain"> i </span><span class="token keyword" style="color:#00009f">in</span><span class="token plain"> </span><span class="token builtin">range</span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">36</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        sx</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> sy </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">180</span><span class="token operator" style="color:#393A34">+</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">i</span><span class="token operator" style="color:#393A34">%</span><span class="token number" style="color:#36acaa">12</span><span class="token punctuation" style="color:#393A34">)</span><span class="token operator" style="color:#393A34">*</span><span class="token number" style="color:#36acaa">130</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">320</span><span class="token operator" style="color:#393A34">+</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">i</span><span class="token operator" style="color:#393A34">//</span><span class="token number" style="color:#36acaa">12</span><span class="token punctuation" style="color:#393A34">)</span><span class="token operator" style="color:#393A34">*</span><span class="token number" style="color:#36acaa">160</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        draw</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">line</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">[</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">W</span><span class="token operator" style="color:#393A34">//</span><span class="token number" style="color:#36acaa">2</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">200</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">sx</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> sy</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> fill</span><span class="token operator" style="color:#393A34">=</span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">60</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">40</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">100</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> width</span><span class="token operator" style="color:#393A34">=</span><span class="token number" style="color:#36acaa">1</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        draw</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">rectangle</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">[</span><span class="token plain">sx</span><span class="token operator" style="color:#393A34">-</span><span class="token number" style="color:#36acaa">35</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> sy</span><span class="token operator" style="color:#393A34">-</span><span class="token number" style="color:#36acaa">20</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> sx</span><span class="token operator" style="color:#393A34">+</span><span class="token number" style="color:#36acaa">35</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> sy</span><span class="token operator" style="color:#393A34">+</span><span class="token number" style="color:#36acaa">20</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> outline</span><span class="token operator" style="color:#393A34">=</span><span class="token plain">BLUE</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> width</span><span class="token operator" style="color:#393A34">=</span><span class="token number" style="color:#36acaa">2</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> fill</span><span class="token operator" style="color:#393A34">=</span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">5</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">10</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">30</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        draw</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">text</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">sx</span><span class="token operator" style="color:#393A34">-</span><span class="token number" style="color:#36acaa">25</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> sy</span><span class="token operator" style="color:#393A34">-</span><span class="token number" style="color:#36acaa">12</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string-interpolation string" style="color:#e3116c">f"GB</span><span class="token string-interpolation interpolation punctuation" style="color:#393A34">{</span><span class="token string-interpolation interpolation">i</span><span class="token string-interpolation interpolation operator" style="color:#393A34">+</span><span class="token string-interpolation interpolation number" style="color:#36acaa">1</span><span class="token string-interpolation interpolation punctuation" style="color:#393A34">}</span><span class="token string-interpolation string" style="color:#e3116c">"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> font</span><span class="token operator" style="color:#393A34">=</span><span class="token plain">find_font</span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">14</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> fill</span><span class="token operator" style="color:#393A34">=</span><span class="token plain">BLUE</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    draw_centered_text</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">draw</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"Rail-optimized  Adaptive Routing  低延迟"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">850</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> find_font</span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">28</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> PURPLE</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    draw_subtitle</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">draw</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"Spectrum-X  专为AI训练流量优化的以太网"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    draw_logo</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">draw</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic"># ... 其余绘图函数 (draw_rack, draw_busbar, draw_assembly, draw_cost_bar 系列,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">#     draw_training_compare, draw_inference_compare, draw_unified_memory,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">#     draw_customers, draw_pie_chart, draw_moore_curve, draw_ending)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">#     完整代码见 video_output/build_video.py，此处略去以保持博客可读性。</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic"># ============================================================</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic"># TTS 旁白 (28段)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic"># ============================================================</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">NARRATIONS </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">[</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token string" style="color:#e3116c">"一台AI服务器机柜，三百万美元。"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token string" style="color:#e3116c">"它叫GB200 NVL72，NVIDIA在2024年GTC大会上发布的旗舰。72颗Blackwell GPU，塞进一个机柜。"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token string" style="color:#e3116c">"三百万美元，相当于三台法拉利488，或者北京五环一套房。"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token string" style="color:#e3116c">"现在，我们来把它拆开。"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token string" style="color:#e3116c">"最大的开销在GPU。36颗GB200 Superchip，每颗封装两颗B200 GPU和一颗Grace CPU。单颗六到七万美元。三十六颗，两百万就出去了。"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token string" style="color:#e3116c">"一颗B200上有两千零八十亿个晶体管，台积电四纳米定制工艺。这个量级的芯片，光流片费用就要上亿美元。"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token string" style="color:#e3116c">"比GPU Die更贵的，是它身边的HBM3e高带宽显存。每颗B200搭载192GB，整个机柜堆了13.5TB。物料成本接近二十万美元。"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token string" style="color:#e3116c">"仅GPU和显存，就花掉两百二十万美元，占总成本的四分之三。"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token string" style="color:#e3116c">"第二笔大开销是NVLink交换网络。十八个NVSwitch交换盘，用九千个铜缆连接器把七十二颗GPU焊成一个整体。"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token string" style="color:#e3116c">"铜背板提供每秒130TB总带宽，比光纤方案便宜六倍。这是NVIDIA的秘密武器。"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token string" style="color:#e3116c">"仅交换网络部分，又是二十五万美元。"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token string" style="color:#e3116c">"这个机柜跑起来要吃掉一百二十千瓦的电。一栋三十户居民楼夏天开满空调也就这个功率。风冷根本顶不住，必须上液冷。"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token string" style="color:#e3116c">"传统数据中心单柜功耗撑死三十千瓦，GB200直接冲到一百二，是极限的四倍。"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token string" style="color:#e3116c">"液冷散热系统——冷却液分配单元、冷板、管路——加起来要十万美元。"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token string" style="color:#e3116c">"GPU算得再快，数据进不来也白搭。每颗Superchip配一块八百G的网卡，加上Spectrum-X交换机，整套网络方案十五万美元。"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token string" style="color:#e3116c">"Spectrum-X是NVIDIA专为AI训练流量优化的以太网方案，能做到InfiniBand级别的性能。"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token string" style="color:#e3116c">"整套网络方案约十五万美元，占总成本百分之五。"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token string" style="color:#e3116c">"这个机柜不是标准件，NVIDIA重新设计了整个结构来容纳七十二颗GPU和一百二十千瓦的供电。"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token string" style="color:#e3116c">"供电是415伏三相直入，跳过传统UPS直接上电，就是为了省转换损耗。"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token string" style="color:#e3116c">"定制机柜、电源分配、组装测试，五万五千美元。"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token string" style="color:#e3116c">"每台NVL72出厂前需要数周组装和七十二小时满负荷烧机测试。任何一个节点出问题，整柜都得返工。"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token string" style="color:#e3116c">"三百万值不值？看你怎么算。训练一个万亿参数大模型，H100要跑三到四个月，GB200一个月以内搞定。"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token string" style="color:#e3116c">"推理性能更是五倍提升，而且因为72颗GPU共享13.5TB统一显存，不用切模型，整个万亿参数模型可以直接塞进一个机柜跑。"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token string" style="color:#e3116c">"72颗GPU在NVLink下变成一台超级GPU，大模型不切分，直接跑。省掉分布式训练的通信开销，这是质的区别。"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token string" style="color:#e3116c">"这也是为什么微软、Meta、Oracle、xAI这些公司已经在排队下单。在这个级别的竞赛里，时间就是护城河。"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token string" style="color:#e3116c">"拆完你会发现，三百万里，两百二十万花在GPU和显存上。剩下的八十万，是让这七十二颗GPU真正能一起工作的代价。"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token string" style="color:#e3116c">"从2016年的DGX-1十二万九，到2024年的GB200 NVL72三百万，AI硬件的价格曲线比摩尔定律陡十倍。这就是算力军备竞赛的真相。"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token string" style="color:#e3116c">"算力无价。但硬件，真的有价。"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">]</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic"># ============================================================</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic"># 核心流程</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic"># ============================================================</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">async</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">def</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">generate_tts</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token triple-quoted-string string" style="color:#e3116c">"""逐段生成 TTS 音频，返回 (路径, 时长) 列表"""</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    AUDIO_DIR</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">mkdir</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">parents</span><span class="token operator" style="color:#393A34">=</span><span class="token boolean" style="color:#36acaa">True</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> exist_ok</span><span class="token operator" style="color:#393A34">=</span><span class="token boolean" style="color:#36acaa">True</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    results </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">[</span><span class="token punctuation" style="color:#393A34">]</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">for</span><span class="token plain"> i</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> text </span><span class="token keyword" style="color:#00009f">in</span><span class="token plain"> </span><span class="token builtin">enumerate</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">NARRATIONS</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        out_file </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> AUDIO_DIR </span><span class="token operator" style="color:#393A34">/</span><span class="token plain"> </span><span class="token string-interpolation string" style="color:#e3116c">f"shot_</span><span class="token string-interpolation interpolation punctuation" style="color:#393A34">{</span><span class="token string-interpolation interpolation">i</span><span class="token string-interpolation interpolation punctuation" style="color:#393A34">:</span><span class="token string-interpolation interpolation format-spec">02d</span><span class="token string-interpolation interpolation punctuation" style="color:#393A34">}</span><span class="token string-interpolation string" style="color:#e3116c">.mp3"</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword" style="color:#00009f">if</span><span class="token plain"> out_file</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">exists</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">            r </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> subprocess</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">run</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">[</span><span class="token string" style="color:#e3116c">"ffprobe"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"-v"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"quiet"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"-show_entries"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">                </span><span class="token string" style="color:#e3116c">"format=duration"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"-of"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"json"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token builtin">str</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">out_file</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">                capture_output</span><span class="token operator" style="color:#393A34">=</span><span class="token boolean" style="color:#36acaa">True</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> text</span><span class="token operator" style="color:#393A34">=</span><span class="token boolean" style="color:#36acaa">True</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">            dur </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token builtin">float</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">json</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">loads</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">r</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">stdout</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">[</span><span class="token string" style="color:#e3116c">"format"</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">[</span><span class="token string" style="color:#e3116c">"duration"</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">            results</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">append</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">(</span><span class="token builtin">str</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">out_file</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> dur</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">            </span><span class="token keyword" style="color:#00009f">continue</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        comm </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> edge_tts</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Communicate</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">text</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> TTS_VOICE</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> rate</span><span class="token operator" style="color:#393A34">=</span><span class="token plain">TTS_RATE</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword" style="color:#00009f">await</span><span class="token plain"> comm</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">save</span><span class="token punctuation" style="color:#393A34">(</span><span class="token builtin">str</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">out_file</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        r </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> subprocess</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">run</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">[</span><span class="token string" style="color:#e3116c">"ffprobe"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"-v"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"quiet"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"-show_entries"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">            </span><span class="token string" style="color:#e3116c">"format=duration"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"-of"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"json"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token builtin">str</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">out_file</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">            capture_output</span><span class="token operator" style="color:#393A34">=</span><span class="token boolean" style="color:#36acaa">True</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> text</span><span class="token operator" style="color:#393A34">=</span><span class="token boolean" style="color:#36acaa">True</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        dur </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token builtin">float</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">json</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">loads</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">r</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">stdout</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">[</span><span class="token string" style="color:#e3116c">"format"</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">[</span><span class="token string" style="color:#e3116c">"duration"</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        results</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">append</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">(</span><span class="token builtin">str</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">out_file</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> dur</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword" style="color:#00009f">print</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string-interpolation string" style="color:#e3116c">f"  [音频] shot_</span><span class="token string-interpolation interpolation punctuation" style="color:#393A34">{</span><span class="token string-interpolation interpolation">i</span><span class="token string-interpolation interpolation punctuation" style="color:#393A34">:</span><span class="token string-interpolation interpolation format-spec">02d</span><span class="token string-interpolation interpolation punctuation" style="color:#393A34">}</span><span class="token string-interpolation string" style="color:#e3116c"> (</span><span class="token string-interpolation interpolation punctuation" style="color:#393A34">{</span><span class="token string-interpolation interpolation">dur</span><span class="token string-interpolation interpolation punctuation" style="color:#393A34">:</span><span class="token string-interpolation interpolation format-spec">.1f</span><span class="token string-interpolation interpolation punctuation" style="color:#393A34">}</span><span class="token string-interpolation string" style="color:#e3116c">s)"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> results</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">def</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">generate_frames</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">audio_durations</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token triple-quoted-string string" style="color:#e3116c">"""Pillow 绘制 28 张 1920×1080 信息图"""</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    FRAMES_DIR</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">mkdir</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">parents</span><span class="token operator" style="color:#393A34">=</span><span class="token boolean" style="color:#36acaa">True</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> exist_ok</span><span class="token operator" style="color:#393A34">=</span><span class="token boolean" style="color:#36acaa">True</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    frame_list </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">[</span><span class="token punctuation" style="color:#393A34">]</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">for</span><span class="token plain"> i</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">title</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> subtitle</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> draw_fn</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">in</span><span class="token plain"> </span><span class="token builtin">enumerate</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">SHOTS</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        img </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> new_frame</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token builtin">globals</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">[</span><span class="token plain">draw_fn</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">img</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain">   </span><span class="token comment" style="color:#999988;font-style:italic"># 按函数名动态调用绘图函数</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        out_path </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> FRAMES_DIR </span><span class="token operator" style="color:#393A34">/</span><span class="token plain"> </span><span class="token string-interpolation string" style="color:#e3116c">f"frame_</span><span class="token string-interpolation interpolation punctuation" style="color:#393A34">{</span><span class="token string-interpolation interpolation">i</span><span class="token string-interpolation interpolation punctuation" style="color:#393A34">:</span><span class="token string-interpolation interpolation format-spec">03d</span><span class="token string-interpolation interpolation punctuation" style="color:#393A34">}</span><span class="token string-interpolation string" style="color:#e3116c">.png"</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        img</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">save</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">out_path</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        dur </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> audio_durations</span><span class="token punctuation" style="color:#393A34">[</span><span class="token plain">i</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">[</span><span class="token number" style="color:#36acaa">1</span><span class="token punctuation" style="color:#393A34">]</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        frame_list</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">append</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">(</span><span class="token builtin">str</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">out_path</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> dur</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> frame_list</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">def</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">generate_srt</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">audio_durations</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token triple-quoted-string string" style="color:#e3116c">"""自动生成 SRT 字幕"""</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    srt</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> t </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">[</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">0.0</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">for</span><span class="token plain"> i</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">_</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> dur</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">in</span><span class="token plain"> </span><span class="token builtin">enumerate</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">audio_durations</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword" style="color:#00009f">def</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">fmt</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">x</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">            h</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> m</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> s </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token builtin">int</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">x</span><span class="token operator" style="color:#393A34">//</span><span class="token number" style="color:#36acaa">3600</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token builtin">int</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">x</span><span class="token operator" style="color:#393A34">%</span><span class="token number" style="color:#36acaa">3600</span><span class="token punctuation" style="color:#393A34">)</span><span class="token operator" style="color:#393A34">//</span><span class="token number" style="color:#36acaa">60</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token builtin">int</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">x</span><span class="token operator" style="color:#393A34">%</span><span class="token number" style="color:#36acaa">60</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">            </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> </span><span class="token string-interpolation string" style="color:#e3116c">f"</span><span class="token string-interpolation interpolation punctuation" style="color:#393A34">{</span><span class="token string-interpolation interpolation">h</span><span class="token string-interpolation interpolation punctuation" style="color:#393A34">:</span><span class="token string-interpolation interpolation format-spec">02d</span><span class="token string-interpolation interpolation punctuation" style="color:#393A34">}</span><span class="token string-interpolation string" style="color:#e3116c">:</span><span class="token string-interpolation interpolation punctuation" style="color:#393A34">{</span><span class="token string-interpolation interpolation">m</span><span class="token string-interpolation interpolation punctuation" style="color:#393A34">:</span><span class="token string-interpolation interpolation format-spec">02d</span><span class="token string-interpolation interpolation punctuation" style="color:#393A34">}</span><span class="token string-interpolation string" style="color:#e3116c">:</span><span class="token string-interpolation interpolation punctuation" style="color:#393A34">{</span><span class="token string-interpolation interpolation">s</span><span class="token string-interpolation interpolation punctuation" style="color:#393A34">:</span><span class="token string-interpolation interpolation format-spec">02d</span><span class="token string-interpolation interpolation punctuation" style="color:#393A34">}</span><span class="token string-interpolation string" style="color:#e3116c">,</span><span class="token string-interpolation interpolation punctuation" style="color:#393A34">{</span><span class="token string-interpolation interpolation builtin">int</span><span class="token string-interpolation interpolation punctuation" style="color:#393A34">(</span><span class="token string-interpolation interpolation punctuation" style="color:#393A34">(</span><span class="token string-interpolation interpolation">x</span><span class="token string-interpolation interpolation operator" style="color:#393A34">%</span><span class="token string-interpolation interpolation number" style="color:#36acaa">1</span><span class="token string-interpolation interpolation punctuation" style="color:#393A34">)</span><span class="token string-interpolation interpolation operator" style="color:#393A34">*</span><span class="token string-interpolation interpolation number" style="color:#36acaa">1000</span><span class="token string-interpolation interpolation punctuation" style="color:#393A34">)</span><span class="token string-interpolation interpolation punctuation" style="color:#393A34">:</span><span class="token string-interpolation interpolation format-spec">03d</span><span class="token string-interpolation interpolation punctuation" style="color:#393A34">}</span><span class="token string-interpolation string" style="color:#e3116c">"</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        srt </span><span class="token operator" style="color:#393A34">+=</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">[</span><span class="token string-interpolation string" style="color:#e3116c">f"</span><span class="token string-interpolation interpolation punctuation" style="color:#393A34">{</span><span class="token string-interpolation interpolation">i</span><span class="token string-interpolation interpolation operator" style="color:#393A34">+</span><span class="token string-interpolation interpolation number" style="color:#36acaa">1</span><span class="token string-interpolation interpolation punctuation" style="color:#393A34">}</span><span class="token string-interpolation string" style="color:#e3116c">"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string-interpolation string" style="color:#e3116c">f"</span><span class="token string-interpolation interpolation punctuation" style="color:#393A34">{</span><span class="token string-interpolation interpolation">fmt</span><span class="token string-interpolation interpolation punctuation" style="color:#393A34">(</span><span class="token string-interpolation interpolation">t</span><span class="token string-interpolation interpolation punctuation" style="color:#393A34">)</span><span class="token string-interpolation interpolation punctuation" style="color:#393A34">}</span><span class="token string-interpolation string" style="color:#e3116c"> --&gt; </span><span class="token string-interpolation interpolation punctuation" style="color:#393A34">{</span><span class="token string-interpolation interpolation">fmt</span><span class="token string-interpolation interpolation punctuation" style="color:#393A34">(</span><span class="token string-interpolation interpolation">t</span><span class="token string-interpolation interpolation operator" style="color:#393A34">+</span><span class="token string-interpolation interpolation">dur</span><span class="token string-interpolation interpolation punctuation" style="color:#393A34">)</span><span class="token string-interpolation interpolation punctuation" style="color:#393A34">}</span><span class="token string-interpolation string" style="color:#e3116c">"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> NARRATIONS</span><span class="token punctuation" style="color:#393A34">[</span><span class="token plain">i</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">""</span><span class="token punctuation" style="color:#393A34">]</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        t </span><span class="token operator" style="color:#393A34">+=</span><span class="token plain"> dur</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    SRT_OUT</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">write_text</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"\n"</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">join</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">srt</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> encoding</span><span class="token operator" style="color:#393A34">=</span><span class="token string" style="color:#e3116c">"utf-8"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">def</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">compose_video</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">frame_list</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token triple-quoted-string string" style="color:#e3116c">"""ffmpeg 合成：帧序列 + 音频 + 字幕 → MP4</span><br></div><div class="token-line" style="color:#393A34"><span class="token triple-quoted-string string" style="color:#e3116c">    注意：实际踩坑后改为两遍编码（先无字幕再烧字幕），</span><br></div><div class="token-line" style="color:#393A34"><span class="token triple-quoted-string string" style="color:#e3116c">    且音频需预处理音量（aresample=44100,volume=4.0）。</span><br></div><div class="token-line" style="color:#393A34"><span class="token triple-quoted-string string" style="color:#e3116c">    此处保留原始逻辑供参考，实际执行命令见上文"实际生成"章节。</span><br></div><div class="token-line" style="color:#393A34"><span class="token triple-quoted-string string" style="color:#e3116c">    """</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token comment" style="color:#999988;font-style:italic"># ... (实际合成逻辑见上文"实际生成"章节的 ffmpeg 命令)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">async</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">def</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">main</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    audio </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">await</span><span class="token plain"> generate_tts</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    frames </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> generate_frames</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">audio</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    generate_srt</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">audio</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    compose_video</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">frames</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">if</span><span class="token plain"> __name__ </span><span class="token operator" style="color:#393A34">==</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"__main__"</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    asyncio</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">run</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">main</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><br></div></code></pre></div></div></div></div></details>
<blockquote>
<p><strong>完整版源码</strong>（含所有 28 个 Pillow 绘图函数的完整实现）见仓库 <code>video_output/build_video.py</code>。</p>
</blockquote>]]></content>
        <category label="ai" term="ai"/>
        <category label="nvidia" term="nvidia"/>
        <category label="gb200" term="gb200"/>
        <category label="hardware" term="hardware"/>
        <category label="gpu" term="gpu"/>
        <category label="infrastructure" term="infrastructure"/>
        <category label="video-script" term="video-script"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[Function Calling 诞生的背景：LLM 为什么要学会调用函数]]></title>
        <id>https://feifeigd.github.io/blog/2026/07/14/function-calling-background</id>
        <link href="https://feifeigd.github.io/blog/2026/07/14/function-calling-background"/>
        <updated>2026-07-14T14:00:00.000Z</updated>
        <summary type="html"><![CDATA[从 LLM 的能力边界出发，理解 Function Calling 为什么是必然产物]]></summary>
        <content type="html"><![CDATA[<h2 class="anchor anchorTargetStickyNavbar_e8hc" id="引言">引言<a href="https://feifeigd.github.io/blog/2026/07/14/function-calling-background#%E5%BC%95%E8%A8%80" class="hash-link" aria-label="引言的直接链接" title="引言的直接链接" translate="no">​</a></h2>
<p>2023 年 6 月，OpenAI 在 GPT-4-0613 和 GPT-3.5-turbo-0613 中首次引入了 <strong>Function Calling</strong> 能力。当时很多人第一反应是："这不就是让模型生成 JSON 吗？有什么特别的？"</p>
<p>两年后再回头去看，Function Calling 是 LLM 从"聊天玩具"走向"生产工具"的关键一步。本文不讲 API 怎么调用，而是聊清楚一个更根本的问题：<strong>Function Calling 到底解决了什么问题？它为什么一定会出现？</strong></p>
<!-- -->
<hr>
<h2 class="anchor anchorTargetStickyNavbar_e8hc" id="纯文本-llm-的能力天花板">纯文本 LLM 的能力天花板<a href="https://feifeigd.github.io/blog/2026/07/14/function-calling-background#%E7%BA%AF%E6%96%87%E6%9C%AC-llm-%E7%9A%84%E8%83%BD%E5%8A%9B%E5%A4%A9%E8%8A%B1%E6%9D%BF" class="hash-link" aria-label="纯文本 LLM 的能力天花板的直接链接" title="纯文本 LLM 的能力天花板的直接链接" translate="no">​</a></h2>
<p>GPT-3 在 2020 年横空出世，ChatGPT 在 2022 年底引爆全球，LLM 展现出了惊人的对话和生成能力。但你在生产环境用过就知道，纯文本模型有几个绕不过去的死穴：</p>
<h3 class="anchor anchorTargetStickyNavbar_e8hc" id="1-幻觉问题模型不知道自己不知道">1. 幻觉问题——模型不知道自己不知道<a href="https://feifeigd.github.io/blog/2026/07/14/function-calling-background#1-%E5%B9%BB%E8%A7%89%E9%97%AE%E9%A2%98%E6%A8%A1%E5%9E%8B%E4%B8%8D%E7%9F%A5%E9%81%93%E8%87%AA%E5%B7%B1%E4%B8%8D%E7%9F%A5%E9%81%93" class="hash-link" aria-label="1. 幻觉问题——模型不知道自己不知道的直接链接" title="1. 幻觉问题——模型不知道自己不知道的直接链接" translate="no">​</a></h3>
<p>你问模型"今天北京天气怎么样？"，它会流畅地编一段天气预报出来。因为训练数据截止到某个时间点，它根本不知道"今天"是什么。更致命的是，它<strong>不会主动告诉你它不知道</strong>，而是用最自信的语气胡说八道。</p>
<h3 class="anchor anchorTargetStickyNavbar_e8hc" id="2-无法与外部系统交互">2. 无法与外部系统交互<a href="https://feifeigd.github.io/blog/2026/07/14/function-calling-background#2-%E6%97%A0%E6%B3%95%E4%B8%8E%E5%A4%96%E9%83%A8%E7%B3%BB%E7%BB%9F%E4%BA%A4%E4%BA%92" class="hash-link" aria-label="2. 无法与外部系统交互的直接链接" title="2. 无法与外部系统交互的直接链接" translate="no">​</a></h3>
<p>企业的核心业务逻辑跑在数据库、API、微服务上，而不是 LLM 的 prompt 里。一个客服机器人如果查不到订单号对应的物流状态、不能取消订单、不能查询库存，那它再"会聊天"也没用——用户要的是解决问题，不是听你绕圈子。</p>
<h3 class="anchor anchorTargetStickyNavbar_e8hc" id="3-无法执行确定性计算">3. 无法执行确定性计算<a href="https://feifeigd.github.io/blog/2026/07/14/function-calling-background#3-%E6%97%A0%E6%B3%95%E6%89%A7%E8%A1%8C%E7%A1%AE%E5%AE%9A%E6%80%A7%E8%AE%A1%E7%AE%97" class="hash-link" aria-label="3. 无法执行确定性计算的直接链接" title="3. 无法执行确定性计算的直接链接" translate="no">​</a></h3>
<p>$12345.67 \times 0.13$ 这种精确计算，LLM 是靠概率"猜"出来的，而不是算出来的。你让 GPT-3.5 做两位数乘法都有概率出错。更不用说日期计算、汇率转换、UUID 生成这些必须 100% 准确的操作。</p>
<h3 class="anchor anchorTargetStickyNavbar_e8hc" id="4-回答不可控">4. 回答不可控<a href="https://feifeigd.github.io/blog/2026/07/14/function-calling-background#4-%E5%9B%9E%E7%AD%94%E4%B8%8D%EF%BF%BD%EF%BF%BD%E5%8F%AF%E6%8E%A7" class="hash-link" aria-label="4. 回答不可控的直接链接" title="4. 回答不可控的直接链接" translate="no">​</a></h3>
<p>同样的 prompt，两次回答可能完全不一样。在对话场景下这或许是"温度"的美，但在"调用 API 删除一台服务器"这种场景下，你绝不希望模型即兴发挥。</p>
<p><strong>总结一句话：LLM 擅长"理解意图"，但完全不具备"执行动作"的能力。</strong> 而这个世界大部分有价值的事情，最终都是"动作"而非"文字"。</p>
<hr>
<h2 class="anchor anchorTargetStickyNavbar_e8hc" id="早期解决方案prompt-engineering-的暴力美學">早期解决方案：Prompt Engineering 的暴力美學<a href="https://feifeigd.github.io/blog/2026/07/14/function-calling-background#%E6%97%A9%E6%9C%9F%E8%A7%A3%E5%86%B3%E6%96%B9%E6%A1%88prompt-engineering-%E7%9A%84%E6%9A%B4%E5%8A%9B%E7%BE%8E%E5%AD%B8" class="hash-link" aria-label="早期解决方案：Prompt Engineering 的暴力美學的直接链接" title="早期解决方案：Prompt Engineering 的暴力美學的直接链接" translate="no">​</a></h2>
<p>在 Function Calling 出现之前，大家已经在用 Prompt Engineering 强行让 LLM 输出结构化数据。大概长这样：</p>
<div class="language-text codeBlockContainer_zaIt theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_SaHH"><pre tabindex="0" class="prism-code language-text codeBlock_KlaO thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_zkpV"><div class="token-line" style="color:#393A34"><span class="token plain">你是一个助手。如果用户想查天气，请严格按照以下 JSON 格式输出：</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">{"action": "get_weather", "city": "城市名"}</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">用户：北京今天天气怎么样？</span><br></div></code></pre></div></div>
<p>然后代码里 <code>json.loads()</code> 解析模型输出，匹配到对应函数去执行。</p>
<p>这套方案<strong>能跑，但极其脆弱</strong>。问题包括：</p>
<ul>
<li class=""><strong>格式不稳定</strong>：模型偶尔多输出一个换行、一个逗号，<code>json.loads()</code> 直接炸。加个 <code>try-except</code> 再重试？那延迟就翻倍了。</li>
<li class=""><strong>依赖 prompt 质量</strong>：你需要在 prompt 里精确描述每个函数的参数、类型、约束。参数一多，prompt 膨胀到几千 token，不仅慢，而且模型的注意力会被稀释。</li>
<li class=""><strong>无法处理复杂嵌套</strong>：嵌套对象、数组、枚举类型，靠纯 prompt 描述会让模型困惑，输出结构经常不符合预期。</li>
<li class=""><strong>没有官方契约</strong>：每个人都在自己的代码里手写 JSON Schema 的"prompt 翻译"，没有任何标准化。</li>
</ul>
<p>那时候社区做了很多轮子——LangChain 的 <code>OutputParser</code>、Guardrails、Instructor——本质上都是在对 LLM 的不稳定输出做"正则匹配 + 重试 + 修复"的补丁。</p>
<hr>
<h2 class="anchor anchorTargetStickyNavbar_e8hc" id="关键转折fine-tuning-让模型原生理解结构化输出">关键转折：Fine-tuning 让模型"原生理解"结构化输出<a href="https://feifeigd.github.io/blog/2026/07/14/function-calling-background#%E5%85%B3%E9%94%AE%E8%BD%AC%E6%8A%98fine-tuning-%E8%AE%A9%E6%A8%A1%E5%9E%8B%E5%8E%9F%E7%94%9F%E7%90%86%E8%A7%A3%E7%BB%93%E6%9E%84%E5%8C%96%E8%BE%93%E5%87%BA" class="hash-link" aria-label="关键转折：Fine-tuning 让模型&quot;原生理解&quot;结构化输出的直接链接" title="关键转折：Fine-tuning 让模型&quot;原生理解&quot;结构化输出的直接链接" translate="no">​</a></h2>
<p>OpenAI 在 2023 年 6 月推出了 Function Calling，核心改动不是 API 层面的——而是<strong>模型层面</strong>的。</p>
<p>他们做了什么？</p>
<p><strong>在 fine-tuning 阶段，用大量结构化的 function call 样本训练模型，让模型学会：</strong></p>
<ol>
<li class=""><strong>精确识别</strong>：用户说的话里，哪些意图需要调用函数</li>
<li class=""><strong>参数提取</strong>：从自然语言中精确提取函数所需的参数，即使参数是隐式的</li>
<li class=""><strong>类型感知</strong>：真正"理解"字段的类型（string / number / boolean / object / array / enum），而不是靠 prompt 猜测</li>
<li class=""><strong>空值处理</strong>：知道哪些参数是必填的，哪些是可选的，可选参数没提到时就留空</li>
<li class=""><strong>多函数选择</strong>：面对多个候选函数时，能选择最合适的那一个，或者决定需要按顺序调用多个</li>
</ol>
<p>用更通俗的话说：<strong>之前的方案是在 prompt 里"教"模型输出 JSON，Function Calling 是让模型在训练阶段就"学会"了这件事。</strong> 从 prompt hack 变成了模型 native capability。</p>
<p>这是一个质变。就像你不需要在 prompt 里说"请用中文回答"，模型自己就知道——因为它在训练时已经内化了这个概念。</p>
<hr>
<h2 class="anchor anchorTargetStickyNavbar_e8hc" id="function-calling-真正解决的核心问题">Function Calling 真正解决的核心问题<a href="https://feifeigd.github.io/blog/2026/07/14/function-calling-background#function-calling-%E7%9C%9F%E6%AD%A3%E8%A7%A3%E5%86%B3%E7%9A%84%E6%A0%B8%E5%BF%83%E9%97%AE%E9%A2%98" class="hash-link" aria-label="Function Calling 真正解决的核心问题的直接链接" title="Function Calling 真正解决的核心问题的直接链接" translate="no">​</a></h2>
<p>把 Function Calling 理解为"让模型输出 JSON"是只见树木不见森林。它本质上是一种<strong>连接 LLM 与外部世界的标准化协议</strong>。</p>
<h3 class="anchor anchorTargetStickyNavbar_e8hc" id="1-将意图桥接到动作">1. 将"意图"桥接到"动作"<a href="https://feifeigd.github.io/blog/2026/07/14/function-calling-background#1-%E5%B0%86%E6%84%8F%E5%9B%BE%E6%A1%A5%E6%8E%A5%E5%88%B0%E5%8A%A8%E4%BD%9C" class="hash-link" aria-label="1. 将&quot;意图&quot;桥接到&quot;动作&quot;的直接链接" title="1. 将&quot;意图&quot;桥接到&quot;动作&quot;的直接链接" translate="no">​</a></h3>
<div class="language-text codeBlockContainer_zaIt theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_SaHH"><pre tabindex="0" class="prism-code language-text codeBlock_KlaO thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_zkpV"><div class="token-line" style="color:#393A34"><span class="token plain">用户："帮我订一张明天去上海的机票"</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">     ↓</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">LLM 理解意图 → 结构化输出：</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">{</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  "function": "search_flights",</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  "parameters": {</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    "destination": "上海",</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    "date": "2026-07-15"</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  }</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">}</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">     ↓</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">代码执行函数 → 返回真实结果</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">     ↓</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">LLM 将结果转为自然语言："明天去上海有以下航班..."</span><br></div></code></pre></div></div>
<p>LLM 只负责"理解意图"和"组织语言"，<strong>真实数据由外部系统提供</strong>。幻觉问题在关键环节被绕开了。</p>
<h3 class="anchor anchorTargetStickyNavbar_e8hc" id="2-分离推理和执行">2. 分离"推理"和"执行"<a href="https://feifeigd.github.io/blog/2026/07/14/function-calling-background#2-%E5%88%86%E7%A6%BB%E6%8E%A8%E7%90%86%E5%92%8C%E6%89%A7%E8%A1%8C" class="hash-link" aria-label="2. 分离&quot;推理&quot;和&quot;执行&quot;的直接链接" title="2. 分离&quot;推理&quot;和&quot;执行&quot;的直接链接" translate="no">​</a></h3>
<p>这是架构层面的关键演进。纯文本 LLM 把推理和执行混在一起——它直接输出"最终答案"，你没法干预中间过程。Function Calling 创造了一个清晰的断点：</p>
<ul>
<li class=""><strong>LLM 负责推理</strong>：理解用户要什么，决定调用哪个函数，提取什么参数</li>
<li class=""><strong>你的代码负责执行</strong>：真正调 API、查数据库、做计算</li>
<li class=""><strong>LLM 负责组织回复</strong>：把执行结果转换成用户友好的语言</li>
</ul>
<p>每一步都是可观测、可拦截、可修正的。这为构建"安全可控"的 AI 系统打下了基础。</p>
<h3 class="anchor anchorTargetStickyNavbar_e8hc" id="3-解决时效性和私有数据的死结">3. 解决"时效性"和"私有数据"的死结<a href="https://feifeigd.github.io/blog/2026/07/14/function-calling-background#3-%E8%A7%A3%E5%86%B3%E6%97%B6%E6%95%88%E6%80%A7%E5%92%8C%E7%A7%81%E6%9C%89%E6%95%B0%E6%8D%AE%E7%9A%84%E6%AD%BB%E7%BB%93" class="hash-link" aria-label="3. 解决&quot;时效性&quot;和&quot;私有数据&quot;的死结的直接链接" title="3. 解决&quot;时效性&quot;和&quot;私有数据&quot;的死结的直接链接" translate="no">​</a></h3>
<p>这是 Function Calling 最实际的商业价值：</p>
<ul>
<li class=""><strong>实时数据</strong>：天气、股价、新闻、汇率——这些通过 Function Calling 接入实时 API，不需要重新训练模型</li>
<li class=""><strong>私有数据</strong>：订单系统、CRM、内部知识库——Function Calling 让 LLM 可以在需要时查询，而不是把所有数据塞进 prompt（既有隐私风险又有长度限制）</li>
<li class=""><strong>写操作</strong>：发邮件、创建工单、下订单——这些 LLM 自己做不到，但通过函数调用完全可以</li>
</ul>
<p><strong>Function Calling 让 LLM 从"一个聪明的数据库"变成了"一个能办事的接口"。</strong></p>
<hr>
<h2 class="anchor anchorTargetStickyNavbar_e8hc" id="生态演进从-openai-到行业标准">生态演进：从 OpenAI 到行业标准<a href="https://feifeigd.github.io/blog/2026/07/14/function-calling-background#%E7%94%9F%E6%80%81%E6%BC%94%E8%BF%9B%E4%BB%8E-openai-%E5%88%B0%E8%A1%8C%E4%B8%9A%E6%A0%87%E5%87%86" class="hash-link" aria-label="生态演进：从 OpenAI 到行业标准的直接链接" title="生态演进：从 OpenAI 到行业标准的直接链接" translate="no">​</a></h2>
<p>Function Calling 不是 OpenAI 一个人的发明，而是整个行业共识的产物。几乎在同一时期：</p>
<ul>
<li class=""><strong>Anthropic</strong> 在 Claude 中推出了 <strong>Tool Use</strong>，理念完全一致</li>
<li class=""><strong>Google</strong> 在 Gemini 中提供了 <strong>Function Calling</strong> 支持</li>
<li class=""><strong>开源模型</strong>通过 fine-tuning 支持 function calling——NexusRaven、Gorilla、Functionary 等专用模型</li>
<li class=""><strong>推理框架</strong>如 vLLM、Ollama 原生支持 tool calling 的 grammar 约束</li>
<li class=""><strong>LangChain / LlamaIndex</strong> 将 function calling 作为 Agent 机制的核心</li>
</ul>
<p>更重要的是，function 的 schema 定义正在收敛到 <strong>JSON Schema</strong> 这个标准上。你定义的函数只要符合 JSON Schema 规范，就可以在 OpenAI、Anthropic、Google 三家 API 之间切换，迁移成本极低。</p>
<p>这标志着 Function Calling 从一个"API 特性"升级为 <strong>LLM 生态的基础设施</strong>。</p>
<hr>
<h2 class="anchor anchorTargetStickyNavbar_e8hc" id="再往前看从-function-calling-到-agent">再往前看：从 Function Calling 到 Agent<a href="https://feifeigd.github.io/blog/2026/07/14/function-calling-background#%E5%86%8D%E5%BE%80%E5%89%8D%E7%9C%8B%E4%BB%8E-function-calling-%E5%88%B0-agent" class="hash-link" aria-label="再往前看：从 Function Calling 到 Agent的直接链接" title="再往前看：从 Function Calling 到 Agent的直接链接" translate="no">​</a></h2>
<p>理解了 Function Calling 诞生的背景，你才能理解为什么 2024-2025 年 Agent 会这么火。</p>
<p>Function Calling 只是第一步——<strong>单次调用、单个函数</strong>。Agent 是这个逻辑的多步延伸：</p>
<ol>
<li class=""><strong>ReAct 模式</strong>：Reasoning + Acting 循环，模型思考→调用函数→观察结果→再思考→再调用</li>
<li class=""><strong>多步规划</strong>：复杂任务拆解为多个子任务，每个子任务可能需要多次函数调用</li>
<li class=""><strong>工具组合</strong>：自动决定使用搜索、计算器、代码执行器、文件读写等不同工具</li>
<li class=""><strong>错误恢复</strong>：函数调用失败后，模型能分析错误信息并调整策略</li>
</ol>
<p>而这些所有能力的基石，恰恰就是 <strong>Function Calling 定义的那个"从意图到结构化动作"的转化能力</strong>。</p>
<hr>
<h2 class="anchor anchorTargetStickyNavbar_e8hc" id="一张图总结演进路径">一张图总结演进路径<a href="https://feifeigd.github.io/blog/2026/07/14/function-calling-background#%E4%B8%80%E5%BC%A0%E5%9B%BE%E6%80%BB%E7%BB%93%E6%BC%94%E8%BF%9B%E8%B7%AF%E5%BE%84" class="hash-link" aria-label="一张图总结演进路径的直接链接" title="一张图总结演进路径的直接链接" translate="no">​</a></h2>
<div class="language-text codeBlockContainer_zaIt theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_SaHH"><pre tabindex="0" class="prism-code language-text codeBlock_KlaO thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_zkpV"><div class="token-line" style="color:#393A34"><span class="token plain">2020-2022: 纯文本 LLM</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  └→ 对话流畅，但无法执行动作，有幻觉</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">2022-2023: Prompt Engineering 硬解</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  └→ 能输出 JSON 了，但脆弱、不稳定、难维护</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">2023.06: OpenAI Function Calling</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  └→ 模型原生理解结构化输出，标准化协议</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">2023-2024: 全行业跟进 + JSON Schema 标准化</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  └→ Anthropic Tool Use / Gemini Function Calling / 开源模型</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">2024-2025: Agent 时代</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  └→ 多步推理 + 工具组合 + 自主规划</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  └→ 基石：Function Calling</span><br></div></code></pre></div></div>
<hr>
<h2 class="anchor anchorTargetStickyNavbar_e8hc" id="最后">最后<a href="https://feifeigd.github.io/blog/2026/07/14/function-calling-background#%E6%9C%80%E5%90%8E" class="hash-link" aria-label="最后的直接链接" title="最后的直接链接" translate="no">​</a></h2>
<p>Function Calling 没那么神秘。它本质上就是解决了 LLM 从"会说话"到"会办事"之间的那一公里路。</p>
<p>如果你今天在构建 AI 应用，function calling 不是一个可选项——它是把 LLM 接入真实业务系统的唯一可靠手段。理解了它为什么诞生，你才能真正用好它。</p>]]></content>
        <category label="ai" term="ai"/>
        <category label="llm" term="llm"/>
        <category label="function-calling" term="function-calling"/>
        <category label="agent" term="agent"/>
        <category label="openai" term="openai"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[DeepSeek开源的价值]]></title>
        <id>https://feifeigd.github.io/blog/2026/07/13/deepseek-open-source-value</id>
        <link href="https://feifeigd.github.io/blog/2026/07/13/deepseek-open-source-value"/>
        <updated>2026-07-13T02:00:00.000Z</updated>
        <summary type="html"><![CDATA[DeepSeek 开源的不仅仅是模型权重，更是 AI 民主化的重要一步]]></summary>
        <content type="html"><![CDATA[<h2 class="anchor anchorTargetStickyNavbar_e8hc" id="引言">引言<a href="https://feifeigd.github.io/blog/2026/07/13/deepseek-open-source-value#%E5%BC%95%E8%A8%80" class="hash-link" aria-label="引言的直接链接" title="引言的直接链接" translate="no">​</a></h2>
<p>2024 年底，DeepSeek 发布了 DeepSeek-V2 和 DeepSeek-R1 系列模型，并选择完全开源。这一举动在全球 AI 社区引发了巨大反响。本文试图从多个维度分析 DeepSeek 开源战略的真正价值。</p>
<!-- -->
<h2 class="anchor anchorTargetStickyNavbar_e8hc" id="打破算力垄断">打破算力垄断<a href="https://feifeigd.github.io/blog/2026/07/13/deepseek-open-source-value#%E6%89%93%E7%A0%B4%E7%AE%97%E5%8A%9B%E5%9E%84%E6%96%AD" class="hash-link" aria-label="打破算力垄断的直接链接" title="打破算力垄断的直接链接" translate="no">​</a></h2>
<p>大模型训练一直被少数科技巨头垄断，核心原因在于算力门槛极高。DeepSeek 通过创新的 MoE（Mixture of Experts）架构和高效的训练方法，大幅降低了训练成本。开源这些技术细节使得更多研究机构和中小公司能够在自己的场景中微调和使用这些模型，而不必从零开始训练。</p>
<h2 class="anchor anchorTargetStickyNavbar_e8hc" id="推动技术透明度">推动技术透明度<a href="https://feifeigd.github.io/blog/2026/07/13/deepseek-open-source-value#%E6%8E%A8%E5%8A%A8%E6%8A%80%E6%9C%AF%E9%80%8F%E6%98%8E%E5%BA%A6" class="hash-link" aria-label="推动技术透明度的直接链接" title="推动技术透明度的直接链接" translate="no">​</a></h2>
<p>闭源模型是一个"黑盒"——用户不知道模型是用什么数据训练的、存在什么偏见、有什么安全漏洞。DeepSeek 的开源策略让学术界和安全研究人员能够深入审查模型，发现潜在问题并提出改进方案。这种透明度对整个 AI 生态的健康发展至关重要。</p>
<h2 class="anchor anchorTargetStickyNavbar_e8hc" id="加速应用落地">加速应用落地<a href="https://feifeigd.github.io/blog/2026/07/13/deepseek-open-source-value#%E5%8A%A0%E9%80%9F%E5%BA%94%E7%94%A8%E8%90%BD%E5%9C%B0" class="hash-link" aria-label="加速应用落地的直接链接" title="加速应用落地的直接链接" translate="no">​</a></h2>
<p>开源降低了使用门槛。开发者可以直接下载模型权重进行本地部署，无需依赖 API 调用，既降低了成本，又解决了数据隐私问题。这对于金融、医疗、政务等对数据安全要求极高的行业尤为重要。</p>
<h2 class="anchor anchorTargetStickyNavbar_e8hc" id="促进全球协作">促进全球协作<a href="https://feifeigd.github.io/blog/2026/07/13/deepseek-open-source-value#%E4%BF%83%E8%BF%9B%E5%85%A8%E7%90%83%E5%8D%8F%E4%BD%9C" class="hash-link" aria-label="促进全球协作的直接链接" title="促进全球协作的直接链接" translate="no">​</a></h2>
<p>DeepSeek 的开源模型已经被全球开发者翻译、量化、优化，适配到各种硬件平台。社区贡献的反哺也帮助 DeepSeek 自身不断改进。这种良性循环是闭源模型无法复制的。</p>
<h2 class="anchor anchorTargetStickyNavbar_e8hc" id="商业与开源的平衡">商业与开源的平衡<a href="https://feifeigd.github.io/blog/2026/07/13/deepseek-open-source-value#%E5%95%86%E4%B8%9A%E4%B8%8E%E5%BC%80%E6%BA%90%E7%9A%84%E5%B9%B3%E8%A1%A1" class="hash-link" aria-label="商业与开源的平衡的直接链接" title="商业与开源的平衡的直接链接" translate="no">​</a></h2>
<p>有人质疑：开源了别人拿去用了，怎么赚钱？DeepSeek 的策略是通过开源模型建立生态和品牌影响力，然后通过企业级服务、定制化解决方案、算力平台等途径变现。这是无数开源公司验证过的成功路径。</p>
<h2 class="anchor anchorTargetStickyNavbar_e8hc" id="对中国的特殊意义">对中国的特殊意义<a href="https://feifeigd.github.io/blog/2026/07/13/deepseek-open-source-value#%E5%AF%B9%E4%B8%AD%E5%9B%BD%E7%9A%84%E7%89%B9%E6%AE%8A%E6%84%8F%E4%B9%89" class="hash-link" aria-label="对中国的特殊意义�的直接链接" title="对中国的特殊意义的直接链接" translate="no">​</a></h2>
<p>在全球 AI 竞争格局中，DeepSeek 的开源实践证明了中国团队在基础模型研发上的创新能力。它打破了"中国 AI 只会跟风"的刻板印象，为国内 AI 社区树立了一个值得学习的榜样。</p>
<h2 class="anchor anchorTargetStickyNavbar_e8hc" id="总结">总结<a href="https://feifeigd.github.io/blog/2026/07/13/deepseek-open-source-value#%E6%80%BB%E7%BB%93" class="hash-link" aria-label="总结的直接链接" title="总结的直接链接" translate="no">​</a></h2>
<p>DeepSeek 开源的不仅仅是代码和权重，更是一种理念：AI 的未来不应该被少数公司掌控，而应该是一个开放、协作、透明的事业。这种价值观本身，就是最大的价值。</p>]]></content>
        <category label="ai" term="ai"/>
        <category label="deepseek" term="deepseek"/>
        <category label="opensource" term="opensource"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[AI Infra 到底是什么]]></title>
        <id>https://feifeigd.github.io/blog/2026/07/07/ai-infra-what-is-it</id>
        <link href="https://feifeigd.github.io/blog/2026/07/07/ai-infra-what-is-it"/>
        <updated>2026-07-07T14:20:00.000Z</updated>
        <summary type="html"><![CDATA[一张图讲清楚 AI Infrastructure 的四个层面]]></summary>
        <content type="html"><![CDATA[<h2 class="anchor anchorTargetStickyNavbar_e8hc" id="一句话">一句话<a href="https://feifeigd.github.io/blog/2026/07/07/ai-infra-what-is-it#%E4%B8%80%E5%8F%A5%E8%AF%9D" class="hash-link" aria-label="一句话的直接链接" title="一句话的直接链接" translate="no">​</a></h2>
<p><strong>AI Infra = AI Infrastructure（AI 基础设施）</strong>，指的是支撑 AI 系统从研发到落地全流程的底层技术栈。</p>
<p>只要你听过"大模型训练太贵了"、"推理速度不够快"、"GPU 利用率上不去"——这些问题的根都在 AI Infra 上。</p>
<hr>
<h2 class="anchor anchorTargetStickyNavbar_e8hc" id="四层架构">四层架构<a href="https://feifeigd.github.io/blog/2026/07/07/ai-infra-what-is-it#%E5%9B%9B%E5%B1%82%E6%9E%B6%E6%9E%84" class="hash-link" aria-label="四层架构的直接链接" title="四层架构的直接链接" translate="no">​</a></h2>
<p>AI Infra 不是单一的东西，从上到下可以拆成四个层面：</p>
<h3 class="anchor anchorTargetStickyNavbar_e8hc" id="1-硬件层--算力的物理基础">1. 硬件层 — 算力的物理基础<a href="https://feifeigd.github.io/blog/2026/07/07/ai-infra-what-is-it#1-%E7%A1%AC%E4%BB%B6%E5%B1%82--%E7%AE%97%E5%8A%9B%E7%9A%84%E7%89%A9%E7%90%86%E5%9F%BA%E7%A1%80" class="hash-link" aria-label="1. 硬件层 — 算力的物理基础的直接链接" title="1. 硬件层 — 算力的物理基础的直接链接" translate="no">​</a></h3>
<p>这层最重、最贵，也是普通人最容易感知的部分：</p>
<ul>
<li class=""><strong>GPU / NPU / TPU</strong> — 算力核心。NVIDIA H100/B200 是当前主流，AMD MI300X 在追赶，Google 有自己的 TPU</li>
<li class=""><strong>高速互联</strong> — 多卡多机通信的命脉：NVLink、InfiniBand、RoCE</li>
<li class=""><strong>存储系统</strong> — 数据集和 checkpoint 的读写瓶颈：Lustre、GPFS、MinIO、JuiceFS</li>
</ul>
<p>训练一个 70B 模型，单机 8 卡 H100 是不够的，需要几十上百台机器组集群，这时候 InfiniBand 的带宽决定了你"能不能卡在通信上"。</p>
<h3 class="anchor anchorTargetStickyNavbar_e8hc" id="2-编排层--算力怎么分怎么调">2. 编排层 — 算力怎么分、怎么调<a href="https://feifeigd.github.io/blog/2026/07/07/ai-infra-what-is-it#2-%E7%BC%96%E6%8E%92%E5%B1%82--%E7%AE%97%E5%8A%9B%E6%80%8E%E4%B9%88%E5%88%86%E6%80%8E%E4%B9%88%E8%B0%83" class="hash-link" aria-label="2. 编排层 — 算力怎么分、怎么调的直接链接" title="2. 编排层 — 算力怎么分、怎么调的直接链接" translate="no">​</a></h3>
<p>硬件买回来只是开始，怎么让几十上百台机器跑起来是另一回事：</p>
<ul>
<li class=""><strong>资源调度</strong> — Slurm（学术圈标配）、Kubernetes + GPU Operator（工业界主流）、Volcano</li>
<li class=""><strong>任务调度</strong> — 谁先跑、跑多久、失败了怎么重试：Apache Airflow、Ray</li>
<li class=""><strong>弹性/混部</strong> — 训练和推理任务混合调度，提高 GPU 利用率</li>
</ul>
<p>搞过 K8s 的人都知道，加上 GPU 之后调度复杂度直接翻倍——要处理 GPU 显存碎片、MIG 分区、节点选择、拓扑亲和性。这层是 AI Infra Engineer 最常打交道的地方。</p>
<h3 class="anchor anchorTargetStickyNavbar_e8hc" id="3-平台软件层--训练和推理的工程化">3. 平台软件层 — 训练和推理的工程化<a href="https://feifeigd.github.io/blog/2026/07/07/ai-infra-what-is-it#3-%E5%B9%B3%E5%8F%B0%E8%BD%AF%E4%BB%B6%E5%B1%82--%E8%AE%AD%E7%BB%83%E5%92%8C%E6%8E%A8%E7%90%86%E7%9A%84%E5%B7%A5%E7%A8%8B%E5%8C%96" class="hash-link" aria-label="3. 平台软件层 — 训练和推理的工程化的直接链接" title="3. 平台软件层 — 训练和推理的工程化的直接链接" translate="no">​</a></h3>
<p>这层解决两个核心问题：<strong>怎么训得快</strong> 和 <strong>怎么跑得稳</strong>。</p>
<p><strong>训练方向：</strong></p>
<ul>
<li class="">PyTorch / JAX — 框架选型</li>
<li class="">DeepSpeed、Megatron-LM、FSDP — 分布式策略：ZeRO、TP、PP、SP</li>
<li class="">混合精度训练（FP16/BF16/FP8）</li>
<li class="">Checkpoint 管理和故障恢复</li>
</ul>
<p><strong>推理方向：</strong></p>
<ul>
<li class="">vLLM、TensorRT-LLM、TGI、SGLang — 推理引擎</li>
<li class="">PagedAttention、Continuous Batching、FlashAttention — 推理加速技术</li>
<li class="">FP8/INT4/INT8 量化</li>
</ul>
<p><strong>模型与数据管理：</strong></p>
<ul>
<li class="">MLflow、Hugging Face Hub、NVIDIA NIM — 模型注册和版本管理</li>
<li class="">Spark、Ray Data、Dask — 数据预处理流水线</li>
</ul>
<h3 class="anchor anchorTargetStickyNavbar_e8hc" id="4-服务业务层--让模型真正可用">4. 服务/业务层 — 让模型真正可用<a href="https://feifeigd.github.io/blog/2026/07/07/ai-infra-what-is-it#4-%E6%9C%8D%E5%8A%A1%E4%B8%9A%E5%8A%A1%E5%B1%82--%E8%AE%A9%E6%A8%A1%E5%9E%8B%E7%9C%9F%E6%AD%A3%E5%8F%AF%E7%94%A8" class="hash-link" aria-label="4. 服务/业务层 — 让模型真正可用的直接链接" title="4. 服务/业务层 — 让模型真正可用的直接链接" translate="no">​</a></h3>
<p>模型训练完了，要部署成线上服务，这层关注的是稳定性、可观测性和自动化：</p>
<ul>
<li class=""><strong>推理网关</strong> — Triton Inference Server、KServe，负责路由、限流、负载均衡</li>
<li class=""><strong>监控</strong> — Prometheus + Grafana 盯 GPU 利用率、吞吐、P99 延迟</li>
<li class=""><strong>MLOps</strong> — 自动评测、A/B 部署、模型回滚（Kubeflow、MLflow、Weights &amp; Biases）</li>
</ul>
<hr>
<h2 class="anchor anchorTargetStickyNavbar_e8hc" id="为什么-ai-infra-这么重要">为什么 AI Infra 这么重要<a href="https://feifeigd.github.io/blog/2026/07/07/ai-infra-what-is-it#%E4%B8%BA%E4%BB%80%E4%B9%88-ai-infra-%E8%BF%99%E4%B9%88%E9%87%8D%E8%A6%81" class="hash-link" aria-label="为什么 AI Infra 这么重要的直接链接" title="为什么 AI Infra 这么重要的直接链接" translate="no">​</a></h2>
<p>三个字：<strong>成本差</strong>。</p>
<p>同样的 70B 模型，AI Infra 做得好的团队，训练成本可能是别人的 1/3，推理延迟可能是别人的 1/5。这不是夸张——DeepSpeed 的 ZeRO-3 能在同样硬件上省 60% 显存，vLLM 的 PagedAttention 能提升 2-4 倍推理吞吐。</p>
<p>另一个角度：<strong>GPU 利用率就是钱</strong>。</p>
<p>H100 一小时几十块的折旧成本，利用率从 30% 提到 80%，相当于 2.6 倍的硬件收益。AI Infra 干的就是这件事。</p>
<hr>
<h2 class="anchor anchorTargetStickyNavbar_e8hc" id="谁在干这个活">谁在干这个活<a href="https://feifeigd.github.io/blog/2026/07/07/ai-infra-what-is-it#%E8%B0%81%E5%9C%A8%E5%B9%B2%E8%BF%99%E4%B8%AA%E6%B4%BB" class="hash-link" aria-label="谁在干这个活的直接链接" title="谁在干这个活的直接链接" translate="no">​</a></h2>
<p>对应的职位通常是 <strong>AI Infra Engineer</strong> / <strong>AI 基础设施工程师</strong>，日常工作包括：</p>
<ul>
<li class="">GPU 集群的搭建、监控和维护</li>
<li class="">分布式训练的性能分析和优化</li>
<li class="">推理服务的延迟优化和稳定性保障</li>
<li class="">MLOps 平台和 CI/CD 流水线的建设</li>
<li class="">存储和网络层面的性能调优</li>
</ul>
<p>如果你在用 Rust / Go / C++ 做这些方向，非常明确就是 Infra 角色。</p>
<hr>
<h2 class="anchor anchorTargetStickyNavbar_e8hc" id="一张图总结">一张图总结<a href="https://feifeigd.github.io/blog/2026/07/07/ai-infra-what-is-it#%E4%B8%80%E5%BC%A0%E5%9B%BE%E6%80%BB%E7%BB%93" class="hash-link" aria-label="一张图总结的直接链接" title="一张图总结的直接链接" translate="no">​</a></h2>
<div class="language-text codeBlockContainer_zaIt theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_SaHH"><pre tabindex="0" class="prism-code language-text codeBlock_KlaO thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_zkpV"><div class="token-line" style="color:#393A34"><span class="token plain">┌─────────────────────────────────┐</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">│  服务/业务层                     │</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">│  推理网关 · 监控 · MLOps · CI/CD│</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">├─────────────────────────────────┤</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">│  平台软件层                     │</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">│  PyTorch · DeepSpeed · vLLM    │</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">│  TensorRT · Triton · MLflow    │</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">├─────────────────────────────────┤</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">│  编排层                         │</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">│  K8s + GPU Op · Slurm · Ray   │</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">│  调度 · 弹性 · 混部             │</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">├─────────────────────────────────┤</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">│  硬件层                         │</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">│  GPU · InfiniBand · 分布式存储  │</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">└─────────────────────────────────┘</span><br></div></code></pre></div></div>
<p><strong>AI Infra = 让 AI 模型能"算得快、训得起、部署稳"的底层工程体系。</strong></p>
<p>不是每个人都需要深入每一层，但理解这个分层结构，能帮你快速定位问题在哪层，以及你的工作落在哪个位置。</p>]]></content>
        <category label="ai" term="ai"/>
        <category label="infra" term="infra"/>
        <category label="mlops" term="mlops"/>
        <category label="engineering" term="engineering"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[用 LangChain + Qdrant + DeepSeek 搭建简历 RAG 系统]]></title>
        <id>https://feifeigd.github.io/blog/2026/07/03/rag-with-langchain-qdrant</id>
        <link href="https://feifeigd.github.io/blog/2026/07/03/rag-with-langchain-qdrant"/>
        <updated>2026-07-03T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[背景]]></summary>
        <content type="html"><![CDATA[<h2 class="anchor anchorTargetStickyNavbar_e8hc" id="背景">背景<a href="https://feifeigd.github.io/blog/2026/07/03/rag-with-langchain-qdrant#%E8%83%8C%E6%99%AF" class="hash-link" aria-label="背景的直接链接" title="背景的直接链接" translate="no">​</a></h2>
<p>需要从一份 Word 简历中提取结构化信息（姓名、专业技能、工作年限），用 RAG 方案比直接写正则解析灵活得多。</p>
<h2 class="anchor anchorTargetStickyNavbar_e8hc" id="技术栈">技术栈<a href="https://feifeigd.github.io/blog/2026/07/03/rag-with-langchain-qdrant#%E6%8A%80%E6%9C%AF%E6%A0%88" class="hash-link" aria-label="技术栈的直接链接" title="技术栈的直接链接" translate="no">​</a></h2>
<table><thead><tr><th>组件</th><th>选型</th></tr></thead><tbody><tr><td>文档加载</td><td>UnstructuredLoader</td></tr><tr><td>向量库</td><td>Qdrant (Docker)</td></tr><tr><td>嵌入模型</td><td>通义千问 text-embedding-v1</td></tr><tr><td>LLM</td><td>DeepSeek v4 Flash</td></tr><tr><td>编排框架</td><td>LangChain</td></tr><tr><td>运行环境</td><td>Python 3.13 + uv</td></tr></tbody></table>
<h2 class="anchor anchorTargetStickyNavbar_e8hc" id="项目结构">项目结构<a href="https://feifeigd.github.io/blog/2026/07/03/rag-with-langchain-qdrant#%E9%A1%B9%E7%9B%AE%E7%BB%93%E6%9E%84" class="hash-link" aria-label="项目结构的直接链接" title="项目结构的直接链接" translate="no">​</a></h2>
<div class="language-text codeBlockContainer_zaIt theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_SaHH"><pre tabindex="0" class="prism-code language-text codeBlock_KlaO thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_zkpV"><div class="token-line" style="color:#393A34"><span class="token plain">rag/</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">├── main.py        # 主流程</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">├── llm.py         # LLM + 向量库封装</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">├── prompt.py      # 本地 prompt 模板</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">├── sensenova.py   # 备用 LLM 客户端</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">├── pyproject.toml # 依赖管理</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">└── uv.lock</span><br></div></code></pre></div></div>
<h2 class="anchor anchorTargetStickyNavbar_e8hc" id="核心流程">核心流程<a href="https://feifeigd.github.io/blog/2026/07/03/rag-with-langchain-qdrant#%E6%A0%B8%E5%BF%83%E6%B5%81%E7%A8%8B" class="hash-link" aria-label="核心流程的直接链接" title="核心流程的直接链接" translate="no">​</a></h2>
<h3 class="anchor anchorTargetStickyNavbar_e8hc" id="1-文档加载与切片">1. 文档加载与切片<a href="https://feifeigd.github.io/blog/2026/07/03/rag-with-langchain-qdrant#1-%E6%96%87%E6%A1%A3%E5%8A%A0%E8%BD%BD%E4%B8%8E%E5%88%87%E7%89%87" class="hash-link" aria-label="1. 文档加载与切片的直接链接" title="1. 文档加载与切片的直接链接" translate="no">​</a></h3>
<div class="language-python codeBlockContainer_zaIt theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_SaHH"><pre tabindex="0" class="prism-code language-python codeBlock_KlaO thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_zkpV"><div class="token-line" style="color:#393A34"><span class="token plain">word </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> UnstructuredLoader</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"简历.docx"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">docs </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> word</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">load</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">splitter </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> RecursiveCharacterTextSplitter</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">chunk_size</span><span class="token operator" style="color:#393A34">=</span><span class="token number" style="color:#36acaa">50</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> chunk_overlap</span><span class="token operator" style="color:#393A34">=</span><span class="token number" style="color:#36acaa">20</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">chunks </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> splitter</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">split_documents</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">docs</span><span class="token punctuation" style="color:#393A34">)</span><br></div></code></pre></div></div>
<p><code>UnstructuredLoader</code> 支持 .docx/.pdf/.pptx 等格式，自动提取文本。分片用 50 字符 + 20 字符重叠，对简历这种短文档粒度合适。</p>
<h3 class="anchor anchorTargetStickyNavbar_e8hc" id="2-向量化存储">2. 向量化存储<a href="https://feifeigd.github.io/blog/2026/07/03/rag-with-langchain-qdrant#2-%E5%90%91%E9%87%8F%E5%8C%96%E5%AD%98%E5%82%A8" class="hash-link" aria-label="2. 向量化存储的直接链接" title="2. 向量化存储的直接链接" translate="no">​</a></h3>
<div class="language-python codeBlockContainer_zaIt theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_SaHH"><pre tabindex="0" class="prism-code language-python codeBlock_KlaO thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_zkpV"><div class="token-line" style="color:#393A34"><span class="token plain">embeddings </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> DashScopeEmbeddings</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    dashscope_api_key</span><span class="token operator" style="color:#393A34">=</span><span class="token plain">os</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">environ</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">get</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"dashscope"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    model</span><span class="token operator" style="color:#393A34">=</span><span class="token string" style="color:#e3116c">"text-embedding-v1"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">vectordb </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> QdrantVectorStore</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">from_documents</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    chunks</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> embeddings</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    collection_name</span><span class="token operator" style="color:#393A34">=</span><span class="token string" style="color:#e3116c">"resume"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    url</span><span class="token operator" style="color:#393A34">=</span><span class="token string" style="color:#e3116c">"http://localhost:6333"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">)</span><br></div></code></pre></div></div>
<p>嵌入用通义千问的 <code>text-embedding-v1</code>，向量库用 Qdrant（Docker 运行），collection 名 <code>resume</code>。</p>
<h3 class="anchor anchorTargetStickyNavbar_e8hc" id="3-lcel-链">3. LCEL 链<a href="https://feifeigd.github.io/blog/2026/07/03/rag-with-langchain-qdrant#3-lcel-%E9%93%BE" class="hash-link" aria-label="3. LCEL 链的直接链接" title="3. LCEL 链的直接链接" translate="no">​</a></h3>
<div class="language-python codeBlockContainer_zaIt theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_SaHH"><pre tabindex="0" class="prism-code language-python codeBlock_KlaO thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_zkpV"><div class="token-line" style="color:#393A34"><span class="token plain">chain </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token string" style="color:#e3116c">"context"</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> vec_store</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">as_retriever</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">|</span><span class="token plain"> format_docs</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token string" style="color:#e3116c">"question"</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> RunnablePassthrough</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">|</span><span class="token plain"> prompt </span><span class="token operator" style="color:#393A34">|</span><span class="token plain"> llm </span><span class="token operator" style="color:#393A34">|</span><span class="token plain"> StrOutputParser</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><br></div></code></pre></div></div>
<p>用 LangChain Expression Language 串联：检索 → 格式化上下文 → 填充 prompt → LLM 推理 → 解析输出。</p>
<h3 class="anchor anchorTargetStickyNavbar_e8hc" id="4-查询">4. 查询<a href="https://feifeigd.github.io/blog/2026/07/03/rag-with-langchain-qdrant#4-%E6%9F%A5%E8%AF%A2" class="hash-link" aria-label="4. 查询的直接链接" title="4. 查询的直接链接" translate="no">​</a></h3>
<div class="language-python codeBlockContainer_zaIt theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_SaHH"><pre tabindex="0" class="prism-code language-python codeBlock_KlaO thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_zkpV"><div class="token-line" style="color:#393A34"><span class="token plain">chain</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">invoke</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"请输入姓名. 格式如下\n姓名: ?"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">chain</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">invoke</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"总结专业技能情况. 格式如下\n专业技能: ?"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">chain</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">invoke</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"根据工作年份总结工作经验. 格式如下\n工作经验: ?年"</span><span class="token punctuation" style="color:#393A34">)</span><br></div></code></pre></div></div>
<p>三次调用分别提取姓名、技能、工作年限，prompt 里约束了输出格式。</p>
<h2 class="anchor anchorTargetStickyNavbar_e8hc" id="实际输出">实际输出<a href="https://feifeigd.github.io/blog/2026/07/03/rag-with-langchain-qdrant#%E5%AE%9E%E9%99%85%E8%BE%93%E5%87%BA" class="hash-link" aria-label="实际输出的直接链接" title="实际输出的直接链接" translate="no">​</a></h2>
<div class="language-text codeBlockContainer_zaIt theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_SaHH"><pre tabindex="0" class="prism-code language-text codeBlock_KlaO thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_zkpV"><div class="token-line" style="color:#393A34"><span class="token plain">姓名: XX</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">专业技能: Go, Python, C/C++, C#, Java, Lua</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">工作经验: 约16年</span><br></div></code></pre></div></div>
<h2 class="anchor anchorTargetStickyNavbar_e8hc" id="踩坑记录">踩坑记录<a href="https://feifeigd.github.io/blog/2026/07/03/rag-with-langchain-qdrant#%E8%B8%A9%E5%9D%91%E8%AE%B0%E5%BD%95" class="hash-link" aria-label="踩坑记录的直接链接" title="踩坑记录的直接链接" translate="no">​</a></h2>
<h3 class="anchor anchorTargetStickyNavbar_e8hc" id="hubpull-安全限制">hub.pull 安全限制<a href="https://feifeigd.github.io/blog/2026/07/03/rag-with-langchain-qdrant#hubpull-%E5%AE%89%E5%85%A8%E9%99%90%E5%88%B6" class="hash-link" aria-label="hub.pull 安全限制的直接链接" title="hub.pull 安全限制的直接链接" translate="no">​</a></h3>
<p><code>hub.pull("rlm/rag-prompt")</code> 默认不允许拉取公开 prompt，需要：</p>
<div class="language-python codeBlockContainer_zaIt theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_SaHH"><pre tabindex="0" class="prism-code language-python codeBlock_KlaO thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_zkpV"><div class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">from</span><span class="token plain"> langsmith </span><span class="token keyword" style="color:#00009f">import</span><span class="token plain"> Client </span><span class="token keyword" style="color:#00009f">as</span><span class="token plain"> LangSmithClient</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">client </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> LangSmithClient</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">prompt </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> client</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">pull_prompt</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"rlm/rag-prompt"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> dangerously_pull_public_prompt</span><span class="token operator" style="color:#393A34">=</span><span class="token boolean" style="color:#36acaa">True</span><span class="token punctuation" style="color:#393A34">)</span><br></div></code></pre></div></div>
<h3 class="anchor anchorTargetStickyNavbar_e8hc" id="缺失依赖">缺失依赖<a href="https://feifeigd.github.io/blog/2026/07/03/rag-with-langchain-qdrant#%E7%BC%BA%E5%A4%B1%E4%BE%9D%E8%B5%96" class="hash-link" aria-label="缺失依赖的直接链接" title="缺失依赖的直接链接" translate="no">​</a></h3>
<p><code>langchain-text-splitters</code>、<code>langchain-community</code>、<code>dashscope</code> 需要在 <code>pyproject.toml</code> 中显式声明。</p>
<h3 class="anchor anchorTargetStickyNavbar_e8hc" id="qdrant-连接">Qdrant 连接<a href="https://feifeigd.github.io/blog/2026/07/03/rag-with-langchain-qdrant#qdrant-%E8%BF%9E%E6%8E%A5" class="hash-link" aria-label="Qdrant 连接的直接链接" title="Qdrant 连接的直接链接" translate="no">​</a></h3>
<p>Qdrant 通过 Docker 启动，确保 <code>localhost:6333</code> 可访问。</p>
<h2 class="anchor anchorTargetStickyNavbar_e8hc" id="完整代码">完整代码<a href="https://feifeigd.github.io/blog/2026/07/03/rag-with-langchain-qdrant#%E5%AE%8C%E6%95%B4%E4%BB%A3%E7%A0%81" class="hash-link" aria-label="完整代码的直接链接" title="完整代码的直接链接" translate="no">​</a></h2>
<h3 class="anchor anchorTargetStickyNavbar_e8hc" id="mainpy">main.py<a href="https://feifeigd.github.io/blog/2026/07/03/rag-with-langchain-qdrant#mainpy" class="hash-link" aria-label="main.py的直接链接" title="main.py的直接链接" translate="no">​</a></h3>
<div class="language-python codeBlockContainer_zaIt theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_SaHH"><pre tabindex="0" class="prism-code language-python codeBlock_KlaO thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_zkpV"><div class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">import</span><span class="token plain"> os</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">from</span><span class="token plain"> langchain_openai </span><span class="token keyword" style="color:#00009f">import</span><span class="token plain"> OpenAIEmbeddings</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">from</span><span class="token plain"> langchain_text_splitters </span><span class="token keyword" style="color:#00009f">import</span><span class="token plain"> RecursiveCharacterTextSplitter</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">from</span><span class="token plain"> langchain_unstructured </span><span class="token keyword" style="color:#00009f">import</span><span class="token plain"> UnstructuredLoader</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">from</span><span class="token plain"> langchain_core</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">output_parsers </span><span class="token keyword" style="color:#00009f">import</span><span class="token plain"> StrOutputParser</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">from</span><span class="token plain"> langchain_core</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">runnables </span><span class="token keyword" style="color:#00009f">import</span><span class="token plain"> RunnablePassthrough</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">from</span><span class="token plain"> langsmith </span><span class="token keyword" style="color:#00009f">import</span><span class="token plain"> Client </span><span class="token keyword" style="color:#00009f">as</span><span class="token plain"> LangSmithClient</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">from</span><span class="token plain"> llm </span><span class="token keyword" style="color:#00009f">import</span><span class="token plain"> DeepSeek</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> QdrantVecStoreFromDocs</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">def</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">clearstr</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">s</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token builtin">str</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">-</span><span class="token operator" style="color:#393A34">&gt;</span><span class="token plain"> </span><span class="token builtin">str</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    filter_chars </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">[</span><span class="token string" style="color:#e3116c">'\n'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'\r'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'\t'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'\u3000'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">' '</span><span class="token punctuation" style="color:#393A34">]</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">for</span><span class="token plain"> char </span><span class="token keyword" style="color:#00009f">in</span><span class="token plain"> filter_chars</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        s </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> s</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">replace</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">char</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">''</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> s</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">def</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">format_docs</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">docs</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">-</span><span class="token operator" style="color:#393A34">&gt;</span><span class="token plain"> </span><span class="token builtin">str</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"\n\n"</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">join</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">clearstr</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">doc</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">page_content</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">for</span><span class="token plain"> doc </span><span class="token keyword" style="color:#00009f">in</span><span class="token plain"> docs</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">def</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">load_doc</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    word </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> UnstructuredLoader</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"C:\\Users\\Administrator\\Downloads\\xxx.docx"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    docs </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> word</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">load</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    splitter </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> RecursiveCharacterTextSplitter</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">chunk_size</span><span class="token operator" style="color:#393A34">=</span><span class="token number" style="color:#36acaa">50</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> chunk_overlap</span><span class="token operator" style="color:#393A34">=</span><span class="token number" style="color:#36acaa">20</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    chunks </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> splitter</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">split_documents</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">docs</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    vec_store </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> QdrantVecStoreFromDocs</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">chunks</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> collection_name</span><span class="token operator" style="color:#393A34">=</span><span class="token string" style="color:#e3116c">"resume"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    llm </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> DeepSeek</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    client </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> LangSmithClient</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    prompt </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> client</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">pull_prompt</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"rlm/rag-prompt"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> dangerously_pull_public_prompt</span><span class="token operator" style="color:#393A34">=</span><span class="token boolean" style="color:#36acaa">True</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    chain </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token string" style="color:#e3116c">"context"</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> vec_store</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">as_retriever</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">|</span><span class="token plain"> format_docs</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token string" style="color:#e3116c">"question"</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> RunnablePassthrough</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">|</span><span class="token plain"> prompt </span><span class="token operator" style="color:#393A34">|</span><span class="token plain"> llm </span><span class="token operator" style="color:#393A34">|</span><span class="token plain"> StrOutputParser</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    ret </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> chain</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">invoke</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"请输入姓名. 格式如下\n姓名: ?"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">print</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">ret</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    ret </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> chain</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">invoke</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"总结专业技能情况,内容可能包含golang、AI Agent、python、rag等.格式如下\n专业技能: ?"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">print</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">ret</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    ret </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> chain</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">invoke</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"根据各大公司工作过的年份总结工作经验有多少年.格式如下\n工作经验: ?年"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">print</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">ret</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">def</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">main</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">print</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"Hello from rag!"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    load_doc</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">if</span><span class="token plain"> __name__ </span><span class="token operator" style="color:#393A34">==</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"__main__"</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    main</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><br></div></code></pre></div></div>
<h3 class="anchor anchorTargetStickyNavbar_e8hc" id="llmpy">llm.py<a href="https://feifeigd.github.io/blog/2026/07/03/rag-with-langchain-qdrant#llmpy" class="hash-link" aria-label="llm.py的直接链接" title="llm.py的直接链接" translate="no">​</a></h3>
<div class="language-python codeBlockContainer_zaIt theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_SaHH"><pre tabindex="0" class="prism-code language-python codeBlock_KlaO thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_zkpV"><div class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">import</span><span class="token plain"> os</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">from</span><span class="token plain"> typing </span><span class="token keyword" style="color:#00009f">import</span><span class="token plain"> List</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> Optional</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">from</span><span class="token plain"> langchain_community</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">embeddings </span><span class="token keyword" style="color:#00009f">import</span><span class="token plain"> DashScopeEmbeddings</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">from</span><span class="token plain"> langchain_core</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">documents </span><span class="token keyword" style="color:#00009f">import</span><span class="token plain"> Document</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">from</span><span class="token plain"> langchain_openai </span><span class="token keyword" style="color:#00009f">import</span><span class="token plain"> ChatOpenAI</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">from</span><span class="token plain"> langchain_qdrant </span><span class="token keyword" style="color:#00009f">import</span><span class="token plain"> QdrantVectorStore</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">def</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">DeepSeek</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> ChatOpenAI</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        model</span><span class="token operator" style="color:#393A34">=</span><span class="token string" style="color:#e3116c">"deepseek-v4-flash"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        api_key</span><span class="token operator" style="color:#393A34">=</span><span class="token plain">os</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">environ</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">get</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"DEEPSEEK_API_KEY"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        base_url</span><span class="token operator" style="color:#393A34">=</span><span class="token string" style="color:#e3116c">"https://api.deepseek.com/v1"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">def</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">get_embeddings</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> DashScopeEmbeddings</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        dashscope_api_key</span><span class="token operator" style="color:#393A34">=</span><span class="token plain">os</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">environ</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">get</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"dashscope"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        model</span><span class="token operator" style="color:#393A34">=</span><span class="token string" style="color:#e3116c">"text-embedding-v1"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">def</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">QdrantVecStoreFromDocs</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">docs</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> List</span><span class="token punctuation" style="color:#393A34">[</span><span class="token plain">Document</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> collection_name</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token builtin">str</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">                           qdrant_url</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> Optional</span><span class="token punctuation" style="color:#393A34">[</span><span class="token builtin">str</span><span class="token punctuation" style="color:#393A34">]</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token boolean" style="color:#36acaa">None</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">                           qdrant_api_key</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> Optional</span><span class="token punctuation" style="color:#393A34">[</span><span class="token builtin">str</span><span class="token punctuation" style="color:#393A34">]</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token boolean" style="color:#36acaa">None</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">if</span><span class="token plain"> qdrant_url </span><span class="token keyword" style="color:#00009f">is</span><span class="token plain"> </span><span class="token boolean" style="color:#36acaa">None</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        qdrant_url </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"http://localhost:6333"</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    embeddings </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> get_embeddings</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    vectordb </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> QdrantVectorStore</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">from_documents</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        docs</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> embeddings</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> collection_name</span><span class="token operator" style="color:#393A34">=</span><span class="token plain">collection_name</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        url</span><span class="token operator" style="color:#393A34">=</span><span class="token plain">qdrant_url</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> api_key</span><span class="token operator" style="color:#393A34">=</span><span class="token plain">qdrant_api_key</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> vectordb</span><br></div></code></pre></div></div>
<h3 class="anchor anchorTargetStickyNavbar_e8hc" id="promptpy">prompt.py<a href="https://feifeigd.github.io/blog/2026/07/03/rag-with-langchain-qdrant#promptpy" class="hash-link" aria-label="prompt.py的直接链接" title="prompt.py的直接链接" translate="no">​</a></h3>
<div class="language-python codeBlockContainer_zaIt theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_SaHH"><pre tabindex="0" class="prism-code language-python codeBlock_KlaO thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_zkpV"><div class="token-line" style="color:#393A34"><span class="token plain">RAGPrompt </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token triple-quoted-string string" style="color:#e3116c">"""</span><br></div><div class="token-line" style="color:#393A34"><span class="token triple-quoted-string string" style="color:#e3116c">You are an assistant for question-answering tasks.</span><br></div><div class="token-line" style="color:#393A34"><span class="token triple-quoted-string string" style="color:#e3116c">Use the following pieces of retrieved context to answer the question.</span><br></div><div class="token-line" style="color:#393A34"><span class="token triple-quoted-string string" style="color:#e3116c">If you don't know the answer, just say that you don't know,</span><br></div><div class="token-line" style="color:#393A34"><span class="token triple-quoted-string string" style="color:#e3116c">don't try to make up an answer.</span><br></div><div class="token-line" style="color:#393A34"><span class="token triple-quoted-string string" style="color:#e3116c">Use three sentences maximum and keep the answer concise.</span><br></div><div class="token-line" style="color:#393A34"><span class="token triple-quoted-string string" style="color:#e3116c">Question: {question}</span><br></div><div class="token-line" style="color:#393A34"><span class="token triple-quoted-string string" style="color:#e3116c">Context: {context}</span><br></div><div class="token-line" style="color:#393A34"><span class="token triple-quoted-string string" style="color:#e3116c">Answer:</span><br></div><div class="token-line" style="color:#393A34"><span class="token triple-quoted-string string" style="color:#e3116c">"""</span><br></div></code></pre></div></div>
<h3 class="anchor anchorTargetStickyNavbar_e8hc" id="pyprojecttoml">pyproject.toml<a href="https://feifeigd.github.io/blog/2026/07/03/rag-with-langchain-qdrant#pyprojecttoml" class="hash-link" aria-label="pyproject.toml的直接链接" title="pyproject.toml的直接链接" translate="no">​</a></h3>
<div class="language-toml codeBlockContainer_zaIt theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_SaHH"><pre tabindex="0" class="prism-code language-toml codeBlock_KlaO thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_zkpV"><div class="token-line" style="color:#393A34"><span class="token plain">[project]</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">name = "rag"</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">version = "0.1.0"</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">description = "Add your description here"</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">readme = "README.md"</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">requires-python = "&gt;=3.13"</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">dependencies = [</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    "langchain&gt;=1.3.11",</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    "langchain-unstructured&gt;=0.1.0",</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    "langchain-openai&gt;=1.3.3",</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    "langchain-text-splitters&gt;=0.3.0",</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    "langchain-community&gt;=0.3.0",</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    "nltk&gt;=3.9.4",</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    "python-docx&gt;=1.2.0",</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    "unstructured&gt;=0.23.1",</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    "langchain-qdrant&gt;=1.1.0",</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    "dashscope&gt;=1.0.0",</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">]</span><br></div></code></pre></div></div>
<h2 class="anchor anchorTargetStickyNavbar_e8hc" id="总结">总结<a href="https://feifeigd.github.io/blog/2026/07/03/rag-with-langchain-qdrant#%E6%80%BB%E7%BB%93" class="hash-link" aria-label="总结的直接链接" title="总结的直接链接" translate="no">​</a></h2>
<p>LangChain 的 LCEL 写 RAG pipeline 非常简洁，配合 Docker 运行的 Qdrant 和 DeepSeek 的 API，从文档到结构化输出只要几十行代码。这套方案不仅适用于简历解析，合同审核、知识库 QA 等场景也能直接复用。</p>]]></content>
    </entry>
    <entry>
        <title type="html"><![CDATA[一个快速查看端口占用进程的工具 sonar]]></title>
        <id>https://feifeigd.github.io/blog/2026/07/02/find-process-by-port</id>
        <link href="https://feifeigd.github.io/blog/2026/07/02/find-process-by-port"/>
        <updated>2026-07-02T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[安装]]></summary>
        <content type="html"><![CDATA[<h2 class="anchor anchorTargetStickyNavbar_e8hc" id="安装">安装<a href="https://feifeigd.github.io/blog/2026/07/02/find-process-by-port#%E5%AE%89%E8%A3%85" class="hash-link" aria-label="安装的直接链接" title="安装的直接链接" translate="no">​</a></h2>
<div class="language-shell codeBlockContainer_zaIt theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_SaHH"><pre tabindex="0" class="prism-code language-shell codeBlock_KlaO thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_zkpV"><div class="token-line" style="color:#393A34"><span class="token plain">curl -sfL https://raw.githubusercontent.com/raskrebs/sonar/main/scripts/install.sh |bash</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">. ~/.bashrc</span><br></div></code></pre></div></div>
<h2 class="anchor anchorTargetStickyNavbar_e8hc" id="一条命令看清全貌">一条命令看清全貌<a href="https://feifeigd.github.io/blog/2026/07/02/find-process-by-port#%E4%B8%80%E6%9D%A1%E5%91%BD%E4%BB%A4%E7%9C%8B%E6%B8%85%E5%85%A8%E8%B2%8C" class="hash-link" aria-label="一条命令看清全貌的直接链接" title="一条命令看清全貌的直接链接" translate="no">​</a></h2>
<div class="language-shell codeBlockContainer_zaIt theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_SaHH"><pre tabindex="0" class="prism-code language-shell codeBlock_KlaO thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_zkpV"><div class="token-line" style="color:#393A34"><span class="token plain">sonar list</span><br></div></code></pre></div></div>
<h2 class="anchor anchorTargetStickyNavbar_e8hc" id="带资源统计">带资源统计<a href="https://feifeigd.github.io/blog/2026/07/02/find-process-by-port#%E5%B8%A6%E8%B5%84%E6%BA%90%E7%BB%9F%E8%AE%A1" class="hash-link" aria-label="带资源统计的直接链接" title="带资源统计的直接链接" translate="no">​</a></h2>
<div class="language-shell codeBlockContainer_zaIt theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_SaHH"><pre tabindex="0" class="prism-code language-shell codeBlock_KlaO thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_zkpV"><div class="token-line" style="color:#393A34"><span class="token plain">sonar list --stats</span><br></div></code></pre></div></div>
<h2 class="anchor anchorTargetStickyNavbar_e8hc" id="自定义列">自定义列<a href="https://feifeigd.github.io/blog/2026/07/02/find-process-by-port#%E8%87%AA%E5%AE%9A%E4%B9%89%E5%88%97" class="hash-link" aria-label="自定义列的直接链接" title="自定义列的直接链接" translate="no">​</a></h2>
<div class="language-shell codeBlockContainer_zaIt theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_SaHH"><pre tabindex="0" class="prism-code language-shell codeBlock_KlaO thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_zkpV"><div class="token-line" style="color:#393A34"><span class="token plain">sonar list -c port,process,cpu,mem,uptime,state</span><br></div></code></pre></div></div>
<h2 class="anchor anchorTargetStickyNavbar_e8hc" id="端口详情">端口详情<a href="https://feifeigd.github.io/blog/2026/07/02/find-process-by-port#%E7%AB%AF%E5%8F%A3%E8%AF%A6%E6%83%85" class="hash-link" aria-label="端口详情的直接链接" title="端口详情的直接链接" translate="no">​</a></h2>
<div class="language-shell codeBlockContainer_zaIt theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_SaHH"><pre tabindex="0" class="prism-code language-shell codeBlock_KlaO thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_zkpV"><div class="token-line" style="color:#393A34"><span class="token plain">sonar info 80</span><br></div></code></pre></div></div>
<h2 class="anchor anchorTargetStickyNavbar_e8hc" id="按端口杀进程">按端口杀进程<a href="https://feifeigd.github.io/blog/2026/07/02/find-process-by-port#%E6%8C%89%E7%AB%AF%E5%8F%A3%E6%9D%80%E8%BF%9B%E7%A8%8B" class="hash-link" aria-label="按端口杀进程的直接链接" title="按端口杀进程的直接链接" translate="no">​</a></h2>
<div class="language-shell codeBlockContainer_zaIt theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_SaHH"><pre tabindex="0" class="prism-code language-shell codeBlock_KlaO thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_zkpV"><div class="token-line" style="color:#393A34"><span class="token plain">sonar kill 80 # SIGTERM</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">sonar kill 80 -f # SIGKILL</span><br></div></code></pre></div></div>
<h2 class="anchor anchorTargetStickyNavbar_e8hc" id="查看日志">查看日志<a href="https://feifeigd.github.io/blog/2026/07/02/find-process-by-port#%E6%9F%A5%E7%9C%8B%E6%97%A5%E5%BF%97" class="hash-link" aria-label="查看日志的直接链接" title="查看日志的直接链接" translate="no">​</a></h2>
<div class="language-shell codeBlockContainer_zaIt theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_SaHH"><pre tabindex="0" class="prism-code language-shell codeBlock_KlaO thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_zkpV"><div class="token-line" style="color:#393A34"><span class="token plain">sonar logs 80</span><br></div></code></pre></div></div>
<h2 class="anchor anchorTargetStickyNavbar_e8hc" id="连接到服务">连接到服务<a href="https://feifeigd.github.io/blog/2026/07/02/find-process-by-port#%E8%BF%9E%E6%8E%A5%E5%88%B0%E6%9C%8D%E5%8A%A1" class="hash-link" aria-label="连接到服务的直接链接" title="连接到服务的直接链接" translate="no">​</a></h2>
<div class="language-shell codeBlockContainer_zaIt theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_SaHH"><pre tabindex="0" class="prism-code language-shell codeBlock_KlaO thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_zkpV"><div class="token-line" style="color:#393A34"><span class="token plain">sonar attach 80</span><br></div></code></pre></div></div>
<h2 class="anchor anchorTargetStickyNavbar_e8hc" id="实时监控">实时监控<a href="https://feifeigd.github.io/blog/2026/07/02/find-process-by-port#%E5%AE%9E%E6%97%B6%E7%9B%91%E6%8E%A7" class="hash-link" aria-label="实时监控的直接链接" title="实时监控的直接链接" translate="no">​</a></h2>
<div class="language-shell codeBlockContainer_zaIt theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_SaHH"><pre tabindex="0" class="prism-code language-shell codeBlock_KlaO thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_zkpV"><div class="token-line" style="color:#393A34"><span class="token plain"># 每2秒刷新，显示变化</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">sonar watch </span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"># 实时资源监控</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">sonar watch --stats</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"># 更快的刷新间隔</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">sonar watch -i 500ms</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"># 端口上下线时发送桌面通知</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">sonar watch --notify </span><br></div></code></pre></div></div>
<h2 class="anchor anchorTargetStickyNavbar_e8hc" id="依赖关系图">依赖关系图<a href="https://feifeigd.github.io/blog/2026/07/02/find-process-by-port#%E4%BE%9D%E8%B5%96%EF%BF%BD%EF%BF%BD%E5%85%B3%E7%B3%BB%E5%9B%BE" class="hash-link" aria-label="依赖关系图的直接链接" title="依赖关系图的直接链接" translate="no">​</a></h2>
<div class="language-shell codeBlockContainer_zaIt theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_SaHH"><pre tabindex="0" class="prism-code language-shell codeBlock_KlaO thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_zkpV"><div class="token-line" style="color:#393A34"><span class="token plain">sonar graph</span><br></div></code></pre></div></div>
<h2 class="anchor anchorTargetStickyNavbar_e8hc" id="等待端口就绪">等待端口就绪<a href="https://feifeigd.github.io/blog/2026/07/02/find-process-by-port#%E7%AD%89%E5%BE%85%E7%AB%AF%E5%8F%A3%E5%B0%B1%E7%BB%AA" class="hash-link" aria-label="等待端口就绪的直接链接" title="等待端口就绪的直接链接" translate="no">​</a></h2>
<div class="language-shell codeBlockContainer_zaIt theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_SaHH"><pre tabindex="0" class="prism-code language-shell codeBlock_KlaO thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_zkpV"><div class="token-line" style="color:#393A34"><span class="token plain"># 等待TCP连接可用</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">sonar wait 80</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"># 多个端口</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">sonar wait 80 6379</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"># 等待HTTP 200</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">sonar wait 80 --http</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"># 检查特定断点</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">sonar wait 80 --http=/health</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"># 超时</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">sonar wait 80 --timeout 30s</span><br></div></code></pre></div></div>
<h2 class="anchor anchorTargetStickyNavbar_e8hc" id="端口映射">端口映射<a href="https://feifeigd.github.io/blog/2026/07/02/find-process-by-port#%E7%AB%AF%E5%8F%A3%E6%98%A0%E5%B0%84" class="hash-link" aria-label="端口映射的直接链接" title="端口映射的直接链接" translate="no">​</a></h2>
<div class="language-shell codeBlockContainer_zaIt theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_SaHH"><pre tabindex="0" class="prism-code language-shell codeBlock_KlaO thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_zkpV"><div class="token-line" style="color:#393A34"><span class="token plain"># 把 6873 端口的服务映射到3002 端口。</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">sonar map 6873 3002</span><br></div></code></pre></div></div>
<h2 class="anchor anchorTargetStickyNavbar_e8hc" id="查找空闲端口">查找空闲端口<a href="https://feifeigd.github.io/blog/2026/07/02/find-process-by-port#%E6%9F%A5%E6%89%BE%E7%A9%BA%E9%97%B2%E7%AB%AF%E5%8F%A3" class="hash-link" aria-label="查找空闲端口的直接链接" title="查找空闲端口的直接链接" translate="no">​</a></h2>
<div class="language-shell codeBlockContainer_zaIt theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_SaHH"><pre tabindex="0" class="prism-code language-shell codeBlock_KlaO thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_zkpV"><div class="token-line" style="color:#393A34"><span class="token plain">sonar next </span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"># 从 8000 开始</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">sonar next 8000</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"># 在范围搜索</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">sonar next 3000-3100</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"># 找 3 个连续空闲端口</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">sonar next -n 3</span><br></div></code></pre></div></div>
<h2 class="anchor anchorTargetStickyNavbar_e8hc" id="远程扫描">远程扫描<a href="https://feifeigd.github.io/blog/2026/07/02/find-process-by-port#%E8%BF%9C%E7%A8%8B%E6%89%AB%E6%8F%8F" class="hash-link" aria-label="远程扫描的直接链接" title="远程扫描的直接链接" translate="no">​</a></h2>
<div class="language-shell codeBlockContainer_zaIt theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_SaHH"><pre tabindex="0" class="prism-code language-shell codeBlock_KlaO thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_zkpV"><div class="token-line" style="color:#393A34"><span class="token plain"># </span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">sonar list  --host user@server</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">sonar watch  --host user@server</span><br></div></code></pre></div></div>]]></content>
    </entry>
    <entry>
        <title type="html"><![CDATA[index]]></title>
        <id>https://feifeigd.github.io/blog/2026/06/24/index</id>
        <link href="https://feifeigd.github.io/blog/2026/06/24/index"/>
        <updated>2026-06-24T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[blog index.md]]></summary>
        <content type="html"><![CDATA[<p>blog index.md</p>]]></content>
    </entry>
    <entry>
        <title type="html"><![CDATA[mdx-blog-post]]></title>
        <id>https://feifeigd.github.io/blog/2021/08/01/mdx-blog-post</id>
        <link href="https://feifeigd.github.io/blog/2021/08/01/mdx-blog-post"/>
        <updated>2021-08-01T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[---]]></summary>
        <content type="html"><![CDATA[<hr>
<p>slug: mdx-blog-post
title: MDX Blog Post</p>
<hr>
<p>Blog posts support</p>
<div class="theme-admonition theme-admonition-tip admonition_b9Ox alert alert--success"><div class="admonitionHeading_ZZDy"><span class="admonitionIcon_HWNP"><svg viewBox="0 0 12 16"><path fill-rule="evenodd" d="M6.5 0C3.48 0 1 2.19 1 5c0 .92.55 2.25 1 3 1.34 2.25 1.78 2.78 2 4v1h5v-1c.22-1.22.66-1.75 2-4 .45-.75 1-2.08 1-3 0-2.81-2.48-5-5.5-5zm3.64 7.48c-.25.44-.47.8-.67 1.11-.86 1.41-1.25 2.06-1.45 3.23-.02.05-.02.11-.02.17H5c0-.06 0-.13-.02-.17-.2-1.17-.59-1.83-1.45-3.23-.2-.31-.42-.67-.67-1.11C2.44 6.78 2 5.65 2 5c0-2.2 2.02-4 4.5-4 1.22 0 2.36.42 3.22 1.19C10.55 2.94 11 3.94 11 5c0 .66-.44 1.78-.86 2.48zM4 14h5c-.23 1.14-1.3 2-2.5 2s-2.27-.86-2.5-2z"></path></svg></span>提示</div><div class="admonitionContent_vGUI"><p>Use the power of React to create interactive blog posts.</p></div></div>
<!-- -->
<p>For example, use JSX to create an interactive button:</p>
<div class="language-js codeBlockContainer_zaIt theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_SaHH"><pre tabindex="0" class="prism-code language-js codeBlock_KlaO thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_zkpV"><div class="token-line" style="color:#393A34"><span class="token operator" style="color:#393A34">&lt;</span><span class="token plain">button onClick</span><span class="token operator" style="color:#393A34">=</span><span class="token punctuation" style="color:#393A34">{</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token arrow operator" style="color:#393A34">=&gt;</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">alert</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'button clicked!'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">}</span><span class="token operator" style="color:#393A34">&gt;</span><span class="token maybe-class-name">Click</span><span class="token plain"> </span><span class="token maybe-class-name">Me</span><span class="token operator" style="color:#393A34">!</span><span class="token operator" style="color:#393A34">&lt;</span><span class="token operator" style="color:#393A34">/</span><span class="token plain">button</span><span class="token operator" style="color:#393A34">&gt;</span><br></div></code></pre></div></div>
<button>Click Me!</button>]]></content>
    </entry>
    <entry>
        <title type="html"><![CDATA[first-blog-post]]></title>
        <id>https://feifeigd.github.io/blog/2019/05/28/first-blog-post</id>
        <link href="https://feifeigd.github.io/blog/2019/05/28/first-blog-post"/>
        <updated>2019-05-28T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[---]]></summary>
        <content type="html"><![CDATA[<hr>
<h2 class="anchor anchorTargetStickyNavbar_e8hc" id="slug-first-blog-posttitle-first-blog-posttags-docusaurus">slug: first-blog-post
title: First Blog Post
tags: [docusaurus]<a href="https://feifeigd.github.io/blog/2019/05/28/first-blog-post#slug-first-blog-posttitle-first-blog-posttags-docusaurus" class="hash-link" aria-label="slug: first-blog-post
title: First Blog Post
tags: [docusaurus]的直接链接" title="slug: first-blog-post
title: First Blog Post
tags: [docusaurus]的直接链接" translate="no">​</a></h2>
<p>Lorem ipsum dolor sit amet...</p>
<!-- -->
<p>...consectetur adipiscing elit.</p>]]></content>
    </entry>
</feed>