<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>开发工具 on KnightLi的博客</title>
        <link>https://knightli.com/categories/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/</link>
        <description>Recent content in 开发工具 on KnightLi的博客</description>
        <generator>Hugo -- gohugo.io</generator>
        <language>zh-cn</language>
        <lastBuildDate>Sat, 30 May 2026 14:43:56 +0800</lastBuildDate><atom:link href="https://knightli.com/categories/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/index.xml" rel="self" type="application/rss+xml" /><item>
        <title>Obsidian 和 Joplin 怎么选？Markdown 笔记工具对比指南</title>
        <link>https://knightli.com/2026/05/30/obsidian-vs-joplin-note-app-comparison/</link>
        <pubDate>Sat, 30 May 2026 14:43:56 +0800</pubDate>
        
        <guid>https://knightli.com/2026/05/30/obsidian-vs-joplin-note-app-comparison/</guid>
        <description>&lt;p&gt;Obsidian 和 Joplin 都是 Markdown 笔记工具，但适合的人群不太一样。&lt;/p&gt;
&lt;p&gt;简单说：Obsidian 更适合深度知识管理、双链卡片盒笔记和高度自定义的用户；Joplin 更适合注重数据隐私、需要全平台同步、偏向传统文件夹分类和网页剪藏的实用型用户。&lt;/p&gt;
&lt;p&gt;如果你想搭建“第二大脑”、写长期研究笔记、折腾插件和知识图谱，优先看 Obsidian。如果你想找一个更安全、更自由的 Evernote / 有道云笔记替代品，优先看 Joplin。&lt;/p&gt;
&lt;h2 id=&#34;核心差异对比&#34;&gt;核心差异对比
&lt;/h2&gt;&lt;table&gt;
  &lt;thead&gt;
      &lt;tr&gt;
          &lt;th&gt;对比维度&lt;/th&gt;
          &lt;th&gt;Obsidian&lt;/th&gt;
          &lt;th&gt;Joplin&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;完全开源，AGPL-3.0 license&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;数据存储&lt;/td&gt;
          &lt;td&gt;本地 &lt;code&gt;.md&lt;/code&gt; 纯文本文件&lt;/td&gt;
          &lt;td&gt;本地数据库管理，笔记内容使用 Markdown&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;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;官方同步&lt;/td&gt;
          &lt;td&gt;Obsidian Sync，付费&lt;/td&gt;
          &lt;td&gt;Joplin Cloud，付费&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;免费同步&lt;/td&gt;
          &lt;td&gt;需要第三方方案，例如 iCloud、Git、坚果云、Syncthing 等&lt;/td&gt;
          &lt;td&gt;内置支持 OneDrive、Dropbox、WebDAV、文件系统等同步目标&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;/tr&gt;
      &lt;tr&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;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id=&#34;数据管理与隐私&#34;&gt;数据管理与隐私
&lt;/h2&gt;&lt;p&gt;Obsidian 的特点是“文件即数据”。你的笔记就是一个个普通 &lt;code&gt;.md&lt;/code&gt; 文件，直接保存在本地文件夹中。即使将来不用 Obsidian，也可以用任意文本编辑器打开这些文件。&lt;/p&gt;
&lt;p&gt;这种方式的优势是直观、开放、便于备份，也适合用 Git 管理。缺点是同步、附件管理和多端一致性需要用户自己规划。&lt;/p&gt;
&lt;p&gt;Joplin 同样使用 Markdown 语法，但笔记由应用数据库管理。它的优势是功能更完整，笔记、附件、标签、同步状态都由应用统一处理。Joplin 还原生支持端到端加密（E2EE），配合第三方网盘同步时，云服务商也难以直接读取笔记内容。&lt;/p&gt;
&lt;p&gt;如果你更看重“我的笔记就是本地文件”，Obsidian 更顺手。如果你更看重“应用帮我管理同步、加密和附件”，Joplin 更省心。&lt;/p&gt;
&lt;h2 id=&#34;同步方案与成本&#34;&gt;同步方案与成本
&lt;/h2&gt;&lt;p&gt;Obsidian 的官方同步服务是 Obsidian Sync，体验好，但需要付费。如果想免费在手机、平板和电脑之间同步，就要自己配置第三方方案，例如 iCloud、Git、Syncthing、坚果云或其他 WebDAV 方案。这对熟悉文件同步的人问题不大，但对新手有门槛。&lt;/p&gt;
&lt;p&gt;Joplin 的同步更偏内置能力。它支持 Joplin Cloud，也支持 OneDrive、Dropbox、WebDAV、文件系统等同步目标。只要绑定账号或配置地址，就可以在多端之间同步笔记。&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;愿意为官方同步付费，想要省心体验&lt;/td&gt;
          &lt;td&gt;Obsidian Sync 或 Joplin Cloud 都可以&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;想免费使用第三方网盘同步&lt;/td&gt;
          &lt;td&gt;Joplin 更直接&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;熟悉 Git / Syncthing / iCloud，并愿意折腾&lt;/td&gt;
          &lt;td&gt;Obsidian 也很好用&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;希望同步时启用端到端加密&lt;/td&gt;
          &lt;td&gt;Joplin 更内置&lt;/td&gt;
      &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id=&#34;插件生态与自定义&#34;&gt;插件生态与自定义
&lt;/h2&gt;&lt;p&gt;Obsidian 的插件生态是它最强的部分之一。通过插件，它可以变成任务看板、闪卡工具、日历、思维导图、个人数据库，甚至接近一个本地知识系统。&lt;/p&gt;
&lt;p&gt;双向链接、反向链接、局部图谱和 Dataview 这类插件，能让零散笔记逐渐形成知识网络。对写书、研究、知识卡片、项目资料沉淀来说，这种能力非常有吸引力。&lt;/p&gt;
&lt;p&gt;Joplin 也支持插件、主题和一些链接能力，但生态丰富度和折腾空间不如 Obsidian。它的好处是更克制，不容易让用户把大量时间花在改界面、换主题和试插件上。&lt;/p&gt;
&lt;p&gt;如果你的目标是“深度定制知识管理系统”，Obsidian 更强。如果你的目标是“稳定记录、同步和搜索”，Joplin 已经够用。&lt;/p&gt;
&lt;h2 id=&#34;网页剪藏能力&#34;&gt;网页剪藏能力
&lt;/h2&gt;&lt;p&gt;网页剪藏是 Joplin 的强项。它提供官方 Web Clipper，可以从浏览器保存网页、简化文章内容、截取页面或保存链接。对于收集离线资料、保存技术文章和整理网页内容的人来说，这个功能很实用。&lt;/p&gt;
&lt;p&gt;Obsidian 原生网页剪藏能力相对弱，通常需要依赖第三方浏览器扩展或其他工作流。可用方案不少，但体验和稳定性取决于插件与网页结构，剪藏后也可能需要手动整理排版。&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;高频保存网页文章&lt;/td&gt;
          &lt;td&gt;Joplin&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;做离线资料库&lt;/td&gt;
          &lt;td&gt;Joplin&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;Obsidian&lt;/td&gt;
      &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id=&#34;组织方式差异&#34;&gt;组织方式差异
&lt;/h2&gt;&lt;p&gt;Obsidian 更像一个以本地文件夹为基础的知识网络。你可以用文件夹整理，也可以用标签、双链、反向链接和图谱组织知识。它适合非线性笔记和主题之间关系复杂的知识库。&lt;/p&gt;
&lt;p&gt;Joplin 更像传统笔记软件。它采用笔记本、子笔记本、笔记的层级结构，也支持标签。对习惯 Evernote、有道云笔记、OneNote 这类工具的人来说，Joplin 的组织方式更熟悉。&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;喜欢文件夹 + 双链 + 图谱&lt;/td&gt;
          &lt;td&gt;Obsidian&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;喜欢笔记本 + 子笔记本 + 标签&lt;/td&gt;
          &lt;td&gt;Joplin&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;做学术研究、写书、卡片盒&lt;/td&gt;
          &lt;td&gt;Obsidian&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;做资料收集、项目笔记、网页归档&lt;/td&gt;
          &lt;td&gt;Joplin&lt;/td&gt;
      &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id=&#34;你应该选哪个&#34;&gt;你应该选哪个
&lt;/h2&gt;&lt;p&gt;选择 Obsidian，如果：&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;你希望笔记直接作为本地 Markdown 文件存在。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;选择 Joplin，如果：&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;/ul&gt;
&lt;h2 id=&#34;简单结论&#34;&gt;简单结论
&lt;/h2&gt;&lt;p&gt;Obsidian 和 Joplin 不是谁绝对更好，而是设计目标不同。&lt;/p&gt;
&lt;p&gt;Obsidian 更像一个可高度定制的 Markdown 知识管理平台，适合愿意搭系统、做双链、玩插件的人。它的上限很高，但也容易让人陷入“搭建系统比写笔记更开心”的状态。&lt;/p&gt;
&lt;p&gt;Joplin 更像一个开源、可同步、可加密的传统笔记应用，适合想稳定记录、网页剪藏、多端同步和长期保存资料的人。它没有 Obsidian 那么强的双链生态，但更接近“装好就能认真记笔记”的工具。&lt;/p&gt;
&lt;p&gt;一句话：想搭第二大脑，选 Obsidian；想要开源版 Evernote，选 Joplin。&lt;/p&gt;
</description>
        </item>
        <item>
        <title>Joplin：离线优先、支持同步和加密的开源笔记应用</title>
        <link>https://knightli.com/2026/05/30/joplin-open-source-note-taking-app/</link>
        <pubDate>Sat, 30 May 2026 14:39:48 +0800</pubDate>
        
        <guid>https://knightli.com/2026/05/30/joplin-open-source-note-taking-app/</guid>
        <description>&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://github.com/laurent22/joplin&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Joplin&lt;/a&gt; 是一个开源笔记与待办应用，支持 Windows、macOS、Linux、Android 和 iOS。它的定位不是轻量便签，而是一个可以长期保存大量笔记、同步到多设备、并尽量让数据掌握在用户手里的知识管理工具。&lt;/p&gt;
&lt;p&gt;Joplin 的笔记使用 Markdown 格式，支持笔记本、标签、全文搜索、附件、待办事项、插件、主题和浏览器 Web Clipper。对于想从 Evernote 迁移出来，或者想用更开放格式管理个人资料的人来说，它是很常见的选择。&lt;/p&gt;
&lt;h2 id=&#34;joplin-解决什么问题&#34;&gt;Joplin 解决什么问题
&lt;/h2&gt;&lt;p&gt;很多笔记应用用起来方便，但数据容易被锁在某个账号、某个云服务或某种私有格式里。Joplin 的思路更偏开放：本地保留完整数据，笔记正文使用 Markdown，再通过用户选择的同步目标在多设备之间同步。&lt;/p&gt;
&lt;p&gt;它适合下面几类需求：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;想把笔记长期保存为 Markdown。&lt;/li&gt;
&lt;li&gt;想在电脑和手机之间同步笔记。&lt;/li&gt;
&lt;li&gt;想从 Evernote 导入旧笔记和附件。&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;h2 id=&#34;核心特性速查&#34;&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;开源&lt;/td&gt;
          &lt;td&gt;仓库公开，项目长期维护，许可证为 AGPL-3.0 license&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;跨平台&lt;/td&gt;
          &lt;td&gt;支持 Windows、macOS、Linux、Android、iOS&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;Markdown&lt;/td&gt;
          &lt;td&gt;笔记正文使用 Markdown，便于阅读、迁移和长期保存&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;支持多种同步目标，包括 Joplin Cloud、Nextcloud、Dropbox、OneDrive 等&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;端到端加密&lt;/td&gt;
          &lt;td&gt;同步时可以启用 E2EE，降低云端存储风险&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;导入&lt;/td&gt;
          &lt;td&gt;支持从 Evernote 导入，也支持普通 Markdown 文件导入&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;扩展&lt;/td&gt;
          &lt;td&gt;支持插件、主题和 Web Clipper&lt;/td&gt;
      &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id=&#34;离线优先是什么意思&#34;&gt;离线优先是什么意思
&lt;/h2&gt;&lt;p&gt;Joplin 官方 README 中强调它是 &amp;ldquo;offline first&amp;rdquo;。这意味着笔记不是只存在于云端，而是保存在本机或手机上。即使没有网络，也能打开、搜索和编辑已有笔记。&lt;/p&gt;
&lt;p&gt;这个设计对笔记工具很重要。网络不好、同步服务临时不可用、或者账号服务出现问题时，本地仍然有完整数据。同步只是让多设备保持一致，而不是把所有使用体验都绑定到云端。&lt;/p&gt;
&lt;h2 id=&#34;markdown-与导入能力&#34;&gt;Markdown 与导入能力
&lt;/h2&gt;&lt;p&gt;Joplin 的笔记使用 Markdown，这让它比完全私有格式更容易迁移和备份。用户可以直接导入普通 Markdown 文件，也可以从 Evernote 导入笔记。&lt;/p&gt;
&lt;p&gt;Evernote 导入时，Joplin 会尝试转换格式化内容，并保留资源文件，例如图片和附件，同时保留创建时间、更新时间、地理位置等元数据。对有多年 Evernote 资料的人来说，这一点比单纯复制文字更重要。&lt;/p&gt;
&lt;p&gt;不过，任何跨应用迁移都不应该盲信“一键完成”。复杂排版、表格、附件、内部链接和标签结构都建议先用少量样本测试，再迁移完整资料库。&lt;/p&gt;
&lt;h2 id=&#34;同步与加密&#34;&gt;同步与加密
&lt;/h2&gt;&lt;p&gt;Joplin 支持多种同步方式。常见选择包括：&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;Joplin Cloud&lt;/td&gt;
          &lt;td&gt;想省心使用官方服务&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;Nextcloud&lt;/td&gt;
          &lt;td&gt;已经有自建云或团队协作环境&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;Dropbox&lt;/td&gt;
          &lt;td&gt;习惯使用 Dropbox 的个人用户&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;OneDrive&lt;/td&gt;
          &lt;td&gt;使用 Microsoft 生态的用户&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;文件系统 / WebDAV 等&lt;/td&gt;
          &lt;td&gt;想自己控制同步位置的人&lt;/td&gt;
      &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;同步可以配合端到端加密使用。启用后，笔记内容在同步到云端前会先加密，云服务更多只是保存加密后的数据。这样可以降低第三方云盘或同步服务泄露内容的风险。&lt;/p&gt;
&lt;p&gt;加密也会带来管理成本。用户需要妥善保存密码和恢复信息，否则换设备或重装后可能无法解密旧笔记。&lt;/p&gt;
&lt;h2 id=&#34;web-clipper-与插件&#34;&gt;Web Clipper 与插件
&lt;/h2&gt;&lt;p&gt;Joplin 还提供浏览器 Web Clipper，用来从 Chrome、Firefox 等浏览器保存网页和截图。对做资料收集、网页剪藏和研究笔记的人来说，这是很实用的入口。&lt;/p&gt;
&lt;p&gt;插件和主题则让 Joplin 更接近一个可扩展平台，而不是固定功能的笔记软件。用户可以根据自己的工作流扩展编辑、展示、搜索、导入导出等能力。&lt;/p&gt;
&lt;h2 id=&#34;和-obsidian-的区别&#34;&gt;和 Obsidian 的区别
&lt;/h2&gt;&lt;p&gt;Joplin 和 Obsidian 都常被 Markdown 用户拿来比较，但两者侧重点不同。&lt;/p&gt;
&lt;table&gt;
  &lt;thead&gt;
      &lt;tr&gt;
          &lt;th&gt;维度&lt;/th&gt;
          &lt;th&gt;Joplin&lt;/th&gt;
          &lt;th&gt;Obsidian&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;本地 Markdown 知识库，强调双链、插件生态和图谱&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;数据组织&lt;/td&gt;
          &lt;td&gt;应用管理笔记本、标签、附件和数据库索引&lt;/td&gt;
          &lt;td&gt;直接围绕文件夹和 Markdown 文件工作&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;同步&lt;/td&gt;
          &lt;td&gt;内置多种同步目标和 E2EE&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;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;如果你想要一个“开源版 Evernote + Markdown + 同步加密”，Joplin 更贴近这个需求。如果你想围绕本地 Markdown 文件搭建高度定制的知识系统，Obsidian 可能更顺手。&lt;/p&gt;
&lt;h2 id=&#34;适合谁使用&#34;&gt;适合谁使用
&lt;/h2&gt;&lt;p&gt;Joplin 适合几类用户：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;想从 Evernote 迁移出来的人。&lt;/li&gt;
&lt;li&gt;想把笔记保存为 Markdown 的用户。&lt;/li&gt;
&lt;li&gt;需要 Windows、macOS、Linux、Android、iOS 多端同步的人。&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;它不一定适合只想要极简便签的人。Joplin 功能较完整，配置同步、加密、插件和导入时，也需要花一点时间理解。&lt;/p&gt;
&lt;h2 id=&#34;使用建议&#34;&gt;使用建议
&lt;/h2&gt;&lt;p&gt;如果你准备试用 Joplin，可以按这个顺序开始：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;先在桌面端创建一个测试笔记本。&lt;/li&gt;
&lt;li&gt;导入少量 Markdown 或 Evernote 样本。&lt;/li&gt;
&lt;li&gt;检查图片、附件、标签、创建时间和格式是否正常。&lt;/li&gt;
&lt;li&gt;再设置同步目标，例如 Joplin Cloud、Nextcloud、Dropbox 或 OneDrive。&lt;/li&gt;
&lt;li&gt;如果要开启端到端加密，先确认所有设备都能正常同步和解密。&lt;/li&gt;
&lt;li&gt;最后再迁移完整笔记库。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;这样做比直接把多年笔记一次性导入更稳，也方便在正式迁移前发现格式或同步问题。&lt;/p&gt;
&lt;h2 id=&#34;我的判断&#34;&gt;我的判断
&lt;/h2&gt;&lt;p&gt;Joplin 的优势在于把几个重要方向放在了一起：Markdown、开源、跨平台、离线优先、同步和端到端加密。它不只是一个写 Markdown 的编辑器，更像一个面向长期使用的个人笔记系统。&lt;/p&gt;
&lt;p&gt;如果你希望笔记数据尽量开放，又不想完全自己拼同步、加密和移动端应用，Joplin 是很值得试的选择。它尤其适合从 Evernote 迁移、重视隐私、多设备使用，并希望以后仍能把数据迁走的用户。&lt;/p&gt;
&lt;p&gt;项目链接：&lt;a class=&#34;link&#34; href=&#34;https://github.com/laurent22/joplin&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;laurent22/joplin&lt;/a&gt;&lt;br&gt;
官方文档：&lt;a class=&#34;link&#34; href=&#34;https://joplinapp.org/help/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Joplin documentation&lt;/a&gt;&lt;/p&gt;
</description>
        </item>
        <item>
        <title>Jimmy：把 Evernote、Notion、Google Keep 等笔记导出转换成 Markdown</title>
        <link>https://knightli.com/2026/05/30/jimmy-note-conversion-tool-markdown/</link>
        <pubDate>Sat, 30 May 2026 11:55:56 +0800</pubDate>
        
        <guid>https://knightli.com/2026/05/30/jimmy-note-conversion-tool-markdown/</guid>
        <description>&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://github.com/marph91/jimmy&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Jimmy&lt;/a&gt; 是一个笔记转换工具，目标是把不同笔记应用或文档格式里的内容转换成 Markdown。它适合想把笔记从封闭应用里迁出来、放进 Obsidian、Joplin，或者只想长期保存为纯文本的人。&lt;/p&gt;
&lt;p&gt;项目文档里的定位很直接：导出或备份原笔记应用的数据，运行 &lt;code&gt;jimmy&lt;/code&gt; 转换，再把结果导入 Joplin、Obsidian，或者直接用 VSCode 等文本编辑器查看。&lt;/p&gt;
&lt;h2 id=&#34;jimmy-解决什么问题&#34;&gt;Jimmy 解决什么问题
&lt;/h2&gt;&lt;p&gt;很多笔记应用都有自己的导出格式。换应用时，最麻烦的往往不是文字内容，而是图片、附件、标签、内部链接和 front matter 这些结构化信息。&lt;/p&gt;
&lt;p&gt;Jimmy 做的事情就是把这些导出数据尽量整理成更通用的 Markdown 目录：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;笔记正文转换为 Markdown。&lt;/li&gt;
&lt;li&gt;尽量保留图片、资源和附件。&lt;/li&gt;
&lt;li&gt;尽量保留标签、外部链接和笔记内部链接。&lt;/li&gt;
&lt;li&gt;输出 Markdown + front matter。&lt;/li&gt;
&lt;li&gt;结果可以导入 Joplin、Obsidian 等工具，也可以直接用文本编辑器查看。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;这类工具的意义在于降低迁移成本。笔记一旦变成 Markdown，就不再强绑定某个应用，后续备份、搜索、版本管理和 LLM 处理都会简单很多。&lt;/p&gt;
&lt;h2 id=&#34;支持的笔记应用很多&#34;&gt;支持的笔记应用很多
&lt;/h2&gt;&lt;p&gt;Jimmy 支持的来源覆盖面很广，包括 Anki、Anytype、Bear、CherryTree、ColorNote、Day One、Diaro、Drafts、Dynalist、Evernote、Google Docs、Google Keep、Joplin、Notion、Obsidian、OneNote、QOwnNotes、RedNotebook、Reflect、Roam Research、Signal、Simplenote、Standard Notes、Synology Note Station、Telegram、Tiddlywiki、Turtl、UpNote、Wordpress、Zim、Zoho Notebook 等。&lt;/p&gt;
&lt;p&gt;并不是所有来源的保真度都完全一样。实际迁移时，仍然要先用一小批笔记试跑，重点检查图片、附件、标签、内部链接和日期字段是否符合预期。&lt;/p&gt;
&lt;h2 id=&#34;也能转换普通文档&#34;&gt;也能转换普通文档
&lt;/h2&gt;&lt;p&gt;除了笔记应用导出，Jimmy 也能处理一些常见文档格式。文档中提到可以转换单个文件，也可以递归转换整个文件夹，适合把杂乱的资料目录整理成 Markdown。&lt;/p&gt;
&lt;p&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;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
      &lt;tr&gt;
          &lt;td&gt;办公文档&lt;/td&gt;
          &lt;td&gt;DOCX、ODT、RTF&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;标记语言&lt;/td&gt;
          &lt;td&gt;Asciidoc、DocBook、Markdown、MediaWiki、reStructuredText&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;网页与电子书&lt;/td&gt;
          &lt;td&gt;HTML、MHTML、EPUB&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;数据与结构化文件&lt;/td&gt;
          &lt;td&gt;CSV、OPML、Jupyter Notebook&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;其他&lt;/td&gt;
          &lt;td&gt;PDF、EML、Fountain、txt2tags&lt;/td&gt;
      &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;如果只是把 DOCX、PDF 或 HTML 批量转成 Markdown，Jimmy 也可以作为一个离线批处理工具来用。&lt;/p&gt;
&lt;h2 id=&#34;两种使用方式&#34;&gt;两种使用方式
&lt;/h2&gt;&lt;p&gt;Jimmy 提供 CLI 和 TUI 两种界面。&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;CLI&lt;/td&gt;
          &lt;td&gt;批处理、脚本、完整功能&lt;/td&gt;
          &lt;td&gt;适合一次性转换文件夹、写迁移脚本、指定来源格式&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;TUI&lt;/td&gt;
          &lt;td&gt;交互式转换&lt;/td&gt;
          &lt;td&gt;适合手动操作，目前功能子集仍处于 beta 状态&lt;/td&gt;
      &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;官方 README 给出的 Linux 示例命令如下：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# 使用交互式 TUI 转换&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;jimmy-linux tui
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# 转换一个 pandoc 支持的单文件&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;jimmy-linux cli libre_office_document.odt
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# 转换整个文件夹&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;jimmy-linux cli path/to/folder
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# 转换 Google Keep 导出&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;jimmy-linux cli takeout-20240401T160516Z-001.zip --format google_keep
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;这些命令说明它不是只面向某一个笔记应用，而是把“笔记导出包”和“普通文档目录”都纳入了同一套转换流程。&lt;/p&gt;
&lt;h2 id=&#34;它的几个特点&#34;&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;离线运行&lt;/td&gt;
          &lt;td&gt;转换过程不依赖云服务，适合处理私人笔记&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;开源&lt;/td&gt;
          &lt;td&gt;仓库采用 GPL-3.0 license&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;跨平台&lt;/td&gt;
          &lt;td&gt;官方提供 Linux、Windows、macOS 下载&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;独立二进制&lt;/td&gt;
          &lt;td&gt;不要求用户额外安装 Docker、Python 或 Node.js&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;不使用 AI&lt;/td&gt;
          &lt;td&gt;转换过程不调用 AI，结果更可控，也减少隐私顾虑&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;Markdown + front matter&lt;/td&gt;
          &lt;td&gt;方便导入笔记软件，也方便后续用 Git 管理&lt;/td&gt;
      &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;其中“离线”和“不使用 AI”很适合笔记迁移场景。笔记里经常有私人信息、工作资料和历史附件，把转换放在本地完成，会让风险边界更清楚。&lt;/p&gt;
&lt;h2 id=&#34;适合谁使用&#34;&gt;适合谁使用
&lt;/h2&gt;&lt;p&gt;Jimmy 适合几类人：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;想从 Evernote、Notion、OneNote、Google Keep 等工具迁移到 Markdown 的用户。&lt;/li&gt;
&lt;li&gt;想把笔记导入 Obsidian、Joplin 或其他纯文本工作流的人。&lt;/li&gt;
&lt;li&gt;想把长期资料保存为未来更容易读取格式的人。&lt;/li&gt;
&lt;li&gt;想把笔记或文档准备成 LLM 可处理文本的人。&lt;/li&gt;
&lt;li&gt;需要递归转换 DOCX、PDF、HTML、ODT 等文件夹资料的人。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;它不一定适合追求“一键完美迁移”的用户。不同笔记应用导出格式差异很大，复杂页面、数据库、嵌入内容和内部链接都可能需要人工复查。&lt;/p&gt;
&lt;h2 id=&#34;使用前的检查建议&#34;&gt;使用前的检查建议
&lt;/h2&gt;&lt;p&gt;真正迁移前，建议按这个顺序做：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;先从原笔记应用导出一小批样本。&lt;/li&gt;
&lt;li&gt;用 Jimmy 转换样本，而不是一上来转换全部笔记。&lt;/li&gt;
&lt;li&gt;检查 Markdown 正文、图片、附件、标签、创建时间、内部链接。&lt;/li&gt;
&lt;li&gt;确认目标应用，例如 Obsidian 或 Joplin，能正确识别目录结构和 front matter。&lt;/li&gt;
&lt;li&gt;再对完整导出包执行转换。&lt;/li&gt;
&lt;li&gt;保留原始导出包和转换结果，至少等确认无误后再清理。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;这个流程虽然慢一点，但能避免迁移后才发现附件丢失、链接断掉或标签结构不对。&lt;/p&gt;
&lt;h2 id=&#34;我的判断&#34;&gt;我的判断
&lt;/h2&gt;&lt;p&gt;Jimmy 的价值在于把笔记迁移从“依赖某个应用的导入器”变成“先转成通用 Markdown”。它支持的来源很多，输出也足够通用，适合把个人知识库从封闭格式里释放出来。&lt;/p&gt;
&lt;p&gt;如果你只是偶尔导出一两篇笔记，可能用不到它。但如果你有多年积累的笔记、附件和文档目录，想迁移到 Obsidian、Joplin 或 Git 管理的 Markdown 工作流，Jimmy 很值得试。它最适合做迁移中间层：先把数据变成可读、可备份、可批处理的文本，再决定放进哪个笔记系统。&lt;/p&gt;
&lt;p&gt;项目链接：&lt;a class=&#34;link&#34; href=&#34;https://github.com/marph91/jimmy&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;marph91/jimmy&lt;/a&gt;&lt;br&gt;
文档链接：&lt;a class=&#34;link&#34; href=&#34;https://marph91.github.io/jimmy/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Jimmy - Note Conversion Tool&lt;/a&gt;&lt;/p&gt;
</description>
        </item>
        <item>
        <title>Google Pay 与 Wallet 推出 Developer MCP Server：把支付集成接入 AI 助手</title>
        <link>https://knightli.com/2026/05/29/google-pay-wallet-developer-mcp-server/</link>
        <pubDate>Fri, 29 May 2026 15:24:18 +0800</pubDate>
        
        <guid>https://knightli.com/2026/05/29/google-pay-wallet-developer-mcp-server/</guid>
        <description>&lt;p&gt;Google Developers 发布了 Google Pay 与 Wallet Developer MCP Server。它面向正在集成 Google Pay API 和 Google Wallet API 的开发者，把官方文档、账号状态、集成校验和部分业务指标接入 MCP 兼容的 AI 开发工具。&lt;/p&gt;
&lt;p&gt;这类更新看起来不像模型发布那么热闹，但对开发者很实用。支付和钱包集成往往不是“会不会写代码”的问题，而是文档细节多、配置项多、审核要求多、错误反馈分散。MCP Server 的价值就在于让 AI 助手可以在更接近真实上下文的位置帮开发者排查问题。&lt;/p&gt;
&lt;h2 id=&#34;它解决什么问题&#34;&gt;它解决什么问题
&lt;/h2&gt;&lt;p&gt;开发者在接入 Google Pay 或 Google Wallet 时，通常要在多个地方来回切换：&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;/ul&gt;
&lt;p&gt;如果只把这些内容当成网页文档，AI 助手最多只能解释概念或生成示例。接入 MCP Server 后，助手可以通过工具访问更具体的信息，从而给出更贴近当前项目状态的建议。&lt;/p&gt;
&lt;h2 id=&#34;mcp-在这里为什么合适&#34;&gt;MCP 在这里为什么合适
&lt;/h2&gt;&lt;p&gt;MCP 的作用是给 AI 应用提供标准化工具接口。对 Google Pay 和 Wallet 这样的开发者产品来说，它非常适合处理“文档加状态加校验”的组合任务。&lt;/p&gt;
&lt;p&gt;例如，开发者可以让支持 MCP 的 AI 工具帮助回答：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;当前集成缺了哪些配置&lt;/li&gt;
&lt;li&gt;某个 Google Pay 请求为什么失败&lt;/li&gt;
&lt;li&gt;Wallet pass 定义里哪些字段可能不符合要求&lt;/li&gt;
&lt;li&gt;代码示例应该如何改成当前业务需要的形态&lt;/li&gt;
&lt;li&gt;集成上线前还需要检查哪些项目&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;这些问题如果只靠大模型记忆，风险很高；如果能结合官方工具和当前账号信息，回答就更可操作。&lt;/p&gt;
&lt;h2 id=&#34;对-ai-编程工作流的意义&#34;&gt;对 AI 编程工作流的意义
&lt;/h2&gt;&lt;p&gt;这次发布也说明一个趋势：AI 编程助手正在从“读代码”走向“读产品系统”。&lt;/p&gt;
&lt;p&gt;过去，开发者让 AI 帮忙集成支付能力，通常只能把文档片段、错误日志和代码贴进去。AI 可以解释，但不一定知道当前集成的真实状态。MCP Server 把这部分能力向前推进了一步，让 AI 助手有机会直接围绕产品集成环境工作。&lt;/p&gt;
&lt;p&gt;这对几类场景尤其有价值：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;新项目首次接入 Google Pay 或 Wallet。&lt;/li&gt;
&lt;li&gt;旧项目迁移到新的 API 或配置方式。&lt;/li&gt;
&lt;li&gt;上线前做集成检查。&lt;/li&gt;
&lt;li&gt;遇到错误码、审核问题或配置不一致时快速定位。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;对团队来说，收益不只是少查几页文档，而是减少“文档理解正确，但配置现场不一致”的摩擦。&lt;/p&gt;
&lt;h2 id=&#34;它不会替代开发者判断&#34;&gt;它不会替代开发者判断
&lt;/h2&gt;&lt;p&gt;支付和钱包相关集成有安全、合规和用户体验要求。MCP Server 可以帮助 AI 助手更快找到信息、检查状态、生成建议，但最终仍需要开发者确认代码、安全策略、商户配置和上线流程。&lt;/p&gt;
&lt;p&gt;尤其是支付链路，不能因为 AI 给出一个看似合理的建议就直接上线。更稳妥的方式是把 MCP 工具当成检查员和导航员：它能缩短定位时间，但不能替代审核、测试和业务责任。&lt;/p&gt;
&lt;h2 id=&#34;我的判断&#34;&gt;我的判断
&lt;/h2&gt;&lt;p&gt;Google Pay 与 Wallet Developer MCP Server 的意义不在于“又多了一个 MCP 示例”，而在于它把 MCP 放进了一个真实、复杂、强约束的开发者场景。&lt;/p&gt;
&lt;p&gt;如果 MCP 只连接文档，它的价值有限；如果它能连接账号状态、集成校验、指标和产品后台，AI 助手就能承担更多实际开发工作。Google 这次发布正好展示了这个方向。&lt;/p&gt;
&lt;p&gt;未来类似能力很可能会出现在更多云服务、广告平台、支付系统和企业 SaaS 里。开发者要适应的不是“AI 会写代码”，而是“AI 可以通过标准工具接口参与整个集成流程”。&lt;/p&gt;
&lt;p&gt;原文链接：&lt;a class=&#34;link&#34; href=&#34;https://developers.googleblog.com/supercharge-your-integration-workflow-with-the-google-pay-wallet-developer-mcp-server/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Supercharge your integration workflow with the Google Pay &amp;amp; Wallet Developer MCP Server&lt;/a&gt;&lt;/p&gt;
</description>
        </item>
        <item>
        <title>Remotion：用 React 以编程方式生成视频</title>
        <link>https://knightli.com/2026/05/27/remotion-react-programmatic-video-generation/</link>
        <pubDate>Wed, 27 May 2026 14:39:22 +0800</pubDate>
        
        <guid>https://knightli.com/2026/05/27/remotion-react-programmatic-video-generation/</guid>
        <description>&lt;p&gt;&lt;code&gt;remotion-dev/remotion&lt;/code&gt; 是一个用 React 以编程方式创建视频的框架。它把视频制作从传统时间轴工具里抽出来，变成可以用组件、状态、数据、API、CSS、Canvas、SVG、WebGL 和算法控制的前端工程问题。&lt;/p&gt;
&lt;p&gt;项目地址：&lt;a class=&#34;link&#34; href=&#34;https://github.com/remotion-dev/remotion&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;remotion-dev/remotion&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;这类工具很适合今天的 AI 编程工作流：如果一个 agent 能生成网页、图表和数据视图，它也可以继续生成视频脚本、动画组件和可渲染的短片。&lt;/p&gt;
&lt;h2 id=&#34;remotion-解决的是什么问题&#34;&gt;Remotion 解决的是什么问题
&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;li&gt;把图表、代码片段和讲解字幕组合成技术短片&lt;/li&gt;
&lt;li&gt;批量生成营销素材、社交媒体短视频或课程片段&lt;/li&gt;
&lt;li&gt;用 CI/CD 或后端服务按需渲染视频&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;如果用传统剪辑软件，这些任务很难完全自动化。Remotion 的做法是把视频当成 React 应用来写：每一帧都是组件和数据在某个时间点的结果。&lt;/p&gt;
&lt;h2 id=&#34;为什么是-react&#34;&gt;为什么是 React
&lt;/h2&gt;&lt;p&gt;Remotion README 里给出的理由很清楚：React 可以复用 Web 技术和组件化能力。&lt;/p&gt;
&lt;p&gt;它让你可以使用：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;CSS 做布局和动画&lt;/li&gt;
&lt;li&gt;SVG 做矢量图形&lt;/li&gt;
&lt;li&gt;Canvas 和 WebGL 做复杂绘制&lt;/li&gt;
&lt;li&gt;JavaScript / TypeScript 做变量、函数、API 调用、数学和算法&lt;/li&gt;
&lt;li&gt;React 组件做复用、组合和快速迭代&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;这意味着前端开发者不需要重新学习一套完全陌生的视频 DSL。很多已有的 UI、图表、设计系统和数据逻辑，都可以迁移到视频生成场景里。&lt;/p&gt;
&lt;h2 id=&#34;快速开始&#34;&gt;快速开始
&lt;/h2&gt;&lt;p&gt;如果已经安装 Node.js，README 给出的入口命令是：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;npx create-video@latest
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;创建项目后，你通常会编写 React 组件来描述画面，再让 Remotion 按帧渲染输出视频。&lt;/p&gt;
&lt;p&gt;更完整的文档可以看：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;文档：&lt;a class=&#34;link&#34; href=&#34;https://www.remotion.dev/docs&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;remotion.dev/docs&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;API Reference：&lt;a class=&#34;link&#34; href=&#34;https://www.remotion.dev/api&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;remotion.dev/api&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;它适合哪些场景&#34;&gt;它适合哪些场景
&lt;/h2&gt;&lt;p&gt;Remotion 最适合“视频内容由数据或代码驱动”的场景。&lt;/p&gt;
&lt;h3 id=&#34;个性化视频&#34;&gt;个性化视频
&lt;/h3&gt;&lt;p&gt;例如年度回顾、用户成就、订单总结、学习报告。每个用户的数据不同，但视觉结构相同。用 React 组件加数据驱动，会比手工剪辑更自然。&lt;/p&gt;
&lt;h3 id=&#34;技术演示视频&#34;&gt;技术演示视频
&lt;/h3&gt;&lt;p&gt;如果视频里包含代码、图表、产品界面、步骤动画和说明文字，Remotion 很适合把这些元素组织成可重复渲染的模板。&lt;/p&gt;
&lt;h3 id=&#34;数据视频和图表动画&#34;&gt;数据视频和图表动画
&lt;/h3&gt;&lt;p&gt;数据可视化本来就是前端强项。Remotion 让图表不仅可以出现在网页里，也可以按时间轴进入视频。&lt;/p&gt;
&lt;h3 id=&#34;ai-生成视频工作流&#34;&gt;AI 生成视频工作流
&lt;/h3&gt;&lt;p&gt;AI agent 可以先生成脚本和素材结构，再生成 Remotion 组件，最后渲染视频。这比让模型直接生成最终视频更可控，因为中间产物是代码，可以检查、修改、版本管理和复用。&lt;/p&gt;
&lt;h2 id=&#34;对-ai-编程工具的意义&#34;&gt;对 AI 编程工具的意义
&lt;/h2&gt;&lt;p&gt;Remotion 对 Codex、Claude Code、Cursor、Gemini CLI 这类 AI 编程工具特别有意思。&lt;/p&gt;
&lt;p&gt;原因是视频生成被拆成了开发任务：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;生成 React 组件。&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;/ol&gt;
&lt;p&gt;这套流程非常适合 agent：每一步都有文件、有代码、有预览、有明确反馈。相比“直接生成一个视频文件”，代码化视频更容易被审阅和迭代。&lt;/p&gt;
&lt;p&gt;如果再结合浏览器侧边栏、截图检查、自动化渲染和评论反馈，Remotion 可以成为 AI 工作流里的视频产物层。&lt;/p&gt;
&lt;h2 id=&#34;使用前要注意许可&#34;&gt;使用前要注意许可
&lt;/h2&gt;&lt;p&gt;Remotion README 特别提醒：Remotion 有特殊许可，在某些公司使用场景下需要获得 company license。&lt;/p&gt;
&lt;p&gt;所以不要只把它当成普通 MIT 小工具来用。个人项目、开源项目、商业项目、企业内部工具，许可要求可能不同。正式用于公司生产前，应该先阅读它的 LICENSE 页面和官方许可说明。&lt;/p&gt;
&lt;p&gt;这点很重要，尤其是把 Remotion 接进自动化内容生成、营销素材生成或企业内部视频流水线时。&lt;/p&gt;
&lt;h2 id=&#34;我的判断&#34;&gt;我的判断
&lt;/h2&gt;&lt;p&gt;Remotion 的价值不只是“用 React 做视频”，而是把视频变成可编程、可复用、可自动化的产物。&lt;/p&gt;
&lt;p&gt;对普通前端团队来说，它适合做数据驱动的视频模板。对 AI 工具来说，它更像一个稳定的输出目标：模型不需要一次性生成黑盒视频，而是生成可读、可改、可渲染的 React 代码。&lt;/p&gt;
&lt;p&gt;如果你的内容需要批量生成、个性化生成、根据数据更新，或者需要让 agent 反复调整视觉细节，Remotion 值得放进工具箱里。它不是传统剪辑软件的替代品，而是把视频生产接入软件工程流程的一种方式。&lt;/p&gt;
</description>
        </item>
        <item>
        <title>CLIProxyAPI Management Center：给 CLIProxyAPI 配一个可视化管理后台</title>
        <link>https://knightli.com/2026/05/24/cliproxyapi-management-center/</link>
        <pubDate>Sun, 24 May 2026 10:05:15 +0800</pubDate>
        
        <guid>https://knightli.com/2026/05/24/cliproxyapi-management-center/</guid>
        <description>&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://github.com/router-for-me/Cli-Proxy-API-Management-Center&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Cli-Proxy-API-Management-Center&lt;/a&gt; 可以理解成 CLIProxyAPI 的“驾驶舱”。&lt;/p&gt;
