<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>文章列表 on 指尖魔法屋</title><link>https://blog.thinkmoon.cn/post-list/</link><description>Recent content in 文章列表 on 指尖魔法屋</description><generator>Hugo</generator><language>zh-cn</language><copyright>© 2025 ThinkBlog. All rights reserved.</copyright><atom:link href="https://blog.thinkmoon.cn/post-list/index.xml" rel="self" type="application/rss+xml"/><item><title>用 GolemBot 把 Codex 接到飞书机器人</title><link>https://blog.thinkmoon.cn/post/995_%E7%94%A8golembot%E6%8A%8Acodex%E6%8E%A5%E5%88%B0%E9%A3%9E%E4%B9%A6%E6%9C%BA%E5%99%A8%E4%BA%BA/</link><pubDate>Tue, 09 Jun 2026 22:19:21 +0800</pubDate><guid>https://blog.thinkmoon.cn/post/995_%E7%94%A8golembot%E6%8A%8Acodex%E6%8E%A5%E5%88%B0%E9%A3%9E%E4%B9%A6%E6%9C%BA%E5%99%A8%E4%BA%BA/</guid><description>&lt;blockquote&gt;
&lt;p&gt;想在飞书里直接 @ 一个机器人，然后让它帮我问 Codex，还能顺手去飞书文档、需求清单、bug 清单里翻资料。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;这个需求一开始很容易被带偏：自己写一个飞书 Bot Gateway，接事件、调模型、维护会话、处理权限、再封装飞书 OpenAPI。&lt;/p&gt;
&lt;p&gt;但这事其实不太值得从零写。飞书机器人入口有现成工具，Codex 本身有 CLI，飞书也有官方 CLI。把这几块拼起来，就能得到一个相对省事的版本。&lt;/p&gt;
&lt;p&gt;下面这张图先把调用链画清楚，后面的安装和配置基本都是围绕这条链路展开。&lt;/p&gt;

&lt;div class="mermaid"&gt;flowchart LR
 A[飞书用户] --&amp;gt; B[飞书机器人]
 B --&amp;gt; C[GolemBot&amp;lt;br/&amp;gt;Feishu Channel]
 C --&amp;gt; D[GolemBot&amp;lt;br/&amp;gt;Codex Engine]
 D --&amp;gt; E[Codex CLI]
 E --&amp;gt; F[AGENTS.md&amp;lt;br/&amp;gt;项目规则]
 E --&amp;gt; G[lark-cli&amp;lt;br/&amp;gt;飞书 CLI Skills]
 G --&amp;gt; H[飞书 Docs]
 G --&amp;gt; I[Base / Sheets]
 G --&amp;gt; J[Tasks / Wiki]&lt;/div&gt;
