<?xml version="1.0" encoding="UTF-8"?><?xml-stylesheet href="/rss/rss-styles.xsl" type="text/xsl"?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>謝懿Shine</title><description>Freiheit als Autonomie</description><link>https://www.futseyi.com/</link><language>en-US</language><image><url>https://www.futseyi.com/favicon/favicon.ico</url><title>謝懿Shine</title><link>https://www.futseyi.com/</link></image><appleTouchIcon>https://www.futseyi.com/favicon/apple-touch-icon.png</appleTouchIcon><item><title>2026 最新土耳其（外区）Apple ID 注册教程：低价订阅 ChatGPT Plus 完整指南（附开启跨区 Apple 家庭共享）</title><link>https://www.futseyi.com/blog/turkey-foreign-apple-id-chatgpt-plus-cross-region-family-sharing/</link><guid isPermaLink="true">https://www.futseyi.com/blog/turkey-foreign-apple-id-chatgpt-plus-cross-region-family-sharing/</guid><description>2026 最新土耳其（外区）Apple ID 注册教程，完整记录如何注册土区 Apple ID、切换 App Store 地区、购买土区礼品卡并低价订阅 ChatGPT Plus，同时开启跨区 Apple 家庭共享，用于后续共享 iCloud 等订阅服务。</description><pubDate>Sat, 16 May 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;最近重新折腾了一遍土耳其区 Apple ID，并成功完成：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;注册土耳其 Apple ID&lt;/li&gt;
&lt;li&gt;购买土区苹果礼品卡&lt;/li&gt;
&lt;li&gt;充值 Apple 余额&lt;/li&gt;
&lt;li&gt;通过 iPhone 成功订阅 ChatGPT Plus&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;附：&lt;/strong&gt; 将土区账号加入中国区 Apple 家庭（以备后续共享土区的 iCloud 订阅）&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;整个流程比想象中稳定很多，所以这里把完整过程整理成一篇教程。&lt;/p&gt;
&lt;p&gt;这篇文章主要适用于：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;想低价订阅 GPT Plus 的用户&lt;/li&gt;
&lt;li&gt;想长期维护土区 Apple 生态的用户&lt;/li&gt;
&lt;li&gt;后期可能需要土区 iCloud / Apple One / Arcade 等订阅的用户&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;注意：本文仅记录个人实操过程与经验。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr /&gt;
&lt;h1&gt;为什么选择土耳其区？&lt;/h1&gt;
&lt;p&gt;相比国区、美区等地区：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;土耳其区订阅价格长期偏低&lt;/li&gt;
&lt;li&gt;Apple 礼品卡获取方便&lt;/li&gt;
&lt;li&gt;GPT Plus 可直接通过 App Store 内购&lt;/li&gt;
&lt;li&gt;后期还能扩展更多 Apple 服务&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;而且：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;GPT 登录账号不需要是土区账号。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;真正需要土区的，其实只是：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;用于支付的 Apple ID&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;所以实际使用体验几乎没有影响。你可以继续保留注册好的 GPT 账号。&lt;/p&gt;
&lt;hr /&gt;
&lt;h1&gt;前期准备&lt;/h1&gt;
&lt;p&gt;开始之前，需要准备以下内容。&lt;/p&gt;
&lt;h2&gt;1. 一个全新的邮箱&lt;/h2&gt;
&lt;p&gt;要求：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;没注册过 Apple ID&lt;/li&gt;
&lt;li&gt;推荐 Gmail / Outlook&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h2&gt;2. 一个手机号&lt;/h2&gt;
&lt;p&gt;最好：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;没绑定过 Apple ID&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;但实际上：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;国内手机号也能正常注册&lt;/li&gt;
&lt;li&gt;即便绑定过 Apple ID，大多数情况下也能用&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;属于“看运气”的部分。&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;3. 一份土耳其地址信息&lt;/h2&gt;
&lt;p&gt;这里推荐直接使用在线生成器：&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://1ktools.com/zh-cn/tools/developer/turkey-address-generator&quot;&gt;https://1ktools.com/zh-cn/tools/developer/turkey-address-generator&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;随机生成一份即可。&lt;/p&gt;
&lt;p&gt;后续：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;礼品卡购买&lt;/li&gt;
&lt;li&gt;Apple 付款信息&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;都可能会用到。&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;4. 一台 Apple 设备&lt;/h2&gt;
&lt;p&gt;支持：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;iPhone&lt;/li&gt;
&lt;li&gt;iPad&lt;/li&gt;
&lt;li&gt;Mac&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;但这里有一个重点：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;GPT 订阅的最终支付必须使用移动设备完成。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;也就是说：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Mac 可以注册&lt;/li&gt;
&lt;li&gt;Mac 可以登录&lt;/li&gt;
&lt;li&gt;但不能完成 App Store 内购支付&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;所以最终还是需要：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;iPhone&lt;/li&gt;
&lt;li&gt;或 iPad&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h1&gt;一、注册土耳其 Apple ID&lt;/h1&gt;
&lt;h2&gt;1. 打开 Apple 官网&lt;/h2&gt;
&lt;p&gt;进入：&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://account.apple.com/&quot;&gt;https://account.apple.com/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;建议：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;使用浏览器无痕模式&lt;/li&gt;
&lt;li&gt;是否开启代理无所谓&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;我测试：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;挂代理可以&lt;/li&gt;
&lt;li&gt;不挂也可以&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h2&gt;2. 创建 Apple 账户&lt;/h2&gt;
&lt;p&gt;进入后点击：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;创建你的 Apple 账户&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;填写时注意：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;国家选择：土耳其&lt;/li&gt;
&lt;li&gt;姓名：可使用土耳其地址生成器里的名字&lt;/li&gt;
&lt;li&gt;出生日期：大于 18 岁即可&lt;/li&gt;
&lt;li&gt;邮箱：新邮箱&lt;/li&gt;
&lt;li&gt;手机号：国内手机号即可&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h2&gt;3. 验证信息&lt;/h2&gt;
&lt;p&gt;填写验证码后，正常情况下就能完成注册。&lt;/p&gt;
&lt;p&gt;这里会看到：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;国家和地区已经显示为土耳其&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;但：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;这并不意味着 App Store 已经真正切换到土区。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;这是很多人容易踩坑的地方。&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;&lt;img src=&quot;./assets/pasted-image-20260516114141.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;hr /&gt;
&lt;h1&gt;二、真正切换 App Store 到土耳其区（关键步骤）&lt;/h1&gt;
&lt;p&gt;很多人：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;明明注册的是土区账号&lt;/li&gt;
&lt;li&gt;结果登录 App Store 后又跳回中国区&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;原因是：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;App Store 地区并没有真正重置。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;这里推荐使用：&lt;/p&gt;
&lt;h2&gt;使用 App Store 地区跳转链接（强烈推荐）&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&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;美国&lt;/td&gt;
&lt;td&gt;&lt;code&gt;itms-apps://itunes.apple.com/WebObjects/MZStore.woa/wa/resetAndRedirect?dsf=143441&amp;amp;cc=us&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;日本&lt;/td&gt;
&lt;td&gt;&lt;code&gt;itms-apps://itunes.apple.com/WebObjects/MZStore.woa/wa/resetAndRedirect?dsf=143462&amp;amp;cc=jp&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;韩国&lt;/td&gt;
&lt;td&gt;&lt;code&gt;itms-apps://itunes.apple.com/WebObjects/MZStore.woa/wa/resetAndRedirect?dsf=143466&amp;amp;cc=kr&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;香港&lt;/td&gt;
&lt;td&gt;&lt;code&gt;itms-apps://itunes.apple.com/WebObjects/MZStore.woa/wa/resetAndRedirect?dsf=143463&amp;amp;cc=hk&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;尼日利亚&lt;/td&gt;
&lt;td&gt;&lt;code&gt;itms-apps://itunes.apple.com/WebObjects/MZStore.woa/wa/resetAndRedirect?dsf=143561&amp;amp;cc=ng&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;土耳其&lt;/td&gt;
&lt;td&gt;&lt;code&gt;itms-apps://itunes.apple.com/WebObjects/MZStore.woa/wa/resetAndRedirect?dsf=143480&amp;amp;cc=tr&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;埃及&lt;/td&gt;
&lt;td&gt;&lt;code&gt;itms-apps://itunes.apple.com/WebObjects/MZStore.woa/wa/resetAndRedirect?dsf=143516&amp;amp;cc=eg&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;印度&lt;/td&gt;
&lt;td&gt;&lt;code&gt;itms-apps://itunes.apple.com/WebObjects/MZStore.woa/wa/resetAndRedirect?dsf=143467&amp;amp;cc=in&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;阿根廷&lt;/td&gt;
&lt;td&gt;&lt;code&gt;itms-apps://itunes.apple.com/WebObjects/MZStore.woa/wa/resetAndRedirect?dsf=143505&amp;amp;cc=ar&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr /&gt;
&lt;h2&gt;1. 退出当前 App Store 账号&lt;/h2&gt;
&lt;p&gt;路径：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;App Store → 头像 → 退出登录&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;注意：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;这里只退出 App Store&lt;/li&gt;
&lt;li&gt;不需要退出 iCloud&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h2&gt;2. 使用 Safari 打开土区跳转链接&lt;/h2&gt;
&lt;p&gt;直接复制到 Safari：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;itms-apps://itunes.apple.com/WebObjects/MZStore.woa/wa/resetAndRedirect?dsf=143480&amp;amp;cc=tr
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Safari 会自动跳转到：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;土耳其区 App Store&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h2&gt;3. 直接登录刚注册的土区账号&lt;/h2&gt;
&lt;p&gt;登录后检查：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;App Store 地区是否为 Turkey（土耳其）&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;确认无误后：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;说明土区 Apple ID 已真正注册成功。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr /&gt;
&lt;p&gt;&lt;img src=&quot;./assets/img_1646.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;hr /&gt;
&lt;h1&gt;三、购买土耳其 Apple 礼品卡&lt;/h1&gt;
&lt;p&gt;接下来需要给账号充值。&lt;/p&gt;
&lt;p&gt;这里推荐两种方式：&lt;/p&gt;
&lt;h2&gt;方案一：正规虚拟卡平台（推荐）&lt;/h2&gt;
&lt;p&gt;推荐：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://www.oyunfor.com/&quot;&gt;https://www.oyunfor.com/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.seagm.com/&quot;&gt;https://www.seagm.com/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;其中：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;SEAGM 支持支付宝&lt;/li&gt;
&lt;li&gt;对国内用户更方便&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;所以我这里直接使用 SEAGM。&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;方案二：国内二手平台&lt;/h2&gt;
&lt;p&gt;比如：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;小黄鱼&lt;/li&gt;
&lt;li&gt;其他电商平台&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;不太推荐。&lt;/p&gt;
&lt;p&gt;原因：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;来源不稳定&lt;/li&gt;
&lt;li&gt;容易涉及灰产卡&lt;/li&gt;
&lt;li&gt;有一定封号风险&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h1&gt;四、购买礼品卡并充值&lt;/h1&gt;
&lt;h2&gt;1. 使用支持支付宝的 SEAGM 购买礼品卡&lt;/h2&gt;
&lt;p&gt;建议：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;网站语言切换中文&lt;/li&gt;
&lt;li&gt;货币切换人民币&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;这样可以直接：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;支付宝扫码付款&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;p&gt;&lt;img src=&quot;./assets/pasted-image-20260516141519.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;2. 获取礼品卡代码&lt;/h2&gt;
&lt;p&gt;付款完成后：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;我的卡密 → 显示卡片&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;即可看到兑换码。&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;&lt;img src=&quot;./assets/pasted-image-20260516141701.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;3. App Store 兑换礼品卡&lt;/h2&gt;
&lt;p&gt;路径：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;App Store → 头像 → 最底部 → 兑换礼品卡或代码&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;输入礼品卡代码即可。&lt;/p&gt;
&lt;p&gt;充值成功后：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Apple 余额会显示对应里拉金额&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;p&gt;&lt;img src=&quot;./assets/pasted-image-20260516142528.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;hr /&gt;
&lt;h1&gt;五、关于付款信息：不需要提前选择 None&lt;/h1&gt;
&lt;p&gt;这里需要特别说明一个很多教程都会提到的问题。&lt;/p&gt;
&lt;p&gt;网上不少教程会说：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;注册完土区 Apple ID 后，需要先去添加付款信息，并且付款方式选择 None。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;但实际操作中，经常会遇到：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;找不到 None 选项&lt;/li&gt;
&lt;li&gt;无法选择 None&lt;/li&gt;
&lt;li&gt;页面要求补充付款信息&lt;/li&gt;
&lt;li&gt;填完后仍然无法保存&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;其实这一步完全可以不用提前处理。&lt;/p&gt;
&lt;p&gt;我的实际流程是：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;不需要注册完 Apple ID 后马上去设置付款方式，也不需要纠结有没有 None。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;只需要先完成：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;土区 Apple ID 注册&lt;/li&gt;
&lt;li&gt;App Store 切换到土耳其区&lt;/li&gt;
&lt;li&gt;礼品卡充值&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;然后直接打开 ChatGPT App 订阅 Plus。&lt;/p&gt;
&lt;p&gt;当你点击订阅时，系统会自动弹出付款信息填写页面。&lt;/p&gt;
&lt;p&gt;这时候不需要选择 None，只需要简单填写土耳其地址信息即可。&lt;/p&gt;
&lt;p&gt;地址可以继续使用前面生成的土耳其地址。&lt;/p&gt;
&lt;p&gt;填写完成后，系统会直接从 Apple ID 余额中扣款完成订阅。&lt;/p&gt;
&lt;hr /&gt;
&lt;h1&gt;六、订阅 ChatGPT Plus&lt;/h1&gt;
&lt;p&gt;充值完成后：&lt;/p&gt;
&lt;p&gt;直接打开 ChatGPT App。&lt;/p&gt;
&lt;p&gt;然后：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;设置 → Upgrade → Subscribe&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;即可完成订阅。&lt;/p&gt;
&lt;p&gt;如果系统弹出付款信息页面：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;不需要选择 None&lt;/li&gt;
&lt;li&gt;不需要绑定银行卡&lt;/li&gt;
&lt;li&gt;只需要填写土耳其地址信息&lt;/li&gt;
&lt;li&gt;确认后会优先使用 Apple ID 余额扣款&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;p&gt;这里需要再次强调：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;GPT 登录账号不需要是土区账号。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;真正需要土区的：&lt;/p&gt;
&lt;p&gt;只是支付 Apple ID。&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;我这里之前已经订阅过 Plus，所以用 Pro 做演示。&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;&lt;img src=&quot;./assets/pasted-image-20260516142849.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;hr /&gt;
&lt;h1&gt;七、将土区账号加入中国区 Apple 家庭（附加功能）&lt;/h1&gt;
&lt;p&gt;这一部分：&lt;/p&gt;
&lt;h2&gt;和 GPT Plus 共享无关&lt;/h2&gt;
&lt;p&gt;这里真正的意义是：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;后续可以共享土区 iCloud / Apple One 等订阅服务。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr /&gt;
&lt;h2&gt;方案：将土区账号加入中国区 Apple 家庭&lt;/h2&gt;
&lt;p&gt;正常邀请会提示：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;不能将其他地区账号加入家庭。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;所以这里推荐两个稳定方法。&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;方法一：隔空投送邀请&lt;/h2&gt;
&lt;p&gt;在中国区家庭管理员设备上：&lt;/p&gt;
&lt;p&gt;进入：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;设置 → Apple ID → 家人共享&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;然后：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;点击右上角添加账号&lt;/li&gt;
&lt;li&gt;选择【邀请他人】&lt;/li&gt;
&lt;li&gt;使用【隔空投送】&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;p&gt;此时：&lt;/p&gt;
&lt;p&gt;另一台登录土区账号的设备：&lt;/p&gt;
&lt;p&gt;开启：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;允许任何人隔空投送&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;两台设备靠近后：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;会自动弹出邀请&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;按提示操作即可。&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;方法二：iMessage 邀请（更稳定）&lt;/h2&gt;
&lt;p&gt;步骤基本一样。&lt;/p&gt;
&lt;p&gt;区别是：&lt;/p&gt;
&lt;p&gt;在邀请方式中选择：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;信息（iMessage）&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;然后：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;输入土区 Apple ID 邮箱&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;即可发送邀请。&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;这个方法实际上更稳定。&lt;/p&gt;
&lt;p&gt;因为：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;隔空投送偶尔失败&lt;/li&gt;
&lt;li&gt;iMessage 成功率更高&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;p&gt;&lt;img src=&quot;./assets/pasted-image-20260516143205.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;hr /&gt;
&lt;h1&gt;最后总结&lt;/h1&gt;
&lt;p&gt;至此，你已经完成了：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;土耳其 Apple ID 注册&lt;/li&gt;
&lt;li&gt;App Store 真正切换土区&lt;/li&gt;
&lt;li&gt;土区礼品卡购买&lt;/li&gt;
&lt;li&gt;Apple 余额充值&lt;/li&gt;
&lt;li&gt;GPT Plus 订阅&lt;/li&gt;
&lt;li&gt;土区账号加入中国区家庭&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;整个流程目前依然稳定可用。&lt;/p&gt;
&lt;p&gt;如果你后续还准备：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;开通土区 iCloud+&lt;/li&gt;
&lt;li&gt;Apple One&lt;/li&gt;
&lt;li&gt;Apple Music&lt;/li&gt;
&lt;li&gt;Arcade&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;那么提前维护一个长期稳定的土区 Apple ID，其实非常值得。&lt;/p&gt;
&lt;hr /&gt;
&lt;h1&gt;常见问题 FAQ&lt;/h1&gt;
&lt;h2&gt;Q1：必须使用代理吗？&lt;/h2&gt;
&lt;p&gt;不必须。&lt;/p&gt;
&lt;p&gt;我测试：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;开代理可以&lt;/li&gt;
&lt;li&gt;不开也能注册&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h2&gt;Q2：为什么 Mac 无法支付？&lt;/h2&gt;
&lt;p&gt;因为 GPT Plus 的 App Store 内购：&lt;/p&gt;
&lt;p&gt;目前只能通过移动端完成。&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;Q3：GPT 账号必须是土区吗？&lt;/h2&gt;
&lt;p&gt;不需要。&lt;/p&gt;
&lt;p&gt;土区只负责：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Apple 支付&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;GPT 账号本身没有限制。&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;Q4：注册完土区 Apple ID 后，必须先添加付款方式并选择 None 吗？&lt;/h2&gt;
&lt;p&gt;不需要。&lt;/p&gt;
&lt;p&gt;很多教程会要求提前设置付款方式，并选择 None。&lt;/p&gt;
&lt;p&gt;但实际操作中：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;None 经常不出现&lt;/li&gt;
&lt;li&gt;可能无法保存&lt;/li&gt;
&lt;li&gt;容易卡在付款信息页面&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;更简单的做法是：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;注册完成后不用管付款方式，直接充值礼品卡，然后去 ChatGPT App 订阅。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;订阅时系统会自动弹出付款信息填写页面。&lt;/p&gt;
&lt;p&gt;这时候只需要填写土耳其地址信息即可，不需要选择 None，也不需要绑定银行卡。&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;Q5：家庭共享是共享 GPT Plus 吗？&lt;/h2&gt;
&lt;p&gt;不是。&lt;/p&gt;
&lt;p&gt;这里只是：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Apple 家庭共享&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;主要用于后续：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;iCloud+&lt;/li&gt;
&lt;li&gt;Apple One&lt;/li&gt;
&lt;li&gt;Apple Music 等服务共享。&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h2&gt;Q6：土区 Apple ID 会封号吗？&lt;/h2&gt;
&lt;p&gt;只要：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;不使用来路不明的黑卡&lt;/li&gt;
&lt;li&gt;不频繁切换地区&lt;/li&gt;
&lt;li&gt;不进行异常退款&lt;/li&gt;
&lt;li&gt;长期稳定使用&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;一般都比较稳定。&lt;/p&gt;
&lt;p&gt;本文使用的是礼品卡充值方式，相对也更加安全。&lt;/p&gt;
</content:encoded></item><item><title>我们都还在路上：在不确定中攒出自己的选择权</title><link>https://www.futseyi.com/blog/on-the-road-accumulating-choices/</link><guid isPermaLink="true">https://www.futseyi.com/blog/on-the-road-accumulating-choices/</guid><description>这不是一篇关于 offer 的总结，也不是一份可以复制的攻略。只是想把一次个人分享会的结尾整理下来，写给你，也写给还在路上的自己：不用急着成为很厉害的人，先成为一个愿意行动、愿意复盘、愿意面对不确定的人。</description><pubDate>Wed, 13 May 2026 00:00:00 GMT</pubDate><content:encoded>&lt;blockquote&gt;
&lt;p&gt;[!IMPORTANT]
&lt;strong&gt;不要等到机会出现时，才开始准备自己。&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr /&gt;
&lt;h1&gt;作为今天最后一个分享人，我其实不想用一个 offer 来结束这场分享&lt;/h1&gt;
&lt;p&gt;因为 offer 很容易让一个故事看起来像是圆满结局。&lt;/p&gt;
&lt;p&gt;但我更想说的是，我其实也还在路上。&lt;/p&gt;
&lt;p&gt;我只是比大家稍微早一点，经历了一些选择、摇摆、试错和调整。&lt;/p&gt;
&lt;p&gt;我今天讲的这些，也不是想告诉大家“你们应该怎么做”。&lt;/p&gt;
&lt;p&gt;而是想说，其实我们都会有迷茫的时候。&lt;/p&gt;
&lt;p&gt;会怀疑自己是不是太普通。&lt;br /&gt;
会觉得别人好像都很清楚自己要什么。&lt;br /&gt;
会看到别人的成绩、比赛、论文、offer，然后觉得自己是不是落后了。&lt;br /&gt;
也会在某个时间点突然发现，原来自己之前想走的路，可能并不一定走得通。&lt;/p&gt;
&lt;p&gt;这些感受都很正常。&lt;/p&gt;
&lt;p&gt;我自己也经历过。&lt;/p&gt;
&lt;h2&gt;所以我想和大家共勉的是&lt;/h2&gt;
&lt;p&gt;不要因为现在不确定，就觉得自己没有未来。&lt;br /&gt;
不要因为一时没有结果，就否定之前的积累。&lt;br /&gt;
不要因为别人走得快，就觉得自己必须复制别人的路线。&lt;br /&gt;
也不要因为计划被打乱，就觉得一切都结束了。&lt;/p&gt;
&lt;p&gt;很多事情，当下看不出意义。&lt;/p&gt;
&lt;p&gt;但只要你还在行动，还在观察，还在复盘，还在一点点积累，它们就有可能在未来某个时候重新连接起来。&lt;/p&gt;
&lt;p&gt;也许你现在还不知道自己以后要去哪里，这很正常。&lt;/p&gt;
&lt;p&gt;大学本来就不是一条单线程任务。&lt;/p&gt;
&lt;p&gt;我们不一定要一开始就知道终点在哪里。&lt;/p&gt;
&lt;p&gt;但我们可以从现在开始，多试一点，多问一点，多记录一点，多表达一点，也多给自己一点耐心。&lt;/p&gt;
&lt;p&gt;你现在做的一个项目、一次表达、一次比赛、一次失败、一次旅行、一次主动联系、一次认真复盘，可能当下都只是零散片段。&lt;/p&gt;
&lt;p&gt;但当你持续行动、持续积累、持续理解自己，这些片段会慢慢连接成线。&lt;/p&gt;
&lt;p&gt;而这些线，最后会变成你面对不确定时的选择权。&lt;/p&gt;
&lt;p&gt;所以最后想把这句话送给大家，也送给我自己：&lt;/p&gt;
&lt;h2&gt;&lt;strong&gt;不用急着成为一个“很厉害的人”。&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;先成为一个愿意行动的人，愿意复盘的人，愿意面对不确定的人，愿意一点点把自己往前推的人。&lt;/p&gt;
&lt;p&gt;我们都还在路上。&lt;/p&gt;
&lt;p&gt;希望大家都能在自己的大学里，慢慢找到自己的节奏，攒下自己的底气，也攒出属于自己的选择权。&lt;/p&gt;
&lt;p&gt;谢谢你们。&lt;/p&gt;
</content:encoded></item><item><title>Claude Desktop 接入第三方模型 API：基于 ccswitch 的配置与踩坑</title><link>https://www.futseyi.com/blog/claude-desktop-third-party-api-ccswitch/</link><guid isPermaLink="true">https://www.futseyi.com/blog/claude-desktop-third-party-api-ccswitch/</guid><description>记录 Claude Desktop 通过 ccswitch 接入DeepSeek模型 API 的完整配置流程与踩坑补充，包括本地路由、Gateway 配置、inferenceModels 注册表补充、/v1/models 404 排查，以及 Claude Desktop 与 VS Code Claude 插件的链路区别。</description><pubDate>Thu, 30 Apr 2026 00:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;Claude Desktop 接入 ccswitch：第三方模型 API 配置与踩坑记录&lt;/h1&gt;
&lt;p&gt;最近想让 Claude Desktop 也能像 Claude Code 一样，通过 ccswitch 接入第三方模型 API，方便在桌面端里切换不同 Provider 测试。&lt;/p&gt;
&lt;p&gt;我主要参考了 LINUX DO 上 sandleft 佬的这篇教程：&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://linux.do/t/topic/2032344&quot;&gt;《如何用功能更强大更美观的 claude 桌面端替代 cli 还能随意切换模型？》&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;原教程已经把核心方案讲清楚了：&lt;strong&gt;Claude Desktop 通过官方 3P Gateway 连接到 ccswitch 本地路由，再由 ccswitch 转发到当前选中的 Provider&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;不过我实际配置时还是遇到了一些坑，比如：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Gateway returned HTTP 400
Gateway returned HTTP 404
requestUrl: http://127.0.0.1:15721/v1/models
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这篇文章主要是对原教程的逻辑做一次重新梳理，并补充我自己遇到的问题和解决方法。&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;一、先搞清楚：Claude Desktop 和 Claude Code 不是同一条链路&lt;/h2&gt;
&lt;p&gt;这是我最开始最容易混淆的地方。&lt;/p&gt;
&lt;p&gt;简单说：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Claude Desktop = 走 ccswitch 本地路由
Claude Code / VS Code Claude 插件 = 走 Claude Code 配置
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Claude Desktop 的请求链路是：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Claude Desktop
→ http://127.0.0.1:15721
→ ccswitch 本地路由
→ 当前 Provider
→ 第三方模型 API
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;而 VS Code 里的 Claude 插件 / Claude Code 更像是读取 ccswitch 写入或切换后的 Claude Code 配置，比如：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;ANTHROPIC_BASE_URL
ANTHROPIC_AUTH_TOKEN
模型名配置
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;所以它的链路更接近：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;VS Code Claude 插件 / Claude Code
→ Claude Code 配置
→ 当前 Provider
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这就解释了一个现象：&lt;strong&gt;ccswitch 本地路由关闭后，VS Code Claude 插件仍然可能正常使用；但 Claude Desktop 要用这套方案，就必须开 ccswitch 本地路由。&lt;/strong&gt;&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;二、开启 ccswitch 本地路由&lt;/h2&gt;
&lt;p&gt;在 ccswitch 里进入本地路由相关页面，确认这些状态：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;本地路由：运行中
路由总开关：开启
Claude：开启
服务地址：http://127.0.0.1:15721
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这里最重要的是服务地址。&lt;/p&gt;
&lt;p&gt;比如 ccswitch 显示的是：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;http://127.0.0.1:15721
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;那 Claude Desktop 里也必须填这个地址。&lt;/p&gt;
&lt;p&gt;我一开始填成了另一个端口，例如：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;http://127.0.0.1:10809
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这当然会出问题。&lt;/p&gt;
&lt;p&gt;所以第一步先确认：&lt;strong&gt;Claude Desktop 里的 Gateway base URL 必须和 ccswitch 显示的本地路由地址一致。&lt;/strong&gt;&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;三、配置 Claude Desktop 的 Gateway&lt;/h2&gt;
&lt;p&gt;在 Claude Desktop 里打开第三方推理配置。&lt;/p&gt;
&lt;p&gt;一般路径是：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Help
→ Troubleshooting
→ Enable Developer mode
→ Developer
→ Configure third-party inference
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Connection 选择：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Gateway
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;然后填写：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Gateway base URL = http://127.0.0.1:15721
Gateway API key = PROXY_MANAGED
Gateway auth scheme = bearer
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这里注意一点：&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Claude Desktop 里不要填真实的第三方模型 API Key。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;这里填：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;PROXY_MANAGED
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;真实 API Key 应该配置在 ccswitch 的 Provider 里。&lt;/p&gt;
&lt;p&gt;也就是说：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Claude Desktop 只负责连接 ccswitch；
ccswitch 才负责连接真实的第三方模型 API。
&lt;/code&gt;&lt;/pre&gt;
&lt;hr /&gt;
&lt;h2&gt;四、最关键的一步：手动补 inferenceModels&lt;/h2&gt;
&lt;p&gt;只配置 Gateway 还不一定够。&lt;/p&gt;
&lt;p&gt;Claude Desktop 会尝试请求：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;http://127.0.0.1:15721/v1/models
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;但 ccswitch 本地路由不一定实现了 &lt;code&gt;/v1/models&lt;/code&gt; 这个接口，于是会出现：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Gateway returned HTTP 404
requestUrl: http://127.0.0.1:15721/v1/models
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这个 404 很容易误导人。&lt;/p&gt;
&lt;p&gt;它的意思不是“整个链路不可用”，而是：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Claude Desktop 想获取模型列表；
但 ccswitch 没有提供 /v1/models；
所以模型列表探测失败。
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;解决方法是：&lt;strong&gt;在 Windows 注册表里手动补上 inferenceModels。&lt;/strong&gt;&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;五、通过 .reg 添加 inferenceModels&lt;/h2&gt;
&lt;p&gt;先在 Claude Desktop 表单里填好：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Gateway base URL = http://127.0.0.1:15721
Gateway API key = PROXY_MANAGED
Gateway auth scheme = bearer
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;然后点击右下角：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Export
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;导出 Windows 的 &lt;code&gt;.reg&lt;/code&gt; 文件。&lt;/p&gt;
&lt;p&gt;用记事本打开 &lt;code&gt;.reg&lt;/code&gt;，找到：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[HKEY_CURRENT_USER\SOFTWARE\Policies\Claude]
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;在下面添加：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&quot;inferenceModels&quot;=&quot;[\&quot;haiku\&quot;,\&quot;sonnet\&quot;,\&quot;opus\&quot;]&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;如果只想先测试一个模型，也可以写：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&quot;inferenceModels&quot;=&quot;[\&quot;sonnet\&quot;]&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;保存后双击导入，或者使用命令：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;reg import &quot;C:\path\to\your.reg&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;导入后，完全退出 Claude Desktop，再重新打开。&lt;/p&gt;
&lt;p&gt;注意：最好不是只关窗口，而是从托盘里彻底退出后重启。&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;六、haiku / sonnet / opus 只是别名&lt;/h2&gt;
&lt;p&gt;这里也容易误解。&lt;/p&gt;
&lt;p&gt;在 &lt;code&gt;inferenceModels&lt;/code&gt; 里写：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&quot;inferenceModels&quot;=&quot;[\&quot;haiku\&quot;,\&quot;sonnet\&quot;,\&quot;opus\&quot;]&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;并不代表你真的在用 Claude Haiku、Claude Sonnet 或 Claude Opus。&lt;/p&gt;
&lt;p&gt;在这里，它们更像是 Claude Desktop 识别的模型槽位或别名。&lt;/p&gt;
&lt;p&gt;真正请求哪个模型，取决于 ccswitch 里的映射。&lt;/p&gt;
&lt;p&gt;比如你可以在 ccswitch 中把这些都映射到同一个模型：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;主模型：deepseek-v4-flash
Haiku 默认模型：deepseek-v4-flash
Sonnet 默认模型：deepseek-v4-flash
Opus 默认模型：deepseek-v4-flash
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;也可以根据需要映射到不同模型。&lt;/p&gt;
&lt;p&gt;所以不要用“你是什么模型？”这种方式判断真实模型。模型自我介绍很容易受到系统提示、别名和兼容层影响。&lt;/p&gt;
&lt;p&gt;更可靠的判断方式是看：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;ccswitch 请求记录
ccswitch 日志
第三方模型控制台用量
实际请求里的 model 字段
&lt;/code&gt;&lt;/pre&gt;
&lt;hr /&gt;
&lt;h2&gt;七、关于模型名后缀，比如 &lt;code&gt;[1m]&lt;/code&gt;&lt;/h2&gt;
&lt;p&gt;有些模型名可能会长这样：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;deepseek-v4-pro[1m]
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这类后缀不能一概认为是错的。&lt;/p&gt;
&lt;p&gt;很多 Provider 或中转服务会用类似 &lt;code&gt;[1m]&lt;/code&gt; 的后缀表示特定模型规格，比如 1M 超长上下文版本。如果你的服务商、面板或 ccswitch 配置要求这样写，那就应该保留。&lt;/p&gt;
&lt;p&gt;但如果遇到：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;HTTP 400
model not found
provider rejected request
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;可以临时切回基础模型名测试，例如：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;deepseek-v4-pro
deepseek-v4-flash
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;先确认基础链路没问题，再切回带后缀的版本。&lt;/p&gt;
&lt;p&gt;关键是判断这个后缀到底是：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;服务商要求的模型规格
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;还是：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;界面展示用的标记
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;前者需要保留，后者不应该传给 API。&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;八、&lt;code&gt;thinking: false&lt;/code&gt; 不是必选项&lt;/h2&gt;
&lt;p&gt;有些教程会建议在 ccswitch 里加：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
  &quot;thinking&quot;: false,
  &quot;includeCoAuthoredBy&quot;: false
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;我自己测试时，不加也能正常使用。&lt;/p&gt;
&lt;p&gt;所以我的建议是：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;能用就先不加。
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;如果后续遇到 400、tool_use、thinking、旧会话上下文不兼容之类的问题，再考虑添加。&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;九、常见报错怎么理解？&lt;/h2&gt;
&lt;h3&gt;1. Gateway returned HTTP 400&lt;/h3&gt;
&lt;p&gt;400 一般表示请求已经发出去了，但 Provider 拒绝了请求。&lt;/p&gt;
&lt;p&gt;常见原因：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;模型名错误
Provider 配置错误
API Key 错误
账号额度或模型权限问题
请求格式不兼容
旧会话上下文不兼容
thinking / tool_use 兼容问题
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;可以按这个顺序排查：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;1. 检查 ccswitch 当前 Provider 是否选对
2. 检查模型名是否正确
3. 检查真实 API Key 是否填在 ccswitch Provider 里
4. 新开 Claude Desktop 会话测试
5. 必要时尝试 thinking: false
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;2. Gateway returned HTTP 404&lt;/h3&gt;
&lt;p&gt;如果 404 的地址是：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;http://127.0.0.1:15721/v1/models
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;那大概率只是 Claude Desktop 在测试模型列表。&lt;/p&gt;
&lt;p&gt;这种情况下，重点不是纠结 &lt;code&gt;/v1/models&lt;/code&gt;，而是补上：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;inferenceModels
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;只要实际对话能正常使用，就说明核心链路是通的。&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;十、如何确认 Claude Desktop 真的走了 ccswitch？&lt;/h2&gt;
&lt;p&gt;可以看 ccswitch 的请求记录或日志。&lt;/p&gt;
&lt;p&gt;日志一般在：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;C:\Users\&amp;lt;用户名&amp;gt;\.cc-switch\logs\cc-switch.log
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;也可以查看数据库：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;C:\Users\&amp;lt;用户名&amp;gt;\.cc-switch\cc-switch.db
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;重点看请求记录里有没有类似字段：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;data_source = proxy
provider_id = 当前选中的 Provider
request_model = sonnet / haiku / opus
model = 实际上游模型
status_code = 200
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;如果能看到 &lt;code&gt;data_source = proxy&lt;/code&gt;，并且 &lt;code&gt;status_code = 200&lt;/code&gt;，就说明 Claude Desktop 的请求确实经过了 ccswitch 本地路由。&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;十一、最终流程总结&lt;/h2&gt;
&lt;p&gt;如果从头配置，我会按这个顺序来：&lt;/p&gt;
&lt;h3&gt;1. 先在 ccswitch 里配置好 Provider&lt;/h3&gt;
&lt;p&gt;确保第三方模型 API 在 ccswitch 中可以正常使用。&lt;/p&gt;
&lt;h3&gt;2. 开启 ccswitch 本地路由&lt;/h3&gt;
&lt;p&gt;确认：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;本地路由：运行中
路由总开关：开启
Claude：开启
服务地址：http://127.0.0.1:15721
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;3. Claude Desktop 配置 Gateway&lt;/h3&gt;
&lt;p&gt;填写：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Gateway base URL = http://127.0.0.1:15721
Gateway API key = PROXY_MANAGED
Gateway auth scheme = bearer
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;4. 导出 .reg&lt;/h3&gt;
&lt;p&gt;点击 Claude Desktop 配置页右下角的：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Export
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;5. 修改 .reg，补上 inferenceModels&lt;/h3&gt;
&lt;p&gt;在：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[HKEY_CURRENT_USER\SOFTWARE\Policies\Claude]
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;下面加：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&quot;inferenceModels&quot;=&quot;[\&quot;haiku\&quot;,\&quot;sonnet\&quot;,\&quot;opus\&quot;]&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;或者先只测一个：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&quot;inferenceModels&quot;=&quot;[\&quot;sonnet\&quot;]&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;6. 导入 .reg 并重启 Claude Desktop&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;reg import &quot;C:\path\to\your.reg&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;然后完全退出并重启 Claude Desktop。&lt;/p&gt;
&lt;h3&gt;7. 新开会话测试&lt;/h3&gt;
&lt;p&gt;不要只看设置页的 Check again。&lt;/p&gt;
&lt;p&gt;如果实际对话可以使用，并且 ccswitch 有请求记录，就说明链路已经跑通。&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;十二、最终使用习惯&lt;/h2&gt;
&lt;p&gt;配置完成后，可以这样理解：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;用 Claude Desktop：
需要开启 ccswitch 本地路由。

用 VS Code Claude 插件 / Claude Code：
通常不需要开启 ccswitch 本地路由，
只要 Claude Code 配置已经切换到对应 Provider。
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;如果要切换 Claude Code 使用的 Provider，还是通过 ccswitch 切换配置。&lt;/p&gt;
&lt;p&gt;但日常只用 VS Code Claude 插件时，本地路由不一定要开。&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;结论&lt;/h2&gt;
&lt;p&gt;这套方案的核心其实很简单：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Claude Desktop
→ 官方 3P Gateway
→ ccswitch 本地路由
→ 第三方模型 API
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;真正容易踩坑的是几个细节：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;1. ccswitch 本地路由必须开启
2. Claude Desktop 的端口要和 ccswitch 一致
3. Gateway API key 建议填 PROXY_MANAGED
4. Windows 下需要手动补 inferenceModels
5. /v1/models 404 不一定影响实际使用
6. haiku / sonnet / opus 只是别名
7. Claude Desktop 和 Claude Code / VS Code 插件不是同一条链路
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;折腾完之后，这套方案还是挺实用的。Claude Desktop 可以通过 ccswitch 接入第三方模型 API，而 Claude Code / VS Code 插件也可以继续使用 ccswitch 写入的配置。&lt;/p&gt;
&lt;p&gt;最后再次感谢 LINUX DO 上 sandleft 佬的原教程。本文只是基于原教程的一次个人实践补充，主要记录我在配置过程中遇到的坑和解决思路。&lt;/p&gt;
</content:encoded></item><item><title>从圆肩到挺拔：我的第一份认真训练计划</title><link>https://www.futseyi.com/blog/first-serious-training-plan/</link><guid isPermaLink="true">https://www.futseyi.com/blog/first-serious-training-plan/</guid><description>健身不足一年，中度圆肩和肋骨外翻。这篇文章记录了我根据自身体态问题重新设计的一套一周训练计划，包含背、胸、肩、腹、腿五个部位的完整动作顺序、组数、重量参考，以及配合游泳的恢复安排。不是模板套用，而是针对推拉失衡、核心不稳定、胸椎活动度不足的真实解法。</description><pubDate>Tue, 21 Apr 2026 00:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;🏋️ 训练计划&lt;/h1&gt;
&lt;h2&gt;180cm / 70kg · 新手不足 1 年 · 圆肩（中度）+ 肋骨外翻 · 增肌 + 体态矫正并重&lt;/h2&gt;
&lt;hr /&gt;
&lt;h1&gt;📅 一周总览&lt;/h1&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;天数&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;&lt;strong&gt;周一&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;背 + 二头&lt;/td&gt;
&lt;td&gt;90 分钟&lt;/td&gt;
&lt;td&gt;拉力优先，对抗圆肩&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;周二&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;胸 + 三头&lt;/td&gt;
&lt;td&gt;90 分钟&lt;/td&gt;
&lt;td&gt;推力控量，肩胛稳定&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;周三&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;体态矫正 → 游泳（技术日）&lt;/td&gt;
&lt;td&gt;15+60 分钟&lt;/td&gt;
&lt;td&gt;激活深层稳定肌，仰泳矫正圆肩&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;周四&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;肩 + 腹&lt;/td&gt;
&lt;td&gt;90 分钟&lt;/td&gt;
&lt;td&gt;后束优先，肋骨控制&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;周五&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;腿 → 游泳（恢复日）&lt;/td&gt;
&lt;td&gt;90+30 分钟&lt;/td&gt;
&lt;td&gt;腿部增肌，游泳放松乳酸&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;周六&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;完全休息&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;周日&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;完全休息&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr /&gt;
&lt;h2&gt;周一｜背 + 二头（90 分钟）&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;💡 &lt;strong&gt;原则&lt;/strong&gt;：面拉永远第一，激活后束后再做大重量；每组开始前检查肩胛是否已下沉&lt;/p&gt;
&lt;/blockquote&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;顺序&lt;/th&gt;
&lt;th&gt;精确动作名称&lt;/th&gt;
&lt;th&gt;英文名&lt;/th&gt;
&lt;th&gt;器械&lt;/th&gt;
&lt;th&gt;组数&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;1&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;面拉&lt;/strong&gt; ⭐&lt;/td&gt;
&lt;td&gt;Cable Face Pull&lt;/td&gt;
&lt;td&gt;绳索机高位 + 绳索把手&lt;/td&gt;
&lt;td&gt;3 组&lt;/td&gt;
&lt;td&gt;15 次&lt;/td&gt;
&lt;td&gt;30–35kg&lt;/td&gt;
&lt;td&gt;60 秒&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;引体向上&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Pull-Up&lt;/td&gt;
&lt;td&gt;固定单杠，宽于肩正握&lt;/td&gt;
&lt;td&gt;3 组&lt;/td&gt;
&lt;td&gt;5–6 次&lt;/td&gt;
&lt;td&gt;自重（不够用辅助机）&lt;/td&gt;
&lt;td&gt;90 秒&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;坐姿宽距下拉&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Lat Pulldown (Wide Grip)&lt;/td&gt;
&lt;td&gt;高位下拉机 + 宽握横杆&lt;/td&gt;
&lt;td&gt;3 组&lt;/td&gt;
&lt;td&gt;10–12 次&lt;/td&gt;
&lt;td&gt;40–45kg&lt;/td&gt;
&lt;td&gt;90 秒&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;悍马机坐姿划船&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Hammer Strength Seated Row&lt;/td&gt;
&lt;td&gt;Hammer Strength 坐姿划船机，双手同时&lt;/td&gt;
&lt;td&gt;3 组&lt;/td&gt;
&lt;td&gt;10 次&lt;/td&gt;
&lt;td&gt;45kg&lt;/td&gt;
&lt;td&gt;90 秒&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;坐姿绳索划船（窄握）&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Seated Cable Row (Close Grip)&lt;/td&gt;
&lt;td&gt;坐姿划船机 + V 形窄握把手&lt;/td&gt;
&lt;td&gt;3 组&lt;/td&gt;
&lt;td&gt;10 次&lt;/td&gt;
&lt;td&gt;35–40kg&lt;/td&gt;
&lt;td&gt;90 秒&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;6&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;EZ 杆弯举&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;EZ Bar Curl&lt;/td&gt;
&lt;td&gt;EZ 曲杆，站姿&lt;/td&gt;
&lt;td&gt;3 组&lt;/td&gt;
&lt;td&gt;10–12 次&lt;/td&gt;
&lt;td&gt;25–27.5kg&lt;/td&gt;
&lt;td&gt;60 秒&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;strong&gt;动作要点：&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;面拉：滑轮与面部同高，双手拉至拳头在耳朵两侧，呼气顶峰停 1 秒&lt;/li&gt;
&lt;li&gt;引体向上：肩胛先向下向后收→再弯肘拉，全程不耸肩&lt;/li&gt;
&lt;li&gt;下拉/划船：想象把肘关节往裤兜方向塞，顶峰夹背停 1 秒&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h2&gt;周二｜胸 + 三头（90 分钟）&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;💡 &lt;strong&gt;原则&lt;/strong&gt;：卧推量控制在 4 组（圆肩者推的总量必须少于拉）；肩胛全程夹紧贴凳&lt;/p&gt;
&lt;/blockquote&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;顺序&lt;/th&gt;
&lt;th&gt;精确动作名称&lt;/th&gt;
&lt;th&gt;英文名&lt;/th&gt;
&lt;th&gt;器械&lt;/th&gt;
&lt;th&gt;组数&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;1&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;俯卧撑&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Push-Up&lt;/td&gt;
&lt;td&gt;徒手，标准宽度&lt;/td&gt;
&lt;td&gt;2 组&lt;/td&gt;
&lt;td&gt;12 次&lt;/td&gt;
&lt;td&gt;自重&lt;/td&gt;
&lt;td&gt;45 秒&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;杠铃平板卧推&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Barbell Bench Press&lt;/td&gt;
&lt;td&gt;平板凳 + 奥林匹克杠铃&lt;/td&gt;
&lt;td&gt;4 组&lt;/td&gt;
&lt;td&gt;8–10 次&lt;/td&gt;
&lt;td&gt;第 1 组 50kg×10 热身，第 2–4 组 55kg×8&lt;/td&gt;
&lt;td&gt;2 分钟&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;蝴蝶机飞鸟&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Pec Deck Fly&lt;/td&gt;
&lt;td&gt;蝴蝶机（Pec Deck Machine）&lt;/td&gt;
&lt;td&gt;3 组&lt;/td&gt;
&lt;td&gt;12 次&lt;/td&gt;
&lt;td&gt;40kg&lt;/td&gt;
&lt;td&gt;90 秒&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;双杠臂屈伸&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Parallel Bar Dip&lt;/td&gt;
&lt;td&gt;双杠&lt;/td&gt;
&lt;td&gt;3 组&lt;/td&gt;
&lt;td&gt;8 次&lt;/td&gt;
&lt;td&gt;自重&lt;/td&gt;
&lt;td&gt;90 秒&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;V-Bar 绳索下压&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Tricep Pushdown (V-Bar)&lt;/td&gt;
&lt;td&gt;绳索机高位 + V 形把手&lt;/td&gt;
&lt;td&gt;3 组&lt;/td&gt;
&lt;td&gt;12 次&lt;/td&gt;
&lt;td&gt;30–35kg&lt;/td&gt;
&lt;td&gt;60 秒&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;6&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;绳索过头臂屈伸&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Overhead Cable Tricep Extension&lt;/td&gt;
&lt;td&gt;绳索机低位 + 绳索把手&lt;/td&gt;
&lt;td&gt;3 组&lt;/td&gt;
&lt;td&gt;12 次&lt;/td&gt;
&lt;td&gt;25–30kg&lt;/td&gt;
&lt;td&gt;60 秒&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;strong&gt;动作要点：&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;卧推：肩胛收紧夹紧贴凳，下放时肘关节约 75° 角，不要完全外展保护肩关节&lt;/li&gt;
&lt;li&gt;双杠：练胸时身体略前倾 15–20°；练三头时身体垂直&lt;/li&gt;
&lt;li&gt;⚠️ 卧推后肩前侧关节不适→立刻减重 5kg 或改哑铃卧推&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h2&gt;周三｜体态矫正 → 游泳技术日（75 分钟）&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;矫正训练（15 分钟，健身房拉伸区或家中）：&lt;/strong&gt;&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;顺序&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;1&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;死虫式&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;每侧 8 次 × 2–3 组&lt;/td&gt;
&lt;td&gt;呼气时把下肋骨压住垫子，腰部全程不离地&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;侧卧胸椎旋转&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;每侧 6 次 × 1–2 组&lt;/td&gt;
&lt;td&gt;感受胸椎段转动,不是腰椎带动&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;面拉&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;15 次×3 组&lt;/td&gt;
&lt;td&gt;滑轮调至面部同高，绳索把手，双手拉至拳头在耳朵两侧，顶峰停 1 秒&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;strong&gt;游泳（60 分钟，技术课模式，不计圈数）：&lt;/strong&gt;&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&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;&lt;strong&gt;仰泳&lt;/strong&gt; ⭐&lt;/td&gt;
&lt;td&gt;50%&lt;/td&gt;
&lt;td&gt;强制肩胛外旋，直接对抗圆肩，是最友好的泳姿&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;自由泳&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;40%&lt;/td&gt;
&lt;td&gt;注意转头换气时不过度抬头，感受每次划水时肩胛轨迹&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;蛙泳&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;10%&lt;/td&gt;
&lt;td&gt;少做，避免抬头动作加重颈部代偿&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr /&gt;
&lt;h2&gt;周四｜肩 + 腹（90 分钟）&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;💡 &lt;strong&gt;原则&lt;/strong&gt;：后束永远第一；腹部每个动作呼气时主动下压肋骨；哑铃推肩全程不挺腰&lt;/p&gt;
&lt;/blockquote&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;顺序&lt;/th&gt;
&lt;th&gt;精确动作名称&lt;/th&gt;
&lt;th&gt;英文名&lt;/th&gt;
&lt;th&gt;器械&lt;/th&gt;
&lt;th&gt;组数&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;1&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;蝴蝶机反向飞鸟&lt;/strong&gt; ⭐&lt;/td&gt;
&lt;td&gt;Reverse Pec Deck Fly&lt;/td&gt;
&lt;td&gt;蝴蝶机反坐（背对靠背）&lt;/td&gt;
&lt;td&gt;4 组&lt;/td&gt;
&lt;td&gt;12–15 次&lt;/td&gt;
&lt;td&gt;35–40kg&lt;/td&gt;
&lt;td&gt;60 秒&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;俯身飞鸟&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Bent-Over Dumbbell Lateral Raise&lt;/td&gt;
&lt;td&gt;哑铃，站姿俯身约 70°&lt;/td&gt;
&lt;td&gt;3 组&lt;/td&gt;
&lt;td&gt;12 次&lt;/td&gt;
&lt;td&gt;7.5kg&lt;/td&gt;
&lt;td&gt;60 秒&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;绳索侧平举&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Cable Lateral Raise (Single Arm)&lt;/td&gt;
&lt;td&gt;绳索机低位 + 单手 D 形环&lt;/td&gt;
&lt;td&gt;3 组&lt;/td&gt;
&lt;td&gt;12 次（每侧）&lt;/td&gt;
&lt;td&gt;10kg&lt;/td&gt;
&lt;td&gt;60 秒&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;哑铃坐姿推肩&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Seated Dumbbell Shoulder Press&lt;/td&gt;
&lt;td&gt;哑铃 + 有靠背调节椅&lt;/td&gt;
&lt;td&gt;3 组&lt;/td&gt;
&lt;td&gt;10 次&lt;/td&gt;
&lt;td&gt;15kg&lt;/td&gt;
&lt;td&gt;90 秒&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;腹&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;平板蝴蝶收腹&lt;/strong&gt; ⭐&lt;/td&gt;
&lt;td&gt;Butterfly Sit-Up&lt;/td&gt;
&lt;td&gt;地面瑜伽垫，双脚脚心相对&lt;/td&gt;
&lt;td&gt;3 组&lt;/td&gt;
&lt;td&gt;25–30 次&lt;/td&gt;
&lt;td&gt;自重&lt;/td&gt;
&lt;td&gt;45 秒&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;6&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;仰卧卷腹&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Crunch&lt;/td&gt;
&lt;td&gt;地面瑜伽垫&lt;/td&gt;
&lt;td&gt;3 组&lt;/td&gt;
&lt;td&gt;12–15 次&lt;/td&gt;
&lt;td&gt;自重&lt;/td&gt;
&lt;td&gt;45 秒&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;7&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;悬挂举腿&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Hanging Leg Raise&lt;/td&gt;
&lt;td&gt;单杠悬挂&lt;/td&gt;
&lt;td&gt;3 组&lt;/td&gt;
&lt;td&gt;8–10 次&lt;/td&gt;
&lt;td&gt;自重&lt;/td&gt;
&lt;td&gt;60 秒&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;strong&gt;动作要点：&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;蝴蝶机反向飞鸟：顶峰时感受后束三角肌夹紧，停 1 秒&lt;/li&gt;
&lt;li&gt;哑铃推肩：腰椎不能过度前凸（不挺腰撑），否则加重肋骨外翻&lt;/li&gt;
&lt;li&gt;悬挂举腿：感受到的是腰用力而非腹部→立刻改&lt;strong&gt;死虫式（Dead Bug)&lt;/strong&gt; 代替 (连续 2 周死虫式每侧 8 次全程腰部不离地后，再尝试重新加回悬挂举腿)&lt;/li&gt;
&lt;li&gt;腹部全部动作：&lt;strong&gt;每次呼气把下肋骨往内往下收&lt;/strong&gt;，这是改善肋骨外翻的核心机制&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h2&gt;周五｜腿 → 游泳恢复日（90+30 分钟）&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;💡 &lt;strong&gt;原则&lt;/strong&gt;：深蹲先用高脚杯哑铃版过渡，待胸椎活动度改善后再加回杠铃深蹲&lt;/p&gt;
&lt;/blockquote&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;顺序&lt;/th&gt;
&lt;th&gt;精确动作名称&lt;/th&gt;
&lt;th&gt;英文名&lt;/th&gt;
&lt;th&gt;器械&lt;/th&gt;
&lt;th&gt;组数&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;1&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;哑铃酒杯深蹲&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Goblet Squat&lt;/td&gt;
&lt;td&gt;单个哑铃竖握置于胸前&lt;/td&gt;
&lt;td&gt;3 组&lt;/td&gt;
&lt;td&gt;12 次&lt;/td&gt;
&lt;td&gt;15–20kg 哑铃&lt;/td&gt;
&lt;td&gt;90 秒&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;腿举&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Leg Press&lt;/td&gt;
&lt;td&gt;腿举机（45° 斜板式）&lt;/td&gt;
&lt;td&gt;4 组&lt;/td&gt;
&lt;td&gt;10–12 次&lt;/td&gt;
&lt;td&gt;第 1 组 50kg×12 热身，第 2–3 组 65kg×10，第 4 组 70kg×8&lt;/td&gt;
&lt;td&gt;2 分钟&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;坐姿髋内收&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Seated Hip Adduction&lt;/td&gt;
&lt;td&gt;内收肌训练机（大腿内侧夹合机）&lt;/td&gt;
&lt;td&gt;3 组&lt;/td&gt;
&lt;td&gt;12–15 次&lt;/td&gt;
&lt;td&gt;40kg&lt;/td&gt;
&lt;td&gt;60 秒&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;strong&gt;游泳（30 分钟，放松恢复）：&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;慢速自由泳为主，心率控制在最大心率 60% 以下（能轻松说话的速度）&lt;/li&gt;
&lt;li&gt;打腿练习有效放松股四头肌和臀肌，促进乳酸代谢&lt;/li&gt;
&lt;li&gt;不计成绩，感受腿部血液流通即可&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h1&gt;📈 递增方案（4 阶段）&lt;/h1&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;阶段&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;&lt;strong&gt;建立期&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;第 1–4 周&lt;/td&gt;
&lt;td&gt;动作模式&lt;/td&gt;
&lt;td&gt;不追加重，专注感受目标肌肉收缩，每个动作做完能明确感受到该肌肉&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;线性递增期&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;第 5 周起&lt;/td&gt;
&lt;td&gt;持续变强&lt;/td&gt;
&lt;td&gt;每 2 周完成所有组次后加重：大肌群 +2.5kg，小肌群 +1.25kg&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;减量周&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;每 6 周一次&lt;/td&gt;
&lt;td&gt;关节恢复&lt;/td&gt;
&lt;td&gt;所有重量退回 80%，组数减半，让结缔组织和神经系统充分休息&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;动作升级&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;3 个月后&lt;/td&gt;
&lt;td&gt;进阶&lt;/td&gt;
&lt;td&gt;高脚杯深蹲→低杠深蹲；引体向上→负重引体；做专业体态评估&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr /&gt;
&lt;h1&gt;🥩 每日蛋白质目标&lt;/h1&gt;
&lt;p&gt;目标 &lt;strong&gt;112–140g/天&lt;/strong&gt;（1.6–2.0g × 70kg），以下组合基本可达标：&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&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;蛋白粉 1 勺（训练后）&lt;/td&gt;
&lt;td&gt;~25g&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;鸡胸肉 150g（任意一餐）&lt;/td&gt;
&lt;td&gt;~35g&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;鸡蛋 3 个&lt;/td&gt;
&lt;td&gt;~18g&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;其他正餐食物（米饭、蔬菜、豆类等）&lt;/td&gt;
&lt;td&gt;~25–35g&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;合计&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;~103–113g ✅&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;训练日可额外补 1 勺蛋白粉轻松达标，不需要刻意大量进食。&lt;/p&gt;
&lt;hr /&gt;
&lt;h1&gt;⚠️ 三条安全红线&lt;/h1&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;某关节（非肌肉）酸痛持续超过 48 小时&lt;/strong&gt; → 该动作本周停，下次退重 10–15% 重新开始&lt;/li&gt;
&lt;/ol&gt;
&lt;hr /&gt;
&lt;h1&gt;🗓️ 3 个月里程碑&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;第 4 周末&lt;/strong&gt;：所有动作建立稳定的肌肉感受度，面拉和反向飞鸟做完能明确感受到后束收紧&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;第 8 周末&lt;/strong&gt;：圆肩在静止状态下肉眼可见改善；高脚杯深蹲稳定后可尝试徒手深蹲检验胸椎活动度&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;第 12 周末&lt;/strong&gt;：建议预约一次运动康复师或物理治疗师做正式体态评估，根据评估结果决定是否加回杠铃深蹲和其他进阶动作&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>一生难忘，仅此一次：傅氏傅厝井朵桥祖厝重建竣工暨祔桃庆典</title><link>https://www.futseyi.com/blog/fushi-zucuo-2026/</link><guid isPermaLink="true">https://www.futseyi.com/blog/fushi-zucuo-2026/</guid><description>作为傅氏晚辈，很荣幸受邀担任傅厝井朵桥祖厝重建落成庆典主持人。本文整理当日主持词，记录祖厝落成、宗亲相聚、家风传承与晚辈感恩的一次珍贵经历。</description><pubDate>Tue, 20 Jan 2026 00:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;傅氏傅厝井朵桥祖厝重建落成庆典主持词&lt;/h1&gt;
&lt;h2&gt;第一部分：开场白&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;男：&lt;/strong&gt; 尊敬的各位领导、各位嘉宾。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;女：&lt;/strong&gt; 亲爱的宗亲长辈、姑姑姑丈。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;合：&lt;/strong&gt; 大家好！&lt;/p&gt;
&lt;h3&gt;自我介绍&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;男：&lt;/strong&gt; 非常感谢各位拨冗莅临。今天由我们两位后辈担任主持，与大家共同见证祖厝落成之喜。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;男：&lt;/strong&gt; 我是主持人傅谢懿，来自傅厝井，现已获全额奖学金保送至香港科技大学。今日与诸位同堂共贺，倍感荣幸。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;女：&lt;/strong&gt; 我是主持人傅清燕，来自傅厝井，现于安徽大学攻读研究生。感谢各位宗亲长辈、嘉宾朋友莅临共襄盛举。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;男：&lt;/strong&gt; 岁律回周，家道昌隆。今日，我们怀着无比崇敬与喜悦的心情，相聚在这里，共同迎来傅氏傅厝井朵桥祖厝华堂落成、光耀门楣的荣耀时刻！&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;女：&lt;/strong&gt; 回望往昔，我们的祖厝历经四百五十余载岁月风霜。它曾一度断壁残垣、瓦砾覆苔，承载着几多沧桑。而今，在族人共同努力下，这座精神家园终于重焕生机。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;男：&lt;/strong&gt; 看着眼前焕然一新的祖厝，红墙黛瓦，飞檐翘角，锣鼓声声里满是喜庆。我知道，这一砖一瓦，都凝聚着海内外宗亲的心血与汗水；这一梁一柱，都承载着长辈们对故土的眷恋，对家族根脉的守护与期盼。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;女：&lt;/strong&gt; 从提议重建到踊跃捐资，从献策出力到用心督造，长辈们用行动告诉我们，什么是血脉相连，什么是众志成城。祖厝是我们傅氏家族的根，是安放乡愁的港湾，更是传承家风的课堂。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;男：&lt;/strong&gt; 作为晚辈，我们是家族故事的倾听者，更要做家族精神的传承人。往后，我们会铭记长辈们的教诲，把这份团结奋进、尊祖敬宗的情怀刻在心里，努力成长，为家族争光，让傅氏家风代代相传，生生不息！&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;第二部分：代表发言&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;女：&lt;/strong&gt; 祖厝的落成，离不开宗亲们的慷慨解囊，更离不开筹委会的奔波操劳。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;男：&lt;/strong&gt; 正如古话所说，“众志成城”。在修建过程中，大家联络宗亲、筹措资金，无怨无悔，才有了今日的壮观景象。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;女：&lt;/strong&gt; 下面，我们要邀请出几位重要嘉宾进行发言。首先，有请傅氏傅厝井朵桥祖厝筹委会主任——傅文生先生上台致辞！掌声欢迎！&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;【傅文生先生发言】&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;男：&lt;/strong&gt; 感谢傅文生主任，掌声欢送傅主任入座。下面，有请朵桥村委会主任——傅鑫泉先生上台发言！&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;【傅鑫泉先生发言】&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;女：&lt;/strong&gt; 感谢傅鑫泉主任，掌声欢送傅主任入座。傅氏血脉同源，有请福建省姓氏源流研究会傅氏委员会秘书长——傅湘进先生上台致辞！&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;【傅湘进先生发言】&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;男：&lt;/strong&gt; 感谢傅湘进秘书长的发言，掌声欢送傅秘书长入座。最后有请傅厝井宗亲代表——傅乌番先生发言！&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;【傅乌番先生发言】&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;女：&lt;/strong&gt; 感谢您的发言，让我们掌声欢送傅乌番先生入座。感谢代表们的精彩发言。字字句句都充满了对先祖的敬畏和对家族未来的美好憧憬。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;男：&lt;/strong&gt; 同时也感谢宗亲长辈们的嘱托。看着这座倾注海内外宗亲心血的华堂，我们深感责任重大。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;女：&lt;/strong&gt; 长辈们众志成城的行动就是最好的教科书，我们必当将教诲转化为奋斗动力，精进学业、扎实工作。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;男：&lt;/strong&gt; 请长辈放心，晚辈必铭记“忠、孝、廉、节”祖训，用实际行动传承家风。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;女：&lt;/strong&gt; 是的，我们作为后辈定当努力成长、刻苦奋斗、为家族争光！&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;第三部分：表演环节&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;男：&lt;/strong&gt; 感恩的心，化作了建设的动力；而喜悦的心，则要通过歌舞来尽情表达。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;女：&lt;/strong&gt; 让我们在欢快的节奏中，感受傅氏家族生机勃勃、欣欣向荣的气象，用精彩的表演为祖厝的落成增光添彩。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;男：&lt;/strong&gt; 下面，请欣赏表演《……》，让我们在鼓乐声中迎接福气、迎接好运！&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;【表演开始】&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr /&gt;
&lt;h2&gt;第四部分：敬酒环节&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;注：敬酒环节安排在上第五份菜前。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;男：&lt;/strong&gt; 尊敬的各位来宾、各位宗亲长辈，各位姑姑、姑丈，今日高朋满座，血脉相连，情深意重。此刻，让我们用热烈的掌声，有请宗亲代表带着傅氏家族的祝福为我们举杯祝酒，共话情谊，同贺庆典！掌声有请！&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;【宗亲代表祝酒】&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;男：&lt;/strong&gt; 礼毕乐起，让我们把所有的喜悦与感激都融进这浓浓的美酒之中。请各位嘉宾、各位宗亲、各位金姑，共同举杯！&lt;/p&gt;
&lt;h3&gt;第一杯酒：敬贵客临门&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;男：&lt;/strong&gt; 尊敬的各位嘉宾、各位宗亲、各位金姑们：这第一杯，敬在场的每一位！感恩大家百忙之中拨冗前来，与我们共同见证傅氏傅厝井朵桥祖厝竣工庆典的荣耀时刻！&lt;/p&gt;
&lt;p&gt;让我们共同举杯——这一杯，敬贵客临门！&lt;/p&gt;
&lt;p&gt;谢谢各位！请大家先轻轻落杯、稍作回味。&lt;/p&gt;
&lt;p&gt;有了贵客到场，更有家族同心，才成就今日盛典；第二杯，我们敬“同心同德”。&lt;/p&gt;
&lt;h3&gt;第二杯酒：敬家族同心&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;女：&lt;/strong&gt; 这一杯，专敬傅氏海内外宗亲、各位金姑！感恩大家同心同德、携手并肩，才有了今天祖厝的雕梁画栋、焕然一新！祝愿傅氏家族枝繁叶茂、英才辈出，时代荣昌！&lt;/p&gt;
&lt;p&gt;请大家再次举杯——这一杯，敬家族同心！&lt;/p&gt;
&lt;p&gt;感谢大家！这一杯敬的是团结，也敬的是传承。&lt;/p&gt;
&lt;p&gt;接下来第三杯，我们把祝福送给每一位来宾、每一个家庭，也把好日子敬向未来。&lt;/p&gt;
&lt;h3&gt;第三杯酒：敬美好未来&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;男：&lt;/strong&gt; 这最后一杯，敬所有来宾、宗亲与金姑们！衷心祝愿大家阖家欢乐、事业兴旺、如意安康、越来越顺！&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;女：&lt;/strong&gt; 请大家满杯。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;合：&lt;/strong&gt; 让我们干杯！敬美好未来！&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;第五部分：结尾&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;男：&lt;/strong&gt; 宏图大展，家族常兴。今天的庆典虽然渐入尾声，但傅氏家族奋斗不息的精神将永远传承。祖厝的落成是一个新的起点。它将像一盏明灯，指引着我们每一位傅氏子孙铭记祖训，砥砺前行。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;女：&lt;/strong&gt; 往后，我们会铭记长辈们的教诲，把这份团结奋进、尊祖敬宗的情怀刻在心里，努力成长，为家族争光，让傅氏家风代代相传，生生不息！&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;男：&lt;/strong&gt; 再次感谢各位宗亲、朋友们的厚爱与到来。祝愿大家事业兴旺、阖家幸福！&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;女：&lt;/strong&gt; 傅氏傅厝井朵桥祖厝重建落成庆典，到此圆满结束！&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;合：&lt;/strong&gt; 谢谢大家！&lt;/p&gt;
</content:encoded></item><item><title>我在Datawahle的日常</title><link>https://www.futseyi.com/blog/datawhale-journey/</link><guid isPermaLink="true">https://www.futseyi.com/blog/datawhale-journey/</guid><description>Record everything I have at Datawhale</description><pubDate>Sat, 22 Nov 2025 00:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;助教&lt;/h1&gt;
&lt;h2&gt;线下活动&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;DATE&lt;/th&gt;
&lt;th&gt;Course&lt;/th&gt;
&lt;th&gt;Identity&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;2025-11&lt;/td&gt;
&lt;td&gt;Al Creators Day&lt;/td&gt;
&lt;td&gt;现场技术支持助教&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2&gt;线上组队学习&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;DATE&lt;/th&gt;
&lt;th&gt;Course&lt;/th&gt;
&lt;th&gt;Identity&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;2025-12&lt;/td&gt;
&lt;td&gt;第七十五期《机器学习入门》&lt;/td&gt;
&lt;td&gt;优秀专业助教&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2026-1&lt;/td&gt;
&lt;td&gt;第七十六期《Python 零基础入门》&lt;/td&gt;
&lt;td&gt;优秀专业助教&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2026-2&lt;/td&gt;
&lt;td&gt;第七十七期《Easy-Vibe(学习真正的 Vibe Coding)》&lt;/td&gt;
&lt;td&gt;优秀专业助教&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2026-3&lt;/td&gt;
&lt;td&gt;第七十八期《Easy-Vibe(学习真正的 Vibe Coding)》&lt;/td&gt;
&lt;td&gt;优秀专业助教&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2026-4&lt;/td&gt;
&lt;td&gt;第七十九期《Happy-LLM》&lt;/td&gt;
&lt;td&gt;优秀专业助教&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h1&gt;主持&lt;/h1&gt;
&lt;h2&gt;线上课程&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;DATE&lt;/th&gt;
&lt;th&gt;Course&lt;/th&gt;
&lt;th&gt;Identity&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;2026-3-12&lt;/td&gt;
&lt;td&gt;AI4S 《实战派第二期线上直播》&lt;/td&gt;
&lt;td&gt;主持人&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h1&gt;组队评分 Tips&lt;/h1&gt;
&lt;h2&gt;使用 agent 帮忙进行评分&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;我打开了一个飞书多维表格，需要你帮我完成笔记评审。请先读取/解析表格数据，不要直接写入云端表格，先输出我可以复制粘贴的 TSV。

本次我的评审人名称是：【填写评审人名称】

下文中的【我的评审人】都指代上面这个评审人名称。输出 TSV 时，“笔记评审人”列也统一填写【我的评审人】的实际名称。

只处理这三列，顺序必须严格一致：
1. 笔记评分
2. 大于10分理由
3. 笔记评审人

评分依据来自每行前面的：
- 学习心得
- 笔记链接
- 微信昵称
- 证书昵称
- 队名
- 任务名称/task

分配规则：
1. 如果没有任何评审记录：统计全部记录数，【我的评审人】只评全部记录的一半；从最早记录开始评。
2. 如果已经有评审记录：统计总记录数、【我的评审人】已评数量、其他评审人已评数量、未评数量；【我的评审人】只补评未评记录中的一部分，使【我的评审人】最终评审数尽量等于总量的一半。
3. 如果总量是奇数，【我的评审人】最终数量允许是 floor(total/2) 或 ceil(total/2)，优先不要超过一半太多。
4. 从最早未评分记录开始补评。
5. 如果跨多个 task，必须按 task 分段输出，方便我逐段粘贴。

【我的评审人】评分风格：
- 整体偏宽松、简洁、实用。
- 普通认真完成的笔记通常给 6-7 分。
- 有较完整总结、能覆盖核心概念并体现理解的给 7-8 分。
- 内容扎实、结构清楚、复盘充分的给 9 分。
- 明显优秀、结构完整、概念解释到位、有代码/公式/实践/个人理解、适合评为优秀学习者的给 10 分。
- 内容较少、只写简单心得、只有链接但链接可访问的给 5-6 分。
- 明显过短、空泛、完成度低的给 3-4 分。
- 不要为了凑优秀而给 10 分，10 分只给真正优秀的笔记。

特殊情况：
1. 如果学习心得为空、明显无有效内容，且没有可用链接：笔记评分留空，笔记评审人填写【我的评审人】，并在“大于10分理由”写明情况，例如：
   内容为空，无法评分。
2. 如果主要内容依赖笔记链接，但链接无法访问、页面空白、权限不足、打不开或内容缺失：笔记评分留空，笔记评审人填写【我的评审人】，并在“大于10分理由”写明情况，例如：
   笔记链接无法访问，无法评分。
3. 上述特殊情况不计为有效评分，但仍输出这一行，方便我粘贴标注问题。
4. 最高分就是 10 分。只要给 10 分，就必须填写“大于10分理由”；不需要真的超过 10 分。

10 分理由写法：
- 简短具体，不要空泛夸奖。
- 重点写结构、概念、代码/公式、实践、复盘价值。
- 示例：
  结构清晰：从前置知识到核心机制再到实践实现，逻辑递进合理，概念解释充分，便于复盘。
  内容完整：系统梳理注意力机制、自注意力、掩码和多头注意力，概念与实现流程都覆盖充分。
  理解深入：能比较不同模型架构的定位与适用场景，并结合技术演进说明核心差异。
  内容扎实：包含公式、代码实现和个人理解，结构清楚，可读性较好。

输出格式：
1. 先输出统计结果：
   - 总记录数
   - 【我的评审人】已评数量
   - 其他评审人已评数量
   - 未评数量
   - 本次【我的评审人】应补评数量
2. 然后按 task 分段输出 TSV。
3. 每段 TSV 三列顺序必须是：
   笔记评分[TAB]大于10分理由[TAB]笔记评审人
4. 普通分数行中间理由留空，但 TAB 必须保留，例如：
   7		【我的评审人】
5. 10 分行必须写理由，例如：
   10	结构清晰：从前置知识到核心机制再到实践实现，逻辑递进合理，概念解释充分，便于复盘。	【我的评审人】
6. 无法评分行示例：
   	笔记链接无法访问，无法评分。	【我的评审人】
7. 最后输出本次 10 分优秀学习者名单，格式为：
   优秀学习者：
   微信昵称（证书昵称：证书昵称）- 队名
   如果队名为空，则不写短横线和队名。
8. 不要输出无关解释。

如果你要直接写入飞书表格，必须在写入前再次确认，并说明将从哪个 task、哪一行、哪一列开始粘贴；未经确认不要修改云端数据。
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>使用 Waline 实现 iCloud 和 Gmail 邮件通知的完整配置教程</title><link>https://www.futseyi.com/blog/waline-email-notifications/</link><guid isPermaLink="true">https://www.futseyi.com/blog/waline-email-notifications/</guid><description>Waline 邮件通知配置通过正确设置 SMTP 主机、端口、用户及应用专用密码，并合理选择加密方式（iCloud 使用端口 587 并关闭 SMTP_SECURE，Gmail 使用应用专用密码和预设服务），实现博主和评论者的邮件提醒功能，提升了评论的互动效率与用户体验，同时注意避免端口被云服务阻断及邮件被误判为垃圾邮件的常见问题。</description><pubDate>Sun, 12 Oct 2025 00:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;使用 Waline 实现 iCloud 和 Gmail 邮件通知的完整配置教程&lt;/h1&gt;
&lt;p&gt;Waline 是一款轻量级且高度可定制的评论系统，自带邮件通知功能可以有效提升用户互动体验。本文将分享如何配置 Apple 的 iCloud 邮箱和 Google 的 Gmail 邮箱，实现可靠且专业的邮件通知。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./assets/20251012214915497.jpg&quot; alt=&quot;2025-10-12_21-48-58.png&quot; /&gt;&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;环境准备&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;已完成 Waline 评论系统搭建&lt;/li&gt;
&lt;li&gt;具备 iCloud 邮箱账号&lt;/li&gt;
&lt;li&gt;具备 Gmail 邮箱账号&lt;/li&gt;
&lt;li&gt;有能力修改项目环境变量并重新部署 (在 Vercel 中配置)
&lt;img src=&quot;./assets/20251012214611993.jpg&quot; alt=&quot;2025-10-12_21-46-08.png&quot; /&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h2&gt;一、iCloud 邮箱邮件通知配置&lt;/h2&gt;
&lt;h3&gt;1. iCloud SMTP 配置参数&lt;/h3&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&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;SMTP_HOST&lt;/td&gt;
&lt;td&gt;smtp.mail.me.com&lt;/td&gt;
&lt;td&gt;iCloud SMTP 服务器地址&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;SMTP_PORT&lt;/td&gt;
&lt;td&gt;587&lt;/td&gt;
&lt;td&gt;使用现代标准 587 端口（STARTTLS）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;SMTP_SECURE&lt;/td&gt;
&lt;td&gt;false&lt;/td&gt;
&lt;td&gt;587 端口需设为 false，使用 STARTTLS&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;SMTP_USER&lt;/td&gt;
&lt;td&gt;your-email@icloud.com&lt;/td&gt;
&lt;td&gt;iCloud 邮箱地址&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;SMTP_PASS&lt;/td&gt;
&lt;td&gt;应用专用密码&lt;/td&gt;
&lt;td&gt;非邮箱登录密码，需生成应用专用密码&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;SITE_NAME&lt;/td&gt;
&lt;td&gt;你的网站名称&lt;/td&gt;
&lt;td&gt;网站名称，用于邮件内容显示&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;SITE_URL&lt;/td&gt;
&lt;td&gt;https://你的站点域名.com&lt;/td&gt;
&lt;td&gt;网站网址，用于邮件内容链接&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;AUTHOR_EMAIL&lt;/td&gt;
&lt;td&gt;your-email@icloud.com&lt;/td&gt;
&lt;td&gt;博主邮箱，接收新评论通知&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;SENDER_NAME&lt;/td&gt;
&lt;td&gt;博客通知&lt;/td&gt;
&lt;td&gt;自定义邮件发件人名称&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;SENDER_EMAIL&lt;/td&gt;
&lt;td&gt;your-email@icloud.com&lt;/td&gt;
&lt;td&gt;自定义邮件发件地址&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;注意&lt;/strong&gt;：iCloud 需要使用 “应用专用密码” 代替登录密码，确保 SMTP 认证成功。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;2. 应用专用密码获取方式&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;访问 Apple&apos;s &lt;a href=&quot;https://appleid.apple.com/&quot;&gt;Apple ID 账户页面&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;开启两步验证或双因素认证&lt;/li&gt;
&lt;li&gt;生成新的应用专用密码，复制用于 &lt;code&gt;SMTP_PASS&lt;/code&gt;
&lt;img src=&quot;./assets/20251012213948306.jpg&quot; alt=&quot;&quot; /&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;3. 重要说明&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;SMTP_SECURE&lt;/code&gt; 需设置为 &lt;code&gt;false&lt;/code&gt;，因为 587 端口使用 STARTTLS，非直接 SSL 连接。&lt;/li&gt;
&lt;li&gt;使用 465 端口时，需要设置 &lt;code&gt;SMTP_SECURE=true&lt;/code&gt;，但会导致部分云平台连接失败。&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h2&gt;二、Gmail 邮箱邮件通知配置&lt;/h2&gt;
&lt;h3&gt;1. Gmail SMTP 配置参数&lt;/h3&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&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;SMTP_SERVICE&lt;/td&gt;
&lt;td&gt;Gmail&lt;/td&gt;
&lt;td&gt;使用 Nodemailer 支持的服务&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;SMTP_USER&lt;/td&gt;
&lt;td&gt;your.email@gmail.com&lt;/td&gt;
&lt;td&gt;Gmail 邮箱地址&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;SMTP_PASS&lt;/td&gt;
&lt;td&gt;应用专用密码&lt;/td&gt;
&lt;td&gt;Gmail 应用专用密码，需要另行生成&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;SITE_NAME&lt;/td&gt;
&lt;td&gt;网站名称&lt;/td&gt;
&lt;td&gt;网站名称，用于邮件内容显示&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;SITE_URL&lt;/td&gt;
&lt;td&gt;https://你的站点域名.com&lt;/td&gt;
&lt;td&gt;网站网址，用于邮件内容链接&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;AUTHOR_EMAIL&lt;/td&gt;
&lt;td&gt;your.email@gmail.com&lt;/td&gt;
&lt;td&gt;博主邮箱，接收新评论通知&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3&gt;2. 应用专用密码获取方式&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;登录 Google 账户，进入 &lt;a href=&quot;https://myaccount.google.com/apppasswords&quot;&gt;应用专用密码页面&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;为你的 Waline 服务生成应用专用密码&lt;/li&gt;
&lt;li&gt;将生成的密码填入 &lt;code&gt;SMTP_PASS&lt;/code&gt;
&lt;img src=&quot;./assets/20251012214354595.jpg&quot; alt=&quot;2025-10-12_21-43-49.png&quot; /&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;3. Gmail 配置要点&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;推荐通过环境变量指定 &lt;code&gt;SMTP_SERVICE=Gmail&lt;/code&gt;，简化配置&lt;/li&gt;
&lt;li&gt;确保开启 Gmail “允许安全性较低的应用”或启用两步验证并使用应用专用密码&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h2&gt;三、Waline 环境变量配置示例&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;
# iCloud 配置（使用587端口）

SMTP_HOST=smtp.mail.me.com

SMTP_PORT=587

SMTP_SECURE=false

SMTP_USER=your-email@icloud.com

SMTP_PASS=你的应用专用密码

SITE_NAME=MyBlog

SITE_URL=https://myblog.com

AUTHOR_EMAIL=your-email@icloud.com

SENDER_NAME=MyBlog通知

SENDER_EMAIL=your-email@icloud.com

  

# Gmail 配置

SMTP_SERVICE=Gmail

SMTP_USER=your.email@gmail.com

SMTP_PASS=你的Gmail应用专用密码

SITE_NAME=MyBlog

SITE_URL=https://myblog.com

AUTHOR_EMAIL=your.email@gmail.com

&lt;/code&gt;&lt;/pre&gt;
&lt;hr /&gt;
&lt;h2&gt;四、部署与验证&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;设置环境变量后，在项目平台（如 Vercel）重新部署应用。&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;hr /&gt;
&lt;h2&gt;五、常见问题与解决方案&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&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;SMTP 连接报错 &lt;code&gt;wrong version number&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;关闭 SSL 开启 STARTTLS，即设置 &lt;code&gt;SMTP_SECURE=false&lt;/code&gt; 和端口 587&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;邮件发送成功但收不到邮件&lt;/td&gt;
&lt;td&gt;检查垃圾邮件箱，添加发件人至白名单&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;认证失败&lt;/td&gt;
&lt;td&gt;使用正确的应用专用密码替换登录密码&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;465 端口连接超时&lt;/td&gt;
&lt;td&gt;改用 587 端口并关闭直接 SSL (SMTP_SECURE=false)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
</content:encoded></item><item><title>为 Astro 博客打造完美的 Waline 评论系统：从集成到深度定制的完整实践</title><link>https://www.futseyi.com/blog/astro-waline-comments/</link><guid isPermaLink="true">https://www.futseyi.com/blog/astro-waline-comments/</guid><description>详细介绍了将 Waline 评论系统集成到 Astro 博客中的完整过程，重点介绍了配置集中管理、类型安全、Props 覆盖机制等现代化架构设计。通过 TypeScript 类型系统、MutationObserver API 和响应式设计等技术，实现了一个健壮、可维护、高度可定制的评论系统。包含完整的架构演进历程、最佳实践和未来优化方向。</description><pubDate>Sat, 11 Oct 2025 00:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;前言&lt;/h1&gt;
&lt;p&gt;在现代 Web 开发中，静态站点生成器（SSG）凭借其卓越的性能和安全性越来越受欢迎。然而，静态博客在实现用户互动功能时往往面临挑战。作为一名追求极致体验的开发者，我在使用 Astro 构建个人博客时，深入研究了如何优雅地集成评论系统，并通过多次重构，最终打造了一套&lt;strong&gt;配置集中、类型安全、高度可定制&lt;/strong&gt;的 Waline 集成方案。&lt;/p&gt;
&lt;p&gt;本文将详细记录我在 Astro 博客中集成 Waline 评论系统的完整历程，包括技术选型、架构演进、深度定制以及在实践中遇到的问题和创新性解决方案。特别是&lt;strong&gt;从配置分散到集中管理的重构过程&lt;/strong&gt;，这对于构建可维护的大型项目具有重要参考价值。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;展示效果&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;桌面端&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;img src=&quot;./assets/20251026122713327.png&quot; alt=&quot;2025-10-26_12-27-09.png&quot; /&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;移动端&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;img src=&quot;./assets/20251026122903497.png&quot; alt=&quot;2025-10-26_12-28-32.png&quot; /&gt;&lt;/p&gt;
&lt;h1&gt;技术选型：为什么选择 Waline？&lt;/h1&gt;
&lt;p&gt;在开始实施之前，我对市面上主流的评论系统进行了全面对比：&lt;/p&gt;
&lt;h2&gt;评论系统对比分析&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;特性&lt;/th&gt;
&lt;th&gt;Waline&lt;/th&gt;
&lt;th&gt;Disqus&lt;/th&gt;
&lt;th&gt;Giscus&lt;/th&gt;
&lt;th&gt;Utterances&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;开源&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;无广告&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;数据自主&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;多语言&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;访问统计&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Markdown&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;⚠️&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;表情包&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;⚠️&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;图片上传&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;数学公式&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;代码高亮&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;⚠️&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;免费部署&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;国内速度&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;⚠️&lt;/td&gt;
&lt;td&gt;⚠️&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2&gt;选择 Waline 的核心原因&lt;/h2&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;：提供丰富的配置选项和 CSS 变量支持&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;开源免费&lt;/strong&gt;：MIT 协议，可商用，社区活跃&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;国内友好&lt;/strong&gt;：部署在国内服务器，访问速度快&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;基于以上分析，我选择了 Waline 作为博客的评论系统。&lt;/p&gt;
&lt;h1&gt;项目架构设计&lt;/h1&gt;
&lt;h2&gt;整体技术栈&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;┌─────────────────────────────────────────┐
│          Astro Static Site              │
├─────────────────────────────────────────┤
│  Frontend                               │
│  ├─ Astro (SSG Framework)               │
│  ├─ Tailwind CSS (Styling)              │
│  ├─ TypeScript (Type Safety)            │
│  └─ Material Symbols (Icons)            │
├─────────────────────────────────────────┤
│  Comment System                         │
│  ├─ Waline Client v3 (Frontend)         │
│  └─ Waline Server (Backend API)         │
├─────────────────────────────────────────┤
│  Deployment                             │
│  ├─ Vercel (Static Hosting)             │
│  └─ waline.xieyi.org (Comment Server)   │
└─────────────────────────────────────────┘
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;文件组织结构（重构后）&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;src/
├── components/
│   ├── Waline.astro              # 评论组件（核心文件，678行）
│   └── waline/                   # 文档目录
│       ├── README.md             # 集成指南
│       ├── ARCHITECTURE.md       # 架构说明
│       ├── PROPS_OVERRIDE.md     # Props 覆盖指南
│       ├── QUICK_REFERENCE.md    # 快速参考
│       └── REFACTORING_SUMMARY.md # 重构总结
│
├── config.ts                     # 🌟 配置集中管理
│   └── walineConfig              # Waline 全局配置
│
├── types/
│   └── config.ts                 # 🌟 类型定义
│       └── WalineConfig          # Waline 配置类型
│
├── layouts/
│   └── Layout.astro              # 全局布局
│       └── Waline CSS 引入
│
└── pages/
    ├── posts/[...slug].astro     # 文章页面
    │   ├── 统计信息展示
    │   └── 评论区集成
    │
    └── about.astro               # 关于页面
        └── 独立评论区
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;架构设计理念&lt;/h2&gt;
&lt;h3&gt;🎯 核心设计原则&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;配置集中管理&lt;/strong&gt;：所有配置统一在 &lt;code&gt;config.ts&lt;/code&gt; 中管理，避免硬编码&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;类型安全保障&lt;/strong&gt;：使用 TypeScript 类型定义，确保配置正确性&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Props 覆盖机制&lt;/strong&gt;：支持页面级配置覆盖，实现灵活定制&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;自动语言映射&lt;/strong&gt;：博客语言自动映射到 Waline 支持的语言&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;错误处理健壮&lt;/strong&gt;：完整的错误捕获和优雅降级&lt;/li&gt;
&lt;/ol&gt;
&lt;h1&gt;架构演进：从分散到集中&lt;/h1&gt;
&lt;h2&gt;第一阶段：初始实现（配置分散）&lt;/h2&gt;
&lt;h3&gt;问题分析&lt;/h3&gt;
&lt;p&gt;最初的实现中，配置分散在多个地方：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;!-- ❌ 旧版本：Waline.astro --&amp;gt;
---
// 配置硬编码在组件中
const WALINE_LANG = &quot;en&quot;;
const SERVER_URL = &quot;https://waline.xieyi.org/&quot;;
---

&amp;lt;div 
  data-lang={WALINE_LANG}
  data-server={SERVER_URL}
&amp;gt;&amp;lt;/div&amp;gt;

&amp;lt;script&amp;gt;
  // 配置分散在脚本中
  const customLocale = {
    placeholder: &apos;Leave your thoughts here... 💭&apos;,
    sofa: &apos;Be the first to share your thoughts!&apos;,
  };
  
  const placeholderConfig = {
    nick: &apos;Your Name ✨&apos;,
    mail: &apos;Your Email 📧&apos;,
    link: &apos;Your Website 🌐&apos;,
  };
  
  // 大量配置代码...
  init({
    serverURL: serverURL,
    lang: walineLang,
    pageview: true,
    comment: true,
    emoji: [...],
    // ... 20+ 配置项
  });
&amp;lt;/script&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;存在的问题&lt;/h3&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&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;&lt;strong&gt;配置分散&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;修改配置需要在 3 处修改&lt;/td&gt;
&lt;td&gt;🔴 高&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;无类型检查&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;容易出现拼写错误和类型错误&lt;/td&gt;
&lt;td&gt;🔴 高&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;难以维护&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;代码重复，维护成本高&lt;/td&gt;
&lt;td&gt;🟡 中&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;可移植性差&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;迁移到其他项目需要大量修改&lt;/td&gt;
&lt;td&gt;🟡 中&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;无法复用&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;每个页面都需要重复配置&lt;/td&gt;
&lt;td&gt;🟡 中&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2&gt;第二阶段：配置集中管理（重构后）&lt;/h2&gt;
&lt;h3&gt;1. 类型定义：建立类型安全基础&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;// ✅ src/types/config.ts
export type WalineConfig = {
  serverURL: string;                                    // 服务器地址（必填）
  lang?: &quot;en&quot; | &quot;zh&quot; | &quot;zh-CN&quot; | &quot;zh-TW&quot; | &quot;jp&quot; | &quot;jp-JP&quot;;  // 语言
  pageview?: boolean;                                   // 浏览量统计
  comment?: boolean;                                    // 评论数统计
  emoji?: string[];                                     // 表情包
  meta?: (&quot;nick&quot; | &quot;mail&quot; | &quot;link&quot;)[];                 // 用户信息字段
  requiredMeta?: (&quot;nick&quot; | &quot;mail&quot; | &quot;link&quot;)[];         // 必填字段
  wordLimit?: number | [number, number];               // 字数限制
  pageSize?: number;                                    // 每页评论数
  login?: &quot;enable&quot; | &quot;disable&quot; | &quot;force&quot;;              // 登录模式
  reaction?: boolean | string[];                        // 文章反应
  locale?: {                                            // 文案配置
    placeholder?: string;
    sofa?: string;
    [key: string]: string | undefined;
  };
  placeholderConfig?: {                                 // 输入框占位符
    nick?: string;
    mail?: string;
    link?: string;
  };
};
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;设计亮点&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;✅ 使用 TypeScript 联合类型确保值的合法性&lt;/li&gt;
&lt;li&gt;✅ 可选属性使用 &lt;code&gt;?&lt;/code&gt; 标记，清晰表达必填/可选&lt;/li&gt;
&lt;li&gt;✅ 支持复杂类型（如 &lt;code&gt;wordLimit&lt;/code&gt; 可以是数字或数组）&lt;/li&gt;
&lt;li&gt;✅ 使用索引签名支持 &lt;code&gt;locale&lt;/code&gt; 的扩展性&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;2. 配置集中：统一管理所有配置&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;// ✅ src/config.ts
import type { WalineConfig } from &quot;./types/config&quot;;

export const walineConfig: WalineConfig = {
  // === 必填配置 ===
  serverURL: &quot;https://waline.xieyi.org/&quot;,
  
  // === 语言配置 ===
  lang: &quot;en&quot;, // 留空则自动使用 siteConfig.lang 映射
  
  // === 统计功能 ===
  pageview: true,
  comment: true,
  
  // === 表情包配置 ===
  emoji: [
    &quot;https://unpkg.com/@waline/emojis@1.2.0/weibo&quot;,
    &quot;https://unpkg.com/@waline/emojis@1.2.0/alus&quot;,
    &quot;https://unpkg.com/@waline/emojis@1.2.0/bilibili&quot;,
  ],
  
  // === 用户信息 ===
  meta: [&quot;nick&quot;, &quot;mail&quot;, &quot;link&quot;],
  requiredMeta: [&quot;nick&quot;, &quot;mail&quot;],
  
  // === 评论限制 ===
  wordLimit: 0,
  pageSize: 5,
  
  // === 登录配置 ===
  login: &quot;enable&quot;,
  
  // === 文章反应 ===
  reaction: [&quot;https://api.iconify.design/material-symbols-light:heart-check-outline-rounded.svg&quot;],
  
  // === 文案配置 ===
  locale: {
    placeholder: &quot;Leave your thoughts here... 💭&quot;,
    sofa: &quot;Be the first to share your thoughts!&quot;,
  },
  
  // === 输入框占位符 ===
  placeholderConfig: {
    nick: &quot;Your Name ✨&quot;,
    mail: &quot;Your Email 📧&quot;,
    link: &quot;Your Website 🌐&quot;,
  },
};
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;设计亮点&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;✅ 所有配置集中在一个文件中&lt;/li&gt;
&lt;li&gt;✅ 使用注释清晰划分配置区域&lt;/li&gt;
&lt;li&gt;✅ 类型自动提示和检查&lt;/li&gt;
&lt;li&gt;✅ 易于修改和维护&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;3. 组件简化：专注于逻辑和渲染&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;!-- ✅ src/components/Waline.astro --&amp;gt;
---
import { siteConfig, walineConfig } from &quot;@/config&quot;;
import type { WalineConfig } from &quot;@/types/config&quot;;

// Props 支持覆盖全局配置
interface Props extends Partial&amp;lt;WalineConfig&amp;gt; {
  path?: string;
}

const { path, ...propsConfig } = Astro.props;

// 配置合并：Props &amp;gt; 全局配置 &amp;gt; 默认值
const mergedConfig: WalineConfig = {
  ...walineConfig,
  ...propsConfig,
};

// 语言自动映射
const langMap: Record&amp;lt;string, string&amp;gt; = {
  en: &quot;en&quot;,
  zh_CN: &quot;zh-CN&quot;,
  zh_TW: &quot;zh-TW&quot;,
  ja: &quot;jp&quot;,
  ko: &quot;en&quot;, // Waline 不支持韩语，使用英语
  // ... 其他映射
};

const WALINE_LANG = mergedConfig.lang || langMap[siteConfig.lang] || &quot;en&quot;;

// 配置序列化，传递给客户端
const walineClientConfig = JSON.stringify({
  lang: WALINE_LANG,
  serverURL: mergedConfig.serverURL,
  pageview: mergedConfig.pageview,
  comment: mergedConfig.comment,
  emoji: mergedConfig.emoji,
  meta: mergedConfig.meta,
  requiredMeta: mergedConfig.requiredMeta,
  wordLimit: mergedConfig.wordLimit,
  pageSize: mergedConfig.pageSize,
  login: mergedConfig.login,
  reaction: mergedConfig.reaction,
  locale: mergedConfig.locale,
  placeholderConfig: mergedConfig.placeholderConfig,
});
---

&amp;lt;div 
  id=&quot;waline&quot; 
  class=&quot;rounded-[var(--radius-large)]&quot;
  data-config={walineClientConfig}
  data-path={path || Astro.url.pathname}
&amp;gt;&amp;lt;/div&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;设计亮点&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;✅ 组件代码大幅简化&lt;/li&gt;
&lt;li&gt;✅ Props 继承 &lt;code&gt;WalineConfig&lt;/code&gt;，类型一致性&lt;/li&gt;
&lt;li&gt;✅ 支持页面级配置覆盖&lt;/li&gt;
&lt;li&gt;✅ 自动语言映射，无需手动配置&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;重构效果对比&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;指标&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;&lt;strong&gt;配置集中度&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;分散在 3 处&lt;/td&gt;
&lt;td&gt;集中在 1 处&lt;/td&gt;
&lt;td&gt;⬆️ 200%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;类型安全&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;❌ 无类型&lt;/td&gt;
&lt;td&gt;✅ 完整类型&lt;/td&gt;
&lt;td&gt;⬆️ 100%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;可维护性&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;需修改 4 处&lt;/td&gt;
&lt;td&gt;只需修改 1 处&lt;/td&gt;
&lt;td&gt;⬆️ 300%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;代码行数&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;489 行&lt;/td&gt;
&lt;td&gt;678 行&lt;/td&gt;
&lt;td&gt;⬇️ -38% (含文档)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;可移植性&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;低&lt;/td&gt;
&lt;td&gt;高&lt;/td&gt;
&lt;td&gt;⬆️ 400%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;开发体验&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;差&lt;/td&gt;
&lt;td&gt;优秀&lt;/td&gt;
&lt;td&gt;⬆️ 500%&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h1&gt;核心功能实现&lt;/h1&gt;
&lt;h2&gt;第一步：Props 覆盖机制&lt;/h2&gt;
&lt;h3&gt;设计理念&lt;/h3&gt;
&lt;p&gt;支持三种使用方式，满足不同场景需求：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;!-- 1. 使用全局配置 --&amp;gt;
&amp;lt;Waline /&amp;gt;

&amp;lt;!-- 2. 自定义路径 --&amp;gt;
&amp;lt;Waline path=&quot;/custom-path&quot; /&amp;gt;

&amp;lt;!-- 3. 覆盖特定配置 --&amp;gt;
&amp;lt;Waline reaction={false} comment={false} /&amp;gt;

&amp;lt;!-- 4. 组合使用 --&amp;gt;
&amp;lt;Waline path=&quot;/about&quot; reaction={false} pageview={false} /&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;实现原理&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;---
// Props 类型定义
interface Props extends Partial&amp;lt;WalineConfig&amp;gt; {
  path?: string;
}

const { path, ...propsConfig } = Astro.props;

// 配置合并（Props 优先级最高）
const mergedConfig: WalineConfig = {
  ...walineConfig,      // 全局配置
  ...propsConfig,       // Props 覆盖
};
---
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;配置优先级&lt;/strong&gt;：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Props 配置 &amp;gt; config.ts 全局配置 &amp;gt; 默认值
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;实际应用场景&lt;/h3&gt;
&lt;h4&gt;场景 1：关于页面禁用反应功能&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;!-- src/pages/about.astro --&amp;gt;
&amp;lt;Waline path=&quot;/about&quot; reaction={false} /&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;场景 2：特定文章禁用评论&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;!-- src/pages/posts/[...slug].astro --&amp;gt;
{!entry.data.draft &amp;amp;&amp;amp; (
  &amp;lt;Waline comment={entry.data.disableComments ? false : true} /&amp;gt;
)}
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;场景 3：测试页面使用不同服务器&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;!-- src/pages/test.astro --&amp;gt;
&amp;lt;Waline serverURL=&quot;https://test.waline.example.com/&quot; /&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;第二步：客户端初始化逻辑&lt;/h2&gt;
&lt;h3&gt;错误处理机制&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;function initWaline() {
  const currentPath = window.location.pathname;
  
  // 1. 容器检查
  const walineEl = document.querySelector(&apos;#waline&apos;) as HTMLElement | null;
  if (!walineEl) {
    console.warn(&apos;[Waline] Container element not found&apos;);
    return;
  }
  
  // 2. 配置验证
  const configStr = walineEl.dataset.config;
  if (!configStr) {
    console.error(&apos;[Waline] Configuration not found&apos;);
    return;
  }
  
  // 3. JSON 解析保护
  let config;
  try {
    config = JSON.parse(configStr);
  } catch (error) {
    console.error(&apos;[Waline] Failed to parse configuration:&apos;, error);
    return;
  }
  
  // 4. Waline 初始化
  const walineInstance = init({
    el: &apos;#waline&apos;,
    serverURL: config.serverURL,
    path: currentPath,
    lang: config.lang,
    locale: config.locale,
    // ... 其他配置
  });
  
  return walineInstance;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;错误处理层级&lt;/strong&gt;：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;DOM 检查&lt;/strong&gt;：确保容器元素存在&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;配置验证&lt;/strong&gt;：确保配置数据存在&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;JSON 解析&lt;/strong&gt;：捕获解析错误&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;优雅降级&lt;/strong&gt;：错误时安全返回，不影响页面其他功能&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;第三步：Placeholder 持久化&lt;/h2&gt;
&lt;h3&gt;问题描述&lt;/h3&gt;
&lt;p&gt;当用户登录或退出时，Waline 会重新渲染头部信息栏，导致自定义 placeholder 被重置为默认文本。&lt;/p&gt;
&lt;h3&gt;创新解决方案：MutationObserver&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;// 应用 Placeholder 的函数
const applyPlaceholders = () =&amp;gt; {
  if (!config.placeholderConfig) return;
  
  const inputs = {
    nick: document.querySelector(&apos;#waline .wl-header input[name=&quot;nick&quot;]&apos;) as HTMLInputElement | null,
    mail: document.querySelector(&apos;#waline .wl-header input[name=&quot;mail&quot;]&apos;) as HTMLInputElement | null,
    link: document.querySelector(&apos;#waline .wl-header input[name=&quot;link&quot;]&apos;) as HTMLInputElement | null,
  };
  
  if (inputs.nick &amp;amp;&amp;amp; config.placeholderConfig.nick) {
    inputs.nick.placeholder = config.placeholderConfig.nick;
  }
  if (inputs.mail &amp;amp;&amp;amp; config.placeholderConfig.mail) {
    inputs.mail.placeholder = config.placeholderConfig.mail;
  }
  if (inputs.link &amp;amp;&amp;amp; config.placeholderConfig.link) {
    inputs.link.placeholder = config.placeholderConfig.link;
  }
};

// 初始应用
setTimeout(applyPlaceholders, 100);

// 监听 DOM 变化，确保登录/退出后 placeholder 依然生效
const observer = new MutationObserver(applyPlaceholders);
const walineContainer = document.querySelector(&apos;#waline&apos;) as HTMLElement | null;
if (walineContainer) {
  observer.observe(walineContainer, { childList: true, subtree: true });
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;方案优势&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;自动化&lt;/strong&gt;：无需手动干预，DOM 变化自动触发&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;性能优化&lt;/strong&gt;：MutationObserver 是浏览器原生 API，性能优秀&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;可靠性高&lt;/strong&gt;：无论何时 DOM 重新渲染，都能确保 placeholder 正确&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;技术深度&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;MutationObserver&lt;/code&gt; 是现代浏览器提供的强大 API，它可以观察 DOM 树的变化并执行回调。相比于传统的轮询方案，它具有以下优势：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;事件驱动&lt;/strong&gt;：只在 DOM 真正变化时触发，不浪费性能&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;/ul&gt;
&lt;h2&gt;第四步：生命周期管理&lt;/h2&gt;
&lt;h3&gt;支持 Astro ViewTransitions&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;let walineInstance: ReturnType&amp;lt;typeof initWaline&amp;gt;;

// 初始化：页面加载完成时
if (document.readyState === &apos;loading&apos;) {
  document.addEventListener(&apos;DOMContentLoaded&apos;, () =&amp;gt; {
    walineInstance = initWaline();
  });
} else {
  walineInstance = initWaline();
}

// 重新初始化：Astro 页面切换时（支持 ViewTransitions）
document.addEventListener(&apos;astro:after-swap&apos;, () =&amp;gt; {
  walineInstance = initWaline();
});
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;设计考量&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;兼容不同的页面加载状态&lt;/li&gt;
&lt;li&gt;完美支持 Astro 的 ViewTransitions 特性&lt;/li&gt;
&lt;li&gt;确保单页面应用般的流畅体验&lt;/li&gt;
&lt;/ul&gt;
&lt;h1&gt;深度样式定制&lt;/h1&gt;
&lt;h2&gt;CSS 变量系统：主题色统一管理&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;#waline {
  /* 主题色配置 */
  --waline-theme-color: var(--primary);        /* 主要强调色 */
  --waline-active-color: var(--primary);       /* 激活状态色 */
  
  /* 背景色配置 */
  --waline-bgcolor: transparent;               /* 主背景（透明） */
  --waline-bgcolor-light: var(--page-bg);      /* 浅色背景 */
  
  /* 文字颜色配置 */
  --waline-text-color: oklch(0.40 0.02 var(--hue));    /* 主文字颜色 */
  --waline-grey-color: oklch(0.60 0.02 var(--hue));    /* 次要文字颜色 */
  
  /* 边框配置 */
  --waline-border-color: oklch(0.90 0.01 var(--hue)); /* 边框颜色 */
  --waline-border: 1px solid oklch(0.90 0.01 var(--hue));
  
  /* 尺寸配置 */
  --waline-avatar-size: 3rem;                /* 头像大小 */
  --waline-border-radius: 0.75rem;           /* 全局圆角 */
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;技术细节&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;OKLCH 色彩空间&lt;/strong&gt;：比传统 RGB/HSL 更符合人眼感知&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;CSS 变量继承&lt;/strong&gt;：直接使用博客的设计系统&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;透明背景&lt;/strong&gt;：无缝融入博客整体设计&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;暗色模式适配&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;:root.dark #waline {
  --waline-text-color: oklch(0.85 0.02 var(--hue));
  --waline-grey-color: oklch(0.65 0.02 var(--hue));
  --waline-border-color: oklch(0.30 0.02 var(--hue));
  --waline-border: 1px solid oklch(0.30 0.02 var(--hue));
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;自动切换&lt;/strong&gt;：通过监听 &lt;code&gt;html.dark&lt;/code&gt; 类，实现暗色模式的自动适配，无需 JavaScript 干预。&lt;/p&gt;
&lt;h2&gt;模块化样式架构&lt;/h2&gt;
&lt;p&gt;样式分为 13 个独立模块，每个模块负责特定的 UI 部分：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;/* 1. CSS 变量配置 - 全局主题 */
/* 2. 输入面板样式 - 评论发表区 */
/* 3. 头部信息栏 - 用户信息输入 */
/* 4. 文本编辑器 - 评论内容 */
/* 5. 提交按钮 - 主操作 */
/* 6. 评论统计 - 数量显示 */
/* 7. 评论卡片 - 单条评论 */
/* 8. 用户信息显示 - 昵称徽章 */
/* 9. 加载状态 - 动画效果 */
/* 10. 组件入场动画 - 视觉体验 */
/* 11. 表情包和上传面板 - 弹出层 */
/* 12. 文章反应按钮 - Reaction */
/* 13. 其他配置 - 杂项 */
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;自定义反应按钮&lt;/h2&gt;
&lt;h3&gt;设计理念&lt;/h3&gt;
&lt;p&gt;使用自定义爱心图标替代默认表情，提供更精美的视觉体验：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;/* 反应图标 - 未激活状态（空心） */
#waline .wl-reaction-item img {
  content: url(&apos;https://api.iconify.design/material-symbols-light:heart-check-outline-rounded.svg&apos;);
  filter: invert(25%);
  transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
}

/* 反应图标 - 激活状态（实心） */
#waline .wl-reaction-item.active img {
  content: url(&apos;https://api.iconify.design/material-symbols-light:heart-check-rounded.svg&apos;);
  animation: reaction-bounce 0.6s cubic-bezier(0.68, -0.55, 0.265, 1.55);
}

/* 点赞弹跳动画 */
@keyframes reaction-bounce {
  0% { transform: scale(1); }
  25% { transform: scale(1.3) rotate(-10deg); }
  50% { transform: scale(1.1) rotate(10deg); }
  75% { transform: scale(1.2) rotate(-5deg); }
  100% { transform: scale(1); }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;交互效果&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;未激活状态&lt;/strong&gt;：显示空心图标 + &quot;Join others who like ~&quot;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;激活状态&lt;/strong&gt;：显示实心图标 + 点赞数 + &quot;Like(s)&quot;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;悬停效果&lt;/strong&gt;：图标放大 1.15 倍 + 亮度提升&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;点击动画&lt;/strong&gt;：弹跳动画 + 旋转效果&lt;/li&gt;
&lt;/ul&gt;
&lt;h1&gt;实战中的问题与创新解决方案&lt;/h1&gt;
&lt;h2&gt;问题 1：表情包和 GIF 弹出层撑开与收回问题&lt;/h2&gt;
&lt;h3&gt;问题描述&lt;/h3&gt;
&lt;p&gt;在深度定制 Waline 后，遇到了移动端和桌面端的复杂问题：&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;移动端问题&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;❌ 表情包选项卡（微博、阿鲁斯、B 站）在移动设备上不可见&lt;/li&gt;
&lt;li&gt;❌ 弹出层使用 &lt;code&gt;position: absolute&lt;/code&gt; 定位失败，跑到屏幕外&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;桌面端问题&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;❌ 初步使用 &lt;code&gt;position: relative&lt;/code&gt; 后，弹出层关闭后无法收回&lt;/li&gt;
&lt;li&gt;❌ 表情包撑开的高度异常（与 GIF 一样大）&lt;/li&gt;
&lt;li&gt;❌ 评论框一直被撑开，必须刷新页面才能恢复&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;解决方案演进过程&lt;/h3&gt;
&lt;h4&gt;尝试 1：移动端临时修复（已废弃）&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;/* ❌ 方案A：只在移动端使用相对定位（问题未完全解决） */
@media screen and (max-width: 768px) {
  #waline .wl-emoji-popup {
    position: relative !important;
    left: 0 !important;
    right: 0 !important;
    transform: none !important;
  }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;结果&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;✅ 移动端选项卡可见了&lt;/li&gt;
&lt;li&gt;⚠️ 只解决了移动端问题&lt;/li&gt;
&lt;li&gt;❌ 应用到桌面端后，弹出层关闭后无法收回&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;尝试 2：深度排查机制&lt;/h4&gt;
&lt;p&gt;通过浏览器开发者工具，我发现了 Waline 的显示/隐藏机制：&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;核心发现&lt;/strong&gt;：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Waline 通过&lt;strong&gt;添加/移除 &lt;code&gt;.display&lt;/code&gt; 类名&lt;/strong&gt;来控制显示/隐藏&lt;/li&gt;
&lt;li&gt;隐藏时&lt;strong&gt;不是设置 &lt;code&gt;display: none&lt;/code&gt;&lt;/strong&gt;，而是移除 &lt;code&gt;.display&lt;/code&gt; 类并清空图片内容&lt;/li&gt;
&lt;li&gt;但是 &lt;code&gt;.wl-emoji-popup&lt;/code&gt; 容器和所有 &lt;code&gt;&amp;lt;button&amp;gt;&lt;/code&gt; 元素仍然存在于 DOM 中&lt;/li&gt;
&lt;li&gt;这导致使用 &lt;code&gt;position: relative&lt;/code&gt; 后，容器即使内容为空也会一直占据空间&lt;/li&gt;
&lt;/ol&gt;
&lt;h4&gt;最终方案：基于类名的优雅解决&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;/* 隐藏未激活的弹出层 */
#waline .wl-emoji-popup:not(.display),
#waline .wl-gif-popup:not(.display) {
  display: none !important;
}

/* 激活时使用相对定位撑开容器 */
#waline .wl-emoji-popup.display,
#waline .wl-gif-popup.display {
  position: relative !important;
  left: 0 !important;
  right: 0 !important;
  transform: none !important;
  margin-top: 0.5rem;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;测试结果&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;✅ 移动端选项卡 100% 可见可用&lt;/li&gt;
&lt;li&gt;✅ 桌面端弹出层正常展开和收回&lt;/li&gt;
&lt;li&gt;✅ 表情包和 GIF 各自根据内容撑开，高度合理&lt;/li&gt;
&lt;li&gt;✅ 点击关闭后评论框立即恢复原状&lt;/li&gt;
&lt;li&gt;✅ 无需媒体查询，全平台统一代码&lt;/li&gt;
&lt;li&gt;✅ 从原来的 30+ 行优化到 12 行&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;技术亮点&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;精准选择器&lt;/strong&gt;：&lt;code&gt;:not(.display)&lt;/code&gt; 直接基于 Waline 的内部机制&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;零额外成本&lt;/strong&gt;：不需要 JavaScript 监听，完全由 CSS 驱动&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;代码极简&lt;/strong&gt;：移除了所有在 &lt;code&gt;display: none&lt;/code&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;：基于 Waline 原有的类名机制，而非对抗它&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;问题 2：移动端统计标签拥挤&lt;/h2&gt;
&lt;h3&gt;响应式解决方案&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;div class=&quot;flex flex-row flex-wrap text-black/30 dark:text-white/30 gap-3 md:gap-5 mb-3&quot;&amp;gt;
  &amp;lt;!-- 每个统计项 --&amp;gt;
  &amp;lt;div class=&quot;flex flex-row items-center&quot;&amp;gt;
    &amp;lt;div class=&quot;...&quot;&amp;gt;
      &amp;lt;Icon name=&quot;...&quot; /&amp;gt;
    &amp;lt;/div&amp;gt;
    &amp;lt;div class=&quot;text-sm&quot;&amp;gt;
      &amp;lt;span class=&quot;waline-pageview-count&quot;&amp;gt;123&amp;lt;/span&amp;gt;
      &amp;lt;!-- 关键：移动端隐藏文字标签 --&amp;gt;
      &amp;lt;span class=&quot;waline-text-views hidden sm:inline&quot;&amp;gt;views&amp;lt;/span&amp;gt;
    &amp;lt;/div&amp;gt;
  &amp;lt;/div&amp;gt;
&amp;lt;/div&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Tailwind 响应式策略&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;flex-wrap&lt;/code&gt;：允许元素在空间不足时换行&lt;/li&gt;
&lt;li&gt;&lt;code&gt;gap-3 md:gap-5&lt;/code&gt;：移动端间距更紧凑，桌面端更舒适&lt;/li&gt;
&lt;li&gt;&lt;code&gt;hidden sm:inline&lt;/code&gt;：小屏隐藏，640px 以上显示&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;用户体验对比&lt;/h3&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&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;手机 (&amp;lt;640px)&lt;/td&gt;
&lt;td&gt;👁 123 💬 45&lt;/td&gt;
&lt;td&gt;节省 40% 空间&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;平板/桌面 (≥640px)&lt;/td&gt;
&lt;td&gt;👁 123 views 💬 45 comments&lt;/td&gt;
&lt;td&gt;信息完整&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h1&gt;页面集成与使用&lt;/h1&gt;
&lt;h2&gt;在文章页面展示统计信息&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;!-- src/pages/posts/[...slug].astro --&amp;gt;
&amp;lt;div class=&quot;flex flex-row flex-wrap text-black/30 dark:text-white/30 gap-3 md:gap-5 mb-3 transition onload-animation&quot;&amp;gt;
  &amp;lt;!-- 字数统计 --&amp;gt;
  &amp;lt;div class=&quot;flex flex-row items-center&quot;&amp;gt;
    &amp;lt;div class=&quot;transition h-6 w-6 rounded-md bg-black/5 dark:bg-white/10 text-black/50 dark:text-white/50 flex items-center justify-center mr-2&quot;&amp;gt;
      &amp;lt;Icon name=&quot;material-symbols:notes-rounded&quot;&amp;gt;&amp;lt;/Icon&amp;gt;
    &amp;lt;/div&amp;gt;
    &amp;lt;div class=&quot;text-sm&quot;&amp;gt;{remarkPluginFrontmatter.words} {&quot; &quot; + i18n(I18nKey.wordsCount)}&amp;lt;/div&amp;gt;
  &amp;lt;/div&amp;gt;
  
  &amp;lt;!-- 阅读时间 --&amp;gt;
  &amp;lt;div class=&quot;flex flex-row items-center&quot;&amp;gt;
    &amp;lt;div class=&quot;transition h-6 w-6 rounded-md bg-black/5 dark:bg-white/10 text-black/50 dark:text-white/50 flex items-center justify-center mr-2&quot;&amp;gt;
      &amp;lt;Icon name=&quot;material-symbols:schedule-outline-rounded&quot;&amp;gt;&amp;lt;/Icon&amp;gt;
    &amp;lt;/div&amp;gt;
    &amp;lt;div class=&quot;text-sm&quot;&amp;gt;
      {remarkPluginFrontmatter.minutes} {&quot; &quot; + i18n(remarkPluginFrontmatter.minutes === 1 ? I18nKey.minuteCount : I18nKey.minutesCount)}
    &amp;lt;/div&amp;gt;
  &amp;lt;/div&amp;gt;
  
  &amp;lt;!-- Waline 浏览量统计 --&amp;gt;
  &amp;lt;div class=&quot;flex flex-row items-center&quot;&amp;gt;
    &amp;lt;div class=&quot;transition h-6 w-6 rounded-md bg-black/5 dark:bg-white/10 text-black/50 dark:text-white/50 flex items-center justify-center mr-2&quot;&amp;gt;
      &amp;lt;Icon name=&quot;material-symbols:visibility-outline-rounded&quot;&amp;gt;&amp;lt;/Icon&amp;gt;
    &amp;lt;/div&amp;gt;
    &amp;lt;div class=&quot;text-sm&quot;&amp;gt;
      &amp;lt;span class=&quot;waline-pageview-count&quot; data-path={Astro.url.pathname}&amp;gt;0&amp;lt;/span&amp;gt;
      &amp;lt;span class=&quot;waline-text-views hidden sm:inline&quot;&amp;gt;views&amp;lt;/span&amp;gt;
    &amp;lt;/div&amp;gt;
  &amp;lt;/div&amp;gt;
  
  &amp;lt;!-- Waline 评论数统计 --&amp;gt;
  &amp;lt;div class=&quot;flex flex-row items-center&quot;&amp;gt;
    &amp;lt;div class=&quot;transition h-6 w-6 rounded-md bg-black/5 dark:bg-white/10 text-black/50 dark:text-white/50 flex items-center justify-center mr-2&quot;&amp;gt;
      &amp;lt;Icon name=&quot;material-symbols:comment-outline-rounded&quot;&amp;gt;&amp;lt;/Icon&amp;gt;
    &amp;lt;/div&amp;gt;
    &amp;lt;div class=&quot;text-sm&quot;&amp;gt;
      &amp;lt;span class=&quot;waline-comment-count&quot; data-path={Astro.url.pathname}&amp;gt;0&amp;lt;/span&amp;gt;
      &amp;lt;span class=&quot;waline-text-comments hidden sm:inline&quot;&amp;gt;comments&amp;lt;/span&amp;gt;
    &amp;lt;/div&amp;gt;
  &amp;lt;/div&amp;gt;
&amp;lt;/div&amp;gt;

&amp;lt;!-- 引入评论组件 --&amp;gt;
&amp;lt;Waline /&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;在关于页面使用&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;!-- src/pages/about.astro --&amp;gt;
&amp;lt;Waline path=&quot;/about&quot; /&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;全局样式引入&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;!-- src/layouts/Layout.astro --&amp;gt;
&amp;lt;head&amp;gt;
  &amp;lt;!-- Waline 评论系统样式 --&amp;gt;
  &amp;lt;link rel=&quot;stylesheet&quot; href=&quot;https://unpkg.com/@waline/client@v3/dist/waline.css&quot; /&amp;gt;
&amp;lt;/head&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h1&gt;配置指南：快速定制&lt;/h1&gt;
&lt;h2&gt;基础配置修改&lt;/h2&gt;
&lt;p&gt;所有配置都在 &lt;code&gt;src/config.ts&lt;/code&gt; 中修改：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;export const walineConfig: WalineConfig = {
  // 修改服务器地址
  serverURL: &quot;https://your-waline-server.com/&quot;,
  
  // 修改语言
  lang: &quot;zh-CN&quot;, // 或留空自动映射
  
  // 修改表情包
  emoji: [
    &quot;https://unpkg.com/@waline/emojis@1.2.0/qq&quot;,
    &quot;https://unpkg.com/@waline/emojis@1.2.0/tieba&quot;,
  ],
  
  // 修改文案
  locale: {
    placeholder: &quot;说点什么吧... 💬&quot;,
    sofa: &quot;快来抢沙发！🎉&quot;,
  },
  
  // 修改输入框占位符
  placeholderConfig: {
    nick: &quot;昵称 ✨&quot;,
    mail: &quot;邮箱 📧&quot;,
    link: &quot;网站 🌐&quot;,
  },
};
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;主题色自定义&lt;/h2&gt;
&lt;p&gt;如果需要独立于博客的主题色：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;/* src/components/Waline.astro */
#waline {
  --waline-theme-color: #0ea5e9;  /* Sky Blue */
  --waline-active-color: #0284c7;  /* Darker Sky Blue */
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;页面级配置覆盖&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;!-- 禁用特定页面的反应功能 --&amp;gt;
&amp;lt;Waline reaction={false} /&amp;gt;

&amp;lt;!-- 禁用评论数统计 --&amp;gt;
&amp;lt;Waline comment={false} /&amp;gt;

&amp;lt;!-- 修改每页评论数 --&amp;gt;
&amp;lt;Waline pageSize={10} /&amp;gt;

&amp;lt;!-- 组合使用 --&amp;gt;
&amp;lt;Waline 
  path=&quot;/special-page&quot;
  reaction={false}
  pageSize={10}
  login=&quot;force&quot;
/&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h1&gt;性能优化策略&lt;/h1&gt;
&lt;h2&gt;1. CSS 动画性能优化&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;/* ✅ 推荐：使用 transform（GPU 加速） */
#waline .wl-btn:hover {
  transform: translateY(-2px);
}

/* ❌ 避免：使用 top/margin（触发重排） */
#waline .wl-btn:hover {
  margin-top: -2px;  /* 性能较差 */
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;2. 懒加载优化&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;// 未来优化方向：Intersection Observer
const observer = new IntersectionObserver((entries) =&amp;gt; {
  entries.forEach(entry =&amp;gt; {
    if (entry.isIntersecting) {
      initWaline();
      observer.disconnect();
    }
  });
});

observer.observe(document.querySelector(&apos;#waline&apos;));
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;3. CDN 资源优化&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;!-- 使用 unpkg CDN 加速资源加载 --&amp;gt;
&amp;lt;script type=&quot;module&quot;&amp;gt;
  import { init } from &apos;https://unpkg.com/@waline/client@v3/dist/waline.js&apos;;
&amp;lt;/script&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h1&gt;最佳实践与经验总结&lt;/h1&gt;
&lt;h2&gt;代码组织原则&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;配置分离&lt;/strong&gt;：将所有可配置项集中在 &lt;code&gt;config.ts&lt;/code&gt; 中&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;类型安全&lt;/strong&gt;：使用 TypeScript 类型定义确保配置正确性&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;h2&gt;架构设计理念&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;配置集中管理&lt;/strong&gt;：避免配置分散导致的维护困难&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Props 覆盖机制&lt;/strong&gt;：提供灵活的页面级定制能力&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;类型安全保障&lt;/strong&gt;：利用 TypeScript 类型系统防止错误&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;错误处理健壮&lt;/strong&gt;：完整的错误捕获和优雅降级&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;样式设计理念&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;主题统一&lt;/strong&gt;：所有颜色使用 CSS 变量，确保与博客主题一致&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;h2&gt;用户体验设计&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;即时反馈&lt;/strong&gt;：所有交互都有 0.3s 的平滑过渡&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;：使用 GPU 加速动画，避免重排重绘&lt;/li&gt;
&lt;/ol&gt;
&lt;h1&gt;未来优化方向&lt;/h1&gt;
&lt;h2&gt;短期计划&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;评论懒加载&lt;/strong&gt;：使用 Intersection Observer 实现可视区域加载&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;缓存优化&lt;/strong&gt;：利用 Service Worker 缓存评论数据&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;邮件通知&lt;/strong&gt;：集成评论通知功能（已在另一篇文章中实现）&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;社交登录&lt;/strong&gt;：支持 GitHub/Google 登录&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;长期规划&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;AI 审核&lt;/strong&gt;：集成 AI 进行垃圾评论过滤&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;h1&gt;技术栈版本信息&lt;/h1&gt;
&lt;pre&gt;&lt;code&gt;{
  &quot;dependencies&quot;: {
    &quot;astro&quot;: &quot;^4.0.0&quot;,
    &quot;@waline/client&quot;: &quot;^3.0.0&quot;,
    &quot;tailwindcss&quot;: &quot;^3.4.0&quot;
  },
  &quot;devDependencies&quot;: {
    &quot;typescript&quot;: &quot;^5.3.0&quot;
  }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h1&gt;文档资源&lt;/h1&gt;
&lt;p&gt;项目包含完整的文档体系：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;src/components/waline/
├── README.md                 # 集成指南（235行）
├── ARCHITECTURE.md           # 架构说明（282行）
├── PROPS_OVERRIDE.md         # Props 覆盖指南（226行）
├── QUICK_REFERENCE.md        # 快速参考（153行）
└── REFACTORING_SUMMARY.md    # 重构总结（92行）
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;总计&lt;/strong&gt;：988 行详细文档，覆盖所有使用场景和技术细节。&lt;/p&gt;
&lt;h1&gt;结语&lt;/h1&gt;
&lt;p&gt;通过这次深度集成 Waline 评论系统的实践，我不仅成功为博客添加了强大的互动功能，还在解决实际问题的过程中积累了宝贵的经验。特别是&lt;strong&gt;从配置分散到集中管理的重构过程&lt;/strong&gt;，体现了软件工程中 &quot; 配置集中、类型安全、易于维护 &quot; 的核心理念。&lt;/p&gt;
&lt;h2&gt;核心收获&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;配置集中管理&lt;/strong&gt;：将配置从组件中抽离到 &lt;code&gt;config.ts&lt;/code&gt;，大幅提升可维护性&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;类型安全保障&lt;/strong&gt;：使用 TypeScript 类型系统，确保配置正确性&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Props 覆盖机制&lt;/strong&gt;：提供灵活的页面级定制能力&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;错误处理健壮&lt;/strong&gt;：完整的错误捕获和优雅降级&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;MutationObserver 应用&lt;/strong&gt;：创新性地解决 placeholder 持久化问题&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;CSS 选择器技巧&lt;/strong&gt;：基于 &lt;code&gt;.display&lt;/code&gt; 类名优雅解决弹出层问题&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;架构演进的启示&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&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;&lt;strong&gt;初始实现&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;配置硬编码，快速上线&lt;/td&gt;
&lt;td&gt;原型验证、小型项目&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;配置集中&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;类型安全，易于维护&lt;/td&gt;
&lt;td&gt;生产环境、长期维护&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Props 覆盖&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;灵活定制，高度可复用&lt;/td&gt;
&lt;td&gt;多场景应用、企业级项目&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;静态站点生成器与动态评论系统的结合，代表了现代 Web 开发的一个重要趋势：在追求性能和安全的同时，不牺牲用户体验和互动性。Astro 的灵活性和 Waline 的可定制性，让这一目标成为了现实。&lt;/p&gt;
&lt;p&gt;如果你也在构建自己的博客，希望这篇文章能给你一些启发。记住，&lt;strong&gt;好的架构不是一蹴而就的，而是在实践中不断迭代和优化的结果&lt;/strong&gt;。技术选型没有绝对的好坏，关键是找到最适合自己需求的方案，并在实践中不断改进。&lt;/p&gt;
&lt;h1&gt;参考资源&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://waline.js.org/&quot;&gt;Waline 官方文档&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://docs.astro.build/&quot;&gt;Astro 官方文档&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/API/MutationObserver&quot;&gt;MDN - MutationObserver&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://oklch.com/&quot;&gt;OKLCH 色彩空间&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://tailwindcss.com/docs/responsive-design&quot;&gt;Tailwind CSS 响应式设计&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.typescriptlang.org/docs/handbook/2/types-from-types.html&quot;&gt;TypeScript 类型系统&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;p&gt;&lt;em&gt;如果这篇文章对你有帮助，欢迎在下方评论区留言交流！这正是 Waline 评论系统的用武之地。😊&lt;/em&gt;&lt;/p&gt;
</content:encoded></item><item><title>vscode优化体验（推荐设置 &amp; 推荐插件）</title><link>https://www.futseyi.com/blog/vscode-settings-extensions/</link><guid isPermaLink="true">https://www.futseyi.com/blog/vscode-settings-extensions/</guid><description>VS Code是一款强大的文本编辑器，通过插件可变为万能IDE。推荐以下优化设置：自动保存、自动猜测编码、平滑滚动、光标平滑动画、滚轮缩放、粘贴/输入/保存时格式化、自动换行、括号对颜色区分、智能提示、对话框样式、调试断点显示</description><pubDate>Wed, 17 Sep 2025 00:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;VSCode 优化使用体验篇（设置 | 插件）&lt;/h1&gt;
&lt;blockquote&gt;
&lt;p&gt;众所周知，vscode 是一个非常好用的 &lt;strong&gt;文本编辑器&lt;/strong&gt;，通过各式各样的插件几乎是万能的，也可以作为好用的 IDE，但 vscode 有很多默认不开启的、个人认为非常好用的一些设置，因此，在这里与大家分享，同时也推荐几个好用的插件。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr /&gt;
&lt;p&gt;vscode 官网：&lt;a href=&quot;https://code.visualstudio.com/&quot;&gt;https://code.visualstudio.com/&lt;/a&gt;&lt;/p&gt;
&lt;h1&gt;推荐设置&lt;/h1&gt;
&lt;p&gt;下面是我的 &lt;code&gt;settings.json&lt;/code&gt; 其中的一些基础配置&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
  &quot;files.autoSave&quot;: &quot;afterDelay&quot;,
  &quot;files.autoGuessEncoding&quot;: true,
  &quot;workbench.list.smoothScrolling&quot;: true,
  &quot;editor.cursorSmoothCaretAnimation&quot;: &quot;on&quot;,
  &quot;editor.smoothScrolling&quot;: true,
  &quot;editor.cursorBlinking&quot;: &quot;smooth&quot;,
  &quot;editor.mouseWheelZoom&quot;: true,
  &quot;editor.formatOnPaste&quot;: true,
  &quot;editor.formatOnType&quot;: true,
  &quot;editor.formatOnSave&quot;: true,
  &quot;editor.wordWrap&quot;: &quot;on&quot;,
  &quot;editor.guides.bracketPairs&quot;: true,
  //&quot;editor.bracketPairColorization.enabled&quot;: true, (此设置vscode在较新版本已默认开启)
  &quot;editor.suggest.snippetsPreventQuickSuggestions&quot;: false,
  &quot;editor.acceptSuggestionOnEnter&quot;: &quot;smart&quot;,
  &quot;editor.suggestSelection&quot;: &quot;recentlyUsed&quot;,
  &quot;window.dialogStyle&quot;: &quot;custom&quot;,
  &quot;debug.showBreakpointsInOverviewRuler&quot;: true,
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h1&gt;插件&lt;/h1&gt;
&lt;blockquote&gt;
&lt;p&gt;插件种类繁多，对于各式各样的插件，我将我推荐的插件分成了四类，其中基础功能类是我认为在各种地方都很有帮助的插件，几乎可以是必备，其余的插件在很多情况下也很有用，可以按需安装&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;外观类&lt;/h2&gt;
&lt;h3&gt;主题&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;Night&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;专门为夜猫子准备的,不过亮色主题也很不错&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./assets/20250917171627107.png&quot; alt=&quot;2025-09-17_17-16-02.png&quot; /&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;One Dark Pro&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;一款非常推荐的暗色调主题，好看又护眼。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./assets/20250917171445437.png&quot; alt=&quot;2025-09-17_17-14-43.png&quot; /&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;GitHub Theme&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;GitHub 的官方主题&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./assets/20250917171501461.png&quot; alt=&quot;2025-09-17_17-14-58.png&quot; /&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;Dracula Official&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;一款很有特点的吸血鬼主题&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./assets/20250917171528469.png&quot; alt=&quot;2025-09-17_17-15-26.png&quot; /&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;图标主题&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;Material Icon Theme&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;个人正在用的图标主题，好看，类型大而全&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./assets/20250917171716120.png&quot; alt=&quot;2025-09-17_17-17-13.png&quot; /&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;背景&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;Vibrancy Continued&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;使 vscode 背景高斯模糊，非常吃性能（慎用&lt;/p&gt;
&lt;p&gt;使用方法：按 &lt;code&gt;F1&lt;/code&gt; 或者 &lt;code&gt;ctrl+shift+p&lt;/code&gt;，键入 &lt;code&gt;Reload Vibrancy&lt;/code&gt;，然后重启 vscode&lt;/p&gt;
&lt;p&gt;取消方法：按 &lt;code&gt;F1&lt;/code&gt; 或者 &lt;code&gt;ctrl+shift+p&lt;/code&gt;，键入 &lt;code&gt;Disable Vibrancy&lt;/code&gt;，然后重启 vscode&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./assets/20250917172019180.png&quot; alt=&quot;2025-09-17_17-20-16.png&quot; /&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;基础功能类&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;Chinese (Simplified) (简体中文)&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;【中文语言包】这应该不用多介绍，是 vscode 的官方中文语言包&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./assets/20250917172033825.png&quot; alt=&quot;2025-09-17_17-20-30.png&quot; /&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;Error Lens&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;【错误提示】可以将原先显示的问题显示在对应行右侧并高亮&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./assets/20250917172041341.png&quot; alt=&quot;2025-09-17_17-20-39.png&quot; /&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;Path Intellisense&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;【路径补全】在输入路径时，有智能提示补全&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./assets/20250917172049104.png&quot; alt=&quot;2025-09-17_17-20-47.png&quot; /&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;Image preview&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;【图像预览】可以预览引入的图像&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./assets/20250917172109191.png&quot; alt=&quot;2025-09-17_17-21-07.png&quot; /&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;拓展功能类&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;CodeSnap&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;【代码截图】一款非常好用的代码截图插件&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;使用方法&lt;/strong&gt;:Open the command palette (Ctrl+Shift+P on Windows and Linux, Cmd+Shift+P on OS X) and search for &lt;code&gt;CodeSnap&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./assets/20250917172120732.png&quot; alt=&quot;2025-09-17_17-21-18.png&quot; /&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;Prettier - Code formatter&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;【代码格式化工具】支持超多语言，一键格式化，美化代码格式&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./assets/20250917172243041.png&quot; alt=&quot;2025-09-17_17-22-41.png&quot; /&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;GBK to UTF8 for vscode&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;【文件编码转化】可以将文件在 GBK 与 UTF8 编码之间无瑕转换&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./assets/20250917172259963.png&quot; alt=&quot;2025-09-17_17-22-57.png&quot; /&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;Hex Editor&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;用来查看文件的 hex 或 UTF-8 编码&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./assets/20250917172318008.png&quot; alt=&quot;2025-09-17_17-23-16.png&quot; /&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;Doxygen Documentation Generator&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;【文档生成器】写注释和文档时非常好用&lt;/p&gt;
&lt;p&gt;默认的使用方法为：在==代码文件头==或者==自定义函数==上方的位置输入：/ ** 然后 enter 键,则会自动生成相应的注释&lt;/p&gt;
&lt;p&gt;自定义代码格式可以通过：File–&amp;gt;Preference–&amp;gt;Settings–&amp;gt;Extensions–&amp;gt;Doxygen Documentation Generator Settings 设置相应的格式&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./assets/20250917172332629.png&quot; alt=&quot;2025-09-17_17-23-31.png&quot; /&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;Remote - SSH&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;【ssh 连接】连接远程服务器或虚拟机&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./assets/20250917172350639.png&quot; alt=&quot;2025-09-17_17-23-48.png&quot; /&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;Hungry Delete&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;【像 IDEA 的退格键】删除整个空格或制表符块，并减少程序员按退格键所需的时间&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;使用方法&lt;/strong&gt;:ctrl+backspace&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./assets/20250917172402545.png&quot; alt=&quot;2025-09-17_17-24-01.png&quot; /&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;算法练习类&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;Code Runner&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;【代码运行工具】支持多种语言，语言运行环境需自己配置&lt;/p&gt;
&lt;p&gt;推荐修改配置：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
  &quot;code-runner.runInTerminal&quot;: true,
  &quot;code-runner.saveAllFilesBeforeRun&quot;: true,
  &quot;code-runner.saveFileBeforeRun&quot;: true
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&quot;./assets/20250917172451938.png&quot; alt=&quot;2025-09-17_17-24-49.png&quot; /&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;Competitive Programming Helper (cph)&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;刷算法题时很好用，可以自己设置样例，一键全部运行&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./assets/20250917172510419.png&quot; alt=&quot;2025-09-17_17-25-08.png&quot; /&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h1&gt;参考链接&lt;/h1&gt;
&lt;p&gt;&lt;a href=&quot;https://blog.csdn.net/qq_51173321/article/details/126287293&quot;&gt;vscode优化使用体验篇（设置 | 插件）_vscode如何开启高帧率-CSDN博客&lt;/a&gt;&lt;/p&gt;
</content:encoded></item><item><title>YOLO V7及多线程优化和边缘端设备RK3588-RK3588S部署</title><link>https://www.futseyi.com/blog/yolo-v7-rk3588-deployment/</link><guid isPermaLink="true">https://www.futseyi.com/blog/yolo-v7-rk3588-deployment/</guid><description>YOLO-V7在RK3588/RK3588S边缘端设备的部署方案。采用多线程技术，支持8个并行线程，同时处理8帧，实现摄像头/视频文件/RTMP/RTSP流的实时处理，并结合GPIO和串口。</description><pubDate>Sun, 27 Jul 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;img src=&quot;./assets/rk3588s.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;多线程 YOLO7&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;8 个并行线程&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;8 个模型实例并行&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;同时处理 8 帧&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;实时视频流&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;摄像头/视频文件&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;RTMP/RTSP 推流&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;GPIO + 串口&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;高帧率实时处理&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;blockquote&gt;
&lt;p&gt;在此方案上修改 &lt;a href=&quot;https://github.com/leafqycc/rknn-cpp-Multithreading&quot;&gt;GitHub - leafqycc/rknn-cpp-Multithreading&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h1&gt;局域网内调试&lt;/h1&gt;
&lt;blockquote&gt;
&lt;p&gt;用网线直连笔记本的以太网口与 RK3588 的以太网口&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;在 Windows 开启“Internet 连接共享”(ICS)，把 Wi‑Fi 共享到以太网&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;ul&gt;
&lt;li&gt;右键 Wi‑Fi → 属性 → 切换到“共享”选项卡&lt;/li&gt;
&lt;li&gt;勾选“允许其他网络用户通过此计算机的 Internet 连接来连接&lt;/li&gt;
&lt;li&gt;完成以上设置后，VS Code 可通过 Remote‑SSH 连接 RK3588：在 VS Code/终端使用 ssh 用户名@192.168.137.x 进行连接。RK3588 端只要 sshd 运行、网线直连、且已拿到 192.168.137.x 地址即可&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;hr /&gt;
&lt;blockquote&gt;
&lt;p&gt;或者可以添加网段
sudo ip addr add 192.168.137.3/24 dev eth0&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h1&gt;主机端操作&lt;/h1&gt;
&lt;h2&gt;模型训练&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;我使用 docker 挂载 file 文件夹中的 code、data、rknn&lt;/p&gt;
&lt;/blockquote&gt;
&lt;pre&gt;&lt;code&gt;docker attach yolov7
&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;p&gt;训练&lt;/p&gt;
&lt;/blockquote&gt;
&lt;pre&gt;&lt;code&gt;# 开始
python train.py --data data/VisDrone.yaml --name yolov7-vis2019

# 恢复
python train.py --resume
#or 指定恢复
python train.py --resume runs/train/yolov7-vis2019/weights/last.pt
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;best.pt 转换为 onnx 模型&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;python export.py --rknpu rk3588 --weight ./runs/train/yolov7-vis2019/weights/best.pt # ./当前目录
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;onnx 转 rknn 模型 (安装 rknn-toolkit 工具)&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;[!NOTE]
请注意,要在此项目上运行新的 onnx 转 rknn 的模型,需要特定的 toolkit 版本 -&amp;gt;1.5.2
&lt;a href=&quot;https://github.com/airockchip/rknn-toolkit2/tree/v1.5.2&quot;&gt;GitHub - airockchip/rknn-toolkit2 at v1.5.2&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;pre&gt;&lt;code&gt;# python
conda activate rknntoolkit

pip install rknn_toolkit2-1.5.2+b642f30c-cp36-cp36m-linux_x86_64.whl
&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;p&gt;在 file/rknn/rknn_model_zoo/examples/yolov7/python 中运行代码进行 onnx -&amp;gt; rknn&lt;/p&gt;
&lt;/blockquote&gt;
&lt;pre&gt;&lt;code&gt;python convert.py ../model/best.onnx rk3588
&lt;/code&gt;&lt;/pre&gt;
&lt;h1&gt;板端操作&lt;/h1&gt;
&lt;pre&gt;&lt;code&gt;#烧入镜像后修改 orangepi 初始密码并通过 orange-config 设置串口 0/1

sudo passwd orangepi  改成 423  #修改的是orangepi这个账户密码

#赋予整个文件夹执行权限

sudo chmod -R +x /home/orangepi/rknn-cpp-Multithreading-yolov7-1.5.2

#安装依赖
sudo apt-get update

sudo apt install cmake gstreamer1.0-rtsp libopencv-dev

#增强性能

sudo ./performance.sh

#自启动

mv detect.desktop ../.config/autostart/



##说明

postprocess.h 文件定义了解析和翻译神经网络原始输出的规则和工具，是连接“AI 模型推理”和“最终可用结果”之间的桥梁。

postprocess.cc 是 postprocess.h 的具体实现。
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;修改模型后需要的步骤&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;基础修改&lt;/p&gt;
&lt;/blockquote&gt;
&lt;pre&gt;&lt;code&gt;将转换好的模型拷贝至部署代码的model/RK3588的文件夹中，同时参照model文件夹中的文本编写类别信息

修改include/postprocess.h中OBJ_CLASS_NUM（类别数） 

和src/postprocess.cc的LABEL_NALE_TXT_PATH（类别信息文本的地址）
&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;p&gt;记得修改锚点数组数据&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;通常换新的模型,输出的锚点会不同 RK_anchors
&lt;img src=&quot;./assets/20250805145902420.png&quot; alt=&quot;2025-08-05_14-58-59.png&quot; /&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;修改模型后记得重新编译&lt;/p&gt;
&lt;/blockquote&gt;
&lt;pre&gt;&lt;code&gt;./build-linux_RK3588.sh
&lt;/code&gt;&lt;/pre&gt;
&lt;h1&gt;手动启动&lt;/h1&gt;
&lt;pre&gt;&lt;code&gt;./start.sh
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>YOLO V11及多线程优化和边缘端设备RK3588-RK3588S部署</title><link>https://www.futseyi.com/blog/yolo-v11-rk3588-deployment/</link><guid isPermaLink="true">https://www.futseyi.com/blog/yolo-v11-rk3588-deployment/</guid><description>在RK3588/RK3588S边缘端设备上部署YOLO-V11模型并进行多线程优化。和实时占用情况。</description><pubDate>Sat, 26 Jul 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;img src=&quot;./assets/rk3588s.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;参考项目&lt;a href=&quot;https://github.com/leafqycc/rknn-multi-threaded&quot;&gt;https://github.com/leafqycc/rknn-multi-threaded&lt;/a&gt;&lt;/p&gt;
&lt;h1&gt;环境部署&lt;/h1&gt;
&lt;h1&gt;RK3588/RK3588S&lt;/h1&gt;
&lt;h2&gt;板端 Anaconda 环境创建&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;安装 Anaconda&lt;/p&gt;
&lt;/blockquote&gt;
&lt;pre&gt;&lt;code&gt;cd ~
wget --user-agent=&quot;Mozilla&quot; https://mirrors.tuna.tsinghua.edu.cn/anaconda/archive/Anaconda3-2024.10-1-Linux-aarch64.sh
sh Anaconda3-2024.10-1-Linux-aarch64.sh
# 如果不能使用conda命令，在环境变量最后加上
nano ~/.bashrc
export PATH=/home/orangepi/anaconda3/bin:$PATH
source ~/.bashrc
&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;p&gt;创建 yolo11 环境并激活&lt;/p&gt;
&lt;/blockquote&gt;
&lt;pre&gt;&lt;code&gt;conda create -y -n yolo11 python=3.10
conda activate yolo11
&lt;/code&gt;&lt;/pre&gt;
&lt;h1&gt;模型选择&lt;/h1&gt;
&lt;h2&gt;1.板端下载官方预转换的 ONNX 模型&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;# yolo11n
wget https://ftrg.zbox.filez.com/v2/delivery/data/95f00b0fc900458ba134f8b180b3f7a1/examples/yolo11/yolo11n.onnx
# yolo11s
wget https://ftrg.zbox.filez.com/v2/delivery/data/95f00b0fc900458ba134f8b180b3f7a1/examples/yolo11/yolo11s.onnx
# yolo11m
wget https://ftrg.zbox.filez.com/v2/delivery/data/95f00b0fc900458ba134f8b180b3f7a1/examples/yolo11/yolo11m.onnx
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;2.使用服务器训练好的模型&lt;/h2&gt;
&lt;h1&gt;模型部署&lt;/h1&gt;
&lt;h2&gt;板端升级 Cmake 版本&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;conda install -c conda-forge cmake=3.25.*
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;板端安装 rknn-toolkit（2.3.0 版本）&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;git clone --branch v2.3.0 https://github.com/airockchip/rknn-toolkit2.git
cd rknn-toolkit2/packages/arm64

conda activate yolo11
pip install -r arm64_requirements_cp310.txt -i https://pypi.tuna.tsinghua.edu.cn/simple
pip install rknn_toolkit2-2.3.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl

cd ~/rknn-toolkit2/rknn-toolkit-lite2/packages
pip install rknn_toolkit_lite2-2.3.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl

# 把 RKNN-Toolkit2 里的可执行文件和动态库手动复制到系统的标准路径中，方便系统识别和调用
cd ~/rknn-toolkit2/rknpu2/runtime/Linux/rknn_server/aarch64/usr/bin
sudo cp * /usr/bin/
cd ~/rknn-toolkit2/rknpu2/runtime/Linux/librknn_api/aarch64
sudo cp * /usr/lib/
&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;p&gt;注意！务必检查安装的 torch 版本是否等于 1.13.1，版本不对会报错&lt;/p&gt;
&lt;/blockquote&gt;
&lt;pre&gt;&lt;code&gt;# 若版本不对，使用下面命令重新安装torch
pip install torch==1.13.1 -i https://pypi.tuna.tsinghua.edu.cn/simple
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;板端克隆官方 Model 仓库&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;git clone https://github.com/airockchip/rknn_model_zoo.git
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;板端 ONNX 转 RKNN 模型&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;# 将ONNX模型放在rknn_model_zoo/examples/yolo11/model
cd rknn_model_zoo/examples/yolo11/python
python convert.py ../model/best.onnx rk3588 # model文件夹会得到yolo11.rknn
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;板端运行示例代码&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;python yolo11.py --model_path ../model/yolo11.rknn --target rk3588 --img_show
&lt;/code&gt;&lt;/pre&gt;
&lt;h1&gt;其他&lt;/h1&gt;
&lt;h2&gt;查看 NPU 驱动版本&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;cat /sys/kernel/debug/rknpu/driver_version
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;查看实时 NPU 占用&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;sudo watch -n 1 &quot;cat /sys/kernel/debug/rknpu/load&quot;
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>用于备份和恢复 Zotero 配置的插件-蒲公英 Tara</title><link>https://www.futseyi.com/blog/zotero-tara-backup-restore/</link><guid isPermaLink="true">https://www.futseyi.com/blog/zotero-tara-backup-restore/</guid><description>Tara 是一款用于备份和恢复 Zotero 配置的插件，功能包括备份已安装插件、CSL 文件、转换器、Locate 文件夹和 Zotero 配置及插件配置。使用方法是点击 Tara 图标创建备份，生成 ZIP 格式的备份文件。恢复时，选择备份文件并重启 Zotero。可以导出备份文件，方便在新电脑上恢复数据。 此外，Tara 支持在不同电脑上通过 Zotero 的同步功能进行备份和恢复，并且可以自定义“备份 Locate”设置。</description><pubDate>Mon, 21 Jul 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;img src=&quot;./assets/logo.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;原文 &lt;a href=&quot;https://zotero-chinese.com/user-guide/plugins/tara&quot;&gt;蒲公英 | Zotero 中文社区&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h1&gt;蒲公英 Tara&lt;/h1&gt;
&lt;blockquote&gt;
&lt;p&gt;Tara 是一个用于备份和恢复 Zotero 配置的插件&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;✅ 备份已安装插件&lt;/p&gt;
&lt;p&gt;✅ 备份 CSL 文件&lt;/p&gt;
&lt;p&gt;✅ 备份转换器 (translators)&lt;/p&gt;
&lt;p&gt;✅ 备份 Locate 文件夹&lt;/p&gt;
&lt;p&gt;✅ 备份 Zotero 配置及插件配置&lt;/p&gt;
&lt;p&gt;下载地址：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/l0o0/tara&quot;&gt;GitHub&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://zotero-chinese.com/plugins/#search-%E8%92%B2%E5%85%AC%E8%8B%B1&quot;&gt;中文社区插件合集页&lt;/a&gt;
搜索 蒲公英&lt;/li&gt;
&lt;/ul&gt;
&lt;h1&gt;1 创建备份 &lt;a&gt;​&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;下载安装 Tara 插件后，通过点击 &lt;code&gt;Tara&lt;/code&gt; 图标来创建一个备份&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./assets/tara-cxh-xqi3.png&quot; alt=&quot;开始备份&quot; /&gt;&lt;/p&gt;
&lt;p&gt;创建成功后，会在 Zotero 中生成一个 &lt;code&gt;Tara_backup&lt;/code&gt; 的条目并自动生成一个 ZIP 格式的附件，这个就是备份文件。&lt;/p&gt;
&lt;p&gt;如果你再点一次创建，会再生成个附件，你可以选择不同时间段的备份文件进行恢复。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./assets/inline-image.png&quot; alt=&quot;备份文件&quot; /&gt;&lt;/p&gt;
&lt;h1&gt;2 恢复备份 &lt;a&gt;​&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;点击 &lt;code&gt;恢复&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./assets/tara-brvjguu7.png&quot; alt=&quot;恢复备份&quot; /&gt;&lt;/p&gt;
&lt;p&gt;可以根据时间来选择要恢复的备份&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./assets/tara-sf33bhrk.png&quot; alt=&quot;选择要恢复备份&quot; /&gt;&lt;/p&gt;
&lt;p&gt;等待备份恢复完成，再重启 Zotero&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./assets/tara-k7xawd7w.png&quot; alt=&quot;备份恢复完成&quot; /&gt;&lt;/p&gt;
&lt;h1&gt;3 导出备份文件 &lt;a&gt;​&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;点击 &lt;code&gt;导出&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./assets/tara-d28v7uvl.png&quot; alt=&quot;导出备份&quot; /&gt;&lt;/p&gt;
&lt;p&gt;等待完成后，去备份目录查看文件是否生成&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./assets/tara-df-z7vf.png&quot; alt=&quot;导出备份成功&quot; /&gt;&lt;/p&gt;
&lt;p&gt;导出时，会将当成的配置信息和插件导出到一个单独 ZIP 文件中，导出的备份会默认储存在 &lt;code&gt;数据储存文件夹\backup&lt;/code&gt; 下。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./assets/inline-image-2.png&quot; alt=&quot;导出的备份文件&quot; /&gt;&lt;/p&gt;
&lt;h1&gt;4 在新电脑上进行数据恢复 &lt;a&gt;​&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;在新电脑上安装了 Zotero，此时 Zotero 上没有任何插件，配置都是默认的。这时，你可以将 &lt;a&gt;导出备份文件&lt;/a&gt; 导出的文件复制到新电脑上。&lt;/p&gt;
&lt;p&gt;在新电脑 Zotero 上，先安装 &lt;code&gt;Tara.xpi&lt;/code&gt; 插件。&lt;/p&gt;
&lt;p&gt;插件安装成功，点击恢复，会出现一个文件选择的窗中，选择 &lt;a&gt;导出备份文件&lt;/a&gt; 中所生成的备份文件，之后 Zotero 会恢复对应的插件及相关配置。&lt;/p&gt;
&lt;h1&gt;5 在不同电脑上同步备份 &lt;a&gt;​&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;当你在多个电脑上同时使用 Zotero 时，可以通过 Zotero 的 &lt;code&gt;同步功能&lt;/code&gt; 来实现数据的快速备份和恢复。&lt;/p&gt;
&lt;p&gt;首先在不同电脑上分别配置同步，然后可以在 A 电脑上创建一个备份，备份文件是随条目一起同步的。那 B 电脑 Zotero 应该会自动同步了创建的备份条目 &lt;code&gt;Tara_backup&lt;/code&gt; 及对应的附件。&lt;/p&gt;
&lt;p&gt;当你在 B 电脑的 Zotero 上点击恢复，选择 A 电脑上刚创建的备份。这样两台电脑上的 Zotero 配置和插件信息就一起同步了。&lt;/p&gt;
&lt;p&gt;注意修改 Tara 的「备份 Locate」设置&lt;/p&gt;
&lt;p&gt;由于不同系统平台或主机上的文件路径可能不一致，tara 在备份时默认过滤掉了 &lt;code&gt;locate&lt;/code&gt; 文件夹，可以通过点击 &lt;code&gt;Tara 图标-设置&lt;/code&gt; 进行修改。&lt;/p&gt;
</content:encoded></item><item><title>Obsidian利用Syncthing全平台同步终极方案 同步ios和PC端</title><link>https://www.futseyi.com/blog/obsidian-syncthing-sync/</link><guid isPermaLink="true">https://www.futseyi.com/blog/obsidian-syncthing-sync/</guid><description>使用 Syncthing 在 Obsidian 笔记软件中实现全平台（包括 iOS 和 PC 端）同步的方案。Syncthing 是一个开源的 P2P 同步工具，可以实时同步文件，安全性高，速度快，且不限于 Obsidian，也可用于同步其他文件。详细介绍了 Syncthing 在 Windows 和 iOS 端的安装和配置方法，重点推荐了 iOS 端的 Synctrain 应用。最后，给出了自动化的配置流程，并通过快捷指令实现了 Obsidian 的自动同步。</description><pubDate>Sun, 20 Jul 2025 00:00:00 GMT</pubDate><content:encoded>&lt;blockquote&gt;
&lt;p&gt;或许这就是最好的 Obsidian 全平台同步方案，甚至在国内可能优于官方的同步，因为它的同步速度取决于你内网带宽！并且它不局限于同步 Obsidian，也可以同步其他基于文件的的资料或者照片以及视频。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h1&gt;1 前言&lt;/h1&gt;
&lt;p&gt;Obsidian 的同步最大的问题是 IOS 端，在桌面端我们可以利用 OneDrive，Dropbox 等工具来同步，但是在 IOS 端我们无法使用这些工具来同步其他 app 的数据，所以如果不使用官方的同步，我们只能依赖插件，例如 &lt;code&gt;remotely-save&lt;/code&gt; 和 &lt;code&gt;live-sync&lt;/code&gt; 或者基于 &lt;code&gt;git&lt;/code&gt; 的 http 插件以及 &lt;code&gt;working copy&lt;/code&gt; 来同步文件，这些插件的最大问题就是性能和对冲突的处理策略不友好，那么 &lt;code&gt;syncthing&lt;/code&gt; 便是终极的同步方案！&lt;/p&gt;
&lt;p&gt;&lt;code&gt;Syncthing&lt;/code&gt; 一个几乎实时的 Obsidian 同步方案，某些方面，它甚至优于官方同步。&lt;/p&gt;
&lt;h1&gt;2 Syncthing 的介绍&lt;/h1&gt;
&lt;p&gt;以下来自 &lt;a href=&quot;https://syncthing.net/&quot;&gt;官网&lt;/a&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Syncthing is a &lt;strong&gt;continuous file synchronization&lt;/strong&gt; program. It synchronizes files between two or more computers in real time, safely protected from prying eyes. Your data is your data alone and you deserve to choose where it is stored, whether it is shared with some third party, and how it’s transmitted over the internet.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;总结来说：syncthing 是一个开源的多端 p2p 同步工具。&lt;/p&gt;
&lt;h1&gt;3 Syncthing 的安装&lt;/h1&gt;
&lt;p&gt;桌面端的下载地址：&lt;a href=&quot;https://syncthing.net/downloads/&quot;&gt;官网下载&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;3.1 Windows 端&lt;/h2&gt;
&lt;p&gt;windows 端有 2 类客户端，一类是基于命令行 +web 端 ui 的客户端，一类是集成 ui 客户端，两种都是一样的。&lt;/p&gt;
&lt;h3&gt;3.1.1 集成 UI 客户端 (有本地 UI 界面)&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/canton7/SyncTrayzor&quot;&gt;SyncTrayzor 下载地址&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;3.1.2 基于 WebUI 的 Base 客户端&lt;/h3&gt;
&lt;p&gt;建议下载安装版 &lt;a href=&quot;https://github.com/Bill-Stewart/SyncthingWindowsSetup/&quot;&gt;Windows 安装版&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;运行：开启菜单中搜索 &lt;code&gt;syncthing&lt;/code&gt;，找到 &lt;code&gt;Start Syncthing&lt;/code&gt; 打开即运行，没有窗口，没有托盘，这时我们打开浏览器，输入 &lt;code&gt;http://127.0.0.1:8384&lt;/code&gt; 即可管理 &lt;a&gt;Syncthing&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;注意：安装版无法开机自启动，你可以安装以下步骤设置自启动。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;资源管理器打开 &lt;code&gt;%APPDATA%\Microsoft\Windows\Start Menu\Programs\Syncthing&lt;/code&gt; 复制 &lt;code&gt;Start Syncthing&lt;/code&gt; 这个快捷方式&lt;/li&gt;
&lt;li&gt;&lt;code&gt;win+R&lt;/code&gt; 输入 &lt;code&gt;shell:startup&lt;/code&gt; 打开自启动文件夹&lt;/li&gt;
&lt;li&gt;把快捷方式粘贴到自启动文件夹中，下次开机会自动启动 syncthing
你也可以记住这个文件夹的位置，或者把 &lt;code&gt;Start Syncthing&lt;/code&gt; 和 &lt;code&gt;Stop Syncthing&lt;/code&gt; 快捷方式复制到桌面用于手动启动和关闭，也可以从开始菜单启停。&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;3.2 iPhone 和 iPad 端&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;iPhone 上一直没有一个友好的 syncthing 客户端，主要是无法跨沙箱，也就无法同步文件夹，这确实非常的难受，使用起来很受限，之前一直使用 &lt;code&gt;mobius sync&lt;/code&gt; 这个收费的客户端，它能跨沙箱，但是如果体验后就必须保持后台，使用体验不算很好。直到开源的 &lt;code&gt;Synctrain&lt;/code&gt; 的出现让 IOS 上的同步体验达到几乎无感。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;3.2.1 Synctrain(免费开源,建议使用这个)&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/pixelspark/sushitrain&quot;&gt;Github 项目&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;App Store：&lt;a href=&quot;https://apps.apple.com/nl/app/synctrain/id6553985316&quot;&gt;Download on the App Store&lt;/a&gt;(非国区哦)&lt;/p&gt;
&lt;p&gt;TF：&lt;a href=&quot;https://testflight.apple.com/join/2f54I4CM&quot;&gt;Test beta versions through TestFlight&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;3.2.2 Mobius Sync&lt;/h3&gt;
&lt;p&gt;App Store 下载，国区 38 元买断，也很不错的 app。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;两个 app 最大的区别在于能否用快捷方式！&lt;/strong&gt;&lt;/p&gt;
&lt;h1&gt;4 Syncthing 配置（演示局域网下的同步）&lt;/h1&gt;
&lt;p&gt;以 Windows 端和 iPhone 同步为例，其他设备加入大同小异，但 syncthing 的中继和发现以及 stun 服务不友好，谨慎使用！&lt;/p&gt;
&lt;p&gt;PC 端点击图标 or 自动启动&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./assets/20250720163344543.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;浏览器打开默认地址 &lt;code&gt;http://127.0.0.1:8384&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;进入界面，设置 GUI 用户名和密码，避免同局域网中的隐私泄露&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./assets/20250720163612626.png&quot; alt=&quot;2025-07-20_16-35-45.png&quot; /&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;在 2 端添加远程设备
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;右上角 &lt;code&gt;操作&lt;/code&gt;&amp;gt;&lt;code&gt;显示ID&lt;/code&gt; 会显示出来二维码。
&lt;img src=&quot;./assets/20250720163710521.png&quot; alt=&quot;2025-07-20_16-37-07.png&quot; /&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;IOS 端打开 Synctrain-&amp;gt; &lt;code&gt;Devices&lt;/code&gt;&amp;gt;&lt;code&gt;Add device&lt;/code&gt; &amp;gt; &lt;code&gt;Scan using camera&lt;/code&gt; 扫描二维码，右上角 &lt;code&gt;Add&lt;/code&gt; 添加设备&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;如果正常，浏览器会收到一条添加设备的通知，点击 &lt;code&gt;添加设备&lt;/code&gt; 即可连接设备&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;添加共享文件夹 &lt;code&gt;Obsidian&lt;/code&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;浏览器 &lt;code&gt;+添加文件夹&lt;/code&gt;
&lt;img src=&quot;./assets/20250720164308909.png&quot; alt=&quot;2025-07-20_16-43-03.png&quot; /&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Obsidian 文件夹点击，然后 &lt;code&gt;编辑&lt;/code&gt;,选择共享文件夹。
&lt;img src=&quot;./assets/20250720161434226.png&quot; alt=&quot;2025-07-20_16-14-27.png&quot; /&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;iPhone 打开 &lt;code&gt;文件&lt;/code&gt;app，在 &lt;code&gt;我的iPhone&lt;/code&gt;&amp;gt;&lt;code&gt;Obsidian&lt;/code&gt; 中新建一个 &lt;code&gt;Obsidian&lt;/code&gt; 的文件夹用于保存 obsidian 的数据&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;iPhone 端 &lt;code&gt;Folders&lt;/code&gt; 中会显示发现了共享的 &lt;code&gt;Obsidian&lt;/code&gt;，选择 &lt;code&gt;Select existing filder&lt;/code&gt; &amp;gt; 第 3 步中新建的 Obsidian 文件夹，显示警告选择继续即可，&lt;code&gt;Synchronize&lt;/code&gt; 选择 &lt;code&gt;All files&lt;/code&gt;，点击右上角 &lt;code&gt;Add folder&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;img src=&quot;./assets/20250720164523014.png&quot; alt=&quot;bb144b792c3fae2154cf3925b41f0476.png&quot; /&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;配置 Over，你可以在同步的文件任意的添加一些文件看看同步的情况如何&lt;/li&gt;
&lt;li&gt;配置自动化流程（灵魂）
&lt;ol&gt;
&lt;li&gt;新建一个快捷指令添加以下 2 个 &lt;code&gt;Synctrain&lt;/code&gt; 动作即可
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;Rescan folder&lt;/code&gt;: &lt;code&gt;Folder&lt;/code&gt; 选择上面的 &lt;code&gt;Obsidian&lt;/code&gt; 文件夹，&lt;code&gt;Subdirectory&lt;/code&gt; 留空&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Synchronize for a while&lt;/code&gt;：&lt;code&gt;Time&lt;/code&gt; 填写 &lt;code&gt;15&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;img src=&quot;./assets/vly5ycrzblu8zia.png&quot; alt=&quot;&quot; /&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;打开自动化，新建一个自动化流程
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;App&lt;/code&gt; 选择 Obsidian，&lt;code&gt;已打开&lt;/code&gt; 和 &lt;code&gt;已关闭&lt;/code&gt; 全部勾选，点击立即运行&lt;/li&gt;
&lt;li&gt;下一步选择刚才创建的快捷指令&lt;/li&gt;
&lt;li&gt;完美自动化！&lt;/li&gt;
&lt;li&gt;&lt;img src=&quot;./assets/fxhlr9bgnvhjb7j.png&quot; alt=&quot;&quot; /&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h1&gt;5 Syncthing 并非仅能同步局域网内的电脑，广域网内电脑照样好同步 (后续更新)&lt;/h1&gt;
&lt;h1&gt;6 参考链接&lt;/h1&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;a href=&quot;https://laozhang.org/archives/3506.html&quot;&gt;Obsidian多端同步终极大法Syncthing、备份终极大法Kopia | 老张博客&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://blog.zdawn.net/archives/obisidian-sync-to-syncthing&quot;&gt;Obsidian利用Syncthing全平台同步终极方案 - Janz Blog&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
</content:encoded></item><item><title>新机Linux(Ubuntu)到手一般都会做如下配置</title><link>https://www.futseyi.com/blog/ubuntu-new-machine-setup/</link><guid isPermaLink="true">https://www.futseyi.com/blog/ubuntu-new-machine-setup/</guid><description>新Linux (Ubuntu) 系统初始化配置步骤： 1. 更改主机名。 2. 更换国内系统源。 3. 更新系统常用软件包。 4. 启用 BBR 网络优化。 5. 启用虚拟内存。 6. 使用国内镜像安装 Docker。 7. 加强 SSH 防护（修改端口、禁止空密码）。 8. 安装 Web 服务 (Caddy)。 9. 更改系统语言为中文。 10. 配置系统时区为上海。 此外，提供了一些参考链接，包括 GitHub 加速下载、Docker 镜像加速服务和代理设置。 最后，还提到了其他优化建议，如 apt 镜像源配置、SSH 优化、fail2ban 防护等。</description><pubDate>Thu, 17 Jul 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;img src=&quot;./assets/linux.gif&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h1&gt;我新机到手一般都会做如下配置&lt;/h1&gt;
&lt;blockquote&gt;
&lt;p&gt;按顺序执行&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h1&gt;1：更改主机名&lt;/h1&gt;
&lt;pre&gt;&lt;code&gt;hostnamectl set-hostname localhost
&lt;/code&gt;&lt;/pre&gt;
&lt;h1&gt;2：换国内系统源（开源脚本）&lt;/h1&gt;
&lt;pre&gt;&lt;code&gt;bash &amp;lt;(curl -sSL https://gitee.com/SuperManito/LinuxMirrors/raw/main/ChangeMirrors.sh)
&lt;/code&gt;&lt;/pre&gt;
&lt;h1&gt;3：更新系统常用包&lt;/h1&gt;
&lt;pre&gt;&lt;code&gt;apt update &amp;amp;&amp;amp; apt install -y curl wget git zip tar lsof vim sudo
&lt;/code&gt;&lt;/pre&gt;
&lt;h1&gt;4：启用 BBR&lt;/h1&gt;
&lt;pre&gt;&lt;code&gt;sudo modprobe tcp_bbr &amp;amp;&amp;amp; echo &quot;net.ipv4.tcp_congestion_control = bbr&quot; | sudo tee -a /etc/sysctl.conf &amp;amp;&amp;amp; sudo sysctl -p
&lt;/code&gt;&lt;/pre&gt;
&lt;h1&gt;5：启用虚拟内存&lt;/h1&gt;
&lt;pre&gt;&lt;code&gt;sudo fallocate -l 2G /swapfile &amp;amp;&amp;amp; sudo chmod 700 /swapfile &amp;amp;&amp;amp; sudo mkswap /swapfile &amp;amp;&amp;amp; sudo swapon /swapfile &amp;amp;&amp;amp; echo &apos;/swapfile none swap sw 0 0&apos; | sudo tee -a /etc/fstab
&lt;/code&gt;&lt;/pre&gt;
&lt;h1&gt;6：使用国内镜像安装 docker（开源脚本）&lt;/h1&gt;
&lt;pre&gt;&lt;code&gt;bash &amp;lt;(curl -sSL https://gitee.com/SuperManito/LinuxMirrors/raw/main/DockerInstallation.sh)
&lt;/code&gt;&lt;/pre&gt;
&lt;h1&gt;7：加强 SSH 防护&lt;/h1&gt;
&lt;p&gt;修改 SSH 配置文件&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;sudo vim /etc/ssh/sshd_config
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;找到对应的配置然后修改&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# 修改SSH服务端口
Port 2222

# 禁止使用空密码登录
PermitEmptyPasswords no
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;重启 SSH 服务&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;sudo systemctl restart ssh
&lt;/code&gt;&lt;/pre&gt;
&lt;h1&gt;8：安装 web 服务（caddy）&lt;/h1&gt;
&lt;pre&gt;&lt;code&gt;sudo apt install -yq debian-keyring debian-archive-keyring apt-transport-https curl &amp;amp;&amp;amp; curl -1sLf &apos;https://dl.cloudsmith.io/public/caddy/stable/gpg.key&apos; | sudo gpg --dearmor -o /usr/share/keyrings/caddy-stable-archive-keyring.gpg &amp;amp;&amp;amp; curl -1sLf &apos;https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt&apos; | sudo tee /etc/apt/sources.list.d/caddy-stable.list &amp;amp;&amp;amp; sudo apt update -q &amp;amp;&amp;amp; sudo apt install -yq caddy
&lt;/code&gt;&lt;/pre&gt;
&lt;h1&gt;9：更改系统语言为中文&lt;/h1&gt;
&lt;pre&gt;&lt;code&gt;sudo nano /etc/locale.gen
# zh_CN.UTF-8 UTF-8       // 取消这行注释

sudo locale-gen
sudo update-locale LANG=zh_CN.UTF-8
sudo localectl set-locale LANG=zh_CN.UTF-8
&lt;/code&gt;&lt;/pre&gt;
&lt;h1&gt;10：配置系统时区为上海&lt;/h1&gt;
&lt;pre&gt;&lt;code&gt;sudo ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
&lt;/code&gt;&lt;/pre&gt;
&lt;h1&gt;11：然后就可以使用 docker 愉快的部署各种服务了（脚本已自动配置国内镜像源），然后配合 caddy 反代各种服务&lt;/h1&gt;
&lt;h1&gt;其他参考&lt;/h1&gt;
&lt;pre&gt;&lt;code&gt;# 鱼香 ros 一键安装
wget http://fishros.com/install -O fishros &amp;amp;&amp;amp; . fishros
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;a href=&quot;https://bgithub.xyz&quot;&gt;GitHub · Build and ship software on a single, collaborative platform · GitHub&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://help.kkgithub.com/&quot;&gt;KGitHub Help&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://gitclone.com/&quot;&gt;方达极客社区&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://github.hscsec.cn&quot;&gt;Title Unavailable | Site Unreachable&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://git.homegu.com&quot;&gt;Title Unavailable | Site Unreachable&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://github.ur1.fun/&quot;&gt;GitHub 加速下载 - 在线工具&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/233boy/v2ray&quot;&gt;GitHub - 233boy/v2ray: 最好用的 V2Ray 一键安装脚本 &amp;amp; 管理脚本&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://linux.do/t/topic/789917&quot;&gt;Docker镜像加速服务整理&lt;/a&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;docker 国内代理看这个帖子：&lt;a href=&quot;https://linux.do/t/topic/789917&quot;&gt;https://linux.do/t/topic/789917&lt;/a&gt;
科学上完用 clash verge + 机场订阅链接
系统 apt 源换国内的（Google 搜一些帖子非常多）&lt;/p&gt;
&lt;p&gt;命令行走代理修改~/.bashrc 文件, 12334 端口修改为实际的代理端口。
注意对于 ping 这类 icmp 协议工具，是没办法走代理的。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;HTTP / HTTPS 代理 export HTTP_PROXY=&quot;http://127.0.0.1:12334&quot; export HTTPS_PROXY=&quot;http://127.0.0.1:12334&quot;&lt;/li&gt;
&lt;li&gt;如果你需要走 SOCKS5（某些工具优先用 ALL_PROXY） export ALL_PROXY=&quot;socks5:&amp;lt;//127.0.0.1:12334&amp;gt;&quot;
修改后 &lt;code&gt;source ~/.bashrc&lt;/code&gt; 保存生效&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;配置 apt 镜像源；
BBR 优化；
优化 SSH 配置（改端口、配置密钥对、心跳维持连接等）；
配置 fail2ban、UFW 等；
配置 .zshrc、.vimrc 等，添加常用的几个 alias；
配置 proxychains；
&lt;s&gt;安装 neofetch、cowsay 等强大的 CLI 工具；&lt;/s&gt;
&lt;s&gt;每天来一把 sudo apt upgrade -y。&lt;/s&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h1&gt;实验室备份&lt;/h1&gt;
&lt;pre&gt;&lt;code&gt;
apt
cd /etc/apt
cp /etc/apt/sources.list /etc/apt/sources.list.bak
gedit sources.list

deb http://mirrors.tuna.tsinghua.edu.cn/ubuntu-ports/ bionic main multiverse restricted universe
deb http://mirrors.tuna.tsinghua.edu.cn/ubuntu-ports/ bionic-security main multiverse restricted universe
deb http://mirrors.tuna.tsinghua.edu.cn/ubuntu-ports/ bionic-updates main multiverse restricted universe
deb http://mirrors.tuna.tsinghua.edu.cn/ubuntu-ports/ bionic-backports main multiverse restricted universe
deb-src http://mirrors.tuna.tsinghua.edu.cn/ubuntu-ports/ bionic main multiverse restricted universe
deb-src http://mirrors.tuna.tsinghua.edu.cn/ubuntu-ports/ bionic-security main multiverse restricted universe
deb-src http://mirrors.tuna.tsinghua.edu.cn/ubuntu-ports/ bionic-updates main multiverse restricted universe
deb-src http://mirrors.tuna.tsinghua.edu.cn/ubuntu-ports/ bionic-backports main multiverse restricted universe

sudo apt-get update

pip
pip3 install --upgrade pip
mkdir ~/.pip
gedit ~/.pip/pip.conf
[global]
index-url =  https://pypi.mirrors.ustc.edu.cn/simple
[install]
trusted-host =  https://pypi.mirrors.ustc.edu.cn

torch
sudo apt-get install python3-pip libopenblas-base libopenmpi-dev libomp-dev
pip3 install Cython
pip3 install numpy torch-1.8.0-cp36-cp36m-linux_aarch64.whl

import torch
import torchvision
print(torch.__version__)
print(torchvision.__version__)

torchvison
sudo apt-get install libjpeg-dev zlib1g-dev libpython3-dev libavcodec-dev libavformat-dev libswscale-dev
cd torchvision
$ export BUILD_VERSION=0.x.0  # where 0.x.0 is the torchvision version  
$ python3 setup.py install --user
$ cd ../  # attempting to load torchvision from build dir will result in import error
$ pip install &apos;pillow&amp;lt;7&apos; # always needed for Python 2.7, not needed torchvision v0.5.0+ with Python 3.6

&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>04讲 - 炼丹流程 - PyTorch深度学习快速入门教程</title><link>https://www.futseyi.com/blog/pytorch-quickstart-training-workflow/</link><guid isPermaLink="true">https://www.futseyi.com/blog/pytorch-quickstart-training-workflow/</guid><description>PyTorch深度学习的炼丹流程，包括模型操作（使用、修改、保存、加载），模型训练（数据集准备、加载、网络模型创建、损失函数、优化器、训练和测试步骤），以及GPU的使用（单卡和多卡）。此外，还提到了验证和准确率计算。 教程中提供了CIFAR10数据集的训练示例，并演示了如何使用TensorBoard进行可视化。最后，介绍了如何加载和验证训练好的模型，以及在不同设备间进行模型迁移。</description><pubDate>Wed, 16 Jul 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;img src=&quot;./assets/padding-strides-odd.gif&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h1&gt;第 04 讲 炼丹流程📝&lt;/h1&gt;
&lt;h1&gt;1.1 模型操作&lt;/h1&gt;
&lt;h2&gt;1.1.1 使用&amp;amp;修改&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;torchvision.models 有分类、语义分割、目标检测等，本次讲分类模型 VGG&lt;/p&gt;
&lt;p&gt;最常用的为 VGG16 和 VGG19，VGG16 的数据集 ImageNet 需安装「scipy」&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;model_pretrained.py&lt;/p&gt;
&lt;/blockquote&gt;
&lt;pre&gt;&lt;code&gt;import torchvision  

from torch import nn  

  

# VGG16 对应的 ImageNet数据集 由于数据集过大选择放弃  

# train_data = torchvision.datasets.ImageNet(&quot;./data_image_net&quot;,  

#                                                 split=&apos;train&apos;,  

#                                                 download=True,  

#                    transform=torchvision.transforms.ToTensor())  

  

# 01 使用  

vgg16_false = torchvision.models.vgg16(pretrained=False) # 初始参数  

vgg16_true = torchvision.models.vgg16(pretrained=True)   # 训练好的  

  

print(vgg16_true) ## 查看网络模型架构 

  

train_data = torchvision.datasets.CIFAR10(&apos;./data&apos;,  

                                          train=True,  

                                          transform=torchvision.transforms.ToTensor(),  

                                          download=True)  

  

# 02 修改方式  

# (1) 加线性层  

print(vgg16_true)  

vgg16_true.classifier.add_module(&apos;add_linear&apos;, nn.Linear(1000, 10))  

print(vgg16_true)  

  

# (2) 直接修改  

print(vgg16_false)  

vgg16_false.classifier[6] = nn.Linear(4096, 10)  

print(vgg16_false)
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;1.1.2 保存&amp;amp;加载&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;训练好的模型需要进行保存，以备后续加载使用&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;model_save.py&lt;/p&gt;
&lt;/blockquote&gt;
&lt;pre&gt;&lt;code&gt;import torch  

import torchvision  

from torch import nn  

  

vgg16 = torchvision.models.vgg16(pretrained=False)  ##不要预训练

  

  

# 01 保存方式  

# (1) 模型参数 + 模型结构  

torch.save(vgg16, &quot;vgg16_method1.pth&quot;)  

  

# (2) 模型参数（官方推荐）  
## .state_dict()是将网络模型保存成Python中字典形式
torch.save(vgg16.state_dict(), &quot;vgg16_method2.pth&quot;)  

  

# 02 自定义模型  

class Tudui(nn.Module):  

    def __init__(self):  

        super(Tudui, self).__init__()  

        self.conv1 = nn.Conv2d(3, 64, kernel_size=3)  

  

    def forward(self, x):  

        x = self.conv1(x)  

        return x  

  

tudui = Tudui()  

torch.save(tudui, &quot;tudui_method1.pth&quot;)
&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;p&gt;自定义模型保存后加载，记得要 「导入」&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;model_load.py&lt;/p&gt;
&lt;/blockquote&gt;
&lt;pre&gt;&lt;code&gt;import torch  

import torchvision  

  

# 01 加载方式  

# (1) 加载 模型参数 + 模型结构  torch.load

model = torch.load(&quot;vgg16_method1.pth&quot;)  

print(model)  

  

# (2) 加载 模型参数  (恢复以字典形式保存的模型的结构) .load_state_dict(torch.load())

vgg16 = torchvision.models.vgg16(pretrained=False)  

vgg16.load_state_dict(torch.load(&quot;vgg16_method2.pth&quot;))  

print(vgg16)  

  

# 02 自定义模型 (有加载陷阱)  

# 需要复制过来 or 导入

## 方式1. 复制过来  (但是不需要tudui = Tudui())
class Tudui(nn.Module):  

    def __init__(self):  

        super(Tudui, self).__init__()  

        self.conv1 = nn.Conv2d(3, 64, kernel_size=3)  

  

    def forward(self, x):  

        x = self.conv1(x)  

        return x

## 方式2. 从上面model_save.py文件导入所有类、函数和变量
from model_save import *  

model = torch.load(&apos;tudui_method1.pth&apos;)  

print(model)
&lt;/code&gt;&lt;/pre&gt;
&lt;h1&gt;1.2 模型训练&lt;/h1&gt;
&lt;blockquote&gt;
&lt;p&gt;train.py&lt;/p&gt;
&lt;/blockquote&gt;
&lt;pre&gt;&lt;code&gt;import torchvision  

from torch.utils.data import DataLoader  

from torch.utils.tensorboard import SummaryWriter  

from model import *  #用下方单独创建的model文件(这样比较规范)

  

# 01 准备数据集  

train_data = torchvision.datasets.CIFAR10(root=&quot;./data&quot;,  

                                          train=True,  

                                          transform=torchvision.transforms.ToTensor(),  

                                          download=True)  

test_data = torchvision.datasets.CIFAR10(root=&quot;./data&quot;,  

                                         train=False,  

                                         transform=torchvision.transforms.ToTensor(),  

                                         download=True)  

# length 查看长度

train_data_size = len(train_data)  

test_data_size = len(test_data)  

print(&quot;训练数据集的长度为：{}&quot;.format(train_data_size))  

print(&quot;测试数据集的长度为：{}&quot;.format(test_data_size))  

  

# 02 利用 DataLoader 加载数据集 

train_dataloader = DataLoader(train_data, batch_size=64)  

test_dataloader = DataLoader(test_data, batch_size=64)  

  

# 03 创建网络模型  

tudui = Tudui()  

  

# 04 损失函数  

loss_fn = nn.CrossEntropyLoss()  

  

# 05 优化器  

learning_rate = 1e-2 # 代表0.01  

optimizer = torch.optim.SGD(tudui.parameters(), lr=learning_rate)  

  

# 06 设置训练网络的一些参数  

total_train_step = 0 # 记录训练的次数  

total_test_step = 0 # 记录测试的次数  

epoch = 10 # 训练的轮数  

  

# 添加tensorboard  可视化查看信息

writer = SummaryWriter(&quot;logs&quot;)  



for i in range(epoch):  

    print(&quot;-------第 {} 轮训练开始-------&quot;.format(i+1))  

  

    &quot;&quot;&quot;  

        仅对一部分网络层有作用， 如Dropout、BatchNorm层  

        tudui.train()   设置成训练模式（可选）  

        tudui.eval()    设置成测试模式（可选）  

    &quot;&quot;&quot;    

    # 07 训练步骤开始  

    tudui.train()  

    for data in train_dataloader:  

        imgs, targets = data  

        outputs = tudui(imgs)  

        loss = loss_fn(outputs, targets)  

  

        # 优化器 进行一次 优化模型  

        optimizer.zero_grad()  ##先梯度清零

        loss.backward()  

        optimizer.step()  


        total_train_step = total_train_step + 1  

        if total_train_step % 100 == 0:  ## 满一百打印一次记录

            print(&quot;训练次数：{}, Loss: {}&quot;.format(total_train_step, loss.item()))  
            ## 这里加.item 是让直接输出显示数值(转为标量值int/float),不显示类型

            writer.add_scalar(&quot;train_loss&quot;, loss.item(), total_train_step)  

                                           

    # 08 测试步骤开始 (使用测试集啦)

    tudui.eval()  

    total_test_loss = 0  

    total_accuracy = 0  

    with torch.no_grad(): # 因为只需要测试，不需要反传梯度  

        for data in test_dataloader:  ## 使用测试数据集

            imgs, targets = data  

            outputs = tudui(imgs)  

  

            loss = loss_fn(outputs, targets)  

            total_test_loss = total_test_loss + loss.item()  

  

            accuracy = (outputs.argmax(1) == targets).sum() # argmax -&amp;gt; 正确个数  argmax(1) -&amp;gt;横向对比

            total_accuracy = total_accuracy + accuracy  

  

    print(&quot;整体测试集上的Loss: {}&quot;.format(total_test_loss))  

    print(&quot;整体测试集上的正确率: {}&quot;.format(total_accuracy/test_data_size))  

    writer.add_scalar(&quot;test_loss&quot;, total_test_loss, total_test_step)  

    writer.add_scalar(&quot;test_accuracy&quot;, total_accuracy/test_data_size, total_test_step)  

    total_test_step = total_test_step + 1  

  
# 保存模型
    torch.save(tudui, &quot;tudui_{}.pth&quot;.format(i))  
	##官方保存方式 torch.save(tudui.state_dict(),&quot;tudui_{}.pth&quot;.format(i))
		##.state_dict()转换为字典型
		
    print(&quot;模型已保存&quot;)  

  

writer.close()
&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;p&gt;model.py&lt;/p&gt;
&lt;/blockquote&gt;
&lt;pre&gt;&lt;code&gt;import torch  

from torch import nn  

  

# 搭建神经网络  

class Tudui(nn.Module):  

    def __init__(self):  

        super(Tudui, self).__init__()  

        self.model = nn.Sequential(  

            nn.Conv2d(3, 32, 5, 1, 2),  

            nn.MaxPool2d(2),  

            nn.Conv2d(32, 32, 5, 1, 2),  

            nn.MaxPool2d(2),  

            nn.Conv2d(32, 64, 5, 1, 2),  

            nn.MaxPool2d(2),  

            nn.Flatten(),  

            nn.Linear(64*4*4, 64),  

            nn.Linear(64, 10)  

        )  

  

    def forward(self, x):  

        x = self.model(x)  

        return x  

  

# main函数  ()

if __name__ == &apos;__main__&apos;:  

  
## 测试网络模型的正确性
    tudui = Tudui()  

    input = torch.ones((64, 3, 32, 32))  

    output = tudui(input)  

    print(output.shape)
&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;p&gt;正确率是分类问题比较特有的指标，计算正确率的方法如下&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;img src=&quot;./assets/628f73791fe06d30077a17f7cc11fe2d-mzgf6hz4-2jeh02.webp&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;argmax() 函数.py&lt;/p&gt;
&lt;/blockquote&gt;
&lt;pre&gt;&lt;code&gt;import torch  

  

# item()函数  

# 从只包含单个元素的张量中提取Python数值，将张量转换为标量值  

a = torch.tensor(5)  

print(a)  

print(a.item())  

  

# argmax()函数  

# 0纵向，1横向  

outputs = torch.tensor([[0.1,0.2],  

                        [0.05,0.4]])  

print(outputs.argmax(0)) # 纵向对比  

print(outputs.argmax(1)) # 横向对比
&lt;/code&gt;&lt;/pre&gt;
&lt;h1&gt;1.3 GPU&lt;/h1&gt;
&lt;p&gt;&lt;img src=&quot;./assets/89d50ef561c5aefcbd26b1a0cf035598-kp36oeqm-z1d1h36.webp&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;train_gpu_1.py&lt;/p&gt;
&lt;/blockquote&gt;
&lt;pre&gt;&lt;code&gt;import torch  

import torchvision  

from torch import nn, cuda  

from torch.utils.data import DataLoader  

from torch.utils.tensorboard import SummaryWriter  

  

# 01 准备数据集

# ···

# ···

  

# 03 创建网络模型  

&quot;&quot;&quot;  

使用GPU要做的修改  

    01 网络模型  

    02 数据  

    03 损失函数  

&quot;&quot;&quot;  

tudui = Tudui()  

if cuda.is_available():  

    tudui.cuda()  ##将网络模型转移到cuda上

  

# 04 损失函数  

loss_fn = nn.CrossEntropyLoss()  

if cuda.is_available():  

    loss_fn = loss_fn.cuda()  

# ···

# ···

    # 07 训练步骤开始   

    for data in train_dataloader:  

        imgs, targets = data  

  

        if cuda.is_available():  

            imgs = imgs.cuda()  

            targets = targets.cuda()  

# ···

# ···

    # 08 测试步骤开始  

        for data in test_dataloader:  

            imgs, targets = data  

  

            if cuda.is_available():  

                imgs = imgs.cuda()  

                targets = targets.cuda()
&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;p&gt;train_gpu_2.py&lt;/p&gt;
&lt;/blockquote&gt;
&lt;pre&gt;&lt;code&gt;import torch  

import torchvision  

from torch import nn, cuda  

from torch.utils.data import DataLoader  

from torch.utils.tensorboard import SummaryWriter  

  

&quot;&quot;&quot;  

单显卡  

Torch.device(“cuda”)  

Torch.device(“cuda:0”)  

  

多显卡-第2张  

Torch.device(“cuda:1”)  

&quot;&quot;&quot;  

# 定义训练的设备  

device = torch.device(&quot;cuda&quot; if torch.cuda.is_available() else &quot;cpu&quot;)  

  

# 01 准备数据集  

# ···

# ···

# 03 创建网络模型  

&quot;&quot;&quot;  

使用GPU要做的修改  

    01 网络模型  

    02 数据  

    03 损失函数  

&quot;&quot;&quot;  

tudui = Tudui()  

tudui.to(device)  

  

# 04 损失函数  

loss_fn = nn.CrossEntropyLoss()  

loss_fn.to(device)  

# ···

# ···

    # 07 训练步骤开始  

    for data in train_dataloader:  

        imgs, targets = data  

  

        imgs = imgs.to(device)  

        targets = targets.to(device)  

# ···

# ···

    # 08 测试步骤开始  

        for data in test_dataloader:  

            imgs, targets = data  

  

            imgs = imgs.to(device)  

            targets = targets.to(device)
&lt;/code&gt;&lt;/pre&gt;
&lt;h1&gt;1.4 验证&lt;/h1&gt;
&lt;blockquote&gt;
&lt;p&gt;[!NOTE]
本节加载模型，选择导入 model 文件中模型的方式，不再复制代码&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;test.py&lt;/p&gt;
&lt;/blockquote&gt;
&lt;pre&gt;&lt;code&gt;import torch  

import torchvision  

from PIL import Image  

from torch import nn  

from model import *  

  

image_path = &quot;./imgs/dog.png&quot;  

image = Image.open(image_path)  

&quot;&quot;&quot;  

png格式是RGBA四个通道，需要转为RGB颜色通道  

视频可以运行是因为不同截图软件保留的通道数是不一样的  

&quot;&quot;&quot;  

image = image.convert(&apos;RGB&apos;)  

transform = torchvision.transforms.Compose([  
					
					    torchvision.transforms.Resize((32, 32)),  
					
					    torchvision.transforms.ToTensor()  

											])  

image = transform(image)  

print(image.shape)  

  

#  01 CPU环境  

# 先注释,因为不用CPU  model = torch.load(&quot;tudui_0.pth&quot;)  

  

# 02 CPU环境 验证 GPU环境下训练的模型  

model = torch.load(&quot;tudui_29_gpu.pth&quot;,map_location=torch.device(&apos;cpu&apos;))  
								## map_location 对应到相应的设备上(映射)

  
# 开始验证

image = torch.reshape(image, (1, 3, 32, 32))  

model.eval()   ## 设置为测试类型(符合规范)

with torch.no_grad():  

    output = model(image)  

print(output)  

print(output.argmax(1)) # 横向
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>03讲 - 神经网络 - PyTorch深度学习快速入门教程</title><link>https://www.futseyi.com/blog/pytorch-quickstart-neural-networks/</link><guid isPermaLink="true">https://www.futseyi.com/blog/pytorch-quickstart-neural-networks/</guid><description>讲解了神经网络的基本结构、常用层、损失函数和优化器。首先介绍了Module、卷积层、池化层、激活层等构成神经网络的基本元素，以及Sequential的使用。然后，讲解了损失函数如L1Loss、MSELoss和CrossEntropyLoss，以及反向传播和优化器（如SGD）的工作原理。最后，通过代码示例演示了如何构建、训练和优化一个简单的神经网络。</description><pubDate>Tue, 15 Jul 2025 00:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;第 03 讲 神经网络📝&lt;/h1&gt;
&lt;h1&gt;1.1 基本骨架&lt;/h1&gt;
&lt;h2&gt;1.1.1 Module&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;torch.nn&lt;/code&gt; 是非常常用的包，其中 &lt;code&gt;torch.container&lt;/code&gt; 中的 &lt;strong&gt;「Module」&lt;/strong&gt; 是所有神经网络的基类&lt;/p&gt;
&lt;p&gt;自己定义的模型需要实现「Module」的 &lt;code&gt;__init__&lt;/code&gt; 和 &lt;code&gt;forward&lt;/code&gt; 函数&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;前向传播&lt;/p&gt;
&lt;p&gt;此图的 F. 是下面代码块定义的 -&amp;gt; import torch.nn.functional as F
&lt;img src=&quot;./assets/fca95ba8f46ae627d659f12c0db2e616-tljk4sl0-z5swsr.webp&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;nn_module.py&lt;/p&gt;
&lt;/blockquote&gt;
&lt;pre&gt;&lt;code&gt;import torch  

from torch import nn  

  

class Tudui(nn.Module):  

    def __init__(self):  

        super().__init__()  ## 习惯性添加,调用了父类 `nn.Module` 的初始化方法,及时下面过程没有使用 `nn.Module` 的高级功能


    def forward(self, input):  ## 当你自定义一个模型，只要继承自 `nn.Module`，就必须定义一个名为 `forward(self, …)` 的方法，用来描述模型的前向传播逻辑

 
        output = input + 1  

        return output  

  

tudui = Tudui()  

x = torch.tensor([1.0])  

output = tudui(x)  

print(output)
# 输出tensor([2.])PyTorch 默认的张量打印格式，表示其值为 2.0
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;1.1.2 Layers&lt;/h2&gt;
&lt;h2&gt;1.1.2.1 Ⅰ 卷积层&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;卷积层中最常使用 &lt;strong&gt;Conv2d&lt;/strong&gt; -- 因为图像为二维&lt;/p&gt;
&lt;p&gt;卷积核的 &lt;strong&gt;「size」&lt;/strong&gt; 一般是预定义好的&lt;/p&gt;
&lt;p&gt;卷积核的 &lt;strong&gt;「weights」&lt;/strong&gt; 一般是先初始化然后通过不断迭代学习而来的&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;img src=&quot;./assets/padding-strides-odd.gif&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./assets/50b94b73ec2b1924a4d770ea06e4f721-dubrwwms-z1pxu8c.webp&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://www.morinha.cc/_astro/d71ecdc3e869d3439ddcb62e22cc892e.CFvv4ckn_DI5V1.webp&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;以上完整输出为:
&lt;img src=&quot;./assets/20250717101933745.png&quot; alt=&quot;2025-07-17_10-19-29.png&quot; /&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;nn_conv.py&lt;/p&gt;
&lt;/blockquote&gt;
&lt;pre&gt;&lt;code&gt;import torch  

import torch.nn.functional as F  

  

input =torch.tensor([[1,2,0,3,1],  

                     [0,1,2,3,1],  

                     [1,2,1,0,0],  

                     [5,2,3,1,1],  

                     [2,1,0,1,1]])  

  

kernel = torch.tensor([[1,2,1],  

                       [0,1,0],  

                       [2,1,0]])  

 
print(input.shape)  

print(kernel.shape)  
#以上输出torch.Size([5,5])和torch.Size([3,3]),不满足使用条件-&amp;gt; - reshape 是为了让数据 shape 满足 conv2d 的要求

# 01 看shape发现不满足,修改一下shape
  

input = torch.reshape(input,(1,1,5,5))  

kernel = torch.reshape(kernel,(1,1,3,3))  

  

## 02 卷积 conv2d

output = F.conv2d(input,kernel,stride=1) ## 这里的stride=1代表上下左右各移动一个像素(去扫描)

print(output)  

  

output2 = F.conv2d(input,kernel,stride=2)  

print(output2)  

  

output3 = F.conv2d(input,kernel,stride=1,padding=1)  ## padding=1代表上下左右填充1个像素

print(output3)
&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;p&gt;观察以下过程&lt;/p&gt;
&lt;p&gt;输出 channel=2,代表有两个卷积核去扫描.并且两个卷积核数值是随机的&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;img src=&quot;./assets/81512b024b672f6a650b5b7ebd0cc78c-z-fku6ud-z1ake0o.webp&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;nn_conv2d.py&lt;/p&gt;
&lt;p&gt;以下正式讲解卷积层的使用&lt;/p&gt;
&lt;/blockquote&gt;
&lt;pre&gt;&lt;code&gt;import torch  

import torchvision  

from torch import nn  

from torch.nn import Conv2d  

from torch.utils.data import DataLoader  

from torch.utils.tensorboard import SummaryWriter  

from urllib3.filepost import writer  

  
# 准备数据集
datset = torchvision.datasets.CIFAR10(&quot;data&quot;,  

                                      train=False, ## 训练数据集太大了,就用测试数据集 

                                      transform=torchvision.transforms.ToTensor(),  

                                      download=True)  

  
# 加载数据集
dataloader = DataLoader(datset,batch_size=64)  

  
# 自定义神经网络
class Tudui(nn.Module):  

    def __init__(self):  

        super().__init__()  

		
## 创建conv1,表示你的第一个卷积层，并且后续可以在`forward`方法里直接用
        self.conv1 = nn.Conv2d(in_channels=3,
		
							  out_channels=6,
							   
                               kernel_size=3, ##卷积核大小
							   
                                    stride=1,
							   
									padding=0)  


    def forward(self,x):  

        x = self.conv1(x)  

        return x  

  
# 初始化这个网络

tudui = Tudui()  

## print(tudui)  


writer = SummaryWriter(&quot;logs&quot;)  

step = 0  

for data in dataloader:  ## `data` 只是一个变量名 它代表每次迭代从 `dataloader` 取出的那 1 批数据

    imgs, targets = data  

    output = tudui(imgs)  

    # print(imgs.shape)  

    # print(output.shape)  

    writer.add_images(&quot;input&quot;,imgs,step) # 输入的torch.Size([64, 3, 32, 32]) 在卷积层中运行后 会输出 [64, 6, 30, 30] 有6通道;TensorBoard add_images 只支持 1 或 3 通道图片，不支持 6 通道


    output = torch.reshape(output,(-1,3,30,30)) 
	## `-1` 代表自动根据其他维度推算 batch 数量, 意思就是这个-1会经过reshape后自动计算成对应的数值.比如将以上[64, 6, 30, 30]的6压缩成两组3的话,就变成[128, 3, 30, 30]
    
  
	
    writer.add_images(&quot;output&quot;,output,step) # 输出的torch.Size([128, 3, 30, 30])  

    step = step + 1

  

writer.close()
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;1.1.2.2 Ⅱ 池化层&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;池化层中最常使用 &lt;strong&gt;「MaxPool2d」&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;其一是对卷积层所提取的信息做更一步降维， &lt;strong&gt;减少计算量&lt;/strong&gt; ，&lt;/p&gt;
&lt;p&gt;其二是 &lt;strong&gt;加强图像特征的不变性&lt;/strong&gt; ，使之增加图像的偏移、旋转等方面的鲁棒性&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;img src=&quot;./assets/dilation.gif&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./assets/057676433aa75853dbf92cdf33c025ff-tpyc1fer-1keqeg.webp&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;nn_maxpool.py&lt;/p&gt;
&lt;/blockquote&gt;
&lt;pre&gt;&lt;code&gt;import torch  

import torchvision  

from torch import nn  

from torch.utils.data import DataLoader  

from torch.utils.tensorboard import SummaryWriter  

  

# 01 测试最大池化的实现  

# input =torch.tensor([ [1,2,0,3,1],  

#                       [0,1,2,3,1],  

#                       [1,2,1,0,0], 

#                       [5,2,3,1,1],

#                       [2,1,0,1,1]  ],

#                      dtype=torch.float32)
						## 这是因为池化操作在底层实现时，用的都是浮点计算

# input = torch.reshape(input,(-1,1,5,5))  

# print(input.shape)  
	##输出torch.Size([1,1,5,5])

#  

# class Tudui(nn.Module):  

#     def __init__(self):  

#         super().__init__()  

#         self.maxpool1 = nn.MaxPool2d(kernel_size=3,ceil_mode=True)  

#  

#     def forward(self, input):  

#         output = self.maxpool1(input)  

#         return output  

#  

# tudui = Tudui()  

# output = tudui(input)  

# print(output)  

   

# 02 针对数据集测试  

dataset = torchvision.datasets.CIFAR10(root=&apos;./data&apos;,  

                                       train=False,  

                                       transform=torchvision.transforms.ToTensor(),  

                                       download=True)  

dataloader = DataLoader(dataset,batch_size=64)  

  

class Tudui(nn.Module):  

    def __init__(self):  

        super().__init__()  

        self.maxpool1 = nn.MaxPool2d(kernel_size=3,ceil_mode=False)  

  

    def forward(self, input):  

        output = self.maxpool1(input)  

        return output  

  

tudui = Tudui()  

  

writer = SummaryWriter(&quot;logs&quot;)  

step = 0  

for data in dataloader:  

    imgs, targets = data  

    writer.add_images(&quot;input&quot;,imgs,step)  


    output = tudui(imgs)  

  

    writer.add_images(&quot;output&quot;,output,step)  

    step = step + 1  

  

writer.close()
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;1.1.2.3 Ⅲ 激活层&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;激活层一般采用 &lt;strong&gt;「非线性激活」&lt;/strong&gt; ，神经网络中引入非线性的特质，才能训练出符合各种特征的模型&lt;/p&gt;
&lt;p&gt;非线性激活函数有很多，如比较常见 &lt;strong&gt;「ReLU」&lt;/strong&gt; 和 &lt;strong&gt;「Sigmoid」&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;nn_relu.py&lt;/p&gt;
&lt;/blockquote&gt;
&lt;pre&gt;&lt;code&gt;import torch  

import torchvision  

from torch import nn  

from torch.nn import ReLU  

from torch.utils.data import DataLoader  

from torch.utils.tensorboard import SummaryWriter  

  

from nn_conv2d import dataloader  

  

# # 01 测试ReLU  

# input = torch.tensor([[1,-0.5],  

#                        [-1,3]])  


# output = torch.reshape(input,(-1,1,2,2))  
	## 输出( [[[[1, -0.5],
	##            [-1, 3]]]] )
	## 如果仅仅在此测试Relu中,可以不需要reshape,但在Conv2d这样的情况下就需要
	
# print(output.shape)  
	## 输出(1,1,2,2)



# class Tudui(nn.Module):  

#     def __init__(self):  

#         super().__init__()  

#         self.relu1 = nn.ReLU()  



#     def forward(self, input):  

#         output = self.relu1(input)  

#         return output  



# tudui = Tudui()  

# output = tudui(input)  

# print(output)  
	## 输出( [[[[1.,0.],
	##            [0., 3.]]]] )
  



# 02 Sigmoid  

dataset = torchvision.datasets.CIFAR10(root=&apos;./data&apos;,  

                                       train=False,  

                                       transform=torchvision.transforms.ToTensor(),  

                                       download=True)  

  

dataloader = DataLoader(dataset,batch_size=64)  

  

class Tudui(nn.Module):  

    def __init__(self):  

        super().__init__()  

        self.sigmoid1 = nn.Sigmoid()  

  

    def forward(self, input):  

        output = self.sigmoid1(input)  

        return output  

  

tudui = Tudui()  

  

writer = SummaryWriter(&quot;logs&quot;)  

  

step = 0  

for data in dataloader:  

    imgs, targets = data  

    writer.add_images(&quot;input&quot;,imgs,step)  

    output = tudui(imgs)  

    writer.add_images(&quot;output&quot;,output,step)  

    step += 1  

  

writer.close()
&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;p&gt;对于 Relu(input,inplace=True/False)&lt;/p&gt;
&lt;p&gt;True 代表替换原来的变量
&lt;img src=&quot;./assets/d1eca2a28f401217b5945dfbf806a631-6lcvf4zt-z2ft5lv.webp&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;1.1.2.4 Ⅳ 其他层&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;「Transformer Layers」 特定的网络结构&lt;/p&gt;
&lt;p&gt;「Sparse Layers」 特定的网络结构，其中的 Embedding 用于自然语言处理&lt;/p&gt;
&lt;p&gt;「Linear Layers」 用的较多，即 全连接层
&lt;img src=&quot;./assets/91c6d5f2a22884cd2ac3f956ff27ae5d-k9wvj-79-ztqv3o.webp&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;nn_linear.py&lt;/p&gt;
&lt;/blockquote&gt;
&lt;pre&gt;&lt;code&gt;import torch  

import torchvision  

from torch import nn  

from torch.nn import Linear  

from torch.utils.data import DataLoader  

  

dataset = torchvision.datasets.CIFAR10(&quot;./data&quot;,  

                                       train=False,  

                                       transform=torchvision.transforms.ToTensor(),  

                                       download=True)  

  

dataloader = DataLoader(dataset, batch_size=64)  

  

class Tudui(nn.Module):  

    def __init__(self):  

        super().__init__()  

        self.linear1 = Linear(196608, 10)  

  

    def forward(self, input):  

        output = self.linear1(input)  

        return output  

  

tudui = Tudui()  

  

for data in dataloader:  

    imgs, targets = data  

    print(imgs.shape) # torch.Size([64, 3, 32, 32])  

  

    # flatten 展平成一行  类似于reshape(1,1,1,-1),但是维度不一样哦
	# 注意, torch.flatten和下面代码中的nn.Flatten()不一样
    output = torch.flatten(imgs)  

    print(output.shape) # torch.Size([196608])  注意:变成一维的了
  

    output = tudui(output)  

    print(output.shape)
    ## 输出torch.Size([10])
&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;p&gt;[!NOTE]
注意点:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;torch.flatten(imgs)&lt;/code&gt;，它&lt;strong&gt;直接把所有图片合成了一个一维向量&lt;/strong&gt;，丢掉了 batch 信息。模型只能输出 `torch.Size([10])&lt;/p&gt;
&lt;p&gt;&lt;code&gt;nn.Flatten()&lt;/code&gt;，只展平单张图片，&lt;strong&gt;不会丢失 batch&lt;/strong&gt;，所以每一张图片都能独立得到 10 维预测，输出就是 &lt;code&gt;torch.Size([64,10])&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;1.1.3 Sequential&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;Sequential 主要是方便代码的编写，使代码更加简洁&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;根据下图搭建神经网络：判断一个图的类别（最后输出为十个类别，最后进行判断）&lt;img src=&quot;./assets/20250718152955923.png&quot; alt=&quot;2025-07-18_15-29-47.png&quot; /&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;nn_seq.py&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;未使用 sequential
&lt;img src=&quot;./assets/20250718154312620.png&quot; alt=&quot;2025-07-18_15-41-43.png&quot; /&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;使用 sequential 统一管理中间层&lt;/p&gt;
&lt;/blockquote&gt;
&lt;pre&gt;&lt;code&gt;import torch  

from torch import nn  

from torch.nn import Conv2d, MaxPool2d, Flatten, Linear, Sequential  

from torch.utils.tensorboard import SummaryWriter  

  

class Tudui(nn.Module):  

    def __init__(self):  

        super(Tudui, self).__init__()  

        self.model1 = Sequential(  

            Conv2d(3, 32, 5, padding=2),##对照以上那个图  

            MaxPool2d(2),  ##池化

            Conv2d(32, 32, 5, padding=2),  

            MaxPool2d(2),  

            Conv2d(32, 64, 5, padding=2),  

            MaxPool2d(2),  

            Flatten(),  ## 展平成一维

            Linear(1024, 64),  

            Linear(64, 10)  

        )  

  

    def forward(self, x):  

        x = self.model1(x)  

        return x  

  

tudui = Tudui()  

print(tudui)  

  

# 检查网络  

input = torch.ones((64, 3, 32, 32))  

output = tudui(input)  

print(output.shape)  ## 输出 torch.Size([64,10])

  
# tensorboard中的add_graph 查看神经网络的流程图  

writer = SummaryWriter(&quot;logs&quot;)  

writer.add_graph(tudui, input)  

writer.close()
&lt;/code&gt;&lt;/pre&gt;
&lt;h1&gt;1.2 损失&amp;amp;优化&lt;/h1&gt;
&lt;h2&gt;1.2.1 损失函数&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;损失函数（Loss Function）用于衡量模型的「预测输出」与「实际标签」之间的差异或者误差&lt;/p&gt;
&lt;p&gt;损失越小越好，根据 loss 调整参数，以减小损失 &lt;img src=&quot;./assets/304e06e4fc68fac4eaf17f5d86f68a49-d-nkg-qp-z2fic4r.webp&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;pre&gt;&lt;code&gt;# 计算output和target之差的「绝对值」

nn.L1Loss()

# 计算output和target之差的「均方差」

nn.MSELoss()
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&quot;./assets/0da9a7533ef2b36e39e3606f9a5225d9-byr0pmmp-zt78v1.webp&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# 交叉熵损失函数（Cross-Entropy Loss Function）是在分类问题中经常使用的一种损失函数

# 当分类预测正确时，损失要比较小，即\`-x[class]\`相比右边的项应较大

nn.CrossEntropyLoss()
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&quot;./assets/df4fa6e51c50cdbc5ac66987b0378511-dxky2nws-1yuhfv.webp&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;nn_loss.py&lt;/p&gt;
&lt;/blockquote&gt;
&lt;pre&gt;&lt;code&gt;import torch  

from torch.nn import L1Loss  

from torch import nn  

  

inputs = torch.tensor([1, 2, 3], dtype=torch.float32)  

targets = torch.tensor([1, 2, 5], dtype=torch.float32)  

  

inputs = torch.reshape(inputs, (1, 1, 1, 3))  

targets = torch.reshape(targets, (1, 1, 1, 3))  

  

# 01 L1Loss  

loss = L1Loss(reduction=&apos;sum&apos;) # mean or sum  选择计算方式

result = loss(inputs, targets)  

print(result)  

  

# 02 MSELoss  

loss_mse = nn.MSELoss()  

result_mse = loss_mse(inputs, targets)  

print(result_mse)  

  

# 03 CrossEntropyLoss  

x = torch.tensor([0.1, 0.2, 0.3])  

y = torch.tensor([1])  

x = torch.reshape(x, (1, 3))  
##`CrossEntropyLoss` 期望 x 的形状是 (1, 3)（一个样本，三个类别），y 的形状是 (1,)
## 必须将 x 的形状由 (3,) 变为 (1, 3)

loss_cross = nn.CrossEntropyLoss()  

result_cross = loss_cross(x, y)  

print(result_cross)
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;1.2.2 反向传播&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;前向传播：将训练集数据输入到 NN 的「输入层」，经过「隐藏层」，最后到达「输出层」并输出结果&lt;/p&gt;
&lt;p&gt;反向传播：计算估计值与实际值之间的误差，并将误差从「输出层」向「隐藏层」反向传播，直至「输入层」&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;nn_loss_network.py&lt;/p&gt;
&lt;/blockquote&gt;
&lt;pre&gt;&lt;code&gt;import torchvision  

from torch import nn  

from torch.nn import Sequential, Conv2d, MaxPool2d, Flatten, Linear  

from torch.utils.data import DataLoader  

  

dataset = torchvision.datasets.CIFAR10(&quot;./data&quot;,  

                                       train=False,  

                                       transform=torchvision.transforms.ToTensor(),  

                                       download=True)  

  

dataloader = DataLoader(dataset, batch_size=1)  

  

class Tudui(nn.Module):  

    def __init__(self):  

        super(Tudui, self).__init__()  

        self.model1 = Sequential(  

            Conv2d(3, 32, 5, padding=2),  

            MaxPool2d(2),  

            Conv2d(32, 32, 5, padding=2),  

            MaxPool2d(2),  

            Conv2d(32, 64, 5, padding=2),  

            MaxPool2d(2),  

            Flatten(),  

            Linear(1024, 64),  

            Linear(64, 10)  

        )  

  

    def forward(self, x):  

        x = self.model1(x)  

        return x  

  

loss = nn.CrossEntropyLoss()  

tudui = Tudui()  

for data in dataloader:  

    imgs, targets = data  

    outputs = tudui(imgs)  

    result_loss = loss(outputs, targets)  

    # 反向传播 计算梯度  

    result_loss.backward()  

    print(&quot;ok&quot;)
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;1.2.3 优化器&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;更新参数 减少损失&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;反向传播（backward）–&amp;gt; 计算出梯度（grad）–&amp;gt; 根据梯度和学习率更新参数 –&amp;gt; 减小 loss&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;优化器的种类比较多，常用的就是 SGD（随机梯度下降）&lt;/p&gt;
&lt;p&gt;不同优化器的参数列表不同，一般设置「parameters」和 l「lr」这两个参数，其他默认 &lt;img src=&quot;./assets/ea482701241d693f50662fa90f380ac0-ccnirmt4-2jtrqs.webp&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;nn_optim.py&lt;/p&gt;
&lt;/blockquote&gt;
&lt;pre&gt;&lt;code&gt;import torch  

import torchvision  

from torch import nn  

from torch.nn import Sequential, Conv2d, MaxPool2d, Flatten, Linear  

from torch.optim.lr_scheduler import StepLR  

from torch.utils.data import DataLoader  

  

dataset = torchvision.datasets.CIFAR10(&quot;./data&quot;,  

                                       train=False,  

                                       transform=torchvision.transforms.ToTensor(),  

                                       download=True)  

  

dataloader = DataLoader(dataset, batch_size=1)  

  

class Tudui(nn.Module):  

    def __init__(self):  

        super(Tudui, self).__init__()  

        self.model1 = Sequential(  

            Conv2d(3, 32, 5, padding=2),  

            MaxPool2d(2),  

            Conv2d(32, 32, 5, padding=2),  

            MaxPool2d(2),  

            Conv2d(32, 64, 5, padding=2),  

            MaxPool2d(2),  

            Flatten(),  

            Linear(1024, 64),  

            Linear(64, 10)  

        )  

  

    def forward(self, x):  

        x = self.model1(x)  

        return x  

  

loss = nn.CrossEntropyLoss()  

tudui = Tudui()  

  

# 优化器 SGD（随机梯度下降）  

optim = torch.optim.SGD(tudui.parameters(), lr=0.01) ## lr学习率，太大不稳定，太小收敛慢  
##tudui.parameters() 的作用：这个方法会自动遍历 `Tudui` 网络中所有子模块（比如 `Conv2d` 和 `Linear` 层），收集这些层的所有可训练参数，返回到torch.optim.SGD


for epoch in range(20):  ## 进行多轮学习

    running_loss = 0.0  

    for data in dataloader:  

        imgs, targets = data  

        outputs = tudui(imgs)  

        result_loss = loss(outputs, targets)  

  

        optim.zero_grad() # 把上一步的梯度清零，否则会累加  

        result_loss.backward()  

        optim.step() # 对weight参数进行更新  

  

        running_loss = running_loss + result_loss  

    print(running_loss)
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>02讲 - 数据 - PyTorch深度学习快速入门教程</title><link>https://www.futseyi.com/blog/pytorch-quickstart-data/</link><guid isPermaLink="true">https://www.futseyi.com/blog/pytorch-quickstart-data/</guid><description>PyTorch中加载和处理数据的相关内容。首先，介绍了Dataset和DataLoader，前者定义了如何获取数据，后者用于加载数据和提供给网络。通过MyData类演示了如何自定义Dataset。接着，讲解了使用TensorBoard进行可视化，包括安装和使用SummaryWriter添加图片和标量数据。然后，介绍了Transforms用于图像变换，包括ToTensor、Normalize、Resize、Compose和RandomCrop等操作，并强调了关注输入输出类型。最后，介绍了DataLoader，演示了如何批量加载数据，并通过TensorBoard查看数据。</description><pubDate>Mon, 14 Jul 2025 00:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;第 02 讲 数据📝&lt;/h1&gt;
&lt;h1&gt;1.1 加载数据&lt;/h1&gt;
&lt;h2&gt;1.1.1 Dataset&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;PyTorch 有关加载数据的，主要涉及 &lt;strong&gt;Dataset&lt;/strong&gt; 和 &lt;strong&gt;DataLoader&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;前者主要告诉后者如何 &lt;strong&gt;获取数据&lt;/strong&gt; ，后者主要用于 &lt;strong&gt;加载数据和为网络提供数据&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;img src=&quot;./assets/35b6ed1c23fde4eb9b0751ad293963a2-uuhm5y0k-z1x1j93.webp&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Dataset

    需要继承抽象父类 \`Dataset\`

    需要重写两个方法 

        \`__getitem__\` 

        \`__len__\`
&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;p&gt;read_data.py&lt;/p&gt;
&lt;/blockquote&gt;
&lt;pre&gt;&lt;code&gt;from torch.utils.data import Dataset  

from PIL import Image  

import os  

  

# 自己封装的 MyData类  

class MyData(Dataset):  

    def __init__(self, root_dir, label_dir):  

        self.root_dir = root_dir  

        self.label_dir = label_dir  

        self.path = os.path.join(self.root_dir, self.label_dir)  

        self.img_path = os.listdir(self.path)  

  

    def __getitem__(self, idx):  

        img_name = self.img_path[idx]  

        img_item_path = os.path.join(self.root_dir, self.label_dir, img_name)  

        img = Image.open(img_item_path)  

        label = self.label_dir  

        return img, label  

  

    def __len__(self):  

        return len(self.img_path)  

  

root_dir = &quot;dataset/train&quot;  

ants_label_dir = &quot;ants&quot;  

bees_label_dir = &quot;bees&quot;  

ants_dataset = MyData(root_dir, ants_label_dir)  

bees_dataset = MyData(root_dir, bees_label_dir)  

  

# 第1种方式  

print(ants_dataset[0])  

  

# 第2种方式（根据上面返回的提示而修改）  

img, label = ants_dataset[0]  

img.show()  

  

# 测试两个数据集的拼接 未改变顺序，ants在前 bees在后  

train_dataset = ants_dataset + bees_dataset  

print(len(ants_dataset))  

print(len(bees_dataset))  

print(len(train_dataset))  

  

img, label = train_dataset[123]  

img.show()  

img, label = train_dataset[124]  

img.show()
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;1.1.2 TensorBoard&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;我们不知道一个神经网络执行具体细节是什么，要人工调试十分困难&lt;/p&gt;
&lt;p&gt;TensorBoard 可以将程序的执行步骤都显示出来，对训练的参数（如损失值）统计并以图展现&lt;/p&gt;
&lt;/blockquote&gt;
&lt;pre&gt;&lt;code&gt;# 在「pytorch」环境中安装（记得关闭梯子）

pip install tensorboard
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;SummaryWriter类

    创建一个事件文件，在给定的目录中添加摘要和事件

        参数1 存放日志的文件夹名

本节视频只用到两个方法

    1. add_image()        

        在事件文件中添加图片

    2. add_scalar()    

        在TensorBoard中添加标量数据

        该方法可以用来添加训练过程中的损失值、准确率等指标，以便于在TensorBoard中进行可视化和比较
&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;p&gt;test_tb.py&lt;/p&gt;
&lt;/blockquote&gt;
&lt;pre&gt;&lt;code&gt;from torch.utils.tensorboard import SummaryWriter  

  

writer = SummaryWriter(&quot;logs&quot;)  ##存储到logs的文件夹

  

# y = 2x  

# 同一个图像标题下，重复修改y值会导致，新图会包含之前的旧图(是个bug,可以通过删除logs文件再创建)  

for i in range(100):  

    writer.add_scalar(&quot;y = 2x&quot;, 2*i, i)  # 2*i y轴    i x轴

writer.close()
&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;p&gt;查看日志的命令&lt;/p&gt;
&lt;/blockquote&gt;
&lt;pre&gt;&lt;code&gt;# logdir=事件文件所在的 文件夹名

tensorboard --logdir=logs

# 可以修改端口(原端口6006)

tensorboard --logdir=logs --port=6007
&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;p&gt;tensorboard.py&lt;/p&gt;
&lt;/blockquote&gt;
&lt;pre&gt;&lt;code&gt;from torch.utils.tensorboard import SummaryWriter  

from PIL import Image  

import numpy as np  

  

writer = SummaryWriter(&quot;logs&quot;)  

  

# 第1步  

# image_path = &quot;data/train/ants_image/0013035.jpg&quot;  

# 第2步  

image_path = &quot;data/train/bees_image/16838648_415acd9e3f.jpg&quot;  

  

img_PIL = Image.open(image_path)  ##获取的图像为PIL型

img_array = np.array(img_PIL)  ##从numpy转换图片类型格式,转为numpy.ndarray型

print(type(img_array))  

print(img_array.shape) ##查看格式为 &quot;HWC&quot;

  

# 从PIL到Numpy，需要在add_image()中指定图像的每一维  

writer.add_image(&quot;test&quot;, img_array, global_step=1, dataformats=&quot;HWC&quot;)
	##`global_step=1`就是告诉TensorBoard：“这张图是训练到第1步时的样子”。通过调整这个值，你能在TensorBoard中滑动查看训练过程中图像的演变。
	##这里的dataformats=&quot;HWC&quot;是格式,H代表高度,W代表宽度,C代表通道  

  
writer.close()
&lt;/code&gt;&lt;/pre&gt;
&lt;h1&gt;1.2 转换数据&lt;/h1&gt;
&lt;h2&gt;1.2.1 Transforms(一个工具箱)&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;Transforms 主要是用于图像变换的操作，可以对图像进行裁剪、标准化等&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;其包括很多常用的图像处理方法，比如 &lt;code&gt;transforms.ToTensor()&lt;/code&gt; &lt;img src=&quot;./assets/3faee1e71ef0c2eec74cea13a763c273-brfwqy8f-zmvgw1.webp&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;[!NOTE]
&lt;strong&gt;为什么用 Tensor 数据类型？&lt;/strong&gt;
Tensor 类型中的很多属性我们都需要在神经网络中用到，如反向传播、梯度等&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;test_tf.py&lt;/p&gt;
&lt;/blockquote&gt;
&lt;pre&gt;&lt;code&gt;from PIL import Image  

from torch.utils.tensorboard import SummaryWriter  

from torchvision import transforms  

  

img_path = &quot;data/train/ants_image/0013035.jpg&quot;  

img = Image.open(img_path)  

print(img)  

  

# 使用transforms  

 

&amp;gt; ToTensor() 可传入\`PIL Image\` 和 \`numpy.ndarray\` 两种图片格式  
&amp;gt; 
&amp;gt;     PIL Image：即用PIL的Image工具打开图像的格式  
&amp;gt; 
&amp;gt;     numpy.ndarray：即用OpenCV打开图像的格式（所以一般用这种方式打开，不用再转换图像了）  



tensor_trans = transforms.ToTensor() ##创建tensor_trans工具 

tensor_img = tensor_trans(img) ##使用tensor_trans工具将img转为Tensor型img 

print(tensor_img)  

  
# 创建tensorboard日志 可以使用tensorboard直观展示

writer = SummaryWriter(&quot;logs&quot;)  

writer.add_image(&quot;Tensor_img&quot;, tensor_img, 0)  

writer.close()
&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;p&gt;补充: 使用 opencv 读取图片&lt;/p&gt;
&lt;/blockquote&gt;
&lt;pre&gt;&lt;code&gt;import cv2

cv_img = cv2.imread(img_path)

print(cv_img) ## 使用opencv读取图片,可以直接得到numpy.ndarray类型img
&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;p&gt;[!NOTE]
多关注 &lt;strong&gt;「输入、输出」&lt;/strong&gt; 类型，不会的多看 &lt;strong&gt;「官方文档」&lt;/strong&gt;
关注方法需要的 &lt;strong&gt;「参数」&lt;/strong&gt; ，不知道返回值的时候 「Print」打印查看&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;call.py
展示 Python 中 &lt;strong&gt;call&lt;/strong&gt; 的用法&lt;/p&gt;
&lt;/blockquote&gt;
&lt;pre&gt;&lt;code&gt;# __call__ 让对象可以直接当函数使用

# 测试

class Person:  

    def __call__(self, name):  

        print(&quot; Hello &quot;+name)  

  

    def hello(self, name):  

        print(&quot;Hello &quot;+name)  

  

person = Person()  

#以下两种调用方式
person(&quot;zhangsan&quot;)## 调用的__call__

person.hello(&quot;lisi&quot;)## 调用的hello对象名
&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;p&gt;useful_tf.py
展示 transforms 的一些功能&lt;/p&gt;
&lt;/blockquote&gt;
&lt;pre&gt;&lt;code&gt;from PIL import Image  

from torch.utils.tensorboard import SummaryWriter  

from torchvision import transforms  

  

writer = SummaryWriter(&quot;logs&quot;)  

img = Image.open(&quot;images/0013035.jpg&quot;)  



print(img)  # 打印后得知，图像为RGB三通道  

  

# 01 transforms.ToTensor()  

trans_totensor = transforms.ToTensor()  

img_tensor = trans_totensor(img)  

print(img_tensor[0][0][0]) ## 打印张量中第一个通道、第一行、第一列的像素值,这通常是一个介于0到1之间的浮点数  

writer.add_image(&quot;ToTensor&quot;, img_tensor, 0) ##  0：全局步数(global step)，用于训练过程中跟踪不同步骤的图像  

  

# 02 transforms.Normalize()

# 是一种归一化,目的是将数据调整到特定的范围内，使其更适合模型训练或分析
# 公式 output[channel] = (input[channel] - mean[channel]) / std[channel]  

trans_norm = transforms.Normalize(mean=[0.5, 0.5, 0.5], std=[0.5, 0.5, 0.5]) 
## mean平均值;std标准差  
## 创建了一个标准化转换器，对RGB三个通道执行：减去均值0.5 ; 除以标准差0.5
## 公式为：normalized = (input - mean) / std

img_norm = trans_norm(img_tensor) ## 输入01得到的Tensor型img  

print(img_norm[0][0][0])  

writer.add_image(&quot;Normalize&quot;, img_norm, 0)  

  

# 03 Resize  用于调整图像尺寸

# 图像为PIL，经过Resize后，仍为PIL.设计初衷就是处理PIL图像，并保持相同的数据类型输出 
# transforms.Resize()可以接受两种参数形式：1. 单个整数：将图像的短边缩放到该尺寸，长边按比例缩放 2. 元组(h,w)：将图像精确缩放到指定尺寸

trans_resize = transforms.Resize((512, 512))  

img_resize = trans_resize(img)  

# 将PIL转为Tensor  

img_resize = trans_totensor(img_resize)  

writer.add_image(&quot;Resize&quot;, img_resize, 0)  

  

# 04 Compose 可以将几个转换组合在一起，先resize，再tensor
# Compose中的操作顺序必须合理

trans_resize_2 = transforms.Resize(512)  

trans_compose = transforms.Compose([trans_resize_2, trans_totensor])  ##相当于合并两个过程

img_resize_2 = trans_compose(img)  

writer.add_image(&quot;Resize&quot;, img_resize_2, 0)  

  

# 05 RandomCrop  随机裁剪

trans_random = transforms.RandomCrop(512)  

trans_compose_2 = transforms.Compose([trans_random, trans_totensor])  

for i in range(10):  ##随机裁剪十个

    img_crop = trans_compose_2(img)  

    writer.add_image(&quot;RandomCrop&quot;, img_crop, i)  

  

writer.close()
&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;p&gt;dataset_tf.py
展示 transform 与数据集使用&lt;/p&gt;
&lt;/blockquote&gt;
&lt;pre&gt;&lt;code&gt;import torchvision  

from torch.utils.tensorboard import SummaryWriter  


  

dataset_transforms = torchvision.transforms.Compose
([  

    torchvision.transforms.ToTensor() 
	## 这里可以进行其他操作(比如resize等等)

])  

train_set = torchvision.datasets.CIFAR10(root=&apos;./dataset&apos;,

                                        train=True,

                                        transform=dataset_transforms,

                                        download=True)  

test_set = torchvision.datasets.CIFAR10(root=&apos;./dataset&apos;,

                                        train=False,

                                        transform=dataset_transforms,

                                        download=True)  

  

# 01 查看一下数据信息  

print(test_set[0])  

## 输出 (&amp;lt;PIL.Image.Image image mode=RGB size=32x32 at 0x23653E11F60&amp;gt;, 3)

img, target = test_set[0]  

print(img)  

print(target) ## 标签也就是label

  

print(test_set.classes)  

print(test_set.classes[target]) # 输出cat(对应3)  

img.show()  

  

# 02 通过tensorboard查看  

writer = SummaryWriter(&quot;logs&quot;)  

  

for i in range(10):  

    img, target = train_set[i]  

    writer.add_image(&quot;test_set&quot;, img, i)  

  

writer.close()
&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;p&gt;查看 logs 日志&lt;/p&gt;
&lt;/blockquote&gt;
&lt;pre&gt;&lt;code&gt;tensorboard --logdir=&quot;logs&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;1.2.2 DataLoader&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;batch_size 取四个数据打包成 imgs.targets,相当于融合在一起&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;img src=&quot;./assets/b1de2e29462999e32b32df0b2a7f49ab-bnwilfj9-zsy3nn.webp&quot; alt=&quot;取四个数据打包&quot; /&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;dataloader.py&lt;/p&gt;
&lt;/blockquote&gt;
&lt;pre&gt;&lt;code&gt;import torchvision  

from torch.utils.data import DataLoader  

from torch.utils.tensorboard import SummaryWriter  

  
# 准备测试集
test_data = torchvision.datasets.CIFAR10(&quot;./dataset&quot;, 

                                        train=False,

                                        transform=torchvision.transforms.ToTensor(),

                                        download=True)  

# 加载测试集
test_loader = DataLoader(test_data,batch_size=64,shuffle=True,

                                                num_workers=0,

                                                drop_last=True)  
## shuffle=True表示在每次遍历数据集（即每个 epoch）前，将数据顺序打乱
## num_workers=0 表示 使用主线程加载数据（加载将是同步进行的）
  

# 查看测试数据集中第一张图片  

img, target = test_data[0]  

print(img.shape)  

print(target)  

  

writer = SummaryWriter(&quot;dataloader&quot;)  

for epoch in range(2):  ## 遍历两轮

    step = 0  

    for data in test_loader:  

        imgs, targets = data  

        # print(imgs.shape)  

        # print(targets)        

        writer.add_images(&quot;Epoch:{}&quot;.format(epoch),imgs,step)  

        step = step + 1  

  

writer.close()
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>01讲 - 配置 - PyTorch深度学习快速入门教程</title><link>https://www.futseyi.com/blog/pytorch-quickstart-configuration/</link><guid isPermaLink="true">https://www.futseyi.com/blog/pytorch-quickstart-configuration/</guid><description>在Anaconda环境下配置PyTorch开发环境的步骤。 首先，安装Anaconda，使用conda创建和激活pytorch环境。 然后，根据是否有显卡选择合适的PyTorch安装命令。 接着，测试PyTorch是否安装成功。 此外，教程还介绍了PyCharm和Jupyter Notebook的配置方法，以及如何使用PyCharm调试conda环境。 最后，讲解了dir()和help()两个函数在PyTorch中的作用。</description><pubDate>Sun, 13 Jul 2025 00:00:00 GMT</pubDate><content:encoded>&lt;blockquote&gt;
&lt;p&gt;教程视频见 B 站 up 主 &lt;a href=&quot;https://www.bilibili.com/video/BV1hE411t7RN?p=9&amp;amp;vd_source=db1ba321ac57d0740e3f5bc3b365ddff&quot;&gt;小土堆&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h1&gt;第 01 讲 配置📝&lt;/h1&gt;
&lt;h1&gt;1.1 基本环境&lt;/h1&gt;
&lt;h2&gt;1.1.1 Anaconda&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;安装当前最新版 Anaconda，安装时记好自己的 安装路径&lt;/p&gt;
&lt;/blockquote&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Anaconda&lt;/th&gt;
&lt;th&gt;链接&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;当前&lt;/td&gt;
&lt;td&gt;&lt;a href=&quot;https://www.anaconda.com/download/success&quot;&gt;https://www.anaconda.com/download/success&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;其他&lt;/td&gt;
&lt;td&gt;&lt;a href=&quot;https://repo.anaconda.com/&quot;&gt;https://repo.anaconda.com&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;blockquote&gt;
&lt;p&gt;也许，你之后会遇到不同的项目，需要使用到不同版本的环境&lt;/p&gt;
&lt;p&gt;比如这个项目要用到 pytorch 0.4，另一个项目要用到 pytorch 1.0&lt;/p&gt;
&lt;p&gt;Anaconda 集成的 conda 就能够解决这个问题&lt;/p&gt;
&lt;p&gt;它可以创造出两个屋子相互隔离，一个屋子放 0.4 版本，一个屋子放 1.0 版本。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;pre&gt;&lt;code&gt;# 启动Anaconda Prompt后，我们首先使用conda指令创建一个屋子，叫做pytorch

conda create -n pytorch python=3.6

# conda      指调用conda包

# create     创建的意思              

# -n         指后面的名字            

# pytorch    即名字(可以更改成自己喜欢的)   

# python=3.6 指创建的屋子为python3.6版本 

# 激活「pytorch」这个屋子

conda activate pytorch

# 查看「pytorch」中的包列表，目前还无pytorch包，需要安装

pip list
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;1.1.2 PyTorch&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;有显卡参考 cuda 版本选择 (无显卡选择 CPU 版本)，选择后复制相应指令&lt;/p&gt;
&lt;/blockquote&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;PyTorch&lt;/th&gt;
&lt;th&gt;链接&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;当前&lt;/td&gt;
&lt;td&gt;&lt;a href=&quot;https://pytorch.org/&quot;&gt;https://pytorch.org/&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;文档&lt;/td&gt;
&lt;td&gt;&lt;a href=&quot;https://pytorch.org/docs/stable/index.html&quot;&gt;https://pytorch.org/docs/stable/index.html&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;pre&gt;&lt;code&gt;# GPU版

pip3 install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu118

# CPU版
pip3 install torch torchvision torchaudio
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;# 测试PyTorch

#1(pytorch) C:\Users\morinha&amp;gt;
pip list

#2(pytorch) C:\Users\morinha&amp;gt;
python

···

&amp;gt;&amp;gt;&amp;gt; import torch

&amp;gt;&amp;gt;&amp;gt; torch.cuda.is_available() #检查GPU是否可以被Pytorch使用

True
&lt;/code&gt;&lt;/pre&gt;
&lt;h1&gt;1.2 基本工具&lt;/h1&gt;
&lt;h2&gt;1.2.1 PyCharm&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;安装当前最新版 PyCharm 专业版 &lt;a href=&quot;https://www.jetbrains.com/pycharm/download&quot;&gt;https://www.jetbrains.com/pycharm/download&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;新建项目 ： &lt;strong&gt;「自定义环境」&lt;/strong&gt; -&amp;gt; &lt;strong&gt;「选择现有」&lt;/strong&gt; -&amp;gt; &lt;strong&gt;「Conda」&lt;/strong&gt; -&amp;gt; &lt;strong&gt;「conda.exe 路径」&lt;/strong&gt; -&amp;gt; 选择创建的 pytorch &lt;img src=&quot;./assets/ec4f70a98895d5f0642cc2fae8daa4d8-b9qski00-zi9v6n.webp&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# Python 控制台 可以输入指令检测是否成功导入Conda的环境

import torch

torch.cuda.is_available()
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;# PyCharm 终端 不显示当前环境「pytorch」

解决办法：「设置」-&amp;gt;「工具 - 终端」-&amp;gt; 把 「Shell 路径」 修改为 「cmd.exe」
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;1.2.2 Jupyter&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;# 进入「pytorch」环境

conda activate pytorch

# 通过这个指令就可以安装好Jupyter

conda install nb_conda

# 在pytorch中启动Jupyter

jupyter notebook
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;新建项目： &lt;strong&gt;「New」&lt;/strong&gt; -&amp;gt; &lt;strong&gt;「conda 的 pytorch 环境」&lt;/strong&gt; &lt;img src=&quot;./assets/9bf24f5476c31d440f2eba6062a0a6a7-cfdzniky-zkwoyu.webp&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# Jupyter Notebook 测试

import torch

torch.cuda.is_available()
&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;p&gt;针对于 ssh 服务器的情况下&lt;/p&gt;
&lt;/blockquote&gt;
&lt;pre&gt;&lt;code&gt;#服务器上启动 Jupyter Notebook(指定了端口)
##--no-browser是 Jupyter Notebook 等命令行工具的一个启动参数，含义是启动服务器时不自动在本地主机打开浏览器
jupyter notebook --no-browser --port=8888

#在你的本地电脑上做 SSH 端口转发
ssh -L 8888:localhost:8888 cnb@10.1.0.100 #cnb@10.1.0.100是服务器的地址加用户名

#本地浏览器访问
http://localhost:8888/?token=xxxxxx
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;1.2.3 两个函数&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;TIP&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;查看帮助：PyCharm 中使用 &lt;strong&gt;「ctrl+ 鼠标移动」&lt;/strong&gt; Jupyter 中使用 &lt;strong&gt;「Name+??」&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;查看参数：PyCharm 中使用 &lt;strong&gt;「ctrl+P」&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&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;dir( )&lt;/td&gt;
&lt;td&gt;能让我们知道工具箱、工具箱中的分隔区有什么东西&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;help( )&lt;/td&gt;
&lt;td&gt;能让我们知道每个工具是如何使用&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;img src=&quot;./assets/cc733d193c182b310918d7b3efcf799f-m-3ok7u1-idkmk.webp&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# 导入 torch

import torch

# dir()

dir(torch)

dir(torch.cuda)

dir(torch.cuda.is_available) 

# help()

help(torch.cuda.is_available)
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;1.2.4 工具对比&lt;/h2&gt;
&lt;p&gt;&lt;img src=&quot;./assets/f6242db10c858c9372e22ca9a5add226-wcu7-iz8-1mzkrf.webp&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
</content:encoded></item><item><title>其他设备通过局域网内主机的代理VPN科学上网(以Jetson设备为例)</title><link>https://www.futseyi.com/blog/lan-vpn-proxy-for-devices/</link><guid isPermaLink="true">https://www.futseyi.com/blog/lan-vpn-proxy-for-devices/</guid><description>通过局域网内主机代理实现Jetson等设备科学上网。首先，在主机端配置代理服务（如v2ray），记录IP地址和端口号，并确保允许局域网访问。可通过修改代理配置文件或设置实现。</description><pubDate>Thu, 10 Jul 2025 00:00:00 GMT</pubDate><content:encoded>&lt;blockquote&gt;
&lt;p&gt;[!NOTE]
&lt;strong&gt;Jetson 等设备不会自动继承主机的代理规则&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h1&gt;1 ​&lt;strong&gt;​主机端代理设置​&lt;/strong&gt;​&lt;/h1&gt;
&lt;p&gt;首先确保主机已搭建代理服务（如 v2ray 等），并记录代理服务器的 IP 地址和端口号。例如：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#查看本地主机ip(不是固定的)
ipconfig
#IPv4 地址 
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;主机 IP：`192.168.3.68&lt;/li&gt;
&lt;li&gt;代理端口：&lt;code&gt;10809&lt;/code&gt;（HTTP）或 &lt;code&gt;10808&lt;/code&gt;（SOCKS5）&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;1.1 &lt;strong&gt;检查代理端口是否监听（Windows 主机）​&lt;/strong&gt;​&lt;/h2&gt;
&lt;p&gt;在 ​&lt;strong&gt;​Windows PowerShell​&lt;/strong&gt;​ 中运行以下命令：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;netstat -ano | findstr &quot;10809&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;如果输出中包含 &lt;code&gt;0.0.0.0:10809&lt;/code&gt; 或 &lt;code&gt;192.168.3.68:10809&lt;/code&gt;，说明代理服务正在运行并监听局域网。&lt;/li&gt;
&lt;li&gt;如果只有 &lt;code&gt;127.0.0.1:10809&lt;/code&gt;，说明代理仅限本地访问，需修改代理配置。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;1.2 ​&lt;strong&gt;​ 修改代理配置以允许局域网访问​&lt;/strong&gt;​&lt;/h2&gt;
&lt;p&gt;根据你的代理软件（如 Clash、Shadowsocks、v2ray 等）：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;​&lt;strong&gt;​打开代理软件的配置文件​&lt;/strong&gt;​（通常是 &lt;code&gt;.yaml&lt;/code&gt; 或 &lt;code&gt;.json&lt;/code&gt; 文件）。&lt;/li&gt;
&lt;li&gt;找到监听地址（&lt;code&gt;bind-address&lt;/code&gt; 或 &lt;code&gt;listen&lt;/code&gt;），将其改为：&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;# 允许所有 IP 访问
listen: 0.0.0.0:10809 
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;或者&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# 仅允许局域网访问
listen: 192.168.3.68:10809
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这里我使用的 v2ray 代理,可以直接在设置中参数设置中允许局域网连接&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./assets/20250708202937664.png&quot; alt=&quot;2025-07-08_20-29-09.png&quot; /&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;重启代理服务。&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;1.3 安全设置&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;​&lt;strong&gt;​限制访问 IP​&lt;/strong&gt;​：
在路由器或主机防火墙中，仅允许 Jetson 的 IP（如 &lt;code&gt;192.168.3.170）访问 &lt;/code&gt;10808/10809` 端口。&lt;/li&gt;
&lt;li&gt;在管理员终端输入&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;# 允许 Jetson (192.168.3.170) 访问 HTTP 代理端口 10809 
New-NetFirewallRule -DisplayName &quot;Allow_Jetson_HTTP&quot; -Direction Inbound -LocalPort 10809 -Protocol TCP -RemoteAddress 192.168.3.170 -Action Allow 
# 允许 Jetson 访问 SOCKS5 代理端口 10808 
New-NetFirewallRule -DisplayName &quot;Allow_Jetson_SOCKS5&quot; -Direction Inbound -LocalPort 10808 -Protocol TCP -RemoteAddress 192.168.3.170 -Action Allow
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;验证规则&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;`# 查看已创建的规则 
Get-NetFirewallRule -DisplayName &quot;Allow_Jetson_*&quot; | Format-Table DisplayName,Enabled,Action,Direction,RemoteAddress`
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;应输出&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;DisplayName        Enabled Action Direction RemoteAddress
-----------        ------- ------ --------- -------------
Allow_Jetson_SOCKS5   True Allow  Inbound   192.168.3.170
Allow_Jetson_HTTP     True Allow  Inbound   192.168.3.170
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;完成设置后，只有 Jetson 设备能使用你的代理，其他 IP 访问会被拒绝，安全性大幅提升！&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h1&gt;2 &lt;strong&gt;​Jetson 端设备配置​&lt;/strong&gt;​&lt;/h1&gt;
&lt;h2&gt;2.1 ​&lt;strong&gt;​系统级代理设置​&lt;/strong&gt;​&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;​&lt;strong&gt;​图形界面设置​&lt;/strong&gt;​&lt;/p&gt;
&lt;pre&gt;&lt;code&gt; - 进入 Ubuntu 的“设置” → “网络” → “网络代理”，选择“手动”模式。
 - 填写主机的代理 IP 和端口（如 HTTP/HTTPS 代理均设为 `192.168.3.68:10809`），保存并应用。
 - *注意*：此方法仅影响图形界面应用（如浏览器），终端仍需单独配置。
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;​&lt;strong&gt;​全局环境变量配置​&lt;/strong&gt;​&lt;/p&gt;
&lt;pre&gt;&lt;code&gt; - 编辑 `/etc/environment` 文件，添加以下内容（需管理员权限）：
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;http_proxy=&quot;http://192.168.3.68:10809&quot; 
https_proxy=&quot;http://192.168.3.68:10809&quot; 
no_proxy=&quot;localhost,127.0.0.1&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;source /etc/environment
# 执行或重启生效。
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;em&gt;适用场景&lt;/em&gt;：所有用户和终端命令（如 &lt;code&gt;apt&lt;/code&gt;、&lt;code&gt;curl&lt;/code&gt;）均通过代理。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;[!NOTE]
&lt;strong&gt;代理环境变量虽然已写入 &lt;code&gt;/etc/environment&lt;/code&gt;，但并未被当前 Shell 会话加载&lt;/strong&gt;
所以建议重启 Jetson 设备,这会强制重新加载所有系统环境变量（包括 &lt;code&gt;/etc/environment&lt;/code&gt; 中的代理配置）&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;2.2 ​&lt;strong&gt;​终端临时代理（仅当前会话有效）​&lt;/strong&gt;​&lt;/h2&gt;
&lt;p&gt;在终端中临时设置代理:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;export http_proxy=http://192.168.3.68:10809 
export https_proxy=http://192.168.3.68:10809
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;配置 HTTP 代理:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;git config --global http.proxy http://192.168.3.68:10809
git config --global https.proxy http://192.168.3.68:10809
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;取消代理配置:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;git config --global --unset http.proxy
git config --global --unset https.proxy
&lt;/code&gt;&lt;/pre&gt;
&lt;h1&gt;3 测试代理效果&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;在 Jetson 终端上测试输入&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;curl -x http://192.168.3.68:10809 -I https://www.google.com
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;如果返回 &lt;code&gt;HTTP/2 200&lt;/code&gt;，说明代理已生效&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;测试无显示代理的 curl&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;	curl -v http://www.google.com
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;​&lt;strong&gt;​预期结果​&lt;/strong&gt;​：&lt;/p&gt;
&lt;p&gt;显示代理连接日志（如 &lt;code&gt;Connecting to 192.168.3.68:10809…&lt;/code&gt;）&lt;/p&gt;
</content:encoded></item><item><title>Jetson系统烧入过程(以Orin - Nano为例)</title><link>https://www.futseyi.com/blog/jetson-orin-nano-flashing/</link><guid isPermaLink="true">https://www.futseyi.com/blog/jetson-orin-nano-flashing/</guid><description>Jetson Orin Nano 烧录系统有两种方法：使用 NVIDIA SDK Manager 或手动搭建 Linux_for_Tegra 环境进行烧录。本文介绍后者，需要在 Ubuntu 系统（16.04 或 18.04 LTS）上安装 qemu-user-static 和 python。然后，从 NVIDIA 官网下载驱动程序包和示例根文件系统包。解压后，进入 Linux_for_Tegra 目录，执行相关脚本。最后，使用 l4t_initrd_flash.sh脚本烧录系统，选择 NVMe 方式。烧录过程中，Jetson 设备会断开并重新连接。 成功后会出现 successful 提示。</description><pubDate>Wed, 09 Jul 2025 00:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;1 前言&lt;/h1&gt;
&lt;p&gt;Jetson 系列产品烧录系统的方法一般有两种，&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;一种为使用 NVIDIA 官方提供的 SDK manager 软件给 Jetson 设备烧录系统。&lt;/li&gt;
&lt;li&gt;另一种即为当前文档所描述的，在安装 Ubuntu 系统的电脑主机上搭建系统烧写目录 Linux_for_Tegra，使用 flash.sh 脚本进行烧录，&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;此方法不仅仅适用于烧录系统，还可用于提取配置好的 Jetson 系统。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;[!NOTE]
搭建 Jetson 系列产品烧录系统的环境需要在电脑主机上安装 Ubuntu 系统。
且安装的 Ubuntu 系统版本为 16.04 LTS 或者 18.04 LTS。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h1&gt;2 环境搭建过程&lt;/h1&gt;
&lt;h2&gt;2.1 在安装有 Ubuntu 系统的电脑主机上安装应用库&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;sudo apt-get install qemu-user-static 
sudo apt-get install python 
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;搭建环境的过程需要以上应用库来将某些 NVIDIA 软件组件安装到 Jetson 开发工具包中。&lt;/p&gt;
&lt;h2&gt;2.2 从 NVIDIA 官网下载所需版本的驱动程序包，和示例根文件系统包&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;下载链接如下：&lt;a href=&quot;https://developer.nvidia.com/embedded/linux-tegra-archive&quot;&gt;https://developer.nvidia.com/embedded/linux-tegra-archive&lt;/a&gt;。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;./assets/20250710095709144.png&quot; alt=&quot;2025-07-10_09-57-05.png&quot; /&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;[!NOTE]
这里我选择较为稳定的版本 35.3.1&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;下载相关文件到 ubuntu 系统中
&lt;img src=&quot;./assets/20250710100223016.png&quot; alt=&quot;2025-07-10_10-01-14.png&quot; /&gt;
&lt;img src=&quot;./assets/20250710100920813.png&quot; alt=&quot;2025-07-10_10-08-36.png&quot; /&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;2.3 查阅指导文档&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;选择版本进入后点击查看指导文档（Jetson Linux Developer Guide）&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;./assets/20250710095908458.png&quot; alt=&quot;2025-07-10_09-58-08.png&quot; /&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;选择目录中&lt;strong&gt;Quick Start&lt;/strong&gt;，滑动到 Environment Variables 部分开始着手操作
&lt;img src=&quot;./assets/20250710100716011.png&quot; alt=&quot;2025-07-10_10-07-04.png&quot; /&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h1&gt;3 开始动手烧录系统&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;通过以上操作,已经将相关驱动文件放入同一个文件夹 (我命名为 Jetson)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Jetson 设备硬件操作
&lt;img src=&quot;./assets/20250710103225255.png&quot; alt=&quot;2025-07-10_10-32-19.png&quot; /&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;具体步骤:&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ol&gt;
&lt;li&gt;解压包&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;1. cd jeston
2. tar xf Jetson_Linux_R35.3.1_aarch64.tbz2
3. sudo tar xpf Tegra_Linux_Sample-Root-Filesystem_R35.3.1_aarch64.tbz2 -C Linux_for_Tegra/rootfs/ #解压到Linux_for_Tegra/rootfs/中
4. cd Linux_for_Tegra/
5. sudo ./apply_binaries.sh 
6. sudo ./tools/l4t_flash_prerequisites.sh
&lt;/code&gt;&lt;/pre&gt;
&lt;ol&gt;
&lt;li&gt;开始烧录&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt; cd Linux_for_Tegra
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;查看&lt;strong&gt;Quick Start&lt;/strong&gt;的第六点,选择烧入的方式 (NVMe,USB,SD)&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./assets/20250710103616045.png&quot; alt=&quot;2025-07-10_10-36-13.png&quot; /&gt;&lt;/p&gt;
&lt;p&gt;这里 Jetson orin Nano 是板载了固态 NVMe,故使用第一条命令&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;sudo ./tools/kernel_flash/l4t_initrd_flash.sh --external-device nvme0n1p1 \   -c tools/kernel_flash/flash_l4t_external.xml -p &quot;-c bootloader/t186ref/cfg/flash_t234_qspi.xml&quot; \   --showlogs --network usb0 jetson-orin-nano-devkit internal
&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;p&gt;[!NOTE]
在烧录过程中,Jetson 设备与主机连接会断开,并重新连接,要及时确认连接到主机中才能继续烧录&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;[!NOTE]
重新连接后若出现如图所示问题:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./assets/20250710104406430.png&quot; alt=&quot;usb问题.png&quot; /&gt;&lt;/p&gt;
&lt;p&gt;可以换根数据线 or 换个在主机端换个数据口插&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;在烧录进行时,最后一步是 Step3&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;./assets/20250710104650792.png&quot; alt=&quot;2025-07-10_10-46-33.png&quot; /&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;出现 successful 就是大功告成啦!&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;./assets/20250710104748635.png&quot; alt=&quot;2025-07-10_10-47-39.png&quot; /&gt;&lt;/p&gt;
</content:encoded></item><item><title>Jetson Orin Nano开发指南记录</title><link>https://www.futseyi.com/blog/jetson-orin-nano-guide/</link><guid isPermaLink="true">https://www.futseyi.com/blog/jetson-orin-nano-guide/</guid><description>动手进行JetsonNanoCLB的开发学习</description><pubDate>Tue, 08 Jul 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;img src=&quot;./assets/jetson-orin-nano-qtr-numbered.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h1&gt;1 换源&lt;/h1&gt;
&lt;h2&gt;1.1 &lt;strong&gt;验证架构和源兼容性​&lt;/strong&gt;​&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;检查系统架构：&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;uname -m
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;如果是 &lt;code&gt;aarch64&lt;/code&gt; 或 &lt;code&gt;arm&lt;/code&gt;，必须使用 &lt;code&gt;ubuntu-ports&lt;/code&gt; 镜像源（如清华、中科大）。&lt;/li&gt;
&lt;li&gt;如果是 &lt;code&gt;x86_64&lt;/code&gt;，可直接用普通 Ubuntu 源。&lt;/li&gt;
&lt;li&gt;这里 Jetson 为 &lt;code&gt;aarch64&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;查看源&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;ls -la /etc/apt/sources.list.d/
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;1.2 两种换源方式&lt;/h2&gt;
&lt;h3&gt;1.2.1 方式 1.鱼香 ROS 一键换源&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;wget http://fishros.com/install -O fishros &amp;amp;&amp;amp; . fishros
&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;p&gt;[!NOTE]
不要清除第三方源: 这样会把 nvidia 源配置文件给删除&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;1.2.2 方式 2.输入以下代码换源&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;# 备份原有源 
sudo cp /etc/apt/sources.list /etc/apt/sources.list.bak 
# 使用 sed 替换为清华镜像源（适用于 ARM） 
sudo sed -i &apos;s|ports.ubuntu.com/ubuntu-ports|mirrors.tuna.tsinghua.edu.cn/ubuntu-ports|g&apos; /etc/apt/sources.list 
# 更新软件列表
sudo apt update
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;如果换源后出现问题，恢复备份：&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;sudo cp /etc/apt/sources.list.bak /etc/apt/sources.list 
sudo apt update
&lt;/code&gt;&lt;/pre&gt;
&lt;h1&gt;2 Jupyter Lab 的安装与使用&lt;/h1&gt;
&lt;p&gt;步骤 1: 更新 pip3 并安装 jupyter lab&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;sudo -H pip3 install --upgrade pip
pip3 install jupyter jupyterlab
sudo reboot
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;步骤 2: 生成 jupyter lab 配置文件&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;jupyter lab --generate-config
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;会生成.jupyter文件,其文件夹下有jupyter_lab_config.py配置文件
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;# 查看jupyterlab位置
which jupyter-lab
# 输出
/home/k/.local/bin/jupyter-lab
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;sudo nano /etc/systemd/system/jupyter.service
#添加以下
[Unit]
Description=Jupyter lab
After=network.target

[Service]
Type=simple
User=k
ExecStart=/home/k/.local/bin/jupyter-lab --port 8888 --no-browser
WorkingDirectory=/home/k/
Restart=always

[Install]
WantedBy=multi-user.target

#启动服务
sudo systemctl enable jupyter.service
sudo systemctl start jupyter.service

#检查是否运行
sudo systemctl status jupyter.service
##输出(active (running))
&lt;/code&gt;&lt;/pre&gt;
&lt;h1&gt;3 部署深度学习&lt;/h1&gt;
&lt;h2&gt;3.1 构建 Jetson-inference 环境&lt;/h2&gt;
&lt;p&gt;步骤 1.下载必要的依赖库&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;sudo apt-get update
sudo apt-get install git cmake
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;步骤 2.下载项目包&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;git clone https://github.com/dusty-nv/jetson-inference.git
cd jetson-inference/
git submodule update --init
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;步骤 3.下载 Python 项目包&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;sudo apt-get install libpython3-dev python3-numpy
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;步骤 4.使用 CMake 进行配置&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;cd  jetson-inference
mkdir build
cd build
cmake ../
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;中途跳出安装 pytorch,选择跳过,后面安装 (可选)&lt;/p&gt;
&lt;p&gt;步骤 5.编译项目&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;cd jetson-inference/build
make
sudo make install
sudo ldconfig
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;3.2 安装 Pytorch 人工智能框架 (迁移学习重新训练网络)(可选)&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;cd jetson-inference/build
./install-pytorch.sh
&lt;/code&gt;&lt;/pre&gt;
&lt;h1&gt;4 Hello AI Word 图像分类推理&lt;/h1&gt;
&lt;p&gt;开启一个终端输入&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#针对CSI摄像头
imagenet
#or
imagenet.py
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;#针对USB摄像头
imagenet /dev/video0
#or
imagenet.py /dev/video0
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>以RKNN系列模型为例，训练一个yolov7的目标检测模型</title><link>https://www.futseyi.com/blog/rknn-yolov7/</link><guid isPermaLink="true">https://www.futseyi.com/blog/rknn-yolov7/</guid><description>使用RKNN系列模型训练YOLOv7目标检测模型： 数据标注: 使用Labelimg标注图片，修改predefined_classes.txt。 模型训练: SSH进入计算服务器Docker，按README进行训练。将标注数据放入yolov7-rknn/datasets，修改数据集配置文件。在yolov7-rknn文件夹下执行train.py训练。训练后，使用export.py导出ONNX文件。 模型转换与部署: 参考airockchip/rknn-toolkit2进行模型转换。将转换好的模型拷贝至部署代码的model/RK3588文件夹，编写类别信息。修改include/postprocess.h和src/postprocess.cc，重新编译代码。按install.md文件执行，并使用orangepi-config使能串口。</description><pubDate>Tue, 08 Jul 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;img src=&quot;./assets/rk3588s.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h1&gt;1.数据标注&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;通过 labelimg 软件进行图片数据标注。&lt;/li&gt;
&lt;li&gt;深入解析 LabelImage：图像标注工具的全面指南 -CSDN 博客&lt;/li&gt;
&lt;li&gt;提前 predefined_classes.txt 文本中修改不同类别的数据。&lt;/li&gt;
&lt;/ul&gt;
&lt;h1&gt;2.模型训练&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;以 RKNN 系列模型为例，训练一个 yolov7 的目标检测模型。&lt;/li&gt;
&lt;li&gt;通过 SSH 进入计算服务器的 Docker 中，按照 readme 文件进行模型训练。&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://10.1.0.100:9000/&quot;&gt;http://10.1.0.100:9000/&lt;/a&gt; user:cnb keyword:cnb423423&lt;/li&gt;
&lt;li&gt;docker attach yolov7-gzq&lt;/li&gt;
&lt;li&gt;通常情况下将标注好的数据放入 yolov7-rknn/datasets 文件夹中，修改
yolov7-rknn/data 文件夹中的数据集配置文件，在 yolov7-rknn 文件夹
中执行 python train.py --data ./data/XXX.yaml --workers 8 --batch 64
--device 0 --epoch 300 进行训练&lt;/li&gt;
&lt;li&gt;执行后运行 python export.py --rknpu rk3588 --
weight ./runs/train/expXX/weights/best.pt 导出 onnx 文件以供转换。&lt;/li&gt;
&lt;/ul&gt;
&lt;h1&gt;3.模型转换与部署&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;参照 airockchip/rknn-toolkit2 at v1.5.2 进行模型转换。&lt;/li&gt;
&lt;li&gt;将转换好的模型拷贝至部署代码的 model/RK3588 的文件夹中，同
时参照 model 文件夹中的文本编写类别信息。&lt;/li&gt;
&lt;li&gt;修改 include/postprocess.h 中 OBJ_CLASS_NUM（类别数） 和
src/postprocess.cc 的 LABEL_NALE_TXT_PATH（类别信息文本的地
址）。&lt;/li&gt;
&lt;li&gt;重新执行编译脚本编译代码。&lt;/li&gt;
&lt;li&gt;按照 install.md 文件执行，并使用 orangepi-config 使能串口 0 和串
口 1。&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>常用软件配置分享 - 持续更新</title><link>https://www.futseyi.com/blog/software-configurations/</link><guid isPermaLink="true">https://www.futseyi.com/blog/software-configurations/</guid><description>本文分享了多款常用软件配置，涵盖Windows、Mac、Linux、Android等平台。内容分为工具类（系统增强、GIF、截图、剪切板、下载）、远程控制、OCR/翻译、局域网文件传输、图片查看器、图表和白板、PDF、解压缩、视频播放器、卸载工具、录屏、桌面快速启动管理等多个类别，并提供了软件名称、平台、说明及下载链接。文章持续更新，欢迎大家分享好用的软件和工具。 平台标识：Windows：🖥️Mac：🍏Linux：🐧Android：🤖工具类(系统增强，GIF，截图，剪切板)</description><pubDate>Wed, 02 Jul 2025 00:00:00 GMT</pubDate><content:encoded>&lt;blockquote&gt;
&lt;p&gt;该文章会持续更新
大家有什么好用的软件或工具也欢迎安利一下，大家一起交流进步。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;平台标识：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Windows：🖥️&lt;/li&gt;
&lt;li&gt;Mac：🍏&lt;/li&gt;
&lt;li&gt;Linux：🐧&lt;/li&gt;
&lt;li&gt;Android：🤖&lt;/li&gt;
&lt;/ul&gt;
&lt;h1&gt;1 我自己使用&lt;/h1&gt;
&lt;h2&gt;1.1 Mac&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;软件&lt;/th&gt;
&lt;th&gt;功能&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;DiskDrill&lt;/td&gt;
&lt;td&gt;磁盘文件恢复软件&lt;/td&gt;
&lt;td&gt;$89.99 买断&lt;/td&gt;
&lt;td&gt;如果早出现二十年，冠希哥会不会另一番模样&lt;/td&gt;
&lt;td&gt;AppStore&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;LocalSend&lt;/td&gt;
&lt;td&gt;跨平台局域网互传工具&lt;/td&gt;
&lt;td&gt;免费&lt;/td&gt;
&lt;td&gt;去™ 生态化反，老子就是来踢翻生态的&lt;/td&gt;
&lt;td&gt;AppStore&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;iShot&lt;/td&gt;
&lt;td&gt;长截图软件&lt;/td&gt;
&lt;td&gt;$4.49/年&lt;/td&gt;
&lt;td&gt;Safari 长截图的结果是个 pdf，嗯，你没看错，是 pdf&lt;/td&gt;
&lt;td&gt;AppStore&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Permute&lt;/td&gt;
&lt;td&gt;转码软件&lt;/td&gt;
&lt;td&gt;$14.99 买断&lt;/td&gt;
&lt;td&gt;又一个 ffmpeg 改套壳，与 Downie 打包买有优惠&lt;/td&gt;
&lt;td&gt;AppStore&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;AdGuard for Safari&lt;/td&gt;
&lt;td&gt;浏览器广告拦截&lt;/td&gt;
&lt;td&gt;基础功能免费&lt;/td&gt;
&lt;td&gt;网页广告屏蔽大师&lt;/td&gt;
&lt;td&gt;AppStore&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;YouTube Dubbing&lt;/td&gt;
&lt;td&gt;Chrome 插件网页视频实时翻译&lt;/td&gt;
&lt;td&gt;限量免费，￥569/年,按量付费&lt;/td&gt;
&lt;td&gt;支持很多外语,但目前还不支持你关心的那些网站&lt;/td&gt;
&lt;td&gt;Chrome 商店&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;LRTimelapse&lt;/td&gt;
&lt;td&gt;延时摄影后期&lt;/td&gt;
&lt;td&gt;C$ 192.71 买断&lt;/td&gt;
&lt;td&gt;不懂&lt;/td&gt;
&lt;td&gt;&lt;a href=&quot;https://lrtimelapse.com/&quot;&gt;&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ScreenFlow 10&lt;/td&gt;
&lt;td&gt;录屏 + 录音 + 录像 + 剪辑&lt;/td&gt;
&lt;td&gt;$169.99 买断&lt;/td&gt;
&lt;td&gt;网课达人&lt;/td&gt;
&lt;td&gt;AppStore&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;自动操作&lt;/td&gt;
&lt;td&gt;自动化工作流&lt;/td&gt;
&lt;td&gt;免费&lt;/td&gt;
&lt;td&gt;脚本小子（图形版）&lt;/td&gt;
&lt;td&gt;系统内置&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;贝锐向日葵&lt;/td&gt;
&lt;td&gt;远程桌面&lt;/td&gt;
&lt;td&gt;基础功能免费&lt;/td&gt;
&lt;td&gt;RustDesk 不香吗&lt;/td&gt;
&lt;td&gt;&lt;a href=&quot;https://www.oray.com/&quot;&gt;&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Final Cut Pro&lt;/td&gt;
&lt;td&gt;剪辑软件&lt;/td&gt;
&lt;td&gt;$299.99 买断&lt;/td&gt;
&lt;td&gt;买之前最好问问自己，剪多少条视频能回本&lt;/td&gt;
&lt;td&gt;AppStore&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;剪映&lt;/td&gt;
&lt;td&gt;剪辑软件&lt;/td&gt;
&lt;td&gt;基础功能免费&lt;/td&gt;
&lt;td&gt;上手剪辑很简单&lt;/td&gt;
&lt;td&gt;AppStore&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Tickets&lt;/td&gt;
&lt;td&gt;键盘音效&lt;/td&gt;
&lt;td&gt;免费&lt;/td&gt;
&lt;td&gt;压力不会消失，但可以转移（给同事）&lt;/td&gt;
&lt;td&gt;&lt;a href=&quot;https://github.com/yingDev/Tickeys&quot;&gt;&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;像素蛋糕&lt;/td&gt;
&lt;td&gt;修图&lt;/td&gt;
&lt;td&gt;按量付费&lt;/td&gt;
&lt;td&gt;说是摄影棚里常用&lt;/td&gt;
&lt;td&gt;&lt;a href=&quot;https://www.pixcakeai.com/&quot;&gt;&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;1Password&lt;/td&gt;
&lt;td&gt;密码管理器&lt;/td&gt;
&lt;td&gt;$2.99 起/月&lt;/td&gt;
&lt;td&gt;内置的密钥管理软件不好用吗&lt;/td&gt;
&lt;td&gt;AppStore&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2&gt;1.2 Windows&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&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;Uninstall&lt;/td&gt;
&lt;td&gt;卸载工具&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;OBS&lt;/td&gt;
&lt;td&gt;录屏&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Windows11 轻松&amp;lt;br&amp;gt;(64bit) 设置&lt;/td&gt;
&lt;td&gt;win11 设置工具&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;PotPlayer&lt;/td&gt;
&lt;td&gt;媒体播放工具&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;图吧工具箱 2025&lt;/td&gt;
&lt;td&gt;win 本工具箱&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;PartAssist&lt;/td&gt;
&lt;td&gt;傲梅分区助手&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;SD Card Formatter&lt;/td&gt;
&lt;td&gt;SD 卡格式化工具&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;BalenaEtcher&lt;/td&gt;
&lt;td&gt;镜像烧入工具&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;PixPin&lt;/td&gt;
&lt;td&gt;截图工具&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;V2rayN&lt;/td&gt;
&lt;td&gt;代理工具&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;PDFXEdit&lt;/td&gt;
&lt;td&gt;pdf 工具&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;IDM&lt;/td&gt;
&lt;td&gt;下载工具&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;LocalSend&lt;/td&gt;
&lt;td&gt;多设备传输工具&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Todesk&lt;/td&gt;
&lt;td&gt;远程桌面&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Piclist&lt;/td&gt;
&lt;td&gt;图床工具 (可以在 github 备份配置文件)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;G-Helper&lt;/td&gt;
&lt;td&gt;ROG 替代奥创中心&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;EcoPaste&lt;/td&gt;
&lt;td&gt;一款开源的跨平台剪切板管理工具&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ExplorerTabUtility&lt;/td&gt;
&lt;td&gt;大幅提升 Windows 11 文件资源管理器的功能：自动将窗口转换为标签页、复制标签页、重新打开已关闭的标签页等等！&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h1&gt;2 工具类 (系统增强，GIF，截图，剪切板，下载)&lt;/h1&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;分类&lt;/th&gt;
&lt;th&gt;名称&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;增强&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;uTools&lt;/td&gt;
&lt;td&gt;🖥️/🍏/🐧&lt;/td&gt;
&lt;td&gt;自由组合插件应用，打造专属你的趁手工具集&lt;/td&gt;
&lt;td&gt;&lt;a href=&quot;https://www.u.tools/download/&quot;&gt;官网&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;GeekDesk 极客桌面&lt;/td&gt;
&lt;td&gt;🖥️&lt;/td&gt;
&lt;td&gt;小巧美观的桌面快速入门管理工具，集成了所有内容搜索&lt;/td&gt;
&lt;td&gt;&lt;a href=&quot;https://github.com/BookerLiu/GeekDesk&quot;&gt;Github&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;CLaunch&lt;/td&gt;
&lt;td&gt;🖥️&lt;/td&gt;
&lt;td&gt;一个快捷启动的小工具，和它的前辈 nrLaunch 一样，继承了日系软件小巧、响应快、简单、方便实用的优点&lt;/td&gt;
&lt;td&gt;&lt;a href=&quot;https://ss1.xrea.com/pyonkichi.g1.xrea.com/en/&quot;&gt;官网&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;ContextMenuManager&lt;/td&gt;
&lt;td&gt;🖥️&lt;/td&gt;
&lt;td&gt;🖱️ 纯粹的 Windows 右键菜单管理程序&lt;/td&gt;
&lt;td&gt;&lt;a href=&quot;https://github.com/BluePointLilac/ContextMenuManager&quot;&gt;Github&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;TrafficMonitor&lt;/td&gt;
&lt;td&gt;🖥️&lt;/td&gt;
&lt;td&gt;用于显示当前网速、CPU 及内存利用率的桌面悬浮窗软件，并支持任务栏显示，支持更换皮肤&lt;/td&gt;
&lt;td&gt;&lt;a href=&quot;https://github.com/zhongyang219/TrafficMonitor&quot;&gt;Github&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;lockhunter&lt;/td&gt;
&lt;td&gt;🖥️&lt;/td&gt;
&lt;td&gt;强制解除文件占用&lt;/td&gt;
&lt;td&gt;&lt;a href=&quot;https://lockhunter.com/&quot;&gt;官网&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;DropPoint&lt;/td&gt;
&lt;td&gt;🖥️/🍏/🐧&lt;/td&gt;
&lt;td&gt;让拖放变得更容易。 无需打开并排窗口即可拖动内容&lt;/td&gt;
&lt;td&gt;&lt;a href=&quot;https://github.com/GameGodS3/DropPoint&quot;&gt;Github&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;ComputerLock&lt;/td&gt;
&lt;td&gt;🖥️&lt;/td&gt;
&lt;td&gt;透明锁屏，一个另类的锁屏工具。&lt;/td&gt;
&lt;td&gt;&lt;a href=&quot;https://github.com/JiuLing-zhang/ComputerLock&quot;&gt;Github&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;OpenArk&lt;/td&gt;
&lt;td&gt;🖥️&lt;/td&gt;
&lt;td&gt;适用于 Windows 的开源 anti-rookit（ARK） 工具&lt;/td&gt;
&lt;td&gt;&lt;a href=&quot;https://github.com/BlackINT3/OpenArk&quot;&gt;Github&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;optimizer&lt;/td&gt;
&lt;td&gt;🖥️&lt;/td&gt;
&lt;td&gt;最好的 Windows 优化器&lt;/td&gt;
&lt;td&gt;&lt;a href=&quot;https://github.com/hellzerg/optimizer&quot;&gt;Github&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;SophiApp&lt;/td&gt;
&lt;td&gt;🖥️&lt;/td&gt;
&lt;td&gt;用于优化设置 Windows 10 和 Windows 11&lt;/td&gt;
&lt;td&gt;&lt;a href=&quot;https://github.com/Sophia-Community/SophiApp&quot;&gt;Github&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;火绒弹窗拦截独立版&lt;/td&gt;
&lt;td&gt;🖥️&lt;/td&gt;
&lt;td&gt;广告弹窗拦截 (蓝奏 密码:7v9p)&lt;/td&gt;
&lt;td&gt;&lt;a href=&quot;https://wangxy.lanzouw.com/iiE1W1f4ddyb&quot;&gt;蓝奏&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;拖把更名器&lt;/td&gt;
&lt;td&gt;🖥️&lt;/td&gt;
&lt;td&gt;批量重命名，第一次需要以管理员身份运行 (蓝奏 密码:cjsm)&lt;/td&gt;
&lt;td&gt;&lt;a href=&quot;https://wangxy.lanzouw.com/b02pa8r0d&quot;&gt;蓝奏&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;截图&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;pixpin&lt;/td&gt;
&lt;td&gt;🖥️ /&lt;a href=&quot;https://txc.qq.com/products/614512/post/171289481172242166/&quot;&gt;🍏测试版&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;功能强大使用简单的截图/贴图工具，帮助你提高效率&lt;/td&gt;
&lt;td&gt;&lt;a href=&quot;https://pixpinapp.com/&quot;&gt;官网&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;Snipaste 贴图&lt;/td&gt;
&lt;td&gt;🖥️/🍏&lt;/td&gt;
&lt;td&gt;微软强大的截图/贴图,不过没有 OCR 功能,故略逊于 PixPin&lt;/td&gt;
&lt;td&gt;&lt;a href=&quot;https://zh.snipaste.com/download.html&quot;&gt;官网&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;snipaste&lt;/td&gt;
&lt;td&gt;🖥️/🍏/🐧&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href=&quot;https://zh.snipaste.com/download.html&quot;&gt;官网&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;faststone&lt;/td&gt;
&lt;td&gt;🖥️&lt;/td&gt;
&lt;td&gt;这是一款功能强大、轻巧且功能完备的屏幕捕捉工具&lt;/td&gt;
&lt;td&gt;&lt;a href=&quot;https://www.faststone.org/FSCaptureDownload.htm&quot;&gt;官网&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Gif&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;screentogif&lt;/td&gt;
&lt;td&gt;🖥️&lt;/td&gt;
&lt;td&gt;GIF 录制编辑工具&lt;/td&gt;
&lt;td&gt;&lt;a href=&quot;https://www.screentogif.com/&quot;&gt;官网&lt;/a&gt; &lt;a href=&quot;https://github.com/NickeManarin/ScreenToGif&quot;&gt;Github&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;剪切板&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;Ditto&lt;/td&gt;
&lt;td&gt;🖥️&lt;/td&gt;
&lt;td&gt;剪切板增强&lt;/td&gt;
&lt;td&gt;&lt;a href=&quot;https://ditto-cp.sourceforge.io/&quot;&gt;官网&lt;/a&gt; &lt;a href=&quot;https://github.com/sabrogden/Ditto&quot;&gt;Github&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;CopyQ&lt;/td&gt;
&lt;td&gt;🖥️/🍏/🐧&lt;/td&gt;
&lt;td&gt;具有高级功能的剪贴板管理器&lt;/td&gt;
&lt;td&gt;&lt;a href=&quot;https://hluk.github.io/CopyQ/&quot;&gt;官网&lt;/a&gt; &lt;a href=&quot;https://github.com/hluk/CopyQ&quot;&gt;Github&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;EcoPaste&lt;/td&gt;
&lt;td&gt;🖥️/🍏/🐧&lt;/td&gt;
&lt;td&gt;一款开源的跨平台剪切板管理工具&lt;/td&gt;
&lt;td&gt;&lt;a href=&quot;https://ecopaste.cn/&quot;&gt;官网&lt;/a&gt; &lt;a href=&quot;https://github.com/ayangweb/EcoPaste&quot;&gt;Github&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;下载&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;Free Download Manager&lt;/td&gt;
&lt;td&gt;🖥️/🍏/🐧/🤖&lt;/td&gt;
&lt;td&gt;強大又現代的下載加速組織器。没有广告软件。100% 清洁，100% 完全免费&lt;/td&gt;
&lt;td&gt;&lt;a href=&quot;https://www.freedownloadmanager.org/zh/&quot;&gt;官网&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;Free Download Manager 补充插件&lt;/td&gt;
&lt;td&gt;🖥️/🍏/🐧/🤖&lt;/td&gt;
&lt;td&gt;视频下载插件&lt;/td&gt;
&lt;td&gt;&lt;a href=&quot;https://github.com/meowcateatrat/elephant&quot;&gt;Elephant addon for FDM&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;文件资源管理器&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;ExplorerTabUtility&lt;/td&gt;
&lt;td&gt;🖥️&lt;/td&gt;
&lt;td&gt;大幅提升 Windows 11 文件资源管理器的功能：自动将窗口转换为标签页、复制标签页、重新打开已关闭的标签页等等！&lt;/td&gt;
&lt;td&gt;&lt;a href=&quot;https://github.com/w4po/ExplorerTabUtility.git&quot;&gt;官网&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h1&gt;3 插件工具&lt;/h1&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;浏览器插件&lt;/th&gt;
&lt;th&gt;B2Y&lt;/th&gt;
&lt;th&gt;🖥️/🍏/🐧/🤖&lt;/th&gt;
&lt;th&gt;YouTube 同步显示 Bilibili 弹幕&lt;/th&gt;
&lt;th&gt;&lt;a href=&quot;https://github.com/ahaduoduoduo/bilibili-youtube-danmaku.git&quot;&gt;Github地址&lt;/a&gt;&amp;lt;br&amp;gt;&lt;a href=&quot;https://chromewebstore.google.com/detail/b2y-youtube-%E5%90%8C%E6%AD%A5%E6%98%BE%E7%A4%BA-bilibili/dmkbhbnbpfijhgpnfahfioedledohfja&quot;&gt;谷歌商店插件&lt;/a&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;/table&gt;
&lt;h1&gt;4 命令行工具&lt;/h1&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;名称&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;Lux&lt;/td&gt;
&lt;td&gt;🍏&lt;/td&gt;
&lt;td&gt;在 Mac 终端命令粘贴视频链接,直接提取下载&lt;/td&gt;
&lt;td&gt;&lt;a href=&quot;https://github.com/iawia002/lux&quot;&gt;官网&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h1&gt;5 远程控制&lt;/h1&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;名称&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;RustDesk&lt;/td&gt;
&lt;td&gt;🖥️/🍏/🐧/🤖&lt;/td&gt;
&lt;td&gt;一款功能完备的开源远程控制替代方案，适用于自托管和安全需求，配置简单。&lt;/td&gt;
&lt;td&gt;&lt;a href=&quot;https://rustdesk.com/&quot;&gt;官网&lt;/a&gt; &lt;a href=&quot;https://www.wxy97.com/archives/58&quot;&gt;自建教程&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Todesk&lt;/td&gt;
&lt;td&gt;🖥️/🍏/🐧/🤖&lt;/td&gt;
&lt;td&gt;支持 1080p 高清画质，连接稳定不限速&lt;/td&gt;
&lt;td&gt;&lt;a href=&quot;https://www.todesk.com/&quot;&gt;官网&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;anydesk&lt;/td&gt;
&lt;td&gt;🖥️/🍏/🐧/🤖&lt;/td&gt;
&lt;td&gt;远程访问的明智之选&lt;/td&gt;
&lt;td&gt;&lt;a href=&quot;https://anydesk.com/zhs&quot;&gt;官网&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h1&gt;6 OCR/翻译&lt;/h1&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;名称&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;STranslate&lt;/td&gt;
&lt;td&gt;🖥️&lt;/td&gt;
&lt;td&gt;一款即开即用、即用即走的翻译、OCR 工具&lt;/td&gt;
&lt;td&gt;&lt;a href=&quot;https://stranslate.zggsong.com/&quot;&gt;官网&lt;/a&gt; &lt;a href=&quot;https://github.com/ZGGSONG/STranslate&quot;&gt;Github&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Pot&lt;/td&gt;
&lt;td&gt;🖥️/🍏/🐧&lt;/td&gt;
&lt;td&gt;跨平台划词翻译和 OCR&lt;/td&gt;
&lt;td&gt;&lt;a href=&quot;https://pot-app.com/&quot;&gt;官网&lt;/a&gt; &lt;a href=&quot;https://github.com/pot-app/pot-desktop&quot;&gt;Github&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Umi-OCR&lt;/td&gt;
&lt;td&gt;🖥️&lt;/td&gt;
&lt;td&gt;开源、免费的离线 OCR 软件。支持截屏/批量导入图片，PDF 文档识别，排除水印/页眉页脚，扫描/生成二维码。内置多国语言库。&lt;/td&gt;
&lt;td&gt;&lt;a href=&quot;https://github.com/hiroi-sora/Umi-OCR&quot;&gt;Github&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;天若 ocr&lt;/td&gt;
&lt;td&gt;🖥️&lt;/td&gt;
&lt;td&gt;文本识别，截图功能， 录制 gif， 上传图床， 截图矫正， 配置云同步&lt;/td&gt;
&lt;td&gt;&lt;a href=&quot;https://ocr.tianruo.net/&quot;&gt;官网&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h1&gt;7 局域网文件传输&lt;/h1&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;名称&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;webd&lt;/td&gt;
&lt;td&gt;🖥️/🐧&lt;/td&gt;
&lt;td&gt;轻量级&lt;/td&gt;
&lt;td&gt;&lt;a href=&quot;https://webd.cf/webd/webd.zh.html&quot;&gt;官网&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;CuteHttpFileServer/chfs&lt;/td&gt;
&lt;td&gt;🖥️/🍏/🐧&lt;/td&gt;
&lt;td&gt;免费的、HTTP 协议的文件共享服务器，使用浏览器可以快速访问。(局域网文件传输)&lt;/td&gt;
&lt;td&gt;&lt;a href=&quot;http://iscute.cn/chfs&quot;&gt;官网&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;gohttpserver&lt;/td&gt;
&lt;td&gt;🖥️/🍏/🐧&lt;/td&gt;
&lt;td&gt;最好的 HTTP 静态文件服务器，用 golang+vue 编写&lt;/td&gt;
&lt;td&gt;&lt;a href=&quot;https://github.com/codeskyblue/gohttpserver&quot;&gt;Github&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;localsend&lt;/td&gt;
&lt;td&gt;🖥️/🍏/🐧/🤖&lt;/td&gt;
&lt;td&gt;将文件分享到附近的设备。免费、开源、跨平台。&lt;/td&gt;
&lt;td&gt;&lt;a href=&quot;https://localsend.org/zh-CN&quot;&gt;官网&lt;/a&gt; &lt;a href=&quot;https://github.com/localsend/localsend&quot;&gt;Github&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;transok-wails&lt;/td&gt;
&lt;td&gt;🖥️/🍏&lt;/td&gt;
&lt;td&gt;一个高效的局域网文件共享工具&lt;/td&gt;
&lt;td&gt;&lt;a href=&quot;https://github.com/bent2685/transok-wails&quot;&gt;Github&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;dufs&lt;/td&gt;
&lt;td&gt;🖥️/🍏/🐧&lt;/td&gt;
&lt;td&gt;文件服务器支持静态服务、上传、搜索、访问控制、webdav…&lt;/td&gt;
&lt;td&gt;&lt;a href=&quot;https://github.com/sigoden/dufs&quot;&gt;Github&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h1&gt;8 图片查看器&lt;/h1&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;名称&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;FSViewerSetup&lt;/td&gt;
&lt;td&gt;🖥️&lt;/td&gt;
&lt;td&gt;图像查看器&lt;/td&gt;
&lt;td&gt;&lt;a href=&quot;https://www.faststone.org/FSIVDownload.htm&quot;&gt;官网&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Honeyview&lt;/td&gt;
&lt;td&gt;🖥️&lt;/td&gt;
&lt;td&gt;快速的图片查看器&lt;/td&gt;
&lt;td&gt;&lt;a href=&quot;https://www.bandisoft.com/honeyview/&quot;&gt;官网&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h1&gt;9 图表和白板&lt;/h1&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;名称&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;drawio-desktop&lt;/td&gt;
&lt;td&gt;🖥️/🍏/🐧&lt;/td&gt;
&lt;td&gt;强大、免费的绘图工具&lt;/td&gt;
&lt;td&gt;&lt;a href=&quot;https://github.com/jgraph/drawio-desktop&quot;&gt;Github&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h1&gt;10 PDF&lt;/h1&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;名称&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;Sumatra PDF&lt;/td&gt;
&lt;td&gt;🖥️&lt;/td&gt;
&lt;td&gt;PDF、电子书 (epub、mobi)、漫画书 (cbz/cbr)、DjVu、XPS、CHM、Windows 图像 浏览器。&lt;/td&gt;
&lt;td&gt;&lt;a href=&quot;https://www.sumatrapdfreader.org/free-pdf-reader&quot;&gt;官网&lt;/a&gt; &lt;a href=&quot;https://github.com/sumatrapdfreader/sumatrapdf&quot;&gt;Github&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h1&gt;11 解压缩&lt;/h1&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;名称&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;7-zip&lt;/td&gt;
&lt;td&gt;🖥️&lt;/td&gt;
&lt;td&gt;完全的开源免费软件，并且压缩率极高。&lt;/td&gt;
&lt;td&gt;&lt;a href=&quot;https://www.7-zip.org/&quot;&gt;官网&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;NanaZip&lt;/td&gt;
&lt;td&gt;🖥️&lt;/td&gt;
&lt;td&gt;适用于现代 Windows 体验的 7-Zip 衍生产品&lt;/td&gt;
&lt;td&gt;&lt;a href=&quot;https://github.com/M2Team/NanaZip&quot;&gt;Github&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Bandizip&lt;/td&gt;
&lt;td&gt;🖥️/🍏&lt;/td&gt;
&lt;td&gt;面向专业人士的压缩软&lt;/td&gt;
&lt;td&gt;&lt;a href=&quot;https://cn.bandisoft.com/bandizip/&quot;&gt;官网&lt;/a&gt; &lt;a href=&quot;https://www.ghxi.com/bandizip.html&quot;&gt;果核&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;WinRar&lt;/td&gt;
&lt;td&gt;🖥️/🍏/🤖&lt;/td&gt;
&lt;td&gt;老牌压缩软件&lt;/td&gt;
&lt;td&gt;&lt;a href=&quot;https://www.winrar.com.cn/index.htm&quot;&gt;官网&lt;/a&gt; &lt;a href=&quot;https://www.ghxi.com/pcwinrar.html&quot;&gt;果核&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;peazip&lt;/td&gt;
&lt;td&gt;🖥️/🍏/🐧&lt;/td&gt;
&lt;td&gt;实用的免费的压缩软件，功能全面易于使用。&lt;/td&gt;
&lt;td&gt;&lt;a href=&quot;https://peazip.github.io/&quot;&gt;官网&lt;/a&gt; &lt;a href=&quot;https://github.com/peazip/PeaZip&quot;&gt;Github&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h1&gt;12 视频播放器&lt;/h1&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;名称&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;potplayer&lt;/td&gt;
&lt;td&gt;🖥️&lt;/td&gt;
&lt;td&gt;万能格式影音播放器&lt;/td&gt;
&lt;td&gt;&lt;a href=&quot;https://potplayer.daum.net/?lang=zh_CN&quot;&gt;官网1&lt;/a&gt; &lt;a href=&quot;http://potplayer.tv/?lang=zh_CN&quot;&gt;官网2&lt;/a&gt; &lt;a href=&quot;https://www.ghxi.com/potplayer.html&quot;&gt;果核&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;VLC&lt;/td&gt;
&lt;td&gt;🖥️/🍏/🐧/🤖&lt;/td&gt;
&lt;td&gt;一款自由、开源的跨平台多媒体播放器及框架&lt;/td&gt;
&lt;td&gt;&lt;a href=&quot;https://www.videolan.org/&quot;&gt;官网&lt;/a&gt; &lt;a href=&quot;https://www.ghxi.com/pcvlc.html&quot;&gt;果核&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h1&gt;13 卸载工具&lt;/h1&gt;
&lt;blockquote&gt;
&lt;p&gt;推荐果核下载&lt;/p&gt;
&lt;/blockquote&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;名称&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;Revo Uninstaller Pro(卸载监控)&lt;/td&gt;
&lt;td&gt;🖥️&lt;/td&gt;
&lt;td&gt;完全删除程序，不留痕迹&lt;/td&gt;
&lt;td&gt;&lt;a href=&quot;https://www.revouninstaller.com/zh/&quot;&gt;官网&lt;/a&gt; &lt;a href=&quot;https://www.ghxi.com/revouninstaller.html&quot;&gt;果核&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Total Uninstall&lt;/td&gt;
&lt;td&gt;🖥️&lt;/td&gt;
&lt;td&gt;可以找出特定软件在系统中留下的每一处痕迹，进行完全的卸载&lt;/td&gt;
&lt;td&gt;&lt;a href=&quot;https://www.martau.com/zh-CN/&quot;&gt;官网&lt;/a&gt; &lt;a href=&quot;https://www.ghxi.com/totaluninstall.html&quot;&gt;果核&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;HiBitUninstaller&lt;/td&gt;
&lt;td&gt;🖥️&lt;/td&gt;
&lt;td&gt;简单易用界面友好的软件卸载完美解决方案，可快速完整地卸载 Windows 系统安装的应用程序&lt;/td&gt;
&lt;td&gt;&lt;a href=&quot;https://www.hibitsoft.ir/Uninstaller.html&quot;&gt;官网&lt;/a&gt; &lt;a href=&quot;https://www.ghxi.com/hibituninstaller.html&quot;&gt;果核&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Uninstall Tool&lt;/td&gt;
&lt;td&gt;🖥️&lt;/td&gt;
&lt;td&gt;小巧、安全、快速、强大的软件卸载删除工具，它支持在使用软件本身的卸载程序卸载完毕后，再扫描软件残留的注册及其它残余文件，将其彻底在系统删除&lt;/td&gt;
&lt;td&gt;&lt;a href=&quot;https://crystalidea.com/uninstall-tool&quot;&gt;官网&lt;/a&gt; &lt;a href=&quot;https://www.ghxi.com/uninstalltool.html&quot;&gt;果核&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Bulk Crap Uninstaller&lt;/td&gt;
&lt;td&gt;🖥️&lt;/td&gt;
&lt;td&gt;开源，快速删除大量不需要的应用程序。&lt;/td&gt;
&lt;td&gt;&lt;a href=&quot;https://github.com/Klocman/Bulk-Crap-Uninstaller/releases&quot;&gt;Github&lt;/a&gt; &lt;a href=&quot;https://www.bcuninstaller.com/&quot;&gt;官网&lt;/a&gt; &lt;a href=&quot;https://www.ghxi.com/bulkcrapuninstaller.html&quot;&gt;果核&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;uninstall_view（推荐）&lt;/td&gt;
&lt;td&gt;🖥️&lt;/td&gt;
&lt;td&gt;适用于 Windows 11/10/8/7/Vista 的替代卸载程序&lt;/td&gt;
&lt;td&gt;&lt;a href=&quot;https://www.nirsoft.net/utils/uninstall_view.html&quot;&gt;来源&lt;/a&gt; &lt;a href=&quot;https://www.123pan.com/s/E8jA-abFl.html&quot;&gt;123网盘下载&lt;/a&gt; 密码 VhIy&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h1&gt;14 录屏&lt;/h1&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;名称&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;Ev 录屏&lt;/td&gt;
&lt;td&gt;🖥️/🍏/🤖&lt;/td&gt;
&lt;td&gt;免费无水印，集视频录制与直播功能于一身的桌面录屏软件 分屏录制 场景编辑 教学画板&lt;/td&gt;
&lt;td&gt;&lt;a href=&quot;https://www.ieway.cn/evcapture.html&quot;&gt;官网&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;OBS Studio&lt;/td&gt;
&lt;td&gt;🖥️/🍏/🐧&lt;/td&gt;
&lt;td&gt;OBS Studio - 用于直播和屏幕录制的免费开源软件&lt;/td&gt;
&lt;td&gt;&lt;a href=&quot;https://obsproject.com/&quot;&gt;官网&lt;/a&gt; &lt;a href=&quot;https://github.com/obsproject/obs-studio&quot;&gt;Github&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;土豆录屏&lt;/td&gt;
&lt;td&gt;🖥️&lt;/td&gt;
&lt;td&gt;免费、无录制时长限制、无水印的录屏软件&lt;/td&gt;
&lt;td&gt;&lt;a href=&quot;http://tudouluping.com/&quot;&gt;官网&lt;/a&gt; &lt;a href=&quot;https://wwoy.lanzouc.com/iShwu16hk7uh&quot;&gt;蓝奏&lt;/a&gt; 密码 tudou&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h1&gt;15 桌面快速启动管理&lt;/h1&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;名称&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;GeekDesk(极客桌面)&lt;/td&gt;
&lt;td&gt;🖥️&lt;/td&gt;
&lt;td&gt;一款 C#构建的免费、小巧、美观、高度自定义的桌面快速启动管理工具，集成了 Everything 搜索功能，不仅能帮我们整理桌面，还能快速启动应用程序、管理文件夹。&lt;/td&gt;
&lt;td&gt;&lt;a href=&quot;https://github.com/BookerLiu/GeekDesk&quot;&gt;Github&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h1&gt;16 相关参考拓展&lt;/h1&gt;
&lt;p&gt;&lt;a href=&quot;https://www.wxy97.com/archives/20&quot;&gt;好用常用软件 - 王旭阳个人博客&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/witt-bit/pc-guide&quot;&gt;Windows 、Linux常用软件配置分享&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://blog.csdn.net/qq_25814297/article/details/119950578&quot;&gt;实用工具软件远古大神Nir Sofer，数百款短小精悍便携工具，从Win2000到Win10通吃&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://linux.do/t/topic/759356&quot;&gt;在windows上必装工具(分享)&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://mp.weixin.qq.com/mp/appmsgalbum?__biz=Mzk4ODQ3MzgzNw==&amp;amp;action=getalbum&amp;amp;album_id=3985102505721004036&quot;&gt;软件管家&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://shiyrj.top/&quot;&gt;石用软件-专注分享实用软件&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://www.macwk.com/&quot;&gt;MacWk - 精品mac软件下载&lt;/a&gt;&lt;/p&gt;
</content:encoded></item><item><title>瓦肯举手礼</title><link>https://www.futseyi.com/blog/vulcan-salute/</link><guid isPermaLink="true">https://www.futseyi.com/blog/vulcan-salute/</guid><description>瓦肯举手礼（Vulcan Salute），又称“火神答复敬礼”，最初出现在美国著名科幻作品《星际迷航》（Star Trek）中，是瓦肯人用于问候的标志性手势</description><pubDate>Wed, 18 Jun 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;img src=&quot;./assets/e3e5403b0a09aeeaba15949b44956a22.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h1&gt;瓦肯举手礼详解&lt;/h1&gt;
&lt;h2&gt;1 起源与背景&lt;/h2&gt;
&lt;p&gt;瓦肯举手礼（Vulcan Salute），又称“火神答复敬礼”，最初出现在美国著名科幻作品《星际迷航》（Star Trek）中，是瓦肯人用于问候的标志性手势 &lt;a href=&quot;https://zh.wikipedia.org/zh-hans/%E7%93%A6%E8%82%AF%E4%B8%BE%E6%89%8B%E7%A4%BC&quot;&gt;1&lt;/a&gt;&lt;a href=&quot;https://baike.baidu.com/item/%E7%93%A6%E8%82%AF%E4%B8%BE%E6%89%8B%E7%A4%BC/9025434&quot;&gt;2&lt;/a&gt;。该手势由斯波克（Spock）的扮演者伦纳德·尼莫伊（Leonard Nimoy）在拍摄过程中提出，灵感来自他童年时参加犹太教祈福仪式时见到的“kohane blessing”手势——该手势象征希伯来字母“ש”，寓意“上帝”&lt;a href=&quot;https://zh.wikipedia.org/zh-hans/%E7%93%A6%E8%82%AF%E4%B8%BE%E6%89%8B%E7%A4%BC&quot;&gt;1&lt;/a&gt;&lt;a href=&quot;https://baike.baidu.com/item/%E7%93%A6%E8%82%AF%E4%B8%BE%E6%89%8B%E7%A4%BC/9025434&quot;&gt;2&lt;/a&gt;&lt;a href=&quot;http://qnck.cyol.com/content/2010-04/27/content_3204214.htm&quot;&gt;3&lt;/a&gt;。&lt;/p&gt;
&lt;h2&gt;2 手势做法&lt;/h2&gt;
&lt;p&gt;瓦肯举手礼的具体做法如下：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;将中指与食指并拢&lt;/li&gt;
&lt;li&gt;将无名指与小指并拢&lt;/li&gt;
&lt;li&gt;尽可能张开大拇指，与其余手指分开&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;这一手势对手指的灵活性有一定要求，现实中并非每个人都能轻松做到 &lt;a href=&quot;https://baike.baidu.com/item/%E7%93%A6%E8%82%AF%E4%B8%BE%E6%89%8B%E7%A4%BC/9025434&quot;&gt;2&lt;/a&gt;&lt;a href=&quot;http://qnck.cyol.com/content/2010-04/27/content_3204214.htm&quot;&gt;3&lt;/a&gt;。&lt;/p&gt;
&lt;h2&gt;3 文化意义与流行&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;祝词&lt;/strong&gt;：瓦肯举手礼常伴随一句著名的祝词“Live long and prosper”，中文常译为“生生不息，繁荣昌盛”或“健康长寿，繁荣昌盛”&lt;a href=&quot;https://zh.wikipedia.org/zh-hans/%E7%93%A6%E8%82%AF%E4%B8%BE%E6%89%8B%E7%A4%BC&quot;&gt;1&lt;/a&gt;&lt;a href=&quot;https://baike.baidu.com/item/%E7%93%A6%E8%82%AF%E4%B8%BE%E6%89%8B%E7%A4%BC/9025434&quot;&gt;2&lt;/a&gt;&lt;a href=&quot;https://m.qidian.com/ask/qhvzfxaycwz&quot;&gt;4&lt;/a&gt;。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;象征意义&lt;/strong&gt;：最初仅为虚构外星文明的问候方式，如今已成为科幻迷、科技圈、网络文化中“来自另一星球”的象征符号 &lt;a href=&quot;https://baike.baidu.com/item/%E7%93%A6%E8%82%AF%E4%B8%BE%E6%89%8B%E7%A4%BC/9025434&quot;&gt;2&lt;/a&gt;&lt;a href=&quot;https://m.qidian.com/ask/qhvzfxaycwz&quot;&gt;4&lt;/a&gt;&lt;a href=&quot;http://qnck.cyol.com/content/2010-04/27/content_3204214.htm&quot;&gt;3&lt;/a&gt;。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Unicode 表情&lt;/strong&gt;：2014 年，瓦肯举手礼被纳入 Unicode 标准，成为🖖（U+1F596）表情符号 &lt;a href=&quot;https://zh.wikipedia.org/zh-hans/%E7%93%A6%E8%82%AF%E4%B8%BE%E6%89%8B%E7%A4%BC&quot;&gt;1&lt;/a&gt;。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;4 趣闻轶事&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;在《星际迷航》拍摄过程中，扮演柯克舰长的威廉·夏特纳因无法独立做出该手势，只能借助鱼线或胶水辅助 &lt;a href=&quot;https://baike.baidu.com/item/%E7%93%A6%E8%82%AF%E4%B8%BE%E6%89%8B%E7%A4%BC/9025434&quot;&gt;2&lt;/a&gt;&lt;a href=&quot;http://qnck.cyol.com/content/2010-04/27/content_3204214.htm&quot;&gt;3&lt;/a&gt;。&lt;/li&gt;
&lt;li&gt;该手势并非人人天生能做，许多演员和粉丝都曾尝试模仿，成为流行梗 &lt;a href=&quot;https://baike.baidu.com/item/%E7%93%A6%E8%82%AF%E4%B8%BE%E6%89%8B%E7%A4%BC/9025434&quot;&gt;2&lt;/a&gt;&lt;a href=&quot;http://qnck.cyol.com/content/2010-04/27/content_3204214.htm&quot;&gt;3&lt;/a&gt;。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;5 在流行文化中的影响&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;除了在《星际迷航》系列中频繁出现，瓦肯举手礼还被其他影视作品、网络表情和现实活动广泛使用，成为跨文化交流的趣味象征 &lt;a href=&quot;https://zh.wikipedia.org/zh-hans/%E7%93%A6%E8%82%AF%E4%B8%BE%E6%89%8B%E7%A4%BC&quot;&gt;1&lt;/a&gt;&lt;a href=&quot;https://baike.baidu.com/item/%E7%93%A6%E8%82%AF%E4%B8%BE%E6%89%8B%E7%A4%BC/9025434&quot;&gt;2&lt;/a&gt;&lt;a href=&quot;https://m.qidian.com/ask/qhvzfxaycwz&quot;&gt;4&lt;/a&gt;。&lt;/li&gt;
&lt;li&gt;该手势也常被用作和平、祝福和友好的象征，超越了原有的科幻语境 &lt;a href=&quot;https://zh.wikipedia.org/zh-hans/%E7%93%A6%E8%82%AF%E4%B8%BE%E6%89%8B%E7%A4%BC&quot;&gt;1&lt;/a&gt;&lt;a href=&quot;https://m.qidian.com/ask/qhvzfxaycwz&quot;&gt;4&lt;/a&gt;。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;6 总结&lt;/h2&gt;
&lt;p&gt;瓦肯举手礼不仅是《星际迷航》的标志性符号，更因其独特的文化内涵和象征意义，在全球范围内流行，成为科幻文化和网络社交中的经典手势 &lt;a href=&quot;https://zh.wikipedia.org/zh-hans/%E7%93%A6%E8%82%AF%E4%B8%BE%E6%89%8B%E7%A4%BC&quot;&gt;1&lt;/a&gt;&lt;a href=&quot;https://baike.baidu.com/item/%E7%93%A6%E8%82%AF%E4%B8%BE%E6%89%8B%E7%A4%BC/9025434&quot;&gt;2&lt;/a&gt;&lt;a href=&quot;https://m.qidian.com/ask/qhvzfxaycwz&quot;&gt;4&lt;/a&gt;。&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;&lt;strong&gt;参考文献&lt;/strong&gt;：&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://zh.wikipedia.org/zh-hans/%E7%93%A6%E8%82%AF%E4%B8%BE%E6%89%8B%E7%A4%BC&quot;&gt;1&lt;/a&gt; &lt;a href=&quot;https://zh.wikipedia.org/zh-hans/%E7%93%A6%E8%82%AF%E4%B8%BE%E6%89%8B%E7%A4%BC&quot;&gt;维基百科：瓦肯举手礼&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://baike.baidu.com/item/%E7%93%A6%E8%82%AF%E4%B8%BE%E6%89%8B%E7%A4%BC/9025434&quot;&gt;2&lt;/a&gt; &lt;a href=&quot;https://baike.baidu.com/item/%E7%93%A6%E8%82%AF%E4%B8%BE%E6%89%8B%E7%A4%BC/9025434&quot;&gt;百度百科：瓦肯举手礼&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://m.qidian.com/ask/qhvzfxaycwz&quot;&gt;4&lt;/a&gt; &lt;a href=&quot;https://m.qidian.com/ask/qhvzfxaycwz&quot;&gt;起点中文：瓦肯举手礼的功能&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://qnck.cyol.com/content/2010-04/27/content_3204214.htm&quot;&gt;3&lt;/a&gt; &lt;a href=&quot;http://qnck.cyol.com/content/2010-04/27/content_3204214.htm&quot;&gt;青年参考：五种流行手势背后的故事&lt;/a&gt;&lt;/p&gt;
</content:encoded></item><item><title>初识MCP技术</title><link>https://www.futseyi.com/blog/mcp-introduction/</link><guid isPermaLink="true">https://www.futseyi.com/blog/mcp-introduction/</guid><description>要用简单的例子理解MCP（Model Context Protocol）的工作原理和架构，可以将其类比为“AI的USB接口”：它让AI模型像插U盘一样，轻松、安全地访问和调用各种外部工具和数据源</description><pubDate>Mon, 16 Jun 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;img src=&quot;./assets/mcp.gif&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h1&gt;1 什么是 MCP 技术？&lt;/h1&gt;
&lt;p&gt;MCP，全称 Model Context Protocol（模型上下文协议），是一种开放标准协议，最早由 Anthropic 公司于 2024 年 11 月推出，旨在让大型语言模型（LLM）能够以标准化的方式无缝连接外部工具和数据源。&lt;/p&gt;
&lt;p&gt;可以把 MCP 理解为 AI 界的“USB-C 接口”或“HTTP 协议”：它统一了 AI 模型与外部世界（如数据库、API、文件系统等）交互的方式，让开发者和用户不需要为每种工具或数据源单独开发适配接口，而是“插上就能用”。&lt;/p&gt;
&lt;h1&gt;2 MCP 的核心作用&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;标准化接口&lt;/strong&gt;：让 AI 模型和各种外部资源之间的通信变得统一、简单。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;高效扩展&lt;/strong&gt;：开发者只需遵循 MCP 协议，就能让 AI 应用轻松接入新的工具或数据源，无需重复开发。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;多模态支持&lt;/strong&gt;：不仅支持文本，还能处理图片、音频等多种数据类型。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;上下文管理&lt;/strong&gt;：让 AI 模型能高效管理多轮对话和复杂的上下文信息。&lt;/li&gt;
&lt;/ul&gt;
&lt;h1&gt;3 MCP 的技术架构（0 基础易懂版）&lt;/h1&gt;
&lt;p&gt;MCP 采用典型的“客户端 - 服务器”架构，分为三个主要角色：&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&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;Host（主机）&lt;/td&gt;
&lt;td&gt;运行 AI 应用的地方，集成 MCP 客户端，负责与用户交互&lt;/td&gt;
&lt;td&gt;Claude Desktop、智能体 App、IDE 插件&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Client（客户端）&lt;/td&gt;
&lt;td&gt;嵌入在 Host 中的模块，负责和 MCP 服务器通信，是 AI 和外部世界的桥梁&lt;/td&gt;
&lt;td&gt;MCP Client 插件&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Server（服务器）&lt;/td&gt;
&lt;td&gt;提供具体的数据、工具和提示模板等资源，供 AI 模型远程调用&lt;/td&gt;
&lt;td&gt;数据库服务器、API 服务、文件服务器&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h1&gt;4 MCP 的工作流程&lt;/h1&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;初始化连接&lt;/strong&gt;：Host 中的 MCP Client 与 MCP Server 建立连接。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;请求资源/工具&lt;/strong&gt;：当 AI 模型需要外部数据或功能时，Client 向 Server 发出请求。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;执行操作&lt;/strong&gt;：Server 根据请求，执行相应操作（如查数据库、运行代码）。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;返回结果&lt;/strong&gt;：Server 将结果返回给 Client，Client 再传递给 AI 模型。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;AI 继续处理&lt;/strong&gt;：AI 模型用这些数据继续完成用户任务。&lt;/li&gt;
&lt;/ol&gt;
&lt;h1&gt;5 MCP 能做什么？&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;让 AI 自动查找和分析本地或远程文件&lt;/li&gt;
&lt;li&gt;让 AI 直接调用数据库、Web API、执行代码等&lt;/li&gt;
&lt;li&gt;让 AI 与各种外部系统（如 CRM、OA、邮件等）无缝集成&lt;/li&gt;
&lt;li&gt;支持开发自己的 AI Agent（智能体），并快速扩展其能力&lt;/li&gt;
&lt;/ul&gt;
&lt;h1&gt;6 为什么 MCP 重要？&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;极大降低开发难度&lt;/strong&gt;：以前每接一个新工具都要写很多集成代码，有了 MCP 只需遵循协议即可。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;让 AI 应用更强大&lt;/strong&gt;：AI 模型不再是“信息孤岛”，能实时访问和操作各种数据和工具。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;推动 AI Agent 爆发&lt;/strong&gt;：MCP 让智能体开发和扩展变得前所未有的简单。&lt;/li&gt;
&lt;/ul&gt;
&lt;h1&gt;7 MCP 架构简化理解&lt;/h1&gt;
&lt;p&gt;MCP 采用&lt;strong&gt;客户端 - 服务器（C/S）架构&lt;/strong&gt;，包含三个核心角色 ：&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&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;Host&lt;/td&gt;
&lt;td&gt;用户直接操作的 AI 应用（如 AI 助手）&lt;/td&gt;
&lt;td&gt;电脑主机&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Client&lt;/td&gt;
&lt;td&gt;在 Host 内，负责与 Server 通信&lt;/td&gt;
&lt;td&gt;USB 驱动程序&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Server&lt;/td&gt;
&lt;td&gt;提供具体功能（如查天气、查文件）&lt;/td&gt;
&lt;td&gt;U 盘/外设&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr /&gt;
&lt;h1&gt;8 工作原理：一步步举例&lt;/h1&gt;
&lt;h1&gt;9 &lt;strong&gt;场景举例：AI 助手查天气&lt;/strong&gt;&lt;/h1&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;用户提问&lt;/strong&gt;
你在 AI 助手（Host）里输入：“帮我查下明天北京的天气。”&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;客户端转发请求&lt;/strong&gt;
Host 中的 MCP Client 收到请求，发现需要用到“查天气”这个工具，于是向 MCP Server 发起调用请求 。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;服务器处理请求&lt;/strong&gt;
MCP Server 收到请求，调用天气 API 获取北京明天的天气数据&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;返回结果&lt;/strong&gt;
MCP Server 把查到的天气数据返回给 Client，Client 再传回 Host。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;AI 助手答复&lt;/strong&gt;
Host 把天气结果整理后，用自然语言回复你：“明天北京多云，最高温度 28℃。”&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;hr /&gt;
&lt;h1&gt;10 &lt;strong&gt;核心流程总结&lt;/strong&gt;&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;连接建立&lt;/strong&gt;：Host 通过 Client 连接 Server，发现有哪些工具可用。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;能力发现&lt;/strong&gt;：Client 向 Server 请求“你能做什么”，Server 返回工具清单（如查天气、查文件等）。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;工具调用&lt;/strong&gt;：AI 模型根据用户需求，通过 Client 调用 Server 上的相关工具 。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;结果整合&lt;/strong&gt;：Server 返回结果，Client 转交 Host，AI 模型用这些数据生成最终答复 。&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h1&gt;11 关键术语简明解释&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Tools（工具）&lt;/strong&gt;：AI 可以调用的具体功能（如查天气、发邮件）。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Resources（资源）&lt;/strong&gt;：AI 可以访问的数据内容（如本地文件、数据库）。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Prompts（提示）&lt;/strong&gt;：预设的任务模板或指令，帮助 AI 更好地理解和操作工具 。&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h1&gt;12 总结类比&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;过去，AI 和每个外部系统都要单独“造轮子”对接，开发量大、难维护。&lt;/li&gt;
&lt;li&gt;有了 MCP，AI 和工具都只需遵循 MCP 协议，就像所有设备都用 USB 接口，插上即用，极大简化了集成和扩展。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;一句话总结&lt;/strong&gt;：MCP 让 AI 像插 USB 一样，安全、标准地访问和调用各种外部工具和数据，实现“万物互联”的 AI 应用体验。&lt;/p&gt;
</content:encoded></item><item><title>Qwen2.5 - VL的vllm部署方案(图像分析)</title><link>https://www.futseyi.com/blog/qwen25-vl-vllm-deployment/</link><guid isPermaLink="true">https://www.futseyi.com/blog/qwen25-vl-vllm-deployment/</guid><description>在浪潮项目中的火灾相关识别</description><pubDate>Sun, 15 Jun 2025 00:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;环境搭建工作&lt;/h1&gt;
&lt;h2&gt;1 使用 Conda 创建环境&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;conda create -n qwen python=3.11 -y

conda activate qwen

sudo apt update &amp;amp;&amp;amp; sudo apt upgrade
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;2 模型下载&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;1.首先安装所需依赖&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;pre&gt;&lt;code&gt;pip install &quot;vllm&amp;gt;0.7.2&quot; &quot;transformers&amp;gt;=4.49.0&quot; accelerate qwen-vl-utils modelscope
&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;p&gt;注释
&lt;strong&gt;vllm&lt;/strong&gt; 用于高效推理大模型。
&lt;strong&gt;transformers 和 accelerate&lt;/strong&gt; 是 Hugging Face 生态的核心库。
&lt;strong&gt;qwen-vl-utils&lt;/strong&gt; 直接关联 Qwen 的视觉 - 语言模型。
&lt;strong&gt;modelscope&lt;/strong&gt; 用于下载或管理预训练模型。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;因为网络问题,可以走国内代理&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;pip install -i https://pypi.tuna.tsinghua.edu.cn/simple   &quot;vllm&amp;gt;0.7.2&quot; &quot;transformers&amp;gt;=4.49.0&quot; accelerate qwen-vl-utils modelscope
&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;2.这里我是用的是 Qwen2.5-VL-7B-Instruct-AWQ(量化过的模型)&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;我的电脑配置是 (4090,24g 显存,实测此模型基本占满显存)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;modelscope download --model Qwen/Qwen2.5-VL-7B-Instruct-AWQ --local_dir /home/kairos/qwen
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;注意 local_dir 后面换成自己的目录 (/home/kairos/qwen)&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;3.使用 vllm 框架启动模型服务&lt;/strong&gt;
可以通过 nividia-smi,查看是不是成功开启服务&lt;/p&gt;
&lt;/blockquote&gt;
&lt;pre&gt;&lt;code&gt;vllm serve /home/kairos/qwen --port 8001 --host 0.0.0.0 --dtype bfloat16 --limit-mm-per-prompt image=5,video=5 --max-model-len 8001
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;注意端口不要与你现有的冲突&lt;/p&gt;
&lt;h1&gt;模型正式测试与调用&lt;/h1&gt;
&lt;h2&gt;1 使用 OpenAI Python SDK 调用&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;1.可以使用本地 usb 摄像头配合 opencv 手动截图单独存放在 captures 文件夹下,供后续大模型调用分析&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;pre&gt;&lt;code&gt;#!/usr/bin/env python3
import cv2
import os
import time
from datetime import datetime

# 配置参数
CAMERA_DEVICE = 0       # /dev/video1
OUTPUT_FOLDER = &quot;captures&quot; # 保存截图的文件夹
AUTO_SAVE_SEC = 0      # 自动截图间隔（秒），0表示手动模式
PRESS_KEY = &apos;s&apos;            # 手动保存的按键

# 创建输出文件夹
os.makedirs(OUTPUT_FOLDER, exist_ok=True)

# 初始化摄像头
cap = cv2.VideoCapture(CAMERA_DEVICE)
if not cap.isOpened():
    print(&quot;无法打开摄像头！&quot;)
    exit()

print(f&quot;摄像头已启动，按 &apos;{PRESS_KEY}&apos; 保存截图，ESC键退出&quot;)

last_save = 0
while True:
    ret, frame = cap.read()
    if not ret:
        print(&quot;无法获取画面&quot;)
        break

    # 显示实时画面
    cv2.imshow(&apos;Camera&apos;, frame)
    
    # 自动保存逻辑
    if AUTO_SAVE_SEC &amp;gt; 0 and (time.time() - last_save) &amp;gt; AUTO_SAVE_SEC:
        timestamp = datetime.now().strftime(&quot;%Y%m%d_%H%M%S&quot;)
        filename = f&quot;{OUTPUT_FOLDER}/auto_{timestamp}.jpg&quot;
        cv2.imwrite(filename, frame)
        print(f&quot;自动保存: {filename}&quot;)
        last_save = time.time()
    
    # 按键处理
    key = cv2.waitKey(1) &amp;amp; 0xFF
    if key == 27:  # ESC键退出
        break
    elif chr(key) == PRESS_KEY:  # 手动保存
        timestamp = datetime.now().strftime(&quot;%Y%m%d_%H%M%S&quot;)
        filename = f&quot;{OUTPUT_FOLDER}/manual_{timestamp}.jpg&quot;
        cv2.imwrite(filename, frame)
        print(f&quot;手动保存: {filename}&quot;)

# 释放资源
cap.release()
cv2.destroyAllWindows()
&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;2.让大模型逐一读取 captures 内所有图像&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;pre&gt;&lt;code&gt;from openai import OpenAI
import base64
import os
import shutil
from pathlib import Path
import time
from watchdog.observers import Observer
from watchdog.events import FileSystemEventHandler
import logging
import cv2
import numpy as np
import json

# 设置日志
logging.basicConfig(level=logging.INFO, format=&apos;%(asctime)s - %(message)s&apos;)

# Set OpenAI&apos;s API key and API base to use vLLM&apos;s API server.
openai_api_key = &quot;EMPTY&quot;
openai_api_base = &quot;http://localhost:8001/v1&quot;
client = OpenAI(
    api_key=openai_api_key,
    base_url=openai_api_base,
)

# 确保目标文件夹存在
FIRE_IMAGES_DIR = &quot;/home/kairos/really_fire&quot;
os.makedirs(FIRE_IMAGES_DIR, exist_ok=True)

# 读取本地图片并转换为base64
def encode_image_to_base64(image_path):
    with open(image_path, &apos;rb&apos;) as image_file:
        return base64.b64encode(image_file.read()).decode(&apos;utf-8&apos;)

def draw_boxes(image_path, boxes, output_path):
    &quot;&quot;&quot;在图片上绘制边框&quot;&quot;&quot;
    img = cv2.imread(image_path)
    for box in boxes:
        x1, y1, x2, y2 = box
        # 绘制红色边框，线宽为2
        cv2.rectangle(img, (x1, y1), (x2, y2), (0, 0, 255), 2)
    cv2.imwrite(output_path, img)

# 处理图片的函数
def process_image(image_path):
    try:
        base64_image = encode_image_to_base64(image_path)
        chat_response = client.chat.completions.create(
            model=&quot;/home/kairos/qwen&quot;,
            messages=[
                {
                    &quot;role&quot;: &quot;system&quot;, 
                    &quot;content&quot;: &quot;&quot;&quot;你是一个专门检测火焰的图像识别助手。你的任务是：
1. 判断图片中是否存在火焰、火灾、烟雾等相关内容
2. 如果存在，请提供每个火焰/烟雾区域的坐标位置（使用像素坐标）
3. 按以下格式回复：
{
    &quot;has_fire&quot;: true/false,
    &quot;description&quot;: &quot;发现火焰/烟雾：[描述]&quot; 或 &quot;未发现火焰相关内容&quot;,
    &quot;boxes&quot;: [[x1,y1,x2,y2], ...] // 每个区域的左上角和右下角坐标
}&quot;&quot;&quot;
                },
                {
                    &quot;role&quot;: &quot;user&quot;,
                    &quot;content&quot;: [
                        {
                            &quot;type&quot;: &quot;image_url&quot;,
                            &quot;image_url&quot;: {
                                &quot;url&quot;: f&quot;data:image/jpeg;base64,{base64_image}&quot;
                            },
                        },
                        {&quot;type&quot;:&quot;text&quot;,&quot;text&quot;:&quot;请检测图片中的火焰、火灾或烟雾，并提供准确的位置坐标。&quot;},
                    ],
                },
            ],
        )
        
        response_text = chat_response.choices[0].message.content
        logging.info(f&quot;检测图片 {image_path}:&quot;)
        logging.info(f&quot;检测结果: {response_text}&quot;)
        
        try:
            # 解析JSON响应
            result = json.loads(response_text)
            
            if result.get(&quot;has_fire&quot;, False):
                # 获取原始文件名和扩展名
                original_filename = os.path.basename(image_path)
                name, ext = os.path.splitext(original_filename)
                timestamp = time.strftime(&quot;%Y%m%d_%H%M%S&quot;)
                
                # 生成新的文件名
                new_filename = f&quot;{timestamp}_{name}_marked{ext}&quot;
                target_path = os.path.join(FIRE_IMAGES_DIR, new_filename)
                
                # 在图片上绘制边框并保存
                if result.get(&quot;boxes&quot;):
                    draw_boxes(image_path, result[&quot;boxes&quot;], target_path)
                    logging.info(f&quot;已标记火焰/烟雾区域并保存至: {target_path}&quot;)
                else:
                    # 如果没有边框信息，直接复制原图
                    shutil.copy2(image_path, target_path)
                    logging.info(f&quot;发现火焰/烟雾，但无法确定具体位置，已保存原图至: {target_path}&quot;)
                
        except json.JSONDecodeError:
            logging.error(&quot;无法解析模型返回的JSON格式&quot;)
        except Exception as e:
            logging.error(f&quot;处理检测结果时出错: {str(e)}&quot;)
            
    except Exception as e:
        logging.error(f&quot;处理图片 {image_path} 时出错: {str(e)}&quot;)

# 文件监控处理类
class ImageHandler(FileSystemEventHandler):
    def on_created(self, event):
        if event.is_directory:
            return
        if event.src_path.lower().endswith((&apos;.jpg&apos;, &apos;.jpeg&apos;)):
            logging.info(f&quot;检测到新图片: {event.src_path}&quot;)
            process_image(event.src_path)

    def on_modified(self, event):
        if event.is_directory:
            return
        if event.src_path.lower().endswith((&apos;.jpg&apos;, &apos;.jpeg&apos;)):
            logging.info(f&quot;检测到图片修改: {event.src_path}&quot;)
            process_image(event.src_path)

def main():
    # 设置监控路径
    path = &quot;/home/kairos/captures&quot;
    
    # 处理已存在的图片
    logging.info(&quot;开始检测现有图片...&quot;)
    for file in Path(path).glob(&quot;*.jp*g&quot;):
        process_image(str(file))
    
    # 设置监控
    event_handler = ImageHandler()
    observer = Observer()
    observer.schedule(event_handler, path, recursive=False)
    observer.start()
    
    logging.info(f&quot;开始监控文件夹: {path}&quot;)
    try:
        while True:
            time.sleep(1)
    except KeyboardInterrupt:
        observer.stop()
        logging.info(&quot;停止监控&quot;)
    
    observer.join()

if __name__ == &quot;__main__&quot;:
    main()
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>部署大模型并用Chatbox连接到远程Ollama服务</title><link>https://www.futseyi.com/blog/chatbox-ollama/</link><guid isPermaLink="true">https://www.futseyi.com/blog/chatbox-ollama/</guid><description>Ollama本地部署大模型</description><pubDate>Wed, 11 Jun 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;img src=&quot;./assets/image.gif&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h1&gt;1 在服务器上安装 Ollama 框架&amp;amp;并使用 systemd 管理 Ollama&lt;/h1&gt;
&lt;p&gt;&lt;strong&gt;在这里因为网络原因,我推荐大家直接到 github 官网下载压缩包,移入服务器中解压使用&lt;/strong&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;在 windows 中打开标签,选择最新的版本代号,选择 ollama-linux-amd64.tgz(我的 ubuntu 系统版本是 x86_64)&lt;/li&gt;
&lt;/ol&gt;
&lt;blockquote&gt;
&lt;p&gt;若不清楚自己的 Linux 系统版本输入 &lt;code&gt;uname -a&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ol&gt;
&lt;li&gt;创建文件夹/home/kairos/fxy-ollama 文件夹并解压到此处&lt;/li&gt;
&lt;/ol&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;tar -xzvf ollama-linux-amd64.tgz -C /home/kairos/fxy-ollama&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ol&gt;
&lt;li&gt;接下来使用 systemd 管理 Ollama
&lt;strong&gt;systemd 是 Linux 系统的现代服务管理工具，相比 nohup 或 screen 等方式，它提供了更稳定、可靠的管理方式，适合生产环境（长期运行的服务）&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;/etc/systemd/system/ollama.service &amp;gt; /dev/null &amp;lt;&amp;lt;EOF [Unit] Description=Ollama Server After=network.target

[Service] User=kairos # 替换为你的用户名 ExecStart=/home/kairos/fxy-ollama/bin/ollama serve WorkingDirectory=/home/kairos Restart=always # 崩溃后自动重启 RestartSec=3 # 重启间隔（秒） Environment=&quot;OLLAMA_HOST=0.0.0.0&quot; # 允许远程访问（可选）
# 资源限制示例（可选） # MemoryLimit=4G # CPUQuota=80%

[Install] WantedBy=multi-user.target EOF ​​(2) 启动并启用服务​​

sudo systemctl daemon-reload # 重新加载配置 sudo systemctl start ollama # 立即启动 sudo systemctl enable ollama # 开机自启

常用命令​​ bash sudo systemctl status ollama # 查看状态 sudo journalctl -u ollama -f # 实时查看日志 sudo systemctl stop ollama # 停止服务 sudo systemctl restart ollama # 重启服务
&lt;/code&gt;&lt;/pre&gt;
&lt;h1&gt;2 使用 Chatbox 连接到远程 Ollama 服务&lt;/h1&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;h2&gt;Ollama 作为 systemd 服务运行，应使用==systemctl== 设置环境变量：&lt;/h2&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;blockquote&gt;
&lt;p&gt;输入 &lt;code&gt;systemctl edit ollama.service&lt;/code&gt; 编辑 systemd 服务配置。这将打开一个编辑器。
在 [Service] 部分下为每个环境变量添加 Environment：
[Service]
&lt;code&gt;Environment=&quot;OLLAMA_HOST=0.0.0.0&quot;&lt;/code&gt;
&lt;code&gt;Environment=&quot;OLLAMA_ORIGINS=*&quot;&lt;/code&gt; 保存并退出。
重新加载 systemd 并重启 Ollama：
&lt;code&gt;systemctl daemon-reload&lt;/code&gt;
&lt;code&gt;systemctl restart ollama&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;h2&gt;在防火墙中允许 Ollama 服务的端口（默认为 11434）&lt;/h2&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;sudo ufw allow 11434/tcp&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;h2&gt;在 Chatbox 中配置连接&lt;/h2&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;blockquote&gt;
&lt;p&gt;在服务器输入 &lt;code&gt;ip a&lt;/code&gt; ,获取 ip 地址例如 192.168.XX.XX
在 windows 终端输入 &lt;code&gt;curl http://192.168.XX.XX:11434/api/tags&lt;/code&gt;
若返回 Ollama 的模型列表则代表内网穿透成功
最后在 Chatbox 中选择 Ollama API 输入 API 域名 &lt;code&gt;http://192.168.XX.XX:11434&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;
</content:encoded></item><item><title>关于biome代码审查</title><link>https://www.futseyi.com/blog/biome-code-review/</link><guid isPermaLink="true">https://www.futseyi.com/blog/biome-code-review/</guid><description>Biome通过自动修复代码格式（如缩进、换行）并支持配置调整，解决Astro和Svelte文件的格式一致性问题。</description><pubDate>Sat, 07 Jun 2025 00:00:00 GMT</pubDate><content:encoded>&lt;blockquote&gt;
&lt;p&gt;[!NOTE]
Biome 检测到多个 &lt;code&gt;.astro&lt;/code&gt; 和 &lt;code&gt;.svelte&lt;/code&gt; 文件的格式问题，主要是 &lt;strong&gt;代码缩进和换行不一致&lt;/strong&gt;。Biome 会尝试自动修复这些问题，但你需要手动确认或调整配置。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h1&gt;1 &lt;strong&gt;解决方案&lt;/strong&gt;&lt;/h1&gt;
&lt;h2&gt;1.1 &lt;strong&gt;自动修复格式问题&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;运行以下命令，让 Biome 自动修复所有格式问题：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;biome format ./src --write
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这会直接修改文件，使其符合 Biome 的默认规则。&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;1.2 &lt;strong&gt;手动检查差异&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;如果自动修复后仍有问题，可以对比 Biome 的期望格式和当前文件的差异：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;biome check ./src
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Biome 会显示哪些行需要调整，例如：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;× Formatter would have printed the following content:
  1 │ - import·{·Icon·}·from·&quot;astro-icon/components&quot;;
  2 │ + import·{·Icon·}·from·&quot;astro-icon/components&quot;;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;-&lt;/code&gt; 表示当前代码，&lt;code&gt;+&lt;/code&gt; 表示 Biome 期望的格式。&lt;/p&gt;
&lt;h2&gt;1.3 &lt;strong&gt;调整 Biome 配置（可选）&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;如果默认规则不符合你的需求，可以在 &lt;code&gt;biome.json&lt;/code&gt; 中修改配置：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
  &quot;formatter&quot;: {
    &quot;indentStyle&quot;: &quot;space&quot;,  // 或 &quot;tab&quot;
    &quot;indentWidth&quot;: 2,       // 缩进宽度
    &quot;lineWidth&quot;: 80         // 每行最大字符数
  },
  &quot;linter&quot;: {
    &quot;rules&quot;: {
      &quot;recommended&quot;: true,
      &quot;correctness&quot;: {
        &quot;noUnusedVariables&quot;: &quot;off&quot;  // 关闭未使用变量的检查
      }
    }
  }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;然后重新运行检查：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;biome check ./src
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;1.4 &lt;strong&gt;忽略特定文件或规则&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;如果某些文件不需要格式化，可以在 &lt;code&gt;biome.json&lt;/code&gt; 中添加 &lt;code&gt;ignore&lt;/code&gt;：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
  &quot;files&quot;: {
    &quot;ignore&quot;: [
      &quot;src/components/LightDarkSwitch.svelte&quot;,
      &quot;src/utils/url-utils.ts&quot;
    ]
  }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;1.5 &lt;strong&gt;使用 &lt;code&gt;npx&lt;/code&gt; 临时运行&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;如果不想全局安装，可以用 &lt;code&gt;npx&lt;/code&gt; 直接运行：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;npx @biomejs/biome format --write ./src
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>配合Cloudflare和Piclist搭建一个属于你的免费图床</title><link>https://www.futseyi.com/blog/cloudflare-piclist-image-hosting/</link><guid isPermaLink="true">https://www.futseyi.com/blog/cloudflare-piclist-image-hosting/</guid><description>使用 Cloudflare 和 Piclist 搭建个人图床的简要步骤： 首先，准备 Cloudflare 账号、域名和 Piclist 软件。在 Cloudflare 中创建 R2 存储桶，配置访问链接。 接着，配置 S3 API，获取访问密钥 ID、机密访问密钥和终结点。在 Piclist 中安装 S3 插件，配置图床信息，包括密钥、桶名、文件路径等。注意，不要勾选 \&quot;ForcePathStyle\&quot; 和 \&quot;Bucket 前缀\&quot;。 最后，使用 Piclist 管理图片，包括上传、下载、预览等，并可选择 GitHub 备份配置文件。</description><pubDate>Mon, 12 May 2025 00:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;1 提前准备&lt;/h1&gt;
&lt;ol&gt;
&lt;li&gt;一个提前注册好的 Cloudflare 账号，并添加一个付费计划,不必担心扣费，可以选择 0 元免费计划&lt;/li&gt;
&lt;li&gt;一个提前注册好的域名，可以选便宜一些的,域名后缀无所谓，只是作为图片网址使用如果不想花一年十几块的域名费，也可以去网上找免费的域名使用&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/Kuingsmile/PicList&quot;&gt;Piclist软件&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;h1&gt;2 创建 Cloudflare R2 存储桶&lt;/h1&gt;
&lt;p&gt;&lt;strong&gt;R2 实际上是一个对象存储。Cloudflare 提供 10G 的免费存储和每月 1000 万次的免费访问&lt;/strong&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;进入 &lt;a href=&quot;https://dash.cloudflare.com/&quot;&gt;Cloudflare 仪表盘&lt;/a&gt;，进入 R2 页面，为你的存储桶起一个名字，然后单击创建&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;img src=&quot;./assets/202408281607397.png&quot; alt=&quot;202408281607397&quot; /&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;配置访问链接&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;不要忘记，我们要搭的毕竟是个图床，不是网盘，接下来，我们要让其中的文件能够方便地通过链接从公网直接访问，让它变成真正意义上的图床&lt;/li&gt;
&lt;li&gt;Cloudflare 提供自己的子域域名，只不过功能受限，速度受限&lt;/li&gt;
&lt;li&gt;所以建议自定义域访问 &lt;a&gt;域名的购买配置&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h1&gt;3 S3 API 配置&lt;/h1&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;接下来，我们看看如何通过调用 S3 API 进行上传下载，并通过 PicList 接入该 API 实现一站式、本地化的图床图片管理&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ol&gt;
&lt;li&gt;要使用 S3 API，要获取 访问秘钥 ID（对应 AccessKeyId）、机密访问秘钥（对应 SecretAccessKey），以及终结点 /endpoint（后面用到）&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;回到 R2 页面,点击 API- 管理 API 令牌,输入令牌名称,指定相关权限&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;./assets/pixpin-2025-05-29-21-41-06.png&quot; alt=&quot;PixPin_2025-05-29_21-41-06&quot; /&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;令牌创建成功后，下方即有 S3 API 需要的信息：&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;./assets/202408281710556.png&quot; alt=&quot;202408281710556&quot; /&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;[!NOTE]
根据 Cloudflare 的安全策略，令牌信息页面一旦关闭，便永远不再展现，如果忘记了相应的信息，只能重新生成新令牌，所以请将令牌信息记录于可信的位置，妥善保管。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h1&gt;4 Piclist 图床配置&lt;/h1&gt;
&lt;blockquote&gt;
&lt;p&gt;现在，事情来到了最后一步 —— 我们需要一个工具软件来接入我们配置好的 S3 API，方便我们从本地上传和管理图片，而不必每次都打开 cloudflare 面板，而 PicList 就是这方面的不二之选。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ol&gt;
&lt;li&gt;打开 &lt;a href=&quot;https://piclist.cn/&quot;&gt;PicList 官方网站&lt;/a&gt;，下载安装软件&lt;/li&gt;
&lt;li&gt;载安装软件，打开后，可以看到，其已经内置支持了不少图床,但是…… 好像就是没有我们用的 cloudflare R2？别急，移步左侧的 “插件” 选项,搜索 s3&lt;/li&gt;
&lt;li&gt;&lt;s&gt;插件有 s3 和 s3-lls,不知道是是不是 BUG,使用两者插件输出图片链接格式不同,对于 CF 图床生成的链接格式 (自定义域名 / 设定的文件路径 / 文件名),s3-lls 插件输出才符合&lt;/s&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;blockquote&gt;
&lt;p&gt;[!NOTE]
以上第 3 点的问题:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;不要勾选 ForcePathStyle&lt;/li&gt;
&lt;li&gt;不要勾选 Bucket 前缀
&lt;img src=&quot;./assets/20250618184603075.png&quot; alt=&quot;PixPin_2025-06-18_18-45-45.png&quot; /&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/blockquote&gt;
&lt;p&gt;各项配置说明如下：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;图床配置名：自定义。&lt;/li&gt;
&lt;li&gt;应用秘钥 ID：对应 AccessKeyId / 访问秘钥 ID。&lt;/li&gt;
&lt;li&gt;应用秘钥：对应 SecretAccessKey / 机密访问秘钥。&lt;/li&gt;
&lt;li&gt;桶名：对应你在 Cloudflare 上创建的桶名称。&lt;/li&gt;
&lt;li&gt;文件路径：定义桶内文件的上传存储路径,在这里我配置的是 content/{year}/{month}/{fileName}.{extName},这样其实很方便我后期管理。&lt;/li&gt;
&lt;li&gt;地区：可以 AUTO 也可以 APAC(亚太地区,可能对访问速度有帮助吧)&lt;/li&gt;
&lt;li&gt;自定义节点：对应 endpoint / 终结点。&lt;/li&gt;
&lt;li&gt;自定义域名：对应 Cloudflare 自定义域或公共 R2.dev 存储桶 URL。&lt;/li&gt;
&lt;/ul&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;下面详细说明 “文件路径” 选项&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;该设置支持几个有固定含义的 payload 选项（如下所列），这些选项用于规定文件的上传路径和命名规则，而我们需要做的，就是根据需要进行恰当组合。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;./assets/202408281844639.png&quot; alt=&quot;202408281844639&quot; /&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;根据上图所列，文件路径可以写成这样：&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;{year}/{month}/{fileName}.{extName}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这样一个文件路径代表什么意思呢？举例来说，我在 2024 年 8 月上传了一张名为 “xxx.jpg” 的图片，按照如上的路径设置，它将会存储在如下位置：“桶名称 / 2024/08/”，而它的文件名就是 “xxx.jpg”，即：原文件名 + 原拓展名。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;同理，我也可以换一种写法：&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;{year}/{month}/{fileName}/{md5}.{extName}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;同样一张图片，在这样的文件路径下，会被上传到 “桶名称 / 2024/08/xxx/” 中，而图片本身会被重命名成 “该图片对应的 md5 字符串.jpg” 的形式。&lt;/p&gt;
&lt;h1&gt;5 Piclist 的管理功能 (可以直接管理你的云端图床)&lt;/h1&gt;
&lt;blockquote&gt;
&lt;p&gt;云存储平台/云服务器和图床平台的管理是 PicList 新增的功能，在这里你可以：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;新建存储桶&lt;/li&gt;
&lt;li&gt;新建/重命名和删除文件夹&lt;/li&gt;
&lt;li&gt;重命名和批量删除文件&lt;/li&gt;
&lt;li&gt;快速批量复制文件公开链接&lt;/li&gt;
&lt;li&gt;批量获取私有文件的临时分享链接&lt;/li&gt;
&lt;li&gt;批量上传和下载各种格式的文件&lt;/li&gt;
&lt;li&gt;预览图片&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;ol&gt;
&lt;li&gt;上面我们用的是 Cloudflare 的 r2 对象存储,所以我们就在 Piclist 配置管理&lt;/li&gt;
&lt;li&gt;点击管理选择 S3 兼容云,进行与上面相似的配置填写&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;img src=&quot;./assets/pixpin-2025-05-29-22-32-59.png&quot; alt=&quot;PixPin_2025-05-29_22-32-59&quot; /&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;这样配置完成后，就可以直接在 Piclist 查看咱们云端的图床啦&lt;/li&gt;
&lt;/ol&gt;
&lt;h1&gt;6 关于配置的同步备份 (使用 Github 仓库备份)&lt;/h1&gt;
&lt;p&gt;&lt;img src=&quot;./assets/pixpin-2025-05-30-13-26-30.png&quot; alt=&quot;PixPin_2025-05-30_13-26-30&quot; /&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;这里我使用 Github 自建私有仓库 (Piclist_Backup ) 进行配置文件的保存&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h1&gt;7 相关参考链接&lt;/h1&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;a href=&quot;https://www.zbf1009.top/archives/28&quot;&gt;https://www.zbf1009.top/archives/28&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://tyxiaoming.xin/2025/01/12/%E6%90%AD%E5%BB%BA%E5%9B%BE%E5%BA%8A/&quot;&gt;https://tyxiaoming.xin/2025/01/12/搭建图床/&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
</content:encoded></item><item><title>代码如诗，文章如歌</title><link>https://www.futseyi.com/blog/code-as-poetry-article-as-song/</link><guid isPermaLink="true">https://www.futseyi.com/blog/code-as-poetry-article-as-song/</guid><description>我会写诗,却好像唱不好歌</description><pubDate>Sun, 24 Nov 2002 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;思来想去，敲下无数行字，却又一行行删除。&lt;/p&gt;
</content:encoded></item></channel></rss>