<!DOCTYPE html><html lang="zh" data-theme="dark"><head><meta charset="utf-8"><meta name="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1"><title>了解 Kagi 的历史 · Cytrogen 的个人博客</title><meta name="description" content="上个月我在 Kagi Store 上下单了 Kagi 的 T 恤衫、袜子周边。不为别的,Kagi 的吉祥物设计很可爱,画风很独特。 不过在搜寻时我发现了这个 Hacker News 链接,也迫使我不得不去探索 Kagi,这个大概被我神话过头的公司。"><link rel="icon" href="../favicon.png"><link rel="canonical" href="https://blog.cytrogen.icu/posts/c2db.html"><link rel="webmention" href="https://webmention.io/blog.cytrogen.icu/webmention"><link rel="me" href="https://gts.cytrogen.icu/@Cytrogen"><link rel="me" href="mailto:blog@cytrogen.icu"><meta name="fediverse:creator" content="@Cytrogen@gts.cytrogen.icu"><link rel="preload" href="../fonts/opensans-regular-latin.woff2" as="font" type="font/woff2" crossorigin="anonymous"><style>@font-face {
font-family: 'Open Sans';
src: url('../fonts/opensans-regular-latin.woff2') format('woff2');
font-weight: 400;
font-style: normal;
font-display: swap;
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
size-adjust: 107%;
ascent-override: 97%;
descent-override: 25%;
line-gap-override: 0%;
}
</style><script>(function() {
try {
// 优先级:用户选择 > 系统偏好 > 默认浅色
const saved = localStorage.getItem('theme');
const theme = saved ||
(window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light');
document.documentElement.setAttribute('data-theme', theme);
document.documentElement.style.colorScheme = theme;
} catch (error) {
// 失败时使用默认主题,不阻塞渲染
document.documentElement.setAttribute('data-theme', 'light');
}
})();
</script><link rel="stylesheet" href="../css/ares.css"><script data-netlify-skip-bundle="true">(function() {
document.addEventListener('DOMContentLoaded', function() {
const theme = document.documentElement.getAttribute('data-theme');
const pageWrapper = document.getElementById('page-wrapper');
if (pageWrapper && theme) {
pageWrapper.setAttribute('data-theme', theme);
}
});
})();
</script><!-- hexo injector head_end start -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@0.12.0/dist/katex.min.css">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/hexo-math@4.0.0/dist/style.css">
<!-- hexo injector head_end end --><meta name="generator" content="Hexo 8.1.1"><link rel="alternate" href="atom.xml" title="Cytrogen 的个人博客" type="application/atom+xml">
</head><body><div id="page-wrapper"><a class="skip-link" href="#main-content">跳到主要内容</a><div class="wrap"><header><a class="logo-link" href="../index.html"><img src="../favicon.png" alt="logo"></a><div class="h-card visually-hidden"><img class="u-photo" src="https://blog.cytrogen.icu/favicon.png" alt="Cytrogen"><a class="p-name u-url u-uid" href="https://blog.cytrogen.icu">Cytrogen</a><p class="p-note">Cytrogen 的个人博客,Cytrogen's Blog</p><a class="u-url" rel="me noopener" target="_blank" href="https://gts.cytrogen.icu/@Cytrogen">Mastodon</a></div><nav class="site-nav"><div class="nav-main"><div class="nav-primary"><ul class="nav-list hidden-mobile"><li class="nav-item"><a class="nav-link" href="../index.html">首页</a></li></ul><div class="nav-tools"><div class="language-menu"><button class="language-toggle" type="button"><svg class="icon icon-globe" width="16" height="16" viewBox="0 0 16 16" fill="currentColor" aria-hidden="true" focusable="false"><path d="M0 8a8 8 0 1 1 16 0A8 8 0 0 1 0 8zm7.5-6.923c-.67.204-1.335.82-1.887 1.855A7.97 7.97 0 0 0 5.145 4H7.5V1.077zM4.09 4a9.267 9.267 0 0 1 .64-1.539 6.7 6.7 0 0 1 .597-.933A7.025 7.025 0 0 0 2.255 4H4.09zm-.582 3.5c.03-.877.138-1.718.312-2.5H1.674a6.958 6.958 0 0 0-.656 2.5h2.49zM4.847 5a12.5 12.5 0 0 0-.338 2.5H7.5V5H4.847zM8.5 5v2.5h2.99a12.495 12.495 0 0 0-.337-2.5H8.5zM4.51 8.5a12.5 12.5 0 0 0 .337 2.5H7.5V8.5H4.51zm3.99 0V11h2.653c.187-.765.306-1.608.338-2.5H8.5zM5.145 12c.138.386.295.744.468 1.068.552 1.035 1.218 1.65 1.887 1.855V12H5.145zm.182 2.472a6.696 6.696 0 0 1-.597-.933A9.268 9.268 0 0 1 4.09 12H2.255a7.024 7.024 0 0 0 3.072 2.472zM3.82 11a13.652 13.652 0 0 1-.312-2.5h-2.49c.062.89.291 1.733.656 2.5H3.82zm6.853 3.472A7.024 7.024 0 0 0 13.745 12H11.91a9.27 9.27 0 0 1-.64 1.539 6.688 6.688 0 0 1-.597.933zM8.5 12v2.923c.67-.204 1.335-.82 1.887-1.855A7.97 7.97 0 0 0 10.855 12H8.5zm3.68-1h2.146c.365-.767.594-1.61.656-2.5h-2.49a13.65 13.65 0 0 1-.312 2.5zm2.802-3.5a6.959 6.959 0 0 0-.656-2.5H12.18c.174.782.282 1.623.312 2.5h2.49zM11.27 2.461c.247.464.462.98.64 1.539h1.835a7.024 7.024 0 0 0-3.072-2.472c.218.284.418.598.597.933zM10.855 4a7.966 7.966 0 0 0-.468-1.068C9.835 1.897 9.17 1.282 8.5 1.077V4h2.355z"></path></svg><span>中文</span></button><div class="language-dropdown"></div></div></div><div class="nav-controls"><div class="more-menu hidden-mobile"><button class="more-toggle" type="button"><span>更多</span><svg class="icon icon-chevron-down" width="12" height="12" viewBox="0 0 12 12" fill="currentColor" aria-hidden="true" focusable="false"><path d="M6 8.825c-.2 0-.4-.1-.5-.2l-3.3-3.3c-.3-.3-.3-.8 0-1.1s.8-.3 1.1 0l2.7 2.7 2.7-2.7c.3-.3.8-.3 1.1 0s.3.8 0 1.1l-3.3 3.3c-.1.1-.3.2-.5.2z"></path></svg></button><div class="more-dropdown"><ul class="dropdown-list"><li class="dropdown-item"><a class="nav-link" href="../archives/index.html">归档</a></li><li class="dropdown-item"><a class="nav-link" href="../categories/index.html">分类</a></li><li class="dropdown-item"><a class="nav-link" href="../tags/index.html">标签</a></li><li class="dropdown-item"><a class="nav-link" href="../about/index.html">关于</a></li><li class="dropdown-item"><a class="nav-link" href="../sitemap/index.html">领地地图</a></li></ul></div></div><div class="theme-switcher"><button class="theme-toggle" type="button" role="switch" aria-pressed="false" aria-label="切换主题"><div class="theme-icon moon-icon"><svg class="icon icon-moon" width="16" height="16" viewBox="0 0 16 16" fill="currentColor" aria-hidden="true" focusable="false"><path d="M6 .278a.768.768 0 0 1 .08.858 7.208 7.208 0 0 0-.878 3.46c0 4.021 3.278 7.277 7.318 7.277.527 0 1.04-.055 1.533-.16a.787.787 0 0 1 .81.316.733.733 0 0 1-.031.893A8.349 8.349 0 0 1 8.344 16C3.734 16 0 12.286 0 7.71 0 4.266 2.114 1.312 5.124.06A.752.752 0 0 1 6 .278z"></path></svg></div><div class="theme-icon sun-icon"><svg class="icon icon-sun" width="16" height="16" viewBox="0 0 16 16" fill="currentColor" aria-hidden="true" focusable="false"><path d="M8 11a3 3 0 1 1 0-6 3 3 0 0 1 0 6zm0 1a4 4 0 1 0 0-8 4 4 0 0 0 0 8zM8 0a.5.5 0 0 1 .5.5v2a.5.5 0 0 1-1 0v-2A.5.5 0 0 1 8 0zm0 13a.5.5 0 0 1 .5.5v2a.5.5 0 0 1-1 0v-2A.5.5 0 0 1 8 13zm8-5a.5.5 0 0 1-.5.5h-2a.5.5 0 0 1 0-1h2a.5.5 0 0 1 .5.5zM3 8a.5.5 0 0 1-.5.5h-2a.5.5 0 0 1 0-1h2A.5.5 0 0 1 3 8zm10.657-5.657a.5.5 0 0 1 0 .707l-1.414 1.415a.5.5 0 1 1-.707-.708l1.414-1.414a.5.5 0 0 1 .707 0zm-9.193 9.193a.5.5 0 0 1 0 .707L3.05 13.657a.5.5 0 0 1-.707-.707l1.414-1.414a.5.5 0 0 1 .707 0zm9.193 2.121a.5.5 0 0 1-.707 0l-1.414-1.414a.5.5 0 0 1 .707-.707l1.414 1.414a.5.5 0 0 1 0 .707zM4.464 4.465a.5.5 0 0 1-.707 0L2.343 3.05a.5.5 0 1 1 .707-.707l1.414 1.414a.5.5 0 0 1 0 .708z"></path></svg></div></button></div><details class="mobile-menu-details hidden-desktop"><summary class="hamburger-menu" aria-label="nav.menu"><svg class="icon icon-bars" width="16" height="16" viewBox="0 0 16 16" fill="currentColor" aria-hidden="true" focusable="false"><path d="M2.5 12a.5.5 0 0 1 .5-.5h10a.5.5 0 0 1 0 1H3a.5.5 0 0 1-.5-.5zm0-4a.5.5 0 0 1 .5-.5h10a.5.5 0 0 1 0 1H3a.5.5 0 0 1-.5-.5zm0-4a.5.5 0 0 1 .5-.5h10a.5.5 0 0 1 0 1H3a.5.5 0 0 1-.5-.5z"></path></svg><span class="menu-text">nav.menu</span></summary><div class="mobile-menu-dropdown"><ul class="mobile-nav-list"><li class="mobile-nav-item"><a class="mobile-nav-link" href="../index.html">首页</a></li><li class="mobile-nav-item"><a class="mobile-nav-link" href="../archives/index.html">归档</a></li><li class="mobile-nav-item"><a class="mobile-nav-link" href="../categories/index.html">分类</a></li><li class="mobile-nav-item"><a class="mobile-nav-link" href="../tags/index.html">标签</a></li><li class="mobile-nav-item"><a class="mobile-nav-link" href="../about/index.html">关于</a></li><li class="mobile-nav-item"><a class="mobile-nav-link" href="../sitemap/index.html">领地地图</a></li></ul></div></details></div></div></div></nav></header><main class="container" id="main-content" tabindex="-1"><div class="post"><article class="post-block h-entry"><div class="post-meta p-author h-card visually-hidden"><img class="author-avatar u-photo" src="../favicon.png" alt="Cytrogen"><span class="p-name">Cytrogen</span><a class="u-url" href="https://blog.cytrogen.icu">https://blog.cytrogen.icu</a></div><a class="post-permalink u-url u-uid visually-hidden" href="https://blog.cytrogen.icu/posts/c2db.html">永久链接</a><div class="p-summary visually-hidden"><p>上个月我在 <a target="_blank" rel="noopener" href="https://store.kagi.com/">Kagi Store</a> 上下单了 Kagi 的 T 恤衫、袜子周边。不为别的,Kagi 的吉祥物设计很可爱,画风很独特。</p>
<p>不过在搜寻时我发现了这个 Hacker News <a target="_blank" rel="noopener" href="https://news.ycombinator.com/item?id=40011314">链接</a>,也迫使我不得不去探索 Kagi,这个大概被我神话过头的公司。</p></div><div class="visually-hidden"><a class="p-category" href="../categories/%E4%B8%AA%E4%BA%BA%E9%9A%8F%E6%83%B3/">个人随想</a></div><a class="u-syndication visually-hidden" target="_blank" rel="noopener" href="https://gts.cytrogen.icu/@cytrogen/statuses/01KNFCMC1V8VYWEB5650KB5F09">https://gts.cytrogen.icu/@cytrogen/statuses/01KNFCMC1V8VYWEB5650KB5F09</a><h1 class="post-title p-name">了解 Kagi 的历史</h1><div class="post-info"><time class="post-date dt-published" datetime="2026-04-04T04:00:00.000Z">4/4/2026</time><time class="dt-updated visually-hidden" datetime="2026-04-05T17:56:44.227Z"></time></div><div class="post-content e-content"><html><head></head><body><p>上个月我在 <a target="_blank" rel="noopener" href="https://store.kagi.com/">Kagi Store</a> 上下单了 Kagi 的 T 恤衫、袜子周边。不为别的,Kagi 的吉祥物设计很可爱,画风很独特。</p>
<p>不过在搜寻时我发现了这个 Hacker News <a target="_blank" rel="noopener" href="https://news.ycombinator.com/item?id=40011314">链接</a>,也迫使我不得不去探索 Kagi,这个大概被我神话过头的公司。</p>
<span id="more"></span>
<p>首先我必须 <a href="/posts/e3b9.html#kagi:~:text=%E7%9C%BC%E5%B0%96%E7%9A%84%E6%9C%8B%E5%8F%8B%E4%BB%AC%E6%88%96%E8%AE%B8%E5%8F%91%E7%8E%B0%E4%BA%86%EF%BC%8C%E6%88%91%E4%B8%80%E4%BC%9A%E5%84%BF%E8%AF%B4%20Kagi%EF%BC%8C%E4%B8%80%E4%BC%9A%E5%84%BF%E8%AF%B4%20Kagi%20Search%20%E7%9A%84%E3%80%82%E8%BF%99%E6%98%AF%E5%9B%A0%E4%B8%BA%EF%BC%8CKagi%20%E5%9C%A8%E6%9C%AC%E6%96%87%E5%86%85%E6%8C%87%E7%9A%84%E6%98%AF%E8%AF%A5%E5%85%AC%E5%8F%B8%EF%BC%8C%E8%80%8C%20Kagi%20Search%20%E6%98%AF%E5%85%B6%E5%90%8D%E4%B8%8B%E7%9A%84%E6%90%9C%E7%B4%A2%E5%BC%95%E6%93%8E%E6%9C%8D%E5%8A%A1%E5%90%8D%E7%A7%B0%E3%80%82%E5%A6%82%E6%9E%9C%E6%88%91%E5%8F%AA%E6%98%AF%E6%83%B3%E8%AF%B4%E6%90%9C%E7%B4%A2%E5%BC%95%E6%93%8E%E7%9A%84%E8%AF%9D%EF%BC%8C%E5%8F%AF%E4%BB%A5%E7%9B%B4%E6%8E%A5%E4%BD%BF%E7%94%A8%20Kagi%E3%80%82%E4%B8%8D%E8%BF%87%E6%88%91%E6%83%B3%E8%AE%B2%E7%9A%84%E6%98%AF%20Kagi%20%E7%9A%84%E4%BA%A7%E5%93%81%EF%BC%8C%E4%B8%8D%E5%8D%95%E5%8D%95%E6%98%AF%E6%90%9C%E7%B4%A2%E5%BC%95%E6%93%8E%E4%B8%80%E4%B8%AA">再度</a> 说清楚,我所说的 Kagi 不单单只是个搜索引擎,而是一个公司(Kagi Inc.)。不过这么说也不准确,因为 Kagi Inc. 这个实体于 2022 年 3 月份才成立,而团队开始捣鼓 Kagi 的 AI 产品早在 2018 年便有记录(见 <a target="_blank" rel="noopener" href="https://help.kagi.com/kagi/company/history.html">Kagi 历史</a>),甚至早过 2019 年 Kagi Search 的原型产品。</p>
<p>Kagi 这家公司太小了,以至于 Wikipedia 都没有 Kagi Inc. 的条目,只有同名为 Kagi、实际上在产品线中叫作 <em> Kagi Search</em> 的搜索引擎产品。要了解 Kagi Inc.,只能慢慢从不同年份的博客文章中找出各种蛛丝马迹了…… 没关系!我 <a href="/posts/2590.html">隐私条款</a> 都读过,还怕你个博客文章!</p>
<p>总之先从 <a target="_blank" rel="noopener" href="https://en.wikipedia.org/wiki/Kagi">Wikipedia</a> 开始吧。Wikipedia 上写了什么并不重要,重要的是它所引用的参考资料,以及开头所写的「这篇文章可能过度依赖与主题密切相关的来源,从而导致条目内容缺乏可验证性和中立性」。稍微看一下参考资料就会发现,许多确实是来自 Kagi 网站自己的文章。</p>
<p>好吧,那我们先读一下 Kagi 自己如何评价自己。在 <a target="_blank" rel="noopener" href="https://help.kagi.com/kagi/company/">Kagi 的关于页面</a>、<a target="_blank" rel="noopener" href="https://help.kagi.com/common/company/history.html">Kagi 历史</a>,和 <a target="_blank" rel="noopener" href="https://blog.kagi.com/what-is-next-for-kagi#3">2024 年 Kagi 的一篇文章</a> 里我们得知,它的历史发展可以划分为四个阶段:</p>
<p>一、技术探索与试错。</p>
<p>Kagi 由 Vladimir Prelovac 于 2018 年 5 月在美国加州的帕罗奥图市创立。最初的四年里,公司完全由 Prelovac 自筹资金,大约是 300 万美元。</p>
<p>早期的 Kagi 并没有直接去做一个完整的搜索引擎,而是将重心放在了 AI 和问答技术上。这一点可以查看被存档下来的 <a target="_blank" rel="noopener" href="https://web.archive.org/web/20241129140750/https://kagi.ai/">kagi.ai</a> 网站。所以你要说 Kagi 是一家 AI 公司,也大差不差吧!这也反映了未来 Kagi 有许多 AI 产品的原因。不过那可是 2018 年,当时的 AI 产品指的还是 Siri 呢!</p>
<p>总之当时的 Kagi 认为未来的搜索引擎必须具备强大的即时问答能力,这倒是和现在大家使用生成式 LLM 聊天机器人的方式差不多:问问题。</p>
<p>在这个阶段,Kagi Search 的第一个原型也诞生了,用的是命令行模式,还挺符合 MVP 开发逻辑的。<a target="_blank" rel="noopener" href="https://orionbrowser.com/">Orion 浏览器</a> 的早期原型也一起出现了。</p>
<p>关于 Kagi Search 的原型体,感兴趣的可以见:</p>
<ul>
<li><a target="_blank" rel="noopener" href="https://blog.kagi.com/last-mile-for-web-search">https://blog.kagi.com/last-mile-for-web-search</a></li>
<li><a target="_blank" rel="noopener" href="https://vimeo.com/754908681">https://vimeo.com/754908681</a></li>
<li><a target="_blank" rel="noopener" href="https://vimeo.com/754899234">https://vimeo.com/754899234</a></li>
</ul>
<p>他们还尝试建立高级搜索业务 <a target="_blank" rel="noopener" href="https://donna.gg/">Donna.gg</a>,不过失败了。</p>
<p>二、底层研发与内侧。</p>
<p>接着疫情来了。Kagi 的团队规模翻倍达到 10 人。他们在 2020 年到 2021 年的期间将早期的技术积累转化为实际的产品,即进入了封闭 Beta 内测阶段的 Kagi Search 和 Orion 浏览器。</p>
<p>三、商业化验证与公测。</p>
<p>2022 年 3 月 4 日,Kagi Inc. 正式注册成立。同年的 6 月份,搜索引擎和浏览器进入公测,并确立了「用户付费」的无广告商业模式 —— 太好了!而仅仅三个月后,就有数千名用户开始为这些产品付费。</p>
<p>2023 年是 Kagi 商业模式被验证的关键节点。这一年他们实现了 100 万美元的 <u>年度经常性收入</u>,证明了「人们愿意为优质且注重隐私的搜索付费」这一假设。同年,他们通过社区向 93 位天使投资人(也是他们的用户)筹集了约 250 万美元。</p>
<p>四、组织进化与生态扩张。</p>
<p>随着公司实现盈利,团队规模扩张至 40 人以上。在 2024 年,Kagi 推出了 Assistant、Translate 以及企业版服务。</p>
<p>更重要的是,在 2024 年初,Kagi 在法律事实上完成了商业实体的转变,成为了一家 <u>公共利益型企业</u>。</p>
<p>到 2025 年,Orion 浏览器也结束了 Beta 测试,并推出了隐私通行证等新功能。</p>
<p>大致的历史中便出现了一些商业术语呢,必须要讲清楚一下。</p>
<p>在理解 Kagi 的实体转变之前,我们得先厘清 <u>商业实体</u> 的概念。</p>
<p>简单来说,商业实体是法律在纸面上创造出来的拟制人,AKA 假人。当创始人开展业务时,如果不成立实体,所有的债务和法律责任都会由创始人个人承担。而成立了商业实体之后,公司就有了自己独立的法定身份,它可以拥有资产、签订合同、雇佣员工,并在法律上承担责任 —— 所以说有些人说自己最爱公司不是错的,它在法律层面上就是个人啊!</p>
<p>对于美国的科技初创公司而言,最常见的实体类型是 <u>特拉华州 C 型股份有限公司</u>。为什么要说「最常见」呢?因为我找不到 Kagi 最初注册时选的类型是什么。<a target="_blank" rel="noopener" href="https://icis.corp.delaware.gov/ecorp/entitysearch/NameSearch.aspx">特拉华州公司检索系统</a> 会直接显示 <em> Benefit Corporation</em>,也就是 Kagi 之后才转变成的公司类型。所以我就默认它是 C 型公司吧。</p>
<p>C 型公司的核心特征在于其在法律和税务上的绝对独立性。它是一个独立于所有者(即股东)的法人实体。这种架构的最显著特点是,你要征两次税(哦不!):公司本身需要为其产生的利润缴纳 <u>企业所得税</u>;当公司将税后利润以股息形式发放给股东时,股东还需要在个人层面缴纳个人所得税。</p>
<p>如果对股份感兴趣的话,我在今年一月份有简单 <a href="/posts/53f4.html#:~:text=%E8%82%A1%E7%A5%A8%E7%9A%84%E6%9C%AC%E8%B4%A8%E6%98%AF%E4%BD%A0%E6%8B%A5%E6%9C%89%E4%B8%80%E5%AE%B6%E5%85%AC%E5%8F%B8%E7%9A%84%E4%B8%80%E9%83%A8%E5%88%86%E3%80%82%E5%AF%B9%E4%BA%8E%E4%B8%8A%E5%B8%82%E5%85%AC%E5%8F%B8%E8%80%8C%E8%A8%80%EF%BC%8C%E5%AE%83%E4%BB%AC%E9%80%9A%E8%BF%87%E5%87%BA%E8%AE%A9%E8%82%A1%E4%BB%BD%E6%9D%A5%E7%AD%B9%E9%9B%86%E8%B5%84%E9%87%91%E5%8E%BB%E7%A0%94%E5%8F%91%E5%92%8C%E6%89%A9%E5%BC%A0%EF%BC%8C%E5%9B%A0%E6%AD%A4%E5%8F%AF%E4%BB%A5%E8%A2%AB%E4%B8%80%E8%88%AC%E4%BA%BA%E4%B9%B0%E5%8E%BB%E3%80%82%E6%AF%8F%E4%B8%80%E5%B9%B4%E5%AE%83%E4%BB%AC%E9%9C%80%E8%A6%81%E6%A0%B9%E6%8D%AE%E8%B5%9A%E6%9D%A5%E7%9A%84%E9%92%B1%E9%80%89%E6%8B%A9%E5%8F%96%E5%A4%9A%E5%B0%91%E7%BB%99%E7%A0%94%E5%8F%91%E3%80%81%E5%8F%96%E5%A4%9A%E5%B0%91%E5%88%86%E7%BA%A2%E7%BB%99%E8%82%A1%E4%B8%9C">聊过</a>。不过当时的聚焦点主要是在股票市场上。这里再说一下:卖股票不意味着一定要在公开股票市场卖,还可以通过私募的方式出售股权。所以就算 Kagi 不是上市公司、你在股票市场上看不到 Kagi 的大名,它依然是有股东的。</p>
<p>继续说。C 型公司允许发行不同层级的股票,能够极为便利地进行股权融资、发放员工期权,所以尽管它存在着税务上的劣势,绝大多数初创公司依然会选择这种架构,天使投资人们也更喜欢它。</p>
<p>在这种架构下,公司董事会和管理层会受到一种被称为 <u>受托责任</u> 的严格法律约束。这种责任要求他们必须将「股东利益最大化」作为核心,甚至唯一的商业决策目的。比方说你得让公司有好看的财务报表、利润要赚得多多的……</p>
<p>顺带一提,这种责任的确立可以追溯到 1919 年著名的 <em> Dodge v. Ford Motor Co.</em> 案。</p>
<p>2024 年初,Kagi 的商业实体转变成了 <u>特拉华州公共利益型企业</u>。它和传统的 C 型公司的区别在于,它要求公司的董事和高管在追求股东财务回报的同时,比如兼顾特定的公共利益,以及其他利益相关者的诉求,比方说用户和社区!</p>
<p>这下你或许就会明白了。Kagi 的卖点本就是「不卖广告、不追踪用户数据、完全由用户付费」,那它要还是维持传统的 C 型公司结构的话,未来要是发展壮大了,可能就会面临巨大的法律和商业冲突。</p>
<p>举个例子,一家大型广告公司提出以极高的溢价收购 Kagi,如果有投资者指出「如果加入广告的话,公司的利润可以翻十倍」,那你在传统 C 型公司的法律框架下,你会拒绝吗?董事会如果拒绝这些能让股东利益最大化的提议的话,就有可能会面临股东的起诉哦。</p>
<p>那转变为公共利益型企业后,Kagi 就可以合法地对利润说「不」了,因为他们「致力于创建一个以人为本、可持续发展的网络」。</p>
<p>这同时也向付费用户,即我们,提供了一个法律层面上的保证,证明其永远不作恶、不卖广告。</p>
<p>而年度经常性收入(Annual Recurring Revenue,简称 ARR)是一项财务指标,主要用于评估订阅制业务或 SaaS 公司的收入表现。它衡量的是「公司在未来十二个月内,基于现有订阅合同可以合理预期的、稳定的经常性总收入」。</p>
<p>对于一个订阅制软件服务而言,100 万美元的年度经常性收入意味着企业已经拥有了可预测的现金流来覆盖基础研发和运营成本,且其商业模式能够在小规模的样本下跑通!</p>
<p>所以这串数字象征着,Kagi 成功打破了「搜索必须免费」的思维定势。</p>
<p>知道了 Kagi 在商业模式上的历史,接着来看看其技术方面上的历史吧。和 Google 不同,Kagi 并非一个像 Google 那样从零开始爬取全网的独立搜索引擎,而是一个 <u>元搜索引擎</u>,或者说是「搜索客户端」。</p>
<p>2023 年,Kagi 曾明确定义过自己的架构:当用户输入一个查询时,Kagi 会将这个请求分发给后端的多个信息源,然后将拉取到的数据进行清洗、重新排序,最后呈现给用户。这一段内容可以见 <a target="_blank" rel="noopener" href="https://web.archive.org/web/20231228222303/https://help.kagi.com/kagi/search-details/search-sources.html">这个被存档的文章</a>。</p>
<p>它的信息源分为两类:一类是垂直领域的 API 接口,例如 Wikipedia、Apple Maps、Yelp、TripAdvisor 等;一类是最为核心的综合网页搜索索引。在早期,Kagi 明确标示了它对外部通用索引的依赖,包括 Google、Bing、Yandex、Brave 和 Mojeek。</p>
<p>怎么说呢,这样的架构就很…… 客户端。如果老板让我写个搜索引擎给他,估计我也会这么做。</p>
<p>进入 2024 年后,Kagi 不再公开列出其使用的传统搜索引擎来源了,这主要是因为两点:</p>
<ol>
<li>Bing 的 API 价格涨幅高达 10 倍(之后 2025 年还停用了 Bing Search API)</li>
<li>Google 不提供公开的搜索 API,除非使用广告联合分发包。</li>
</ol>
<p>这意味着,Kagi 失去了通过正规合同获取这两大巨头数据的合法路径。在一篇 2026 年的 <a target="_blank" rel="noopener" href="https://web.archive.org/web/20260125151549/https://blog.kagi.com/waiting-dawn-search">被存档文章</a> 中,Kagi 承认道:「由于无法在兼容的条款下获得直接授权,我们和许多其他公司一样,使用第三方 API 提供商来获取 SERP 风格的结果(SERP 指搜索引擎结果页面)。」</p>
<p>这种方式是灰色的,因为第三方 API 供应商本质是在通过技术手段大抓特抓 Google 和 Bing 的搜索结果。再加上 2025 年年底 Google 还真的起诉了大型抓取服务商 SerpApi,侧面反映出了 Kagi 确实不该公开列出自己所使用的源。</p>
<p>所以我们也不知道 Kagi 的搜索结果具体都来自谁,不过根源肯定也会是 Google 和 Bing 就是了。</p>
<p>值得一说的是,这些 API 是按次计费的,是变动成本,而我们用户订阅 Kagi 是每个月支付固定的金额。这意味着,成本和收入是可以错位的,随之而来的隐患便是破产。</p>
<p>顺带一提 Kagi 也有自己的爬虫和索引系统,其中最核心的是针对 small web 的 Teclis。它的技术实现,很暴力:使用 Puppeteer 配合 uBlock Origin 来渲染网页。如果在加载网页时触发了 5 个以上的广告或者追踪器拦截请求,该网页就会被直接从索引中剔除。</p>
<p>随后 Kagi 会使用 Elasticsearch 和 Typesense 进行全文检索,结合自然语言处理模型进行语义向量搜索。</p>
<p>你已经对 Kagi 有一个大致上的了解了,现在让我们把焦点放在本次要回应的文章上吧!</p>
<p>lori 在 Kagi 的 Discord 频道中观察许久,基于这些观察,他提出了一些普通用户不会考虑到的点。由于这篇文章发布于 2024 年,所以一些东西可能是过时的:</p>
<p>一、T 恤衫事件。</p>
<p>先前说到 Kagi 在 2023 年筹集了约 250 万美元的社区资金,其中有 <a target="_blank" rel="noopener" href="https://blog.kagi.com/safe-round">67 万美元</a> 是他们首次外部融资筹集来的。接着在 2024 年 1 月 24 日,Kagi 表示为了庆祝自己有了两万名付费会员,拨出了其中的三分之一,也就是 20 多万美元成立了一个全新的业务实体来生产,并免费分发这两万件 T 恤衫。</p>
<p>这让 lori 觉得很困惑:为什么要花这么多做这种事情呢?我也承认花这么多钱做这件事听上去有欠考虑。</p>
<p>但我对 lori 提到的这个「业务实体」更感兴趣:它叫什么名字?在哪里?真的有一个独立的仓库吗?因为你不能就 Kagi 的 <a target="_blank" rel="noopener" href="https://blog.kagi.com/celebrating-20k">博客文章</a> 这么说了,所以相信他们成立了家商业实体。</p>
<p>商业实体的注册和成立,都是可以被查到的。证明这个实体是否存在,便成了我的首要目标 —— 我也很好奇嘛。</p>
<p>Kagi 在 2024 年 9 月份,也就是 Kagi Store 上线的时候发布的 <a target="_blank" rel="noopener" href="https://blog.kagi.com/mountains-of-cotton">博客文章</a> 中提到:「我们并没有真的开一家 T 恤工厂。」所以 lori 文章中所说的工厂是绝对被夸大了的。</p>
<p>但我还是很好奇啊!没有工厂,不意味着商业实体不存在,对不对?为此我跑到多个德国的商业登记系统数据库内进行检索,结果发现唯一一个和关键词 <em> Kagi</em> 相关的公司是 Kagi Trade UG。但这是一家机械贸易公司,2021 年便成立了,和我们现在说的 Kagi 明显不是同一个。</p>
<p>这就很难办了。确实,Kagi 为发 T 恤衫设立的那个实体,名称不一定是 <em> Kagi</em>,高管也不一定是 Prelovac。那咋办呢?</p>
<p>我只能说,就像我们不知道 Kagi 的传统搜索结果来自哪个第三方服务商,我们也不知道 Kagi 到底有没有成立一个商务实体在德国 —— 好啦,我认为没有。如果有的话,早就被人翻个底朝天了,也轮不到我这个站在 2026 年的时间点的人指手画脚。</p>
<p>说回 T 恤衫本身。根据 2024 年 4 月 12 日 Prelovac 通过 Hacker News 对这篇文章的 <a target="_blank" rel="noopener" href="https://news.ycombinator.com/item?id=40013592">回应</a> 中可以看出,他想要取悦用户社区。因为 Kagi 不做任何付费广告,能增长完全是依靠社区的口口相传。</p>
<p>我尝试用其他方式来为 T 恤衫辩解,最终只能想到「穿上它上街相当于免费为 Kagi 打广告」这一个说辞。那两万个用户到底想不想要这件 T 恤衫呢?我不得而知。我只能说它作为一个品牌的周边挺不错的,但我会更期待初创公司只花一点点钱,找些合作商定制马克杯、贴纸什么的送出去。</p>
<p>二、整整两年忘记缴纳销售税。</p>
<p>lori 认为 Kagi 有两年没有缴纳销售税很莫名其妙,以此怀疑 Kagi 当时的财务状况并不好 —— 呃,说实话,两年没有缴纳销售税,也没有听上去那么糟糕?因为我有许多客户有数年,甚至二十多年都没有缴纳销售税。原因通常是他们的税务师不负责任、没有把这件事情告诉他们。最后我们也只能让他们自首。</p>
<p>根据 Prelovac 在 Discord 中的截图,看上去也更像是他们没有意识到自己需要缴纳销售税这件事。也很符合我心目中一心只有技术的技术宅的刻板印象啦。其实我在搞公司之前,也对税务一窍不通,现在顶多是知道一些些。</p>
<p>税务这个东西我只能说,不懂的人是真的不懂,也会惹出许多笑话。但这并不是他们的错,义务教育里又没有教过美国人们税务知识,而会学习它们的多是 ego 比天还高的傻瓜税务师。这也是我们公司一直在想办法改善的问题,也在致力于帮助那些被不专业的税务师坑骗的人们 —— 咦,怎么开始推销了?</p>
<p>不单单是税务师,会计师、律师也有着同样的问题。自己不专业就算了,冷落自己的客户,然后搞出来的破事儿丢给客户自己处理。就算客户不知道、将事情都交给税务师处理,但如果被税务局查到、抓包了,依然是客户承担主要责任。</p>
<p>之后我阅读了 Prelovac 对 lori 文章的回应,即一个被 lori 公开在 <a target="_blank" rel="noopener" href="https://web.archive.org/web/20240508204319/https://hackers.town/@lori/112255132348604770">Fediverse</a> 上的 <a target="_blank" rel="noopener" href="https://web.archive.org/web/20240412070624mp_/https://d-shoot.net/files/kagiemails.txt">邮件串</a> 后得知,最初是 Prelovac 不知道付费搜索会被市场接受,所以早期就没搞。好吧,我以为你不知道呢!</p>
<p>三、AI 愿景与用户期待的严重错位。</p>
<p>这是这篇文章中最核心的技术冲突。</p>
<p>很多用户转投 Kagi,是为了逃离 Google 越来越臃肿的 AI 概括和 SEO 垃圾,他们想要一个老派、纯粹、只给链接的搜索引擎。</p>
<p>但我先前也说过了,Kagi 在 2018 年创立的第一天叫 <em><a target="_blank" rel="noopener" href="http://Kagi.ai">Kagi.ai</a></em>。Prelovac 的终极愿景从来都不是做个复古的搜索引擎,而是做一个用 AI 帮用户总结的工具。</p>
<p>在这个终极愿景实现之前,Kagi 靠下放控制权留住了这些讨厌 AI 的用户,也就是用户可以在客户端层干预搜索结果,比方说拉黑特定内容农场。</p>
<p>这也解释了另一个问题:既然终极目标是 AI,为何 Kagi 还要花好几年时间做一个传统搜索页面呢?原因在于,早期大语言模型存在着严重的幻觉问题,Kagi 必须先打磨出一个具有高质量清洗、去重和过滤能力的传统搜索系统,以此作为未来 AI 产品的基座 —— 只要底层的信源足够干净,上层的 AI 总结才具备真正的可用性。</p>
<p>也就是说,Kagi 的技术策略是「表面做 A,实际为了 B」。这一点也体现在 Kagi 庞杂的产品线上。除了 Kagi Search 外,Kagi 显然想要做个互联网生态全家桶,涵盖了搜索引擎、浏览器、电子邮箱服务等我们平日会使用到的东西。lori 认为这些太多了,只做 Kagi Search 会更好。</p>
<p>事实上,在先前的 Hacker News 讨论串中也有很多人在当时认为是在浪费资源。比方说有个评论认为,Kagi 在和 Google 以及 Microsoft 竞争,将资源放在非核心产品的东西上都是在放弃。</p>
<p>不过 Kagi Search 真的是 Google 和 Bing 的竞品么?它们确实都是搜索引擎,但说是竞品实在是太高抬 Kagi Search 了。它的搜索来源真要追溯,不还是 Google 跟 Bing 吗?Kagi Search 只能算是元搜索客户端的一员罢了;根据现在的 <a target="_blank" rel="noopener" href="https://kagi.com/stats?sub_stats=members">统计</a> 来看,其会员数根本不够格,才近 7 万而已。</p>
<p>说到 Kagi 其他的产品,我其实都有在尝试使用。比如 Orion 浏览器,我就安装了个在 iPad 上,来代替原先的 Edge 浏览器 —— 嗯,我在折腾 degoogle 和 demicrosoft 的时候把我的 iPad 给忘了。这个支持 Chromium 和 Firefox 插件的 Webkit 浏览器很有趣,我还在探索阶段。</p>
<p>我用的最少的是 Kagi News,因为我压根不怎么阅读新闻。其次是 Kagi Maps,它怎么说呢,没有导航系统意味着我很少会打开它,但是搜索地点还算不错,可以说是 Kagi Search 附带的地图功能。</p>
<p>至于 Kagi Assistant 嘛…… 我只使用过 Quick mode,更进阶的 Research mode 我没有打算付费使用。我使用过竞品 Perplexity,这种问答引擎找资料挺有帮助的,但产品类型并不是我会经常使用的。</p>
<p>如果 Kagi 真的要弄出一个互联网全家桶的话,我会不会使用是个好问题:我会放弃自己托管的邮件服务,改用 Kagi 邮箱么?不过当务之急的应该是,先让 Kagi Small Web 支持中文独立网络吧!</p>
<p>四、隐私观的本质分歧。</p>
<p>Kagi 是一家在美国注册的公司,这已经注定了其存储的隐私数据在美国政府面前不值一提。我在 <a href="/posts/2590.html">研究 VPS 服务商的隐私条款的文章</a> 中已经提到过了,在美国注册的实体,其数据无论存储在哪里都没有用,依然可以被美国政府够到。</p>
<p>GDPR 也不是那么神仙的存在:想要自己隐私安全的唯一办法就是,不要把自己的信息上传到互联网!</p>
<p>但是 2024 年的 Discord 频道截图中也可以看出,当时的 Kagi 团队对隐私权并不了解,甚至可以说是有点白痴了 —— 你的卖点是尊重隐私,但你表现出来的好像对隐私一窍不通?比方说「电子邮件地址不属于个人身份信息」、「世界上除了罪犯,极少有人需要真正的完全匿名」。唉,初创公司另一个难过的槛儿是公关问题啊。</p>
<p>不过当年的担忧,在 2025 年有了满意的 <a target="_blank" rel="noopener" href="https://blog.kagi.com/kagi-privacy-pass">答卷</a>:Kagi 推出了 Privacy Pass 身份验证!也就是说,用户的付费账户身份和实际搜索行为在数学层面上彻底地切断了联系。紧接着 Kagi 还官方支持了 Tor 服务。</p>
<p>现在用户的搜索查询不再与包含邮箱的账户绑定,那么 Kagi 在处理搜索数据时,就几乎不再触及个人可识别信息。即使 Stripe 依然保留着用户的付款信息和邮箱,但只要这些信息无法与用户的搜索历史关联,隐私泄露的风险和法律合规的压力便大大降低了。</p>
<p>这篇文章也意外为 Orion 浏览器正了名。过去用户视其为不务正业,但文章中提到,由于 Safari 的技术限制,Privacy Pass 无法在 Safari 上完美实现。此时,拥有自己底层控制权的 Orion 浏览器的价值便体现了出来~ 可喜可贺,可喜可贺。</p>
<p>五、不要给我发邮件了!</p>
<p>在文章发布后,Prelovac 尝试通过电子邮件和 lori 联系上,以此来讨论这些事情,也就是先前我分享的邮件串。</p>
<p>lori 最初便表示了不想要和 Prelovac 有任何联系,也不想要和 Prelovac 沟通 —— 理由在文章的结尾写明了,他在 Discord 频道中已经知道了 Prelovac 是个什么样的人,所以无力去和他起争执。但是 Prelovac 依然向 lori 发送了对文章的回应。</p>
<p>电子邮件这样的沟通方式,因为会存储到对方的数据库内,所以并不静默。如果 Prelovac 只是在自己的博客上写了篇回应,那也真的还好啦,但明知对方不想要沟通的情况下,还是硬把观点塞给对方,这就是对对方的不尊重了。</p>
<p>至于我会不会因此讨厌 Kagi、不再使用 Kagi 的产品,那自然是不会的。因为 Kagi 是集体工程的产物,不单单是 Prelovac 个人的项目。需要将产品的使用价值与创始人的个人做派剥离开来。</p>
<p>但也就我先前常提到的,这是个「马后炮」的回应。在 2026 年的现在,Kagi 的一切看上去很不错:它已经不是个无法与创始人的个人特质解绑的初创公司了。</p>
<p>无论用户会选择继续支持,还是放弃 Kagi,都是他们自己的选择。这一点上,我和 lori 的观点是一样的。</p>
</body></html></div></article></div></main><footer><div class="paginator"><a class="next" href="a4c0.html">下一篇</a></div><!-- Webmention 显示区域--><div class="webmention-section" data-page-url="posts/c2db.html" data-full-url="https://blog.cytrogen.icu/posts/c2db.html" data-syndication-url="https://gts.cytrogen.icu/@cytrogen/statuses/01KNFCMC1V8VYWEB5650KB5F09" data-mode="static">
<script type="application/json" class="webmention-overrides-data">{"bySourceDomain":{"v1sta.xyz":{"name":"远景幻想 V1STA","url":"https://v1sta.xyz/","photo":"https://v1sta.xyz/wp-content/uploads/2026/03/V1sta-Orb-Output512-2.png"}}}</script>
<h3 class="webmention-title">Webmentions (<span class="webmention-count">1</span>)</h3><form class="webmention-form" action="https://webmention.io/blog.cytrogen.icu/webmention" method="POST">
<input type="hidden" name="target" value="https://blog.cytrogen.icu/posts/c2db.html">
<label for="webmention-source">你的文章 URL</label>
<div class="webmention-form-row">
<input id="webmention-source" type="url" name="source" placeholder="https://example.com/your-post" required>
<button type="submit">发送 Webmention</button>
</div>
</form><div class="webmention-respond">
<a class="webmention-respond-btn" href="https://gts.cytrogen.icu/@cytrogen/statuses/01KNFCMC1V8VYWEB5650KB5F09" target="_blank" rel="noopener syndication">在 Mastodon 上回应本文</a>
</div><div class="webmention-group webmention-group-likes"><div class="webmention-compact-list"><a class="webmention-compact-item" href="https://mstdn.feddit.social/@admin" target="_blank" rel="noopener ugc" title="KIP/JΛYCHØU ⁂ :chuckya: :atproto: :nostr:"><img class="webmention-compact-photo" src="https://avatars.webmention.io/gts.cytrogen.icu/4af8316b6cde2290bc2029175c200b4ff310f3fe6335711a44ad73ca52c90896.png" alt="KIP/JΛYCHØU ⁂ :chuckya: :atproto: :nostr:" title="KIP/JΛYCHØU ⁂ :chuckya: :atproto: :nostr:" loading="lazy"></a><span class="webmention-compact-label">(1) 喜欢了这篇文章</span></div></div><p class="webmention-hint">本站支持 <a href="https://www.w3.org/TR/webmention/" target="_blank" rel="noopener">Webmention</a>。你可以在 Fediverse(如 Mastodon)上回应本文的联合链接,互动会自动出现在此处。<a href="/colophon/#webmention">详情见营造记</a>。</p></div><!-- 邮件评论--><div class="email-comment-section email-comment-loading" data-post-id="c2db" data-blog-domain="blog.cytrogen.icu">
<h3 class="email-comment-title">邮件评论 (<span class="email-comment-count">0</span>)</h3>
<p class="email-comment-intro">通过邮件参与讨论:<a href="mailto:post-c2db@blog.cytrogen.icu" aria-label="通过邮件发送评论">post-c2db@blog.cytrogen.icu</a></p>
<p class="email-comment-empty">还没有邮件评论。</p>
<p class="email-comment-hint">发送邮件到上方地址即可评论。你的名字会公开显示,但邮箱地址不会。</p>
</div><script src="/js/email-comment.js" defer></script><div class="copyright"><p class="footer-links"><a href="../friends/index.html">友链</a><span class="footer-separator"> ·</span><a href="../links/index.html">邻邦</a><span class="footer-separator"> ·</span><a href="../contact/index.html">联络</a><span class="footer-separator"> ·</span><a href="../colophon/index.html">营造记</a><span class="footer-separator"> ·</span><a href="../atom.xml">RSS订阅</a></p><p>© 2025 - 2026 <a href="https://blog.cytrogen.icu">Cytrogen</a>, powered by <a href="https://hexo.io/" target="_blank">Hexo</a> and <a href="https://github.com/cytrogen/hexo-theme-ares" target="_blank">hexo-theme-ares</a>.</p><p><a href="https://blogscn.fun" target="_blank" rel="noopener">BLOGS·CN</a></p></div></footer></div></div><a class="back-to-top" href="#top" aria-label="返回顶部"><svg width="20" height="20" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true"><path d="M3.293 9.707a1 1 0 010-1.414L9.586 2a2 2 0 012.828 0l6.293 6.293a1 1 0 01-1.414 1.414L11 3.414V17a1 1 0 11-2 0V3.414L2.707 9.707a1 1 0 01-1.414 0z"></path></svg></a><script>document.addEventListener('DOMContentLoaded', function() {
const codeBlocks = document.querySelectorAll('figure.highlight');
codeBlocks.forEach(block => {
let caption = block.querySelector('figcaption');
if (!caption) {
caption = document.createElement('figcaption');
block.insertBefore(caption, block.firstChild);
}
const info = document.createElement('div');
info.className = 'info';
const filename = caption.querySelector('span');
if (filename) {
filename.className = 'filename';
info.appendChild(filename);
}
const lang = block.className.split(' ')[1];
if (lang) {
const langSpan = document.createElement('span');
langSpan.className = 'lang-name';
langSpan.textContent = lang;
info.appendChild(langSpan);
}
const sourceLink = caption.querySelector('a');
if (sourceLink) {
sourceLink.className = 'source-link';
info.appendChild(sourceLink);
}
const actions = document.createElement('div');
actions.className = 'actions';
const codeHeight = block.scrollHeight;
const threshold = 300;
if (codeHeight > threshold) {
block.classList.add('folded');
const toggleBtn = document.createElement('button');
toggleBtn.textContent = '展开';
toggleBtn.addEventListener('click', () => {
block.classList.toggle('folded');
toggleBtn.textContent = block.classList.contains('folded') ? '展开' : '折叠';
});
actions.appendChild(toggleBtn);
}
const copyBtn = document.createElement('button');
copyBtn.textContent = '复制';
copyBtn.addEventListener('click', async () => {
const codeLines = block.querySelectorAll('.code .line');
const code = Array.from(codeLines)
.map(line => line.textContent)
.join('\n')
.replace(/\n\n/g, '\n');
try {
await navigator.clipboard.writeText(code);
copyBtn.textContent = '已复制';
copyBtn.classList.add('copied');
setTimeout(() => {
copyBtn.textContent = '复制';
copyBtn.classList.remove('copied');
}, 3000);
} catch (err) {
console.error('复制失败:', err);
copyBtn.textContent = '复制失败';
setTimeout(() => {
copyBtn.textContent = '复制';
}, 3000);
}
});
actions.appendChild(copyBtn);
caption.innerHTML = '';
caption.appendChild(info);
caption.appendChild(actions);
const markedLines = block.getAttribute('data-marked-lines');
if (markedLines) {
const lines = markedLines.split(',');
lines.forEach(range => {
if (range.includes('-')) {
const [start, end] = range.split('-').map(Number);
for (let i = start; i <= end; i++) {
const line = block.querySelector(`.line-${i}`);
if (line) line.classList.add('marked');
}
} else {
const line = block.querySelector(`.line-${range}`);
if (line) line.classList.add('marked');
}
});
}
});
});</script><script async src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js" id="MathJax-script"></script><script>(function() {
document.addEventListener('DOMContentLoaded', function() {
const themeToggle = document.querySelector('.theme-toggle');
if (!themeToggle) return;
const getCurrentTheme = () => {
return document.documentElement.getAttribute('data-theme') || 'light';
};
const updateUI = (theme) => {
const isDark = theme === 'dark';
themeToggle.setAttribute('aria-pressed', isDark.toString());
};
const setTheme = (theme) => {
document.documentElement.setAttribute('data-theme', theme);
document.documentElement.style.colorScheme = theme;
const pageWrapper = document.getElementById('page-wrapper');
if (pageWrapper) {
pageWrapper.setAttribute('data-theme', theme);
}
// Find and remove the temporary anti-flicker style tag if it exists.
// This ensures the main stylesheet takes full control after the initial load.
const antiFlickerStyle = document.getElementById('anti-flicker-style');
if (antiFlickerStyle) {
antiFlickerStyle.remove();
}
localStorage.setItem('theme', theme);
updateUI(theme);
};
const toggleTheme = () => {
const current = getCurrentTheme();
const newTheme = current === 'light' ? 'dark' : 'light';
setTheme(newTheme);
};
updateUI(getCurrentTheme());
themeToggle.addEventListener('click', toggleTheme);
if (window.matchMedia) {
const mediaQuery = window.matchMedia('(prefers-color-scheme: dark)');
mediaQuery.addEventListener('change', function(e) {
if (!localStorage.getItem('theme')) {
const theme = e.matches ? 'dark' : 'light';
setTheme(theme);
}
});
}
});
})();
</script><script src="../js/details-toggle.js" defer></script><script>(function() {
document.addEventListener('DOMContentLoaded', function() {
const backToTopBtn = document.querySelector('.back-to-top');
if (!backToTopBtn) return;
const toggleButtonVisibility = () => {
const scrollTop = window.pageYOffset || document.documentElement.scrollTop;
const shouldShow = scrollTop > 200;
if (shouldShow) {
backToTopBtn.classList.add('is-visible');
} else {
backToTopBtn.classList.remove('is-visible');
}
};
let ticking = false;
const handleScroll = () => {
if (!ticking) {
requestAnimationFrame(() => {
toggleButtonVisibility();
ticking = false;
});
ticking = true;
}
};
const scrollToTop = (event) => {
event.preventDefault();
window.scrollTo({
top: 0,
behavior: 'smooth'
});
};
window.addEventListener('scroll', handleScroll);
backToTopBtn.addEventListener('click', scrollToTop);
toggleButtonVisibility();
});
})();</script></body></html>