&lt;p&gt;前一篇提到的 &lt;a class=&#34;link&#34; href=&#34;https://github.com/router-for-me/CLIProxyAPI&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;CLIProxyAPI&lt;/a&gt; 负责把 Gemini CLI、Codex、Claude Code、OpenRouter 等能力代理成统一 API；而这个 Management Center 解决的是另一个问题：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;代理服务跑起来之后，配置、账号、OAuth、日志、配额和凭据，总不能全靠手改文件和翻终端吧？&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;所以它提供了一个 Web 管理界面，让你可以用浏览器管理 CLIProxyAPI 的配置与运行状态。&lt;/p&gt;
&lt;h2 id=&#34;它是什么&#34;&gt;它是什么
&lt;/h2&gt;&lt;p&gt;从项目说明看，Cli-Proxy-API-Management-Center 是 CLIProxyAPI 的独立管理前端，核心功能包括：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;可视化编辑 CLIProxyAPI 配置。&lt;/li&gt;
&lt;li&gt;上传和管理 &lt;code&gt;auth.json&lt;/code&gt; 一类认证文件。&lt;/li&gt;
&lt;li&gt;查看请求日志和模型响应日志。&lt;/li&gt;
&lt;li&gt;管理 OAuth 认证流程。&lt;/li&gt;
&lt;li&gt;检查 Gemini CLI 账号配额。&lt;/li&gt;
&lt;li&gt;提供账号、配置、日志等日常维护入口。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;另外，官方仓库也提示：新版 CLIProxyAPI 已经内置了这个管理界面，可以直接通过 &lt;code&gt;/management.html&lt;/code&gt; 访问；独立仓库仍然保留给需要单独部署或二次开发的人使用。&lt;/p&gt;
&lt;p&gt;这点很重要。也就是说，大多数普通用户未必需要额外部署这个仓库；先确认你的 CLIProxyAPI 版本是否已经自带管理页。&lt;/p&gt;
&lt;h2 id=&#34;它解决的不是调用模型而是管理模型入口&#34;&gt;它解决的不是“调用模型”，而是“管理模型入口”
&lt;/h2&gt;&lt;p&gt;CLIProxyAPI 的难点不只是能不能把请求转到模型。&lt;/p&gt;
&lt;p&gt;真正麻烦的是这些东西：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;多个 Gemini、OpenAI、Claude、Codex 账号如何放进池子里。&lt;/li&gt;
&lt;li&gt;哪个账号已经失效，哪个账号配额快用完。&lt;/li&gt;
&lt;li&gt;OAuth 登录态怎么导入、刷新和排查。&lt;/li&gt;
&lt;li&gt;配置文件怎么改才不会漏逗号、漏字段。&lt;/li&gt;
&lt;li&gt;请求到底打到了哪个 provider、哪个模型、哪个账号。&lt;/li&gt;
&lt;li&gt;失败请求是上游问题、协议问题，还是本地配置问题。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Management Center 的价值就在这里：它把“代理基础设施”的日常维护变成可视化操作。&lt;/p&gt;
&lt;p&gt;如果你只是本机跑一个账号、偶尔调几次 API，它不一定是刚需；但只要你开始做多账号、多模型、多客户端接入，一个后台界面就会明显省事。&lt;/p&gt;
&lt;h2 id=&#34;典型使用场景&#34;&gt;典型使用场景
&lt;/h2&gt;&lt;p&gt;第一，管理账号池。&lt;/p&gt;
&lt;p&gt;CLIProxyAPI 支持多账号轮询和负载均衡，但账号越多，越不适合靠手工翻配置文件维护。管理中心可以帮助你查看账号状态、导入凭据、排查异常账号。&lt;/p&gt;
&lt;p&gt;第二，排查请求失败。&lt;/p&gt;
&lt;p&gt;当客户端报错时，你需要知道请求有没有进代理、走了哪个 provider、返回了什么错误。日志界面比在终端里滚屏找错误舒服很多。&lt;/p&gt;
&lt;p&gt;第三，处理 OAuth。&lt;/p&gt;
&lt;p&gt;Codex、Claude Code、Gemini CLI 这类工具经常涉及 OAuth 登录态。管理中心提供 OAuth 相关操作入口，能减少重复命令行操作。&lt;/p&gt;
&lt;p&gt;第四，给团队内部使用。&lt;/p&gt;
&lt;p&gt;如果 CLIProxyAPI 变成团队共享网关，那管理者需要一个能快速查看配置和状态的界面。否则每次变更都要登录服务器改文件，效率很低，也容易误操作。&lt;/p&gt;
&lt;h2 id=&#34;和-cliproxyapi-的关系&#34;&gt;和 CLIProxyAPI 的关系
&lt;/h2&gt;&lt;p&gt;可以把两者分成前后两层：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;7
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;客户端 / IDE / 脚本
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        |
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        v
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;CLIProxyAPI：负责协议代理、账号池、模型路由
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        |
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        v
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Gemini CLI / Codex / Claude Code / OpenRouter / 上游模型
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;Management Center 不在这条推理请求链路的核心位置。它更像运维面板：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;7
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;浏览器
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  |
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  v
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Management Center：编辑配置、看日志、管账号、查配额
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  |
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  v
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;CLIProxyAPI 管理接口 / 配置 / 日志 / 凭据
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;所以不要把它理解成另一个模型代理。它是管理 CLIProxyAPI 的工具，不是替代 CLIProxyAPI 的工具。&lt;/p&gt;
&lt;h2 id=&#34;为什么新版内置后仍然值得单独看&#34;&gt;为什么新版内置后仍然值得单独看
&lt;/h2&gt;&lt;p&gt;既然 CLIProxyAPI 已经内置了 &lt;code&gt;/management.html&lt;/code&gt;，为什么还要关注这个独立仓库？&lt;/p&gt;
&lt;p&gt;主要有三个原因。&lt;/p&gt;
&lt;p&gt;第一，独立仓库能让你看清管理中心本身的功能边界。哪些是前端负责的，哪些必须由 CLIProxyAPI 后端提供接口，一眼更清楚。&lt;/p&gt;
&lt;p&gt;第二，如果你要二次开发，比如改 UI、加鉴权、接自己的监控系统，独立仓库更适合作为入口。&lt;/p&gt;
&lt;p&gt;第三，如果你的部署环境比较特殊，比如前后端分开部署、管理页走单独域名、静态资源由内网网关托管，独立版本更灵活。&lt;/p&gt;
&lt;p&gt;对普通个人用户来说，优先用 CLIProxyAPI 内置版就够了；对团队或深度定制用户，独立仓库更有意义。&lt;/p&gt;
&lt;h2 id=&#34;部署时最该注意什么&#34;&gt;部署时最该注意什么
&lt;/h2&gt;&lt;p&gt;管理后台接触的是敏感东西：账号、OAuth、API Key、日志、请求内容、上游配额。&lt;/p&gt;
&lt;p&gt;所以第一条原则是：不要把管理页面裸露到公网。&lt;/p&gt;
&lt;p&gt;比较稳的做法是：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;只允许本机访问，比如绑定 &lt;code&gt;127.0.0.1&lt;/code&gt;。&lt;/li&gt;
&lt;li&gt;如果必须远程访问，放到 VPN、Tailscale、内网跳板机或反向代理鉴权后面。&lt;/li&gt;
&lt;li&gt;给管理接口加认证，不要只靠“地址没人知道”。&lt;/li&gt;
&lt;li&gt;日志里尽量避免暴露完整 Key、Cookie、OAuth token 和用户原始请求。&lt;/li&gt;
&lt;li&gt;团队环境里要分清“调用 API 的人”和“能改配置的人”。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;很多代理工具真正出问题，不是模型调用失败，而是管理口、日志和凭据文件没保护好。&lt;/p&gt;
&lt;h2 id=&#34;它适合和哪些东西一起用&#34;&gt;它适合和哪些东西一起用
&lt;/h2&gt;&lt;p&gt;如果你只部署 CLIProxyAPI，一个管理中心已经能解决基础维护问题。&lt;/p&gt;
&lt;p&gt;如果你进一步关心统计和可观测性，还可以搭配 CLIProxyAPI 生态里的其他工具：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;CPA Usage Keeper：偏用量同步和 SQLite 存储。&lt;/li&gt;
&lt;li&gt;CLIProxyAPI Usage Dashboard：偏本地优先的用量、配额和图表展示。&lt;/li&gt;
&lt;li&gt;CPA-Manager：偏完整管理中心，关注请求监控、费用估算、账号巡检和异常账号清理建议。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;可以简单理解：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Management Center 管“配置和日常维护”。&lt;/li&gt;
&lt;li&gt;Usage Dashboard 管“看用量和配额”。&lt;/li&gt;
&lt;li&gt;CPA-Manager 管“更重的运营和巡检”。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;实际用哪个，要看你的部署规模。个人本机用不需要把全家桶都装上。&lt;/p&gt;
&lt;h2 id=&#34;使用建议&#34;&gt;使用建议
&lt;/h2&gt;&lt;p&gt;如果你刚开始折腾 CLIProxyAPI，可以按这个顺序来：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;先让 CLIProxyAPI 本体跑通，确认 API 能正常响应。&lt;/li&gt;
&lt;li&gt;打开内置的 &lt;code&gt;/management.html&lt;/code&gt;，看看配置和日志是否能正常读取。&lt;/li&gt;
&lt;li&gt;再导入一个账号或一个 provider，确认管理界面能反映状态变化。&lt;/li&gt;
&lt;li&gt;有公网访问需求时，先做认证和网络隔离，再考虑开放入口。&lt;/li&gt;
&lt;li&gt;等账号和请求量变多，再补用量统计和更完整的管理工具。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;不要一开始就把所有账号、所有 provider、所有管理组件一次性接上。越是代理和账号池类项目，越适合小步验证。&lt;/p&gt;
&lt;h2 id=&#34;总结&#34;&gt;总结
&lt;/h2&gt;&lt;p&gt;Cli-Proxy-API-Management-Center 的定位很清楚：它不是模型、不是聊天客户端，也不是新的 API 网关；它是 CLIProxyAPI 的可视化管理层。&lt;/p&gt;
&lt;p&gt;当 CLIProxyAPI 只是一个本机小工具时，你可以不用它；当 CLIProxyAPI 开始承载多账号、多模型、多客户端调用时，它就会变成很实用的“控制台”。&lt;/p&gt;
&lt;p&gt;真正要注意的是安全边界。管理后台能改配置、看日志、碰凭据，一旦暴露不当，风险比普通 API 调用口还高。把它放在可信网络里，用认证保护好，再去享受可视化管理带来的省心。&lt;/p&gt;
&lt;p&gt;参考资料：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://github.com/router-for-me/Cli-Proxy-API-Management-Center&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;router-for-me/Cli-Proxy-API-Management-Center GitHub 仓库&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://github.com/router-for-me/CLIProxyAPI&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;router-for-me/CLIProxyAPI GitHub 仓库&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://help.router-for.me/cn/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;CLIProxyAPI 官方文档&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
        </item>
        <item>
        <title>CLIProxyAPI：把 Codex、Claude Code、Gemini CLI 统一封装成 API</title>
        <link>https://knightli.com/2026/05/24/cliproxyapi-cli-to-api-gateway/</link>
        <pubDate>Sun, 24 May 2026 10:03:33 +0800</pubDate>
        
        <guid>https://knightli.com/2026/05/24/cliproxyapi-cli-to-api-gateway/</guid>
        <description>&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://github.com/router-for-me/CLIProxyAPI&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;CLIProxyAPI&lt;/a&gt; 是一个很有“民间工程味”的项目：它不是再造一个大模型，也不是单纯做 API 转发，而是把一堆原本偏交互式、偏 CLI、偏 OAuth 登录的 AI 工具，重新包成统一 API 服务。&lt;/p&gt;
&lt;p&gt;它支持的对象包括 Gemini CLI、OpenAI Codex、Claude Code、Amp CLI、AI Studio Build，以及上游 OpenAI 兼容服务。换句话说，它想解决的问题是：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;我手上有 CLI 工具、有订阅账号、有 OAuth 登录态，能不能像调用普通 API 一样，把这些能力接到自己的客户端、脚本、IDE 或内部服务里？&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;CLIProxyAPI 给出的答案是：可以，中间加一层代理，把不同来源的 CLI 能力转换成 OpenAI、Gemini、Claude、Codex 兼容接口。&lt;/p&gt;
&lt;h2 id=&#34;它真正解决的痛点&#34;&gt;它真正解决的痛点
&lt;/h2&gt;&lt;p&gt;很多 AI 编程工具的能力本来很强，但默认使用方式并不适合自动化。&lt;/p&gt;
&lt;p&gt;比如：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Gemini CLI 能登录账号使用，但你的程序更习惯调用 HTTP API。&lt;/li&gt;
&lt;li&gt;Claude Code 很适合交互式编码，但接入其他客户端时会遇到协议不一致。&lt;/li&gt;
&lt;li&gt;Codex CLI 支持 OAuth 登录和 Responses 风格能力，但不是所有上层工具都知道怎么和它说话。&lt;/li&gt;
&lt;li&gt;一个团队可能有多个账号，需要轮询、负载均衡、异常账号剔除和配额观察。&lt;/li&gt;
&lt;li&gt;你想让某些工具只认 OpenAI 格式，但后端实际可能是 Gemini、Claude 或 Codex。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;CLIProxyAPI 的定位，就是做这些工具和客户端之间的“协议适配层”。&lt;/p&gt;
&lt;p&gt;它把复杂的一侧藏在后面：OAuth、CLI 登录、多账号、不同协议、不同 provider。前面则暴露相对熟悉的接口，比如 OpenAI Chat Completions、OpenAI Responses、Gemini、Claude Messages、Codex 相关端点。&lt;/p&gt;
&lt;h2 id=&#34;能力概览&#34;&gt;能力概览
&lt;/h2&gt;&lt;p&gt;从官方 README 和文档看，CLIProxyAPI 目前的核心能力包括：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;为 CLI 模型提供 OpenAI、Gemini、Claude、Codex 兼容 API 端点。&lt;/li&gt;
&lt;li&gt;通过 OAuth 登录接入 OpenAI Codex 和 Claude Code。&lt;/li&gt;
&lt;li&gt;支持流式、非流式响应，以及部分场景下的 WebSocket。&lt;/li&gt;
&lt;li&gt;支持函数调用、工具调用和多模态输入。&lt;/li&gt;
&lt;li&gt;支持 Gemini、OpenAI、Claude 多账号轮询与负载均衡。&lt;/li&gt;
&lt;li&gt;支持 Gemini AI Studio API Key。&lt;/li&gt;
&lt;li&gt;支持 AI Studio Build、Gemini CLI、Claude Code、OpenAI Codex 的多账号池。&lt;/li&gt;
&lt;li&gt;可以通过配置接入 OpenAI 兼容上游，比如 OpenRouter。&lt;/li&gt;
&lt;li&gt;提供 Go SDK，方便把代理能力嵌入到自己的服务里。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;这类项目最有价值的地方，不是“多支持几个模型名”，而是把账号登录、协议转换和请求路由这些琐碎工作打包起来。&lt;/p&gt;
&lt;h2 id=&#34;它适合谁用&#34;&gt;它适合谁用
&lt;/h2&gt;&lt;p&gt;CLIProxyAPI 更适合下面几类人：&lt;/p&gt;
&lt;p&gt;第一类是重度 AI 编程用户。你已经在用 Codex、Claude Code、Gemini CLI，但想把它们接到 Cursor、Cline、RooCode、Amp、内部脚本或自建工作流里。&lt;/p&gt;
&lt;p&gt;第二类是有多账号池的人。比如你有多个 Gemini、OpenAI、Claude 登录态，不想手工切换，希望自动轮询、均衡使用、遇到异常账号时能快速排查。&lt;/p&gt;
&lt;p&gt;第三类是做团队内部网关的人。团队不希望每个客户端都分别适配 Gemini、Claude、Codex，而是想通过一个中间层统一暴露 API。&lt;/p&gt;
&lt;p&gt;第四类是喜欢折腾协议的人。你可能关心 Responses、Chat Completions、Claude Messages、Gemini v1beta 这些接口如何互相转换，也可能希望在同一套客户端里切换不同后端。&lt;/p&gt;
&lt;p&gt;如果只是个人偶尔问几句 AI，或者只用官方 App 聊天，那 CLIProxyAPI 的部署和维护成本就显得重了。&lt;/p&gt;
&lt;h2 id=&#34;和普通-api-中转有什么不同&#34;&gt;和普通 API 中转有什么不同
&lt;/h2&gt;&lt;p&gt;普通 API 中转服务一般是：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;客户端 -&amp;gt; 中转 API -&amp;gt; 上游模型 API
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;CLIProxyAPI 的链路更像：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;客户端 -&amp;gt; CLIProxyAPI -&amp;gt; CLI / OAuth 登录态 / 多账号池 -&amp;gt; 模型服务
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;区别在于，它处理的不只是 API Key 转发，还包括 CLI 工具、OAuth 账号、协议表面和模型别名。&lt;/p&gt;
&lt;p&gt;比如 Codex 和 Claude Code 这类工具，本身就不是传统意义上“拿一个 API Key 就能稳定调用”的模式。CLIProxyAPI 把这些登录态和调用逻辑包装起来，让外部客户端像调用 API 一样访问它们。&lt;/p&gt;
&lt;p&gt;这也是它吸引人的地方，同时也是它复杂的地方。&lt;/p&gt;
&lt;h2 id=&#34;使用时最容易误解的地方&#34;&gt;使用时最容易误解的地方
&lt;/h2&gt;&lt;p&gt;第一，不要以为统一 &lt;code&gt;/v1/...&lt;/code&gt; 就能解决所有协议差异。&lt;/p&gt;
&lt;p&gt;CLIProxyAPI 文档里专门提醒过：当你需要某一类后端的请求和响应形态时，优先使用 provider-specific 路径。例如 messages 风格用 &lt;code&gt;/api/provider/{provider}/v1/messages&lt;/code&gt;，Gemini 模型路径用 &lt;code&gt;/api/provider/{provider}/v1beta/models/...&lt;/code&gt;，chat-completions 风格用 &lt;code&gt;/api/provider/{provider}/v1/chat/completions&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;统一入口方便，但不同协议的语义并不会凭空消失。工具调用、流式返回、多模态输入、系统消息处理，都可能因为后端不同而有细节差异。&lt;/p&gt;
&lt;p&gt;第二，模型名不等于唯一后端。&lt;/p&gt;
&lt;p&gt;如果多个后端暴露了相同的客户端可见模型名，仅靠路径不一定能锁定真正执行推理的那个后端。要严格固定后端，最好使用唯一 alias、前缀，或者避免让多个后端暴露同名模型。&lt;/p&gt;
&lt;p&gt;第三，多账号轮询不是无限额度。&lt;/p&gt;
&lt;p&gt;轮询只能更均匀地使用账号池，不能绕过上游服务的真实限制。账号异常、配额耗尽、风控、OAuth 失效，都需要单独监控。&lt;/p&gt;
&lt;p&gt;第四，它不是免维护魔法盒。&lt;/p&gt;
&lt;p&gt;一旦你把它放进日常工作流，就要关心配置、日志、上游账号状态、版本升级、客户端兼容性和安全边界。&lt;/p&gt;
&lt;h2 id=&#34;管理和监控怎么办&#34;&gt;管理和监控怎么办
&lt;/h2&gt;&lt;p&gt;官方 README 提到，从 v6.10.0 开始，CLIProxyAPI 和 CPAMC 不再预置数据统计功能。如果需要使用量统计，可以配合独立项目：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;CPA Usage Keeper：同步 CLIProxyAPI 数据，存到 SQLite，并提供聚合 API 和仪表盘。&lt;/li&gt;
&lt;li&gt;CLIProxyAPI Usage Dashboard：本地优先的用量与配额看板，可展示账号、模型、时间窗口和 Codex 配额余量。&lt;/li&gt;
&lt;li&gt;CPA-Manager：更完整的管理中心，面向请求监控、费用估算、账号池巡检、异常账号定位和清理建议。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;这说明 CLIProxyAPI 的核心更偏“代理和协议层”，而不是一站式商业管理后台。如果是团队使用，最好一开始就把日志、监控和账号池管理考虑进去。&lt;/p&gt;
&lt;h2 id=&#34;一个比较合理的使用姿势&#34;&gt;一个比较合理的使用姿势
&lt;/h2&gt;&lt;p&gt;如果要试用，可以按这个顺序来：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;先用官方文档的 Quick Start 跑起来。&lt;/li&gt;
&lt;li&gt;只接一个 provider，比如 Gemini CLI 或 Codex，确认基本请求能通。&lt;/li&gt;
&lt;li&gt;再测试流式响应、工具调用、多模态输入这些高风险能力。&lt;/li&gt;
&lt;li&gt;确认客户端实际使用的是哪个 endpoint，不要混用协议路径。&lt;/li&gt;
&lt;li&gt;最后再加入多账号轮询、管理面板和用量统计。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;不要一上来就把 Gemini、Codex、Claude、OpenRouter、多账号和所有客户端全接进去。这样出错时很难判断是认证问题、协议问题、模型名问题，还是上游账号问题。&lt;/p&gt;
&lt;h2 id=&#34;安全边界也要想清楚&#34;&gt;安全边界也要想清楚
&lt;/h2&gt;&lt;p&gt;CLIProxyAPI 会接触到账号登录态、API Key、OAuth 相关凭据和请求内容。它如果只跑在自己机器上，风险相对可控；如果暴露到公网或团队内网，就必须认真处理认证、访问控制、日志脱敏和网络隔离。&lt;/p&gt;
&lt;p&gt;尤其是管理端点，最好只允许本机或可信内网访问。不要为了省事直接把管理接口裸露出去。&lt;/p&gt;
&lt;h2 id=&#34;总结&#34;&gt;总结
&lt;/h2&gt;&lt;p&gt;CLIProxyAPI 的价值在于，它把原本散落在多个 CLI、多个账号、多个协议里的 AI 能力，收拢成一个可编程的 API 层。&lt;/p&gt;
&lt;p&gt;它适合重度 AI 编程用户、多账号用户和团队内部网关场景；不太适合只想“开箱即用、完全无维护”的轻量用户。&lt;/p&gt;
&lt;p&gt;如果你正在折腾 Codex、Claude Code、Gemini CLI 这些工具，并且希望把它们接进自己的客户端或自动化工作流里，CLIProxyAPI 值得认真看一眼。但要把它当基础设施来用，而不是当一次性小工具来用。&lt;/p&gt;
&lt;p&gt;参考资料：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://github.com/router-for-me/CLIProxyAPI&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;router-for-me/CLIProxyAPI GitHub 仓库&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://github.com/router-for-me/CLIProxyAPI/blob/main/README_CN.md&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;CLIProxyAPI 中文 README&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://help.router-for.me/cn/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;CLIProxyAPI 官方文档&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
        </item>
        <item>
        <title>让 Codex 使用 DeepSeek 模型的两种方法：本地网关和 OpenRouter BYOK</title>
        <link>https://knightli.com/2026/05/24/codex-deepseek-config-ccx-openrouter-byok/</link>
        <pubDate>Sun, 24 May 2026 09:52:55 +0800</pubDate>
        
        <guid>https://knightli.com/2026/05/24/codex-deepseek-config-ccx-openrouter-byok/</guid>
        <description>&lt;p&gt;想让 Codex 使用 DeepSeek，第一反应通常是改 &lt;code&gt;~/.codex/config.toml&lt;/code&gt;：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-toml&#34; data-lang=&#34;toml&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nx&#34;&gt;model&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;deepseek-chat&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nx&#34;&gt;base_url&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;https://api.deepseek.com&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;这个思路在一些旧版本或普通 OpenAI SDK 场景里确实成立，但放到当前 Codex CLI 上，很容易撞到一个底层问题：Codex 的自定义模型供应商走的是 OpenAI Responses 协议，而 DeepSeek 官方接口主要提供 OpenAI 兼容的 Chat Completions 调用方式。&lt;/p&gt;
&lt;p&gt;我本机当前是 &lt;code&gt;codex-cli 0.111.0&lt;/code&gt;。&lt;code&gt;codex --help&lt;/code&gt; 里可以看到它支持 &lt;code&gt;--config&lt;/code&gt;、&lt;code&gt;--model&lt;/code&gt;、&lt;code&gt;--profile&lt;/code&gt; 这些配置入口；OpenAI 官方 Codex 配置参考也写得很明确：&lt;code&gt;model_providers.&amp;lt;id&amp;gt;.wire_api&lt;/code&gt; 目前只支持 &lt;code&gt;responses&lt;/code&gt;，省略时也默认是 &lt;code&gt;responses&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;DeepSeek 官方文档则给出的调用路径是 &lt;code&gt;https://api.deepseek.com/chat/completions&lt;/code&gt;，示例也是 &lt;code&gt;client.chat.completions.create(...)&lt;/code&gt;。所以问题不在于 DeepSeek 不能被 OpenAI SDK 调用，而在于 Codex 发出去的请求语义和 DeepSeek 原生接口能理解的语义不完全是一套东西。&lt;/p&gt;
&lt;p&gt;这就是为什么直接把 &lt;code&gt;base_url&lt;/code&gt; 改成 &lt;code&gt;https://api.deepseek.com&lt;/code&gt; 后，可能出现下面这些现象：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;请求路径不匹配，直接 404 或返回格式不对。&lt;/li&gt;
&lt;li&gt;多轮对话、工具调用、补丁生成时解析失败。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;tool_calls&lt;/code&gt; 顺序、消息结构、流式事件格式对不上。&lt;/li&gt;
&lt;li&gt;看起来模型能回一句话，但一到 Codex 真正干活就开始报错。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;更稳的办法，是在 Codex 和 DeepSeek 之间放一个“翻译层”。常见有两种路线。&lt;/p&gt;
&lt;h2 id=&#34;方法一用本地网关桥接-deepseek&#34;&gt;方法一：用本地网关桥接 DeepSeek
&lt;/h2&gt;&lt;p&gt;本地网关的作用不是简单转发，而是把 Codex 侧的 Responses 风格请求，转换成 DeepSeek 能处理的 Chat Completions 风格请求，再把 DeepSeek 的结果转换回 Codex 能吃的格式。&lt;/p&gt;
&lt;p&gt;如果你用的是 ccx 一类本地网关，配置思路大致是这样：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;7
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;8
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-toml&#34; data-lang=&#34;toml&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;profiles&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;deepseek-ccx&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nx&#34;&gt;model&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;deepseek-v4-flash&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nx&#34;&gt;model_provider&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;ccx-bridge&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;model_providers&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;ccx-bridge&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nx&#34;&gt;name&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;Local CCX Gateway&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nx&#34;&gt;base_url&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;http://localhost:3000/v1&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nx&#34;&gt;env_key&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;DEEPSEEK_API_KEY&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;然后在终端里设置 DeepSeek Key，再用这个 profile 启动：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nb&#34;&gt;export&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;DEEPSEEK_API_KEY&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;your-deepseek-key&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;codex --profile deepseek-ccx
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;PowerShell 里是：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-powershell&#34; data-lang=&#34;powershell&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;$env:DEEPSEEK_API_KEY&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;your-deepseek-key&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;codex&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;-profile&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;deepseek-ccx&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;这里有两个细节要注意。&lt;/p&gt;
&lt;p&gt;第一，&lt;code&gt;base_url&lt;/code&gt; 要指向网关暴露给 Codex 的地址，不是 DeepSeek 官方地址。网关背后再去调用 DeepSeek。&lt;/p&gt;
&lt;p&gt;第二，&lt;code&gt;env_key&lt;/code&gt; 写什么取决于网关怎么鉴权。有的网关直接读取 DeepSeek 官方 Key，有的网关会要求你给它一个本地代理 Key，再由网关自己的后台保存 DeepSeek Key。遇到这种情况，&lt;code&gt;env_key&lt;/code&gt; 就应该改成网关要求的环境变量名。&lt;/p&gt;
&lt;p&gt;这条路的优点是本地可控，延迟和成本也更容易算清楚。缺点是你必须确认网关真的支持 Codex 当前使用的 Responses 语义，而不是只做了普通 Chat Completions 代理。&lt;/p&gt;
&lt;h2 id=&#34;方法二用-openrouter-byok-做线上桥接&#34;&gt;方法二：用 OpenRouter BYOK 做线上桥接
&lt;/h2&gt;&lt;p&gt;如果不想在本地部署网关，可以考虑 OpenRouter 的 BYOK。BYOK 的意思是把你自己的上游供应商 Key 绑定到 OpenRouter，由 OpenRouter 负责路由和转发。&lt;/p&gt;
&lt;p&gt;这里最容易写错的是环境变量。Codex 访问的是 OpenRouter，所以 &lt;code&gt;env_key&lt;/code&gt; 通常应该是 &lt;code&gt;OPENROUTER_API_KEY&lt;/code&gt;，不是 &lt;code&gt;DEEPSEEK_API_KEY&lt;/code&gt;。DeepSeek Key 要在 OpenRouter 的 BYOK 或 provider key 设置里添加。&lt;/p&gt;
&lt;p&gt;配置示例：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;7
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;8
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-toml&#34; data-lang=&#34;toml&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;profiles&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;deepseek-openrouter&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nx&#34;&gt;model&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;deepseek/deepseek-chat&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nx&#34;&gt;model_provider&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;openrouter&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;model_providers&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;openrouter&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nx&#34;&gt;name&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;OpenRouter&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nx&#34;&gt;base_url&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;https://openrouter.ai/api/v1&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nx&#34;&gt;env_key&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;OPENROUTER_API_KEY&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;启动方式：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nb&#34;&gt;export&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;OPENROUTER_API_KEY&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;your-openrouter-key&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;codex --profile deepseek-openrouter
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;PowerShell：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-powershell&#34; data-lang=&#34;powershell&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;$env:OPENROUTER_API_KEY&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;your-openrouter-key&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;codex&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;-profile&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;deepseek-openrouter&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;然后在 OpenRouter 后台把 DeepSeek 的 provider key 加进去。OpenRouter 的 BYOK 文档说明，绑定的 provider key 会被加密保存，并用于路由到对应供应商。&lt;/p&gt;
&lt;p&gt;这条路的优点是省掉本地网关维护成本，配置起来更像普通第三方 API 代理。缺点是中间多了一层线上服务，排障时要同时看 Codex、OpenRouter、DeepSeek 三边的错误信息。&lt;/p&gt;
&lt;h2 id=&#34;要不要继续用-deepseek-chat-这个模型名&#34;&gt;要不要继续用 deepseek-chat 这个模型名？
&lt;/h2&gt;&lt;p&gt;DeepSeek 官方文档在 2026 年 5 月的说明里，推荐模型名已经出现 &lt;code&gt;deepseek-v4-flash&lt;/code&gt; 和 &lt;code&gt;deepseek-v4-pro&lt;/code&gt;，并提示 &lt;code&gt;deepseek-chat&lt;/code&gt;、&lt;code&gt;deepseek-reasoner&lt;/code&gt; 兼容别名会在 2026-07-24 之后废弃。&lt;/p&gt;
&lt;p&gt;所以新配置里更建议优先测试：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-toml&#34; data-lang=&#34;toml&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nx&#34;&gt;model&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;deepseek-v4-flash&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;如果走 OpenRouter，则要按 OpenRouter 的模型命名来写，例如：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-toml&#34; data-lang=&#34;toml&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nx&#34;&gt;model&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;deepseek/deepseek-chat&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;实际可用名称以你所用网关或 OpenRouter 模型页为准。模型名不对时，错误通常会表现为 &lt;code&gt;model not found&lt;/code&gt;、404，或者 provider 找不到对应 endpoint。&lt;/p&gt;
&lt;h2 id=&#34;直接改-deepseek-官方-base_url-为什么不推荐&#34;&gt;直接改 DeepSeek 官方 base_url 为什么不推荐
&lt;/h2&gt;&lt;p&gt;你当然可以试着写：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;7
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;8
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-toml&#34; data-lang=&#34;toml&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;profiles&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;deepseek-direct&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nx&#34;&gt;model&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;deepseek-v4-flash&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nx&#34;&gt;model_provider&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;deepseek&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;model_providers&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;deepseek&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nx&#34;&gt;name&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;DeepSeek&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nx&#34;&gt;base_url&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;https://api.deepseek.com&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nx&#34;&gt;env_key&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;DEEPSEEK_API_KEY&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;但这更像排错实验，不适合作为稳定方案。因为 Codex 会按 Responses 协议去和自定义 provider 说话，而 DeepSeek 官方示例走的是 &lt;code&gt;/chat/completions&lt;/code&gt;。如果 DeepSeek 或 Codex 未来补齐了兼容层，这种直连才可能变得简单；在此之前，桥接层更靠谱。&lt;/p&gt;
&lt;h2 id=&#34;改完配置后还是走-openai-怎么办&#34;&gt;改完配置后还是走 OpenAI 怎么办
&lt;/h2&gt;&lt;p&gt;先确认配置文件位置。全局配置应该在：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;~/.codex/config.toml
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;项目里的 &lt;code&gt;.codex/config.toml&lt;/code&gt; 不适合放 &lt;code&gt;model_provider&lt;/code&gt;、&lt;code&gt;model_providers&lt;/code&gt; 这类机器级 provider 配置。OpenAI 官方文档也提醒，项目级配置不会覆盖这些本地 provider 和认证相关字段。&lt;/p&gt;
&lt;p&gt;如果 Codex 仍然要求网页登录，或者看起来还在走默认 OpenAI 模型，可以先退出当前登录态：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;codex &lt;span class=&#34;nb&#34;&gt;logout&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;有些旧教程会写成交互界面里的 &lt;code&gt;/logout&lt;/code&gt;。在当前 CLI 里，更稳的是直接在终端执行 &lt;code&gt;codex logout&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;还可以用临时参数做一次快速验证：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;codex --profile deepseek-ccx
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;或者：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;codex -c &lt;span class=&#34;nv&#34;&gt;model_provider&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;ccx-bridge -c &lt;span class=&#34;nv&#34;&gt;model&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;deepseek-v4-flash
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;如果这样能生效，说明配置本身可读；如果不生效，优先检查 profile 名称、TOML 语法、环境变量是否只在当前 shell 里有效。&lt;/p&gt;
&lt;h2 id=&#34;排障清单&#34;&gt;排障清单
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;&lt;code&gt;401&lt;/code&gt;：Key 不对，或者 &lt;code&gt;env_key&lt;/code&gt; 指向了错误的环境变量。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;404&lt;/code&gt;：&lt;code&gt;base_url&lt;/code&gt; 或模型名不对，也可能是把 Responses 请求打到了只支持 Chat Completions 的地址。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;tool_calls&lt;/code&gt;、patch、流式解析报错：大概率是协议桥接不完整。&lt;/li&gt;
&lt;li&gt;仍然提示登录 OpenAI：执行 &lt;code&gt;codex logout&lt;/code&gt;，再确认是否用了正确 profile。&lt;/li&gt;
&lt;li&gt;PowerShell 设置环境变量后新开窗口失效：&lt;code&gt;$env:...&lt;/code&gt; 只对当前会话生效，需要长期保存就改用户环境变量。&lt;/li&gt;
&lt;li&gt;OpenRouter BYOK 没走自己的 DeepSeek Key：检查 OpenRouter 后台 provider key 是否绑定、是否允许当前 OpenRouter API Key 使用，以及是否开启了 fallback。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;结论&#34;&gt;结论
&lt;/h2&gt;&lt;p&gt;让 Codex 使用 DeepSeek，不是不能改 &lt;code&gt;config.toml&lt;/code&gt;，而是不能只改 &lt;code&gt;base_url&lt;/code&gt; 就指望一切自动兼容。&lt;/p&gt;
&lt;p&gt;当前更稳的两条路是：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;用本地网关做协议桥接，Codex 连本地网关，网关再连 DeepSeek。&lt;/li&gt;
&lt;li&gt;用 OpenRouter BYOK 做线上转发，Codex 连 OpenRouter，DeepSeek Key 绑定在 OpenRouter 后台。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;如果只是想快速试用，OpenRouter 路线更省事；如果你希望 Key、成本、日志都尽量掌握在自己手里，本地网关更适合长期折腾。&lt;/p&gt;
&lt;p&gt;参考资料：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://developers.openai.com/codex/config-reference/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;OpenAI Codex Configuration Reference&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://api-docs.deepseek.com/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;DeepSeek API Docs&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://openrouter.ai/docs/use-cases/byok/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;OpenRouter BYOK Documentation&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
        </item>
        <item>
        <title>CodeGraph 是什么？给 Claude Code、Codex 和 Cursor 加一个本地代码地图</title>
        <link>https://knightli.com/2026/05/23/codegraph-local-code-knowledge-graph-ai-coding-agent/</link>
        <pubDate>Sat, 23 May 2026 21:09:46 +0800</pubDate>
        
        <guid>https://knightli.com/2026/05/23/codegraph-local-code-knowledge-graph-ai-coding-agent/</guid>
        <description>&lt;p&gt;&lt;code&gt;CodeGraph&lt;/code&gt; 是一个给 AI 编程工具使用的本地代码知识图谱。它会提前给项目建立索引，把符号关系、调用图、代码结构、路由关系等信息整理成可查询的图，让 Claude Code、Codex CLI、Cursor、OpenCode、Hermes Agent 这类工具不用每次都靠 grep、glob、Read 和子代理到处翻文件。&lt;/p&gt;