&lt;p&gt;这篇文章就按这个思路写一版可操作的教程。&lt;/p&gt;
&lt;h2 id="先说结论"&gt;先说结论&lt;/h2&gt;
&lt;p&gt;我会选这套组合：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;code&gt;GolemBot&lt;/code&gt;：负责把飞书机器人消息接进来，并转给 Codex。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Codex CLI&lt;/code&gt;：负责真正的 Agent 推理、命令调用和上下文处理。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;AGENTS.md&lt;/code&gt;：负责告诉 Codex 该怎么查飞书资料、哪些事情不能乱做。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;lark-cli&lt;/code&gt;：负责读取飞书 Docs、Base、Sheets、Tasks、Wiki。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;larksuite/cli&lt;/code&gt; Skills：让 Codex 更知道飞书 CLI 该怎么用。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;这样做的好处是少写胶水代码。GolemBot 处理 IM 渠道，Codex 处理 Agent，飞书 CLI 处理数据访问。&lt;/p&gt;</description></item><item><title>调试 OpenAI Responses API 的 Web Search 踩坑记录</title><link>https://blog.thinkmoon.cn/post/994_%E8%B0%83%E8%AF%95openai-responses-api%E7%9A%84web-search%E8%B8%A9%E5%9D%91%E8%AE%B0%E5%BD%95/</link><pubDate>Thu, 30 Apr 2026 10:30:00 +0800</pubDate><guid>https://blog.thinkmoon.cn/post/994_%E8%B0%83%E8%AF%95openai-responses-api%E7%9A%84web-search%E8%B8%A9%E5%9D%91%E8%AE%B0%E5%BD%95/</guid><description>&lt;p&gt;最近在做一个投资研究 Agent，其中有个很具体的需求：监控腾讯控股 &lt;code&gt;0700.HK&lt;/code&gt; 的估值指标，尤其是 trailing PE 或 TTM PE。&lt;/p&gt;
&lt;p&gt;这个需求看起来不复杂，但实际做下来踩了几个坑。直接访问 Yahoo Finance 的接口，在当前运行环境里会返回 &lt;code&gt;403 Forbidden&lt;/code&gt;；换用模型的 web search 又遇到了 Responses API 请求格式、流式响应解析和第三方 provider 兼容性问题。&lt;/p&gt;
&lt;p&gt;这篇文章记录一下这次调试过程。重点不是“怎么让模型搜索网页”，而是：当你真的把 OpenAI 新版 Responses API 里的 &lt;code&gt;web_search&lt;/code&gt; 接到工程代码里时，哪些地方最容易出错。&lt;/p&gt;
&lt;h2 id="需求背景"&gt;需求背景&lt;/h2&gt;
&lt;p&gt;腾讯 PE 监控任务需要拿到 &lt;code&gt;0700.HK&lt;/code&gt; 当前的 trailing PE 或 TTM PE。&lt;/p&gt;
&lt;p&gt;最开始的思路很直接：从常见财经数据源获取结构化数据。但是 Yahoo Finance 在当前环境里不稳定，接口返回 &lt;code&gt;403 Forbidden&lt;/code&gt;。后来通过 web search 找到一个当前可访问、页面结构也比较容易解析的数据源：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;https://stockanalysis.com/quote/hkg/0700/statistics/
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;所以最后的数据源策略变成了两层：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;优先直接抓取 StockAnalysis 页面，解析 &lt;code&gt;P/E Ratio&lt;/code&gt;；&lt;/li&gt;
&lt;li&gt;如果网页结构变化、抓取失败，才使用 Responses API 的 &lt;code&gt;web_search&lt;/code&gt; 作为兜底。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;这个顺序很重要。模型搜索适合发现信息和兜底，不适合作为首选的结构化行情接口。&lt;/p&gt;
&lt;h2 id="官方写法和实际差异"&gt;官方写法和实际差异&lt;/h2&gt;
&lt;p&gt;OpenAI 官方文档里，Web Search 是 Responses API 的内置工具。官方示例大致是这样的：&lt;/p&gt;</description></item><item><title>Harness Engineering 的介绍与编程实践</title><link>https://blog.thinkmoon.cn/post/993_harness-engineering%E7%9A%84%E4%BB%8B%E7%BB%8D%E4%B8%8E%E5%AE%9E%E8%B7%B5/</link><pubDate>Thu, 23 Apr 2026 15:20:00 +0800</pubDate><guid>https://blog.thinkmoon.cn/post/993_harness-engineering%E7%9A%84%E4%BB%8B%E7%BB%8D%E4%B8%8E%E5%AE%9E%E8%B7%B5/</guid><description>&lt;blockquote&gt;
&lt;p&gt;同样是用 AI 编程，有的团队已经能让 Agent 稳定改代码、跑测试、收敛结果；有的团队却还停留在“写得挺像，但一跑就炸”。差距往往出在模型外面那套工程系统，也就是让 AI 能安全干活的 Harness。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id="为什么会有-harness-engineering"&gt;为什么会有 Harness Engineering&lt;/h2&gt;
&lt;p&gt;这两年 AI 编程工具变化很快。&lt;/p&gt;
&lt;p&gt;最早大家更多是在“问模型”：解释代码、生成函数、补一段脚本。这个阶段最重要的是 Prompt Engineering，也就是把需求讲清楚，减少模型理解偏差。&lt;/p&gt;
&lt;p&gt;后来大家发现，只会写提示词还不够。模型如果不知道项目目录、接口约定、历史设计和运行方式，就很容易一本正经地瞎猜。于是 Context Engineering 开始被反复提起：该给模型哪些文件、日志、文档和规则，才能让它少幻觉。&lt;/p&gt;
&lt;p&gt;但当 AI 真的开始改文件、跑命令、修测试，问题又变了。&lt;/p&gt;
&lt;p&gt;这时最让人头疼的，开始变成这些事：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;破坏已有结构；&lt;/li&gt;
&lt;li&gt;不按既定文档开发；&lt;/li&gt;
&lt;li&gt;规避失败，假装成功；&lt;/li&gt;
&lt;li&gt;顺着错误假设越修越远；&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;这些问题，光加一句“请谨慎操作”没什么用。你需要一套外部机制，让 AI 的行为有边界、有反馈、能收敛。这套机制，就是 Harness。&lt;/p&gt;
&lt;p&gt;一个很好记的公式是：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Agent = Model + Harness
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;模型负责推理和生成，Harness 负责环境、工具、约束、状态和反馈。没有 Harness，模型更像一个会说话的大脑；有了 Harness，它才更像一个能在工程环境里干活的代理。&lt;/p&gt;
&lt;p&gt;OpenAI 在 2026-02-11 发布的官方文章里，对这套“模型之外的工程系统”有一套比较完整的展开，本文很多整理也受它影响。&lt;/p&gt;
&lt;h2 id="harness-到底在管什么"&gt;Harness 到底在管什么&lt;/h2&gt;
&lt;p&gt;&lt;img src="https://cdn.jsdelivr.net/gh/thinkmoon/pic@master/images/20260428133806.png" alt="20260428133806"&gt;&lt;/p&gt;
&lt;p&gt;可以把Harness 理解成&amp;quot;控制与治理层&amp;quot;, 通俗来说就是: &amp;ldquo;护栏&amp;rdquo; + &amp;ldquo;工具链&amp;rdquo; + &amp;ldquo;运行框架&amp;rdquo;。&lt;/p&gt;
&lt;p&gt;别把它理解成某个单独工具，也别理解成一个提示词模板。更准确地说，它是一层围着模型搭起来的工程控制系统。&lt;/p&gt;
&lt;p&gt;落到 AI 编程场景，Harness 一般要把几件事管起来：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;上下文管理&lt;/strong&gt;：让代理知道项目结构、任务目标、相关文件和编码约束；&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;工具接口&lt;/strong&gt;：让它能读文件、搜代码、跑测试、打补丁，少靠猜；&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;执行沙盒&lt;/strong&gt;：让命令运行在受限环境里，出错也别伤到真实环境；&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;规则约束&lt;/strong&gt;：用架构规则, skills, Hooks限制越界动作；&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;验证循环&lt;/strong&gt;：把测试失败、构建报错、审查意见重新喂回去，让它继续修；&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;人工闸门&lt;/strong&gt;：删文件、改生产配置、发版部署这类动作，必须有人点头。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;所以我现在更倾向于把 Harness Engineering 看成一件工程活。它要解决的是环境问题：就算模型犯错，错误也尽量落在可控范围内。即：用流程与规范来约束模型。&lt;/p&gt;</description></item><item><title>边缘设备RK3588下RKNN的推理适配</title><link>https://blog.thinkmoon.cn/post/992-%E8%BE%B9%E7%BC%98%E8%AE%BE%E5%A4%87rk3588%E4%B8%8Brknn%E7%9A%84%E6%8E%A8%E7%90%86%E9%80%82%E9%85%8D/</link><pubDate>Wed, 08 Apr 2026 10:30:00 +0000</pubDate><guid>https://blog.thinkmoon.cn/post/992-%E8%BE%B9%E7%BC%98%E8%AE%BE%E5%A4%87rk3588%E4%B8%8Brknn%E7%9A%84%E6%8E%A8%E7%90%86%E9%80%82%E9%85%8D/</guid><description>&lt;p&gt;&lt;img src="https://cdn.jsdelivr.net/gh/thinkmoon/pic@master/images/20260409145613.png" alt="20260409145613"&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;这篇文章主要梳理一件事：如何把训练侧模型，稳定地落到 RK3588 上跑起来。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id="rknn-是什么"&gt;RKNN 是什么&lt;/h2&gt;
&lt;p&gt;RKNN 是瑞芯微（Rockchip）围绕自研 NPU 推出的完整软件栈，用来解决模型从训练框架到板端推理的落地问题。&lt;/p&gt;
&lt;p&gt;常用到的核心组件有两个：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;RKNN-Toolkit2&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;运行在 PC 端（通常是 Ubuntu）的开发工具链，负责把第三方框架模型（如 PyTorch、TensorFlow、ONNX）转换、量化、优化为 &lt;code&gt;.rknn&lt;/code&gt; 文件。&lt;/p&gt;
&lt;p&gt;项目地址：&lt;/p&gt;
&lt;p&gt;&lt;a href="https://github.com/airockchip/rknn-toolkit2"&gt;https://github.com/airockchip/rknn-toolkit2&lt;/a&gt;&lt;/p&gt;
&lt;ol start="2"&gt;
&lt;li&gt;RKNN Runtime&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;运行在嵌入式板卡端（如 RK3588）的运行时库，负责加载 &lt;code&gt;.rknn&lt;/code&gt; 模型并调用 NPU 执行推理。&lt;/p&gt;
&lt;h2 id="如何判断我的设备是否支持rknn"&gt;如何判断我的设备是否支持RKNN&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;看型号，如rk3588，就是支持的&lt;/li&gt;
&lt;li&gt;使用命令&lt;code&gt;sudo cat /sys/kernel/debug/rknpu/load&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;img src="https://cdn.jsdelivr.net/gh/thinkmoon/pic@master/images/20260409135024.png" alt="20260409135024"&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;该结果表示有3个RK npu&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id="rknn-的典型工作流"&gt;RKNN 的典型工作流&lt;/h2&gt;
&lt;p&gt;从开发到部署，一般可以分成 4 个阶段：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;模型转换&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;把 &lt;code&gt;.onnx&lt;/code&gt; 或 &lt;code&gt;.pt&lt;/code&gt; 模型导入 Toolkit，完成图转换与算子适配。&lt;/p&gt;
&lt;ol start="2"&gt;
&lt;li&gt;量化与优化&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;这是 RKNN 提速的关键步骤。NPU 更擅长整数计算（INT8），通常会把 FP32 模型量化为 INT8，在保证精度可接受的前提下换取更高吞吐和更低延迟。&lt;/p&gt;
&lt;ol start="3"&gt;
&lt;li&gt;模型导出&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;导出目标模型文件：&lt;code&gt;.rknn&lt;/code&gt;。&lt;/p&gt;
&lt;ol start="4"&gt;
&lt;li&gt;板端推理&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;在 RK3588 上通过 C/C++ 或 Python 接口调用 Runtime，完成加载、预处理、推理和后处理。&lt;/p&gt;
&lt;p&gt;&lt;img src="https://cdn.jsdelivr.net/gh/thinkmoon/pic@master/images/20260409141450.png" alt="20260409141450"&gt;&lt;/p&gt;
&lt;h2 id="性能优化1-模型的int8量化"&gt;性能优化（1）&amp;mdash; 模型的int8量化&lt;/h2&gt;
&lt;p&gt;众说周知，通用模型的精度是FP32的，而量化就是将FP32精度的权重降低至FP16，甚至是INT8，或者更极端一点的INT4。这样模型的计算量就会大幅减少，与之带来的后果也是准确度的下降。&lt;/p&gt;</description></item><item><title>使用python实现动量量化策略监控面板</title><link>https://blog.thinkmoon.cn/post/991-%E4%BD%BF%E7%94%A8python%E5%AE%9E%E7%8E%B0%E5%8A%A8%E9%87%8F%E9%87%8F%E5%8C%96%E7%AD%96%E7%95%A5%E7%9B%91%E6%8E%A7%E9%9D%A2%E6%9D%BF/</link><pubDate>Mon, 22 Dec 2025 10:00:00 +0000</pubDate><guid>https://blog.thinkmoon.cn/post/991-%E4%BD%BF%E7%94%A8python%E5%AE%9E%E7%8E%B0%E5%8A%A8%E9%87%8F%E9%87%8F%E5%8C%96%E7%AD%96%E7%95%A5%E7%9B%91%E6%8E%A7%E9%9D%A2%E6%9D%BF/</guid><description>&lt;h1 id="使用python实现动量量化策略监控面板"&gt;使用python实现动量量化策略监控面板&lt;/h1&gt;
&lt;h2 id="1-什么是动量策略"&gt;1. 什么是动量策略？&lt;/h2&gt;
&lt;p&gt;在金融市场中，动量效应（Momentum Effect）被誉为“金融界的牛顿第一定律”。它的核心逻辑是：&lt;strong&gt;强者恒强&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;动量策略不关注公司的财务报表，也不关心基本面估值，它只看价格趋势。&lt;/p&gt;
&lt;p&gt;它假设过去一段时间表现最好的资产，在未来的一段时间内大概率会继续表现良好；反之，过去表现最差的资产，未来大概率会继续下跌。这是一种**“追涨杀跌”**的策略，但不同于散户的情绪化操作，它是基于严格的数据回测和纪律执行的。&lt;/p&gt;
&lt;h2 id="2-标的选择构建微型全天候组合"&gt;2. 标的选择：构建“微型全天候”组合&lt;/h2&gt;
&lt;p&gt;为了提高策略的稳健性，我们不建议只在单一股市内部寻找动量。在本次实践中，我们选取了五个&lt;strong&gt;低相关性&lt;/strong&gt;的跨国、跨类别资产作为池子：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;创业板 ETF (159915)&lt;/strong&gt;：代表 A 股高弹性、科技成长风格。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;沪深 300 ETF (510300)&lt;/strong&gt;：代表 A 股大盘、价值蓝筹风格。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;纳指 100 ETF (513100)&lt;/strong&gt;：代表全球科技龙头，与 A 股周期错位。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;黄金 ETF (518880)&lt;/strong&gt;：经典的避险资产，在股市动荡时常有独立行情。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;货币 ETF (511880)&lt;/strong&gt;：作为“防御港湾”，当上述风险资产全部熄火时，用来保护本金。&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="3-策略逻辑设计"&gt;3. 策略逻辑设计&lt;/h2&gt;
&lt;p&gt;我们设计的量化看板遵循以下双重逻辑：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;相对动量（优中选优）&lt;/strong&gt;：计算这四个风险资产过去 $N$ 天（如 20 天）的涨幅，找出表现最强的那一个。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;绝对动量（止损风控）&lt;/strong&gt;：如果表现最强的资产收益率依然为负（或者低于货币基金收益），说明市场整体环境极差，此时策略强制切换至 &lt;strong&gt;货币 ETF&lt;/strong&gt; 进行空仓避险。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="4-技术栈实现"&gt;4. 技术栈实现&lt;/h2&gt;
&lt;p&gt;为了保证环境的纯净和运行的性能，我们推荐使用以下配置方案：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;环境管理&lt;/strong&gt;：Conda (推荐 Python 3.11 版本)。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;数据来源&lt;/strong&gt;：AkShare (免费开源的金融数据接口库)。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;前端展示&lt;/strong&gt;：Streamlit (极速构建 Web 数据看板的利器)。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;交互绘图&lt;/strong&gt;：Plotly (提供响应式的缩放图表)。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="核心代码实现逻辑"&gt;核心代码实现逻辑&lt;/h3&gt;
&lt;p&gt;创建环境&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;conda create -n quant_lab &lt;span class="nv"&gt;python&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;3.11 -c conda-forge -y
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;conda activate quant_lab
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;安装相关依赖&lt;/p&gt;</description></item><item><title>使用智谱api将长语音转文本</title><link>https://blog.thinkmoon.cn/post/990-%E4%BD%BF%E7%94%A8%E6%99%BA%E8%B0%B1api%E5%B0%86%E9%95%BF%E8%AF%AD%E9%9F%B3%E8%BD%AC%E6%96%87%E6%9C%AC/</link><pubDate>Tue, 16 Dec 2025 19:40:00 +0000</pubDate><guid>https://blog.thinkmoon.cn/post/990-%E4%BD%BF%E7%94%A8%E6%99%BA%E8%B0%B1api%E5%B0%86%E9%95%BF%E8%AF%AD%E9%9F%B3%E8%BD%AC%E6%96%87%E6%9C%AC/</guid><description>&lt;p&gt;&lt;img src="https://cdn.jsdelivr.net/gh/thinkmoon/pic@master/images/20251217200921.png" alt="20251217200921"&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;智谱AI语音识别API在准确性和响应速度方面表现出色，但受限于单次请求最大30秒的音频长度限制。本文基于pyannote.audio的语音活动检测(VAD)技术，实现了智能音频分块策略：在语音段落间隙处精确切割，避免截断语义单元；通过批量异步调用API接口，实现对长音频文件的完整转写；最终拼接处理结果输出。从Conda环境配置到生产代码实现，提供完整的可复现解决方案。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id="一长语音转文本的核心挑战"&gt;一、长语音转文本的核心挑战&lt;/h2&gt;
&lt;p&gt;主要的挑战是目前的条件没有合适的API。正好智谱API有token和API，先拿来用了。但是智谱API只能支持25M以下以及30s以内的语音。所以我们需要语音文件先断句，再分块，接着调用智谱API，最后拼接成最终结果。&lt;/p&gt;
&lt;h2 id="三关键技术实现智能音频分块"&gt;三、关键技术：实现智能音频分块&lt;/h2&gt;
&lt;p&gt;这是自建系统的核心技术，也是本实践的重点。&lt;strong&gt;目标是在静音处切分音频&lt;/strong&gt;，避免截断单词。&lt;/p&gt;
&lt;h3 id="31-核心思想"&gt;3.1 核心思想&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;加载音频&lt;/strong&gt;：读取长音频文件。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;检测静音&lt;/strong&gt;：遍历音频，识别出静音段（声音能量低于阈值）。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;标记边界&lt;/strong&gt;：以静音为边界，切分语音。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;生成音频块&lt;/strong&gt;：保存为独立的短音频文件。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;添加保护垫&lt;/strong&gt;：在切分点两边保留一小段音频作为缓冲，防止截断。&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id="32-三种实现方案"&gt;3.2 三种实现方案&lt;/h3&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th style="text-align: left"&gt;方案&lt;/th&gt;
					&lt;th style="text-align: left"&gt;优点&lt;/th&gt;
					&lt;th style="text-align: left"&gt;缺点&lt;/th&gt;
					&lt;th style="text-align: left"&gt;推荐场景&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;&lt;strong&gt;&lt;code&gt;pydub&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
					&lt;td style="text-align: left"&gt;极其简单，代码少&lt;/td&gt;
					&lt;td style="text-align: left"&gt;精度一般，噪音敏感&lt;/td&gt;
					&lt;td style="text-align: left"&gt;快速原型验证、干净录音&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;&lt;strong&gt;&lt;code&gt;webrtcvad&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
					&lt;td style="text-align: left"&gt;精度高，轻量快速&lt;/td&gt;
					&lt;td style="text-align: left"&gt;API底层，代码复杂&lt;/td&gt;
					&lt;td style="text-align: left"&gt;对准确率有要求、生产环境&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;&lt;strong&gt;&lt;code&gt;pyannote.audio&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
					&lt;td style="text-align: left"&gt;效果最好，功能强大（含说话人分离）&lt;/td&gt;
					&lt;td style="text-align: left"&gt;依赖重，资源消耗大&lt;/td&gt;
					&lt;td style="text-align: left"&gt;需要说话人分离、追求最佳效果&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id="33-使用-pyannoteaudio-进行分块本实践选择"&gt;3.3 使用 &lt;code&gt;pyannote.audio&lt;/code&gt; 进行分块（本实践选择）&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;pyannote.audio&lt;/code&gt; 是一个基于 PyTorch 的开源神经语音工具包，效果最好，且能同时完成说话人分离。选型原则：条件允许范围内，选最好！&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;但是本实践没有进行说话人分离&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id="四完整实践使用pyannoteaudio切割并调用api转写"&gt;四、完整实践：使用pyannote.audio切割并调用API转写&lt;/h2&gt;