&lt;p&gt;它解决的是一个很实际的问题：AI Agent 看大型代码库时，很多成本不是花在真正修改代码上，而是花在“找代码在哪里”。如果每次都重新搜索、读取、筛选，token、时间和工具调用都会被消耗掉。&lt;code&gt;CodeGraph&lt;/code&gt; 的思路是先把代码库变成一张本地地图，让 Agent 先问地图，再决定要不要读具体文件。&lt;/p&gt;
&lt;h2 id=&#34;它主要解决什么痛点&#34;&gt;它主要解决什么痛点
&lt;/h2&gt;&lt;p&gt;AI 编程工具在小项目里通常还好，文件少，搜索快，读一遍也不贵。但项目一大，常见问题就会出现：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Agent 为了理解一个模块，反复调用 grep、find、ls、Read。&lt;/li&gt;
&lt;li&gt;探索子代理读了很多无关文件，主任务上下文却没有变清楚。&lt;/li&gt;
&lt;li&gt;问一个架构问题时，token 大量花在定位文件上。&lt;/li&gt;
&lt;li&gt;改一个函数前，不知道谁在调用它、它又调用了谁。&lt;/li&gt;
&lt;li&gt;Web 项目里，URL 路由和实际处理函数之间的关系不够直观。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;code&gt;CodeGraph&lt;/code&gt; 试图把这些“先找路”的工作前置。项目索引建好后，Agent 可以直接查询相关符号、调用方、被调用方、影响范围和代码片段。&lt;/p&gt;
&lt;h2 id=&#34;安装方式&#34;&gt;安装方式
&lt;/h2&gt;&lt;p&gt;项目提供跨平台安装脚本，不要求用户自己准备 Node.js：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;curl -fsSL https://raw.githubusercontent.com/colbymchenry/codegraph/main/install.sh &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt; sh
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;Windows PowerShell 可以使用：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-powershell&#34; data-lang=&#34;powershell&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nb&#34;&gt;irm &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;https&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;//&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;raw&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;py&#34;&gt;githubusercontent&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;com&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;/&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;colbymchenry&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;/&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;codegraph&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;/&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;main&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;/&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;install&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;py&#34;&gt;ps1&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;iex
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;如果已经有 Node 环境，也可以直接用 npm：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;npx @colbymchenry/codegraph
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;或者全局安装：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;npm i -g @colbymchenry/codegraph
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;安装器会自动检测并配置已安装的 Agent，例如 Claude Code、Cursor、Codex CLI、opencode 和 Hermes Agent。它会写入对应的 MCP server 配置和指令文件，让这些工具知道什么时候调用 CodeGraph。&lt;/p&gt;
&lt;h2 id=&#34;初始化项目&#34;&gt;初始化项目
&lt;/h2&gt;&lt;p&gt;安装完成后，需要在目标项目里建立索引：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nb&#34;&gt;cd&lt;/span&gt; your-project
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;codegraph init -i
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;这个命令会生成项目级知识图谱索引。README 中提到，只要项目里存在 &lt;code&gt;.codegraph/&lt;/code&gt; 目录，Agent 就可以自动使用 CodeGraph 工具。&lt;/p&gt;
&lt;p&gt;如果不想继续使用，也可以卸载全局配置：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;codegraph uninstall
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;它会移除安装器写入的 MCP server 配置、指令和权限。项目中的 &lt;code&gt;.codegraph/&lt;/code&gt; 索引不会被自动删除，如果要移除项目索引，需要使用 &lt;code&gt;codegraph uninit&lt;/code&gt;。&lt;/p&gt;
&lt;h2 id=&#34;为什么它对-agent-有用&#34;&gt;为什么它对 Agent 有用
&lt;/h2&gt;&lt;p&gt;Claude Code、Codex CLI、Cursor 这类工具在理解代码库时，常常会先做探索：找文件、读入口、查引用、再追调用链。这个过程对人来说像“翻项目”，对模型来说就是一串工具调用和上下文消耗。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;CodeGraph&lt;/code&gt; 把这一步变成索引查询。Agent 可以先用 &lt;code&gt;codegraph_context&lt;/code&gt; 找到相关入口、符号和片段，再用 &lt;code&gt;codegraph_explore&lt;/code&gt; 或其他工具读取必要内容。这样做的好处是：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;少读无关文件。&lt;/li&gt;
&lt;li&gt;少调用搜索工具。&lt;/li&gt;
&lt;li&gt;更快找到真正相关的代码。&lt;/li&gt;
&lt;li&gt;改动前更容易看清影响范围。&lt;/li&gt;
&lt;li&gt;大型仓库里的架构问题更容易回答。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;项目 README 给出的基准测试显示，在 7 个真实开源代码库上，对比启用 CodeGraph 和不启用 CodeGraph，平均结果是成本更低、token 更少、速度更快、工具调用更少。具体数字会受项目规模、语言、问题类型和 Agent 使用方式影响，但方向很清楚：越大的仓库，预索引的价值越明显。&lt;/p&gt;
&lt;h2 id=&#34;核心能力&#34;&gt;核心能力
&lt;/h2&gt;&lt;h3 id=&#34;1-智能上下文构建&#34;&gt;1. 智能上下文构建
&lt;/h3&gt;&lt;p&gt;一个工具调用可以返回入口点、相关符号和代码片段，减少 Agent 先派一堆探索任务再慢慢筛选的情况。对架构理解、模块定位、功能入口分析很有用。&lt;/p&gt;
&lt;h3 id=&#34;2-全文搜索&#34;&gt;2. 全文搜索
&lt;/h3&gt;&lt;p&gt;CodeGraph 使用 FTS5 做全文搜索，可以在整个代码库里快速按名称和文本查找代码。这不是替代所有 grep 场景，而是让 Agent 有一个更结构化的第一站。&lt;/p&gt;
&lt;h3 id=&#34;3-影响分析&#34;&gt;3. 影响分析
&lt;/h3&gt;&lt;p&gt;在改函数、类、方法或路由前，可以查询 callers、callees 和影响半径。对重构、修 bug、删除旧代码尤其有用，因为最怕的就是只改了当前文件，却漏掉上游或下游调用。&lt;/p&gt;
&lt;h3 id=&#34;4-自动保持新鲜&#34;&gt;4. 自动保持新鲜
&lt;/h3&gt;&lt;p&gt;README 中提到，CodeGraph 使用原生文件系统事件，例如 FSEvents、inotify、ReadDirectoryChangesW，并带有 debounce auto-sync。意思是索引会随着本地代码变化自动更新，不需要每改一个文件都手动重建。&lt;/p&gt;
&lt;h3 id=&#34;5-多语言支持&#34;&gt;5. 多语言支持
&lt;/h3&gt;&lt;p&gt;项目列出的支持范围超过 19 种语言，包括 TypeScript、JavaScript、Python、Go、Rust、Java、C#、PHP、Ruby、C、C++、Swift、Kotlin、Dart、Lua、Luau、Svelte、Liquid、Pascal / Delphi 等。&lt;/p&gt;
&lt;p&gt;这让它更适合多语言仓库和全栈项目，而不是只服务某一种语言。&lt;/p&gt;
&lt;h3 id=&#34;6-web-路由感知&#34;&gt;6. Web 路由感知
&lt;/h3&gt;&lt;p&gt;CodeGraph 还会识别多种 Web 框架里的路由文件和路由声明，把 URL pattern 和处理函数连接起来。README 中提到的框架包括 Django、Flask、FastAPI、Express、NestJS、Laravel、Rails、Spring、Gin、Axum、ASP.NET、Vapor、React Router、SvelteKit 等。&lt;/p&gt;
&lt;p&gt;这点很实用。很多 Web 项目的真实入口不是某个明显的 &lt;code&gt;main&lt;/code&gt; 函数，而是路由、controller、handler、view 或 resolver。Agent 如果能先知道 URL 到处理函数的关系，理解业务流程会快很多。&lt;/p&gt;
&lt;h2 id=&#34;本地优先的设计&#34;&gt;本地优先的设计
&lt;/h2&gt;&lt;p&gt;CodeGraph 强调 &lt;code&gt;100% local&lt;/code&gt;。它不需要 API key，不依赖外部服务，索引数据保存在本地 SQLite 数据库里。&lt;/p&gt;
&lt;p&gt;对企业项目、私有仓库或敏感代码来说，这个设计很重要。AI 工具接入代码库时，大家最担心的往往不是“能不能查到代码”，而是“代码结构和索引会不会被发出去”。CodeGraph 的定位是本地构建、本地查询、本地服务 Agent。&lt;/p&gt;
&lt;p&gt;当然，本地也意味着要考虑磁盘空间、索引时间、文件监听和项目规模。如果仓库特别大，第一次初始化和后续同步仍然需要资源。&lt;/p&gt;
&lt;h2 id=&#34;适合哪些场景&#34;&gt;适合哪些场景
&lt;/h2&gt;&lt;p&gt;CodeGraph 更适合这些场景：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;大型代码库，经常需要问架构和调用链问题。&lt;/li&gt;
&lt;li&gt;使用 Claude Code、Codex CLI、Cursor 等 Agent 做代码理解和修改。&lt;/li&gt;
&lt;li&gt;希望减少 Agent 到处读文件、乱搜、反复探索。&lt;/li&gt;
&lt;li&gt;需要在改动前分析影响范围。&lt;/li&gt;
&lt;li&gt;Web 项目路由复杂，需要快速从 URL 找到处理函数。&lt;/li&gt;
&lt;li&gt;团队希望给 AI Agent 一个更稳定的本地项目索引。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;如果只是几十个文件的小项目，普通搜索已经够快，CodeGraph 的优势可能不明显。它最有价值的地方，是中大型代码库和经常让 Agent 做探索的场景。&lt;/p&gt;
&lt;h2 id=&#34;使用时要注意什么&#34;&gt;使用时要注意什么
&lt;/h2&gt;&lt;p&gt;第一，CodeGraph 不是替代代码审查和测试的工具。它能帮助 Agent 更快找到相关代码，但不能保证 Agent 的修改一定正确。&lt;/p&gt;
&lt;p&gt;第二，索引质量会影响使用效果。项目结构复杂、生成代码很多、语言混杂或 build 产物没有排除时，索引可能会变得臃肿。使用前最好确认 &lt;code&gt;.gitignore&lt;/code&gt;、项目目录和索引范围是否合理。&lt;/p&gt;
&lt;p&gt;第三，MCP 配置和 Agent 指令很关键。README 里也提醒，CodeGraph 只有在被正确查询时才有帮助。如果 Agent 仍然绕开它去大量读文件，预索引就会变成额外开销。&lt;/p&gt;
&lt;p&gt;第四，虽然它是本地工具，也要注意权限。安装器会写入 Agent 配置和权限列表，团队环境中最好统一审查这些配置。&lt;/p&gt;
&lt;h2 id=&#34;小结&#34;&gt;小结
&lt;/h2&gt;&lt;p&gt;&lt;code&gt;CodeGraph&lt;/code&gt; 的价值可以简单理解为：给 AI Agent 一张本地代码地图。它不是让模型更聪明，而是让模型少迷路。&lt;/p&gt;
&lt;p&gt;当 Claude Code、Codex CLI、Cursor 这类工具面对大型仓库时，最耗费上下文的往往是探索过程。CodeGraph 用预索引的符号关系、调用图、路由图和全文搜索，把“找代码”这一步提前做好，让 Agent 把更多预算花在理解和修改上。&lt;/p&gt;
&lt;p&gt;如果你已经在真实项目里使用 AI 编程工具，并且经常遇到“它读了一堆文件还是没找到重点”的情况，CodeGraph 值得试一下。它代表了 AI 编程工具的一个重要方向：不只是换更强的模型，也要给模型更好的本地代码上下文。&lt;/p&gt;
&lt;p&gt;参考资料：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;GitHub 项目：&lt;a class=&#34;link&#34; href=&#34;https://github.com/colbymchenry/codegraph&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;https://github.com/colbymchenry/codegraph&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
        </item>
        <item>
        <title>oh-my-pi 是什么？一个把终端、IDE 和调试器打通的 AI 编程助手</title>
        <link>https://knightli.com/2026/05/23/oh-my-pi-ai-coding-agent-terminal-ide-lsp-debugger/</link>
        <pubDate>Sat, 23 May 2026 19:02:20 +0800</pubDate>
        
        <guid>https://knightli.com/2026/05/23/oh-my-pi-ai-coding-agent-terminal-ide-lsp-debugger/</guid>
        <description>&lt;p&gt;&lt;code&gt;oh-my-pi&lt;/code&gt; 是一个面向终端和编辑器的 AI Coding Agent。它来自 Mario Zechner 的 &lt;code&gt;Pi&lt;/code&gt; 项目分支，由 &lt;code&gt;can1357&lt;/code&gt; 继续扩展，目标不是只做一个命令行聊天界面，而是把文件读取、代码搜索、结构化编辑、LSP、调试器、浏览器、子代理和多模型提供商接到同一个编程工作流里。&lt;/p&gt;
&lt;p&gt;从项目 README 看，它更像一套 AI 编程工具底座：终端里可以直接交互，编辑器可以通过 ACP 接入，Node 项目也可以通过 SDK 嵌入。对已经在用 Claude Code、Codex CLI、Cline、Cursor 或其他 Agent 工具的人来说，&lt;code&gt;oh-my-pi&lt;/code&gt; 值得关注的地方在于它把很多原本分散在外部工具里的能力做成了内置工具面。&lt;/p&gt;
&lt;h2 id=&#34;它主要解决什么问题&#34;&gt;它主要解决什么问题
&lt;/h2&gt;&lt;p&gt;很多 AI 编程工具的短板不在模型本身，而在工具接口。模型想改代码时，如果只能拿到粗糙的全文、脆弱的字符串替换和一次性 shell，失败率就会被工具链放大。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;oh-my-pi&lt;/code&gt; 的思路是把这些常见摩擦点压低：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;读取文件时优先给结构化摘要，而不是把整份文件塞进上下文。&lt;/li&gt;
&lt;li&gt;搜索、glob、find、语法高亮、token 计数等能力尽量放进原生实现，减少对外部命令的依赖。&lt;/li&gt;
&lt;li&gt;写代码时接入 LSP，让重命名、引用查找、文件移动更接近 IDE 行为。&lt;/li&gt;
&lt;li&gt;调试时接入 &lt;code&gt;lldb&lt;/code&gt;、&lt;code&gt;dlv&lt;/code&gt;、&lt;code&gt;debugpy&lt;/code&gt; 等 DAP 工具，而不是只靠日志和猜测。&lt;/li&gt;
&lt;li&gt;复杂任务可以拆给子代理，并用结构化结果返回。&lt;/li&gt;
&lt;li&gt;对编辑操作使用内容锚点和预览机制，降低错误 patch 直接落盘的概率。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;这些设计说明它关注的不是“模型会不会回答”，而是“模型能不能稳定完成一次真实代码修改”。&lt;/p&gt;
&lt;h2 id=&#34;安装方式&#34;&gt;安装方式
&lt;/h2&gt;&lt;p&gt;项目提供了几种安装入口。macOS 和 Linux 可以使用安装脚本：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;curl -fsSL https://omp.sh/install &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt; sh
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;如果使用 Bun，官方推荐全局安装 npm 包：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;bun install -g @oh-my-pi/pi-coding-agent
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;Windows PowerShell 可以使用：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-powershell&#34; data-lang=&#34;powershell&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nb&#34;&gt;irm &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;https&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;//&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;omp&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;sh&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;/&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;install&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;py&#34;&gt;ps1&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;iex
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;项目 README 还提到可以通过 &lt;code&gt;mise&lt;/code&gt; 固定版本：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;mise use -g github:can1357/oh-my-pi
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;安装前要注意 Bun 版本要求。README 中标注的平台范围包括 macOS、Linux、Windows，并要求 &lt;code&gt;bun &amp;gt;= 1.3.14&lt;/code&gt;。&lt;/p&gt;
&lt;h2 id=&#34;值得关注的能力&#34;&gt;值得关注的能力
&lt;/h2&gt;&lt;h3 id=&#34;1-工具调用不只停留在-shell&#34;&gt;1. 工具调用不只停留在 shell
&lt;/h3&gt;&lt;p&gt;&lt;code&gt;oh-my-pi&lt;/code&gt; 内置了文件读取、搜索、写入、编辑、AST 编辑、浏览器、任务拆分、调试、LSP 等工具。README 中提到它有 32 个内置工具、13 个 LSP 操作和 27 个 DAP 操作。&lt;/p&gt;
&lt;p&gt;这意味着 Agent 不必把所有事情都包装成命令行输出。比如查引用可以走 LSP，读 PR 或 issue 可以走统一的文件式接口，网页和 PDF 可以被转换成带链接结构的 Markdown，再交给模型处理。&lt;/p&gt;
&lt;h3 id=&#34;2-lsp-接入更适合真实代码库&#34;&gt;2. LSP 接入更适合真实代码库
&lt;/h3&gt;&lt;p&gt;对大型项目来说，重命名和移动文件最怕漏掉 re-export、别名导入、barrel file 或跨目录引用。&lt;code&gt;oh-my-pi&lt;/code&gt; 的 README 特别强调写入路径会接入 LSP，例如文件重命名会经过 &lt;code&gt;workspace/willRenameFiles&lt;/code&gt;，让编辑更接近 IDE 的语义操作。&lt;/p&gt;
&lt;p&gt;这类能力适合 TypeScript、Rust、Go、Python 等项目里的日常重构，尤其是那些“手动改能改，但很容易漏一个引用”的场景。&lt;/p&gt;
&lt;h3 id=&#34;3-调试器是一级工具&#34;&gt;3. 调试器是一级工具
&lt;/h3&gt;&lt;p&gt;很多 AI 编程流程遇到崩溃时，仍然停留在添加日志、重新运行、再读输出。&lt;code&gt;oh-my-pi&lt;/code&gt; 把 DAP 调试器接入工具面，README 里举了 C 程序用 &lt;code&gt;lldb&lt;/code&gt;、Go 服务用 &lt;code&gt;dlv&lt;/code&gt;、Python 进程用 &lt;code&gt;debugpy&lt;/code&gt; 的例子。&lt;/p&gt;
&lt;p&gt;这会改变 Agent 处理 bug 的方式：它可以暂停进程、查看栈帧、读局部变量，再决定下一步，而不是只靠报错文本猜测。&lt;/p&gt;
&lt;h3 id=&#34;4-hashline-编辑降低-patch-失败率&#34;&gt;4. Hashline 编辑降低 patch 失败率
&lt;/h3&gt;&lt;p&gt;项目强调的 &lt;code&gt;Hashline&lt;/code&gt; 是一种基于内容锚点的编辑方式。它的目标是让模型指向要修改的内容锚点，而不是反复输出大段 diff。这样做的好处是减少空格、上下文过期、字符串匹配失败造成的编辑错误。&lt;/p&gt;
&lt;p&gt;对 Agent 工具来说，这类机制很重要。模型能力再强，如果写入接口经常失败，最终体验仍然会变成反复重试。&lt;/p&gt;
&lt;h3 id=&#34;5-子代理和工作区隔离&#34;&gt;5. 子代理和工作区隔离
&lt;/h3&gt;&lt;p&gt;README 中介绍了 &lt;code&gt;task&lt;/code&gt; 子代理能力：一个任务可以拆给多个隔离 worker，结果再以结构化对象返回。项目还包含工作区隔离相关实现，用来支持并行任务、分支探索和避免互相覆盖。&lt;/p&gt;
&lt;p&gt;这适合代码审查、迁移、批量修复、测试定位等任务。真正的价值不只是“并行更快”，而是让不同探索路径之间的上下文和文件改动更清楚。&lt;/p&gt;
&lt;h3 id=&#34;6-兼容已有规则和配置&#34;&gt;6. 兼容已有规则和配置
&lt;/h3&gt;&lt;p&gt;&lt;code&gt;oh-my-pi&lt;/code&gt; 首次运行时会读取已有工具留下的规则和配置，包括 &lt;code&gt;.claude&lt;/code&gt;、&lt;code&gt;.cursor&lt;/code&gt;、&lt;code&gt;.windsurf&lt;/code&gt;、&lt;code&gt;.gemini&lt;/code&gt;、&lt;code&gt;.codex&lt;/code&gt;、&lt;code&gt;.cline&lt;/code&gt;、&lt;code&gt;.github/copilot&lt;/code&gt; 和 &lt;code&gt;.vscode&lt;/code&gt; 等目录。&lt;/p&gt;
&lt;p&gt;这点很实用。很多团队已经为不同 AI 工具写过规则，如果每换一个工具都要迁移一遍，成本会很高。&lt;code&gt;oh-my-pi&lt;/code&gt; 的做法是尽量直接继承已有上下文。&lt;/p&gt;
&lt;h2 id=&#34;四种入口&#34;&gt;四种入口
&lt;/h2&gt;&lt;p&gt;项目提供了四类使用入口：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;交互式 TUI：在终端里直接运行 &lt;code&gt;omp&lt;/code&gt;。&lt;/li&gt;
&lt;li&gt;一次性命令：用 &lt;code&gt;omp -p&lt;/code&gt; 发送单次 prompt。&lt;/li&gt;
&lt;li&gt;Node SDK：通过 &lt;code&gt;@oh-my-pi/pi-coding-agent&lt;/code&gt; 嵌入到 Node 或 TypeScript 项目。&lt;/li&gt;
&lt;li&gt;RPC / ACP：通过 stdio 或 Agent Client Protocol 接入其他程序和编辑器。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;这说明它不只面向个人终端用户，也给 IDE、插件、自动化平台和内部工具留了集成空间。&lt;/p&gt;
&lt;h2 id=&#34;适合谁尝试&#34;&gt;适合谁尝试
&lt;/h2&gt;&lt;p&gt;&lt;code&gt;oh-my-pi&lt;/code&gt; 比较适合这几类用户：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;经常在终端里做代码修改、调试和审查的人。&lt;/li&gt;
&lt;li&gt;已经在使用 AI Coding Agent，但觉得文件读取、patch、搜索或调试链路不够稳的人。&lt;/li&gt;
&lt;li&gt;想把 Agent 接入编辑器、RPC 或 Node 服务的开发者。&lt;/li&gt;
&lt;li&gt;需要在一个工具里切换多模型和多提供商的人。&lt;/li&gt;
&lt;li&gt;对 LSP、DAP、AST 编辑和子代理这些底层能力感兴趣的工具开发者。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;如果只是想要一个开箱即用的聊天式代码助手，学习成本可能会偏高。它更适合愿意理解工具链，并把 Agent 当成可配置开发环境的人。&lt;/p&gt;
&lt;h2 id=&#34;使用时要注意什么&#34;&gt;使用时要注意什么
&lt;/h2&gt;&lt;p&gt;第一，&lt;code&gt;oh-my-pi&lt;/code&gt; 仍然是快速演进中的开源项目。仓库提交频繁，issue 和 PR 数量也不少，安装和使用时要预期到变化。&lt;/p&gt;
&lt;p&gt;第二，它的能力边界和本地环境强相关。LSP、调试器、Bun、模型提供商认证、终端环境、Windows 或 Unix 差异都会影响体验。&lt;/p&gt;
&lt;p&gt;第三，内置工具多不等于每个场景都应该全开。实际使用时更适合按任务启用需要的工具，把规则、权限和工作区边界配置清楚。&lt;/p&gt;
&lt;p&gt;第四，AI Agent 能写代码，也能误改代码。即使有预览和锚点编辑机制，重要项目仍然要保留版本控制、测试和人工审查。&lt;/p&gt;
&lt;h2 id=&#34;小结&#34;&gt;小结
&lt;/h2&gt;&lt;p&gt;&lt;code&gt;oh-my-pi&lt;/code&gt; 的亮点不在于又做了一个 AI 终端壳，而在于它把 AI 编程中最容易拖后腿的工具层重新整理了一遍：文件读取、搜索、编辑、LSP、调试、浏览器、子代理和 SDK 都被放进同一个 Agent 工作流。&lt;/p&gt;
&lt;p&gt;它适合关注 AI 编程基础设施的人，也适合想比较不同 Coding Agent 路线的开发者。当前 AI 编程工具的竞争，已经不只是模型回答质量的竞争，也是在比谁能把模型稳定接入真实代码库、真实调试流程和真实团队规则。&lt;code&gt;oh-my-pi&lt;/code&gt; 正是在这个方向上给出了一套很激进的开源实现。&lt;/p&gt;
&lt;p&gt;参考资料：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;GitHub 项目：&lt;a class=&#34;link&#34; href=&#34;https://github.com/can1357/oh-my-pi&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;https://github.com/can1357/oh-my-pi&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;官方站点：&lt;a class=&#34;link&#34; href=&#34;https://omp.sh/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;https://omp.sh/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;SDK 文档：&lt;a class=&#34;link&#34; href=&#34;https://omp.sh/docs/sdk&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;https://omp.sh/docs/sdk&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
        </item>
        <item>
        <title>Graphify 解决 Claude Code 最大局限：把代码库变成 AI 可查询知识图谱</title>
        <link>https://knightli.com/2026/05/21/safishamsi-graphify-ai-code-knowledge-graph/</link>
        <pubDate>Thu, 21 May 2026 08:02:32 +0800</pubDate>
        
        <guid>https://knightli.com/2026/05/21/safishamsi-graphify-ai-code-knowledge-graph/</guid>
        <description>&lt;p&gt;&lt;code&gt;safishamsi/graphify&lt;/code&gt; 是一个面向 AI 编程助手的知识图谱工具。它的目标很直接：把一个项目目录里的代码、文档、SQL schema、脚本、论文、图片、视频和音频，整理成可查询的知识图谱，让 AI 助手不再只靠 &lt;code&gt;grep&lt;/code&gt;、全文阅读或临时搜索来理解项目。&lt;/p&gt;
&lt;p&gt;项目地址：&lt;a class=&#34;link&#34; href=&#34;https://github.com/safishamsi/graphify&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;safishamsi/graphify&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;截至本文整理时，GitHub 页面显示项目约有 50.2k stars、5.4k forks，许可证为 MIT。README 对它的描述是：在 AI 编程助手里输入 &lt;code&gt;/graphify&lt;/code&gt;，它就会把整个项目映射成一个可以查询的知识图谱。&lt;/p&gt;
&lt;h2 id=&#34;它解决的核心问题&#34;&gt;它解决的核心问题
&lt;/h2&gt;&lt;p&gt;AI 编程助手越来越强，但在真实代码库里仍然经常遇到几个问题：&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;代码、数据库 schema、文档和基础设施配置分散在不同地方。&lt;/li&gt;
&lt;li&gt;多人协作时，每个人对项目结构的理解不一致。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Graphify 想做的是给项目生成一层“记忆层”。它把代码实体、文档概念、数据库表、配置、设计说明和跨文件关系连接起来，让 AI 助手可以按图谱查询，而不是每次从零开始扫文件。&lt;/p&gt;
&lt;h2 id=&#34;最小使用方式&#34;&gt;最小使用方式
&lt;/h2&gt;&lt;p&gt;Graphify 的最小用法非常简单。安装后，在 AI 编程助手里输入：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;/graphify .
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;在 PowerShell 里要注意，前导 &lt;code&gt;/&lt;/code&gt; 会被当成路径分隔符，所以 Windows PowerShell 下应使用：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;graphify .
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;运行后会生成 &lt;code&gt;graphify-out/&lt;/code&gt; 目录，核心文件包括：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;graphify-out/
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;├── graph.html
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;├── GRAPH_REPORT.md
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;└── graph.json
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;这三个文件分工不同：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;graph.html&lt;/code&gt;：浏览器里打开的交互式图谱，可以点击节点、过滤和搜索。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;GRAPH_REPORT.md&lt;/code&gt;：项目亮点、关键概念、意外连接和推荐问题。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;graph.json&lt;/code&gt;：完整图谱，后续可以直接查询，不必重新读所有文件。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;如果想生成更可读的架构页面和 Mermaid 调用流图，可以运行：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;graphify &lt;span class=&#34;nb&#34;&gt;export&lt;/span&gt; callflow-html
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h2 id=&#34;安装和平台支持&#34;&gt;安装和平台支持
&lt;/h2&gt;&lt;p&gt;Graphify 的 PyPI 包名是 &lt;code&gt;graphifyy&lt;/code&gt;，注意是双 &lt;code&gt;y&lt;/code&gt;。README 特别提醒，PyPI 上其他 &lt;code&gt;graphify*&lt;/code&gt; 包并不属于该项目，但 CLI 命令仍然叫 &lt;code&gt;graphify&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;推荐安装方式是：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;uv tool install graphifyy
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;也可以使用：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;pipx install graphifyy
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;pip install graphifyy
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;安装后注册到 AI 助手：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;graphify install
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;项目支持的平台很多，包括 Claude Code、Codex、OpenCode、GitHub Copilot CLI、VS Code Copilot Chat、Aider、Cursor、Gemini CLI、Kimi Code、Kiro、Google Antigravity 等。不同平台可以用不同安装命令，例如：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;graphify install --platform codex
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;graphify install --platform gemini
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;graphify cursor install
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;graphify antigravity install
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;Codex 用户还需要在 &lt;code&gt;~/.codex/config.toml&lt;/code&gt; 的 &lt;code&gt;[features]&lt;/code&gt; 下加入：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-toml&#34; data-lang=&#34;toml&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nx&#34;&gt;multi_agent&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;true&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;README 也说明，Codex 使用 &lt;code&gt;$graphify&lt;/code&gt;，不是 &lt;code&gt;/graphify&lt;/code&gt;。&lt;/p&gt;
&lt;h2 id=&#34;它能处理哪些文件&#34;&gt;它能处理哪些文件
&lt;/h2&gt;&lt;p&gt;Graphify 覆盖的输入类型很广。&lt;/p&gt;
&lt;p&gt;代码方面，它支持 31 种语言，包括 Python、TypeScript、JavaScript、Go、Rust、Java、C/C++、Ruby、C#、Kotlin、Scala、PHP、Swift、Lua、Zig、PowerShell、SQL、Shell、JSON 等。&lt;/p&gt;
&lt;p&gt;文档方面，它支持：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;.md&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;.mdx&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;.qmd&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;.html&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;.txt&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;.rst&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;.yaml&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;.yml&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;还可以通过可选依赖扩展更多类型：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;7
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;pip install &lt;span class=&#34;s2&#34;&gt;&amp;#34;graphifyy[pdf]&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;pip install &lt;span class=&#34;s2&#34;&gt;&amp;#34;graphifyy[office]&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;pip install &lt;span class=&#34;s2&#34;&gt;&amp;#34;graphifyy[video]&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;pip install &lt;span class=&#34;s2&#34;&gt;&amp;#34;graphifyy[mcp]&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;pip install &lt;span class=&#34;s2&#34;&gt;&amp;#34;graphifyy[neo4j]&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;pip install &lt;span class=&#34;s2&#34;&gt;&amp;#34;graphifyy[sql]&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;pip install &lt;span class=&#34;s2&#34;&gt;&amp;#34;graphifyy[all]&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;其中，&lt;code&gt;pdf&lt;/code&gt; 用于 PDF 提取，&lt;code&gt;office&lt;/code&gt; 用于 &lt;code&gt;.docx&lt;/code&gt; 和 &lt;code&gt;.xlsx&lt;/code&gt;，&lt;code&gt;video&lt;/code&gt; 用于视频和音频转写，&lt;code&gt;mcp&lt;/code&gt; 用于 MCP stdio server，&lt;code&gt;neo4j&lt;/code&gt; 用于推送到 Neo4j，&lt;code&gt;sql&lt;/code&gt; 用于 SQL schema 提取。&lt;/p&gt;
&lt;h2 id=&#34;生成的报告有什么价值&#34;&gt;生成的报告有什么价值
&lt;/h2&gt;&lt;p&gt;&lt;code&gt;GRAPH_REPORT.md&lt;/code&gt; 不是普通摘要，它会把项目里更值得 AI 助手关注的关系挑出来。&lt;/p&gt;
&lt;p&gt;README 里提到的报告内容包括：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;God nodes&lt;/code&gt;：项目里连接最多的核心概念。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Surprising connections&lt;/code&gt;：跨文件、跨模块的意外连接。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;The why&lt;/code&gt;：从注释、docstring、设计文档里提取出的设计理由。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Suggested questions&lt;/code&gt;：图谱特别适合回答的问题。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Confidence tags&lt;/code&gt;：关系会标记为 &lt;code&gt;EXTRACTED&lt;/code&gt;、&lt;code&gt;INFERRED&lt;/code&gt; 或 &lt;code&gt;AMBIGUOUS&lt;/code&gt;。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;这点很关键。普通搜索只能告诉你“哪里出现了这个词”，而图谱可以回答“这个概念和哪些模块、配置、表、文档有关”。对大型代码库来说，这比单纯全文检索更接近架构理解。&lt;/p&gt;
&lt;h2 id=&#34;常用命令&#34;&gt;常用命令
&lt;/h2&gt;&lt;p&gt;Graphify 的常见命令包括：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;7
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;8
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;9
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;/graphify .
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;/graphify ./docs --update
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;/graphify . --cluster-only
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;/graphify . --no-viz
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;/graphify . --wiki
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;graphify &lt;span class=&#34;nb&#34;&gt;export&lt;/span&gt; callflow-html
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;/graphify query &lt;span class=&#34;s2&#34;&gt;&amp;#34;what connects auth to the database?&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;/graphify path &lt;span class=&#34;s2&#34;&gt;&amp;#34;UserService&amp;#34;&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;DatabasePool&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;/graphify explain &lt;span class=&#34;s2&#34;&gt;&amp;#34;RateLimiter&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;也可以把论文或视频加入图谱：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;/graphify add https://arxiv.org/abs/1706.03762
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;/graphify add &amp;lt;youtube-url&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;如果要做 PR 辅助分析，还可以使用：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;graphify prs
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;graphify prs &lt;span class=&#34;m&#34;&gt;42&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;graphify prs --triage
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;graphify prs --conflicts
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;这类命令适合代码评审场景：看 PR 影响了哪些图谱社区、是否和其他 PR 有冲突风险、哪些 review queue 更值得优先处理。&lt;/p&gt;
&lt;h2 id=&#34;和-mcpneo4jci-的关系&#34;&gt;和 MCP、Neo4j、CI 的关系
&lt;/h2&gt;&lt;p&gt;Graphify 不只是生成 HTML 图。它也可以把图谱暴露给 AI 助手反复调用。&lt;/p&gt;
&lt;p&gt;例如可以启动 MCP server：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;python -m graphify.serve graphify-out/graph.json
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;MCP server 提供的能力包括 &lt;code&gt;query_graph&lt;/code&gt;、&lt;code&gt;get_node&lt;/code&gt;、&lt;code&gt;get_neighbors&lt;/code&gt;、&lt;code&gt;shortest_path&lt;/code&gt;、&lt;code&gt;list_prs&lt;/code&gt;、&lt;code&gt;get_pr_impact&lt;/code&gt;、&lt;code&gt;triage_prs&lt;/code&gt; 等。&lt;/p&gt;
&lt;p&gt;它也支持 Neo4j 导出或推送：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;/graphify ./raw --neo4j
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;/graphify ./raw --neo4j-push bolt://localhost:7687
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;团队协作上，README 建议可以提交 &lt;code&gt;graphify-out/&lt;/code&gt;，让团队每个人拉取后都能共享同一份项目地图。还可以运行：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;graphify hook install
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;这样每次 git commit 后自动重建图谱，并设置 merge driver，避免 &lt;code&gt;graph.json&lt;/code&gt; 在多人并行提交时留下冲突标记。&lt;/p&gt;
&lt;h2 id=&#34;隐私和成本要怎么看&#34;&gt;隐私和成本要怎么看
&lt;/h2&gt;&lt;p&gt;Graphify 的 README 对隐私边界写得比较清楚。&lt;/p&gt;
&lt;p&gt;代码文件会通过 tree-sitter 在本地解析，不会发出 API 调用。视频和音频可以通过 faster-whisper 本地转写。文档、PDF、图片这类语义提取内容，则会通过你的 AI 助手模型 API 处理。&lt;/p&gt;
&lt;p&gt;如果用 headless &lt;code&gt;graphify extract&lt;/code&gt;，可能需要设置这些环境变量：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;7
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;ANTHROPIC_API_KEY
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;GEMINI_API_KEY
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;GOOGLE_API_KEY
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;OPENAI_API_KEY
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;DEEPSEEK_API_KEY
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;MOONSHOT_API_KEY
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;OLLAMA_BASE_URL
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;本地 Ollama、AWS Bedrock、Claude Code CLI 等也可以作为 backend。README 还写明项目没有 telemetry、usage tracking 和 analytics。&lt;/p&gt;
&lt;p&gt;实际使用时要注意：代码本地解析不等于所有内容都不出网。涉及文档、PDF、图片或云端模型时，仍然要看 backend、API key、企业合规和数据边界。&lt;/p&gt;
&lt;h2 id=&#34;适合哪些场景&#34;&gt;适合哪些场景
&lt;/h2&gt;&lt;p&gt;Graphify 适合几类用户：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;想让 Claude Code、Codex、Cursor、Gemini CLI 更懂项目结构的开发者。&lt;/li&gt;
&lt;li&gt;需要快速理解大型陌生代码库的人。&lt;/li&gt;
&lt;li&gt;需要把代码、SQL schema、文档、配置放在一起分析的团队。&lt;/li&gt;
&lt;li&gt;做架构审查、PR review、重构影响分析的人。&lt;/li&gt;
&lt;li&gt;希望把项目知识暴露成 MCP 工具给 Agent 使用的人。&lt;/li&gt;
&lt;li&gt;想为团队保留“项目地图”的技术负责人。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;它不一定适合所有项目。小型脚本、一次性 demo、结构非常简单的仓库，用普通搜索和 README 可能已经够用。Graphify 的价值更容易出现在模块多、文档多、团队协作多、AI 助手频繁参与开发的大项目里。&lt;/p&gt;
&lt;h2 id=&#34;小结&#34;&gt;小结
&lt;/h2&gt;&lt;p&gt;Graphify 的意义在于，它把 AI 编程助手的上下文从“临时读取文件”推进到“长期可查询的项目知识图谱”。&lt;/p&gt;
&lt;p&gt;对开发者来说，它不是替代 IDE、搜索或 LSP，而是给 AI 助手补一层结构化记忆：哪些模块重要、哪些概念连接紧密、哪些文档解释了设计理由、某个 PR 会影响哪些社区。随着 Codex、Claude Code、Gemini CLI、Antigravity 这类 Agent 工具继续普及，这类“项目图谱层”会越来越有用。&lt;/p&gt;
&lt;p&gt;参考来源：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://github.com/safishamsi/graphify&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;GitHub：safishamsi/graphify&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
        </item>
        <item>
        <title>Vercel AI SDK 是什么？TypeScript 开发者构建 AI 应用的统一工具包</title>
        <link>https://knightli.com/2026/05/17/vercel-ai-sdk-typescript-agent-toolkit/</link>
        <pubDate>Sun, 17 May 2026 23:07:38 +0800</pubDate>
        
        <guid>https://knightli.com/2026/05/17/vercel-ai-sdk-typescript-agent-toolkit/</guid>
        <description>&lt;p&gt;&lt;code&gt;vercel/ai&lt;/code&gt; 是 Vercel 维护的开源 AI SDK。&lt;/p&gt;
&lt;p&gt;它的定位很明确：给 TypeScript 开发者提供一套统一工具，用来构建 AI 应用和 AI Agent。它来自 Next.js 背后的团队，但并不只服务于 Next.js，也支持 React、Svelte、Vue、Angular 等 UI 框架，以及 Node.js 等运行时。&lt;/p&gt;
&lt;p&gt;项目地址：&lt;a class=&#34;link&#34; href=&#34;https://github.com/vercel/ai&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;https://github.com/vercel/ai&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;如果你正在做聊天应用、AI 写作工具、RAG 应用、带工具调用的 Agent、流式输出界面，或者想把多个模型供应商接到同一个应用里，Vercel AI SDK 是一个值得关注的基础库。&lt;/p&gt;
&lt;h2 id=&#34;它解决的核心问题&#34;&gt;它解决的核心问题
&lt;/h2&gt;&lt;p&gt;现在做 AI 应用，最大麻烦之一不是“能不能调模型”，而是不同模型供应商的接口、流式输出、工具调用、错误处理和前端状态管理都不一样。&lt;/p&gt;
&lt;p&gt;例如：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;OpenAI 有自己的 SDK 和响应格式。&lt;/li&gt;
&lt;li&gt;Anthropic 有自己的消息结构。&lt;/li&gt;
&lt;li&gt;Google、xAI、Mistral、DeepSeek、Groq 等也各有差异。&lt;/li&gt;
&lt;li&gt;流式输出需要处理 chunk。&lt;/li&gt;
&lt;li&gt;工具调用需要处理模型发起的结构化请求。&lt;/li&gt;
&lt;li&gt;前端聊天 UI 还要管理消息、加载状态、取消、重试和错误展示。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;如果每个供应商都手写一套适配层，项目会很快变复杂。&lt;/p&gt;
&lt;p&gt;Vercel AI SDK 的思路是把这些差异收敛到统一 API 后面。开发者用一套接口写应用，再通过 Provider 接入不同模型。&lt;/p&gt;
&lt;h2 id=&#34;统一-provider-架构&#34;&gt;统一 Provider 架构
&lt;/h2&gt;&lt;p&gt;Vercel AI SDK 的一个核心特点，是 provider-agnostic，也就是不绑定单一模型厂商。&lt;/p&gt;
&lt;p&gt;它可以通过统一 API 访问 OpenAI、Anthropic、Google 等模型提供方。项目 README 还提到，默认情况下 AI SDK 会使用 Vercel AI Gateway，让开发者更容易访问多个主流 provider。&lt;/p&gt;
&lt;p&gt;这对工程项目很实用。&lt;/p&gt;
&lt;p&gt;因为很多 AI 产品最终都不会只依赖一个模型：&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;/ul&gt;
&lt;p&gt;统一 Provider 架构让应用更容易做模型切换、灰度测试、成本控制和备选方案。&lt;/p&gt;
&lt;h2 id=&#34;流式输出是前端体验的关键&#34;&gt;流式输出是前端体验的关键
&lt;/h2&gt;&lt;p&gt;AI 应用和传统 API 最大的体验差异之一，是响应可能很长。&lt;/p&gt;
&lt;p&gt;如果用户每次都要等完整回答返回，聊天工具、写作工具和代码助手会显得很慢。流式输出可以让文本逐步显示，用户更早看到结果。&lt;/p&gt;
&lt;p&gt;Vercel AI SDK 对流式生成做了比较完整的封装。开发者不需要从零处理底层事件流，而是可以使用 SDK 提供的生成和流式接口，把模型输出接到前端 UI。&lt;/p&gt;
&lt;p&gt;这对 Next.js / React 应用尤其方便。&lt;/p&gt;
&lt;p&gt;一个 AI 聊天界面看起来简单，但实际要处理：&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;流式 token 展示。&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;p&gt;这些都是 AI SDK 试图帮开发者减少重复劳动的地方。&lt;/p&gt;
&lt;h2 id=&#34;工具调用和-agent-场景&#34;&gt;工具调用和 Agent 场景
&lt;/h2&gt;&lt;p&gt;随着 AI 应用从“聊天”走向“做事”，工具调用变得越来越重要。&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;调用业务 API。&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;p&gt;Vercel AI SDK 支持工具调用相关能力，让开发者可以定义工具、参数和执行逻辑，再让模型在合适时机请求调用。&lt;/p&gt;
&lt;p&gt;这也是它从“聊天 UI SDK”扩展到“AI 应用和 Agent 工具包”的关键。&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;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;AI SDK 可以帮助处理接口和流程，但安全边界仍然需要开发者自己设计。&lt;/p&gt;
&lt;h2 id=&#34;ui-集成能力&#34;&gt;UI 集成能力
&lt;/h2&gt;&lt;p&gt;Vercel AI SDK 对前端框架比较友好。&lt;/p&gt;
&lt;p&gt;它不仅提供核心生成 API，也围绕聊天、补全、消息状态和流式 UI 做了封装。对于使用 Next.js 和 React 的团队来说，这能减少很多样板代码。&lt;/p&gt;
&lt;p&gt;但它并不只适合 Vercel 部署。&lt;/p&gt;
&lt;p&gt;如果你的项目本身是 TypeScript 技术栈，或者后端运行在 Node.js 环境，AI SDK 仍然可以作为模型调用和流式处理层来使用。是否部署在 Vercel，取决于你的应用架构、团队习惯和基础设施选择。&lt;/p&gt;
&lt;h2 id=&#34;skill-for-coding-agents&#34;&gt;Skill for Coding Agents
&lt;/h2&gt;&lt;p&gt;&lt;code&gt;vercel/ai&lt;/code&gt; README 里还有一个有趣的建议：如果你使用 Claude Code、Cursor 等 coding agent，可以把 AI SDK skill 加到仓库里。&lt;/p&gt;
&lt;p&gt;示例命令是：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;npx skills add vercel/ai
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;这说明 Vercel 已经意识到，AI SDK 的用户不只是人类开发者，也包括 coding agent。&lt;/p&gt;
&lt;p&gt;当 agent 修改使用 AI SDK 的项目时，如果仓库里有专门的 skill，它可以更好地理解 SDK 约定、常见 API、项目结构和最佳实践，减少乱写代码的概率。&lt;/p&gt;
&lt;p&gt;这个方向很值得注意。&lt;/p&gt;
&lt;p&gt;未来开源项目可能不只提供 README 和 docs，还会提供给 AI coding agent 使用的结构化技能说明。对复杂 SDK 来说，这会变成新的开发者体验入口。&lt;/p&gt;
&lt;h2 id=&#34;适合哪些项目&#34;&gt;适合哪些项目
&lt;/h2&gt;&lt;p&gt;Vercel AI SDK 适合这几类场景：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;基于 Next.js / React 的 AI 聊天应用。&lt;/li&gt;
&lt;li&gt;需要流式输出的写作、问答、客服和代码助手。&lt;/li&gt;
&lt;li&gt;需要接入多个模型 provider 的 AI 产品。&lt;/li&gt;
&lt;li&gt;想快速构建 RAG 或文档问答原型的团队。&lt;/li&gt;
&lt;li&gt;需要工具调用、函数调用或轻量 Agent 能力的应用。&lt;/li&gt;
&lt;li&gt;已经使用 TypeScript / Node.js 技术栈的团队。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;它尤其适合前端和全栈开发者。因为很多 AI 应用的难点不只是模型调用，而是如何把模型输出变成稳定、流畅、可交互的产品体验。&lt;/p&gt;
&lt;h2 id=&#34;不适合什么场景&#34;&gt;不适合什么场景
&lt;/h2&gt;&lt;p&gt;如果你的项目主要是 Python 后端、深度学习训练、模型微调或底层推理服务，Vercel AI SDK 可能不是核心工具。&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;管理 GPU 推理集群。&lt;/li&gt;
&lt;li&gt;做底层 batch inference。&lt;/li&gt;
&lt;li&gt;深度控制 tokenizer、KV cache、量化和推理引擎。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;那更应该看 PyTorch、vLLM、SGLang、TensorRT-LLM、llama.cpp 或云厂商推理服务。&lt;/p&gt;
&lt;p&gt;Vercel AI SDK 更像“把模型能力接进产品”的应用开发层。&lt;/p&gt;
&lt;h2 id=&#34;使用时要注意什么&#34;&gt;使用时要注意什么
&lt;/h2&gt;&lt;p&gt;第一，不要把统一 API 理解成完全无差异。&lt;/p&gt;
&lt;p&gt;不同模型 provider 的能力、上下文长度、工具调用格式、流式细节、错误类型和计费方式仍然不同。统一 SDK 能减少工程摩擦，但不能消除模型差异。&lt;/p&gt;
&lt;p&gt;第二，要控制成本。&lt;/p&gt;
&lt;p&gt;AI 应用一旦上线，流式聊天、重试、工具调用、RAG 检索和多模型 fallback 都可能增加调用成本。需要做限流、缓存、日志和预算监控。&lt;/p&gt;
&lt;p&gt;第三，要处理安全边界。&lt;/p&gt;
&lt;p&gt;如果模型能调用工具，就必须限制工具能做什么。不要让模型直接执行高风险操作，也不要把密钥、数据库写权限和生产环境操作裸露给模型。&lt;/p&gt;
&lt;p&gt;第四，要保留可观测性。&lt;/p&gt;
&lt;p&gt;AI 应用出问题时，不能只看前端报错。你需要知道用户输入、模型选择、工具调用、响应时间、token 消耗、错误类型和最终输出。&lt;/p&gt;
&lt;h2 id=&#34;小结&#34;&gt;小结
&lt;/h2&gt;&lt;p&gt;&lt;code&gt;vercel/ai&lt;/code&gt; 不是一个新的模型，也不是单纯的聊天组件。&lt;/p&gt;
&lt;p&gt;它更像 TypeScript AI 应用开发的基础设施：统一 Provider、流式输出、工具调用、前端状态管理和 agent 场景，都被放进一个开源 SDK 里。&lt;/p&gt;
&lt;p&gt;对已经使用 Next.js、React、TypeScript、Node.js 的团队来说，它可以显著降低从“模型 API 能跑”到“产品体验可用”的工程成本。&lt;/p&gt;
&lt;p&gt;但它也不是万能层。模型选择、权限设计、成本控制、日志监控和业务安全，仍然需要开发者自己负责。&lt;/p&gt;
&lt;p&gt;如果你想做 AI 应用，而不是训练模型，Vercel AI SDK 是一个值得先试的工具包。&lt;/p&gt;
&lt;h2 id=&#34;参考资料&#34;&gt;参考资料
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://github.com/vercel/ai&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;vercel/ai GitHub 仓库&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://ai-sdk.dev/docs/introduction&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;AI SDK Documentation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://vercel.com/blog/introducing-the-vercel-ai-sdk/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Vercel：Introducing the Vercel AI SDK&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
        </item>
        <item>
        <title>Bun：把 JavaScript 运行时、包管理器、测试和打包合在一起</title>
        <link>https://knightli.com/2026/05/17/bun-javascript-toolkit/</link>
        <pubDate>Sun, 17 May 2026 17:42:25 +0800</pubDate>
        
        <guid>https://knightli.com/2026/05/17/bun-javascript-toolkit/</guid>
        <description>&lt;p&gt;Bun 是 oven-sh 开源的 JavaScript / TypeScript 一体化工具链。&lt;/p&gt;
&lt;p&gt;它不是只想做一个更快的 Node.js 替代品，而是把运行时、包管理器、脚本运行器、测试运行器和打包器都塞进同一个 &lt;code&gt;bun&lt;/code&gt; 命令里。对前端和 Node.js 开发者来说，Bun 的吸引力在于：少装一堆工具，少等一堆安装和构建过程，很多常见任务可以直接用一个命令完成。&lt;/p&gt;
&lt;p&gt;项目地址：&lt;a class=&#34;link&#34; href=&#34;https://github.com/oven-sh/bun&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;https://github.com/oven-sh/bun&lt;/a&gt;&lt;/p&gt;
&lt;h2 id=&#34;先说结论&#34;&gt;先说结论
&lt;/h2&gt;&lt;p&gt;Bun 最适合想简化 JavaScript 工具链的人。&lt;/p&gt;
&lt;p&gt;它能做这些事：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;运行 JavaScript、TypeScript、JSX 和 TSX。&lt;/li&gt;
&lt;li&gt;作为 Node.js 兼容运行时。&lt;/li&gt;
&lt;li&gt;替代 npm / yarn / pnpm 做包管理。&lt;/li&gt;
&lt;li&gt;运行 &lt;code&gt;package.json&lt;/code&gt; 里的 scripts。&lt;/li&gt;
&lt;li&gt;执行测试。&lt;/li&gt;
&lt;li&gt;打包前端或后端代码。&lt;/li&gt;
&lt;li&gt;用 &lt;code&gt;bunx&lt;/code&gt; 执行 npm 包里的命令。&lt;/li&gt;
&lt;li&gt;提供 &lt;code&gt;Bun.serve&lt;/code&gt;、&lt;code&gt;bun:sqlite&lt;/code&gt;、&lt;code&gt;Bun.sql&lt;/code&gt;、&lt;code&gt;Bun.redis&lt;/code&gt;、&lt;code&gt;Bun.s3&lt;/code&gt; 等内建 API。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;它最明显的价值是开发体验：安装依赖快、启动快、命令统一、TypeScript 和 JSX 开箱即用。&lt;/p&gt;
&lt;p&gt;但 Bun 也不是所有项目都该立刻切换。大型 Node.js 项目、依赖大量原生扩展的项目、生产稳定性要求极高的服务，仍然需要逐项验证兼容性、构建行为、测试行为和部署方式。&lt;/p&gt;
&lt;h2 id=&#34;bun-是什么&#34;&gt;Bun 是什么
&lt;/h2&gt;&lt;p&gt;按照官方 README 的描述，Bun 是一个面向 JavaScript 和 TypeScript 应用的一体化工具包。它以单个可执行文件 &lt;code&gt;bun&lt;/code&gt; 发布。&lt;/p&gt;
&lt;p&gt;它的核心是 Bun runtime：一个快速 JavaScript 运行时，目标是作为 Node.js 的 drop-in replacement。Bun 使用 Zig 编写，底层基于 JavaScriptCore，重点优化启动时间和内存占用。&lt;/p&gt;
&lt;p&gt;这意味着你可以直接运行：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;bun run index.tsx
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;TypeScript 和 JSX 不需要额外配置就能跑。&lt;/p&gt;
&lt;p&gt;同一个 &lt;code&gt;bun&lt;/code&gt; 命令还包含：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;test runner&lt;/li&gt;
&lt;li&gt;script runner&lt;/li&gt;
&lt;li&gt;Node.js 兼容包管理器&lt;/li&gt;
&lt;li&gt;bundler&lt;/li&gt;
&lt;li&gt;package runner&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;常见命令包括：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;bun &lt;span class=&#34;nb&#34;&gt;test&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;bun run start
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;bun install &amp;lt;pkg&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;bunx cowsay &lt;span class=&#34;s1&#34;&gt;&amp;#39;Hello, world!&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;过去一个项目里可能同时出现 &lt;code&gt;node&lt;/code&gt;、&lt;code&gt;npm&lt;/code&gt;、&lt;code&gt;pnpm&lt;/code&gt;、&lt;code&gt;tsx&lt;/code&gt;、&lt;code&gt;jest&lt;/code&gt;、&lt;code&gt;vitest&lt;/code&gt;、&lt;code&gt;webpack&lt;/code&gt;、&lt;code&gt;esbuild&lt;/code&gt;、&lt;code&gt;ts-node&lt;/code&gt; 等工具。Bun 的路线是尽量把高频路径收进一个工具里。&lt;/p&gt;
&lt;h2 id=&#34;安装方式&#34;&gt;安装方式
&lt;/h2&gt;&lt;p&gt;Bun 支持 Linux、macOS 和 Windows，覆盖 x64 与 arm64。&lt;/p&gt;
&lt;p&gt;官方推荐安装脚本：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;curl -fsSL https://bun.com/install &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt; bash
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;Windows：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-powershell&#34; data-lang=&#34;powershell&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;powershell&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;-c&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;irm bun.sh/install.ps1 | iex&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;也可以通过 npm 安装：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;npm install -g bun
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;macOS Homebrew：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;brew tap oven-sh/bun
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;brew install bun
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;Docker：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;docker pull oven/bun
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;docker run --rm --init --ulimit &lt;span class=&#34;nv&#34;&gt;memlock&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;-1:-1 oven/bun
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;Linux 用户要注意内核版本。README 提到强烈建议 Linux kernel &lt;code&gt;5.6&lt;/code&gt; 或更高，最低要求是 &lt;code&gt;5.1&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;升级到最新版：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;bun upgrade
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;升级到 canary：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;bun upgrade --canary
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;生产环境一般不建议直接用 canary，除非你是在验证新特性或排查特定 bug。&lt;/p&gt;
&lt;h2 id=&#34;为什么-bun-会快&#34;&gt;为什么 Bun 会快
&lt;/h2&gt;&lt;p&gt;Bun 的“快”主要来自几个层面。&lt;/p&gt;
&lt;p&gt;第一，运行时启动快。&lt;/p&gt;
&lt;p&gt;很多 CLI 工具和开发脚本的瓶颈不是长期 CPU 运算，而是进程启动、模块加载、TypeScript 转译和依赖解析。Bun 针对这些路径做了很多优化。&lt;/p&gt;
&lt;p&gt;第二，包管理快。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;bun install&lt;/code&gt; 的目标是替代 npm / yarn / pnpm 的依赖安装流程。它使用全局缓存和自己的 lockfile，安装大量依赖时通常能明显减少等待。&lt;/p&gt;
&lt;p&gt;第三，TypeScript / JSX 开箱即用。&lt;/p&gt;
&lt;p&gt;很多项目只是想运行一个 &lt;code&gt;.ts&lt;/code&gt; 或 &lt;code&gt;.tsx&lt;/code&gt; 脚本，传统 Node.js 工具链需要额外加 &lt;code&gt;tsx&lt;/code&gt;、&lt;code&gt;ts-node&lt;/code&gt;、Babel 或构建步骤。Bun 可以直接跑，减少了胶水工具。&lt;/p&gt;
&lt;p&gt;第四，内置工具减少进程和配置切换。&lt;/p&gt;
&lt;p&gt;测试、脚本、打包、运行都在同一个工具里，很多场景不用再在多个 CLI 之间切换。&lt;/p&gt;
&lt;p&gt;但要注意，“Bun 很快”不等于每个项目都一定更快。真实效果取决于依赖类型、脚本逻辑、测试框架、构建配置、Node.js API 使用情况和 CI 缓存策略。&lt;/p&gt;
&lt;h2 id=&#34;包管理替代-npm--yarn--pnpm&#34;&gt;包管理：替代 npm / yarn / pnpm
&lt;/h2&gt;&lt;p&gt;Bun 可以直接安装依赖：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;bun install
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;添加依赖：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;bun add react
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;添加开发依赖：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;bun add -d typescript
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;移除依赖：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;bun remove react
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;查看依赖原因：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;bun why react
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;安全检查：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;bun audit
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;如果你从 npm 或 pnpm 迁移，重点要看：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;bun.lock&lt;/code&gt; 是否进入版本控制。&lt;/li&gt;
&lt;li&gt;CI 是否使用 &lt;code&gt;bun install --frozen-lockfile&lt;/code&gt;。&lt;/li&gt;
&lt;li&gt;私有 registry 和 &lt;code&gt;.npmrc&lt;/code&gt; 是否兼容。&lt;/li&gt;
&lt;li&gt;workspace 行为是否符合预期。&lt;/li&gt;
&lt;li&gt;lifecycle scripts 是否会带来安全风险。&lt;/li&gt;
&lt;li&gt;原本依赖 pnpm 特性的 monorepo 是否能平滑迁移。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;小项目可以直接试。大型 monorepo 不建议一次性全切，可以先在单个 package 或 CI 的非关键任务里试。&lt;/p&gt;
&lt;h2 id=&#34;运行脚本和-typescript&#34;&gt;运行脚本和 TypeScript
&lt;/h2&gt;&lt;p&gt;Bun 可以运行 &lt;code&gt;package.json&lt;/code&gt; 里的脚本：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;bun run start
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;也可以直接运行文件：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;bun run index.ts
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;bun run index.tsx
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;这对工具脚本很方便。比如以前项目里有一堆：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;scripts/build.ts&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;scripts/seed.ts&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;scripts/migrate.ts&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;scripts/check.ts&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;如果用 Node.js，通常要解决 TypeScript loader 或预编译问题。Bun 的直接运行能力可以让这些脚本更轻。&lt;/p&gt;
&lt;p&gt;不过，如果脚本依赖 Node.js 特定行为，尤其是 loader、ESM/CJS 边界、原生模块、child process、文件监听和某些边缘 API，仍然要测试。&lt;/p&gt;
&lt;h2 id=&#34;测试运行器&#34;&gt;测试运行器
&lt;/h2&gt;&lt;p&gt;Bun 内置测试运行器：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;bun &lt;span class=&#34;nb&#34;&gt;test&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;它适合想减少 Jest / Vitest 配置的小项目，也适合把一些单元测试、工具测试、库测试迁移到更轻的运行方式。&lt;/p&gt;
&lt;p&gt;迁移测试时重点关注：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;expect&lt;/code&gt; 行为差异。&lt;/li&gt;
&lt;li&gt;mock API 差异。&lt;/li&gt;
&lt;li&gt;snapshot 行为。&lt;/li&gt;
&lt;li&gt;DOM 测试环境。&lt;/li&gt;
&lt;li&gt;测试发现规则。&lt;/li&gt;
&lt;li&gt;覆盖率输出。&lt;/li&gt;
&lt;li&gt;CI reporter 支持。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;如果项目已经深度依赖 Jest 生态，比如大量自定义 matcher、复杂 mock、jsdom、babel-jest、ts-jest，迁移就不要太急。可以先让新模块用 &lt;code&gt;bun test&lt;/code&gt;，旧测试继续保留原框架。&lt;/p&gt;
&lt;h2 id=&#34;打包和构建&#34;&gt;打包和构建
&lt;/h2&gt;&lt;p&gt;Bun 也提供 bundler，常见用法是：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;bun build ./src/index.ts --outdir ./dist
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;它可以用于前端包、后端脚本、CLI 工具和库构建。Bun 文档里还覆盖了 loaders、plugins、macros、CSS、HTML、HMR、minifier、single-file executable 等方向。&lt;/p&gt;
&lt;p&gt;适合优先尝试的场景：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;小型前端工具。&lt;/li&gt;
&lt;li&gt;Node.js CLI。&lt;/li&gt;
&lt;li&gt;内部脚本。&lt;/li&gt;
&lt;li&gt;单文件服务。&lt;/li&gt;
&lt;li&gt;不依赖复杂 webpack loader 的项目。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;谨慎迁移的场景：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;复杂 webpack 插件链。&lt;/li&gt;
&lt;li&gt;大量 Vite 插件。&lt;/li&gt;
&lt;li&gt;深度依赖 Babel 转换。&lt;/li&gt;
&lt;li&gt;特殊 CSS / asset pipeline。&lt;/li&gt;
&lt;li&gt;微前端和模块联邦。&lt;/li&gt;
&lt;li&gt;对构建产物 hash、chunk、兼容性要求很细的项目。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Bun bundler 很有吸引力，但构建工具迁移的风险通常比包管理更高，最好单独验证。&lt;/p&gt;
&lt;h2 id=&#34;运行-http-服务&#34;&gt;运行 HTTP 服务
&lt;/h2&gt;&lt;p&gt;Bun 提供 &lt;code&gt;Bun.serve&lt;/code&gt; 来写 HTTP 服务：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;6
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-ts&#34; data-lang=&#34;ts&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nx&#34;&gt;Bun&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;serve&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;({&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nx&#34;&gt;port&lt;/span&gt;: &lt;span class=&#34;kt&#34;&gt;3000&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nx&#34;&gt;fetch&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;req&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;new&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;Response&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;Hello from Bun&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;p&#34;&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;})&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;这对小型 API、内部服务、Webhook receiver、边缘风格服务很方便。Bun 还提供 WebSockets、Workers、Streams、SQLite、PostgreSQL、Redis、S3、TCP/UDP sockets 等 API。&lt;/p&gt;
&lt;p&gt;但如果你已有 Express、Fastify、NestJS、Next.js、Hono、Elysia 等框架，也可以先看它们在 Bun 上的兼容程度，不必为了用 Bun 就重写服务。&lt;/p&gt;
&lt;p&gt;更现实的路径是：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;先用 Bun 做开发脚本和包管理。&lt;/li&gt;
&lt;li&gt;再用 Bun 跑测试。&lt;/li&gt;
&lt;li&gt;最后评估是否把运行时切到 Bun。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;运行时迁移最需要谨慎，因为它直接影响生产服务行为。&lt;/p&gt;
&lt;h2 id=&#34;和-nodejs-的关系&#34;&gt;和 Node.js 的关系
&lt;/h2&gt;&lt;p&gt;Bun 的目标之一是作为 Node.js 的 drop-in replacement，但“兼容”不是“完全等同”。&lt;/p&gt;
&lt;p&gt;Node.js 生态已经积累了很多年，很多包依赖细微行为：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;CJS / ESM 互操作。&lt;/li&gt;
&lt;li&gt;Node 内置模块。&lt;/li&gt;
&lt;li&gt;原生扩展。&lt;/li&gt;
&lt;li&gt;npm lifecycle scripts。&lt;/li&gt;
&lt;li&gt;文件系统边缘行为。&lt;/li&gt;
&lt;li&gt;stream 和 Buffer 细节。&lt;/li&gt;
&lt;li&gt;worker / child_process。&lt;/li&gt;
&lt;li&gt;调试和 profiling。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Bun 在兼容性上进步很快，但生产迁移仍要以测试结果为准。&lt;/p&gt;
&lt;p&gt;比较稳妥的判断方式：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;你的测试能否在 Bun 下通过。&lt;/li&gt;
&lt;li&gt;关键依赖是否支持 Bun。&lt;/li&gt;
&lt;li&gt;构建产物是否一致。&lt;/li&gt;
&lt;li&gt;CI 和本地表现是否一致。&lt;/li&gt;
&lt;li&gt;线上运行是否有监控和回滚。&lt;/li&gt;
&lt;li&gt;Docker 镜像和部署脚本是否稳定。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;如果只是替换包管理器，风险较低；如果替换生产运行时，风险高很多。&lt;/p&gt;
&lt;h2 id=&#34;适合哪些项目&#34;&gt;适合哪些项目
&lt;/h2&gt;&lt;p&gt;Bun 很适合这些场景：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;新的 JavaScript / TypeScript 小项目。&lt;/li&gt;
&lt;li&gt;内部工具和脚本。&lt;/li&gt;
&lt;li&gt;CLI 项目。&lt;/li&gt;
&lt;li&gt;需要快速安装依赖的 CI。&lt;/li&gt;
&lt;li&gt;希望减少工具链复杂度的前端项目。&lt;/li&gt;
&lt;li&gt;对启动速度敏感的脚本和服务。&lt;/li&gt;
&lt;li&gt;想用 TypeScript 开箱即跑的开发者。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;暂时要谨慎的场景：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;超大型 monorepo。&lt;/li&gt;
&lt;li&gt;深度绑定 pnpm workspace 行为的项目。&lt;/li&gt;
&lt;li&gt;依赖大量 Node.js 原生扩展的服务。&lt;/li&gt;
&lt;li&gt;构建链路高度定制的前端工程。&lt;/li&gt;
&lt;li&gt;对生产运行时一致性要求极高的后端。&lt;/li&gt;
&lt;li&gt;依赖 Jest 复杂生态的测试套件。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;一个保守但实用的策略是：先把 Bun 当作开发工具，而不是马上替代全部生产运行时。&lt;/p&gt;
&lt;h2 id=&#34;迁移建议&#34;&gt;迁移建议
&lt;/h2&gt;&lt;p&gt;如果想在现有项目试 Bun，可以按这个顺序：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;在本地安装 Bun。&lt;/li&gt;
&lt;li&gt;运行 &lt;code&gt;bun install&lt;/code&gt;，观察依赖安装结果。&lt;/li&gt;
&lt;li&gt;提交或暂存 &lt;code&gt;bun.lock&lt;/code&gt;，避免和原 lockfile 混用造成混乱。&lt;/li&gt;
&lt;li&gt;尝试 &lt;code&gt;bun run &amp;lt;script&amp;gt;&lt;/code&gt; 跑常用脚本。&lt;/li&gt;
&lt;li&gt;用 &lt;code&gt;bun test&lt;/code&gt; 迁移少量测试。&lt;/li&gt;
&lt;li&gt;在 CI 加一个非阻塞 Bun job。&lt;/li&gt;
&lt;li&gt;确认没有兼容问题后，再考虑替换主安装流程。&lt;/li&gt;
&lt;li&gt;最后再评估生产运行时是否切换。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;对于团队项目，最好保留回滚路径：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;迁移前保留原 npm / pnpm / yarn 流程。&lt;/li&gt;
&lt;li&gt;CI 里同时跑一段时间。&lt;/li&gt;
&lt;li&gt;不要在同一次改动里同时换运行时、包管理器、测试框架和打包器。&lt;/li&gt;
&lt;li&gt;把迁移拆成小步骤，每一步都有可验证收益。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;这样做虽然慢一点，但不容易把问题混在一起。&lt;/p&gt;
&lt;h2 id=&#34;常见命令速查&#34;&gt;常见命令速查
&lt;/h2&gt;&lt;p&gt;安装：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;curl -fsSL https://bun.com/install &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt; bash
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;升级：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;bun upgrade
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;安装依赖：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;bun install
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;添加依赖：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;bun add lodash
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;运行脚本：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;bun run dev
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;直接运行 TypeScript：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;bun run scripts/build.ts
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;测试：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;bun &lt;span class=&#34;nb&#34;&gt;test&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;打包：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;bun build ./src/index.ts --outdir ./dist
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;执行包命令：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;bunx cowsay &lt;span class=&#34;s1&#34;&gt;&amp;#39;Hello, world!&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h2 id=&#34;总结&#34;&gt;总结
&lt;/h2&gt;&lt;p&gt;Bun 的价值不只是“比 Node.js 快”。更重要的是，它把 JavaScript / TypeScript 开发里一堆分散工具收进了一个 &lt;code&gt;bun&lt;/code&gt; 命令：运行时、包管理器、脚本运行器、测试运行器和打包器。&lt;/p&gt;
&lt;p&gt;对新项目和内部工具来说，这种一体化体验很舒服：安装快、启动快、配置少，TypeScript 和 JSX 也能直接跑。对已有大型项目来说，Bun 更适合先从低风险环节切入，比如包安装、脚本和部分测试，再逐步验证构建和运行时。&lt;/p&gt;
&lt;p&gt;如果你经常被 Node.js 工具链里的安装速度、配置碎片和测试启动时间折磨，Bun 值得认真试一下。但真正迁移生产服务时，还是要回到最朴素的工程判断：测试能不能过、依赖是否兼容、CI 是否稳定、线上有没有回滚。&lt;/p&gt;
&lt;p&gt;参考链接：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://github.com/oven-sh/bun&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;oven-sh/bun&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://bun.com/docs&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Bun Documentation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://bun.com/docs/installation&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Bun Installation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://bun.com/docs/runtime/nodejs-compat&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Bun Node.js compatibility&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
        </item>
        <item>
        <title>Godot 游戏开发入门：从节点、场景到第一个 2D 小游戏</title>
        <link>https://knightli.com/2026/05/17/godot-game-development-beginner-guide/</link>
        <pubDate>Sun, 17 May 2026 12:37:30 +0800</pubDate>
        
        <guid>https://knightli.com/2026/05/17/godot-game-development-beginner-guide/</guid>
        <description>&lt;p&gt;Godot 是一款开源游戏引擎，适合从 2D 小游戏、独立游戏原型，到中等规模的 3D 项目开发。&lt;/p&gt;