&lt;p&gt;实现一个完整的流程：使用 &lt;code&gt;pyannote.audio&lt;/code&gt; 切割音频，然后调用智谱AI的API进行转写。&lt;/p&gt;
&lt;h3 id="41-环境准备"&gt;4.1 环境准备&lt;/h3&gt;
&lt;p&gt;首先，为了避免系统环境冲突，强烈建议创建一个虚拟环境。&lt;/p&gt;
&lt;h3 id="安装依赖"&gt;安装依赖&lt;/h3&gt;
&lt;p&gt;依赖文件&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;audio_env&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;channels&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;conda-forge&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;defaults&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/free/&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/main/&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/conda-forge/&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;dependencies&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;_libgcc_mutex=0.1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;_openmp_mutex=5.1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;aom=3.9.1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;bzip2=1.0.8&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;ca-certificates=2025.12.2&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;cairo=1.18.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;dav1d=1.2.1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;expat=2.7.3&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;ffmpeg=7.1.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;font-ttf-dejavu-sans-mono=2.37&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;font-ttf-inconsolata=3.000&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;font-ttf-source-code-pro=2.038&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;font-ttf-ubuntu=0.83&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;fontconfig=2.15.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;fonts-conda-ecosystem=1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;fonts-conda-forge=1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;freetype=2.14.1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;fribidi=1.0.16&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;gdk-pixbuf=2.42.12&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;gmp=6.3.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;graphite2=1.3.14&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;harfbuzz=9.0.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;icu=73.2&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;lame=3.100&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;ld_impl_linux-64=2.44&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;lerc=4.0.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;libabseil=20240722.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;libass=0.17.3&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;libdeflate=1.22&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;libdrm=2.4.125&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;libegl=1.7.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;libexpat=2.7.3&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;libffi=3.4.4&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;libfreetype=2.14.1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;libfreetype6=2.14.1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;libgcc=15.2.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;libgcc-ng=15.2.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;libgl=1.7.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;libglib=2.84.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;libglvnd=1.7.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;libglx=1.7.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;libgomp=15.2.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;libhwloc=2.12.1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;libiconv=1.18&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;libjpeg-turbo=3.1.2&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;libnsl=2.0.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;libopenvino=2024.4.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;libopenvino-auto-batch-plugin=2024.4.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;libopenvino-auto-plugin=2024.4.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;libopenvino-hetero-plugin=2024.4.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;libopenvino-intel-cpu-plugin=2024.4.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;libopenvino-intel-gpu-plugin=2024.4.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;libopenvino-intel-npu-plugin=2024.4.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;libopenvino-ir-frontend=2024.4.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;libopenvino-onnx-frontend=2024.4.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;libopenvino-paddle-frontend=2024.4.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;libopenvino-pytorch-frontend=2024.4.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;libopenvino-tensorflow-frontend=2024.4.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;libopenvino-tensorflow-lite-frontend=2024.4.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;libopus=1.6&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;libpciaccess=0.18&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;libpng=1.6.53&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;libprotobuf=5.28.2&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;librsvg=2.58.4&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;libstdcxx=15.2.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;libstdcxx-ng=15.2.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;libtiff=4.7.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;libuuid=1.41.5&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;libva=2.23.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;libvpx=1.14.1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;libwebp-base=1.6.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;libxcb=1.17.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;libxml2=2.13.9&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;libzlib=1.3.1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;ncurses=6.5&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;ocl-icd=2.3.3&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;opencl-headers=2025.06.13&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;openh264=2.5.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;openssl=3.6.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;pango=1.54.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;pcre2=10.44&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;pip=25.3&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;pixman=0.46.4&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;pthread-stubs=0.3&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;pugixml=1.14&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;python=3.10.19&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;readline=8.3&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;setuptools=80.9.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;snappy=1.2.2&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;sqlite=3.51.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;svt-av1=2.3.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;tbb=2022.3.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;tk=8.6.15&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;wayland=1.24.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;wayland-protocols=1.47&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;wheel=0.45.1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;x264=1!164.3095&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;x265=3.5&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;xorg-libice=1.1.2&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;xorg-libsm=1.2.6&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;xorg-libx11=1.8.12&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;xorg-libxau=1.0.12&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;xorg-libxdmcp=1.1.5&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;xorg-libxext=1.3.6&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;xorg-libxfixes=6.0.2&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;xorg-libxrender=0.9.12&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;xorg-xorgproto=2024.1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;xz=5.6.4&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;zlib=1.3.1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;zstd=1.5.7&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;pip&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;aiohappyeyeballs==2.6.1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;aiohttp==3.13.2&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;aiosignal==1.4.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;alembic==1.17.2&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;antlr4-python3-runtime=4.9.3&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;anyio=4.12.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;asteroid-filterbanks==0.4.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;async-timeout==5.0.1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;attrs==25.4.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;certifi==2025.11.12&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;cffi==2.0.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;charset-normalizer==3.4.4&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;click==8.3.1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;colorlog==6.10.1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;contourpy==1.3.2&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;cycler==0.12.1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;docopt==0.6.2&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;einops==0.8.1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;exceptiongroup==1.3.1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;filelock==3.20.1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;fonttools==4.61.1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;frozenlist==1.8.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;fsspec==2025.12.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;googleapis-common-protos==1.72.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;greenlet==3.3.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;grpcio==1.76.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;h11==0.16.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;hf-xet==1.2.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;httpcore==1.0.9&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;httpx==0.28.1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;huggingface-hub==0.23.5&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;hyperpyyaml==1.2.2&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;idna==3.11&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;importlib-metadata==8.7.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;jinja2==3.1.6&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;joblib==1.5.3&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;julius==0.2.7&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;kiwisolver==1.4.9&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;lightning==2.6.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;lightning-utilities==0.15.2&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;mako==1.3.10&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;markdown-it-py==4.0.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;markupsafe==3.0.3&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;matplotlib==3.10.8&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;mdurl==0.1.2&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;mpmath==1.3.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;multidict==6.7.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;networkx==3.4.2&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;numpy==1.26.4&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;nvidia-cublas-cu12==12.1.3.1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;nvidia-cuda-cupti-cu12==12.1.105&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;nvidia-cuda-nvrtc-cu12==12.1.105&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;nvidia-cuda-runtime-cu12==12.1.105&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;nvidia-cudnn-cu12==9.1.0.70&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;nvidia-cufft-cu12==11.0.2.54&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;nvidia-cufile-cu12==1.13.1.3&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;nvidia-curand-cu12==10.3.2.106&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;nvidia-cusolver-cu12==11.4.5.107&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;nvidia-cusparse-cu12==12.1.0.106&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;nvidia-cusparselt-cu12==0.7.1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;nvidia-nccl-cu12==2.20.5&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;nvidia-nvjitlink-cu12==12.8.93&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;nvidia-nvshmem-cu12==3.3.20&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;nvidia-nvtx-cu12==12.1.105&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;omegaconf==2.3.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;opentelemetry-api==1.39.1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;opentelemetry-exporter-otlp==1.39.1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;opentelemetry-exporter-otlp-proto-common==1.39.1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;opentelemetry-exporter-otlp-proto-grpc==1.39.1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;opentelemetry-exporter-otlp-proto-http==1.39.1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;opentelemetry-proto==1.39.1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;opentelemetry-sdk==1.39.1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;opentelemetry-semantic-conventions==0.60b1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;optuna==4.6.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;packaging==25.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;pandas==2.3.3&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;pillow==12.0.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;primepy==1.3&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;propcache==0.4.1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;protobuf==6.33.2&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;pyannote-audio==3.1.1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;pyannote-core==5.0.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;pyannote-database==5.1.3&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;pyannote-metrics==3.2.1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;pyannote-pipeline==3.0.1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;pyannoteai-sdk==0.3.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;pycparser==2.23&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;pydub==0.25.1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;pygments==2.19.2&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;pyparsing==3.2.5&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;pysocks==1.7.1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;python-dateutil==2.9.0.post0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;pytorch-lightning==1.9.5&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;pytorch-metric-learning==2.9.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;pytz==2025.2&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;pyyaml==6.0.3&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;requests==2.32.5&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;rich==14.2.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;ruamel-yaml==0.18.16&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;ruamel-yaml-clib==0.2.15&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;safetensors==0.7.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;scikit-learn==1.7.2&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;scipy==1.15.3&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;semver==3.0.4&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;sentencepiece==0.2.1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;shellingham==1.5.4&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;six==1.17.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;socksio==1.0.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;sortedcontainers==2.4.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;soundfile==0.13.1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;speechbrain==1.0.3&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;sqlalchemy==2.0.45&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;sympy==1.14.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;tabulate==0.9.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;tensorboardx==2.6.4&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;threadpoolctl==3.6.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;tomli==2.3.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;torch==2.4.0+cu121&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;torch-audiomentations==0.12.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;torch-pitch-shift==1.2.5&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;torchaudio==2.4.0+cu121&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;torchcodec==0.7.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;torchmetrics==0.11.4&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;torchvision==0.19.0+cu121&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;tqdm==4.67.1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;triton==3.0.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;typer==0.20.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;typer-slim==0.20.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;typing-extensions==4.15.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;tzdata==2025.3&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;urllib3==2.6.2&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;yarl==1.22.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;zipp==3.23.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="安装依赖-1"&gt;安装依赖&lt;/h3&gt;
&lt;p&gt;将上述内容保存为 &lt;code&gt;environment.yml&lt;/code&gt; 文件，然后执行以下命令安装所有依赖：&lt;/p&gt;</description></item><item><title>一些在Jetson设备的开发经验</title><link>https://blog.thinkmoon.cn/post/989_%E4%B8%80%E4%BA%9B%E5%9C%A8jetson%E8%AE%BE%E5%A4%87%E7%9A%84%E5%BC%80%E5%8F%91%E7%BB%8F%E9%AA%8C/</link><pubDate>Mon, 27 Oct 2025 10:30:00 +0000</pubDate><guid>https://blog.thinkmoon.cn/post/989_%E4%B8%80%E4%BA%9B%E5%9C%A8jetson%E8%AE%BE%E5%A4%87%E7%9A%84%E5%BC%80%E5%8F%91%E7%BB%8F%E9%AA%8C/</guid><description>&lt;h1 id="一些在jetson设备的开发经验"&gt;一些在Jetson设备的开发经验&lt;/h1&gt;
&lt;blockquote&gt;
&lt;p&gt;NVIDIA Jetson系列设备作为边缘AI计算的重要平台，在计算机视觉和深度学习应用中发挥着关键作用。本文将详细介绍Jetson设备的刷机、SDK安装、YOLO模型部署以及TensorRT优化等开发经验，帮助开发者快速上手并实现高性能的AI应用部署。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id="一jetson设备概述"&gt;一、Jetson设备概述&lt;/h2&gt;
&lt;h3 id="11-什么是nvidia-jetson"&gt;1.1 什么是NVIDIA Jetson？&lt;/h3&gt;
&lt;p&gt;NVIDIA Jetson是一系列基于ARM架构的嵌入式AI计算平台，专为边缘计算和机器人应用设计。Jetson设备集成了高性能的GPU、CPU和深度学习加速器，能够在低功耗环境下运行复杂的AI模型。&lt;/p&gt;
&lt;h3 id="12-jetson系列对比"&gt;1.2 Jetson系列对比&lt;/h3&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;设备型号&lt;/th&gt;
					&lt;th&gt;GPU&lt;/th&gt;
					&lt;th&gt;CPU&lt;/th&gt;
					&lt;th&gt;内存&lt;/th&gt;
					&lt;th&gt;功耗&lt;/th&gt;
					&lt;th&gt;适用场景&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;Jetson AGX Orin (64GB)&lt;/td&gt;
					&lt;td&gt;2048-core Ampere&lt;/td&gt;
					&lt;td&gt;12-core Arm Cortex-A78AE&lt;/td&gt;
					&lt;td&gt;64GB LPDDR5&lt;/td&gt;
					&lt;td&gt;60W&lt;/td&gt;
					&lt;td&gt;高性能AI推理&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Jetson Orin NX 16GB&lt;/td&gt;
					&lt;td&gt;1024-core Ampere&lt;/td&gt;
					&lt;td&gt;8-core Arm Cortex-A78AE&lt;/td&gt;
					&lt;td&gt;16GB LPDDR5&lt;/td&gt;
					&lt;td&gt;25W&lt;/td&gt;
					&lt;td&gt;中等性能应用&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Jetson Orin Nano&lt;/td&gt;
					&lt;td&gt;1024-core Ampere&lt;/td&gt;
					&lt;td&gt;6-core Arm Cortex-A78AE&lt;/td&gt;
					&lt;td&gt;8GB LPDDR5&lt;/td&gt;
					&lt;td&gt;15W&lt;/td&gt;
					&lt;td&gt;入门级AI应用&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="二jetpack-sdk安装与配置"&gt;二、JetPack SDK安装与配置&lt;/h2&gt;
&lt;h3 id="21-什么是nvidia-jetpack"&gt;2.1 什么是NVIDIA JetPack？&lt;/h3&gt;
&lt;p&gt;JetPack是NVIDIA为Jetson设备提供的软件开发套件，包含了完整的操作系统、CUDA、cuDNN、TensorRT等深度学习框架和工具链。&lt;/p&gt;
&lt;h3 id="22-刷机步骤"&gt;2.2 刷机步骤&lt;/h3&gt;
&lt;h4 id="221-准备工作"&gt;2.2.1 准备工作&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;下载JetPack SDK Manager&lt;/li&gt;
&lt;li&gt;准备USB线缆和电源适配器&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id="222-刷机流程"&gt;2.2.2 刷机流程&lt;/h4&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;下载JetPack SDK Manager&lt;/strong&gt;&lt;/p&gt;</description></item><item><title>探索 Python 的 Typing 库：增强代码健壮性</title><link>https://blog.thinkmoon.cn/post/988-%E6%8E%A2%E7%B4%A2-python-%E7%9A%84-typing-%E5%BA%93%E5%A2%9E%E5%BC%BA%E4%BB%A3%E7%A0%81%E5%81%A5%E5%A3%AE%E6%80%A7/</link><pubDate>Mon, 29 Sep 2025 14:19:00 +0000</pubDate><guid>https://blog.thinkmoon.cn/post/988-%E6%8E%A2%E7%B4%A2-python-%E7%9A%84-typing-%E5%BA%93%E5%A2%9E%E5%BC%BA%E4%BB%A3%E7%A0%81%E5%81%A5%E5%A3%AE%E6%80%A7/</guid><description>&lt;h1 id="探索-python-的-typing-库增强代码健壮性"&gt;探索 Python 的 Typing 库：增强代码健壮性&lt;/h1&gt;
&lt;p&gt;Python 的 &lt;code&gt;typing&lt;/code&gt; 库自 Python 3.5 引入，为动态类型的 Python 带来了静态类型注解功能，使开发者能够编写更健壮、可维护的代码。本文将深入探讨 &lt;code&gt;typing&lt;/code&gt; 模块的主要功能、优势以及实用示例。&lt;/p&gt;
&lt;h2 id="为什么使用类型注解"&gt;为什么使用类型注解？&lt;/h2&gt;
&lt;p&gt;类型注解通过明确声明变量、函数参数和返回值的预期类型，提升了代码的可读性、可维护性和可靠性。它们支持像 &lt;code&gt;mypy&lt;/code&gt; 这样的静态类型检查工具，在运行前捕获潜在错误。此外，类型注解还能增强 IDE 对自动补全和重构的支持，提高开发效率。&lt;/p&gt;
&lt;h2 id="开始使用-typing-库"&gt;开始使用 Typing 库&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;typing&lt;/code&gt; 模块提供了丰富的工具来定义类型注解。以下是一些常用功能的介绍。&lt;/p&gt;
&lt;h3 id="基本类型注解"&gt;基本类型注解&lt;/h3&gt;
&lt;p&gt;类型注解可用于变量、函数参数和返回值，语法简单直观。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;typing&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;List&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Dict&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 变量注解&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;Alice&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;age&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;int&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;30&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 带类型注解的函数&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;greet&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;person&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;你好，&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;person&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;！&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;在此例中，&lt;code&gt;name&lt;/code&gt; 声明为 &lt;code&gt;str&lt;/code&gt; 类型，&lt;code&gt;age&lt;/code&gt; 为 &lt;code&gt;int&lt;/code&gt; 类型，&lt;code&gt;greet&lt;/code&gt; 函数接受一个 &lt;code&gt;str&lt;/code&gt; 参数并返回一个 &lt;code&gt;str&lt;/code&gt;。使用 &lt;code&gt;mypy&lt;/code&gt; 等静态类型检查工具可以确保类型使用正确。&lt;/p&gt;
&lt;h3 id="集合类型的复杂注解"&gt;集合类型的复杂注解&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;typing&lt;/code&gt; 模块支持对列表、字典和元组等集合类型的复杂注解。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;typing&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;List&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Dict&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Tuple&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 整数列表&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;numbers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;List&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;int&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 字符串键和浮点值字典&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;scores&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Dict&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;float&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;Alice&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;95.5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;Bob&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;87.0&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 指定类型的元组&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;point&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Tuple&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;int&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;int&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;原点&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;这些注解清楚地表明了集合内元素的预期类型，减少歧义和潜在错误。&lt;/p&gt;</description></item><item><title>使用CloudFlare反向代理七牛云存储实现SSL自由</title><link>https://blog.thinkmoon.cn/post/985_%E4%BD%BF%E7%94%A8cloudflare%E5%8F%8D%E5%90%91%E4%BB%A3%E7%90%86%E4%B8%83%E7%89%9B%E4%BA%91%E5%AD%98%E5%82%A8%E5%AE%9E%E7%8E%B0ssl%E8%87%AA%E7%94%B1/</link><pubDate>Wed, 19 Mar 2025 14:19:00 +0000</pubDate><guid>https://blog.thinkmoon.cn/post/985_%E4%BD%BF%E7%94%A8cloudflare%E5%8F%8D%E5%90%91%E4%BB%A3%E7%90%86%E4%B8%83%E7%89%9B%E4%BA%91%E5%AD%98%E5%82%A8%E5%AE%9E%E7%8E%B0ssl%E8%87%AA%E7%94%B1/</guid><description>&lt;h1 id="基于cloudflare-workers的七牛云https代理方案"&gt;基于CloudFlare Workers的七牛云HTTPS代理方案&lt;/h1&gt;
&lt;h2 id="一方案背景与核心价值"&gt;一、方案背景与核心价值&lt;/h2&gt;
&lt;h3 id="11-问题场景"&gt;1.1 问题场景&lt;/h3&gt;
&lt;p&gt;七牛云存储作为国内主流对象存储服务，其HTTP直连访问存在两大痛点：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;SSL证书成本&lt;/strong&gt;：自定义域名HTTPS服务需单独购买证书&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;混合内容风险&lt;/strong&gt;：主站HTTPS页面加载HTTP资源触发安全警告&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="12-技术选型"&gt;1.2 技术选型&lt;/h3&gt;
&lt;p&gt;通过CloudFlare Workers实现四大核心能力：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;协议转换层&lt;/strong&gt;：将用户HTTPS请求转换为对七牛HTTP源站的请求&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;动态内容改写&lt;/strong&gt;：实时替换响应中的HTTP资源链接&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;全局缓存加速&lt;/strong&gt;：利用全球CDN节点提升访问速度&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;零运维成本&lt;/strong&gt;：无需维护服务器基础设施&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="二原理说明"&gt;二、原理说明&lt;/h2&gt;
&lt;p&gt;Cloudflare Worker 是一个无服务器计算平台，通过拦截请求并修改响应实现代理。核心思路是：&lt;/p&gt;
&lt;p&gt;将用户 HTTPS 请求转发到原始 HTTP 站点。
修改响应头，强制 HTTPS 协议并修复混合内容问题。&lt;/p&gt;
&lt;h2 id="三操作步骤"&gt;三、操作步骤&lt;/h2&gt;
&lt;h3 id="1-创建-cloudflare-worker"&gt;1. 创建 Cloudflare Worker&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;登录 Cloudflare 控制台 → Workers &amp;amp; Pages → 创建新 Worker。&lt;/li&gt;
&lt;li&gt;进入代码编辑界面。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="2-编写代理脚本"&gt;2. 编写代理脚本&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-javascript" data-lang="javascript"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;addEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;fetch&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;event&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;respondWith&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;handleRequest&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;request&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;handleRequest&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;request&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;// 替换为你的 HTTP 源站地址
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;originUrl&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;http://your-http-site.com&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;url&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;URL&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;// 构建指向 HTTP 源站的新请求
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;newRequest&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;Request&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;originUrl&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;pathname&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;search&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;headers&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;method&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;method&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;body&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;body&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;});&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;// 发送请求并获取响应
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kr"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;newRequest&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;// 修改响应头强制 HTTPS
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;modifiedHeaders&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;Headers&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;modifiedHeaders&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;Content-Security-Policy&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;upgrade-insecure-requests&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;modifiedHeaders&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;delete&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;Content-Security-Policy-Report-Only&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;// 返回处理后的响应
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;Response&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;body&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;status&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;status&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;headers&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;modifiedHeaders&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;});&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="3-部署并配置路由"&gt;3. 部署并配置路由&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;点击 Deploy 部署 Worker。&lt;/li&gt;
&lt;li&gt;在 Worker 设置中绑定自定义域名（如 &lt;a href="https://proxy.your-domain.com"&gt;https://proxy.your-domain.com&lt;/a&gt; ）。&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id="4-调整-ssltls-模式"&gt;4. 调整 SSL/TLS 模式&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;进入 Cloudflare 域名控制台 → SSL/TLS → 概述。&lt;/li&gt;
&lt;li&gt;选择 Flexible 模式（允许 Cloudflare 通过 HTTPS 连接用户，但到源站使用 HTTP）。&lt;/li&gt;
&lt;/ol&gt;</description></item><item><title>stabilityai/stable-diffusion-3-medium 试用体验</title><link>https://blog.thinkmoon.cn/post/983_stabilityai_stable-diffusion-3-medium-%E8%AF%95%E7%94%A8%E4%BD%93%E9%AA%8C/</link><pubDate>Fri, 21 Jun 2024 23:23:30 +0000</pubDate><guid>https://blog.thinkmoon.cn/post/983_stabilityai_stable-diffusion-3-medium-%E8%AF%95%E7%94%A8%E4%BD%93%E9%AA%8C/</guid><description>&lt;blockquote&gt;
&lt;p&gt;在当今的科技领域，人工智能和深度学习技术的发展日新月异。其中，稳定扩散模型（Stable Diffusion Model）作为一种强大的生成模型，在图像生成、视频处理等领域展现出了巨大的潜力。而 ComfyUI 则是一款功能强大的图形用户界面，为用户提供了便捷的操作和可视化的工作流程。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;本文将详细介绍如何在 ComfyUI 中安装和使用稳定扩散模型，并通过实际案例展示其在图像生成方面的应用。无论你是初学者还是有一定经验的开发者，都可以通过本文了解到稳定扩散模型的基本原理和使用方法，从而为你的研究和项目提供有力的支持。&lt;/p&gt;
&lt;h2 id="背景知识-名词解释"&gt;背景知识-名词解释&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;Stable Diffusion&lt;/code&gt;: 是一种强大的人工智能图像生成模型。它的主要功能是根据用户输入的文本描述，生成逼真、富有创意和多样化的图像。用户可以通过输入详细的描述，如主题、场景、颜色、风格、物体的特征等，Stable Diffusion 能够理解这些文本信息，并运用其学习到的知识和算法，生成相应的图像。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;ComfyUI&lt;/code&gt;: 是一个用于生成图像的用户界面。它通常与图像生成模型（如 Stable Diffusion）结合使用，为用户提供了一种更直观、更易于操作的方式来控制和调整图像生成的参数和设置。ComfyUI 允许用户通过图形化的界面，以拖放、选择、输入数值等方式来定制图像生成的各种条件，例如模型选择、提示词权重、采样方法、步数、分辨率等。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;CLIP&lt;/code&gt;（Contrastive Language-Image Pre-Training）是一种多模态预训练神经网络，由OpenAI在2021年发布。它的核心思想是使用大量图像和文本的配对数据进行预训练，以学习图像和文本之间的对齐关系。&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="官方地址"&gt;官方地址&lt;/h2&gt;
&lt;p&gt;&lt;a href="https://huggingface.co/stabilityai/stable-diffusion-3-medium"&gt;https://huggingface.co/stabilityai/stable-diffusion-3-medium&lt;/a&gt;&lt;/p&gt;
&lt;h2 id="安装教程"&gt;安装教程&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;下载模型，我这里先直接下载16位的试试水&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;img src="https://blog.cdn.thinkmoon.cn/2024-06-21/21-39-32" alt="Description"&gt;&lt;/p&gt;
&lt;ol start="2"&gt;
&lt;li&gt;下载comfy UI&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;a href="https://github.com/comfyanonymous/ComfyUI?tab=readme-ov-file#installing"&gt;https://github.com/comfyanonymous/ComfyUI?tab=readme-ov-file#installing&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src="https://blog.cdn.thinkmoon.cn/2024-06-21/22-23-35" alt="Description"&gt;&lt;/p&gt;
&lt;ol start="3"&gt;
&lt;li&gt;解压下载好的 comfy UI 7z包&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;img src="https://blog.cdn.thinkmoon.cn/2024-06-21/22-44-15" alt="Description"&gt;&lt;/p&gt;
&lt;ol start="4"&gt;
&lt;li&gt;运行&lt;code&gt;run_nvidia_gpu.bat&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;出现工作流界面则说明安装成功&lt;/p&gt;
&lt;p&gt;&lt;img src="https://blog.cdn.thinkmoon.cn/2024-06-21/22-45-52" alt="Description"&gt;&lt;/p&gt;
&lt;h2 id="导入checkpoint"&gt;导入checkPoint&lt;/h2&gt;
&lt;p&gt;将下载好的SD模型导入到，ComfyUI的checkpoint文件夹&lt;code&gt;ComfyUI\models\checkpoints&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src="https://blog.cdn.thinkmoon.cn/2024-06-21/22-58-21" alt="Description"&gt;&lt;/p&gt;
&lt;p&gt;当在工作流界面可以选择到下载的模型的时候，则说明导入成功&lt;/p&gt;
&lt;p&gt;&lt;img src="https://blog.cdn.thinkmoon.cn/2024-06-21/22-59-06" alt="Description"&gt;&lt;/p&gt;
&lt;h2 id="导入工作流"&gt;导入工作流&lt;/h2&gt;
&lt;p&gt;下载SD3官方的3个流程图文件&lt;/p&gt;
&lt;p&gt;&lt;img src="https://blog.cdn.thinkmoon.cn/2024-06-21/22-59-56" alt="Description"&gt;&lt;/p&gt;
&lt;p&gt;点击load选择要导入的流程图&lt;/p&gt;
&lt;p&gt;&lt;img src="https://blog.cdn.thinkmoon.cn/2024-06-21/23-01-32" alt="Description"&gt;&lt;/p&gt;
&lt;p&gt;流程图文件解释&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;sd3_medium_example_workflow_basic.json &amp;ndash; 基础工作流&lt;/li&gt;
&lt;li&gt;sd3_medium_example_workflow_multi_prompt.json &amp;ndash; 多prompt工作流&lt;/li&gt;
&lt;li&gt;sd3_medium_example_workflow_upscaling.json &amp;ndash; 带图片放大的工作流&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="配置流程图"&gt;配置流程图&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;切换模型，切换到下载的模型&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;img src="https://blog.cdn.thinkmoon.cn/2024-06-21/23-09-59" alt="Description"&gt;&lt;/p&gt;
&lt;ol start="2"&gt;
&lt;li&gt;删除原Clip节点，从模型节点中拖出clip指向prompt。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;因为我上面下载的模型自带Clip能力，从模型中引入即可。&lt;/p&gt;
&lt;p&gt;&lt;img src="https://blog.cdn.thinkmoon.cn/2024-06-21/23-11-35" alt="Description"&gt;&lt;/p&gt;
&lt;h2 id="运行sd3模型"&gt;运行SD3模型&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;输入prompt&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;img src="https://blog.cdn.thinkmoon.cn/2024-06-21/23-05-08" alt="Description"&gt;&lt;/p&gt;
&lt;ol start="2"&gt;
&lt;li&gt;运行生图队列&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;img src="https://blog.cdn.thinkmoon.cn/2024-06-21/23-05-59" alt="Description"&gt;&lt;/p&gt;</description></item><item><title>Python 虚拟环境与包管理完整指南</title><link>https://blog.thinkmoon.cn/post/980_%E5%9C%A8-windows-%E7%B3%BB%E7%BB%9F%E4%B8%AD%E9%85%8D%E7%BD%AE-pip-%E6%B8%85%E5%8D%8E%E6%BA%90/</link><pubDate>Fri, 07 Jun 2024 22:15:03 +0000</pubDate><guid>https://blog.thinkmoon.cn/post/980_%E5%9C%A8-windows-%E7%B3%BB%E7%BB%9F%E4%B8%AD%E9%85%8D%E7%BD%AE-pip-%E6%B8%85%E5%8D%8E%E6%BA%90/</guid><description>&lt;blockquote&gt;
&lt;p&gt;在使用 Python 进行开发时，我们需要处理包管理、依赖隔离等问题。本文将介绍如何在 Windows 系统中配置 pip 源、创建虚拟环境，以及管理项目依赖，帮助你高效地进行 Python 开发。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id="第一部分配置-pip-清华源"&gt;第一部分：配置 pip 清华源&lt;/h2&gt;
&lt;h3 id="为什么要配置镜像源"&gt;为什么要配置镜像源？&lt;/h3&gt;
&lt;p&gt;在使用 Python 进行开发时，我们经常会用到 pip 来安装各种包。但有时默认的源下载速度可能较慢，这时候配置国内的镜像源就很有必要了。&lt;/p&gt;
&lt;h3 id="配置步骤"&gt;配置步骤&lt;/h3&gt;
&lt;h4 id="第一步创建配置文件"&gt;第一步：创建配置文件&lt;/h4&gt;
&lt;p&gt;在你的用户目录下（一般是 C:\Users\你的用户名），可以通过在资源管理器的地址栏输入 &lt;code&gt;%appdata%&lt;/code&gt; 后回车快速打开 appdata 文件夹。创建一个名为 pip 的文件夹，然后在该文件夹内创建一个名为 pip.ini 的文件。&lt;/p&gt;
&lt;h4 id="第二步编辑配置文件"&gt;第二步：编辑配置文件&lt;/h4&gt;
&lt;p&gt;用文本编辑器打开 pip.ini 文件，在其中添加以下内容：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-ini" data-lang="ini"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;[global]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;index-url&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;https://pypi.tuna.tsinghua.edu.cn/simple&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h4 id="第三步验证配置"&gt;第三步：验证配置&lt;/h4&gt;
&lt;p&gt;打开命令提示符，输入 pip install 某个包，观察下载速度是否有所提升。如果配置成功，下载速度应该会比之前快很多。&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="第二部分python-venv-虚拟环境"&gt;第二部分：Python venv 虚拟环境&lt;/h2&gt;
&lt;h3 id="什么是-python-venv"&gt;什么是 Python venv？&lt;/h3&gt;
&lt;p&gt;Python venv 是 Python 标准库中的一个模块，用于创建虚拟环境。虚拟环境是一个独立的 Python 运行环境，它包含了项目所需的 Python 解释器和所有依赖包。通过使用虚拟环境，我们可以在不同的项目中使用不同的依赖版本，从而避免依赖冲突。&lt;/p&gt;
&lt;h3 id="如何创建-python-venv"&gt;如何创建 Python venv？&lt;/h3&gt;
&lt;p&gt;在 Windows 环境下，我们可以使用以下命令创建 Python venv：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;打开命令提示符（CMD）或 PowerShell。&lt;/li&gt;
&lt;li&gt;进入项目目录。&lt;/li&gt;
&lt;li&gt;运行以下命令创建虚拟环境：&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;python -m venv venv
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;blockquote&gt;
&lt;p&gt;其中，venv 是虚拟环境的名称，你可以根据需要修改。&lt;/p&gt;</description></item><item><title>路由器openwrt安装python</title><link>https://blog.thinkmoon.cn/post/979_%E8%B7%AF%E7%94%B1%E5%99%A8openwrt%E5%AE%89%E8%A3%85python/</link><pubDate>Mon, 25 Dec 2023 21:10:14 +0000</pubDate><guid>https://blog.thinkmoon.cn/post/979_%E8%B7%AF%E7%94%B1%E5%99%A8openwrt%E5%AE%89%E8%A3%85python/</guid><description>&lt;p&gt;&lt;img src="https://blog.cdn.thinkmoon.cn/2023-12-18/22-08-33" alt="Description"&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;使用u盘当路由器的系统盘，一不小心碰到它，路由器又挂了。决定把U盘作为挂载盘安装软件&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id="挂载u盘"&gt;挂载U盘&lt;/h2&gt;
&lt;p&gt;&lt;img src="https://blog.cdn.thinkmoon.cn/2023-12-18/22-14-40" alt="Description"&gt;&lt;/p&gt;
&lt;p&gt;启用挂载的设备&lt;/p&gt;
&lt;p&gt;&lt;img src="https://blog.cdn.thinkmoon.cn/2023-12-18/22-15-23" alt="Description"&gt;&lt;/p&gt;
&lt;h2 id="opkg包配置安装目录"&gt;opkg包配置安装目录&lt;/h2&gt;
&lt;p&gt;增加一个opkg安装路径&lt;/p&gt;
&lt;p&gt;&lt;img src="https://blog.cdn.thinkmoon.cn/2023-12-18/22-16-29" alt="Description"&gt;&lt;/p&gt;
&lt;h2 id="配置path路径"&gt;配置PATH路径&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;export&lt;/span&gt; &lt;span class="nv"&gt;PATH&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;$PATH&lt;/span&gt;:/mnt/sda/opkg/usr//bin
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;export PATH=$PATH:/mnt/sda/opkg/usr/bin&amp;#39;&lt;/span&gt; &amp;gt;&amp;gt; /etc/profile
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="指定路径安装okpg包"&gt;指定路径安装okpg包&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;opkg update
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;opkg -d usb install python3 
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;opkg -d usb install python3-pip
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;请注意：&lt;code&gt;-d usb&lt;/code&gt;为必需的，否则依旧会安装到根目录&lt;/p&gt;
&lt;p&gt;&lt;img src="https://blog.cdn.thinkmoon.cn/2023-12-18/22-21-15" alt="Description"&gt;&lt;/p&gt;
&lt;p&gt;打开对应目录可以看到，已经多了一个opkg目录&lt;/p&gt;
&lt;p&gt;&lt;img src="https://blog.cdn.thinkmoon.cn/2023-12-18/22-22-02" alt="Description"&gt;&lt;/p&gt;
&lt;p&gt;输出python3，测试是否安装成功&lt;/p&gt;
&lt;h2 id="安装pip"&gt;安装pip&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;python -m pip install -U --force pip
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;img src="https://blog.cdn.thinkmoon.cn/2023-12-18/22-41-39" alt="Description"&gt;&lt;/p&gt;
&lt;h2 id="安装python依赖"&gt;安装python依赖&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;pip3 install requests
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;img src="https://blog.cdn.thinkmoon.cn/2023-12-18/22-45-57" alt="Description"&gt;&lt;/p&gt;
&lt;h2 id="换国内源"&gt;换国内源&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;pip config &lt;span class="nb"&gt;set&lt;/span&gt; global.index-url https://pypi.tuna.tsinghua.edu.cn/simple
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="后记"&gt;后记&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;现在换成挂载overlays了，直接在系统盘上面再套一层，避免u盘掉线后的系统启动不了的情况&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id="参考文章"&gt;参考文章&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href="https://openwrt.org/zh/docs/techref/opkg"&gt;OPKG 软件包管理&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;</description></item><item><title>游戏设计模式之组件模式</title><link>https://blog.thinkmoon.cn/post/978_%E6%B8%B8%E6%88%8F%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8B%E7%BB%84%E4%BB%B6%E6%A8%A1%E5%BC%8F/</link><pubDate>Sun, 04 Jun 2023 16:20:04 +0000</pubDate><guid>https://blog.thinkmoon.cn/post/978_%E6%B8%B8%E6%88%8F%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8B%E7%BB%84%E4%BB%B6%E6%A8%A1%E5%BC%8F/</guid><description>&lt;p&gt;&lt;img src="https://blog.cdn.thinkmoon.cn/2023-06-04/16-19-37" alt="组件模式"&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;前言&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;我第一次接触到组件模式是在饥荒的mod开发过程中了解到的。在组件模式下，一系列的能力（如灯光，buff）将会被抽象为组件，组件内部实现这种能力。不同的对象都可以使用这一个组件，提高代码的复用性，避免耦合性过强。&lt;/p&gt;
&lt;h2 id="什么是组件模式"&gt;什么是组件模式&lt;/h2&gt;
&lt;p&gt;允许一个单一的实体跨越多个不同域而不会导致耦合。&lt;/p&gt;
&lt;h2 id="为什么需要组件模式"&gt;为什么需要组件模式&lt;/h2&gt;
&lt;p&gt;组件模式的目的是减少代码耦合性，提高代码复用率。&lt;/p&gt;
&lt;p&gt;可以拿饭店菜单打比方。如果每个实体是一个类，那就只能订套餐。 我们需要为每种可能的组合定义各自的类。 为了满足每位用户，我们需要十几种套餐。&lt;/p&gt;
&lt;p&gt;组件是照单点菜——每位顾客都可以选他们想要的，菜单记录可选的菜式。&lt;/p&gt;
&lt;h2 id="参考文档"&gt;参考文档&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href="https://gpp.tkchu.me/component.html"&gt;组件模式&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://zhuanlan.zhihu.com/p/494412571"&gt;【游戏编程模式】组件模式&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;</description></item><item><title>nestjs配置swagger教程</title><link>https://blog.thinkmoon.cn/post/976_nestjs%E9%85%8D%E7%BD%AEswagger%E6%95%99%E7%A8%8B/</link><pubDate>Fri, 16 Dec 2022 20:58:16 +0000</pubDate><guid>https://blog.thinkmoon.cn/post/976_nestjs%E9%85%8D%E7%BD%AEswagger%E6%95%99%E7%A8%8B/</guid><description>&lt;blockquote&gt;
&lt;p&gt;本文记录如何在nestjs框架下配置swagger。OpenAPI是一个与语言无关的RESTful API定义说明，Nest提供了一个专有的模块来利用装饰器生成类似声明。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id="安装"&gt;安装&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;npm install --save @nestjs/swagger swagger-ui-express
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="引导"&gt;引导&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-typescript" data-lang="typescript"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;NestFactory&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="kr"&gt;from&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;@nestjs/core&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;AppModule&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="kr"&gt;from&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;./modules/app.module&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Logger&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="kr"&gt;from&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;@nestjs/common&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;SwaggerModule&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;DocumentBuilder&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="kr"&gt;from&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;@nestjs/swagger&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;bootstrap() {&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;app&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;NestFactory&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;AppModule&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;options&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;DocumentBuilder&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;setTitle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;api-collect&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;setDescription&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;API文档&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;setVersion&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;1.0&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;build&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;SwaggerModule&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;createDocument&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;options&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;SwaggerModule&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;setup&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;doc&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;listen&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3001&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;bootstrap&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nx"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;Logger&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;启动成功&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;这里主要引入了两个模块，&lt;code&gt;SwaggerModule&lt;/code&gt;和&lt;code&gt;DocumentBuilder&lt;/code&gt;。其中&lt;code&gt;DocumentBuilder&lt;/code&gt;建立一个遵循OpenAPI 标准的基础文档。它提供了不同的方法来配置类似标题、描述、版本等信息属性。&lt;/p&gt;
&lt;p&gt;（SwaggerModule#createDocument()方法返回)是一个遵循OpenAPI文档的序列化对象。除了HTTP，你也可以以JSON/YAML文件格式保存和使用它。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;SwaggerModule.setup(&amp;lsquo;api&amp;rsquo;, app, document);&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;此行代码标记你的文档最终挂载的路径。&lt;/p&gt;
&lt;h2 id="运行体验"&gt;运行体验&lt;/h2&gt;
&lt;p&gt;&lt;img src="https://blog.cdn.thinkmoon.cn/2022-12-16/20-41-35" alt="nestjs swagger"&gt;&lt;/p&gt;
&lt;p&gt;此时我们就可以看到熟悉的swagger界面啦。&lt;/p&gt;
&lt;h2 id="类型和参数"&gt;类型和参数&lt;/h2&gt;
&lt;p&gt;如果我们想设置swagger对应的参数请求类型，那么也可以使用它的反射来创建响应模型。&lt;/p&gt;
&lt;p&gt;使用ts声明一个参数请求dto&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-typescript" data-lang="typescript"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;export&lt;/span&gt; &lt;span class="kr"&gt;class&lt;/span&gt; &lt;span class="nx"&gt;ParamsDto&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;params?&lt;/span&gt;: &lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;[];&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;接口上声明对应的入参&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-typescript" data-lang="typescript"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Body&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Controller&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Post&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Query&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="kr"&gt;from&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;@nestjs/common&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;SqlService&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="kr"&gt;from&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;../service/sql.service&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;CodeDto&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="kr"&gt;from&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;../entity/code.dto&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;ParamsDto&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="kr"&gt;from&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;../entity/params.dto&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;PathDto&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="kr"&gt;from&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;../entity/path.dto&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;@Controller&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;api-collect&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;export&lt;/span&gt; &lt;span class="kr"&gt;class&lt;/span&gt; &lt;span class="nx"&gt;SqlController&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kr"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kr"&gt;private&lt;/span&gt; &lt;span class="kr"&gt;readonly&lt;/span&gt; &lt;span class="nx"&gt;sqlService&lt;/span&gt;: &lt;span class="kt"&gt;SqlService&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kd"&gt;@Post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;/execute-by-path&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;executeByPath&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;@Query&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="nx"&gt;pathDto&lt;/span&gt;: &lt;span class="kt"&gt;PathDto&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kd"&gt;@Body&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="nx"&gt;paramsDto&lt;/span&gt;: &lt;span class="kt"&gt;ParamsDto&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;sqlService&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;executeSqlByPath&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;pathDto&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;path&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;paramsDto&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;params&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kd"&gt;@Post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;/execute-by-code&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;executeByCode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;@Query&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="nx"&gt;codeDto&lt;/span&gt;: &lt;span class="kt"&gt;CodeDto&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kd"&gt;@Body&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="nx"&gt;paramsDto&lt;/span&gt;: &lt;span class="kt"&gt;ParamsDto&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;sqlService&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;executeSqlByCode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;codeDto&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;code&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;paramsDto&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;params&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;激活swagger ts类型扫描插件（Nestjs框架自带）&lt;/p&gt;</description></item><item><title>Vue3使用customRef()主动触发响应更新</title><link>https://blog.thinkmoon.cn/post/975_vue3%E4%BD%BF%E7%94%A8customref__%E4%B8%BB%E5%8A%A8%E8%A7%A6%E5%8F%91%E5%93%8D%E5%BA%94%E6%9B%B4%E6%96%B0/</link><pubDate>Mon, 12 Dec 2022 22:11:09 +0000</pubDate><guid>https://blog.thinkmoon.cn/post/975_vue3%E4%BD%BF%E7%94%A8customref__%E4%B8%BB%E5%8A%A8%E8%A7%A6%E5%8F%91%E5%93%8D%E5%BA%94%E6%9B%B4%E6%96%B0/</guid><description>&lt;p&gt;&lt;img src="https://blog.cdn.thinkmoon.cn/2022-12-12/21-07-40" alt="customRef()"&gt;&lt;/p&gt;
&lt;h2 id="前言"&gt;前言&lt;/h2&gt;
&lt;p&gt;在vue3中（尤其是setup语法）vue框架会自动处理事件响应。但是假设有个场景，我们实现了一个数据结构，只要触发对应操作时，就刷新视图。这个问题在选项式API有个公共API，提供强制刷新能力，那就是&lt;code&gt;$forceUpdate()&lt;/code&gt;。&lt;code&gt;$forceUpdate()&lt;/code&gt;会全量刷新，而且组合式API不支持该方法，这个时候如果我们想主动触发视图更新，可以使用Vue3提供的&lt;code&gt;customRef()&lt;/code&gt;自定义一个ref。&lt;/p&gt;
&lt;h2 id="介绍"&gt;介绍&lt;/h2&gt;
&lt;p&gt;customRef()，创建一个自定义的 ref，显式声明对其依赖追踪和更新触发的控制方式。&lt;/p&gt;
&lt;p&gt;形如&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-typescript" data-lang="typescript"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;customRef&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;T&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;(&lt;/span&gt;&lt;span class="nx"&gt;factory&lt;/span&gt;: &lt;span class="kt"&gt;CustomRefFactory&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;T&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;)&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Ref&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;T&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;CustomRefFactory&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;T&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;track&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;trigger&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kr"&gt;get&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;T&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kr"&gt;set&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;: &lt;span class="kt"&gt;T&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;其中，track函数告诉框架这是一个需要追踪变更的变量，一般在get里面调用。trigger则是数据变化时调用，用以通知框架，该变量已发生变化触发视图更新。&lt;/p&gt;
&lt;h2 id="示例"&gt;示例&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;实现一个日志展示功能，当日志增加时，触发视图更新&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;img src="https://blog.cdn.thinkmoon.cn/2022-12-12/21-53-09" alt="Description"&gt;&lt;/p&gt;
&lt;p&gt;这是一个简陋的日志系统，永远展示最后十条日志(截图少了个.slice(-10))。而且我在程序最后加了个定时器，每隔一秒定时增加一条日志。&lt;/p&gt;
&lt;p&gt;从图中的结果可以发现，对应的数据变化并未相应的渲染在视图上。这个使用我们就需要customRef实现一个自定义的ref，当日志增加时主动触发trigger通知视图更新&lt;/p&gt;
&lt;h2 id="使用customref改造"&gt;使用customRef改造&lt;/h2&gt;
&lt;p&gt;&lt;img src="https://blog.cdn.thinkmoon.cn/2022-12-12/22-03-09" alt="Description"&gt;&lt;/p&gt;
&lt;h2 id="总结"&gt;总结&lt;/h2&gt;
&lt;p&gt;使用customRef的好处就是可以把trigger暴露到外部，直接触发trigger就会触发刷新，实现按需加载的效果。&lt;/p&gt;</description></item><item><title>Google Adsence广告拦截收入挽回</title><link>https://blog.thinkmoon.cn/post/970_google-adsence%E5%B9%BF%E5%91%8A%E6%8B%A6%E6%88%AA%E6%94%B6%E5%85%A5%E6%8C%BD%E5%9B%9E/</link><pubDate>Mon, 12 Dec 2022 20:54:51 +0000</pubDate><guid>https://blog.thinkmoon.cn/post/970_google-adsence%E5%B9%BF%E5%91%8A%E6%8B%A6%E6%88%AA%E6%94%B6%E5%85%A5%E6%8C%BD%E5%9B%9E/</guid><description>&lt;blockquote&gt;
&lt;p&gt;前言：很久未关注Google Adsence了，发现谷歌出了个《Google Adsence广告拦截收入挽回》功能。该功能通过提醒用户允许在您的网站上展示广告，挽回您可能会因用户启用了广告拦截器而损失的收入。这边主要介绍该功能的配置流程和使用效果。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id="自研到放弃"&gt;自研到放弃&lt;/h2&gt;
&lt;p&gt;本站最开始的博客系统，使用的是自研的防广告拦截功能。当遇到广告被拦截时，直接跳转至特定的页面，阻断用户访问。具体技术细节见&lt;a href="https://blog.thinkmoon.cn/post/816/"&gt;《让你的网站防广告屏蔽》&lt;/a&gt;。但该方案对用户侵入性过强，且有绑架用户的嫌疑。后在权衡再三的情况之下，便将其放弃。&lt;/p&gt;
&lt;h2 id="google-adsence广告拦截收入挽回"&gt;Google Adsence广告拦截收入挽回&lt;/h2&gt;
&lt;h3 id="开通流程"&gt;开通流程&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;进入隐私权和消息菜单&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;img src="https://blog.cdn.thinkmoon.cn/2022-12-11/23-38-27" alt="隐私权和消息菜单"&gt;&lt;/p&gt;
&lt;ol start="2"&gt;
&lt;li&gt;选择广告拦截收入挽回&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;img src="https://blog.cdn.thinkmoon.cn/2022-12-11/23-39-29" alt="广告拦截收入挽回"&gt;&lt;/p&gt;
&lt;ol start="3"&gt;
&lt;li&gt;创建一个新的挽回消息&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;img src="https://blog.cdn.thinkmoon.cn/2022-12-11/23-40-26" alt="创建一个新的挽回消息"&gt;&lt;/p&gt;
&lt;ol start="4"&gt;
&lt;li&gt;设置文本和样式&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;img src="https://blog.cdn.thinkmoon.cn/2022-12-11/23-41-57" alt="设置文本和样式"&gt;&lt;/p&gt;
&lt;h3 id="展示效果"&gt;展示效果&lt;/h3&gt;
&lt;p&gt;再来看看开启广告拦截后的显示效果&lt;/p&gt;
&lt;p&gt;&lt;img src="https://blog.cdn.thinkmoon.cn/2022-12-11/23-43-03" alt="挽回消息"&gt;&lt;/p&gt;
&lt;p&gt;这里用户可以进行两个操作&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;叉掉弹窗，继续访问（无影响）&lt;/li&gt;
&lt;li&gt;点击允许广告，若用户使用的chrome广告插件adblock等，则会自动开启广告&lt;/li&gt;
&lt;/ol&gt;
&lt;blockquote&gt;
&lt;p&gt;tips: 自动开启广告需要进行如下设置
&lt;img src="https://blog.cdn.thinkmoon.cn/2022-12-11/23-46-27" alt="自动开启广告"&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id="总结"&gt;总结&lt;/h2&gt;
&lt;p&gt;Google Adsence广告拦截收入挽回功能，是一种非破坏的，友好挽回方式。如果用户实在不愿意接受广告，则可关闭弹窗继续访问。但若经过挽回后，用户愿意接受广告，则广告收入将会获得一定的提高，是一个两全其美的办法。&lt;/p&gt;</description></item><item><title>如何理解Promise</title><link>https://blog.thinkmoon.cn/post/956_%E5%A6%82%E4%BD%95%E7%90%86%E8%A7%A3promise/</link><pubDate>Fri, 09 Dec 2022 21:35:49 +0000</pubDate><guid>https://blog.thinkmoon.cn/post/956_%E5%A6%82%E4%BD%95%E7%90%86%E8%A7%A3promise/</guid><description>&lt;blockquote&gt;
&lt;p&gt;Promise是啥？异步函数？对象？怎么用才更自信？如何理解更好的理解Promise？本文将分享本人对于Promise的一些经验与想法。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id="背景知识"&gt;背景知识&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;此段将介绍一些理解本文的背景知识，你可以很轻松愉快的阅读此段。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id="函数是一等公民"&gt;函数是一等公民&lt;/h3&gt;
&lt;p&gt;总所周知，在JavaScript里面，函数是一等公民。你可以用来赋值，传参，回调，包装，作为函数返回值return。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;以下内容援引于&lt;a href="https://github.com/felix-cao/Blog/issues/150"&gt;JavaScript 为什么说函数是一等公民？&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ol&gt;
&lt;li&gt;函数与数字一样可以存储到变量中&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-js" data-lang="js"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;fortyTwo&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;42&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;fortyOne&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;41&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ol start="2"&gt;
&lt;li&gt;函数与数字一样可以存储为数组的一个元素&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-js" data-lang="js"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;nums&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;42&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;41&lt;/span&gt; &lt;span class="p"&gt;}]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ol start="3"&gt;
&lt;li&gt;函数与数字一样可以在使用时直接创建出来&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-js" data-lang="js"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="mi"&gt;42&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;fuction&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;41&lt;/span&gt; &lt;span class="p"&gt;})();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// 83
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ol start="4"&gt;
&lt;li&gt;函数与数字一样可以被传递给另一个函数&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-js" data-lang="js"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;weirdAdd&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="nx"&gt;n&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;fun&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;n&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;fun&lt;/span&gt;&lt;span class="p"&gt;()}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;weirdAdd&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;42&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;41&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ol start="5"&gt;
&lt;li&gt;函数与数字一样可以被另一个函数返回&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-js" data-lang="js"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;add&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;num1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;42&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;num2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;num1&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;num2&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;fun&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;add&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;fun&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;41&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// 83
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;函数就是变量，变量可以存放函数。就是玩~&lt;/p&gt;
&lt;h2 id="链式调用"&gt;链式调用&lt;/h2&gt;
&lt;p&gt;由于函数可以作为对象的属性值，那我们访问形如&lt;code&gt;a.b&lt;/code&gt;时就相当与访问到了一个函数体。那么，给它再加上&lt;code&gt;()&lt;/code&gt;不就执行了么，比如图：&lt;code&gt;a.b()&lt;/code&gt;;再拓展一下，如果这个函数又返回了一个同样的对象，那是不是可以继续执行下去了呢？比如: a.b().c().d()；这操作，实属放飞自我了。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-js" data-lang="js"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;Person&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{};&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;Person&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;prototype&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;setAge&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;age&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;age&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;age&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;Person&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;prototype&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;setWeight&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;weight&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;weight&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;weight&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;Person&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;prototype&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;get&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(){&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="sb"&gt;`{age: &lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;age&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sb"&gt;, weight: &lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;weight&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sb"&gt;}`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;person&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;Person&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;des&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;person&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;setAge&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;setWeight&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;get&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;des&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="js的事件循环"&gt;js的事件循环&lt;/h3&gt;
&lt;p&gt;详见&lt;a href="https://blog.thinkmoon.cn/post/907/"&gt;js事件循环&amp;ndash;指尖魔法屋&lt;/a&gt;&lt;/p&gt;
&lt;h3 id="promise的用法"&gt;promise的用法&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;Promise 对象用于表示一个异步操作的最终完成（或失败）及其结果值。&amp;mdash;来自《MDN》&lt;/p&gt;
&lt;/blockquote&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-js" data-lang="js"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;myPromise&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;reject&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;reject&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;myPromise&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;handleResolvedA&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;handleRejectedA&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="我们要如何理解promise"&gt;我们要如何理解promise&lt;/h2&gt;
&lt;p&gt;从实现角度，我们可以这样理解。首先Promise是对象，然后呢，这个对象有三个属性一个叫then一个叫catch，最后一个叫做finally。构造函数会传递两个参数（resolve,reject)。这两个参数本身是个封装的函数，如果调用resolve，它就执行Promise.then()里面的函数，最后再执行Prmise.finally()。catch反之。&lt;/p&gt;</description></item><item><title>前端模块化</title><link>https://blog.thinkmoon.cn/post/943_%E5%89%8D%E7%AB%AF%E6%A8%A1%E5%9D%97%E5%8C%96/</link><pubDate>Wed, 15 Jun 2022 00:00:02 +0000</pubDate><guid>https://blog.thinkmoon.cn/post/943_%E5%89%8D%E7%AB%AF%E6%A8%A1%E5%9D%97%E5%8C%96/</guid><description>&lt;h2 id="什么是模块化"&gt;什么是模块化？&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;在程序设计领域，模块就是为完成某一个功能的一段程序或者子程序&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;一个文件可以是一个模块，一个文件夹也可以是一个模块。模块的思想完美的符合了设计模式中的单一职责原则。只做一件事，或者一类事，分清任务的边界。&lt;/p&gt;
&lt;h2 id="为什么需要模块化"&gt;为什么需要模块化？&lt;/h2&gt;
&lt;p&gt;模块化的目的是将任务细分，在现阶段的软件工程阶段，模块化的方式可以将一个大任务分给不同的人或组织，每个人所负责的模块相对独立而又互为依存关系。而在开源领域和工程复用阶段，模块化可以让我们更方便的站在人民群众的肩膀上，众人拾薪柴火高。使我们可以更多的关注业务逻辑，而不用过分在意实现细节。&lt;/p&gt;
&lt;h2 id="现阶段前端有哪些模块化方式"&gt;现阶段前端有哪些模块化方式？&lt;/h2&gt;
&lt;p&gt;现阶段前端模块化规范有这几种，AMD（Asynchronous Module Definition，CMD（Common Module Definition），CommonJs，Es6 Moduel；&lt;/p&gt;
&lt;h4 id="amdrequirejs"&gt;AMD(require.js)&lt;/h4&gt;
&lt;p&gt;AMD规范如其全名一致，异步模块定义。是require.js 在推广过程中对模块化定义的规范产出的。它的主要思想是前置依赖，让依赖先加载和执行，然后再之后后面的语句。所有依赖这个模块的语句，都定义在一个回调函数中，等到加载完成之后，才会运行这个回调函数。&lt;/p&gt;
&lt;h4 id="cmdseajs"&gt;CMD(sea.js)&lt;/h4&gt;
&lt;p&gt;CMD与AMD规范不一样，AMD是一种与预加载的方式，否管你有没有用到，先把依赖加载进来执行了再说。而CMD是按需依赖的形式，你先运行把，运行到哪里了缺啥你再告诉我，我给你按需依赖。&lt;/p&gt;
&lt;h4 id="commonjs"&gt;Commonjs&lt;/h4&gt;
&lt;p&gt;CommonJs，运行时加载，理论上来说，这个规范一般都是用于服务端的node环境，与前端可能相关性不大，但是作为Js的模块化规范的几大巨头之一，我们也应该了解其思想和实现逻辑。CommonJs模块都是对象，先读取加载整个模块，生成一个对象，然后再从这个对象上面读取方法。由于它是读取后深拷贝（对值的拷贝）这个时候你再进行模块内部变量的改变，是不会影响原依赖模块的使用。CommonJs是同步加载的，一般同步就意味着等待，而有效等待的前提就需要良好的运行环境，这在浏览器上变换莫测的网络环境显然是没法满足的，一个404的js，就造成页面的长时间等待。所以这个规范一般被用作服务端node环境。&lt;/p&gt;
&lt;h4 id="es6-module"&gt;ES6 module&lt;/h4&gt;
&lt;p&gt;在我学前端的心路历程中，但凡跟ES6扯上关系的，总得带点牛逼气息，ES6 module也是如此，它是从语言层面定义的模块化解决方案。ES6的模块不是对象，&lt;code&gt;import&lt;/code&gt;命令会被 JavaScript 引擎静态分析，在编译时就引入模块代码，而不是在代码运行时加载，所以&lt;strong&gt;无法实现条件加载&lt;/strong&gt;。也正因为这个，使得静态分析成为可能。&lt;/p&gt;
&lt;h2 id="我该用哪种模块化方式"&gt;我该用哪种模块化方式？&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;答：当然是最牛逼的&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;理想上，我们应该全部使用ES6 module这种牛逼的方式。但是理想与现实总是存在着略微的差距，虽然我们平常写Vue组件，ES6 module 用得是肆无忌惮，风生水起。但这并不意味着我们现在生产环境上用的就是这个模式，所见有时并非所得。一方面并非所有的浏览器都能够支持ES6 module，另一方面则是由于，现如今磅礴的前端生态环境，巨额的嵌套引用入会导致额外的网络往返，在生产环境中发布未打包的 ESM 仍然效率低下（即使使用 HTTP/2）。实际上当我们run build时，聪明的打包器帮我们完成一系列操作，tree-shaking、懒加载和 chunk 分割（以获得更好的缓存），让我们以最淳朴的形式表现于浏览器，当真是反哺归真。&lt;/p&gt;
&lt;h2 id="参考文档"&gt;参考文档&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href="https://vitejs.bootcss.com/guide/why.html"&gt;为什么选 Vite&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href="https://github.com/zgfang1993/blog/issues/29"&gt;前端模块化&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href="https://baike.baidu.com/item/%E6%A8%A1%E5%9D%97/437198"&gt;模块设计术语&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;</description></item><item><title>在Colab上运行DeepfaceLab训练模型</title><link>https://blog.thinkmoon.cn/post/949_%E5%9C%A8colab%E4%B8%8A%E8%BF%90%E8%A1%8Cdeepfacelab%E8%AE%AD%E7%BB%83%E6%A8%A1%E5%9E%8B/</link><pubDate>Tue, 14 Jun 2022 23:59:41 +0000</pubDate><guid>https://blog.thinkmoon.cn/post/949_%E5%9C%A8colab%E4%B8%8A%E8%BF%90%E8%A1%8Cdeepfacelab%E8%AE%AD%E7%BB%83%E6%A8%A1%E5%9E%8B/</guid><description>&lt;h2 id="环境"&gt;环境&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;Colab：https://colab.research.google.com/&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="利用开源的deepfacelab_colab"&gt;利用开源的DeepFaceLab_Colab&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;地址&lt;a href="https://github.com/dream80/DeepFaceLab_Colab"&gt;DeepFaceLab_Colab&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id="打开最新版本v5"&gt;打开最新版本V5&lt;/h2&gt;
&lt;p&gt;&lt;a href="https://github.com/dream80/DeepFaceLab_Colab/blob/master/DeepFaceLab_Colab_V5.ipynb"&gt;DeepFaceLab_Colab_V5.ipynb&lt;/a&gt;&lt;/p&gt;
&lt;h2 id="操作步骤"&gt;操作步骤&lt;/h2&gt;
&lt;h3 id="1-挂载谷歌云盘"&gt;1. 挂载谷歌云盘&lt;/h3&gt;
&lt;p&gt;运行第一步挂载云盘命令，会弹出谷歌云盘授权窗口，点击允许。&lt;/p&gt;
&lt;p&gt;&lt;img src="https://blog.cdn.thinkmoon.cn/2022-07-09/16-20-55" alt="挂载谷歌云盘"&gt;&lt;/p&gt;
&lt;h3 id="2-初始化项目"&gt;2. 初始化项目&lt;/h3&gt;
&lt;p&gt;该命令会在你的谷歌云盘上创建一个DeepFaceLab的文件夹，如果你使用的tensorflow 1还会安装cuda 10&lt;/p&gt;
&lt;p&gt;&lt;img src="https://blog.cdn.thinkmoon.cn/2022-07-09/16-27-23" alt="初始化项目"&gt;&lt;/p&gt;
&lt;h3 id="3-准备素材"&gt;3. 准备素材&lt;/h3&gt;
&lt;p&gt;&lt;img src="https://blog.cdn.thinkmoon.cn/2022-07-09/16-28-59" alt="准备素材"&gt;&lt;/p&gt;
&lt;p&gt;该命令会从demo仓库下载一份示例数据。同时你可以指定上传文件，覆盖对应的素材。&lt;/p&gt;
&lt;h3 id="4-安装软件"&gt;4. 安装软件&lt;/h3&gt;
&lt;p&gt;&lt;img src="https://blog.cdn.thinkmoon.cn/2022-07-09/16-31-11" alt="安装软件"&gt;&lt;/p&gt;
&lt;p&gt;我这里安装的是最新版本，静候安装完成。&lt;/p&gt;
&lt;p&gt;&lt;img src="https://blog.cdn.thinkmoon.cn/2022-07-09/16-32-43" alt="安装失败"&gt;&lt;/p&gt;
&lt;p&gt;然后我第一次安装失败了。莫慌，这里只需要重新点一下“重启运行时”重新运行即可。&lt;/p&gt;
&lt;p&gt;&lt;img src="https://blog.cdn.thinkmoon.cn/2022-07-09/16-34-00" alt="重启运行时"&gt;&lt;/p&gt;
&lt;p&gt;重启时这里会发生变化&lt;/p&gt;
&lt;p&gt;&lt;img src="https://blog.cdn.thinkmoon.cn/2022-07-09/16-34-49" alt="重启初始化"&gt;&lt;/p&gt;
&lt;p&gt;重新执行&lt;code&gt;初始化项目&lt;/code&gt;,&lt;code&gt;安装软件&lt;/code&gt;这两个命令操作&lt;/p&gt;
&lt;h3 id="提取源面部和目标面部"&gt;提取源面部和目标面部&lt;/h3&gt;
&lt;p&gt;&lt;img src="https://blog.cdn.thinkmoon.cn/2022-07-09/16-38-53" alt="提取面部"&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src="https://blog.cdn.thinkmoon.cn/2022-07-09/16-42-11" alt="目标抽取"&gt;&lt;/p&gt;
&lt;h3 id="开始训练"&gt;开始训练&lt;/h3&gt;
&lt;p&gt;&lt;img src="https://blog.cdn.thinkmoon.cn/2022-07-09/16-43-26" alt="开始训练"&gt;&lt;/p&gt;
&lt;h2 id="注意事项"&gt;注意事项&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;colab上面使用的是linux平台，linux平台拥有更好的合成效果&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;训练时，可以直接在谷歌云盘&lt;code&gt;workspace/model&lt;/code&gt;中查看最新的训练预览效果。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;如果挂载的云盘上面已经安装了deepface的时候，可以修改初始化代码，如下：&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;blockquote&gt;
&lt;p&gt;一键训练&lt;/p&gt;
&lt;/blockquote&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;! /opt/bin/nvidia-smi
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;from google.colab import drive
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;drive.mount&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;/content/drive&amp;#39;&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;import os 
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nv"&gt;root&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;/content/drive/MyDrive/&amp;#34;&lt;/span&gt; &lt;span class="c1"&gt;#@param {type:&amp;#34;string&amp;#34;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;%cd &lt;span class="nv"&gt;$root&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nv"&gt;deepfacelab&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;os.path.join&lt;span class="o"&gt;(&lt;/span&gt;root,&lt;span class="s2"&gt;&amp;#34;DeepFaceLab&amp;#34;&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nv"&gt;workspace&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;os.path.join&lt;span class="o"&gt;(&lt;/span&gt;deepfacelab,&lt;span class="s2"&gt;&amp;#34;workspace&amp;#34;&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nv"&gt;deepfacelab_cloab&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;os.path.join&lt;span class="o"&gt;(&lt;/span&gt;deepfacelab,&lt;span class="s2"&gt;&amp;#34;DeepFaceLab_Colab&amp;#34;&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;#@title 训练模型&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nv"&gt;Model&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;SAEHD&amp;#34;&lt;/span&gt; &lt;span class="c1"&gt;#@param [&amp;#34;SAEHD&amp;#34;,&amp;#34;AMP&amp;#34;,&amp;#34;Quick96&amp;#34;,&amp;#34;XSeg&amp;#34;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;%cd &lt;span class="nv"&gt;$deepfacelab_cloab&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;!pip install -r requirements-colab.txt 
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nv"&gt;cmd&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;main.py train --training-data-src-dir ../workspace/data_src/aligned --training-data-dst-dir ../workspace/data_dst/aligned --model-dir ../workspace/model --model &amp;#34;&lt;/span&gt;+Model+&lt;span class="s2"&gt;&amp;#34; --no-preview&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;!python &lt;span class="nv"&gt;$cmd&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ol start="3"&gt;
&lt;li&gt;src素材库一定需要各种角度，光线的高清素材，此时训练效果最好&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;img src="https://blog.cdn.thinkmoon.cn/2022-04-10/16-11-03" alt="效果展示"&gt;&lt;/p&gt;</description></item><item><title>使用github Action自动部署博客</title><link>https://blog.thinkmoon.cn/post/950_%E4%BD%BF%E7%94%A8github-action%E8%87%AA%E5%8A%A8%E9%83%A8%E7%BD%B2%E5%8D%9A%E5%AE%A2/</link><pubDate>Tue, 14 Jun 2022 23:59:09 +0000</pubDate><guid>https://blog.thinkmoon.cn/post/950_%E4%BD%BF%E7%94%A8github-action%E8%87%AA%E5%8A%A8%E9%83%A8%E7%BD%B2%E5%8D%9A%E5%AE%A2/</guid><description>&lt;h2 id="背景提要"&gt;背景提要&lt;/h2&gt;
&lt;p&gt;为什么需要它？最开始我使用的是本地编译，然后手动上传的方式，后来发现过于麻烦。尤其是nuxt编译后，产生一大堆ouput文件，手动上传耗时费力。&lt;/p&gt;
&lt;p&gt;再后来我在服务器上，设置了一个定时任务。每晚从github拉取最新的代码，然后在服务器上编译。实行了一段时间，感觉还行。但是，随着服务上的服务越来越多，资源占有越来越大，我发现偶尔会出现编译nuxt时内存溢出的情况（请原谅我1核2G的服务，它已经尽力了）。&lt;/p&gt;
&lt;p&gt;然后便产生了，使用githu action编译目标产物ouput文件，通知服务器自动拉取的想法。那么，说干就干，试试吧！&lt;/p&gt;
&lt;h2 id="创建github-action"&gt;创建GitHub Action&lt;/h2&gt;
&lt;p&gt;使用node.js模板，该模板会自动使用预装node.js的环境。模板中有三种node.js版本，如果保持预留配置，则会三个环境都执行一次。这里我只使用16.x版本（因为跟我服务器版本一致）&lt;/p&gt;
&lt;p&gt;&lt;img src="https://blog.cdn.thinkmoon.cn/2022-04-10/23-08-15" alt="创建GitHub Action"&gt;&lt;/p&gt;
&lt;p&gt;大致流程可分为&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;拉取代码&lt;/li&gt;
&lt;li&gt;安装依赖&lt;/li&gt;
&lt;li&gt;编译output&lt;/li&gt;
&lt;li&gt;归档到特定分支（gh-pages）&lt;/li&gt;
&lt;li&gt;web-hook通知服务器&lt;/li&gt;
&lt;li&gt;服务接收事件，拉取编译后的文件，并重启&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="拉取代码"&gt;拉取代码&lt;/h2&gt;
&lt;p&gt;该步骤由github完成，只需声明使用的分支名称即可&lt;/p&gt;
&lt;h2 id="安装依赖"&gt;安装依赖&lt;/h2&gt;
&lt;p&gt;&lt;img src="https://blog.cdn.thinkmoon.cn/2022-04-10/23-15-32" alt="GitHub Action 安装依赖"&gt;&lt;/p&gt;
&lt;h2 id="编译output"&gt;编译output&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;run&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;yarn run build&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="归档到特定分支gh-page"&gt;归档到特定分支（gh-page）&lt;/h2&gt;
&lt;p&gt;我这儿随便在maket place选一个开源Action（GitHub Pages v3），配置对应的参数，如下：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;- &lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;GitHub Pages v3&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;uses&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;peaceiris/actions-github-pages@v3.1.12&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;with&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;personal_token&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;${{ secrets.ACCESS_TOKEN }}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;publish_dir&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;.output&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;blockquote&gt;
&lt;p&gt;请注意：关于这个personal_token，github有个坑。我也是折腾了两个多小时才总结出来的。生成的personal_token是不能明文存储在yaml文件中的，必须使用变量传递。否则一旦提交的时候，github出于安全考虑会自动静默删除对应person_token。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id="完整配置"&gt;完整配置&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c"&gt;# This workflow will do a clean installation of node dependencies, cache/restore them, build the source code and run tests across different versions of node&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c"&gt;# For more information see: https://help.github.com/actions/language-and-framework-guides/using-nodejs-with-github-actions&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;Node.js CI&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;on&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;push&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;branches&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;main ]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;pull_request&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;branches&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;main ]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;jobs&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;build&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;runs-on&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;ubuntu-latest&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;strategy&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;matrix&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;node-version&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="m"&gt;16.&lt;/span&gt;&lt;span class="l"&gt;x]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# See supported Node.js release schedule at https://nodejs.org/en/about/releases/&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;steps&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;uses&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;actions/checkout@v3&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;Use Node.js ${{ matrix.node-version }}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;uses&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;actions/setup-node@v3&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;run&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;yarn&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;run&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;yarn run build&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;GitHub Pages v3&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;uses&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;peaceiris/actions-github-pages@v3.1.12&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;with&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;personal_token&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;${{ secrets.ACCESS_TOKEN }}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;publish_dir&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;.output&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="触发action"&gt;触发Action&lt;/h2&gt;
&lt;p&gt;提交代码，等待流水线执行。&lt;/p&gt;</description></item></channel></rss>