&lt;p&gt;它最大的特点是轻量、开源、启动快，节点和场景系统非常清晰。对新手来说，Godot 的门槛通常比 Unity 低；对独立开发者来说，它不绑定商业授权模式，也更容易做出可控的小项目。&lt;/p&gt;
&lt;p&gt;这篇文章用最少概念把 Godot 的入门路线讲清楚：你先理解节点和场景，再学 GDScript，最后用一个 2D 小游戏把输入、物理、碰撞、UI、音效和导出串起来。&lt;/p&gt;
&lt;h2 id=&#34;先说结论&#34;&gt;先说结论
&lt;/h2&gt;&lt;p&gt;Godot 入门不要一上来就学大而全的引擎功能。&lt;/p&gt;
&lt;p&gt;更合理的路线是：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;先做 2D，不急着做 3D。&lt;/li&gt;
&lt;li&gt;先理解节点和场景，不急着写复杂架构。&lt;/li&gt;
&lt;li&gt;先学 GDScript，不急着上 C#。&lt;/li&gt;
&lt;li&gt;先做一个能跑、能失败、能重开的小游戏。&lt;/li&gt;
&lt;li&gt;再逐步补动画、音效、UI、关卡和导出。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;只要做完一个完整小项目，你对 Godot 的理解会比刷十几个零散教程更稳。&lt;/p&gt;
&lt;h2 id=&#34;godot-适合什么人&#34;&gt;Godot 适合什么人
&lt;/h2&gt;&lt;p&gt;Godot 很适合这几类人：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;想从零开始学游戏开发。&lt;/li&gt;
&lt;li&gt;想做 2D 独立游戏。&lt;/li&gt;
&lt;li&gt;想快速做玩法原型。&lt;/li&gt;
&lt;li&gt;不想被复杂商业引擎工具链压住。&lt;/li&gt;
&lt;li&gt;想理解游戏引擎底层组织方式。&lt;/li&gt;
&lt;li&gt;有一点 Python / JavaScript 经验，想快速上手脚本。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;如果你的目标是大型 3A 画面、复杂商业团队管线、现成资产商店生态，Unity 或 Unreal 可能仍然更成熟。但如果目标是学习和做自己的游戏，Godot 非常适合起步。&lt;/p&gt;
&lt;h2 id=&#34;安装和项目创建&#34;&gt;安装和项目创建
&lt;/h2&gt;&lt;p&gt;Godot 的安装很简单。&lt;/p&gt;
&lt;p&gt;到官网下载安装包，解压后直接运行即可。它不像很多大型引擎那样必须先装完整启动器，也不需要复杂账号流程。&lt;/p&gt;
&lt;p&gt;新建项目时，建议先选：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Renderer：默认即可。&lt;/li&gt;
&lt;li&gt;Project Name：用英文短横线或下划线。&lt;/li&gt;
&lt;li&gt;路径：不要放在中文或空格特别多的目录里。&lt;/li&gt;
&lt;li&gt;版本管理：建议从一开始就用 Git。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;第一个项目可以叫：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;first-godot-game
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;项目创建后，Godot 会进入编辑器。你需要先熟悉几个区域：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Scene：当前场景的节点树。&lt;/li&gt;
&lt;li&gt;FileSystem：项目资源目录。&lt;/li&gt;
&lt;li&gt;Inspector：选中节点的属性面板。&lt;/li&gt;
&lt;li&gt;Script：脚本编辑区。&lt;/li&gt;
&lt;li&gt;2D / 3D 视图：编辑画面和对象位置。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;godot-的核心节点和场景&#34;&gt;Godot 的核心：节点和场景
&lt;/h2&gt;&lt;p&gt;Godot 最重要的概念只有两个：节点和场景。&lt;/p&gt;
&lt;p&gt;节点是功能单元。比如：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;Node2D&lt;/code&gt;：2D 对象基础节点。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Sprite2D&lt;/code&gt;：显示图片。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;CollisionShape2D&lt;/code&gt;：碰撞形状。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;CharacterBody2D&lt;/code&gt;：可移动角色。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Camera2D&lt;/code&gt;：2D 摄像机。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;AudioStreamPlayer&lt;/code&gt;：播放音频。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Label&lt;/code&gt;：显示文字。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;场景是一组节点的组合。一个角色可以是一个场景，一个敌人可以是一个场景，一个关卡也可以是一个场景。&lt;/p&gt;
&lt;p&gt;比如一个玩家角色场景可能长这样：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Player (CharacterBody2D)
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;├── Sprite2D
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;├── CollisionShape2D
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;└── Camera2D
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;这棵树的意思是：玩家本体负责移动，&lt;code&gt;Sprite2D&lt;/code&gt; 负责显示角色图片，&lt;code&gt;CollisionShape2D&lt;/code&gt; 负责碰撞，&lt;code&gt;Camera2D&lt;/code&gt; 跟随玩家。&lt;/p&gt;
&lt;p&gt;Godot 的思路就是：把游戏拆成很多可复用场景，再把场景组合成完整游戏。&lt;/p&gt;
&lt;h2 id=&#34;第一个-2d-项目做什么&#34;&gt;第一个 2D 项目做什么
&lt;/h2&gt;&lt;p&gt;新手第一个项目不要做 RPG、开放世界、联机游戏或复杂平台跳跃。&lt;/p&gt;
&lt;p&gt;建议做一个最小 2D 闪避游戏：&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;/ul&gt;
&lt;p&gt;这个项目很小，但能覆盖 Godot 入门最重要的东西：&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;UI 显示。&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;h2 id=&#34;玩家移动怎么写&#34;&gt;玩家移动怎么写
&lt;/h2&gt;&lt;p&gt;在 Godot 里，玩家角色通常用 &lt;code&gt;CharacterBody2D&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;给 &lt;code&gt;Player&lt;/code&gt; 节点挂一个脚本：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;12
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;13
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-gdscript&#34; data-lang=&#34;gdscript&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kd&#34;&gt;extends&lt;/span&gt; &lt;span class=&#34;nc&#34;&gt;CharacterBody2D&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nd&#34;&gt;@export&lt;/span&gt; &lt;span class=&#34;kd&#34;&gt;var&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;speed&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;:=&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;300.0&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kd&#34;&gt;func&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;_physics_process&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;delta&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;kd&#34;&gt;var&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;direction&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;:=&lt;/span&gt; &lt;span class=&#34;nc&#34;&gt;Vector2&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ZERO&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;direction&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;x&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nc&#34;&gt;Input&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;get_axis&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;move_left&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;move_right&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;direction&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;y&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nc&#34;&gt;Input&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;get_axis&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;move_up&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;move_down&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;direction&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;direction&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;normalized&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;velocity&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;direction&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;*&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;speed&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nf&#34;&gt;move_and_slide&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&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;code&gt;velocity&lt;/code&gt;。&lt;/li&gt;
&lt;li&gt;用 &lt;code&gt;move_and_slide()&lt;/code&gt; 让角色移动并处理碰撞。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;还需要在 Project Settings 里设置输入：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;move_left  -&amp;gt; A / Left
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;move_right -&amp;gt; D / Right
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;move_up    -&amp;gt; W / Up
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;move_down  -&amp;gt; S / Down
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;Godot 的输入系统建议一开始就用 action，不要在代码里直接写死键盘按键。这样以后支持手柄、触屏或改键会方便很多。&lt;/p&gt;
&lt;h2 id=&#34;碰撞和物理怎么理解&#34;&gt;碰撞和物理怎么理解
&lt;/h2&gt;&lt;p&gt;Godot 的碰撞不是只靠图片大小判断，而是靠碰撞形状。&lt;/p&gt;
&lt;p&gt;常用节点有：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;CollisionShape2D&lt;/code&gt;：给角色或敌人定义碰撞范围。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Area2D&lt;/code&gt;：检测进入、离开、重叠，适合触发器。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;CharacterBody2D&lt;/code&gt;：适合玩家和会移动的角色。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;RigidBody2D&lt;/code&gt;：适合受物理力影响的物体。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;StaticBody2D&lt;/code&gt;：适合墙、地面、固定障碍。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;入门阶段记住一个原则：&lt;/p&gt;
&lt;p&gt;如果你要自己控制角色移动，用 &lt;code&gt;CharacterBody2D&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;如果你只想检测“玩家碰到敌人”，敌人可以用 &lt;code&gt;Area2D&lt;/code&gt;，再监听信号：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-gdscript&#34; data-lang=&#34;gdscript&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kd&#34;&gt;func&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;_on_body_entered&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;body&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;body&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;name&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;==&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;Player&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;nf&#34;&gt;get_tree&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;reload_current_scene&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;后面项目变复杂时，可以改成发送 &lt;code&gt;game_over&lt;/code&gt; 信号，而不是直接重载场景。新手阶段先跑通逻辑更重要。&lt;/p&gt;
&lt;h2 id=&#34;场景实例化让敌人不断出现&#34;&gt;场景实例化：让敌人不断出现
&lt;/h2&gt;&lt;p&gt;Godot 的场景可以当成“预制体”使用。&lt;/p&gt;
&lt;p&gt;假设你有一个 &lt;code&gt;Enemy.tscn&lt;/code&gt;，可以在主场景里用脚本生成它：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;6
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-gdscript&#34; data-lang=&#34;gdscript&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nd&#34;&gt;@export&lt;/span&gt; &lt;span class=&#34;kd&#34;&gt;var&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;enemy_scene&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nc&#34;&gt;PackedScene&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kd&#34;&gt;func&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;spawn_enemy&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;():&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;kd&#34;&gt;var&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;enemy&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;enemy_scene&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;instantiate&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;enemy&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;position&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nc&#34;&gt;Vector2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;800&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;randf_range&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;50&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;550&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nf&#34;&gt;add_child&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;enemy&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;再配合 &lt;code&gt;Timer&lt;/code&gt; 节点，每隔一段时间调用一次 &lt;code&gt;spawn_enemy()&lt;/code&gt;，敌人就会不断生成。&lt;/p&gt;
&lt;p&gt;这就是 Godot 项目常见组织方式：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;一个场景负责一种对象。&lt;/li&gt;
&lt;li&gt;主场景负责调度和组合。&lt;/li&gt;
&lt;li&gt;需要时动态实例化子场景。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;ui-和分数&#34;&gt;UI 和分数
&lt;/h2&gt;&lt;p&gt;Godot 的 UI 使用 &lt;code&gt;Control&lt;/code&gt; 系列节点。&lt;/p&gt;
&lt;p&gt;常用节点包括：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;CanvasLayer&lt;/code&gt;：让 UI 固定在屏幕上，不跟随相机移动。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Label&lt;/code&gt;：显示文字。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Button&lt;/code&gt;：按钮。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Panel&lt;/code&gt;：面板背景。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;VBoxContainer&lt;/code&gt; / &lt;code&gt;HBoxContainer&lt;/code&gt;：自动排版。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;分数可以先用存活时间来做：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;5
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-gdscript&#34; data-lang=&#34;gdscript&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kd&#34;&gt;var&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;score&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;:=&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.0&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kd&#34;&gt;func&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;_process&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;delta&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;score&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;delta&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nx&#34;&gt;$CanvasLayer/ScoreLabel&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;text&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;str&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;score&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;这样每秒增加 1 分。后面可以改成击败敌人、收集金币或完成关卡加分。&lt;/p&gt;
&lt;h2 id=&#34;音效和反馈&#34;&gt;音效和反馈
&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;li&gt;得分音效。&lt;/li&gt;
&lt;li&gt;失败音效。&lt;/li&gt;
&lt;li&gt;屏幕震动或闪烁。&lt;/li&gt;
&lt;li&gt;按钮 hover / pressed 状态。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Godot 里可以用 &lt;code&gt;AudioStreamPlayer&lt;/code&gt; 播放音效：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-gdscript&#34; data-lang=&#34;gdscript&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nx&#34;&gt;$HitSound&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;play&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;新手常犯的错误是只做功能，不做反馈。功能能跑只是第一步，玩家能不能感到“我做了一个动作，游戏回应了我”，才是游戏体验的开始。&lt;/p&gt;
&lt;h2 id=&#34;文件怎么组织&#34;&gt;文件怎么组织
&lt;/h2&gt;&lt;p&gt;项目一开始就建议整理目录：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;12
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;13
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;res://
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;├── scenes/
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;│   ├── Main.tscn
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;│   ├── Player.tscn
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;│   └── Enemy.tscn
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;├── scripts/
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;│   ├── player.gd
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;│   └── enemy.gd
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;├── assets/
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;│   ├── sprites/
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;│   └── audio/
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;└── ui/
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    └── GameOver.tscn
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;不要把所有资源都丢在根目录。小游戏阶段无所谓，项目稍微大一点就会混乱。&lt;/p&gt;
&lt;p&gt;一个简单原则是：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;场景放 &lt;code&gt;scenes/&lt;/code&gt;。&lt;/li&gt;
&lt;li&gt;脚本放 &lt;code&gt;scripts/&lt;/code&gt;。&lt;/li&gt;
&lt;li&gt;图片和音频放 &lt;code&gt;assets/&lt;/code&gt;。&lt;/li&gt;
&lt;li&gt;UI 单独放 &lt;code&gt;ui/&lt;/code&gt;。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;godot-新手常见坑&#34;&gt;Godot 新手常见坑
&lt;/h2&gt;&lt;p&gt;第一个坑：节点选错。&lt;/p&gt;
&lt;p&gt;能自己控制移动的角色用 &lt;code&gt;CharacterBody2D&lt;/code&gt;，不是随便用 &lt;code&gt;Node2D&lt;/code&gt;。触发检测用 &lt;code&gt;Area2D&lt;/code&gt;，固定障碍用 &lt;code&gt;StaticBody2D&lt;/code&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;code&gt;KEY_A&lt;/code&gt;，用输入 action。&lt;/p&gt;
&lt;p&gt;第四个坑：场景职责混乱。&lt;/p&gt;
&lt;p&gt;不要让一个脚本同时管玩家、敌人、UI、音效和关卡。新手可以简单，但不要所有东西都堆在 &lt;code&gt;Main.gd&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;第五个坑：一开始就做大项目。&lt;/p&gt;
&lt;p&gt;第一个项目越小越好。只要完整，有开始、有失败、有重新开始，就比半途而废的大项目更有价值。&lt;/p&gt;
&lt;h2 id=&#34;推荐学习路线&#34;&gt;推荐学习路线
&lt;/h2&gt;&lt;p&gt;可以按这个顺序学：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;编辑器基本操作。&lt;/li&gt;
&lt;li&gt;节点和场景。&lt;/li&gt;
&lt;li&gt;GDScript 基础。&lt;/li&gt;
&lt;li&gt;输入系统。&lt;/li&gt;
&lt;li&gt;2D 角色移动。&lt;/li&gt;
&lt;li&gt;碰撞和 Area2D。&lt;/li&gt;
&lt;li&gt;Timer 和动态生成。&lt;/li&gt;
&lt;li&gt;UI 和分数。&lt;/li&gt;
&lt;li&gt;音效和动画。&lt;/li&gt;
&lt;li&gt;导出桌面或 Web 版本。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;不要一开始就钻源码，也不要马上学渲染管线、Shader、多人联机、复杂 AI。先把一个小项目做完，很多概念自然会有位置。&lt;/p&gt;
&lt;h2 id=&#34;godot-和-unity-怎么选&#34;&gt;Godot 和 Unity 怎么选
&lt;/h2&gt;&lt;p&gt;如果你主要做 2D 独立游戏、教学项目、个人原型，Godot 非常舒服。&lt;/p&gt;
&lt;p&gt;如果你需要庞大的资产商店、成熟商业插件、移动广告和商业化 SDK、成熟团队经验，Unity 生态仍然更强。&lt;/p&gt;
&lt;p&gt;如果你要做高规格 3D、复杂渲染、影视级画面，Unreal 更适合。&lt;/p&gt;
&lt;p&gt;对新手来说，不要把选引擎变成拖延。Godot 足够你做出大量完整小游戏。你真正需要先学会的是：&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;/ul&gt;
&lt;p&gt;这些能力换到其他引擎也能用。&lt;/p&gt;
&lt;h2 id=&#34;第一个项目的完成标准&#34;&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;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;li&gt;能导出一个可运行版本。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;做到这里，你就不是“打开过 Godot”，而是真的完成了一个游戏闭环。&lt;/p&gt;
&lt;h2 id=&#34;总结&#34;&gt;总结
&lt;/h2&gt;&lt;p&gt;Godot 入门的关键，不是把所有功能看一遍，而是先理解它的组织方式：节点组成场景，场景组成游戏，脚本驱动行为，信号连接事件，资源通过目录管理。&lt;/p&gt;
&lt;p&gt;第一个项目建议从 2D 小游戏开始。玩家移动、敌人生成、碰撞失败、UI 分数、音效反馈、重新开始，这几个环节跑通之后，再去学动画树、TileMap、存档、状态机、3D、Shader 和导出优化。&lt;/p&gt;
&lt;p&gt;游戏开发不是先学完引擎再开始做，而是在做小项目的过程中反复补概念。Godot 的优势正好在这里：它足够轻，能让你很快从“想做游戏”走到“真的跑起来”。&lt;/p&gt;
</description>
        </item>
        <item>
        <title>Ghostty 文档速读：安装、配置与日常使用要点</title>
        <link>https://knightli.com/2026/05/15/ghostty-docs-install-config-usage-guide/</link>
        <pubDate>Fri, 15 May 2026 14:50:11 +0800</pubDate>
        
        <guid>https://knightli.com/2026/05/15/ghostty-docs-install-config-usage-guide/</guid>
        <description>&lt;p&gt;Ghostty 是一个新的终端模拟器，但它并不只是“又一个更快的终端”。按照官方文档的说法，它想同时兼顾三个方向：速度、功能和原生桌面体验。也就是说，它既希望有 GPU 加速和较好的渲染性能，也希望在 macOS 和 Linux 上尽量像一个真正的本地应用，而不是把所有交互都塞进自绘界面里。&lt;/p&gt;
&lt;p&gt;如果你正在用 iTerm2、Kitty、Alacritty、WezTerm 或系统自带终端，Ghostty 最值得关注的地方不是某一个单点功能，而是它把“开箱即用”和“深度可配置”放在了一起。默认配置已经能直接使用；想继续折腾时，文档又给了配置文件、主题、快捷键、字体、Shell 集成和终端控制序列等完整入口。&lt;/p&gt;
&lt;h2 id=&#34;先看定位&#34;&gt;先看定位
&lt;/h2&gt;&lt;p&gt;Ghostty 的核心定位可以概括为三句话：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;它是跨平台终端模拟器，目前重点覆盖 macOS 和 Linux。&lt;/li&gt;
&lt;li&gt;它使用平台原生 UI：macOS 端使用 Swift、AppKit 和 SwiftUI，Linux 端使用 Zig 和 GTK4。&lt;/li&gt;
&lt;li&gt;它的终端核心是 &lt;code&gt;libghostty&lt;/code&gt;，GUI 应用围绕这个共享核心构建。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;这个设计会影响日常体验。比如标签页、分屏、错误提示、窗口状态恢复、系统快捷键等能力，不是简单做成“看起来像桌面应用”的组件，而是尽量贴近所在系统的交互习惯。macOS 和 Linux 默认快捷键也会按各自平台约定区分。&lt;/p&gt;
&lt;h2 id=&#34;安装方式macos-最直接linux-看发行版&#34;&gt;安装方式：macOS 最直接，Linux 看发行版
&lt;/h2&gt;&lt;p&gt;官方预构建二进制主要面向 macOS。最普通的安装方式是下载 &lt;code&gt;.dmg&lt;/code&gt;，打开后把 Ghostty 拖到 Applications 目录。Homebrew 用户也可以用社区维护的 cask：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;brew install --cask ghostty
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;Linux 的情况更分散。Ghostty 文档把不同发行版的包管理器、社区二进制和源码构建分开说明。Arch、Alpine、Gentoo、NixOS、Snap、Solus、Void 等都有对应路径；如果发行版没有官方或可信仓库，文档更倾向于让用户从源码构建，而不是随意安装第三方二进制。&lt;/p&gt;
&lt;p&gt;这点对服务器和工作机尤其重要：终端模拟器会处理大量输入输出、剪贴板、链接、SSH 会话和本地文件路径。安装源最好保守一点，优先选官方 macOS 包、发行版仓库或自己能审计来源的构建流程。&lt;/p&gt;
&lt;h2 id=&#34;配置先别急着复制一大份-dotfiles&#34;&gt;配置：先别急着复制一大份 dotfiles
&lt;/h2&gt;&lt;p&gt;Ghostty 的配置哲学是“零配置可用”。默认字体内置 JetBrains Mono，也带有 Nerd Font 支持；大多数用户第一次打开就能正常工作。文档甚至建议，如果你发现必须配置某个非主观选项才舒服，可以先考虑它是不是应该成为默认行为。&lt;/p&gt;
&lt;p&gt;真正需要定制时，Ghostty 使用文本配置文件。当前配置文件名是 &lt;code&gt;config.ghostty&lt;/code&gt;，旧版本也支持 &lt;code&gt;config&lt;/code&gt;。常见路径包括：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;$XDG_CONFIG_HOME/ghostty/config.ghostty
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;$XDG_CONFIG_HOME/ghostty/config
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;$HOME/.config/ghostty/config.ghostty
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;$HOME/.config/ghostty/config
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;macOS 还会读取：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;$HOME/Library/Application Support/com.mitchellh.ghostty/config.ghostty
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;$HOME/Library/Application Support/com.mitchellh.ghostty/config
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;配置语法非常直接，就是 &lt;code&gt;key = value&lt;/code&gt;。例如：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;font-family = JetBrains Mono
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;font-size = 14
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;theme = light:Rose Pine Dawn,dark:Rose Pine
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;keybind = ctrl+shift+t=new_tab
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;一个实用建议是：不要一开始就找别人的完整配置照抄。更稳的方式是先裸跑几天，只改三类东西：字体、字号和主题。等你真的发现快捷键、分屏、窗口、Shell 集成有摩擦，再逐项加配置。&lt;/p&gt;
&lt;h2 id=&#34;文档查询本地也能查完整配置&#34;&gt;文档查询：本地也能查完整配置
&lt;/h2&gt;&lt;p&gt;Ghostty 的配置项很多，官方文档把它们集中在 Option Reference。除了网页，安装后也可以从本地查配置参考：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;ghostty +show-config --default --docs
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;这个命令会把默认配置和文档输出到标准输出，适合接到分页器里慢慢搜：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;ghostty +show-config --default --docs &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt; less
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;查看可用字体时可以用：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;ghostty +list-fonts
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;查看内置和可用主题时可以用：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;ghostty +list-themes
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;查看默认快捷键时可以用：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;ghostty +list-keybinds --default
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;这些命令比在网上复制片段更可靠，因为它们来自你当前安装的 Ghostty 版本。&lt;/p&gt;
&lt;h2 id=&#34;快捷键把动作当成核心概念&#34;&gt;快捷键：把“动作”当成核心概念
&lt;/h2&gt;&lt;p&gt;Ghostty 的快捷键配置格式是：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;keybind = trigger=action
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;&lt;code&gt;trigger&lt;/code&gt; 是按键触发方式，&lt;code&gt;action&lt;/code&gt; 是 Ghostty 执行的动作。比如新建标签页、关闭当前 surface、重新加载配置、跳转到提示符等，都属于 action。这个模型的好处是清晰：你不是在“改某个菜单项”，而是在把一个输入序列绑定到一个动作。&lt;/p&gt;
&lt;p&gt;配置改完后，可以在运行时重新加载。默认快捷键是：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Linux：&lt;code&gt;ctrl+shift+,&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;macOS：&lt;code&gt;cmd+shift+,&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;不过并不是所有配置都能即时生效。有些选项只影响新建终端，有些需要完整重启。遇到“配置写了但没变化”时，先查对应选项说明，比反复怀疑语法更省时间。&lt;/p&gt;
&lt;h2 id=&#34;主题和字体先用内置再做细调&#34;&gt;主题和字体：先用内置，再做细调
&lt;/h2&gt;&lt;p&gt;Ghostty 自带大量主题，并支持按系统浅色、深色模式切换不同主题：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;theme = light:Rose Pine Dawn,dark:Rose Pine
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;主题也可以来自自定义文件。文档提醒得很明确：主题文件本质上也是 Ghostty 配置文件，可以设置很多配置项，所以不要随便使用不可信来源的主题。&lt;/p&gt;
&lt;p&gt;字体方面，&lt;code&gt;font-family&lt;/code&gt; 可以重复多次，用来指定 fallback 字体。对多语言环境很实用，比如主字体负责英文和符号，后续字体补中文、日文或其他字符。遇到 emoji、粗体、斜体、连字等显示细节时，再去 Option Reference 里查对应选项即可。&lt;/p&gt;
&lt;h2 id=&#34;shell-集成ssh-用户尤其应该看&#34;&gt;Shell 集成：SSH 用户尤其应该看
&lt;/h2&gt;&lt;p&gt;Ghostty 支持自动注入 shell integration，覆盖 &lt;code&gt;bash&lt;/code&gt;、&lt;code&gt;elvish&lt;/code&gt;、&lt;code&gt;fish&lt;/code&gt;、&lt;code&gt;nushell&lt;/code&gt; 和 &lt;code&gt;zsh&lt;/code&gt;。启用后，一些体验会更自然，比如：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;新终端从前一个终端的工作目录打开。&lt;/li&gt;
&lt;li&gt;复杂提示符 resize 时可以重绘，而不是被错误回流。&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;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;shell-integration = none
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;更值得注意的是 SSH。Ghostty 使用 &lt;code&gt;xterm-ghostty&lt;/code&gt; 作为 &lt;code&gt;TERM&lt;/code&gt;，但很多远程主机还没有对应的 terminfo。文档提供了 &lt;code&gt;ssh-env&lt;/code&gt; 和 &lt;code&gt;ssh-terminfo&lt;/code&gt; 两个 shell integration 功能，默认关闭，可以按需启用：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;shell-integration-features = ssh-env,ssh-terminfo
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;如果你经常连接旧服务器、容器、跳板机或严格管理的生产环境，建议先读完官方的 Terminfo 和 Shell Integration 文档，再决定是否启用这些功能。终端能力协商看起来不起眼，但一旦出问题，表现可能是颜色异常、快捷键失灵、全屏程序显示错乱。&lt;/p&gt;
&lt;h2 id=&#34;我的上手顺序&#34;&gt;我的上手顺序
&lt;/h2&gt;&lt;p&gt;如果只是想判断 Ghostty 是否适合自己，可以按这个顺序试：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;安装后不写配置，直接用一天。&lt;/li&gt;
&lt;li&gt;只调整 &lt;code&gt;font-family&lt;/code&gt;、&lt;code&gt;font-size&lt;/code&gt; 和 &lt;code&gt;theme&lt;/code&gt;。&lt;/li&gt;
&lt;li&gt;用 &lt;code&gt;ghostty +list-keybinds --default&lt;/code&gt; 看默认快捷键，而不是先搬运别人的快捷键表。&lt;/li&gt;
&lt;li&gt;如果常用 SSH，优先检查远程主机的 terminfo 兼容问题。&lt;/li&gt;
&lt;li&gt;最后再处理分屏、窗口、透明度、标题栏、背景图等视觉和工作流偏好。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Ghostty 文档写得比较工程化，适合把它当成“配置参考手册”而不是“宣传页”阅读。对多数用户来说，真正的判断标准也很简单：默认体验是否已经舒服，日常编辑器、Shell、SSH、tmux 或 Zellij 是否稳定。如果这几件事都顺，Ghostty 就值得进入你的长期终端候选列表。&lt;/p&gt;
&lt;h2 id=&#34;参考链接&#34;&gt;参考链接
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://ghostty.org/docs&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Ghostty Docs&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://ghostty.org/docs/about&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;About Ghostty&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://ghostty.org/docs/config&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Configuration&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://ghostty.org/docs/config/keybind&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Custom Keybindings&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://ghostty.org/docs/install/binary&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Prebuilt Ghostty Binaries and Packages&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://ghostty.org/docs/features/shell-integration&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Shell Integration&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
        </item>
        <item>
        <title>VS Code 切换界面语言的方法：中文、英文和其他语言</title>
        <link>https://knightli.com/2026/05/08/vscode-switch-display-language/</link>
        <pubDate>Fri, 08 May 2026 13:28:14 +0800</pubDate>
        
        <guid>https://knightli.com/2026/05/08/vscode-switch-display-language/</guid>
        <description>&lt;p&gt;VS Code 支持多种界面语言。常见做法是先安装对应语言包，再通过命令面板选择显示语言；如果需要固定某种语言，也可以手动修改 &lt;code&gt;argv.json&lt;/code&gt; 中的 &lt;code&gt;locale&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;这套方法不仅适用于简体中文，也适用于英文、繁体中文、日文、韩文、法文、德文、西班牙文等语言。&lt;/p&gt;
&lt;h2 id=&#34;安装对应语言包&#34;&gt;安装对应语言包
&lt;/h2&gt;&lt;p&gt;如果要切换到非英文界面，通常需要先安装语言包。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;打开 VS Code 左侧扩展面板，也可以使用快捷键 &lt;code&gt;Ctrl+Shift+X&lt;/code&gt;。&lt;/li&gt;
&lt;li&gt;在搜索框中输入目标语言，例如 &lt;code&gt;Chinese&lt;/code&gt;、&lt;code&gt;Japanese&lt;/code&gt;、&lt;code&gt;Korean&lt;/code&gt;、&lt;code&gt;French&lt;/code&gt;。&lt;/li&gt;
&lt;li&gt;选择对应语言包，点击 &lt;code&gt;Install&lt;/code&gt;。&lt;/li&gt;
&lt;li&gt;安装完成后，按提示重启 VS Code。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;简体中文常用语言包是 &lt;code&gt;Chinese (Simplified)&lt;/code&gt;，繁体中文常用语言包是 &lt;code&gt;Chinese (Traditional)&lt;/code&gt;。&lt;/p&gt;
&lt;h2 id=&#34;通过命令面板切换语言&#34;&gt;通过命令面板切换语言
&lt;/h2&gt;&lt;p&gt;这是最推荐的切换方式，适合大多数用户。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;打开命令面板：&lt;code&gt;Ctrl+Shift+P&lt;/code&gt;。&lt;/li&gt;
&lt;li&gt;输入 &lt;code&gt;Configure Display Language&lt;/code&gt;。&lt;/li&gt;
&lt;li&gt;选择 &lt;code&gt;Configure Display Language&lt;/code&gt; 命令。&lt;/li&gt;
&lt;li&gt;在列表中选择要使用的语言。&lt;/li&gt;
&lt;li&gt;按提示重启 VS Code。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;重启后，菜单、设置页和常见提示会切换到所选语言。如果列表里没有目标语言，先到扩展面板安装对应语言包。&lt;/p&gt;
&lt;h2 id=&#34;通过-argvjson-手动指定语言&#34;&gt;通过 argv.json 手动指定语言
&lt;/h2&gt;&lt;p&gt;如果命令面板切换失败，或者想明确固定显示语言，可以直接修改 VS Code 的运行时参数文件。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;打开命令面板：&lt;code&gt;Ctrl+Shift+P&lt;/code&gt;。&lt;/li&gt;
&lt;li&gt;输入并选择 &lt;code&gt;Preferences: Configure Runtime Arguments&lt;/code&gt;。&lt;/li&gt;
&lt;li&gt;找到或添加 &lt;code&gt;locale&lt;/code&gt; 配置项。&lt;/li&gt;
&lt;li&gt;把值改成目标语言代码。&lt;/li&gt;
&lt;li&gt;保存后重启 VS Code。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;例如切换为英文：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-json&#34; data-lang=&#34;json&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nt&#34;&gt;&amp;#34;locale&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;en&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;切换为简体中文：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-json&#34; data-lang=&#34;json&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nt&#34;&gt;&amp;#34;locale&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;zh-cn&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;切换为日文：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-json&#34; data-lang=&#34;json&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nt&#34;&gt;&amp;#34;locale&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;ja&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;&lt;code&gt;argv.json&lt;/code&gt; 是 JSON 文件，修改时要注意逗号和引号。配置写错时，VS Code 可能无法正确读取语言设置。&lt;/p&gt;
&lt;h2 id=&#34;常用界面语言代码&#34;&gt;常用界面语言代码
&lt;/h2&gt;&lt;table&gt;
  &lt;thead&gt;
      &lt;tr&gt;
          &lt;th&gt;显示语言&lt;/th&gt;
          &lt;th&gt;locale&lt;/th&gt;
      &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
      &lt;tr&gt;
          &lt;td&gt;English (US)&lt;/td&gt;
          &lt;td&gt;&lt;code&gt;en&lt;/code&gt;&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;简体中文&lt;/td&gt;
          &lt;td&gt;&lt;code&gt;zh-cn&lt;/code&gt;&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;繁体中文&lt;/td&gt;
          &lt;td&gt;&lt;code&gt;zh-tw&lt;/code&gt;&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;French&lt;/td&gt;
          &lt;td&gt;&lt;code&gt;fr&lt;/code&gt;&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;German&lt;/td&gt;
          &lt;td&gt;&lt;code&gt;de&lt;/code&gt;&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;Italian&lt;/td&gt;
          &lt;td&gt;&lt;code&gt;it&lt;/code&gt;&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;Spanish&lt;/td&gt;
          &lt;td&gt;&lt;code&gt;es&lt;/code&gt;&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;Japanese&lt;/td&gt;
          &lt;td&gt;&lt;code&gt;ja&lt;/code&gt;&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;Korean&lt;/td&gt;
          &lt;td&gt;&lt;code&gt;ko&lt;/code&gt;&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;Russian&lt;/td&gt;
          &lt;td&gt;&lt;code&gt;ru&lt;/code&gt;&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;Portuguese (Brazil)&lt;/td&gt;
          &lt;td&gt;&lt;code&gt;pt-br&lt;/code&gt;&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;Turkish&lt;/td&gt;
          &lt;td&gt;&lt;code&gt;tr&lt;/code&gt;&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;Bulgarian&lt;/td&gt;
          &lt;td&gt;&lt;code&gt;bg&lt;/code&gt;&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;Hungarian&lt;/td&gt;
          &lt;td&gt;&lt;code&gt;hu&lt;/code&gt;&lt;/td&gt;
      &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id=&#34;语言没有生效怎么办&#34;&gt;语言没有生效怎么办
&lt;/h2&gt;&lt;p&gt;可以按下面顺序排查：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;确认目标语言包已经安装。&lt;/li&gt;
&lt;li&gt;确认 &lt;code&gt;locale&lt;/code&gt; 写的是正确语言代码，例如简体中文是 &lt;code&gt;zh-cn&lt;/code&gt;，不是 &lt;code&gt;zh-CN&lt;/code&gt;。&lt;/li&gt;
&lt;li&gt;修改语言后完整关闭并重新打开 VS Code。&lt;/li&gt;
&lt;li&gt;如果手动改过 &lt;code&gt;argv.json&lt;/code&gt;，检查 JSON 语法是否正确。&lt;/li&gt;
&lt;li&gt;如果配置混乱，可以删除 &lt;code&gt;locale&lt;/code&gt; 项，再通过 &lt;code&gt;Configure Display Language&lt;/code&gt; 重新选择。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;一般来说，通过 &lt;code&gt;Configure Display Language&lt;/code&gt; 切换最省事；只有在需要强制指定语言或命令面板切换不生效时，才建议手动修改 &lt;code&gt;argv.json&lt;/code&gt;。&lt;/p&gt;
&lt;h2 id=&#34;参考资料&#34;&gt;参考资料
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://blog.csdn.net/mighty13/article/details/114420578&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;VScode：将VScode界面的显示语言改为简体中文，切换VScode界面的显示语言&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
        </item>
        <item>
        <title>opencode、Claude Code、Codex 有什么区别？开源 AI 编程工具使用指南</title>
        <link>https://knightli.com/2026/05/08/opencode-open-source-ai-coding-agent/</link>
        <pubDate>Fri, 08 May 2026 08:33:37 +0800</pubDate>
        
        <guid>https://knightli.com/2026/05/08/opencode-open-source-ai-coding-agent/</guid>
        <description>&lt;p&gt;&lt;code&gt;opencode&lt;/code&gt; 是 anomalyco 开源的 AI Coding Agent。它的定位很直接：让开发者在终端里使用一个可编程、可扩展、可接入多家模型的代码助手。&lt;/p&gt;
&lt;p&gt;如果把它和 &lt;code&gt;Claude Code&lt;/code&gt;、&lt;code&gt;Codex&lt;/code&gt; 放在一起看，三者解决的是同一类问题：让 AI 进入真实代码库，理解上下文，修改文件，运行命令和测试。但它们的产品取向不一样。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;opencode&lt;/code&gt; 更强调开源、多模型和终端 TUI；&lt;code&gt;Claude Code&lt;/code&gt; 更强调 Anthropic 模型生态和本地工程协作；&lt;code&gt;Codex&lt;/code&gt; 则是 OpenAI 的 AI coding agent，可以在终端、IDE、Codex app 和云端任务里使用。&lt;/p&gt;
&lt;h2 id=&#34;opencode-适合谁&#34;&gt;opencode 适合谁
&lt;/h2&gt;&lt;p&gt;opencode 更适合这几类开发者：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;想在终端里完成代码修改、项目分析和工程任务的人。&lt;/li&gt;
&lt;li&gt;希望 AI Coding Agent 不绑定单一模型提供商的人。&lt;/li&gt;
&lt;li&gt;偏好开源工具，想自己审计、扩展或二次开发的人。&lt;/li&gt;
&lt;li&gt;已经习惯 Neovim、TUI、命令行工作流的人。&lt;/li&gt;
&lt;li&gt;希望以后用桌面端、移动端或其他客户端远程驱动同一个编码代理的人。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;它的重点不是做一个聊天窗口，而是把 AI 编程能力放进开发者原本使用的终端和项目目录里。&lt;/p&gt;
&lt;h2 id=&#34;安装方式&#34;&gt;安装方式
&lt;/h2&gt;&lt;p&gt;官方 README 提供了多种安装方式。&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;12
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;13
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;14
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;15
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;16
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;17
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;18
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;19
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;20
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;21
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# 直接安装&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;curl -fsSL https://opencode.ai/install &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt; bash
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# npm&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;npm i -g opencode-ai@latest
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# Windows&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;scoop install opencode
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;choco install opencode
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# macOS 和 Linux&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;brew install anomalyco/tap/opencode
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;brew install opencode
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# Arch Linux&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;sudo pacman -S opencode
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;paru -S opencode-bin
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# 其他方式&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;mise use -g opencode
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;nix run nixpkgs#opencode
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;官方也提醒，安装前最好先移除 0.1.x 之前的旧版本，避免旧版本残留造成问题。&lt;/p&gt;
&lt;p&gt;安装脚本会按优先级选择安装目录：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;code&gt;$OPENCODE_INSTALL_DIR&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;$XDG_BIN_DIR&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;$HOME/bin&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;$HOME/.opencode/bin&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;如果需要指定路径，可以这样写：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;OPENCODE_INSTALL_DIR&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;/usr/local/bin curl -fsSL https://opencode.ai/install &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt; bash
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;XDG_BIN_DIR&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$HOME&lt;/span&gt;/.local/bin curl -fsSL https://opencode.ai/install &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt; bash
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h2 id=&#34;桌面应用还在-beta&#34;&gt;桌面应用还在 Beta
&lt;/h2&gt;&lt;p&gt;除了命令行工具，opencode 也提供桌面应用，目前仍处于 Beta。可以从 GitHub Releases 或 &lt;code&gt;opencode.ai/download&lt;/code&gt; 下载。&lt;/p&gt;
&lt;p&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;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
      &lt;tr&gt;
          &lt;td&gt;macOS Apple Silicon&lt;/td&gt;
          &lt;td&gt;&lt;code&gt;opencode-desktop-mac-arm64.dmg&lt;/code&gt;&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;macOS Intel&lt;/td&gt;
          &lt;td&gt;&lt;code&gt;opencode-desktop-mac-x64.dmg&lt;/code&gt;&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;Windows&lt;/td&gt;
          &lt;td&gt;&lt;code&gt;opencode-desktop-windows-x64.exe&lt;/code&gt;&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;Linux&lt;/td&gt;
          &lt;td&gt;&lt;code&gt;.deb&lt;/code&gt;、&lt;code&gt;.rpm&lt;/code&gt; 或 &lt;code&gt;.AppImage&lt;/code&gt;&lt;/td&gt;
      &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;macOS 和 Windows 也可以通过包管理器安装桌面端。&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;6
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# macOS&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;brew install --cask opencode-desktop
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# Windows&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;scoop bucket add extras
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;scoop install extras/opencode-desktop
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h2 id=&#34;两种内置-agent-模式&#34;&gt;两种内置 Agent 模式
&lt;/h2&gt;&lt;p&gt;opencode 内置两种 Agent，可以通过 &lt;code&gt;Tab&lt;/code&gt; 键切换。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;build&lt;/code&gt; 是默认模式，拥有完整开发权限，适合直接修改代码、运行命令和推进工程任务。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;plan&lt;/code&gt; 是只读模式，更适合分析陌生代码库、理解项目结构、制定修改方案。它默认拒绝文件编辑，并且在运行 bash 命令前会询问。&lt;/p&gt;
&lt;p&gt;另外，opencode 还带有一个 &lt;code&gt;general&lt;/code&gt; 子 Agent，用于复杂搜索和多步骤任务。用户可以在消息中输入 &lt;code&gt;@general&lt;/code&gt; 调用。&lt;/p&gt;
&lt;p&gt;这个设计比较实用：真正动手前先用 &lt;code&gt;plan&lt;/code&gt; 看清楚项目，需要改代码时再切到 &lt;code&gt;build&lt;/code&gt;。对于大型仓库，读写权限分开能减少误操作。&lt;/p&gt;
&lt;h2 id=&#34;codex-是什么&#34;&gt;Codex 是什么
&lt;/h2&gt;&lt;p&gt;&lt;code&gt;Codex&lt;/code&gt; 是 OpenAI 的 AI coding agent，用来帮助开发者写代码、审查代码、修复 bug 和交付工程任务。&lt;/p&gt;
&lt;p&gt;和单纯的代码补全工具不同，Codex 更接近一个可以操作代码库的 Agent。它可以在本地工具里和你结对，也可以把任务委托到云端执行。OpenAI 官方资料里提到，Codex 可以通过 CLI、IDE、Codex app、ChatGPT/Codex 云端等不同入口使用。&lt;/p&gt;
&lt;p&gt;对开发者来说，Codex 的重点有几处：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;可以读取代码库、编辑文件、运行命令和测试。&lt;/li&gt;
&lt;li&gt;支持终端、IDE、应用和云端等多种使用界面。&lt;/li&gt;
&lt;li&gt;适合修 bug、写功能、重构、迁移、代码审查和测试补齐。&lt;/li&gt;
&lt;li&gt;更偏 OpenAI 账户、模型和 Codex 产品体系。&lt;/li&gt;
&lt;li&gt;云端任务适合并行处理多个相对清晰的工程任务。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;如果 opencode 更像一个开放的终端代理框架，Codex 更像 OpenAI 提供的一整套 AI 编程工作台：本地可以结对，云端可以委托，团队可以把它接入更长的工程流程。&lt;/p&gt;
&lt;h2 id=&#34;三者核心区别&#34;&gt;三者核心区别
&lt;/h2&gt;&lt;p&gt;opencode、Claude Code、Codex 都是 AI 编程工具，但选择时可以先看这几个维度。&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;&lt;code&gt;opencode&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;开源 AI Coding Agent&lt;/td&gt;
          &lt;td&gt;开源、多模型、TUI、客户端/服务器架构&lt;/td&gt;
          &lt;td&gt;想要开放工具链、可替换模型、偏终端工作流的开发者&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;code&gt;Claude Code&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;Anthropic 的命令行编程工具&lt;/td&gt;
          &lt;td&gt;Claude 模型体验、代码理解、长上下文、工程任务协作&lt;/td&gt;
          &lt;td&gt;已经使用 Claude/Anthropic 生态，希望本地推进代码任务的开发者&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;code&gt;Codex&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;OpenAI 的 AI coding agent&lt;/td&gt;
          &lt;td&gt;CLI、IDE、Codex app、云端任务、多 Agent 工作流&lt;/td&gt;
          &lt;td&gt;已经使用 ChatGPT/OpenAI，希望本地结对和云端委托并用的团队&lt;/td&gt;
      &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;简单说，opencode 的关键词是“开源和可替换”，Claude Code 的关键词是“Claude 生态和本地工程代理”，Codex 的关键词是“OpenAI 生态和多入口协作”。&lt;/p&gt;
&lt;h2 id=&#34;和-claude-code-的区别&#34;&gt;和 Claude Code 的区别
&lt;/h2&gt;&lt;p&gt;opencode 的官方 FAQ 直接把 Claude Code 拿来对比。两者能力上很接近，但差异主要在这几处。&lt;/p&gt;
&lt;p&gt;第一，opencode 是 100% 开源项目，代码托管在 GitHub，并使用 MIT license。&lt;/p&gt;
&lt;p&gt;第二，opencode 不绑定单一模型提供商。它推荐 OpenCode Zen 提供的模型，但也可以搭配 Claude、OpenAI、Google 或本地模型。对开发者来说，这意味着模型成本、能力和可用性变化时，不必被某一个平台锁住。&lt;/p&gt;
&lt;p&gt;第三，opencode 内置可选的 LSP 支持。对代码补全、跳转、诊断和项目理解来说，LSP 是非常关键的基础能力。&lt;/p&gt;
&lt;p&gt;第四，opencode 更强调 TUI。它由 Neovim 用户和 terminal.shop 的创建者打造，产品重心明显放在终端体验上。&lt;/p&gt;
&lt;p&gt;第五，opencode 采用客户端/服务器架构。也就是说，opencode 可以在你的电脑上运行，未来由 TUI、桌面端、移动端或其他客户端来控制。TUI 只是其中一种前端形态。&lt;/p&gt;
&lt;h2 id=&#34;什么时候选-opencodeclaude-code-或-codex&#34;&gt;什么时候选 opencode、Claude Code 或 Codex
&lt;/h2&gt;&lt;p&gt;如果你已经在使用 Claude Code 或 Codex，opencode 不一定是立刻替换它们的工具。更合理的看法是：它提供了一个开源、可替换模型、偏终端的选择。&lt;/p&gt;
&lt;p&gt;可以优先考虑 opencode 的场景包括：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;你希望 AI 编程工具尽量开源。&lt;/li&gt;
&lt;li&gt;你不想把工作流绑定在某个模型供应商上。&lt;/li&gt;
&lt;li&gt;你希望用同一个工具测试 Claude、OpenAI、Google 或本地模型。&lt;/li&gt;
&lt;li&gt;你喜欢 TUI，不希望主要工作流被桌面应用或网页应用打断。&lt;/li&gt;
&lt;li&gt;你关注客户端/服务器架构带来的远程控制能力。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;可以优先考虑 Claude Code 的场景包括：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;你主要使用 Claude 模型。&lt;/li&gt;
&lt;li&gt;你重视长上下文、代码理解和复杂工程任务协作。&lt;/li&gt;
&lt;li&gt;你希望在本地仓库中持续推进修改、测试和重构。&lt;/li&gt;
&lt;li&gt;你更信任 Anthropic 对 Claude Code 的默认产品体验。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;可以优先考虑 Codex 的场景包括：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;你已经在使用 ChatGPT 或 OpenAI 账户体系。&lt;/li&gt;
&lt;li&gt;你希望同一个 coding agent 覆盖终端、IDE、桌面应用和云端任务。&lt;/li&gt;
&lt;li&gt;你想把较清晰的 bug 修复、功能开发、迁移、测试补齐交给云端并行处理。&lt;/li&gt;
&lt;li&gt;你需要代码审查、后台任务、团队协作和多 Agent 工作流。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;如果你更看重官方闭环体验、模型默认配置、企业管理和现成集成，Claude Code 或 Codex 可能更省心；如果你更看重可控性、开放性和 provider-agnostic，opencode 更值得关注。&lt;/p&gt;
&lt;h2 id=&#34;需要注意的地方&#34;&gt;需要注意的地方
&lt;/h2&gt;&lt;p&gt;opencode、Claude Code 和 Codex 都发展很快，GitHub release、安装命令、桌面端文件名、模型可用性和套餐权限都可能变化。实际安装和选型前，最好直接查看各自官方 README、文档和发布页面。&lt;/p&gt;
&lt;p&gt;另外，它的桌面应用仍然标注为 Beta，不适合默认当作稳定生产工具。对于日常工程任务，终端版仍然是更主要的入口。&lt;/p&gt;
&lt;p&gt;从工具趋势看，opencode 代表的是 AI Coding Agent 的开放工具链方向：模型可以替换，客户端可以替换，核心代理能力尽量开放。Codex 和 Claude Code 则更像模型公司把 coding agent 做成完整产品入口。对开发者来说，这两条路线会长期并存。&lt;/p&gt;
&lt;h2 id=&#34;参考链接&#34;&gt;参考链接
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;opencode GitHub：&lt;a class=&#34;link&#34; href=&#34;https://github.com/anomalyco/opencode&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;https://github.com/anomalyco/opencode&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;opencode 官网：&lt;a class=&#34;link&#34; href=&#34;https://opencode.ai&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;https://opencode.ai&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;opencode 文档：&lt;a class=&#34;link&#34; href=&#34;https://opencode.ai/docs&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;https://opencode.ai/docs&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;opencode Releases：&lt;a class=&#34;link&#34; href=&#34;https://github.com/anomalyco/opencode/releases&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;https://github.com/anomalyco/opencode/releases&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;OpenAI Codex：&lt;a class=&#34;link&#34; href=&#34;https://openai.com/codex/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;https://openai.com/codex/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Using Codex with your ChatGPT plan：&lt;a class=&#34;link&#34; href=&#34;https://help.openai.com/en/articles/11369540-codex-in-chatgpt&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;https://help.openai.com/en/articles/11369540-codex-in-chatgpt&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;OpenAI Codex CLI Getting Started：&lt;a class=&#34;link&#34; href=&#34;https://help.openai.com/en/articles/11096431-openai-codex-ci-getting-started&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;https://help.openai.com/en/articles/11096431-openai-codex-ci-getting-started&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
        </item>
        <item>
        <title>uv 安装指南：macOS、Linux、Windows、pipx、Homebrew 和 WinGet 怎么选</title>
        <link>https://knightli.com/2026/05/07/uv-installation-guide/</link>
        <pubDate>Thu, 07 May 2026 23:02:49 +0800</pubDate>
        
        <guid>https://knightli.com/2026/05/07/uv-installation-guide/</guid>
        <description>&lt;p&gt;&lt;code&gt;uv&lt;/code&gt; 是 Astral 推出的 Python 工具链管理器，可以用来管理 Python 版本、虚拟环境、依赖、脚本、项目和工具。它的安装方式很多，官方文档提供了独立安装脚本，也支持 PyPI、Homebrew、WinGet、Scoop、Docker、GitHub Releases 和 Cargo。&lt;/p&gt;
&lt;p&gt;如果只是想快速安装，优先用官方独立安装脚本。如果你希望通过系统包管理器维护版本，就用 Homebrew、WinGet 或 Scoop。如果你已经习惯 Python 工具隔离安装，可以用 &lt;code&gt;pipx&lt;/code&gt;。&lt;/p&gt;
&lt;h2 id=&#34;快速选择&#34;&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;macOS / Linux 快速安装&lt;/td&gt;
          &lt;td&gt;官方独立安装脚本&lt;/td&gt;
          &lt;td&gt;&lt;code&gt;curl -LsSf https://astral.sh/uv/install.sh | sh&lt;/code&gt;&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;macOS / Linux 没有 curl&lt;/td&gt;
          &lt;td&gt;官方脚本 + wget&lt;/td&gt;
          &lt;td&gt;&lt;code&gt;wget -qO- https://astral.sh/uv/install.sh | sh&lt;/code&gt;&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;Windows 快速安装&lt;/td&gt;
          &lt;td&gt;PowerShell 安装脚本&lt;/td&gt;
          &lt;td&gt;&lt;code&gt;powershell -ExecutionPolicy ByPass -c &amp;quot;irm https://astral.sh/uv/install.ps1 | iex&amp;quot;&lt;/code&gt;&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;Python 工具隔离安装&lt;/td&gt;
          &lt;td&gt;pipx&lt;/td&gt;
          &lt;td&gt;&lt;code&gt;pipx install uv&lt;/code&gt;&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;临时或传统 Python 安装&lt;/td&gt;
          &lt;td&gt;pip&lt;/td&gt;
          &lt;td&gt;&lt;code&gt;pip install uv&lt;/code&gt;&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;macOS 包管理&lt;/td&gt;
          &lt;td&gt;Homebrew&lt;/td&gt;
          &lt;td&gt;&lt;code&gt;brew install uv&lt;/code&gt;&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;macOS MacPorts 用户&lt;/td&gt;
          &lt;td&gt;MacPorts&lt;/td&gt;
          &lt;td&gt;&lt;code&gt;sudo port install uv&lt;/code&gt;&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;Windows 包管理&lt;/td&gt;
          &lt;td&gt;WinGet&lt;/td&gt;
          &lt;td&gt;&lt;code&gt;winget install --id=astral-sh.uv -e&lt;/code&gt;&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;Windows Scoop 用户&lt;/td&gt;
          &lt;td&gt;Scoop&lt;/td&gt;
          &lt;td&gt;&lt;code&gt;scoop install main/uv&lt;/code&gt;&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;Rust 用户&lt;/td&gt;
          &lt;td&gt;Cargo&lt;/td&gt;
          &lt;td&gt;&lt;code&gt;cargo install --locked uv&lt;/code&gt;&lt;/td&gt;
      &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;最推荐的通用方案：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;macOS / Linux：官方独立安装脚本；&lt;/li&gt;
&lt;li&gt;Windows：官方 PowerShell 安装脚本或 WinGet；&lt;/li&gt;
&lt;li&gt;已经使用 &lt;code&gt;pipx&lt;/code&gt; 管理 Python CLI 工具：&lt;code&gt;pipx install uv&lt;/code&gt;。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;macos-和-linux官方安装脚本&#34;&gt;macOS 和 Linux：官方安装脚本
&lt;/h2&gt;&lt;p&gt;官方最直接的安装方式是用 &lt;code&gt;curl&lt;/code&gt; 下载脚本并交给 &lt;code&gt;sh&lt;/code&gt; 执行：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;curl -LsSf https://astral.sh/uv/install.sh &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt; sh
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;如果系统没有 &lt;code&gt;curl&lt;/code&gt;，可以用 &lt;code&gt;wget&lt;/code&gt;：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;wget -qO- https://astral.sh/uv/install.sh &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt; sh
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;如果想安装指定版本，可以把版本号放进 URL。比如官方示例中的 &lt;code&gt;0.11.11&lt;/code&gt;：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;curl -LsSf https://astral.sh/uv/0.11.11/install.sh &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt; sh
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;这个方式适合绝大多数个人开发环境。它的优点是简单、跨平台、和 uv 官方更新机制配合最好。&lt;/p&gt;
&lt;p&gt;安装脚本会把 &lt;code&gt;uv&lt;/code&gt;、&lt;code&gt;uvx&lt;/code&gt; 等二进制文件安装到用户目录下，并可能修改 shell profile，让命令可以直接在终端中使用。如果你不希望安装器修改 PATH，可以参考官方 installer 选项，例如设置 &lt;code&gt;UV_NO_MODIFY_PATH=1&lt;/code&gt;。&lt;/p&gt;
&lt;h2 id=&#34;windowspowershell-安装脚本&#34;&gt;Windows：PowerShell 安装脚本
&lt;/h2&gt;&lt;p&gt;Windows 官方安装方式是用 PowerShell 执行安装脚本：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-powershell&#34; data-lang=&#34;powershell&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;powershell&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;-ExecutionPolicy&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;ByPass&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;-c&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;irm https://astral.sh/uv/install.ps1 | iex&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;如果要安装指定版本，也可以把版本号放进 URL：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-powershell&#34; data-lang=&#34;powershell&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;powershell&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;-ExecutionPolicy&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;ByPass&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;-c&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;irm https://astral.sh/uv/0.11.11/install.ps1 | iex&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;这里的 &lt;code&gt;ExecutionPolicy ByPass&lt;/code&gt; 是为了允许从互联网获取并执行安装脚本。安全习惯上，执行前可以先查看脚本内容：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-powershell&#34; data-lang=&#34;powershell&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;powershell&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;-c&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;irm https://astral.sh/uv/install.ps1 | more&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;如果你习惯 Windows 包管理器，也可以优先用 WinGet 或 Scoop。&lt;/p&gt;
&lt;h2 id=&#34;用-pipx-安装&#34;&gt;用 pipx 安装
&lt;/h2&gt;&lt;p&gt;官方文档提到，uv 发布到了 PyPI。如果从 PyPI 安装，推荐放进隔离环境，例如用 &lt;code&gt;pipx&lt;/code&gt;：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;pipx install uv
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;这个方式适合已经把 &lt;code&gt;pipx&lt;/code&gt; 当作 Python CLI 工具管理器的人。它可以避免把 uv 和当前项目环境混在一起。&lt;/p&gt;
&lt;p&gt;如果没有 &lt;code&gt;pipx&lt;/code&gt;，也可以直接用 &lt;code&gt;pip&lt;/code&gt;：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;pip install uv
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;但要注意：uv 在许多平台上提供预构建 wheel。如果某个平台没有对应 wheel，就会从源码构建，这时需要 Rust 工具链。&lt;/p&gt;
&lt;p&gt;我的建议是：个人机器上，&lt;code&gt;pipx install uv&lt;/code&gt; 比 &lt;code&gt;pip install uv&lt;/code&gt; 更干净；项目环境里，不建议把 uv 当作项目依赖安装。&lt;/p&gt;
&lt;h2 id=&#34;homebrewmacportswinget-和-scoop&#34;&gt;Homebrew、MacPorts、WinGet 和 Scoop
&lt;/h2&gt;&lt;p&gt;如果你更喜欢系统包管理器，uv 也支持常见渠道。&lt;/p&gt;
&lt;p&gt;macOS 上用 Homebrew：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;brew install uv
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;MacPorts 用户可以用：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;sudo port install uv
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;Windows 上用 WinGet：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-powershell&#34; data-lang=&#34;powershell&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;winget&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;install&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;-id&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;astral-sh&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;py&#34;&gt;uv&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;-e&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;Scoop 用户可以用：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-powershell&#34; data-lang=&#34;powershell&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;scoop&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;install&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;main&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;/&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;uv&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;这些方式的好处是统一交给系统包管理器维护。缺点是升级节奏取决于对应包源，而不是 uv 官方安装脚本。&lt;/p&gt;
&lt;h2 id=&#34;dockergithub-releases-和-cargo&#34;&gt;Docker、GitHub Releases 和 Cargo
&lt;/h2&gt;&lt;p&gt;uv 还提供 Docker 镜像，地址在 GitHub Container Registry：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;ghcr.io/astral-sh/uv
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;这适合 CI、Dockerfile、构建镜像和临时运行环境。实际使用时，建议再看官方 Docker 集成文档。&lt;/p&gt;
&lt;p&gt;如果你想手动下载二进制文件，可以从 GitHub Releases 获取。每个 release 页面通常包含支持平台的二进制文件，也会说明如何用 GitHub 地址调用独立安装器。&lt;/p&gt;
&lt;p&gt;Rust 用户也可以从 crates.io 安装：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;cargo install --locked uv
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;但这个方式会从源码构建，需要兼容的 Rust 工具链。除非你明确需要从 Rust 生态安装，否则普通用户不必优先选 Cargo。&lt;/p&gt;
&lt;h2 id=&#34;升级-uv&#34;&gt;升级 uv
&lt;/h2&gt;&lt;p&gt;如果 uv 是通过官方独立安装脚本安装的，可以用自更新命令：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;uv self update
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;官方提示说，更新 uv 会重新运行安装器，并可能修改 shell profile。如果不希望更新时修改 PATH，可以设置：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;UV_NO_MODIFY_PATH&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;m&#34;&gt;1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;如果你是通过其他方式安装的，就应该用对应包管理器升级。比如用 &lt;code&gt;pip&lt;/code&gt; 安装，就用：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;pip install --upgrade uv
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;Homebrew、WinGet、Scoop、MacPorts 也应该走各自的升级命令。&lt;/p&gt;
&lt;h2 id=&#34;启用-shell-自动补全&#34;&gt;启用 shell 自动补全
&lt;/h2&gt;&lt;p&gt;uv 支持 shell 自动补全。官方文档建议先用下面命令确认当前 shell：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;$SHELL&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;Bash：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&amp;#39;eval &amp;#34;$(uv generate-shell-completion bash)&amp;#34;&amp;#39;&lt;/span&gt; &amp;gt;&amp;gt; ~/.bashrc
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;Zsh：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&amp;#39;eval &amp;#34;$(uv generate-shell-completion zsh)&amp;#34;&amp;#39;&lt;/span&gt; &amp;gt;&amp;gt; ~/.zshrc
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;fish：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&amp;#39;uv generate-shell-completion fish | source&amp;#39;&lt;/span&gt; &amp;gt; ~/.config/fish/completions/uv.fish
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;PowerShell：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-powershell&#34; data-lang=&#34;powershell&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(!(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;Test-Path&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;-Path&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;$PROFILE&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nb&#34;&gt;New-Item&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;-ItemType&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;File&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;-Path&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;$PROFILE&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;-Force&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nb&#34;&gt;Add-Content&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;-Path&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;$PROFILE&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;-Value&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&amp;#39;(&amp;amp; uv generate-shell-completion powershell) | Out-String | Invoke-Expression&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;如果你也经常用 &lt;code&gt;uvx&lt;/code&gt;，可以单独启用 &lt;code&gt;uvx&lt;/code&gt; 补全。&lt;/p&gt;
&lt;p&gt;Bash：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&amp;#39;eval &amp;#34;$(uvx --generate-shell-completion bash)&amp;#34;&amp;#39;&lt;/span&gt; &amp;gt;&amp;gt; ~/.bashrc
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;Zsh：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&amp;#39;eval &amp;#34;$(uvx --generate-shell-completion zsh)&amp;#34;&amp;#39;&lt;/span&gt; &amp;gt;&amp;gt; ~/.zshrc
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;fish：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&amp;#39;uvx --generate-shell-completion fish | source&amp;#39;&lt;/span&gt; &amp;gt; ~/.config/fish/completions/uvx.fish
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;PowerShell：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-powershell&#34; data-lang=&#34;powershell&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(!(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;Test-Path&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;-Path&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;$PROFILE&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nb&#34;&gt;New-Item&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;-ItemType&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;File&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;-Path&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;$PROFILE&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;-Force&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nb&#34;&gt;Add-Content&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;-Path&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;$PROFILE&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;-Value&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&amp;#39;(&amp;amp; uvx --generate-shell-completion powershell) | Out-String | Invoke-Expression&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;配置后需要重启 shell，或者重新加载对应配置文件。&lt;/p&gt;
&lt;h2 id=&#34;卸载-uv&#34;&gt;卸载 uv
&lt;/h2&gt;&lt;p&gt;如果要卸载 uv，可以先清理缓存和 uv 存储的数据：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;uv cache clean
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;rm -r &lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;$(&lt;/span&gt;uv python dir&lt;span class=&#34;k&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;rm -r &lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;$(&lt;/span&gt;uv tool dir&lt;span class=&#34;k&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;然后删除二进制文件。&lt;/p&gt;
&lt;p&gt;macOS / Linux：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;rm ~/.local/bin/uv ~/.local/bin/uvx
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;Windows：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-powershell&#34; data-lang=&#34;powershell&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nb&#34;&gt;rm &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$HOME&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;\.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;local&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;\&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;bin&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;\&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;uv&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;py&#34;&gt;exe&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nb&#34;&gt;rm &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$HOME&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;\.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;local&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;\&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;bin&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;\&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;uvx&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;py&#34;&gt;exe&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nb&#34;&gt;rm &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$HOME&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;\.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;local&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;\&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;bin&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;\&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;uvw&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;py&#34;&gt;exe&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;官方文档还提醒：&lt;code&gt;0.5.0&lt;/code&gt; 之前，uv 会安装到 &lt;code&gt;~/.cargo/bin&lt;/code&gt;。如果你从早期版本升级过，旧二进制文件可能仍然留在那里，需要手动删除。&lt;/p&gt;
&lt;h2 id=&#34;安装后先做什么&#34;&gt;安装后先做什么
&lt;/h2&gt;&lt;p&gt;安装完成后，建议先确认版本：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;uv --version
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;然后可以从几个常见任务开始：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;uv python install
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;uv venv
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;uv pip install requests
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;uvx ruff --version
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;如果你是新项目，可以进一步学习：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;uv init&lt;/code&gt;：初始化项目；&lt;/li&gt;
&lt;li&gt;&lt;code&gt;uv add&lt;/code&gt;：添加依赖；&lt;/li&gt;
&lt;li&gt;&lt;code&gt;uv sync&lt;/code&gt;：同步环境；&lt;/li&gt;
&lt;li&gt;&lt;code&gt;uv run&lt;/code&gt;：在项目环境中运行命令；&lt;/li&gt;
&lt;li&gt;&lt;code&gt;uvx&lt;/code&gt;：临时运行 Python CLI 工具。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;我的建议&#34;&gt;我的建议
&lt;/h2&gt;&lt;p&gt;个人开发机上，优先使用官方独立安装脚本，因为它最贴近 uv 官方文档，也支持 &lt;code&gt;uv self update&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;Windows 用户如果不想执行远程脚本，可以用 WinGet 或 Scoop。macOS 用户如果习惯所有工具都交给 Homebrew 管理，可以直接 &lt;code&gt;brew install uv&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;已经使用 &lt;code&gt;pipx&lt;/code&gt; 管理 Python CLI 工具的人，可以用 &lt;code&gt;pipx install uv&lt;/code&gt;。但不建议在具体项目虚拟环境里用 &lt;code&gt;pip install uv&lt;/code&gt;，这样容易把工具链和项目依赖混在一起。&lt;/p&gt;
&lt;p&gt;如果是 CI 或容器构建，优先看 Docker 和 GitHub Releases，根据镜像构建流程固定版本。&lt;/p&gt;
&lt;h2 id=&#34;相关链接&#34;&gt;相关链接
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;uv 安装文档：&lt;a class=&#34;link&#34; href=&#34;https://docs.astral.sh/uv/getting-started/installation/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;https://docs.astral.sh/uv/getting-started/installation/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;uv First steps：&lt;a class=&#34;link&#34; href=&#34;https://docs.astral.sh/uv/getting-started/first-steps/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;https://docs.astral.sh/uv/getting-started/first-steps/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;uv Docker 集成：&lt;a class=&#34;link&#34; href=&#34;https://docs.astral.sh/uv/guides/integration/docker/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;https://docs.astral.sh/uv/guides/integration/docker/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;uv GitHub Releases：&lt;a class=&#34;link&#34; href=&#34;https://github.com/astral-sh/uv/releases&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;https://github.com/astral-sh/uv/releases&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
        </item>
        <item>
        <title>Awesome Codex Skills：给 Codex CLI 扩展技能的社区清单</title>
        <link>https://knightli.com/2026/05/07/awesome-codex-skills-composio/</link>
        <pubDate>Thu, 07 May 2026 20:19:15 +0800</pubDate>
        
        <guid>https://knightli.com/2026/05/07/awesome-codex-skills-composio/</guid>
        <description>&lt;p&gt;ComposioHQ 的 &lt;a class=&#34;link&#34; href=&#34;https://github.com/ComposioHQ/awesome-codex-skills&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;awesome-codex-skills&lt;/a&gt; 是一个面向 Codex CLI 的社区技能清单。它的价值不在于再写一堆提示词模板，而是把一类可重复的工作流程整理成可安装、可复用、可维护的 Skill。&lt;/p&gt;
&lt;p&gt;如果你已经把 Codex 当成日常开发搭档，这类仓库的意义会很直接：把经常重复讲的规则、命令、资料入口和操作步骤沉淀下来，下次只要调用对应技能，Codex 就能按同一套上下文继续工作。&lt;/p&gt;
&lt;h2 id=&#34;这个仓库解决什么问题&#34;&gt;这个仓库解决什么问题
&lt;/h2&gt;&lt;p&gt;Codex Skills 可以理解成给 Codex CLI 增加“专门工作模式”的方式。普通提示词适合临时说明一次需求，Skill 更适合长期复用。&lt;/p&gt;
&lt;p&gt;比如你经常需要：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;按固定格式生成提交信息；&lt;/li&gt;
&lt;li&gt;查阅某类 API 文档；&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;这些内容如果每次都重新输入，很快就会变成负担。Skill 的思路是把这些规则放进一个独立目录里，核心通常是一份 &lt;code&gt;SKILL.md&lt;/code&gt;，必要时再配合脚本、模板、参考资料或资产文件。Codex 在被触发时读取这份说明，然后按照里面定义的流程执行。&lt;/p&gt;
&lt;h2 id=&#34;和普通提示词有什么不同&#34;&gt;和普通提示词有什么不同
&lt;/h2&gt;&lt;p&gt;普通提示词更像一次性指令，适合告诉模型“这次怎么做”。Skill 更像一个小型操作手册，适合告诉 Codex“以后遇到这类任务都按这个方式做”。&lt;/p&gt;
&lt;p&gt;它的优势主要有三个：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;可复用&lt;/strong&gt;：常用工作流不用反复复制粘贴。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;可审查&lt;/strong&gt;：技能文件通常是本地 Markdown，可以直接打开、修改和版本管理。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;可扩展&lt;/strong&gt;：复杂技能可以带脚本、模板和参考资料，不只是自然语言说明。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;这也是 &lt;code&gt;awesome-codex-skills&lt;/code&gt; 这类清单的价值所在：它帮你集中发现已经写好的技能，再根据自己的工作习惯挑选、安装和改造。&lt;/p&gt;
&lt;h2 id=&#34;如何安装和使用&#34;&gt;如何安装和使用
&lt;/h2&gt;&lt;p&gt;仓库提供了安装脚本，也支持手动安装。典型流程是先克隆仓库，再运行安装脚本：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;git clone https://github.com/ComposioHQ/awesome-codex-skills.git
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nb&#34;&gt;cd&lt;/span&gt; awesome-codex-skills
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;python install.py
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;如果你只想试用少数技能，建议先看清每个技能目录里的 &lt;code&gt;SKILL.md&lt;/code&gt;，确认它会读取哪些资料、运行哪些脚本、修改哪些文件，再安装到本地 Codex skills 目录。&lt;/p&gt;
&lt;p&gt;安装之后，Codex 可以在合适的任务中自动匹配技能，也可以通过明确点名的方式调用。对长期使用者来说，更实用的方式往往是：先安装一个社区技能，再把里面的说明改成自己的项目规范。&lt;/p&gt;
&lt;h2 id=&#34;适合关注哪些技能&#34;&gt;适合关注哪些技能
&lt;/h2&gt;&lt;p&gt;这类仓库里最值得优先看的，不一定是名字最酷的技能，而是能稳定减少重复劳动的技能。&lt;/p&gt;
&lt;p&gt;我会优先关注几类：&lt;/p&gt;
&lt;ul&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;：把 Codex 和外部服务、API、命令行工具连接起来。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;项目规范类&lt;/strong&gt;：把团队约定、目录结构、命名规则、部署步骤写进固定流程。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;如果一个技能只是把一句提示词包装了一下，价值有限；如果它能把“查资料、判断、执行、验证、输出”串成稳定流程，就值得长期保留。&lt;/p&gt;
&lt;h2 id=&#34;使用时要注意什么&#34;&gt;使用时要注意什么
&lt;/h2&gt;&lt;p&gt;社区技能虽然方便，但不要把它当成黑盒直接运行。尤其是带脚本的 Skill，安装前最好先检查三件事：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;code&gt;SKILL.md&lt;/code&gt; 里要求 Codex 做什么；&lt;/li&gt;
&lt;li&gt;是否包含会访问网络、读写文件或调用外部服务的脚本；&lt;/li&gt;
&lt;li&gt;默认路径、命令和权限是否适合你的本地环境。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Skill 本质上是在扩大 Codex 的行动边界。写得好，它会让 Codex 更像熟悉你项目的同事；写得粗糙，它也可能把不适合你的规则带进工作流。所以最理想的用法不是“装很多”，而是“装少数、改到顺手、长期维护”。&lt;/p&gt;
&lt;h2 id=&#34;我的判断&#34;&gt;我的判断
&lt;/h2&gt;&lt;p&gt;&lt;code&gt;awesome-codex-skills&lt;/code&gt; 值得收藏，尤其适合已经开始用 Codex CLI 做真实开发、文档或自动化任务的人。它不是官方能力本身，而是一个社区整理的技能入口：你可以从里面找灵感，也可以把常用流程改造成自己的本地技能库。&lt;/p&gt;
&lt;p&gt;对重度用户来说，Codex Skills 的重点不是让 AI 多记一点东西，而是让 AI 在同类任务中少走弯路。把规则写成 Skill，等于把一次次临时沟通沉淀成可复用的工作基础设施。&lt;/p&gt;
</description>
        </item>
        <item>
        <title>Warp 开源：从终端到 Agentic Development Environment</title>
        <link>https://knightli.com/2026/05/07/warpdotdev-warp-open-source-agentic-terminal/</link>
        <pubDate>Thu, 07 May 2026 20:15:08 +0800</pubDate>
        
        <guid>https://knightli.com/2026/05/07/warpdotdev-warp-open-source-agentic-terminal/</guid>
        <description>&lt;p&gt;&lt;code&gt;warpdotdev/warp&lt;/code&gt; 是 Warp 的开源客户端仓库。Warp 官方现在把它定位为一个“从终端生长出来的 agentic development environment”，也就是以终端为基础，但把 AI coding agent、代码库索引、任务管理和开发工作流放进同一个环境里。&lt;/p&gt;
&lt;p&gt;这不是一个普通的终端模拟器开源仓库。它更像是在回答一个问题：当 Claude Code、Codex、Gemini CLI 这类 agent 越来越常见时，终端本身要不要变成一个能调度、观察和管理 agent 的开发环境？&lt;/p&gt;
&lt;p&gt;Warp 的答案是：要。&lt;/p&gt;
&lt;h2 id=&#34;这个仓库现在是什么状态&#34;&gt;这个仓库现在是什么状态
&lt;/h2&gt;&lt;p&gt;截至 2026 年 5 月 7 日查看，&lt;code&gt;warpdotdev/warp&lt;/code&gt; 是公开仓库，GitHub 页面显示约 56k stars、4.1k forks。仓库 README 说明，Warp 的客户端代码已经开源，并欢迎社区贡献。&lt;/p&gt;
&lt;p&gt;仓库的主语言是 Rust。GitHub 语言统计里，Rust 占比超过 98%。这和 Warp 的定位一致：它不是网页壳，而是一个跨平台的原生开发工具。&lt;/p&gt;
&lt;p&gt;README 中有几个信息点很重要：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Warp 是一个 agentic development environment, born out of the terminal。&lt;/li&gt;
&lt;li&gt;它可以使用内置 coding agent，也可以接入 Claude Code、Codex、Gemini CLI 等外部 CLI agent。&lt;/li&gt;
&lt;li&gt;OpenAI 是新开源 Warp 仓库的 founding sponsor。&lt;/li&gt;
&lt;li&gt;仓库中的 agentic management workflows 由 GPT models 驱动。&lt;/li&gt;
&lt;li&gt;Warp UI 框架相关 crate 使用 MIT license，其余代码使用 AGPL v3。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;这些信息说明，Warp 开源不是单纯把一个终端放出来，而是把它作为“agent 工作流实验场”来运营。&lt;/p&gt;
&lt;h2 id=&#34;warp-不只是终端&#34;&gt;Warp 不只是终端
&lt;/h2&gt;&lt;p&gt;传统终端主要解决三个问题：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;启动 shell。&lt;/li&gt;
&lt;li&gt;执行命令。&lt;/li&gt;
&lt;li&gt;显示输出。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Warp 早期的差异化，是让终端更现代：命令块、补全、历史、协作、UI 化交互、跨平台体验。现在它的重心继续往前走，开始围绕 AI agent 组织开发流程。&lt;/p&gt;
&lt;p&gt;从 README 看，Warp 不再只强调“更好用的 terminal”，而是强调：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;内置 coding agent。&lt;/li&gt;
&lt;li&gt;支持外部 CLI agent。&lt;/li&gt;
&lt;li&gt;issue triage。&lt;/li&gt;
&lt;li&gt;spec 编写。&lt;/li&gt;
&lt;li&gt;PR review。&lt;/li&gt;
&lt;li&gt;contributor coordination。&lt;/li&gt;
&lt;li&gt;可观察的 agent sessions。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;也就是说，Warp 想把终端从“你输入命令的地方”，变成“你和多个 agent 一起工作的地方”。&lt;/p&gt;
&lt;h2 id=&#34;oz-和开源项目管理&#34;&gt;Oz 和开源项目管理
&lt;/h2&gt;&lt;p&gt;README 里多次提到 &lt;code&gt;Oz&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;Warp 的贡献概览页面可以看到成千上万个 Oz agents 在做 issue triage、写 specs、实现改动、review PR。这个设计很有意思，因为它把 AI agent 从“帮个人写代码”扩展到了“帮开源项目管理协作”。&lt;/p&gt;
&lt;p&gt;传统开源项目最难的不是写代码，而是维护：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;issue 太多，没人分类。&lt;/li&gt;
&lt;li&gt;bug 和 feature request 混在一起。&lt;/li&gt;
&lt;li&gt;新贡献者不知道哪些任务能做。&lt;/li&gt;
&lt;li&gt;PR review 压力大。&lt;/li&gt;
&lt;li&gt;维护者很难持续跟进社区讨论。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Warp 的思路是，让 agent 先承担一部分项目管理和协作工作。README 中还提到 &lt;code&gt;Oz for OSS&lt;/code&gt;，这是面向维护者的合作计划，用于把类似 agentic open-source management workflows 带到其他开源仓库。&lt;/p&gt;
&lt;p&gt;这说明 Warp 的野心不只是终端产品本身，也包括探索 AI 时代开源维护的新模式。&lt;/p&gt;
&lt;h2 id=&#34;仓库结构和技术栈&#34;&gt;仓库结构和技术栈
&lt;/h2&gt;&lt;p&gt;从仓库结构看，Warp 是一个大型 Rust 项目。&lt;/p&gt;
&lt;p&gt;根目录里能看到：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;app/&lt;/code&gt;：主应用相关代码。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;crates/&lt;/code&gt;：核心 Rust crates。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;assets/&lt;/code&gt;：资源文件。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;command-signatures-v2/&lt;/code&gt;：命令签名相关内容。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;docker/&lt;/code&gt;、&lt;code&gt;script/&lt;/code&gt;、&lt;code&gt;resources/&lt;/code&gt;、&lt;code&gt;specs/&lt;/code&gt; 等工程目录。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;.claude/&lt;/code&gt;、&lt;code&gt;.warp/&lt;/code&gt;、&lt;code&gt;.agents/skills&lt;/code&gt; 等 agent 相关配置。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;code&gt;WARP.md&lt;/code&gt; 里给出了更详细的工程说明。它提到 Warp 是 Rust-based terminal emulator，并使用一个自研 UI 框架 &lt;code&gt;WarpUI&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;主要模块可以粗略理解为：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;app/&lt;/code&gt;：终端模拟、shell 管理、AI 集成、Drive、认证、设置、workspace 和 session。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;crates/warp_core/&lt;/code&gt;：核心工具和平台抽象。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;crates/editor/&lt;/code&gt;：文本编辑功能。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;crates/warpui/&lt;/code&gt; 和 &lt;code&gt;crates/warpui_core/&lt;/code&gt;：自研 UI 框架。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;crates/ipc/&lt;/code&gt;：进程间通信。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;crates/graphql/&lt;/code&gt;：GraphQL 客户端和 schema。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;WARP.md 还提到几个架构特点：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Entity-Handle system。&lt;/li&gt;
&lt;li&gt;模块化 workspace 结构。&lt;/li&gt;
&lt;li&gt;macOS、Windows、Linux 跨平台，以及 WASM target。&lt;/li&gt;
&lt;li&gt;AI integration，包含 Agent Mode、上下文感知和代码库索引。&lt;/li&gt;
&lt;li&gt;Warp Drive 云同步。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;这说明 Warp 的复杂度已经接近一个完整 IDE，而不是传统意义上的轻量 terminal。&lt;/p&gt;
&lt;h2 id=&#34;本地构建方式&#34;&gt;本地构建方式
&lt;/h2&gt;&lt;p&gt;README 给出的本地构建方式很简洁：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;./script/bootstrap
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;./script/run
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;./script/presubmit
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;其中：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;./script/bootstrap&lt;/code&gt;：执行平台相关初始化。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;./script/run&lt;/code&gt;：构建并运行 Warp。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;./script/presubmit&lt;/code&gt;：执行格式化、clippy 和测试等提交前检查。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;WARP.md 里还列出了更细的命令：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;5
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;cargo run
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;cargo bundle --bin warp
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;cargo nextest run --no-fail-fast --workspace --exclude command-signatures-v2
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;cargo fmt
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;cargo clippy --workspace --all-targets --all-features --tests -- -D warnings
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;如果要给 Warp 提交代码，&lt;code&gt;./script/presubmit&lt;/code&gt; 基本是必须跑的。&lt;/p&gt;
&lt;h2 id=&#34;贡献流程&#34;&gt;贡献流程
&lt;/h2&gt;&lt;p&gt;Warp 的贡献流程不是简单“发 PR 就行”。&lt;/p&gt;
&lt;p&gt;README 描述了一个从 issue 到 PR 的轻量流程：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;先搜索已有 issue。&lt;/li&gt;
&lt;li&gt;没有重复再提交 bug 或 feature request。&lt;/li&gt;
&lt;li&gt;维护者会 review issue，并可能打上 readiness label。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ready-to-spec&lt;/code&gt; 表示设计可以被贡献者展开成 spec。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ready-to-implement&lt;/code&gt; 表示设计已相对明确，可以开始写代码 PR。&lt;/li&gt;
&lt;li&gt;贡献者可以认领带标签的 issue。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;这个流程适合大型开源项目。它把“想法”“设计”“实现”拆开，减少贡献者一上来就写错方向的风险。&lt;/p&gt;
&lt;p&gt;对 AI agent 来说，这也很适合。agent 可以先整理 issue、写 spec、补测试，再进入实现。Warp 自己也在用这种方式展示 agentic project management。&lt;/p&gt;
&lt;h2 id=&#34;许可mit--agpl-v3&#34;&gt;许可：MIT + AGPL v3
&lt;/h2&gt;&lt;p&gt;Warp 采用双许可结构。&lt;/p&gt;
&lt;p&gt;README 说明：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Warp UI framework，也就是 &lt;code&gt;warpui_core&lt;/code&gt; 和 &lt;code&gt;warpui&lt;/code&gt; crates，使用 MIT license。&lt;/li&gt;
&lt;li&gt;仓库其余代码使用 AGPL v3。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;这点很重要。AGPL v3 对网络服务和分发有更强的开源要求。如果你只是学习、研究、贡献代码，问题不大；但如果想把 Warp 代码用于商业产品或闭源衍生项目，就必须认真读 license，必要时咨询法律意见。&lt;/p&gt;
&lt;p&gt;简单说，Warp 是开源了，但不是“随便拿去闭源商用”的宽松许可。&lt;/p&gt;
&lt;h2 id=&#34;值得关注的地方&#34;&gt;值得关注的地方
&lt;/h2&gt;&lt;p&gt;第一，Warp 把终端、agent、项目管理放在一起。&lt;/p&gt;
&lt;p&gt;很多 AI coding 工具仍然是 CLI 或编辑器插件。Warp 试图从终端入口出发，把 agent 任务、代码执行、命令输出、PR 工作流和团队协作整合起来。&lt;/p&gt;
&lt;p&gt;第二，Warp 的开源方式很适合观察 agent 工作流。&lt;/p&gt;
&lt;p&gt;它不只是发布代码，还把贡献概览、agent session、issue triage 和 spec 流程公开出来。对于想研究 AI 如何参与开源协作的人，这个仓库本身就是样本。&lt;/p&gt;
&lt;p&gt;第三，Warp 是一个复杂 Rust 桌面应用。&lt;/p&gt;
&lt;p&gt;如果你想学习 Rust GUI、终端模拟器、跨平台应用、GraphQL 客户端、云同步和 AI 集成，Warp 仓库有不少可看的结构。但它不是小项目，新贡献者需要先读文档和 issue 流程。&lt;/p&gt;
&lt;p&gt;第四，Warp 支持“自带 agent”和“bring your own CLI agent”两条线。&lt;/p&gt;
&lt;p&gt;这点很现实。开发者不会只用一个 agent。Claude Code、Codex、Gemini CLI、OpenCode、OpenClaw 等工具会长期共存。Warp 如果能成为它们的工作台，就比单一终端更有价值。&lt;/p&gt;
&lt;h2 id=&#34;适合谁关注&#34;&gt;适合谁关注
&lt;/h2&gt;&lt;p&gt;如果你是普通终端用户，关注 Warp 的意义在于：终端可能正在从命令行工具变成 AI 工作台。&lt;/p&gt;
&lt;p&gt;如果你是 AI coding agent 重度用户，Warp 值得关注，因为它试图管理多个 agent，而不是只做一个聊天入口。&lt;/p&gt;
&lt;p&gt;如果你是开源维护者，可以关注 Oz for OSS 这条线。它试图用 agent 做 issue triage、PR review、社区协作和贡献者引导。&lt;/p&gt;
&lt;p&gt;如果你是 Rust 开发者，Warp 是一个大型真实桌面应用样本，可以研究它如何组织 UI、终端、云同步、AI 集成和跨平台代码。&lt;/p&gt;
&lt;p&gt;如果你只是想找一个能马上替代传统终端的工具，建议先下载正式版使用，再决定是否研究源码。直接从源码构建更适合贡献者和深度玩家。&lt;/p&gt;
&lt;h2 id=&#34;简短判断&#34;&gt;简短判断
&lt;/h2&gt;&lt;p&gt;Warp 开源的重点，不只是“一个现代终端开源了”。&lt;/p&gt;
&lt;p&gt;更准确地说，Warp 正在把终端升级成 agentic development environment：终端负责连接 shell、代码库、命令执行、agent、issue、PR 和协作流程。&lt;/p&gt;
&lt;p&gt;在 AI coding agent 继续增长的背景下，开发环境的入口可能会发生变化。过去是 IDE 统治开发体验，终端负责命令执行；现在终端可能反过来成为 agent 协作的中心。Warp 这个仓库，正是在探索这种可能性。&lt;/p&gt;
&lt;h2 id=&#34;相关链接&#34;&gt;相关链接
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;GitHub 仓库：&lt;a class=&#34;link&#34; href=&#34;https://github.com/warpdotdev/warp&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;https://github.com/warpdotdev/warp&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Warp 官网：&lt;a class=&#34;link&#34; href=&#34;https://www.warp.dev&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;https://www.warp.dev&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Warp 文档：&lt;a class=&#34;link&#34; href=&#34;https://docs.warp.dev&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;https://docs.warp.dev&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Warp 构建概览：&lt;a class=&#34;link&#34; href=&#34;https://build.warp.dev&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;https://build.warp.dev&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;WARP.md：&lt;a class=&#34;link&#34; href=&#34;https://github.com/warpdotdev/warp/blob/master/WARP.md&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;https://github.com/warpdotdev/warp/blob/master/WARP.md&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;CONTRIBUTING.md：&lt;a class=&#34;link&#34; href=&#34;https://github.com/warpdotdev/warp/blob/master/CONTRIBUTING.md&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;https://github.com/warpdotdev/warp/blob/master/CONTRIBUTING.md&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
        </item>
        <item>
        <title>编译 UEFI 程序入门：从 uefi-simple 到第一个 .EFI</title>
        <link>https://knightli.com/2026/04/30/compile-uefi-program-beginner-guide/</link>
        <pubDate>Thu, 30 Apr 2026 19:53:08 +0800</pubDate>
        
        <guid>https://knightli.com/2026/04/30/compile-uefi-program-beginner-guide/</guid>
        <description>&lt;p&gt;编译第一个 UEFI 程序并不轻松：环境安装耗时，链接器报错很多，&lt;code&gt;.EFI&lt;/code&gt; 程序也不像普通桌面程序那样有成熟直观的编辑和运行体验。&lt;/p&gt;
&lt;p&gt;这篇就按入门角度整理一下：如果只是想先编译出自己的第一个 UEFI 程序，应该从哪里开始，哪些概念要先搞清楚，哪些坑最容易遇到。&lt;/p&gt;
&lt;h2 id=&#34;uefi-程序是什么&#34;&gt;UEFI 程序是什么
&lt;/h2&gt;&lt;p&gt;UEFI 程序通常是一个 &lt;code&gt;.EFI&lt;/code&gt; 文件。&lt;/p&gt;
&lt;p&gt;它不是 Windows 下双击运行的普通 &lt;code&gt;.exe&lt;/code&gt;，而是运行在 UEFI 固件环境里的 PE/COFF 可执行文件。常见场景包括：&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;/ul&gt;
&lt;p&gt;你在系统启动早期看到的很多功能，本质上都可能和 UEFI 应用、驱动或固件服务有关。&lt;/p&gt;
&lt;p&gt;对初学者来说，先不用急着理解完整固件开发。第一步只要完成一个目标：编译出一个能被 UEFI Shell 或模拟器加载的 &lt;code&gt;.EFI&lt;/code&gt; 文件。&lt;/p&gt;
&lt;h2 id=&#34;为什么不建议一开始就上-edk-ii&#34;&gt;为什么不建议一开始就上 EDK II
&lt;/h2&gt;&lt;p&gt;UEFI 正式开发经常会遇到 EDK II。&lt;/p&gt;
&lt;p&gt;EDK II 功能完整，也更接近真实固件工程，但它对新手不太友好：&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;/ul&gt;
&lt;p&gt;如果目标只是“先跑起来一个最小 UEFI 程序”，更适合从轻量示例开始。&lt;/p&gt;
&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://github.com/pbatard/uefi-simple&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;pbatard/uefi-simple&lt;/a&gt; 就是这类项目。它的定位很直接：提供一个简单的 UEFI Hello World 示例，让你先把 &lt;code&gt;.EFI&lt;/code&gt; 编译出来。&lt;/p&gt;
&lt;h2 id=&#34;uefi-simple-适合用来做什么&#34;&gt;&lt;code&gt;uefi-simple&lt;/code&gt; 适合用来做什么
&lt;/h2&gt;&lt;p&gt;&lt;code&gt;uefi-simple&lt;/code&gt; 适合做 UEFI 入门的第一块踏板。&lt;/p&gt;
&lt;p&gt;它主要解决三个问题：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;给你一个最小可编译的 UEFI 应用结构&lt;/li&gt;
&lt;li&gt;帮你避开一开始就接触大型固件工程的复杂度&lt;/li&gt;
&lt;li&gt;让你能先验证编译、链接、运行链路是否通&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;这个项目支持不同构建方式，包括 Visual Studio 2022 和 MinGW/gcc，也可以配合 QEMU 与 OVMF 做测试。&lt;/p&gt;
&lt;p&gt;也就是说，你不一定非要准备真实机器反复重启测试。先用模拟器把程序跑起来，会安全很多。&lt;/p&gt;
&lt;h2 id=&#34;入门前要准备哪些东西&#34;&gt;入门前要准备哪些东西
&lt;/h2&gt;&lt;p&gt;最少需要准备几类工具。&lt;/p&gt;
&lt;p&gt;第一类是编译工具链。&lt;/p&gt;
&lt;p&gt;如果你在 Windows 上，可以优先考虑：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Visual Studio 2022&lt;/li&gt;
&lt;li&gt;或 MinGW/gcc&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;第二类是 UEFI 运行环境。&lt;/p&gt;
&lt;p&gt;可以有两种选择：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;用真实机器的 UEFI Shell 运行 &lt;code&gt;.EFI&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;用 QEMU + OVMF 在虚拟环境里测试&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;第三类是示例项目。&lt;/p&gt;
&lt;p&gt;新手不建议从空目录开始手写构建脚本。直接使用 &lt;code&gt;uefi-simple&lt;/code&gt; 这类最小示例，可以少踩很多构建系统的坑。&lt;/p&gt;
&lt;h2 id=&#34;大致流程&#34;&gt;大致流程
&lt;/h2&gt;&lt;p&gt;一个最小 UEFI 程序的入门流程可以这样理解。&lt;/p&gt;
&lt;p&gt;第一步，拿到示例项目。&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-powershell&#34; data-lang=&#34;powershell&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;git&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;clone&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;https&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;//&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;github&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;com&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;/&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;pbatard&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;/&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;uefi-simple&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;py&#34;&gt;git&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;第二步，选择构建工具链。&lt;/p&gt;
&lt;p&gt;如果用 Visual Studio，就按项目里的 Visual Studio 方案构建。&lt;br&gt;
如果用 MinGW/gcc，就按项目提供的 Makefile 或说明走。&lt;/p&gt;
&lt;p&gt;第三步，生成 &lt;code&gt;.EFI&lt;/code&gt; 文件。&lt;/p&gt;
&lt;p&gt;这里最关键的是确认目标架构。常见 PC 一般是 &lt;code&gt;x86_64&lt;/code&gt;，也就是 64 位 UEFI 环境。&lt;/p&gt;
&lt;p&gt;第四步，把 &lt;code&gt;.EFI&lt;/code&gt; 放到可以被 UEFI Shell 访问的位置。&lt;/p&gt;
&lt;p&gt;如果用真实机器，通常会准备一个 FAT32 分区或 U 盘。&lt;br&gt;
如果用 QEMU，可以把目录或镜像挂载进去。&lt;/p&gt;
&lt;p&gt;第五步，在 UEFI Shell 里运行。&lt;/p&gt;
&lt;p&gt;运行效果通常就是一个最小输出，比如打印类似 Hello World 的内容。&lt;/p&gt;
&lt;h2 id=&#34;最容易卡住的地方&#34;&gt;最容易卡住的地方
&lt;/h2&gt;&lt;p&gt;编译 UEFI 程序最容易卡的不是 C 语言本身，而是环境和链接。&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;li&gt;缺少 UEFI 入口点&lt;/li&gt;
&lt;li&gt;生成的是普通可执行文件，不是 UEFI 能加载的 &lt;code&gt;.EFI&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;QEMU 或 OVMF 没配置好&lt;/li&gt;
&lt;li&gt;真实机器 Secure Boot 阻止运行未签名程序&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;尤其是链接器报错，经常会让新手误以为代码写错了。&lt;br&gt;
实际上，很多时候是入口函数、子系统、目标架构或链接脚本配置不对。&lt;/p&gt;
&lt;p&gt;所以第一阶段不要急着改复杂逻辑。先确保原始示例能编译、能运行，再一点点改输出内容。&lt;/p&gt;
&lt;h2 id=&#34;测试时为什么推荐-qemu--ovmf&#34;&gt;测试时为什么推荐 QEMU + OVMF
&lt;/h2&gt;&lt;p&gt;真实机器测试 UEFI 程序并不是不行，但新手阶段不太方便。&lt;/p&gt;
&lt;p&gt;因为你可能需要反复：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;编译&lt;/li&gt;
&lt;li&gt;拷贝到 U 盘&lt;/li&gt;
&lt;li&gt;重启&lt;/li&gt;
&lt;li&gt;进入 UEFI Shell&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;QEMU + OVMF 的好处是可以在操作系统里直接模拟 UEFI 环境。你可以更快地验证 &lt;code&gt;.EFI&lt;/code&gt; 是否能被加载，也不容易影响真实机器启动项。&lt;/p&gt;
&lt;p&gt;等程序基本跑通，再放到真实机器上测试，会更稳。&lt;/p&gt;
&lt;h2 id=&#34;新手应该先改哪里&#34;&gt;新手应该先改哪里
&lt;/h2&gt;&lt;p&gt;如果你已经用示例项目编译出了第一个 &lt;code&gt;.EFI&lt;/code&gt;，下一步不要马上写复杂功能。&lt;/p&gt;
&lt;p&gt;建议按这个顺序改：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;先改输出文本，确认重新编译后的程序确实生效。&lt;/li&gt;
&lt;li&gt;再尝试读取 UEFI 提供的简单信息。&lt;/li&gt;
&lt;li&gt;再理解入口函数、输出协议和基本服务。&lt;/li&gt;
&lt;li&gt;最后再考虑文件系统、图形输出、启动项管理等复杂功能。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;这样做的好处是每一步都能验证。&lt;br&gt;
如果一上来就改很多东西，出错时很难判断到底是代码问题、编译问题，还是运行环境问题。&lt;/p&gt;
&lt;h2 id=&#34;和普通-c-程序有什么不同&#34;&gt;和普通 C 程序有什么不同
&lt;/h2&gt;&lt;p&gt;UEFI 程序虽然可以用 C 写，但它和普通 C 程序的运行环境完全不同。&lt;/p&gt;
&lt;p&gt;普通 C 程序通常运行在操作系统里，可以依赖标准库、文件系统、进程模型和系统调用。&lt;/p&gt;
&lt;p&gt;UEFI 程序运行在操作系统启动之前，它依赖的是 UEFI 固件提供的服务。很多你在普通程序里习惯使用的东西，在这里并不是天然可用。&lt;/p&gt;
&lt;p&gt;所以写 UEFI 程序时，要先适应几个变化：&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;/ul&gt;
&lt;p&gt;这也是为什么推荐先从最小示例开始，而不是直接照普通 C 程序的习惯写。&lt;/p&gt;
&lt;h2 id=&#34;一个比较现实的学习路线&#34;&gt;一个比较现实的学习路线
&lt;/h2&gt;&lt;p&gt;如果只是入门，可以按这个路线走：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;第一步：编译 &lt;code&gt;uefi-simple&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;第二步：用 QEMU + OVMF 跑起来&lt;/li&gt;
&lt;li&gt;第三步：修改 Hello World 输出&lt;/li&gt;
&lt;li&gt;第四步：理解 UEFI Shell 怎么加载 &lt;code&gt;.EFI&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;第五步：学习 UEFI 的入口函数和基本输出协议&lt;/li&gt;
&lt;li&gt;第六步：再看 EDK II 或更完整的 UEFI 开发资料&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;这条路线的重点是先让反馈闭环跑起来。&lt;/p&gt;
&lt;p&gt;只要你能从源码生成 &lt;code&gt;.EFI&lt;/code&gt;，再在 UEFI 环境里看到输出，就已经跨过了最难的第一道门槛。&lt;/p&gt;
&lt;h2 id=&#34;参考&#34;&gt;参考
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://github.com/pbatard/uefi-simple&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;pbatard/uefi-simple&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://zhuanlan.zhihu.com/p/643704056&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;知乎：编译 UEFI 程序相关资料&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;最后一句&#34;&gt;最后一句
&lt;/h2&gt;&lt;p&gt;编译第一个 UEFI 程序，难点通常不在“写出一段 C 代码”，而在把工具链、链接格式和运行环境串起来。&lt;/p&gt;
&lt;p&gt;先别急着做复杂功能。&lt;br&gt;
从 &lt;code&gt;uefi-simple&lt;/code&gt; 这种最小示例开始，先得到一个能运行的 &lt;code&gt;.EFI&lt;/code&gt;，再逐步理解 UEFI 的入口、协议和构建方式，会轻松很多。&lt;/p&gt;
</description>
        </item>
        <item>
        <title>GoAccess 最新版自编译与使用记录：从源码安装到实时 HTML 报表</title>
        <link>https://knightli.com/2026/04/29/goaccess-build-from-source-and-latest-usage/</link>
        <pubDate>Wed, 29 Apr 2026 00:08:00 +0800</pubDate>
        
        <guid>https://knightli.com/2026/04/29/goaccess-build-from-source-and-latest-usage/</guid>
        <description>&lt;p&gt;时间点按 &lt;code&gt;2026-04-29&lt;/code&gt; 整理，当前官方 README 里给出的最新稳定版是 &lt;code&gt;1.10.2&lt;/code&gt;。&lt;/p&gt;
&lt;h2 id=&#34;1-先装编译依赖&#34;&gt;1. 先装编译依赖
&lt;/h2&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;sudo apt-get update
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;sudo apt-get install -y build-essential wget tar &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  libncurses-dev libmaxminddb-dev libssl-dev zlib1g-dev
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h2 id=&#34;2-下载最新版源码包&#34;&gt;2. 下载最新版源码包
&lt;/h2&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nb&#34;&gt;cd&lt;/span&gt; /usr/local/src
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;sudo wget https://tar.goaccess.io/goaccess-1.10.2.tar.gz
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;sudo tar -xzvf goaccess-1.10.2.tar.gz
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nb&#34;&gt;cd&lt;/span&gt; goaccess-1.10.2
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h2 id=&#34;3-配置编译参数&#34;&gt;3. 配置编译参数
&lt;/h2&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;sudo ./configure --enable-utf8 --enable-geoip&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;mmdb --with-zlib
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;如果你还想给实时 HTML 报表配 TLS，也可以改成：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;sudo ./configure --enable-utf8 --enable-geoip&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;mmdb --with-zlib --with-openssl
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h2 id=&#34;4-编译并安装&#34;&gt;4. 编译并安装
&lt;/h2&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;sudo make
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;sudo make install
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h2 id=&#34;5-确认版本&#34;&gt;5. 确认版本
&lt;/h2&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;goaccess --version
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;which goaccess
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h2 id=&#34;6-直接看终端报表&#34;&gt;6. 直接看终端报表
&lt;/h2&gt;&lt;p&gt;Nginx 或 Apache 常见 combined 日志可以先这样跑：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;goaccess /var/log/nginx/access.log --log-format&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;COMBINED
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;如果日志路径是 Apache：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;goaccess /var/log/apache2/access.log --log-format&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;COMBINED
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h2 id=&#34;7-生成静态-html-报表&#34;&gt;7. 生成静态 HTML 报表
&lt;/h2&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;goaccess /var/log/nginx/access.log &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  --log-format&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;COMBINED &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  -a &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  -o /usr/share/nginx/html/goaccess-report.html
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;输出到当前目录也可以：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;goaccess /var/log/nginx/access.log &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  --log-format&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;COMBINED &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  -a &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  -o report.html
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h2 id=&#34;8-生成实时-html-报表&#34;&gt;8. 生成实时 HTML 报表
&lt;/h2&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;5
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;goaccess /var/log/nginx/access.log &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  --log-format&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;COMBINED &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  -a &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  -o /usr/share/nginx/html/goaccess-report.html &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  --real-time-html
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;如果要改端口：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;6
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;goaccess /var/log/nginx/access.log &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  --log-format&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;COMBINED &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  -a &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  -o /usr/share/nginx/html/goaccess-report.html &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  --real-time-html &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  --port&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;m&#34;&gt;7891&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;如果只绑定本机：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;6
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;goaccess /var/log/nginx/access.log &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  --log-format&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;COMBINED &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  -a &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  -o /usr/share/nginx/html/goaccess-report.html &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  --real-time-html &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  --addr&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;127.0.0.1
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h2 id=&#34;9-持续追日志&#34;&gt;9. 持续追日志
&lt;/h2&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;tail -f /var/log/nginx/access.log &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt; goaccess --log-format&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;COMBINED -
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;从文件开头开始并保持实时：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;tail -f -n +0 /var/log/nginx/access.log &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt; goaccess &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  --log-format&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;COMBINED &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  -o report.html &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  --real-time-html -
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h2 id=&#34;10-只看某类请求&#34;&gt;10. 只看某类请求
&lt;/h2&gt;&lt;p&gt;例如只看带 &lt;code&gt;firefox&lt;/code&gt; 的请求：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;tail -f /var/log/nginx/access.log &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt; grep -i --line-buffered &lt;span class=&#34;s1&#34;&gt;&amp;#39;firefox&amp;#39;&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt; goaccess &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  --log-format&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;COMBINED -
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;例如只看 &lt;code&gt;5xx&lt;/code&gt; 和 &lt;code&gt;3xx&lt;/code&gt;：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;tail -f -n +0 /var/log/nginx/access.log &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt; awk &lt;span class=&#34;s1&#34;&gt;&amp;#39;$9~/3[0-9]{2}|5[0-9]{2}/&amp;#39;&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt; goaccess &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  --log-format&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;COMBINED &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  -o out.html -
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h2 id=&#34;11-多个日志一起分析&#34;&gt;11. 多个日志一起分析
&lt;/h2&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;goaccess /var/log/nginx/access.log /var/log/nginx/access.log.1 --log-format&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;COMBINED
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;压缩和未压缩一起读：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;zcat --force /var/log/nginx/access.log* &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt; goaccess --log-format&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;COMBINED -
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h2 id=&#34;12-开多线程&#34;&gt;12. 开多线程
&lt;/h2&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;goaccess /var/log/nginx/access.log &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  --log-format&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;COMBINED &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  -o report.html &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  -j &lt;span class=&#34;m&#34;&gt;4&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;加大 chunk：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;5
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;goaccess /var/log/nginx/access.log &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  --log-format&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;COMBINED &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  -o report.html &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  -j &lt;span class=&#34;m&#34;&gt;4&lt;/span&gt; &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  --chunk-size&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;m&#34;&gt;8192&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h2 id=&#34;13-增量处理&#34;&gt;13. 增量处理
&lt;/h2&gt;&lt;p&gt;先持久化一份旧日志：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;goaccess /var/log/nginx/access.log.1 --log-format&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;COMBINED --persist
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;再追加当前日志：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;goaccess /var/log/nginx/access.log --log-format&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;COMBINED --restore --persist
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;只读取已持久化数据：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;goaccess --restore
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h2 id=&#34;14-我自己会先跑的一组命令&#34;&gt;14. 我自己会先跑的一组命令
&lt;/h2&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;12
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;13
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;14
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;15
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;16
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;17
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;18
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;19
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;sudo apt-get update
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;sudo apt-get install -y build-essential wget tar &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  libncurses-dev libmaxminddb-dev libssl-dev zlib1g-dev
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nb&#34;&gt;cd&lt;/span&gt; /usr/local/src
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;sudo wget https://tar.goaccess.io/goaccess-1.10.2.tar.gz
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;sudo tar -xzvf goaccess-1.10.2.tar.gz
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nb&#34;&gt;cd&lt;/span&gt; goaccess-1.10.2
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;sudo ./configure --enable-utf8 --enable-geoip&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;mmdb --with-zlib --with-openssl
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;sudo make
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;sudo make install
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;goaccess --version
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;goaccess /var/log/nginx/access.log &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  --log-format&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;COMBINED &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  -a &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  -o /usr/share/nginx/html/goaccess-report.html &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  --real-time-html
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;就这样。&lt;br&gt;
如果你的目标很明确，其实只要把最新版源码编译好，再把 &lt;code&gt;--log-format=COMBINED&lt;/code&gt; 和 &lt;code&gt;--real-time-html&lt;/code&gt; 这两个参数先跑通，后面基本就是围着日志路径、输出文件和端口在改。&lt;/p&gt;
</description>
        </item>
        <item>
        <title>2026 年嵌入式开发环境怎么选：Keil、STM32CubeIDE、VS Code 与 AI 协作</title>
        <link>https://knightli.com/2026/04/22/embedded-development-environment-keil-vscode-ai-2026/</link>
        <pubDate>Wed, 22 Apr 2026 23:05:00 +0800</pubDate>
        
        <guid>https://knightli.com/2026/04/22/embedded-development-environment-keil-vscode-ai-2026/</guid>
        <description>&lt;p&gt;只要你还在做单片机或者嵌入式开发，很快就会遇到一个很现实的问题：到了 2026 年，在 AI 写代码已经越来越普遍的情况下，开发环境到底应该怎么选？&lt;/p&gt;
&lt;p&gt;这个问题表面上像是在比较几个 IDE，实际讨论的却是另一件事：你到底是要一个“能把工程跑起来的工具”，还是一套“兼顾生态、编码体验和 AI 协作能力”的工作流。&lt;/p&gt;
&lt;p&gt;如果按这个角度去看，答案往往就不是简单地在 &lt;code&gt;Keil&lt;/code&gt;、&lt;code&gt;STM32CubeIDE&lt;/code&gt;、&lt;code&gt;VS Code&lt;/code&gt;、&lt;code&gt;CLion&lt;/code&gt; 里选一个，而是重新组合它们各自最擅长的部分。&lt;/p&gt;
&lt;h2 id=&#34;先看几个主流选项各自解决什么问题&#34;&gt;先看几个主流选项，各自解决什么问题
&lt;/h2&gt;&lt;p&gt;嵌入式领域这些年常见的环境，基本还是那几类：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;Keil&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;STM32CubeIDE&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;VS Code&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;CLion&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;如果再往前追，当然还会有人提 &lt;code&gt;IAR&lt;/code&gt;。只是从今天的讨论出发，更值得看的已经不是“谁资格最老”，而是谁更适合当前这套开发现实。&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://knightli.com/2026/04/22/embedded-development-environment-keil-vscode-ai-2026/embedded-ide-comparison.svg&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;嵌入式开发环境横向对比图&#34;
	
	
&gt;&lt;/p&gt;
&lt;h2 id=&#34;keil生态强上手稳但编辑体验已经明显落后&#34;&gt;Keil：生态强、上手稳，但编辑体验已经明显落后
&lt;/h2&gt;&lt;p&gt;&lt;code&gt;Keil&lt;/code&gt; 到今天仍然很难绕开，原因不复杂：它用得实在太广了。&lt;/p&gt;
&lt;p&gt;无论是公司里留下来的老工程，还是网上大量教程、资料、示例工程，很多都还是围绕 &lt;code&gt;Keil&lt;/code&gt; 组织的。它在编译、下载、调试这一整套流程上依然成熟，尤其是你真的要把板子跑起来时，它的路径非常短。&lt;/p&gt;
&lt;p&gt;它的问题也同样明显：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;界面老&lt;/li&gt;
&lt;li&gt;编辑体验一般&lt;/li&gt;
&lt;li&gt;不擅长承担 AI 辅助编码的主场&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;所以 &lt;code&gt;Keil&lt;/code&gt; 更像是一个“工程入口和调试底座”，而不是一个面向 2026 年编码体验的理想编辑环境。&lt;/p&gt;
&lt;h2 id=&#34;stm32cubeide对-stm32-友好但更多是学习和快速起步工具&#34;&gt;STM32CubeIDE：对 STM32 友好，但更多是学习和快速起步工具
&lt;/h2&gt;&lt;p&gt;如果你主要在 &lt;code&gt;STM32&lt;/code&gt; 生态里活动，&lt;code&gt;STM32CubeIDE&lt;/code&gt; 很容易成为第一个接触到的环境。&lt;/p&gt;
&lt;p&gt;它的优点很明确：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;上手友好&lt;/li&gt;
&lt;li&gt;外设配置和工程生成方便&lt;/li&gt;
&lt;li&gt;调试链路相对完整&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;对学生、新手和刚起步的项目来说，这套体验确实足够直接。&lt;/p&gt;
&lt;p&gt;但一旦进入更长期、更多协作、更多定制的工程环境，它的局限也会慢慢暴露出来。尤其是在商业项目或者更复杂的团队工作流里，它未必是那个最舒服的主环境。&lt;/p&gt;
&lt;p&gt;所以它更适合“快速启动”和“STM32 生态内的一体化体验”，不一定适合作为长期主力编辑器。&lt;/p&gt;
&lt;h2 id=&#34;vs-code严格说不是-ide但在-ai-时代优势越来越明显&#34;&gt;VS Code：严格说不是 IDE，但在 AI 时代优势越来越明显
&lt;/h2&gt;&lt;p&gt;&lt;code&gt;VS Code&lt;/code&gt; 严格来说并不是传统意义上的 IDE，更准确地说，它是一个可扩展的代码编辑器。&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;对新手不够友好&lt;/li&gt;
&lt;li&gt;不能开箱即用地替代嵌入式 IDE 全流程&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;li&gt;语法高亮、跳转、搜索、重构体验更好&lt;/li&gt;
&lt;li&gt;对 AI 工具和 Agent 工作流支持更积极&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;在今天这个阶段，很多人真正需要的已经不只是“能写代码”，而是“写代码时能不能顺手把 AI 协作接进来”。从这个角度看，&lt;code&gt;VS Code&lt;/code&gt; 的优势几乎是肉眼可见的。&lt;/p&gt;
&lt;h2 id=&#34;clion体验不错但在嵌入式场景里不够主流&#34;&gt;CLion：体验不错，但在嵌入式场景里不够主流
&lt;/h2&gt;&lt;p&gt;&lt;code&gt;CLion&lt;/code&gt; 经常会被提到，因为它的 C/C++ 编码体验一直不差。&lt;/p&gt;
&lt;p&gt;但对很多嵌入式开发者来说，它的问题不一定出在“好不好用”，而是“值不值得切过去”：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;用的人相对少&lt;/li&gt;
&lt;li&gt;与现有嵌入式工程生态连接不如 &lt;code&gt;Keil&lt;/code&gt; 直接&lt;/li&gt;
&lt;li&gt;在 AI 协作这件事上，也未必比 &lt;code&gt;VS Code&lt;/code&gt; 更有现实优势&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;所以它更像是一个“理论上也能做得不错”的选项，但在今天的嵌入式主流工作流里，并不是最自然的那个核心。&lt;/p&gt;
&lt;h2 id=&#34;更现实的答案keil-负责编译调试vs-code-负责写代码&#34;&gt;更现实的答案：Keil 负责编译调试，VS Code 负责写代码
&lt;/h2&gt;&lt;p&gt;如果把上面这些工具拆开看，很容易得到一个更务实的结论：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;用 &lt;code&gt;Keil&lt;/code&gt; 保留现有工程生态、编译、下载和调试能力&lt;/li&gt;
&lt;li&gt;用 &lt;code&gt;VS Code&lt;/code&gt; 承担日常编码、搜索、跳转和 AI 协作&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;这套组合的价值在于，它不是试图用一个工具包打天下，而是让每个工具回到自己最擅长的位置。&lt;/p&gt;
&lt;p&gt;对很多嵌入式工程来说，&lt;code&gt;Keil&lt;/code&gt; 的生态根本绕不开。既然如此，与其强行把所有工作都塞回 &lt;code&gt;Keil&lt;/code&gt;，不如承认它更适合作为后端编译调试入口；而真正的编辑体验，则交给 &lt;code&gt;VS Code&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://knightli.com/2026/04/22/embedded-development-environment-keil-vscode-ai-2026/keil-vscode-ai-workflow.svg&#34;
	
	
	
	loading=&#34;lazy&#34;
	
		alt=&#34;Keil 与 VS Code 组合工作流示意图&#34;
	
	
&gt;&lt;/p&gt;
&lt;h2 id=&#34;为什么这套组合在-ai-时代更有优势&#34;&gt;为什么这套组合在 AI 时代更有优势
&lt;/h2&gt;&lt;p&gt;到了今天，开发环境的分界线已经不只是“编辑器顺不顺手”，而是“它能不能自然接入 AI”。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;VS Code&lt;/code&gt; 在这件事上有几个很现实的优势：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;AI 插件和 Agent 支持更活跃&lt;/li&gt;
&lt;li&gt;代码浏览体验更适合让 AI 读工程、改工程&lt;/li&gt;
&lt;li&gt;更容易和现代插件生态结合&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;这意味着你可以把嵌入式开发里最痛苦的一部分工作，开始交给 AI 帮你分担：&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;/ul&gt;
&lt;p&gt;这些事情过去不是不能做，而是做起来不顺。&lt;code&gt;VS Code&lt;/code&gt; 的意义不只是“更好看”，而是它更容易成为 AI 协作的工作台。&lt;/p&gt;
&lt;h2 id=&#34;关键补丁用插件把-vs-code-和-keil-工程接起来&#34;&gt;关键补丁：用插件把 VS Code 和 Keil 工程接起来
&lt;/h2&gt;&lt;p&gt;这套工作流能不能成立，核心不在口号，而在你能不能把 &lt;code&gt;VS Code&lt;/code&gt; 和 &lt;code&gt;Keil&lt;/code&gt; 工程接起来。&lt;/p&gt;
&lt;p&gt;比较实用的一类插件思路，是让 &lt;code&gt;VS Code&lt;/code&gt; 直接读取 &lt;code&gt;Keil&lt;/code&gt; 工程结构，并在编辑器内部调用 &lt;code&gt;Keil&lt;/code&gt; 后台程序完成：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;打开工程&lt;/li&gt;
&lt;li&gt;编译&lt;/li&gt;
&lt;li&gt;下载&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;这样一来，你日常写代码不用频繁在两个界面之间来回切，只有到了更重的调试环节，再回到 &lt;code&gt;Keil&lt;/code&gt; 里做单步、断点和寄存器观察。&lt;/p&gt;
&lt;p&gt;这类插件真正有价值的地方，不只是“少切几个窗口”，而是它让工作流连续起来了。&lt;/p&gt;
&lt;h2 id=&#34;不要忽视-cc-基础插件配置&#34;&gt;不要忽视 C/C++ 基础插件配置
&lt;/h2&gt;&lt;p&gt;如果你打算把 &lt;code&gt;VS Code&lt;/code&gt; 当作嵌入式主编辑器，一个非常基础但常被忽略的点是：一定要把 C/C++ 基础插件和工程索引配置好。&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;li&gt;头文件关系混乱&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;很多人会误以为是 &lt;code&gt;VS Code&lt;/code&gt; 不适合嵌入式，实际上往往只是工程索引和插件配置没接好。&lt;/p&gt;
&lt;p&gt;一旦这部分配置完整，&lt;code&gt;VS Code&lt;/code&gt; 才能真正发挥出它在阅读大型工程、搜索符号、配合 AI 辅助修改代码上的优势。&lt;/p&gt;
&lt;h2 id=&#34;这套工作流最适合谁&#34;&gt;这套工作流最适合谁
&lt;/h2&gt;&lt;p&gt;我觉得下面这几类人，会特别适合这种组合式环境：&lt;/p&gt;
&lt;h3 id=&#34;1-已经有大量-keil-工程的人&#34;&gt;1. 已经有大量 Keil 工程的人
&lt;/h3&gt;&lt;p&gt;如果你公司项目、课程资料或者历史代码都围绕 &lt;code&gt;Keil&lt;/code&gt; 展开，那就没必要为了“现代化”硬切掉原有生态。保留 &lt;code&gt;Keil&lt;/code&gt;，再补一个 &lt;code&gt;VS Code&lt;/code&gt; 前端，是迁移成本最低的做法。&lt;/p&gt;
&lt;h3 id=&#34;2-想用-ai-辅助写嵌入式代码的人&#34;&gt;2. 想用 AI 辅助写嵌入式代码的人
&lt;/h3&gt;&lt;p&gt;如果你已经习惯让 AI 帮你解释函数、补样板代码、改局部逻辑，那么 &lt;code&gt;VS Code&lt;/code&gt; 会比传统嵌入式 IDE 更自然地承接这件事。&lt;/p&gt;
&lt;h3 id=&#34;3-想同时兼顾学习资料和真实项目的人&#34;&gt;3. 想同时兼顾学习资料和真实项目的人
&lt;/h3&gt;&lt;p&gt;很多学习资料仍然建立在 &lt;code&gt;Keil&lt;/code&gt; 上，但你自己的工作流未必要停留在那个年代。把 &lt;code&gt;Keil&lt;/code&gt; 作为工程兼容层，把 &lt;code&gt;VS Code&lt;/code&gt; 作为生产力层，会更平衡。&lt;/p&gt;
&lt;h2 id=&#34;结语&#34;&gt;结语
&lt;/h2&gt;&lt;p&gt;到了 2026 年，嵌入式开发环境的关键问题，已经不再只是“哪个 IDE 功能更多”，而是“哪种组合最符合今天的工作方式”。&lt;/p&gt;
&lt;p&gt;如果你只想快速起步，&lt;code&gt;STM32CubeIDE&lt;/code&gt; 依然有它的位置；如果你要稳定接住大量既有工程，&lt;code&gt;Keil&lt;/code&gt; 依然绕不开；但如果你还想把现代编辑体验和 AI 协作一起接进来，那么更现实的答案，往往是：&lt;/p&gt;
&lt;p&gt;&lt;code&gt;Keil&lt;/code&gt; 负责编译和调试，&lt;code&gt;VS Code&lt;/code&gt; 负责写代码。&lt;/p&gt;
&lt;p&gt;这不一定是唯一答案，但很可能是当下最不拧巴的一种答案。&lt;/p&gt;
</description>
        </item>
        <item>
        <title>8 种常见配置文件格式怎么选：INI、XML、JSON、YAML、TOML 到 Markdown</title>
        <link>https://knightli.com/2026/04/22/common-config-file-formats-ini-xml-json-yaml-toml-markdown/</link>
        <pubDate>Wed, 22 Apr 2026 21:48:37 +0800</pubDate>
        
        <guid>https://knightli.com/2026/04/22/common-config-file-formats-ini-xml-json-yaml-toml-markdown/</guid>
        <description>&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;在 AI Agent 时代，配置文件这件事会不会发生变化&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;这篇文章就是围绕这个问题做的一次简洁整理。&lt;/p&gt;
&lt;h2 id=&#34;01-配置文件本质上是在协调人和机器&#34;&gt;01 配置文件，本质上是在协调“人”和“机器”
&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;
&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;ul&gt;
&lt;li&gt;解析要快&lt;/li&gt;
&lt;li&gt;规则要严，类型要清楚，最好没有歧义&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;这就是为什么配置文件格式总是在“人类友好”和“机器友好”之间拉扯。越适合人阅读的格式，机器往往解析更麻烦；越适合机器高效处理的格式，人写起来通常越容易崩溃。&lt;/p&gt;
&lt;h2 id=&#34;02-ini简单直白但能力有限&#34;&gt;02 INI：简单直白，但能力有限
&lt;/h2&gt;&lt;p&gt;先从 &lt;code&gt;INI&lt;/code&gt; 说起。&lt;/p&gt;
&lt;p&gt;它的优点非常直接：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;结构简单&lt;/li&gt;
&lt;li&gt;分区加键值对，几乎一眼就能看懂&lt;/li&gt;
&lt;li&gt;支持注释&lt;/li&gt;
&lt;li&gt;很适合一些轻量配置场景，比如游戏参数微调、基础环境设置&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;如果你改过老游戏配置，或者手动调过一些工具参数，基本都见过它。&lt;/p&gt;
&lt;p&gt;但 &lt;code&gt;INI&lt;/code&gt; 的问题也很明显。它的结构太扁平，原生不适合表达复杂嵌套和数组。再加上它通常缺少严格的类型系统，很多值本质上就是一串文本，最终怎么解释，要靠程序自己处理。&lt;/p&gt;
&lt;p&gt;所以 &lt;code&gt;INI&lt;/code&gt; 更像是一台老式但顺手的工具车，轻活很好用，复杂项目就容易力不从心。&lt;/p&gt;
&lt;p&gt;例如一个很典型的 &lt;code&gt;INI&lt;/code&gt; 配置会长这样：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;6
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-ini&#34; data-lang=&#34;ini&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;[server]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;na&#34;&gt;host&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;127.0.0.1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;na&#34;&gt;port&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;8080&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;[feature]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;na&#34;&gt;enable_cache&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;true&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h2 id=&#34;03-xml严谨稳定但写起来很累&#34;&gt;03 XML：严谨、稳定，但写起来很累
&lt;/h2&gt;&lt;p&gt;第二位是 &lt;code&gt;XML&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;如果你维护过老 Java 项目，或者见过一大堆成对闭合标签的配置文件，对它应该不陌生。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;XML&lt;/code&gt; 的优点是：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;层级结构明确&lt;/li&gt;
&lt;li&gt;支持注释&lt;/li&gt;
&lt;li&gt;规则严整&lt;/li&gt;
&lt;li&gt;可以配合 schema 做强校验&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;li&gt;稍微漏一个闭合标签，就可能整页报错&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;所以 &lt;code&gt;XML&lt;/code&gt; 非常像一份盖章齐全的正式合同。机器喜欢，人工维护 often 很累。如今很多新项目已经不再优先选它，但在一些老系统和严规则场景里，它依然没有完全退场。&lt;/p&gt;
&lt;p&gt;同样的配置如果写成 &lt;code&gt;XML&lt;/code&gt;，大概会是这样：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;7
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;8
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;9
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-xml&#34; data-lang=&#34;xml&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nt&#34;&gt;&amp;lt;config&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nt&#34;&gt;&amp;lt;server&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nt&#34;&gt;&amp;lt;host&amp;gt;&lt;/span&gt;127.0.0.1&lt;span class=&#34;nt&#34;&gt;&amp;lt;/host&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nt&#34;&gt;&amp;lt;port&amp;gt;&lt;/span&gt;8080&lt;span class=&#34;nt&#34;&gt;&amp;lt;/port&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nt&#34;&gt;&amp;lt;/server&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nt&#34;&gt;&amp;lt;feature&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nt&#34;&gt;&amp;lt;enable_cache&amp;gt;&lt;/span&gt;true&lt;span class=&#34;nt&#34;&gt;&amp;lt;/enable_cache&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nt&#34;&gt;&amp;lt;/feature&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nt&#34;&gt;&amp;lt;/config&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h2 id=&#34;04-json数据交换霸主但不适合手写复杂配置&#34;&gt;04 JSON：数据交换霸主，但不适合手写复杂配置
&lt;/h2&gt;&lt;p&gt;说到现代开发，&lt;code&gt;JSON&lt;/code&gt; 几乎绕不过去。&lt;/p&gt;
&lt;p&gt;对 &lt;code&gt;JSON&lt;/code&gt; 来说，一个很典型的判断是：作为数据交换格式，它非常强；但作为人工维护的配置文件，它有点别扭。&lt;/p&gt;
&lt;p&gt;它的优势包括：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;对象和数组结构清晰&lt;/li&gt;
&lt;li&gt;网络传输友好&lt;/li&gt;
&lt;li&gt;解析器成熟&lt;/li&gt;
&lt;li&gt;对 Web API 和前后端通信非常合适&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;尤其和 &lt;code&gt;XML&lt;/code&gt; 放在一起时，&lt;code&gt;JSON&lt;/code&gt; 的轻量优势会非常明显。同样的数据结构，&lt;code&gt;JSON&lt;/code&gt; 通常更短，也更适合在网络里传来传去。&lt;/p&gt;
&lt;p&gt;但它有个致命缺点：标准 &lt;code&gt;JSON&lt;/code&gt; 不支持注释。&lt;/p&gt;
&lt;p&gt;另外，它的语法也比较严格：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;key 必须带双引号&lt;/li&gt;
&lt;li&gt;最后一项后面不能多逗号&lt;/li&gt;
&lt;li&gt;少一个符号就会直接报错&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;所以 &lt;code&gt;JSON&lt;/code&gt; 很适合 API、服务之间的数据交换，却不总是适合手动维护、需要写说明、需要频繁修改的配置文件。&lt;/p&gt;
&lt;p&gt;比如：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;7
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;8
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;9
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-json&#34; data-lang=&#34;json&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nt&#34;&gt;&amp;#34;server&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nt&#34;&gt;&amp;#34;host&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;127.0.0.1&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nt&#34;&gt;&amp;#34;port&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;8080&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;p&#34;&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nt&#34;&gt;&amp;#34;feature&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nt&#34;&gt;&amp;#34;enable_cache&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;true&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h2 id=&#34;05-yaml可读性很强但缩进和隐式类型会坑你&#34;&gt;05 YAML：可读性很强，但缩进和隐式类型会坑你
&lt;/h2&gt;&lt;p&gt;如果你碰过 Docker、CI/CD、Kubernetes、自动化部署，基本一定和 &lt;code&gt;YAML&lt;/code&gt; 打过交道。&lt;/p&gt;
&lt;p&gt;它最吸引人的地方，就是看起来很“干净”：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;少了很多大括号和引号&lt;/li&gt;
&lt;li&gt;用缩进表达层级&lt;/li&gt;
&lt;li&gt;支持注释&lt;/li&gt;
&lt;li&gt;还能做锚点复用&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;所以从人的第一眼体验来说，&lt;code&gt;YAML&lt;/code&gt; 通常比 &lt;code&gt;JSON&lt;/code&gt; 友好得多。&lt;/p&gt;
&lt;p&gt;但问题也正出在这里。它把很多复杂性藏起来了，实际使用时经常出现两类经典事故：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;缩进地狱&lt;/li&gt;
&lt;li&gt;隐式类型转换&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;缩进问题很好理解，空格多一个少一个，配置就可能直接坏掉。更麻烦的是隐式类型转换，比如某些看起来像普通字符串的值，可能会被自动解释成布尔值或别的类型。&lt;/p&gt;
&lt;p&gt;这也是为什么很多人一边夸 &lt;code&gt;YAML&lt;/code&gt; 好看，一边又被它折腾得很惨。它在人类阅读体验上确实很好，但机器解析它时并不轻松，而且不同解析库之间还可能有细微差异。&lt;/p&gt;
&lt;p&gt;同样的配置写成 &lt;code&gt;YAML&lt;/code&gt;，通常会更清爽：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;6
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nt&#34;&gt;server&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;host&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;127.0.0.1&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;port&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;8080&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nt&#34;&gt;feature&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;enable_cache&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;true&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h2 id=&#34;06-toml在可读性和确定性之间找平衡&#34;&gt;06 TOML：在可读性和确定性之间找平衡
&lt;/h2&gt;&lt;p&gt;&lt;code&gt;TOML&lt;/code&gt; 经常被放在“当代均衡答案”的位置上。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;TOML&lt;/code&gt; 的好处在于，它有点像把 &lt;code&gt;INI&lt;/code&gt; 的直观和 &lt;code&gt;JSON&lt;/code&gt; 的类型明确结合在一起：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;支持注释&lt;/li&gt;
&lt;li&gt;结构清楚&lt;/li&gt;
&lt;li&gt;强类型更明确&lt;/li&gt;
&lt;li&gt;日期时间等常见类型支持更自然&lt;/li&gt;
&lt;li&gt;不容易出现 &lt;code&gt;YAML&lt;/code&gt; 那种隐式转换坑&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;尤其在现代工具链里，&lt;code&gt;TOML&lt;/code&gt; 已经越来越常见，比如 &lt;code&gt;Python&lt;/code&gt; 的 &lt;code&gt;pyproject.toml&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;当然它也不是没有缺点。对于很深层的嵌套结构，&lt;code&gt;TOML&lt;/code&gt; 会显得有点啰嗦，路径式书写写多了会烦。但如果场景是中小型项目配置、工具配置、包管理配置，&lt;code&gt;TOML&lt;/code&gt; 的整体体验往往比较稳。&lt;/p&gt;
&lt;p&gt;如果你想找一种“注释有、语义清、机器也不难受”的格式，&lt;code&gt;TOML&lt;/code&gt; 确实值得优先考虑。&lt;/p&gt;
&lt;p&gt;一个常见的 &lt;code&gt;TOML&lt;/code&gt; 写法会像这样：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;6
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-toml&#34; data-lang=&#34;toml&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;server&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nx&#34;&gt;host&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;127.0.0.1&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nx&#34;&gt;port&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;8080&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;feature&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nx&#34;&gt;enable_cache&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;true&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h2 id=&#34;07-conf-和-apache-配置不是通用格式而是领域语法&#34;&gt;07 &lt;code&gt;.conf&lt;/code&gt; 和 Apache 配置：不是通用格式，而是领域语法
&lt;/h2&gt;&lt;p&gt;有一点很值得提醒：很多人看到 &lt;code&gt;.conf&lt;/code&gt;，会误以为它是一种统一格式，其实不是。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;.conf&lt;/code&gt; 只是“configuration”的后缀名，里面到底怎么写，完全看具体系统自己的规则。也就是说，&lt;code&gt;.conf&lt;/code&gt; 更像一个大类，不是一套标准语法。&lt;/p&gt;
&lt;p&gt;拿 &lt;code&gt;Apache&lt;/code&gt; 配置举例，它的配置方式很有代表性：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;一部分像单行指令&lt;/li&gt;
&lt;li&gt;一部分又像带作用域的标签结构&lt;/li&gt;
&lt;li&gt;很适合 Web 服务器这种特定领域&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;优点是对运维场景很顺手，表达权限、路由、虚拟主机这类规则比较自然；问题是它几乎只服务于自己的生态，不具备很强的通用性。&lt;/p&gt;
&lt;p&gt;所以这类配置更像“领域专用语言”，在特定系统里很好用，但不适合拿来当通用配置格式看待。&lt;/p&gt;
&lt;p&gt;例如一个极简的 Apache 风格配置，会更像一组指令：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;6
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-apache&#34; data-lang=&#34;apache&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nb&#34;&gt;Listen&lt;/span&gt; &lt;span class=&#34;m&#34;&gt;80&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nt&#34;&gt;&amp;lt;VirtualHost&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;*:80&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nb&#34;&gt;ServerName&lt;/span&gt; example.com
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nb&#34;&gt;DocumentRoot&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;/var/www/html&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nt&#34;&gt;&amp;lt;/VirtualHost&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h2 id=&#34;08-protocol-buffers工业级强类型方案但门槛高&#34;&gt;08 Protocol Buffers：工业级强类型方案，但门槛高
&lt;/h2&gt;&lt;p&gt;&lt;code&gt;Protocol Buffers&lt;/code&gt; 其实已经不是传统意义上的“随手写个配置文件”了，而更像一套正式的数据定义和序列化方案。&lt;/p&gt;
&lt;p&gt;它的优势很强：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;强类型&lt;/li&gt;
&lt;li&gt;schema 明确&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;ul&gt;
&lt;li&gt;需要先写 &lt;code&gt;.proto&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;需要工具链和编译步骤&lt;/li&gt;
&lt;li&gt;对小项目来说门槛偏高&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;所以它不适合“我就配个小工具”的轻量场景，但如果你是在做大型系统、RPC、分布式服务或者长期演进的数据协议，它会比很多轻量配置格式更可靠。&lt;/p&gt;
&lt;p&gt;它的写法更接近“先定义结构，再生成代码”：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;7
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-proto&#34; data-lang=&#34;proto&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;syntax&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;proto3&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;err&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kd&#34;&gt;message&lt;/span&gt; &lt;span class=&#34;nc&#34;&gt;ServerConfig&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;kt&#34;&gt;string&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;host&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;kt&#34;&gt;int32&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;port&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;kt&#34;&gt;bool&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;enable_cache&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;3&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h2 id=&#34;09-在-ai-agent-时代markdown-可能重新变成配置方式&#34;&gt;09 在 AI Agent 时代，Markdown 可能重新变成“配置方式”
&lt;/h2&gt;&lt;p&gt;最有意思的部分，是把 &lt;code&gt;Markdown&lt;/code&gt; 也算进了“配置文件”的讨论里。&lt;/p&gt;
&lt;p&gt;这在传统程序视角里听起来有点奇怪，因为 &lt;code&gt;Markdown&lt;/code&gt; 本来更像文档格式。但如果把对象换成大语言模型和 AI Agent，这个判断其实是成立的。&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;列表就是步骤&lt;/li&gt;
&lt;li&gt;加粗就是强调&lt;/li&gt;
&lt;li&gt;自然语言本身就能承载规则&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;也就是说，当配置对象从“死板的解析器”变成“能读懂语义的 Agent”，&lt;code&gt;Markdown&lt;/code&gt; 这类人类友好的结构化文本，反而可能成为一种更自然的配置形式。&lt;/p&gt;
&lt;p&gt;这也是一个很关键的判断：在传统软件时代，很多配置格式是为了让人去适应机器；而在 AI 时代，机器开始反过来适应人的表达。&lt;/p&gt;
&lt;p&gt;比如给 Agent 写任务配置，完全可能直接写成这样：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;12
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;13
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;14
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-markdown&#34; data-lang=&#34;markdown&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;gh&#34;&gt;# 任务目标
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;为新用户写一封欢迎邮件。
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;gu&#34;&gt;## 要求
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;-&lt;/span&gt; 语气友好
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;-&lt;/span&gt; 不超过 150 字
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;-&lt;/span&gt; 提到产品的 3 个核心功能
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;gu&#34;&gt;## 禁止事项
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;-&lt;/span&gt; 不要承诺不存在的功能
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;-&lt;/span&gt; 不要使用夸张营销语气
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h2 id=&#34;10-到底该怎么选&#34;&gt;10 到底该怎么选
&lt;/h2&gt;&lt;p&gt;如果把这些观点压缩一下，我觉得可以简单分成这样几类：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;想要极简、轻量、扁平配置：&lt;code&gt;INI&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;想要强结构、强校验、老系统兼容：&lt;code&gt;XML&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;想要网络传输和接口交换：&lt;code&gt;JSON&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;想要高可读性、云原生和部署配置：&lt;code&gt;YAML&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;想要更稳的现代通用配置体验：&lt;code&gt;TOML&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;想要特定系统内部规则：&lt;code&gt;.conf&lt;/code&gt; / &lt;code&gt;Apache&lt;/code&gt; 一类 DSL&lt;/li&gt;
&lt;li&gt;想要工业级协议和长期演进能力：&lt;code&gt;Protocol Buffers&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;面向 AI Agent 的自然表达和任务编排：&lt;code&gt;Markdown&lt;/code&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;li&gt;为服务之间通信&lt;/li&gt;
&lt;li&gt;还是为 AI Agent 理解和执行&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;简单总结&#34;&gt;简单总结
&lt;/h2&gt;&lt;p&gt;配置文件的发展史，本质上就是人和机器不断重新分配理解成本的过程。&lt;/p&gt;
&lt;p&gt;过去是人迁就机器，所以我们要记各种括号、缩进、引号和严格规则。现在随着大语言模型和 Agent 系统越来越成熟，机器开始更能理解自然表达，于是“配置”这件事本身也在变化。&lt;/p&gt;
&lt;p&gt;也许未来很多场景里，配置文件不再是某种固定格式，而更像一段结构化意图说明。而在那之前，&lt;code&gt;JSON&lt;/code&gt;、&lt;code&gt;YAML&lt;/code&gt;、&lt;code&gt;TOML&lt;/code&gt;、&lt;code&gt;INI&lt;/code&gt;、&lt;code&gt;XML&lt;/code&gt; 这些格式依然会长期共存，各自占据最适合自己的位置。&lt;/p&gt;
</description>
        </item>
        <item>
        <title>Windows 上在 VS Code 里构建 Docker 镜像：从环境准备到一键构建</title>
        <link>https://knightli.com/2026/04/16/vscode-docker-image-build-windows/</link>
        <pubDate>Thu, 16 Apr 2026 10:20:00 +0800</pubDate>
        
        <guid>https://knightli.com/2026/04/16/vscode-docker-image-build-windows/</guid>
        <description>&lt;p&gt;如果你想在 Windows 上直接用 VS Code 管理并构建 Docker 镜像，流程其实很短。核心就是三步：先把环境装好，再准备 Dockerfile，最后执行构建。&lt;/p&gt;
&lt;h2 id=&#34;01-前置准备&#34;&gt;01 前置准备
&lt;/h2&gt;&lt;p&gt;先确认两项基础条件：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;安装并启动 Docker Desktop。&lt;/li&gt;
&lt;li&gt;在 VS Code 里安装 Microsoft 官方 &lt;code&gt;Docker&lt;/code&gt; 扩展。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;在 Windows 上，建议把 Docker Desktop 切到 &lt;code&gt;WSL 2&lt;/code&gt; 后端（&lt;code&gt;Settings &amp;gt; Resources &amp;gt; WSL Integration&lt;/code&gt;），一般会更稳定、性能也更好。&lt;/p&gt;
&lt;h2 id=&#34;02-准备-dockerfile&#34;&gt;02 准备 Dockerfile
&lt;/h2&gt;&lt;p&gt;如果项目里还没有 Dockerfile，可以直接让 VS Code 生成：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;在 VS Code 打开你的项目目录。&lt;/li&gt;
&lt;li&gt;按 &lt;code&gt;F1&lt;/code&gt; 或 &lt;code&gt;Ctrl+Shift+P&lt;/code&gt; 打开命令面板。&lt;/li&gt;
&lt;li&gt;运行 &lt;code&gt;Docker: Add Docker Files to Workspace&lt;/code&gt;。&lt;/li&gt;
&lt;li&gt;选择你的平台（例如 Node.js、Python、.NET），按提示完成。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;执行后通常会得到至少两个文件：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;Dockerfile&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;.dockerignore&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;这一步的价值是先有一个可工作的基础版本，后面再按项目需求微调。&lt;/p&gt;
&lt;h2 id=&#34;03-构建镜像的三种方式&#34;&gt;03 构建镜像的三种方式
&lt;/h2&gt;&lt;h3 id=&#34;方式-a右键-dockerfile&#34;&gt;方式 A：右键 Dockerfile
&lt;/h3&gt;&lt;p&gt;在资源管理器中右键 &lt;code&gt;Dockerfile&lt;/code&gt;，选择 &lt;code&gt;Build Image...&lt;/code&gt;，然后输入镜像标签（tag）。&lt;/p&gt;
&lt;h3 id=&#34;方式-b命令面板&#34;&gt;方式 B：命令面板
&lt;/h3&gt;&lt;p&gt;按 &lt;code&gt;F1&lt;/code&gt; 运行 &lt;code&gt;Docker: Build Image&lt;/code&gt;，再按提示选择上下文和标签。&lt;/p&gt;
&lt;h3 id=&#34;方式-c集成终端命令&#34;&gt;方式 C：集成终端命令
&lt;/h3&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;docker build -t your-image-name .
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;这条命令表示用当前目录作为构建上下文，生成名为 &lt;code&gt;your-image-name&lt;/code&gt; 的镜像。&lt;/p&gt;
&lt;h2 id=&#34;04-常见问题快速检查&#34;&gt;04 常见问题快速检查
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;Docker Desktop 没启动：先确认托盘图标显示为运行状态。&lt;/li&gt;
&lt;li&gt;构建很慢：优先检查是否启用 WSL 2 后端。&lt;/li&gt;
&lt;li&gt;构建失败提示找不到文件：确认执行目录是项目根目录，且 &lt;code&gt;Dockerfile&lt;/code&gt; 在上下文内。&lt;/li&gt;
&lt;li&gt;扩展看不到 Docker 资源：重启一次 VS Code，或确认 Docker CLI 可用（&lt;code&gt;docker version&lt;/code&gt;）。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;小结&#34;&gt;小结
&lt;/h2&gt;&lt;p&gt;在 Windows 上用 VS Code 构建 Docker 镜像并不复杂。先安装 Docker Desktop 和 Docker 扩展，再用命令面板生成 Dockerfile，最后用右键或 &lt;code&gt;docker build&lt;/code&gt; 即可完成日常构建流程。&lt;/p&gt;
</description>
        </item>
        <item>
        <title>CH347 开发常用资源整理：驱动、工具与 SPI Flash 刷写</title>
        <link>https://knightli.com/2026/04/03/ch347-resources-drivers-tools/</link>
        <pubDate>Fri, 03 Apr 2026 10:00:00 +0800</pubDate>
        
        <guid>https://knightli.com/2026/04/03/ch347-resources-drivers-tools/</guid>
        <description>&lt;p&gt;这篇文章整理我在使用 CH347 时最常用的一组资源，目标是开箱就能开始调试和刷写。&lt;/p&gt;
&lt;p&gt;如果你刚接触 CH347，建议按下面顺序准备环境：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;先看官方产品页确认资料入口&lt;/li&gt;
&lt;li&gt;按用途安装对应驱动&lt;/li&gt;
&lt;li&gt;准备 SPI Flash 刷写工具并做连通性验证&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&#34;官方入口&#34;&gt;官方入口
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;CH347 产品页：https://www.wch.cn/products/CH347.html&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;建议优先从官方页面进入下载区，避免拿到来源不明或版本过旧的驱动包。&lt;/p&gt;
&lt;h2 id=&#34;常用驱动&#34;&gt;常用驱动
&lt;/h2&gt;&lt;h3 id=&#34;1-ch341parexe&#34;&gt;1) &lt;code&gt;CH341PAR.EXE&lt;/code&gt;
&lt;/h3&gt;&lt;p&gt;用途：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;USB 转 JTAG / SPI / I2C / 并口 / GPIO 等接口驱动&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;适用场景：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;你需要用 CH347 做多协议通信或底层接口调试时&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;2-ch343serexe&#34;&gt;2) &lt;code&gt;CH343SER.EXE&lt;/code&gt;
&lt;/h3&gt;&lt;p&gt;用途：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;USB 转高速串口 Windows 厂商驱动&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;适用场景：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;主要把 CH347 当串口工具使用，且需要较高串口速率时&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;spi-flash-刷写工具&#34;&gt;SPI Flash 刷写工具
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;AsProgrammer：https://github.com/nofeletru/UsbAsp-flash&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;常见用途：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;识别 SPI NOR Flash&lt;/li&gt;
&lt;li&gt;读取芯片 ID&lt;/li&gt;
&lt;li&gt;备份原始固件&lt;/li&gt;
&lt;li&gt;擦除/写入/校验固件&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;推荐操作顺序避免踩坑&#34;&gt;推荐操作顺序（避免踩坑）
&lt;/h2&gt;&lt;ol&gt;
&lt;li&gt;安装驱动后重新插拔设备，再打开设备管理器确认是否识别正常。&lt;/li&gt;
&lt;li&gt;第一次刷写前先执行一次“读取 + 备份”，保留原厂内容。&lt;/li&gt;
&lt;li&gt;写入后一定做校验（verify），不要只看“写入成功”提示。&lt;/li&gt;
&lt;li&gt;如果识别不到芯片，优先检查供电、电平和接线，再检查软件配置。&lt;/li&gt;
&lt;/ol&gt;
</description>
        </item>
        <item>
        <title>FFmpeg 的 `-map` 参数详解：精准选择视频、音频与字幕流</title>
        <link>https://knightli.com/2026/04/02/ffmpeg-map-parameter-guide/</link>
        <pubDate>Thu, 02 Apr 2026 23:14:03 +0800</pubDate>
        
        <guid>https://knightli.com/2026/04/02/ffmpeg-map-parameter-guide/</guid>
        <description>&lt;p&gt;在多音轨、多字幕的视频处理中，&lt;code&gt;-map&lt;/code&gt; 是 FFmpeg 最关键也最容易用错的参数之一。&lt;/p&gt;
&lt;p&gt;如果你不显式指定 &lt;code&gt;-map&lt;/code&gt;，FFmpeg 会按默认规则自动挑选流，结果常常不是你想要的。比如：&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;code&gt;-map&lt;/code&gt; 怎么用。&lt;/p&gt;
&lt;h2 id=&#34;先理解什么是流&#34;&gt;先理解什么是“流”
&lt;/h2&gt;&lt;p&gt;一个容器文件（例如 &lt;code&gt;mp4&lt;/code&gt;、&lt;code&gt;mkv&lt;/code&gt;）里通常不止一个内容流（stream），常见包括：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;视频流（&lt;code&gt;v&lt;/code&gt;）&lt;/li&gt;
&lt;li&gt;音频流（&lt;code&gt;a&lt;/code&gt;）&lt;/li&gt;
&lt;li&gt;字幕流（&lt;code&gt;s&lt;/code&gt;）&lt;/li&gt;
&lt;li&gt;附件/数据流（如字体、封面、章节等）&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;你可以先用 &lt;code&gt;ffprobe&lt;/code&gt; 看清文件里有什么流：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;ffprobe -hide_banner input.mkv
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h2 id=&#34;-map-的基本语法&#34;&gt;&lt;code&gt;-map&lt;/code&gt; 的基本语法
&lt;/h2&gt;&lt;p&gt;最常见写法：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;-map input_index[:stream_type][:stream_index]
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;例如：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;0:v&lt;/code&gt;：第 1 个输入文件的所有视频流&lt;/li&gt;
&lt;li&gt;&lt;code&gt;0:a:0&lt;/code&gt;：第 1 个输入文件的第 1 条音频流&lt;/li&gt;
&lt;li&gt;&lt;code&gt;1:s:1&lt;/code&gt;：第 2 个输入文件的第 2 条字幕流&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;说明：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;input_index&lt;/code&gt; 从 &lt;code&gt;0&lt;/code&gt; 开始，对应 &lt;code&gt;-i&lt;/code&gt; 的顺序&lt;/li&gt;
&lt;li&gt;&lt;code&gt;stream_index&lt;/code&gt; 也从 &lt;code&gt;0&lt;/code&gt; 开始&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;实战示例&#34;&gt;实战示例
&lt;/h2&gt;&lt;h3 id=&#34;1-视频来自-a音频来自-b&#34;&gt;1) 视频来自 A，音频来自 B
&lt;/h3&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;ffmpeg -i english.mp4 -i french.mp3 &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  -map 0:v:0 -map 1:a:0 &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  -c:v copy -c:a aac &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  french.mp4
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;含义：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;取 &lt;code&gt;english.mp4&lt;/code&gt; 的第 1 条视频流&lt;/li&gt;
&lt;li&gt;取 &lt;code&gt;french.mp3&lt;/code&gt; 的第 1 条音频流&lt;/li&gt;
&lt;li&gt;合并输出为 &lt;code&gt;french.mp4&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;2-保留第一个输入的全部流再额外加一条音轨&#34;&gt;2) 保留第一个输入的全部流，再额外加一条音轨
&lt;/h3&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;ffmpeg -i english.mp4 -i french.mp3 &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  -map &lt;span class=&#34;m&#34;&gt;0&lt;/span&gt; -map 1:a:0 &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  -c copy &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  english-french.mp4
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;含义：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;-map 0&lt;/code&gt; 先把第一个输入文件中的所有流都带上&lt;/li&gt;
&lt;li&gt;再追加第二个输入的第 1 条音频流&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;两个很实用的进阶技巧&#34;&gt;两个很实用的进阶技巧
&lt;/h2&gt;&lt;h3 id=&#34;1-负映射排除不想要的流&#34;&gt;1) 负映射：排除不想要的流
&lt;/h3&gt;&lt;p&gt;例如保留第一个输入的全部流，但去掉第 2 条音频流：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;ffmpeg -i input.mkv -map &lt;span class=&#34;m&#34;&gt;0&lt;/span&gt; -map -0:a:1 -c copy output.mkv
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h3 id=&#34;2-可选映射流不存在也不中断&#34;&gt;2) 可选映射：流不存在也不中断
&lt;/h3&gt;&lt;p&gt;某些文件可能没有字幕，这时可以用 &lt;code&gt;?&lt;/code&gt;：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;ffmpeg -i input.mp4 -map 0:v -map 0:a -map 0:s? -c copy output.mp4
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;&lt;code&gt;0:s?&lt;/code&gt; 表示“有字幕就映射，没有就跳过，不报错”。&lt;/p&gt;
&lt;h2 id=&#34;常见坑位&#34;&gt;常见坑位
&lt;/h2&gt;&lt;ol&gt;
&lt;li&gt;&lt;code&gt;-map&lt;/code&gt; 一旦使用，FFmpeg 就不再按默认自动选流，必须把你要的都写出来。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-c copy&lt;/code&gt; 只是封装复制，不做转码；若目标容器不支持某编码，仍会失败。&lt;/li&gt;
&lt;li&gt;多输入时最容易错的是输入序号，记住序号只看 &lt;code&gt;-i&lt;/code&gt; 的先后顺序。&lt;/li&gt;
&lt;li&gt;想做稳定脚本时，先 &lt;code&gt;ffprobe&lt;/code&gt; 再生成 &lt;code&gt;-map&lt;/code&gt;，比手写更稳。&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&#34;总结&#34;&gt;总结
&lt;/h2&gt;&lt;p&gt;&lt;code&gt;-map&lt;/code&gt; 的核心就是一句话：明确告诉 FFmpeg，“从哪个输入，拿哪类流，拿第几条”。&lt;/p&gt;
&lt;p&gt;掌握它之后，你就能稳定处理多音轨、多字幕、跨文件拼接等复杂场景，避免“导出结果不对但又不知道为什么”的问题。&lt;/p&gt;
</description>
        </item>
        <item>
        <title>如何排查由插件引起的 VS Code CPU 占用过高</title>
        <link>https://knightli.com/2026/04/01/vscode-extension-cpu-troubleshooting/</link>
        <pubDate>Wed, 01 Apr 2026 00:00:00 +0000</pubDate>
        
        <guid>https://knightli.com/2026/04/01/vscode-extension-cpu-troubleshooting/</guid>
        <description>&lt;p&gt;VS Code 突然变卡、风扇狂转、CPU 长时间高占用时，最常见原因通常不是编辑器本体，而是扩展插件冲突或插件行为异常。&lt;/p&gt;
&lt;p&gt;这篇文章给你一套可以立即执行的排查路径，优先用最省时间的方法定位问题。&lt;/p&gt;
&lt;h2 id=&#34;先做最快的定位start-extension-bisect&#34;&gt;先做最快的定位：Start Extension Bisect
&lt;/h2&gt;&lt;p&gt;&lt;code&gt;Start Extension Bisect&lt;/code&gt; 的核心思路是二分法：
每一轮临时禁用一半扩展并重启，通过你反馈“问题是否仍存在”，快速缩小范围，直到定位到可疑插件。&lt;/p&gt;
&lt;p&gt;操作步骤：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;按 &lt;code&gt;Ctrl+Shift+P&lt;/code&gt;（macOS 为 &lt;code&gt;Cmd+Shift+P&lt;/code&gt;）打开命令面板。&lt;/li&gt;
&lt;li&gt;输入并执行 &lt;code&gt;Start Extension Bisect&lt;/code&gt;。&lt;/li&gt;
&lt;li&gt;每次重启后观察 CPU 占用和卡顿是否复现。&lt;/li&gt;
&lt;li&gt;重复几轮后，VS Code 会给出可疑扩展列表。&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&#34;定位后怎么处理&#34;&gt;定位后怎么处理
&lt;/h2&gt;&lt;p&gt;找到可疑插件后，建议按这个顺序处理：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;先更新插件到最新版本。&lt;/li&gt;
&lt;li&gt;若无改善，临时禁用该插件 1-2 天观察。&lt;/li&gt;
&lt;li&gt;对于功能可替代的插件，优先换成更轻量方案。&lt;/li&gt;
&lt;li&gt;若必须使用该插件，检查它的高级配置，关闭不必要的实时分析、索引或监听功能。&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&#34;两个容易被忽略的放大器&#34;&gt;两个容易被忽略的“放大器”
&lt;/h2&gt;&lt;p&gt;即使主因是插件，以下配置也会放大 CPU 问题：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;搜索范围过大&lt;br&gt;
例如把构建产物、依赖目录、日志目录也纳入全局搜索，会让插件和文件索引持续高负载。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;文件监控包含大目录或软链接&lt;br&gt;
软链接、缓存目录、自动生成目录容易触发大量文件事件，导致扩展反复工作。&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;可以在 &lt;code&gt;settings.json&lt;/code&gt; 中适当排除目录，例如：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;12
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-json&#34; data-lang=&#34;json&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nt&#34;&gt;&amp;#34;search.exclude&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nt&#34;&gt;&amp;#34;**/node_modules&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;true&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nt&#34;&gt;&amp;#34;**/dist&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;true&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nt&#34;&gt;&amp;#34;**/build&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;true&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;p&#34;&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nt&#34;&gt;&amp;#34;files.watcherExclude&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nt&#34;&gt;&amp;#34;**/.git/objects/**&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;true&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nt&#34;&gt;&amp;#34;**/node_modules/**&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;true&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nt&#34;&gt;&amp;#34;**/dist/**&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;true&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h2 id=&#34;复盘建议&#34;&gt;复盘建议
&lt;/h2&gt;&lt;p&gt;如果你已经定位到问题插件，建议记录三件事：插件名称、触发场景、最终处理方式。&lt;br&gt;
这样下次迁移环境或重装系统时，可以快速避开同类问题。&lt;/p&gt;
&lt;h2 id=&#34;总结&#34;&gt;总结
&lt;/h2&gt;&lt;p&gt;VS Code 高 CPU 占用的排查，最有效路径是先用 &lt;code&gt;Start Extension Bisect&lt;/code&gt; 快速定位，再结合搜索和文件监控范围做收敛。&lt;br&gt;
先定位，再优化，比“盲目禁用一堆插件”更省时间，也更稳定。&lt;/p&gt;
</description>
        </item>
        
    </channel>
</rss>
