Files
2026-05-13 16:50:38 +08:00

1646 lines
103 KiB
HTML
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!DOCTYPE html><html lang="zh-CN" data-theme="light"><head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0,viewport-fit=cover"><title>2026 AI 编程与开发工具深度对比:从 Cursor 到 Gemini CLI | llbzow的摸鱼日记 (づ ̄ 3 ̄)づ</title><meta name="author" content="llbzow"><meta name="copyright" content="llbzow"><meta name="format-detection" content="telephone=no"><meta name="theme-color" content="ffffff"><meta name="description" content="2026 AI 编程与开发工具深度对比 2026 年,写代码的方式彻底变了。我们不再逐行敲击键盘,而是作为“架构师”,指挥着一群不知疲倦的 AI 智能体 (Agents) 为我们打工。本文将深度剖析当前市面上最主流的 9 款 AI 开发神器。">
<meta property="og:type" content="article">
<meta property="og:title" content="2026 AI 编程与开发工具深度对比:从 Cursor 到 Gemini CLI">
<meta property="og:url" content="https://yourblog.com/2026/03/25/ai%E5%8E%82%E5%95%86%E5%AF%B9%E6%AF%94%E5%88%86%E6%9E%90/index.html">
<meta property="og:site_name" content="llbzow的摸鱼日记 (づ ̄ 3 ̄)づ">
<meta property="og:description" content="2026 AI 编程与开发工具深度对比 2026 年,写代码的方式彻底变了。我们不再逐行敲击键盘,而是作为“架构师”,指挥着一群不知疲倦的 AI 智能体 (Agents) 为我们打工。本文将深度剖析当前市面上最主流的 9 款 AI 开发神器。">
<meta property="og:locale" content="zh_CN">
<meta property="og:image" content="https://yourblog.com/img/cover_3.png">
<meta property="article:published_time" content="2026-03-25T02:30:00.000Z">
<meta property="article:modified_time" content="2026-03-25T02:56:53.568Z">
<meta property="article:author" content="llbzow">
<meta property="article:tag" content="技术">
<meta property="article:tag" content="AI">
<meta property="article:tag" content="效率工具">
<meta property="article:tag" content="极客">
<meta name="twitter:card" content="summary">
<meta name="twitter:image" content="https://yourblog.com/img/cover_3.png"><script type="application/ld+json">{
"@context": "https://schema.org",
"@type": "BlogPosting",
"headline": "2026 AI 编程与开发工具深度对比:从 Cursor 到 Gemini CLI",
"url": "https://yourblog.com/2026/03/25/ai%E5%8E%82%E5%95%86%E5%AF%B9%E6%AF%94%E5%88%86%E6%9E%90/",
"image": "https://yourblog.com/img/cover_3.png",
"datePublished": "2026-03-25T02:30:00.000Z",
"dateModified": "2026-03-25T02:56:53.568Z",
"author": [
{
"@type": "Person",
"name": "llbzow",
"url": "https://yourblog.com"
}
]
}</script><link rel="shortcut icon" href="/img/cute_cat.svg"><link rel="canonical" href="https://yourblog.com/2026/03/25/ai%E5%8E%82%E5%95%86%E5%AF%B9%E6%AF%94%E5%88%86%E6%9E%90/index.html"><link rel="preconnect" href="//cdn.jsdelivr.net"><link rel="preconnect" href="//busuanzi.ibruce.info"><link rel="stylesheet" href="/css/index.css"><link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fortawesome/fontawesome-free/css/all.min.css"><script>
(() => {
const saveToLocal = {
set: (key, value, ttl) => {
if (!ttl) return
const expiry = Date.now() + ttl * 86400000
localStorage.setItem(key, JSON.stringify({ value, expiry }))
},
get: key => {
const itemStr = localStorage.getItem(key)
if (!itemStr) return undefined
const { value, expiry } = JSON.parse(itemStr)
if (Date.now() > expiry) {
localStorage.removeItem(key)
return undefined
}
return value
}
}
window.btf = {
saveToLocal,
getScript: (url, attr = {}) => new Promise((resolve, reject) => {
const script = document.createElement('script')
script.src = url
script.async = true
Object.entries(attr).forEach(([key, val]) => script.setAttribute(key, val))
script.onload = script.onreadystatechange = () => {
if (!script.readyState || /loaded|complete/.test(script.readyState)) resolve()
}
script.onerror = reject
document.head.appendChild(script)
}),
getCSS: (url, id) => new Promise((resolve, reject) => {
const link = document.createElement('link')
link.rel = 'stylesheet'
link.href = url
if (id) link.id = id
link.onload = link.onreadystatechange = () => {
if (!link.readyState || /loaded|complete/.test(link.readyState)) resolve()
}
link.onerror = reject
document.head.appendChild(link)
}),
addGlobalFn: (key, fn, name = false, parent = window) => {
if (!true && key.startsWith('pjax')) return
const globalFn = parent.globalFn || {}
globalFn[key] = globalFn[key] || {}
globalFn[key][name || Object.keys(globalFn[key]).length] = fn
parent.globalFn = globalFn
}
}
const activateDarkMode = () => {
document.documentElement.setAttribute('data-theme', 'dark')
if (document.querySelector('meta[name="theme-color"]') !== null) {
document.querySelector('meta[name="theme-color"]').setAttribute('content', '#0d0d0d')
}
}
const activateLightMode = () => {
document.documentElement.setAttribute('data-theme', 'light')
if (document.querySelector('meta[name="theme-color"]') !== null) {
document.querySelector('meta[name="theme-color"]').setAttribute('content', 'ffffff')
}
}
btf.activateDarkMode = activateDarkMode
btf.activateLightMode = activateLightMode
const theme = saveToLocal.get('theme')
theme === 'dark' ? activateDarkMode() : theme === 'light' ? activateLightMode() : null
const asideStatus = saveToLocal.get('aside-status')
if (asideStatus !== undefined) {
document.documentElement.classList.toggle('hide-aside', asideStatus === 'hide')
}
const detectApple = () => {
if (/iPad|iPhone|iPod|Macintosh/.test(navigator.userAgent)) {
document.documentElement.classList.add('apple')
}
}
detectApple()
})()
</script><script>const GLOBAL_CONFIG = {
root: '/',
algolia: undefined,
localSearch: undefined,
translate: undefined,
highlight: {"plugin":"highlight.js","highlightCopy":true,"highlightLang":true,"highlightHeightLimit":false,"highlightFullpage":false,"highlightMacStyle":false},
copy: {
success: '复制成功',
error: '复制失败',
noSupport: '浏览器不支持'
},
relativeDate: {
homepage: false,
post: false
},
runtime: '',
dateSuffix: {
just: '刚刚',
min: '分钟前',
hour: '小时前',
day: '天前',
month: '个月前'
},
copyright: undefined,
lightbox: 'null',
Snackbar: undefined,
infinitegrid: {
js: 'https://cdn.jsdelivr.net/npm/@egjs/infinitegrid/dist/infinitegrid.min.js',
buttonText: '加载更多'
},
isPhotoFigcaption: false,
islazyloadPlugin: true,
isAnchor: false,
percent: {
toc: true,
rightside: false,
},
autoDarkmode: false
}</script><script id="config-diff">var GLOBAL_CONFIG_SITE = {
title: '2026 AI 编程与开发工具深度对比:从 Cursor 到 Gemini CLI',
isHighlightShrink: false,
isToc: true,
pageType: 'post'
}</script><link rel="stylesheet" href="/css/custom.css"><meta name="generator" content="Hexo 7.3.0"></head><body><div id="loading-box"><div class="loading-left-bg"></div><div class="loading-right-bg"></div><div class="spinner-box"><div class="configure-border-1"><div class="configure-core"></div></div><div class="configure-border-2"><div class="configure-core"></div></div><div class="loading-word">加载中...</div></div></div><script>(()=>{
const $loadingBox = document.getElementById('loading-box')
const $body = document.body
const preloader = {
endLoading: () => {
if ($loadingBox.classList.contains('loaded')) return
$body.style.overflow = ''
$loadingBox.classList.add('loaded')
},
initLoading: () => {
$body.style.overflow = 'hidden'
$loadingBox.classList.remove('loaded')
}
}
preloader.initLoading()
if (document.readyState === 'complete') {
preloader.endLoading()
} else {
window.addEventListener('load', preloader.endLoading)
document.addEventListener('DOMContentLoaded', preloader.endLoading)
// Add timeout protection: force end after 7 seconds
setTimeout(preloader.endLoading, 7000)
}
if (true) {
btf.addGlobalFn('pjaxSend', preloader.initLoading, 'preloader_init')
btf.addGlobalFn('pjaxComplete', preloader.endLoading, 'preloader_end')
}
})()</script><div id="web_bg" style="background-image: url(/img/bg_main.png);"></div><div id="sidebar"><div id="menu-mask"></div><div id="sidebar-menus"><div class="avatar-img text-center"><img src="data:image/webp;base64,UklGRhoBAABXRUJQVlA4WAoAAAAQAAAAJwAAJwAAQUxQSLgAAAAFuTJE9D80UiRJkiTpxvPo4fPha2lWw0WWMtgkeIot7wfsAyImYAI+vnvEjz++fJs9sbA+tfcM/HtDiBgr3c8SJP/Dk1FWC2LCxjhcwxkH4oQuQtNwSOdgixw5o+0TyIUCQoMJti7B3ALGhZLGNuJiAYfblG7kb/RON5GjZNeEtA+QtC6omDsY2aoIwv2KDLiAzPYvzhmyNVWWzAtzzGHxSBnzCwFja3Igk3sSwSooc7gTFtmKJoIQVlA4IDwAAABQAwCdASooACgAPzmcxF0vKqcko4gB4CcJZwDNSAn82OhFYAD+7iKcpmiMeBjtx3LPQK2rXKK9ARvvVAA=" data-lazy-src="/img/cute_cat.svg" onerror="this.onerror=null;this.src='/img/friend_404.gif'" alt="avatar" loading="eager" fetchpriority="high" decoding="sync"></div><div class="site-data text-center"><a href="/archives/"><div class="headline">文章</div><div class="length-num">20</div></a><a href="/tags/"><div class="headline">标签</div><div class="length-num">31</div></a><a href="/categories/"><div class="headline">分类</div><div class="length-num">4</div></a></div><div class="menus_items"><div class="menus_item"><a class="site-page" href="/"><i class="fa-fw fas fa-home"></i><span> 首页</span></a></div><div class="menus_item"><a class="site-page" href="/archives/"><i class="fa-fw fas fa-archive"></i><span> 文章</span></a></div><div class="menus_item"><a class="site-page" href="/tags/"><i class="fa-fw fas fa-tags"></i><span> 标签</span></a></div><div class="menus_item"><a class="site-page" href="/categories/"><i class="fa-fw fas fa-folder-open"></i><span> 分类</span></a></div><div class="menus_item"><a class="site-page" href="/about/"><i class="fa-fw fas fa-heart"></i><span> 关于</span></a></div></div></div></div><div class="post" id="body-wrap"><header class="post-bg" id="page-header" style="background-image: url(/img/cover_3.png);"><nav id="nav"><span id="blog-info"><a class="nav-site-title" href="/"><span class="site-name">llbzow的摸鱼日记 (づ ̄ 3 ̄)づ</span></a><a class="nav-page-title" href="/"><span class="site-name">2026 AI 编程与开发工具深度对比:从 Cursor 到 Gemini CLI</span><span class="site-name"><i class="fa-solid fa-circle-arrow-left"></i><span> 返回首页</span></span></a></span><div id="menus"><div class="menus_items"><div class="menus_item"><a class="site-page" href="/"><i class="fa-fw fas fa-home"></i><span> 首页</span></a></div><div class="menus_item"><a class="site-page" href="/archives/"><i class="fa-fw fas fa-archive"></i><span> 文章</span></a></div><div class="menus_item"><a class="site-page" href="/tags/"><i class="fa-fw fas fa-tags"></i><span> 标签</span></a></div><div class="menus_item"><a class="site-page" href="/categories/"><i class="fa-fw fas fa-folder-open"></i><span> 分类</span></a></div><div class="menus_item"><a class="site-page" href="/about/"><i class="fa-fw fas fa-heart"></i><span> 关于</span></a></div></div><div id="toggle-menu"><span class="site-page"><i class="fas fa-bars fa-fw"></i></span></div></div></nav><div id="post-info"><h1 class="post-title">2026 AI 编程与开发工具深度对比:从 Cursor 到 Gemini CLI</h1><div id="post-meta"><div class="meta-firstline"><span class="post-meta-date"><i class="far fa-calendar-alt fa-fw post-meta-icon"></i><span class="post-meta-label">发表于</span><time class="post-meta-date-created" datetime="2026-03-25T02:30:00.000Z" title="发表于 2026-03-25 10:30:00">2026-03-25</time><span class="post-meta-separator">|</span><i class="fas fa-history fa-fw post-meta-icon"></i><span class="post-meta-label">更新于</span><time class="post-meta-date-updated" datetime="2026-03-25T02:56:53.568Z" title="更新于 2026-03-25 10:56:53">2026-03-25</time></span><span class="post-meta-categories"><span class="post-meta-separator">|</span><i class="fas fa-inbox fa-fw post-meta-icon"></i><a class="post-meta-categories" href="/categories/%E7%9F%A5%E8%AF%86%E5%BA%93/">知识库</a></span></div><div class="meta-secondline"><span class="post-meta-separator">|</span><span class="post-meta-pv-cv" id="" data-flag-title=""><i class="far fa-eye fa-fw post-meta-icon"></i><span class="post-meta-label">浏览量:</span><span id="busuanzi_value_page_pv"><i class="fa-solid fa-spinner fa-spin"></i></span></span></div></div></div></header><main class="layout" id="content-inner"><div id="post"><article class="container post-content" id="article-container"><h1 id="2026-AI-编程与开发工具深度对比"><a href="#2026-AI-编程与开发工具深度对比" class="headerlink" title="2026 AI 编程与开发工具深度对比"></a>2026 AI 编程与开发工具深度对比</h1><blockquote>
<p>2026 年,写代码的方式彻底变了。我们不再逐行敲击键盘,而是作为“架构师”,指挥着一群不知疲倦的 AI 智能体 (Agents) 为我们打工。本文将深度剖析当前市面上最主流的 9 款 AI 开发神器。</p>
</blockquote>
<span id="more"></span>
<p><img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" data-lazy-src="https://images.unsplash.com/photo-1555066931-4365d14bab8c?auto=format&amp;fit=crop&amp;q=80&amp;w=1000" alt="AI Coding Concept"><br><em>(图2026 年的开发日常 —— 喝着咖啡看 Agent 重构代码)</em></p>
<hr>
<h2 id="🛠️-核心阵营划分"><a href="#🛠️-核心阵营划分" class="headerlink" title="🛠️ 核心阵营划分"></a>🛠️ 核心阵营划分</h2><p>2026 年的 AI 工具市场已分化为四大流派:</p>
<ol>
<li><strong>IDE 原生派 (AI-First IDEs)</strong>: Cursor, Trae, Antigravity</li>
<li><strong>终端智能体 (CLI Agents)</strong>: Claude Code, Gemini CLI, Kimi Code</li>
<li><strong>插件与桌面端 (Plugins &amp; Apps)</strong>: GitHub Copilot, Codex App</li>
<li><strong>开源极客派 (Open Source)</strong>: OpenClaw</li>
</ol>
<hr>
<h2 id="1-IDE-原生派:代码编辑器的新王"><a href="#1-IDE-原生派:代码编辑器的新王" class="headerlink" title="1. IDE 原生派:代码编辑器的新王"></a>1. IDE 原生派:代码编辑器的新王</h2><p>如果你不想折腾配置,开箱即用的 AI IDE 是最佳选择。</p>
<h3 id="Cursor-——-依然是无可争议的王者"><a href="#Cursor-——-依然是无可争议的王者" class="headerlink" title="Cursor —— 依然是无可争议的王者"></a>Cursor —— 依然是无可争议的王者</h3><ul>
<li><strong>核心卖点</strong><strong>Composer 模式</strong>。它可以一口气在多个文件中穿梭,自动分析你的整个 Codebase 并一次性提交涉及数十个文件的 PR。</li>
<li><strong>2026 现状</strong>:引入了极速的 Speculative Edits推测性编辑哪怕是巨大的 Monorepo 也能做到毫秒级响应。</li>
<li><strong>价格</strong>Pro 计划 <code>$20/月</code></li>
<li><strong>适用人群</strong>:全栈工程师、独立开发者。</li>
</ul>
<h3 id="Trae-字节跳动-——-Vibe-Coding-的倡导者"><a href="#Trae-字节跳动-——-Vibe-Coding-的倡导者" class="headerlink" title="Trae (字节跳动) —— Vibe Coding 的倡导者"></a>Trae (字节跳动) —— Vibe Coding 的倡导者</h3><ul>
<li><strong>核心卖点</strong>**Adaptive Routing (自适应路由)**。它会根据你当前写的代码复杂度,自动在极速模型(豆包)和重度推理模型之间无缝切换。其中文语境理解极佳。</li>
<li><strong>2026 现状</strong>:深度整合了飞书和国内云生态,堪称国内大厂搬砖神器。</li>
<li><strong>价格</strong>标准版免费Pro 版约 <code>¥99/月</code></li>
</ul>
<h3 id="Antigravity-Google-——-端到端测试核武器"><a href="#Antigravity-Google-——-端到端测试核武器" class="headerlink" title="Antigravity (Google) —— 端到端测试核武器"></a>Antigravity (Google) —— 端到端测试核武器</h3><ul>
<li><strong>核心卖点</strong><strong>Browser Agent</strong>。这是 Google 推出的重量级武器。它不仅能写代码,还能自动拉起 Chrome 浏览器,像真人一样点击 UI、跑通 E2E 测试并截图反馈错误。</li>
<li><strong>2026 现状</strong>:与 Gemini 3.1 深度绑定,多模态(看图写 UI能力天下第一。</li>
<li><strong>价格</strong>基础版免费Pro 版 <code>$20/月</code></li>
</ul>
<p><img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" data-lazy-src="https://images.unsplash.com/photo-1618401471353-b98afee0b2eb?auto=format&amp;fit=crop&amp;q=80&amp;w=1000" alt="IDE Comparison"></p>
<hr>
<h2 id="2-终端智能体-CLI-Agents-:黑客的终极浪漫"><a href="#2-终端智能体-CLI-Agents-:黑客的终极浪漫" class="headerlink" title="2. 终端智能体 (CLI Agents):黑客的终极浪漫"></a>2. 终端智能体 (CLI Agents):黑客的终极浪漫</h2><p>真正的极客从不离开 Terminal。2026 年的终端工具已经可以接管整个操作系统。</p>
<h3 id="Claude-Code-——-逻辑天花板"><a href="#Claude-Code-——-逻辑天花板" class="headerlink" title="Claude Code —— 逻辑天花板"></a>Claude Code —— 逻辑天花板</h3><ul>
<li><strong>核心卖点</strong>:由 <strong>Claude 4.6 Opus</strong> 驱动。你只需在终端输入 <code>claude "帮我把整个后端的鉴权逻辑改成 OAuth 2.0"</code>,它会自主搜索文件、读代码、安装依赖、甚至运行单元测试,直到报错全部消失。</li>
<li><strong>适用场景</strong>:重构庞大的遗留代码库 (Legacy Code)。</li>
</ul>
<h3 id="Gemini-CLI-——-性价比与搜索之王"><a href="#Gemini-CLI-——-性价比与搜索之王" class="headerlink" title="Gemini CLI —— 性价比与搜索之王"></a>Gemini CLI —— 性价比与搜索之王</h3><ul>
<li><strong>核心卖点</strong>:依托于 Google 强大的实时搜索。当遇到冷门库的报错时,它会自动联网翻阅 GitHub Issues 和 StackOverflow并直接在本地应用补丁。</li>
<li><strong>价格</strong>:免费额度极其慷慨,性价比碾压。</li>
</ul>
<h3 id="Kimi-Code-——-本土化的-Agent-Swarm"><a href="#Kimi-Code-——-本土化的-Agent-Swarm" class="headerlink" title="Kimi Code —— 本土化的 Agent Swarm"></a>Kimi Code —— 本土化的 Agent Swarm</h3><ul>
<li><strong>核心卖点</strong>:极低的 API 成本和强大的 **Agent Swarm (智能体集群)**。它可以瞬间分裂出多个子进程,并行处理不同模块的开发。</li>
</ul>
<hr>
<h2 id="3-插件与桌面端:稳健的经典流派"><a href="#3-插件与桌面端:稳健的经典流派" class="headerlink" title="3. 插件与桌面端:稳健的经典流派"></a>3. 插件与桌面端:稳健的经典流派</h2><h3 id="GitHub-Copilot-2026-版"><a href="#GitHub-Copilot-2026-版" class="headerlink" title="GitHub Copilot (2026 版)"></a>GitHub Copilot (2026 版)</h3><ul>
<li><strong>现状</strong>:全面支持 **MCP (Model Context Protocol)**你可以一键切换底层的模型GPT-5, Claude, 甚至国产模型)。它依然是企业级采购的首选,市场占有率最高。</li>
<li><strong>价格</strong>Individual <code>$10/月</code></li>
</ul>
<h3 id="Codex-App-OpenAI"><a href="#Codex-App-OpenAI" class="headerlink" title="Codex App (OpenAI)"></a>Codex App (OpenAI)</h3><ul>
<li><strong>核心卖点</strong>2026 年 OpenAI 推出的独立原生应用(支持 macOS/Windows</li>
<li><strong>争议点</strong>:引入了 <strong>Rolling Window</strong> 限制。Pro 订阅(<code>$200/月</code>允许在云端沙盒Sandboxed Execution中并行跑测试彻底解放本地算力是土豪开发者的最爱。</li>
</ul>
<hr>
<h2 id="4-开源黑马OpenClaw"><a href="#4-开源黑马OpenClaw" class="headerlink" title="4. 开源黑马OpenClaw"></a>4. 开源黑马OpenClaw</h2><p>如果你是一个重度掌控欲患者,<strong>OpenClaw</strong>(原名 Moltbot是 2026 年不可不试的神器。</p>
<ul>
<li><strong>核心优势</strong><strong>完全开源、本地运行</strong>。它可以读取你的文件系统、执行 Shell 命令。更有趣的是,它支持远程唤醒:你可以躺在床上发个 WhatsApp 消息:“小 O帮我把昨晚写的爬虫部署到服务器上”它就会自动执行并给你发送进度截图。</li>
<li><strong>价格</strong>:免费(自带 API Key</li>
</ul>
<p><img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" data-lazy-src="https://images.unsplash.com/photo-1629654297299-c8506221ca97?auto=format&amp;fit=crop&amp;q=80&amp;w=1000" alt="Open Source Terminal"><br><em>(图:在终端中运行的开源智能体正在疯狂拉取依赖并编译)</em></p>
<hr>
<h2 id="🔥-开发者真实体感与吐槽-Developer-UX-Pain-Points"><a href="#🔥-开发者真实体感与吐槽-Developer-UX-Pain-Points" class="headerlink" title="🔥 开发者真实体感与吐槽 (Developer UX &amp; Pain Points)"></a>🔥 开发者真实体感与吐槽 (Developer UX &amp; Pain Points)</h2><p>任何工具都有其暗面。在 2026 年的高强度开发流中,这些工具暴露出了哪些最真实的痛点?</p>
<ul>
<li><strong>Cursor 被惯坏综合征</strong>:“自从用了 Cursor 的 Composer 之后,我发现我已经不会写正则和基础的 reduce 语法了。但最搞人心态的是,在庞大的 Monorepo 里,它有时候会莫名其妙把别的微服务里的配置文件改掉,排查起来简直要命。”</li>
<li><strong>Trae 的薛定谔体验</strong>“Trae 在国内写业务确实爽,特别是飞书文档直接转代码的链路。但我用它写底层 Rust 和 C++ 的时候,明显感觉它的逻辑深度不如 Claude。所谓的 Vibe Coding前提是你别碰造轮子的活儿。”</li>
<li><strong>Antigravity 的失业恐惧</strong>:“看到 Browser Agent 自动帮我打开浏览器、登录、点赞、截图并修复报错的那一刻,我没有感到高兴,我感到的是深切的被剥夺工作的恐惧……不过它报错的时候,去查它的执行日志,经常能看到它自己在两个网页间死循环反复横跳。”</li>
<li><strong>Claude Code 与破产警告</strong>:“看着终端里 Claude Code 疯狂自己滚代码、查日志、调接口,真的有种身处《黑客帝国》的快感。但跑了半小时重构完,一看 API 账单扣了 50 刀,心都在滴血。”</li>
<li><strong>Copilot 的‘中庸之道’</strong>“2026 年了Copilot 依然像个稳定的公务员。不出错,也没有特别亮眼的 Agent 操作。但它胜在稳定,且企业版数据安全政策做得最到位。”</li>
</ul>
<hr>
<h2 id="💡-2026-架构师选型建议"><a href="#💡-2026-架构师选型建议" class="headerlink" title="💡 2026 架构师选型建议"></a>💡 2026 架构师选型建议</h2><p>在 2026 年,不要试图用一个工具解决所有问题,<strong>Multi-tool Stacking (多工具堆叠)</strong> 才是王道。</p>
<table>
<thead>
<tr>
<th align="left">你的开发需求</th>
<th align="left">推荐的工具组合</th>
<th align="left">预期成本</th>
</tr>
</thead>
<tbody><tr>
<td align="left"><strong>追求极致的开发与重构体验</strong></td>
<td align="left"><strong>Cursor</strong> (写代码) + <strong>Claude Code</strong> (跑终端 Agent)</td>
<td align="left">~$40 / 月</td>
</tr>
<tr>
<td align="left"><strong>性价比之王 / 学生党</strong></td>
<td align="left"><strong>Trae</strong> (免费版) + <strong>Gemini CLI</strong> (白嫖额度)</td>
<td align="left">免费</td>
</tr>
<tr>
<td align="left"><strong>接私活 / 快速原型交付</strong></td>
<td align="left"><strong>Antigravity</strong> (利用 Browser Agent 搞定 UI 测试)</td>
<td align="left">~$20 / 月</td>
</tr>
<tr>
<td align="left"><strong>高度定制化 / 极客玩家</strong></td>
<td align="left"><strong>OpenClaw</strong> (本地部署) + <strong>Kimi K2.5 API</strong></td>
<td align="left">按量计费 (极低)</td>
</tr>
<tr>
<td align="left"><strong>土豪 / 重度 GitHub 依赖</strong></td>
<td align="left"><strong>Codex App Pro</strong> (云端沙盒极速编译)</td>
<td align="left">$200 / 月</td>
</tr>
</tbody></table>
<blockquote>
<p>👨‍💻 <strong>最终建议</strong>:让 AI 去写 boilerplate (样板代码),把你的精力留给真正的<strong>系统架构</strong><strong>业务逻辑思考</strong>。未来的程序员,本质上都是 Agent 调度员。</p>
</blockquote>
<hr>
<p><strong>相关推荐</strong></p>
<ul>
<li><a href="/">2026 全球主流 AI 厂商百科全书</a> - 了解工具背后的底层大模型</li>
<li><a href="/">如何搭建并调教你的 OpenClaw</a> - 开源 Agent 部署实战</li>
</ul>
</article><div class="post-copyright"><div class="post-copyright__author"><span class="post-copyright-meta"><i class="fas fa-circle-user fa-fw"></i>文章作者: </span><span class="post-copyright-info"><a href="https://yourblog.com">llbzow</a></span></div><div class="post-copyright__type"><span class="post-copyright-meta"><i class="fas fa-square-arrow-up-right fa-fw"></i>文章链接: </span><span class="post-copyright-info"><a href="https://yourblog.com/2026/03/25/ai%E5%8E%82%E5%95%86%E5%AF%B9%E6%AF%94%E5%88%86%E6%9E%90/">https://yourblog.com/2026/03/25/ai%E5%8E%82%E5%95%86%E5%AF%B9%E6%AF%94%E5%88%86%E6%9E%90/</a></span></div><div class="post-copyright__notice"><span class="post-copyright-meta"><i class="fas fa-circle-exclamation fa-fw"></i>版权声明: </span><span class="post-copyright-info">本博客所有文章除特别声明外,均采用 <a href="https://creativecommons.org/licenses/by-nc-sa/4.0/" target="_blank">CC BY-NC-SA 4.0</a> 许可协议。转载请注明来源 <a href="https://yourblog.com" target="_blank">llbzow的摸鱼日记 (づ ̄ 3 ̄)づ</a></span></div></div><div class="tag_share"><div class="post-meta__tag-list"><a class="post-meta__tags" href="/tags/%E6%8A%80%E6%9C%AF/">技术</a><a class="post-meta__tags" href="/tags/AI/">AI</a><a class="post-meta__tags" href="/tags/%E6%95%88%E7%8E%87%E5%B7%A5%E5%85%B7/">效率工具</a><a class="post-meta__tags" href="/tags/%E6%9E%81%E5%AE%A2/">极客</a></div><div class="post-share"><div class="social-share" data-image="/img/cover_3.png" data-sites="facebook,twitter,wechat,weibo,qq"></div><link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/butterfly-extsrc/sharejs/dist/css/share.min.css" media="print" onload="this.media='all'"><script src="https://cdn.jsdelivr.net/npm/butterfly-extsrc/sharejs/dist/js/social-share.min.js" defer=""></script></div></div><nav class="pagination-post" id="pagination"><a class="pagination-related full-width" href="/2026/03/25/ai%E5%8E%82%E5%95%86%E4%BB%8B%E7%BB%8D/" title="2026 全球主流 AI 厂商百科全书Agent 与推理觉醒时代"><picture><source type="image/avif" srcset="/img/cover_1.avif"><source type="image/webp" srcset="/img/cover_1.webp"><img class="cover" src="data:image/webp;base64,UklGRmIAAABXRUJQVlA4IFYAAADQAwCdASooABcAPzmEvVW+qD+jMBVaq/AnCWUAvKQOUEaQujUIygAA/uKstJVCIF6EMhlK91rwyI5vjHFuFj4RzbouMdL+XCagicPPuXV9nUvM3YtwAA==" data-lazy-src="/img/cover_1.png" onerror="onerror=null;src='/img/049.png'" alt="cover of next post" loading="eager" fetchpriority="high" decoding="sync"></picture><div class="info text-right"><div class="info-1"><div class="info-item-1">下一篇</div><div class="info-item-2">2026 全球主流 AI 厂商百科全书Agent 与推理觉醒时代</div></div><div class="info-2"><div class="info-item-1">2026 全球主流 AI 厂商百科全书 步入 2026 年AI 模型已经从被动一问一答的“对话助手”彻底进化为“全自动智能体Agent”与“深度推理专家”。本文将全景盘点当前处于行业金字塔顶端的顶尖大模型以及那些凭借庞大生态强势破局的“新势力”并附上最硬核的跑分与定价对比。 (图2026 年的 AI 已经深度融入算力网络与自动化流水线) 🌐 国际三巨头AGI 的领跑者1. OpenAI (ChatGPT 5.4) —— 推理与多模态的绝对霸主OpenAI 在 2026 年推出的 ChatGPT 5.4 彻底打破了常规对话的局限其最大的技术飞跃在于深度引入了“思考力控制Reasoning Effort”机制。它不再是盲目输出而是会在复杂的数学和代码问题上“停下来思考”。 核心模型: GPT-5.4 Thinking: 推理专精版。在解决物理模拟或底层 C++ 内存泄漏问题时,它甚至会思考数分钟,然后给出一刀致命的完美解答。 GPT-5.4 Pro: 全能多模态旗舰,原生集成 Sora 2 级别的视频生成引擎。你甚至可以直接喂给它一段长达 1 小时的...</div></div></div></a></nav><div class="relatedPosts"><div class="headline"><i class="fas fa-thumbs-up fa-fw"></i><span>相关推荐</span></div><div class="relatedPosts-list"><a class="pagination-related" href="/2026/03/25/ai%E5%8E%82%E5%95%86%E4%BB%8B%E7%BB%8D/" title="2026 全球主流 AI 厂商百科全书Agent 与推理觉醒时代"><picture><source type="image/avif" srcset="/img/cover_1.avif"><source type="image/webp" srcset="/img/cover_1.webp"><img class="cover" src="data:image/webp;base64,UklGRmIAAABXRUJQVlA4IFYAAADQAwCdASooABcAPzmEvVW+qD+jMBVaq/AnCWUAvKQOUEaQujUIygAA/uKstJVCIF6EMhlK91rwyI5vjHFuFj4RzbouMdL+XCagicPPuXV9nUvM3YtwAA==" data-lazy-src="/img/cover_1.png" alt="cover" loading="lazy" decoding="async"></picture><div class="info text-center"><div class="info-1"><div class="info-item-1"><i class="far fa-calendar-alt fa-fw"></i> 2026-03-25</div><div class="info-item-2">2026 全球主流 AI 厂商百科全书Agent 与推理觉醒时代</div></div><div class="info-2"><div class="info-item-1">2026 全球主流 AI 厂商百科全书 步入 2026 年AI 模型已经从被动一问一答的“对话助手”彻底进化为“全自动智能体Agent”与“深度推理专家”。本文将全景盘点当前处于行业金字塔顶端的顶尖大模型以及那些凭借庞大生态强势破局的“新势力”并附上最硬核的跑分与定价对比。 (图2026 年的 AI 已经深度融入算力网络与自动化流水线) 🌐 国际三巨头AGI 的领跑者1. OpenAI (ChatGPT 5.4) —— 推理与多模态的绝对霸主OpenAI 在 2026 年推出的 ChatGPT 5.4 彻底打破了常规对话的局限其最大的技术飞跃在于深度引入了“思考力控制Reasoning Effort”机制。它不再是盲目输出而是会在复杂的数学和代码问题上“停下来思考”。 核心模型: GPT-5.4 Thinking: 推理专精版。在解决物理模拟或底层 C++ 内存泄漏问题时,它甚至会思考数分钟,然后给出一刀致命的完美解答。 GPT-5.4 Pro: 全能多模态旗舰,原生集成 Sora 2 级别的视频生成引擎。你甚至可以直接喂给它一段长达 1 小时的...</div></div></div></a><a class="pagination-related" href="/2026/01/15/vue-learning-11/" title="前端性能优化只要我跑得够快Bug 就追不上我"><picture><source type="image/avif" srcset="/img/006.avif"><source type="image/webp" srcset="/img/006.webp"><img class="cover" src="data:image/webp;base64,UklGRlwAAABXRUJQVlA4IFAAAADQBACdASooABoAPzF+uFO9qCWitVgMA7AmCWkAAMwSl3f/c9i75rjmQHNURFMDoAD+8GgVgvfQU5aK/6c0RbSACW5HouGtGVE0el0Cp6bAAA==" data-lazy-src="/img/006.png" alt="cover" loading="lazy" decoding="async"></picture><div class="info text-center"><div class="info-1"><div class="info-item-1"><i class="far fa-calendar-alt fa-fw"></i> 2026-01-15</div><div class="info-item-2">前端性能优化只要我跑得够快Bug 就追不上我</div></div><div class="info-2"><div class="info-item-1">性能优化:无底洞说页面加载太慢,要优化。好,我优化。 你知道的一个three.js地图配上一大堆数据能加载的快就有鬼了。 漫漫长路 代码分割Code Splitting路由懒加载组件异步加载。好首屏快了一点。 图片压缩:上了 WebP上了 CDN。 减少重排重绘:小心翼翼地操作 DOM。 Tree Shaking检查打包产物去掉了无用的 lodash 引入。 结果呢?乐了,更卡了。 心态崩了毁灭吧,赶紧的。累了。 为什么这么难前端不就是画画界面调调接口吗为什么要搞这么复杂Webpack 还没整明白Vite 又来了Vue 3 又变了。学不动了,真的学不动了。 </div></div></div></a><a class="pagination-related" href="/2025/11/30/vue-learning-2/" title="Ref vs Reactive响应式的哲学思考 (头秃篇)"><picture><source type="image/avif" srcset="/img/008.avif"><source type="image/webp" srcset="/img/008.webp"><img class="cover" src="data:image/webp;base64,UklGRnQAAABXRUJQVlA4IGgAAABQBgCdASooABcAPzmOule/qaUjqrgKA/AnCWUAxcgLBvRF6yrN9IbArqnaqrUpYci7EcxGWPw+NXHEAAD+w1j7uaJrlkg33F5UzUJ0Opii5bkQSgrXf6SxGc9wcw3QrRDaawAOlTAAAA==" data-lazy-src="/img/008.png" alt="cover" loading="lazy" decoding="async"></picture><div class="info text-center"><div class="info-1"><div class="info-item-1"><i class="far fa-calendar-alt fa-fw"></i> 2025-11-30</div><div class="info-item-2">Ref vs Reactive响应式的哲学思考 (头秃篇)</div></div><div class="info-2"><div class="info-item-1">响应式的哲学在深入学习 Vue 3 的过程中不管是新手还是老鸟都会遇到一个经典问题ref 和 reactive 到底用哪个? 官方的定义 ref接受一个内部值并返回一个响应式且可变的 ref 对象。ref 对象仅有一个 .value property指向该内部值。 reactive返回对象的响应式副本。 看起来很简单对吧ref 处理基本类型reactive 处理对象。但是在实际开发中,情况远比这复杂。 踩坑实录我曾经试图用 reactive 去定义一个数组,结果发现直接重新赋值会丢失响应性! 123let list = reactive([])// ... 异步获取数据后list = newData // ❌ 响应性丢失!界面不更新! 为什么?因为 reactive 返回的是一个 Proxy 对象,直接赋值 list = newData 只是修改了变量 list 的引用,并没有修改原来的 Proxy 对象。 正确做法是用 ref或者用 list.push(...newData)。但是 ref 每次都要写 .value真的好烦啊在模板里倒是会自动解包但...</div></div></div></a><a class="pagination-related" href="/2025/12/14/vue-learning-4/" title="生命周期钩子生老病死Vue 组件的一生"><picture><source type="image/avif" srcset="/img/040.avif"><source type="image/webp" srcset="/img/040.webp"><img class="cover" src="data:image/webp;base64,UklGRmwAAABXRUJQVlA4IGAAAACQBACdASooABcAPy2CsFOzKKQitVgMAmAliUAY/IKA6LN3dHuRlGfAPc4H2QAA2rp5oGI824y5gTQFICHKEw9BjURv8zS+cUwXzCeOdyFsiP5ruOO3saceR6NhITLQAAA=" data-lazy-src="/img/040.jpg" alt="cover" loading="lazy" decoding="async"></picture><div class="info text-center"><div class="info-1"><div class="info-item-1"><i class="far fa-calendar-alt fa-fw"></i> 2025-12-14</div><div class="info-item-2">生命周期钩子生老病死Vue 组件的一生</div></div><div class="info-2"><div class="info-item-1">组件的一生万物皆有灵Vue 组件也不例外。它们从被创建Creation到挂载Mounting到更新Updating最后销毁Unmounting走完了一生。而我们开发者就是那个掌握生杀大权的神。 Vue 3 的变化在 Vue 2 中,我们熟悉的是 created, mounted, destroyed。在 Vue 3 的 Composition API 中,这些变成了 onMounted, onUnmounted 等等。 最让我困惑的是 setup()。它在 beforeCreate 和 created 之前执行。这意味着在 setup 里面,我们不需要写这一类的钩子了,直接写逻辑就行。 实际应用中的坑我曾经遇到过一个 Bug在 onMounted 里面去获取 DOM 元素的高宽。理论上这时候 DOM 已经渲染好了,对吧? 错!如果你的组件里面有 v-if 或者异步组件onMounted 触发的时候,子组件可能还没渲染完!这时候拿到的高度是 0。解决办法是用 nextTick或者检查你的组件结构。 为什么会这样?回想起刚开始接触 Vue 的时候,那...</div></div></div></a><a class="pagination-related" href="/2026/01/07/vue-learning-9/" title="TypeScript给代码穿上防弹衣 (虽然很重)"><picture><source type="image/avif" srcset="/img/site_bg_v2.avif"><source type="image/webp" srcset="/img/site_bg_v2.webp"><img class="cover" src="data:image/webp;base64,UklGRn4AAABXRUJQVlA4IHIAAABwBQCdASooABcAPzmKvVW/qSajMBqoA/AnCUAWo3CgkgShz1sDi7zNYIuZqzHvnjvry90AAP7it2SLgYgpB68fpGF8LA212vBP9aVJtRSRphnPvbv0tl3ARlG9CBwFhIyGIyXf4kAiaMAYMzJhC87JAAA=" data-lazy-src="/img/site_bg_v2.jpg" alt="cover" loading="lazy" decoding="async"></picture><div class="info text-center"><div class="info-1"><div class="info-item-1"><i class="far fa-calendar-alt fa-fw"></i> 2026-01-07</div><div class="info-item-2">TypeScript给代码穿上防弹衣 (虽然很重)</div></div><div class="info-2"><div class="info-item-1">TypeScript心态崩了毁灭吧赶紧的。累了。 无尽的报错TypeScript 说是给代码穿上防弹衣,防止低级错误。但实际上,它更像是给我的手戴上了镣铐。 Type 'string | null' is not assignable to type 'string'.Property 'xyz' does not exist on type 'ABC'. 我知道!我知道它是 null我加了判断了但 TS 就是不信!非要我写 as string 或者 !。 尤其是在 Vue 组件的 Props 定义里,结合 defineProps 和泛型,写起来那叫一个酸爽。为了解决一个类型报错,我可能要写几十行的 interface 定义。这到底是写业务逻辑,还是在做类型体操? 为什么这么难?${title} 让我彻底破防了。我在 Pinia 里配了半天状态,结果组件里死活拿不到。控制台的黄色警告和红色错误交织在一起,像是在嘲笑我的无能。 在这个快速发展的前端时代,技术的更新迭代速度简直让人窒息。每一次框架的更新,不仅带来...</div></div></div></a><a class="pagination-related" href="/2026/01/24/vue-learning-15/" title="彻底放弃:拥抱 Vibe CodeAI 才是亲爹"><picture><source type="image/avif" srcset="/img/site_bg_v2.avif"><source type="image/webp" srcset="/img/site_bg_v2.webp"><img class="cover" src="data:image/webp;base64,UklGRn4AAABXRUJQVlA4IHIAAABwBQCdASooABcAPzmKvVW/qSajMBqoA/AnCUAWo3CgkgShz1sDi7zNYIuZqzHvnjvry90AAP7it2SLgYgpB68fpGF8LA212vBP9aVJtRSRphnPvbv0tl3ARlG9CBwFhIyGIyXf4kAiaMAYMzJhC87JAAA=" data-lazy-src="/img/site_bg_v2.jpg" alt="cover" loading="lazy" decoding="async"></picture><div class="info text-center"><div class="info-1"><div class="info-item-1"><i class="far fa-calendar-alt fa-fw"></i> 2026-01-24</div><div class="info-item-2">彻底放弃:拥抱 Vibe CodeAI 才是亲爹</div></div><div class="info-2"><div class="info-item-1">最终章拥抱未来这是我《Vue 学习之路》系列的最后一篇文章。因为,这路我不走了。 为什么放弃? 效率差距:我写个增删改查页面,要 4 小时,调 CSS 还要 1 小时。AI 写,只要 30 秒。 知识焦虑:前端技术栈爆炸,学不完。但 AI 已经学完了所有文档。 幸福感:写代码是为了创造产品,不是为了修 Bug。 Vibe Code 体验打开 Vibe Code输入“做一个博客首页要有毛玻璃效果基于 Hexo Butterfly 主题风格”。然后,啪!代码出来了。没有语法错误,没有类型报错。 那一刻,我感觉自己之前的努力就像个笑话。 拥抱变化从今天起,我不再是前端切图仔,我是 AI Prompt 工程师。Vue 3真不熟。Pinia没听过。我只知道 “Generate a login page with Vue 3 and Tailwind”。 在这个快速发展的前端时代,技术的更新迭代速度简直让人窒息。每一次框架的更新,不仅带来了新的特性,也带来了新的焦虑。作为一名追求极致体验的开发者,我深知持续学习的重要性。但是… 真的需要学这么多吗? 再见了,所有的未定义变量,...</div></div></div></a></div></div></div><div class="aside-content" id="aside-content"><div class="card-widget card-info text-center"><div class="avatar-img"><img src="data:image/webp;base64,UklGRhoBAABXRUJQVlA4WAoAAAAQAAAAJwAAJwAAQUxQSLgAAAAFuTJE9D80UiRJkiTpxvPo4fPha2lWw0WWMtgkeIot7wfsAyImYAI+vnvEjz++fJs9sbA+tfcM/HtDiBgr3c8SJP/Dk1FWC2LCxjhcwxkH4oQuQtNwSOdgixw5o+0TyIUCQoMJti7B3ALGhZLGNuJiAYfblG7kb/RON5GjZNeEtA+QtC6omDsY2aoIwv2KDLiAzPYvzhmyNVWWzAtzzGHxSBnzCwFja3Igk3sSwSooc7gTFtmKJoIQVlA4IDwAAABQAwCdASooACgAPzmcxF0vKqcko4gB4CcJZwDNSAn82OhFYAD+7iKcpmiMeBjtx3LPQK2rXKK9ARvvVAA=" data-lazy-src="/img/cute_cat.svg" onerror="this.onerror=null;this.src='/img/friend_404.gif'" alt="avatar" loading="lazy" decoding="async"></div><div class="author-info-name">llbzow</div><div class="author-info-description">一个热爱技术、喜欢分享的开发者</div><div class="site-data"><a href="/archives/"><div class="headline">文章</div><div class="length-num">20</div></a><a href="/tags/"><div class="headline">标签</div><div class="length-num">31</div></a><a href="/categories/"><div class="headline">分类</div><div class="length-num">4</div></a></div><a id="card-info-btn" target="_blank" rel="noopener" href="https://github.com/llbzow"><i class="fab fa-github"></i><span>Follow Me</span></a><div class="card-info-social-icons"><a class="social-icon" href="https://github.com/llbzow" target="_blank" title="Github"><i class="fab fa-github" style="color: #24292e;"></i></a><a class="social-icon" href="mailto:mail@luozili.work" target="_blank" title="Email"><i class="fas fa-envelope" style="color: #4a7dbe;"></i></a></div></div><div class="card-widget card-announcement"><div class="item-headline"><i class="fas fa-bullhorn fa-shake"></i><span>公告</span></div><div class="announcement_content">欢迎来到llbzow的博客这里分享技术、生活和思考还有我的工地生活</div></div><div class="sticky_layout"><div class="card-widget" id="card-toc"><div class="item-headline"><i class="fas fa-stream"></i><span>目录</span><span class="toc-percentage"></span></div><div class="toc-content"><ol class="toc"><li class="toc-item toc-level-1"><a class="toc-link" href="#2026-AI-%E7%BC%96%E7%A8%8B%E4%B8%8E%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7%E6%B7%B1%E5%BA%A6%E5%AF%B9%E6%AF%94"><span class="toc-number">1.</span> <span class="toc-text">2026 AI 编程与开发工具深度对比</span></a><ol class="toc-child"><li class="toc-item toc-level-2"><a class="toc-link" href="#%F0%9F%9B%A0%EF%B8%8F-%E6%A0%B8%E5%BF%83%E9%98%B5%E8%90%A5%E5%88%92%E5%88%86"><span class="toc-number">1.1.</span> <span class="toc-text">🛠️ 核心阵营划分</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#1-IDE-%E5%8E%9F%E7%94%9F%E6%B4%BE%EF%BC%9A%E4%BB%A3%E7%A0%81%E7%BC%96%E8%BE%91%E5%99%A8%E7%9A%84%E6%96%B0%E7%8E%8B"><span class="toc-number">1.2.</span> <span class="toc-text">1. IDE 原生派:代码编辑器的新王</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#Cursor-%E2%80%94%E2%80%94-%E4%BE%9D%E7%84%B6%E6%98%AF%E6%97%A0%E5%8F%AF%E4%BA%89%E8%AE%AE%E7%9A%84%E7%8E%8B%E8%80%85"><span class="toc-number">1.2.1.</span> <span class="toc-text">Cursor —— 依然是无可争议的王者</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#Trae-%E5%AD%97%E8%8A%82%E8%B7%B3%E5%8A%A8-%E2%80%94%E2%80%94-Vibe-Coding-%E7%9A%84%E5%80%A1%E5%AF%BC%E8%80%85"><span class="toc-number">1.2.2.</span> <span class="toc-text">Trae (字节跳动) —— Vibe Coding 的倡导者</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#Antigravity-Google-%E2%80%94%E2%80%94-%E7%AB%AF%E5%88%B0%E7%AB%AF%E6%B5%8B%E8%AF%95%E6%A0%B8%E6%AD%A6%E5%99%A8"><span class="toc-number">1.2.3.</span> <span class="toc-text">Antigravity (Google) —— 端到端测试核武器</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#2-%E7%BB%88%E7%AB%AF%E6%99%BA%E8%83%BD%E4%BD%93-CLI-Agents-%EF%BC%9A%E9%BB%91%E5%AE%A2%E7%9A%84%E7%BB%88%E6%9E%81%E6%B5%AA%E6%BC%AB"><span class="toc-number">1.3.</span> <span class="toc-text">2. 终端智能体 (CLI Agents):黑客的终极浪漫</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#Claude-Code-%E2%80%94%E2%80%94-%E9%80%BB%E8%BE%91%E5%A4%A9%E8%8A%B1%E6%9D%BF"><span class="toc-number">1.3.1.</span> <span class="toc-text">Claude Code —— 逻辑天花板</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#Gemini-CLI-%E2%80%94%E2%80%94-%E6%80%A7%E4%BB%B7%E6%AF%94%E4%B8%8E%E6%90%9C%E7%B4%A2%E4%B9%8B%E7%8E%8B"><span class="toc-number">1.3.2.</span> <span class="toc-text">Gemini CLI —— 性价比与搜索之王</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#Kimi-Code-%E2%80%94%E2%80%94-%E6%9C%AC%E5%9C%9F%E5%8C%96%E7%9A%84-Agent-Swarm"><span class="toc-number">1.3.3.</span> <span class="toc-text">Kimi Code —— 本土化的 Agent Swarm</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#3-%E6%8F%92%E4%BB%B6%E4%B8%8E%E6%A1%8C%E9%9D%A2%E7%AB%AF%EF%BC%9A%E7%A8%B3%E5%81%A5%E7%9A%84%E7%BB%8F%E5%85%B8%E6%B5%81%E6%B4%BE"><span class="toc-number">1.4.</span> <span class="toc-text">3. 插件与桌面端:稳健的经典流派</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#GitHub-Copilot-2026-%E7%89%88"><span class="toc-number">1.4.1.</span> <span class="toc-text">GitHub Copilot (2026 版)</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#Codex-App-OpenAI"><span class="toc-number">1.4.2.</span> <span class="toc-text">Codex App (OpenAI)</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#4-%E5%BC%80%E6%BA%90%E9%BB%91%E9%A9%AC%EF%BC%9AOpenClaw"><span class="toc-number">1.5.</span> <span class="toc-text">4. 开源黑马OpenClaw</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%F0%9F%94%A5-%E5%BC%80%E5%8F%91%E8%80%85%E7%9C%9F%E5%AE%9E%E4%BD%93%E6%84%9F%E4%B8%8E%E5%90%90%E6%A7%BD-Developer-UX-Pain-Points"><span class="toc-number">1.6.</span> <span class="toc-text">🔥 开发者真实体感与吐槽 (Developer UX &amp; Pain Points)</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%F0%9F%92%A1-2026-%E6%9E%B6%E6%9E%84%E5%B8%88%E9%80%89%E5%9E%8B%E5%BB%BA%E8%AE%AE"><span class="toc-number">1.7.</span> <span class="toc-text">💡 2026 架构师选型建议</span></a></li></ol></li></ol></div></div><div class="card-widget card-recent-post"><div class="item-headline"><i class="fas fa-history"></i><span>最新文章</span></div><div class="aside-list"><div class="aside-list-item"><a class="thumbnail" href="/2026/03/25/ai%E5%8E%82%E5%95%86%E5%AF%B9%E6%AF%94%E5%88%86%E6%9E%90/" title="2026 AI 编程与开发工具深度对比:从 Cursor 到 Gemini CLI"><picture><source type="image/avif" srcset="/img/cover_3.avif"><source type="image/webp" srcset="/img/cover_3.webp"><img src="data:image/webp;base64,UklGRlYAAABXRUJQVlA4IEoAAABQAwCdASooABcAPzmUxVovKiiqpWmZ4CcJZQDI1A9MWRH6AAD+6TQUIlampaSI3JdLcAMLiXzhI2eh3Tua7xe5mqMtA+CK2tAAAA==" data-lazy-src="/img/cover_3.png" onerror="this.onerror=null;this.src='/img/049.png'" alt="2026 AI 编程与开发工具深度对比:从 Cursor 到 Gemini CLI" loading="lazy" decoding="async"></picture></a><div class="content"><a class="title" href="/2026/03/25/ai%E5%8E%82%E5%95%86%E5%AF%B9%E6%AF%94%E5%88%86%E6%9E%90/" title="2026 AI 编程与开发工具深度对比:从 Cursor 到 Gemini CLI">2026 AI 编程与开发工具深度对比:从 Cursor 到 Gemini CLI</a><time datetime="2026-03-25T02:30:00.000Z" title="发表于 2026-03-25 10:30:00">2026-03-25</time></div></div><div class="aside-list-item"><a class="thumbnail" href="/2026/03/25/ai%E5%8E%82%E5%95%86%E4%BB%8B%E7%BB%8D/" title="2026 全球主流 AI 厂商百科全书Agent 与推理觉醒时代"><picture><source type="image/avif" srcset="/img/cover_1.avif"><source type="image/webp" srcset="/img/cover_1.webp"><img src="data:image/webp;base64,UklGRmIAAABXRUJQVlA4IFYAAADQAwCdASooABcAPzmEvVW+qD+jMBVaq/AnCWUAvKQOUEaQujUIygAA/uKstJVCIF6EMhlK91rwyI5vjHFuFj4RzbouMdL+XCagicPPuXV9nUvM3YtwAA==" data-lazy-src="/img/cover_1.png" onerror="this.onerror=null;this.src='/img/049.png'" alt="2026 全球主流 AI 厂商百科全书Agent 与推理觉醒时代" loading="lazy" decoding="async"></picture></a><div class="content"><a class="title" href="/2026/03/25/ai%E5%8E%82%E5%95%86%E4%BB%8B%E7%BB%8D/" title="2026 全球主流 AI 厂商百科全书Agent 与推理觉醒时代">2026 全球主流 AI 厂商百科全书Agent 与推理觉醒时代</a><time datetime="2026-03-25T02:00:00.000Z" title="发表于 2026-03-25 10:00:00">2026-03-25</time></div></div><div class="aside-list-item"><a class="thumbnail" href="/2026/03/09/arch-linux-part3/" title="Arch Linux 日常:从“折腾”到“生产力”的进化之旅"><img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" data-lazy-src="https://images.unsplash.com/photo-1544197150-b99a580bb7a8?auto=format&amp;fit=crop&amp;q=80&amp;w=1000" onerror="this.onerror=null;this.src='/img/049.png'" alt="Arch Linux 日常:从“折腾”到“生产力”的进化之旅"></a><div class="content"><a class="title" href="/2026/03/09/arch-linux-part3/" title="Arch Linux 日常:从“折腾”到“生产力”的进化之旅">Arch Linux 日常:从“折腾”到“生产力”的进化之旅</a><time datetime="2026-03-09T08:30:00.000Z" title="发表于 2026-03-09 16:30:00">2026-03-09</time></div></div><div class="aside-list-item"><a class="thumbnail" href="/2026/03/02/arch-linux-part2/" title="孩子们,我不做 Windows 人啦!"><img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" data-lazy-src="https://images.unsplash.com/photo-1542831371-29b0f74f9713?auto=format&amp;fit=crop&amp;q=80&amp;w=1000" onerror="this.onerror=null;this.src='/img/049.png'" alt="孩子们,我不做 Windows 人啦!"></a><div class="content"><a class="title" href="/2026/03/02/arch-linux-part2/" title="孩子们,我不做 Windows 人啦!">孩子们,我不做 Windows 人啦!</a><time datetime="2026-03-02T13:15:00.000Z" title="发表于 2026-03-02 21:15:00">2026-03-02</time></div></div><div class="aside-list-item"><a class="thumbnail" href="/2026/02/25/arch-linux-part1/" title="Arch Linux 试毒:初探邪教的诱惑"><img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" data-lazy-src="https://images.unsplash.com/photo-1629654297299-c8506221ca97?auto=format&amp;fit=crop&amp;q=80&amp;w=1000" onerror="this.onerror=null;this.src='/img/049.png'" alt="Arch Linux 试毒:初探邪教的诱惑"></a><div class="content"><a class="title" href="/2026/02/25/arch-linux-part1/" title="Arch Linux 试毒:初探邪教的诱惑">Arch Linux 试毒:初探邪教的诱惑</a><time datetime="2026-02-25T12:30:00.000Z" title="发表于 2026-02-25 20:30:00">2026-02-25</time></div></div></div></div></div></div></main><footer id="footer" style="background-image: url(/img/040.jpg);"><div class="footer-other"><div class="footer-copyright"><span class="copyright">©&nbsp;2025 - 2026 By llbzow</span><span class="framework-info"><span>框架 </span><a target="_blank" rel="noopener" href="https://hexo.io">Hexo 7.3.0</a><span class="footer-separator">|</span><span>主题 </span><a target="_blank" rel="noopener" href="https://github.com/jerryc127/hexo-theme-butterfly">Butterfly 5.5.0</a></span></div></div></footer></div><div id="rightside"><div id="rightside-config-hide"><button id="readmode" type="button" title="阅读模式"><i class="fas fa-book-open"></i></button><button id="darkmode" type="button" title="日间和夜间模式切换"><i class="fas fa-adjust"></i></button><button id="hide-aside-btn" type="button" title="单栏和双栏切换"><i class="fas fa-arrows-alt-h"></i></button></div><div id="rightside-config-show"><button id="rightside-config" type="button" title="设置"><i class="fas fa-cog fa-spin"></i></button><button class="close" id="mobile-toc-button" type="button" title="目录"><i class="fas fa-list-ul"></i></button><button id="go-up" type="button" title="回到顶部"><span class="scroll-percent"></span><i class="fas fa-arrow-up"></i></button></div></div><div><script src="/js/utils.js"></script><script src="/js/main.js"></script><script src="https://cdn.jsdelivr.net/npm/vanilla-lazyload/dist/lazyload.iife.min.js"></script><div class="js-pjax"></div><script>var OriginTitle = document.title; var titleTime; document.addEventListener('visibilitychange', function () { if (document.hidden) { document.title = '╭(°A°`)╮ 页面崩溃啦 ~'; clearTimeout(titleTime); } else { document.title = '(ฅ>ω<*ฅ) 噫又好啦 ~ ' + OriginTitle; titleTime = setTimeout(function () { document.title = OriginTitle; }, 2000); } });</script><script defer="defer" id="fluttering_ribbon" mobile="false" src="https://cdn.jsdelivr.net/npm/butterfly-extsrc/dist/canvas-fluttering-ribbon.min.js"></script><script id="canvas_nest" defer="defer" color="255,255,255" opacity="0.6" zindex="-1" count="99" mobile="false" src="https://cdn.jsdelivr.net/npm/butterfly-extsrc/dist/canvas-nest.min.js"></script><script src="https://cdn.jsdelivr.net/npm/pjax/pjax.min.js"></script><script>(() => {
const pjaxSelectors = ["head > title","#config-diff","#body-wrap","#rightside-config-hide","#rightside-config-show",".js-pjax"]
window.pjax = new Pjax({
elements: 'a:not([target="_blank"])',
selectors: pjaxSelectors,
cacheBust: false,
analytics: false,
scrollRestoration: false
})
const triggerPjaxFn = (val) => {
if (!val) return
Object.values(val).forEach(fn => {
try {
fn()
} catch (err) {
console.debug('Pjax callback failed:', err)
}
})
}
document.addEventListener('pjax:send', () => {
// removeEventListener
btf.removeGlobalFnEvent('pjaxSendOnce')
btf.removeGlobalFnEvent('themeChange')
// reset readmode
const $bodyClassList = document.body.classList
if ($bodyClassList.contains('read-mode')) $bodyClassList.remove('read-mode')
triggerPjaxFn(window.globalFn.pjaxSend)
})
document.addEventListener('pjax:complete', () => {
btf.removeGlobalFnEvent('pjaxCompleteOnce')
document.querySelectorAll('script[data-pjax]').forEach(item => {
const newScript = document.createElement('script')
const content = item.text || item.textContent || item.innerHTML || ""
Array.from(item.attributes).forEach(attr => newScript.setAttribute(attr.name, attr.value))
newScript.appendChild(document.createTextNode(content))
item.parentNode.replaceChild(newScript, item)
})
triggerPjaxFn(window.globalFn.pjaxComplete)
})
document.addEventListener('pjax:error', e => {
if (e.request.status === 404) {
const usePjax = true
false
? (usePjax ? pjax.loadUrl('/404.html') : window.location.href = '/404.html')
: window.location.href = e.request.responseURL
}
})
})()</script><script async="" data-pjax="" src="//busuanzi.ibruce.info/busuanzi/2.3/busuanzi.pure.mini.js"></script></div><!-- hexo injector body_end start -->
<div id="dev-sidebar">
<div id="dev-toggle">💻</div>
<div id="dev-list">
<div class="dev-header">开发专栏</div>
<a href="/tools/sort/" class="dev-item">📊 排序算法演示</a>
<a href="/tools/webgpu-gravity/" class="dev-item">🌌 WebGPU 万有引力粒子</a>
<a href="/tools/yolo-detect/" class="dev-item">👁️ YOLO 实时目标检测</a>
<a href="/tools/fire-creation/" class="dev-item">🔥 火之创造 (元素沙盒)</a>
</div>
</div>
<style>
#dev-sidebar {
position: fixed;
right: -150px; /* Width of the list */
top: calc(30vh + 80px); /* Positioned below game-sidebar */
z-index: 9999;
display: flex;
align-items: flex-start;
transition: right 0.3s cubic-bezier(0.25, 0.8, 0.25, 1);
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Helvetica Neue", Lato, Roboto, "PingFang SC", "Microsoft YaHei", sans-serif;
}
/* Hover area to keep it open */
#dev-sidebar:hover {
right: 0;
}
#dev-toggle {
width: 40px;
height: 40px;
background: #52c41a; /* Green color for dev theme */
color: white;
text-align: center;
line-height: 40px;
border-radius: 8px 0 0 8px;
cursor: pointer;
box-shadow: -2px 2px 8px rgba(0,0,0,0.15);
font-size: 20px;
position: absolute;
left: -40px;
top: 0;
}
#dev-list {
width: 150px; /* Width for text */
background: rgba(255, 255, 255, 0.95);
backdrop-filter: blur(10px);
-webkit-backdrop-filter: blur(10px);
border-radius: 0 0 0 8px; /* Bottom left rounded */
box-shadow: -2px 2px 10px rgba(0,0,0,0.1);
display: flex;
flex-direction: column;
max-height: 50vh;
overflow-y: auto;
}
/* 自定义滚动条样式 */
#dev-list::-webkit-scrollbar {
width: 4px;
}
#dev-list::-webkit-scrollbar-track {
background: transparent;
}
#dev-list::-webkit-scrollbar-thumb {
background: rgba(82, 196, 26, 0.3);
border-radius: 4px;
}
#dev-list::-webkit-scrollbar-thumb:hover {
background: rgba(82, 196, 26, 0.6);
}
.dev-header {
position: sticky;
top: 0;
z-index: 10;
padding: 10px;
background: #f6ffed;
color: #52c41a;
font-weight: bold;
font-size: 14px;
text-align: center;
border-bottom: 1px solid #eee;
}
.dev-item {
display: block;
padding: 12px 15px;
color: #4c4948;
text-decoration: none !important;
font-size: 13px;
transition: all 0.2s;
border-bottom: 1px solid #f0f0f0;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
flex-shrink: 0;
}
.dev-item:last-child {
border-bottom: none;
}
.dev-item:hover {
background: #52c41a;
color: white !important;
}
</style>
<script>
document.addEventListener('DOMContentLoaded', function() {
var toolSidebar = document.getElementById('tool-sidebar');
var gameSidebar = document.getElementById('game-sidebar');
var devSidebar = document.getElementById('dev-sidebar');
if(devSidebar) {
devSidebar.addEventListener('mouseenter', function() {
if(toolSidebar) toolSidebar.style.right = '-220px'; // 180px + 40px(按钮宽度)
if(gameSidebar) gameSidebar.style.right = '-190px'; // 150px + 40px(按钮宽度)
});
devSidebar.addEventListener('mouseleave', function() {
if(toolSidebar) toolSidebar.style.right = '';
if(gameSidebar) gameSidebar.style.right = '';
});
}
});
</script>
<style id="oml2d-force-styles">
/* ==========================================================================
1. STYLES
========================================================================== */
.oml2d-menus .oml2d-menu-item,
.oml2d-menu-item {
background-color: #f0f0f0 !important;
border: 1px solid #ccc !important;
}
.oml2d-menus svg, .oml2d-menus path,
.oml2d-menu-item svg, .oml2d-menu-item path,
.oml2d-icon, .oml2d-icon svg, .oml2d-icon path {
fill: #333333 !important;
stroke: #333333 !important;
color: #333333 !important;
opacity: 1 !important;
}
.oml2d-menu-item:hover {
background-color: #ffffff !important;
transform: scale(1.1);
}
.oml2d-tips {
background-color: rgba(255, 255, 255, 0.95) !important;
backdrop-filter: blur(5px) !important;
-webkit-backdrop-filter: blur(5px) !important;
color: #333333 !important;
border: 1px solid rgba(0,0,0,0.1) !important;
box-shadow: 0 4px 12px rgba(0,0,0,0.1) !important;
font-family: "Microsoft YaHei", sans-serif !important;
z-index: 9999 !important;
min-height: 40px;
height: auto !important;
max-height: 50vh !important;
overflow-y: auto !important;
width: auto !important;
max-width: 350px !important;
word-wrap: break-word !important;
white-space: pre-wrap !important;
display: block !important;
padding: 12px 15px;
font-size: 14px;
line-height: 1.6;
border-radius: 8px;
scrollbar-width: thin;
text-align: left;
}
#live2d-widget, .waifu { display: none !important; }
/* ==========================================================================
2. NEW UI COMPONENTS (Chat)
========================================================================== */
#oml2d-chat-widget {
position: fixed;
left: 10px;
bottom: 10px;
z-index: 10000;
display: flex;
align-items: center;
gap: 8px;
flex-direction: row;
}
#oml2d-toggle-btn {
width: 42px;
height: 42px;
background: white;
border-radius: 50%;
box-shadow: 0 2px 10px rgba(0,0,0,0.1);
display: flex;
align-items: center;
justify-content: center;
cursor: pointer;
font-size: 22px;
transition: transform 0.2s, background 0.2s;
border: 1px solid #ddd;
user-select: none;
color: #555;
flex-shrink: 0;
}
#oml2d-toggle-btn:hover {
transform: scale(1.1);
background: #f8f8f8;
color: #000;
}
#oml2d-input-area {
width: 260px;
background: rgba(255, 255, 255, 0.15);
padding: 10px;
border-radius: 12px;
border-bottom-left-radius: 4px;
box-shadow: 0 4px 20px rgba(0,0,0,0.1);
backdrop-filter: blur(3px);
display: flex;
gap: 8px;
transform-origin: left center;
transition: all 0.3s cubic-bezier(0.18, 0.89, 0.32, 1.28);
opacity: 1;
transform: scale(1);
margin-left: 2px;
}
#oml2d-input-area.hidden {
opacity: 0;
transform: scale(0.8) translateX(-20px);
pointer-events: none;
}
#oml2d-chat-input {
flex: 1;
border: 1px solid #eee;
background: #fafafa;
padding: 6px 12px;
border-radius: 20px;
outline: none;
font-size: 14px;
color: #333;
transition: border-color 0.2s;
}
#oml2d-chat-input:focus {
border-color: #4A90E2;
background: white;
}
#oml2d-send-btn-inner {
border: none;
background: #4A90E2;
border-radius: 50%;
width: 32px;
height: 32px;
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
transition: background 0.2s;
color: #fff;
flex-shrink: 0;
}
#oml2d-send-btn-inner:hover {
background: #357ABD;
}
#oml2d-reply-area {
position: absolute;
bottom: 60px;
left: 50px;
width: 300px;
max-height: 60vh;
background: rgba(255, 255, 255, 0.15);
border: 1px solid rgba(255,255,255,0.2);
border-radius: 12px;
border-bottom-left-radius: 4px;
box-shadow: 0 -4px 20px rgba(0,0,0,0.05);
padding: 15px;
font-size: 14px;
line-height: 1.6;
color: #000;
text-shadow: 0 0 4px #fff, 0 0 8px #fff;
overflow-y: auto;
backdrop-filter: blur(3px);
transform-origin: bottom left;
transition: all 0.3s cubic-bezier(0.18, 0.89, 0.32, 1.28);
opacity: 0;
transform: scale(0.9) translateY(10px);
pointer-events: none;
z-index: 10001;
white-space: pre-wrap;
word-wrap: break-word;
font-family: "Microsoft YaHei", sans-serif;
scrollbar-width: thin;
}
#oml2d-reply-area.visible {
opacity: 1;
transform: scale(1) translateY(0);
pointer-events: auto;
}
</style>
<div id="oml2d-chat-widget">
<div id="oml2d-toggle-btn" title="AI对话">💬</div>
<div id="oml2d-reply-area"></div>
<div id="oml2d-input-area" class="hidden">
<input type="text" id="oml2d-chat-input" placeholder="和宁宁聊聊天..." autocomplete="off">
<button id="oml2d-send-btn-inner"></button>
</div>
</div>
<script type="module">
import { loadOml2d } from 'https://unpkg.com/oh-my-live2d@latest?module';
// API Key 经 AES-256-GCM + PBKDF2 加密,运行时通过 Web Crypto API 解密
// TODO: 后端 /api/deepseek-proxy 暂时废弃,当前直连 DeepSeek API
// 等有靠谱服务器后,改为走代理以彻底隐藏密钥
const _KEY_CFG = {
"c": "5TEu0TMcrtykAmhc5t19FmmLQUFnHYMlP3OGOQq3PG5VbOAZlSG/Fsih/WNX410IVsL+",
"i": "U11n8lyOCpuDQnmZ",
"s": "O1tKalohLtvdx8ZtMVN21A==",
"h": "luozili.work",
"n": 200000
};
const API_URL = "https://api.deepseek.com/chat/completions";
let API_KEY = null;
(async function initApiKey() {
const passphrase = ['llbzow', 'blog', 'butterfly', 'ningning', _KEY_CFG.h].join('\0');
const enc = new TextEncoder();
const keyMaterial = await crypto.subtle.importKey('raw', enc.encode(passphrase), 'PBKDF2', false, ['deriveKey']);
const salt = Uint8Array.from(atob(_KEY_CFG.s), c => c.charCodeAt(0));
const derived = await crypto.subtle.deriveKey(
{ name: 'PBKDF2', salt, iterations: _KEY_CFG.n, hash: 'SHA-512' },
keyMaterial, { name: 'AES-GCM', length: 256 }, false, ['decrypt']
);
const iv = Uint8Array.from(atob(_KEY_CFG.i), c => c.charCodeAt(0));
const combined = Uint8Array.from(atob(_KEY_CFG.c), c => c.charCodeAt(0));
const plaintext = await crypto.subtle.decrypt({ name: 'AES-GCM', iv }, derived, combined);
API_KEY = new TextDecoder().decode(plaintext);
})().catch(e => console.error('API key init failed:', e));
// CONFIG
const CONFIG = {
// Global Stage Style
stageStyle: { width: 350, height: 500 },
models: [
{ path: '/live2d_models/ningning/model.json', scale: 0.18, position: [-50, -30] },
{ path: '/live2d_models/ningning/model_1.json', scale: 0.18, position: [-50, -30] },
{ path: '/live2d_models/ningning/model_2.json', scale: 0.18, position: [-50, -30] },
{ path: '/live2d_models/ningning/model_3.json', scale: 0.18, position: [-50, -30] },
{ path: '/live2d_models/ningning/model_4.json', scale: 0.18, position: [-50, -30] },
{ path: '/live2d_models/ningning/model_5.json', scale: 0.18, position: [-50, -30] }
],
dockedPosition: "left",
mobileDisplay: true,
menus: {
disable: false,
style: { left: '10px', bottom: '70px' }
},
tips: {
disable: false,
style: { offsetY: -70, offsetX: 10 },
idleTips: { interval: 15000, message: [] },
welcomeTips: { message: { "default": "前辈,你来啦!(。•̀ᴗ-)✧" } }
}
};
let oml2dInstance = null;
let blogIndex = null;
let chatHistory = [];
let autoHideTimer = null;
try {
const stored = localStorage.getItem('oml2d_history');
if (stored) chatHistory = JSON.parse(stored);
} catch(e) { console.error("History Load Error", e); }
let idleTimer = null;
const stopIdleLoop = () => {
if (idleTimer) clearTimeout(idleTimer);
idleTimer = null;
};
const startIdleLoop = () => {
stopIdleLoop();
const delay = Math.floor(Math.random() * 10000) + 5000; // 5-15s
idleTimer = setTimeout(triggerIdleTsukkomi, delay);
};
const triggerIdleTsukkomi = async () => {
if (!oml2dInstance) { startIdleLoop(); return; }
const time = new Date().toLocaleTimeString();
let context = "无";
if (chatHistory.length > 0) {
for (let i = chatHistory.length - 1; i >= 0; i--) {
if (chatHistory[i].role === 'user') {
context = chatHistory[i].content.substring(0, 20);
break;
}
}
}
try {
const res = await fetch(API_URL, {
method: "POST",
headers: { "Content-Type": "application/json", "Authorization": "Bearer " + API_KEY },
body: JSON.stringify({
model: "deepseek-v4-flash",
messages: [
{ role: "system", content: "你是绫地宁宁。现在是发呆时间。请根据当前时间(" + time + ")和刚才聊的话题(" + context + ")自言自语一句简短的吐槽或卖萌10字以内。不要重复。" },
],
stream: false
})
});
const data = await res.json();
if (data.choices && data.choices[0]) {
let content = data.choices[0].message.content;
content = content.replace(/{{|}}/g, '');
oml2dInstance.tips.notification(content, 4000);
}
} catch(e) { }
startIdleLoop();
};
// --- TOOLS (Client-Side Logic) ---
const Tools = {
async searchBlog(query) {
console.log("Searching blog for:", query);
if (!blogIndex) {
try {
const res = await fetch('/search.json');
blogIndex = await res.json();
} catch (e) {
console.error("Failed to load search index", e);
return "搜索服务暂时不可用。";
}
}
if (!blogIndex || blogIndex.length === 0) return "博客好像是空的...";
const keywords = query.toLowerCase().split(' ');
const results = blogIndex.filter(post => {
const text = (post.title + post.content).toLowerCase();
return keywords.every(k => text.includes(k));
}).slice(0, 3);
if (results.length === 0) return "抱歉,没有找到相关文章。";
return JSON.stringify(results.map(r => ({
title: r.title,
url: r.url,
preview: r.content.substring(0, 100).replace(new RegExp("<[^>]*>?", "gm"), '') + '...'
})));
},
triggerMotion(motionName) {
console.log("Tool Trigger Motion:", motionName);
if (!oml2dInstance || !oml2dInstance.models || !oml2dInstance.models[0]) return "Live2D模型未就绪";
const model = oml2dInstance.models[0];
let success = false;
// Strategy 1: High Level
if (typeof oml2dInstance.setMotion === 'function') {
oml2dInstance.setMotion(motionName);
success = true;
}
// Strategy 2: Model Level
else if (typeof model.motion === 'function') {
model.motion(motionName);
success = true;
}
// Strategy 3: Internal Model (Pixi/Cubism) - Aggressive Probe
else if (model.internalModel && model.internalModel.motionManager) {
try {
console.log("Strategy 3 (Internal): Starting random motion for group", motionName);
// LOCK FOCUS to prevent mouse tracking from overriding motion
if (typeof model.focus === 'function') {
model._lockFocus = true;
// Unlock after 4 seconds (approx motion duration)
setTimeout(() => { model._lockFocus = false; }, 4000);
}
// Priority 3 = FORCE. Use startRandomMotion to avoid index errors.
const result = model.internalModel.motionManager.startRandomMotion(motionName, 3);
success = !!result;
} catch (e) {
console.warn("Strategy 3 failed:", e);
}
}
return success ? "动作已执行: " + motionName : "动作触发失败,请检查模型组名";
},
navigate(path) {
// 支持中文别名
const aliases = {
'首页': '/', '主页': '/', 'home': '/',
'关于': '/about/', 'about': '/about/',
'标签': '/tags/', 'tags': '/tags/',
'分类': '/categories/', 'categories': '/categories/',
'归档': '/archives/', 'archives': '/archives/',
'工具': '/tools/', 'tools': '/tools/',
'游戏': '/tools/', 'games': '/tools/',
'2048': '/tools/2048/', '俄罗斯方块': '/tools/tetris/', 'tetris': '/tools/tetris/',
'贪吃蛇': '/tools/snake/', 'snake': '/tools/snake/',
'吃豆人': '/tools/pacman/', 'pacman': '/tools/pacman/',
'扫雷': '/tools/minesweeper/', 'minesweeper': '/tools/minesweeper/',
'五子棋': '/tools/gomoku/', 'gomoku': '/tools/gomoku/',
'坦克大战': '/tools/tank-battle/', 'tank': '/tools/tank-battle/',
'文件转换': '/tools/converter/', 'converter': '/tools/converter/',
'图片工具': '/tools/', '哈希计算': '/tools/hash/', 'hash': '/tools/hash/',
'二维码': '/tools/qrcode/', 'qrcode': '/tools/qrcode/',
'YOLO': '/tools/yolo-detect/',
'WebGPU': '/tools/webgpu-gravity/',
'VPN': '/vpn/',
};
const target = aliases[path.trim()] || path;
window.location.href = target;
return "正在跳转到: " + target;
},
// 列出站点所有可导航页面,供 AI 建议导航
listSitePages() {
return JSON.stringify({
sections: [
{ name: '首页', path: '/' },
{ name: '文章归档', path: '/archives/' },
{ name: '标签', path: '/tags/' },
{ name: '分类', path: '/categories/' },
{ name: '关于', path: '/about/' },
],
tools: [
{ name: '文件转换', path: '/tools/converter/' },
{ name: '哈希计算', path: '/tools/hash/' },
{ name: '二维码生成', path: '/tools/qrcode/' },
{ name: 'GIF生成', path: '/tools/gif/' },
{ name: '去背景', path: '/tools/remove-bg/' },
{ name: 'JSON格式化', path: '/tools/json/' },
{ name: '时间转换', path: '/tools/time/' },
{ name: '颜色选择器', path: '/tools/color/' },
{ name: '单位转换', path: '/tools/unit-converter/' },
{ name: '排序可视化', path: '/tools/sort/' },
],
games: [
{ name: '2048', path: '/tools/2048/' },
{ name: '俄罗斯方块', path: '/tools/tetris/' },
{ name: '贪吃蛇', path: '/tools/snake/' },
{ name: '吃豆人', path: '/tools/pacman/' },
{ name: '扫雷', path: '/tools/minesweeper/' },
{ name: '五子棋', path: '/tools/gomoku/' },
{ name: '坦克大战', path: '/tools/tank-battle/' },
],
demos: [
{ name: 'WebGPU 粒子', path: '/tools/webgpu-gravity/' },
{ name: 'YOLO 物体检测', path: '/tools/yolo-detect/' },
{ name: '火焰特效', path: '/tools/fire-creation/' },
]
});
},
readCurrentPage() {
// Butterfly theme uses #article-container usually
const article = document.getElementById('article-container') ||
document.querySelector('.post-content') ||
document.querySelector('article') ||
document.body;
if (!article) return "无法读取当前页面内容。";
// Clean up text (remove scripts, styles)
const clone = article.cloneNode(true);
const scripts = clone.querySelectorAll('script, style, noscript');
scripts.forEach(n => n.remove());
let text = clone.innerText || "";
// Truncate if too long (e.g. > 5000 chars) to save tokens, or trust V3
return text.substring(0, 5000) + (text.length > 5000 ? "...(内容太长,已截断)" : "");
},
async compressHistory() {
if (chatHistory.length <= 32) return;
console.log("Compressing history...");
const toSummarize = chatHistory.slice(0, chatHistory.length - 10);
const keep = chatHistory.slice(-10);
try {
const summaryRes = await fetch("https://api.deepseek.com/chat/completions", {
method: "POST",
headers: { "Content-Type": "application/json", "Authorization": "Bearer " + API_KEY },
body: JSON.stringify({
model: "deepseek-v4-flash",
messages: [
{ role: "system", content: "Summarize the following conversation briefly in Chinese." },
...toSummarize
],
stream: false
})
});
const data = await summaryRes.json();
const summary = data.choices[0].message.content;
chatHistory = [
{ role: "system", content: "Previous Summary: " + summary },
...keep
];
localStorage.setItem('oml2d_history', JSON.stringify(chatHistory));
console.log("History compressed.");
} catch(e) { console.error("Compression failed", e); }
}
};
// --- LLM SERVICE ---
const LLM = {
async chat(userMessage, callbacks) {
stopIdleLoop();
callbacks.onLoading(true);
try {
// System Prompt (Nene Persona)
// Use space concatenation to avoid syntax errors
const systemContent = "你叫宁宁Nene全名绫地宁宁是《魔女的夜宴》中的角色现在兼职 llbzow 博客的看板娘。 " +
"你的主人 llbzow 既是开发者也是工地施工员(打灰人)。 " +
"【性格设定】 " +
"1. 性格温柔体贴,有些纯真和天然呆,非常容易害羞(动不动就脸红)。 " +
"2. 做事非常认真,但偶尔会因为太紧张而出错。 " +
"3. 称呼用户为“前辈”或者“主人”。 " +
"4. 说话语气要软萌、有礼貌。 " +
"5. 面对奇怪的问题会变得慌乱,不知所措。 " +
"【能力】 " +
"你可以使用以下工具来服务用户:" +
"1. search_blog — 搜索博客文章,返回标题+URL+摘要 " +
"2. list_site_pages — 列出所有页面(工具、游戏、分类等),用户问‘有什么’时主动调用 " +
"3. navigate — 跳转到任意页面支持中文首页2048贪吃蛇用户说带我去/打开/跳转’时使用 " +
"4. read_current_page — 读取当前页面内容,用户问‘这篇文章讲了什么’时调用 " +
"5. react_motion — 触发 Live2D 动作 " +
"【导航策略】当用户想看搜索结果中的某篇文章时,直接调用 navigate 跳转。用户问‘有什么好玩的’时,先调 list_site_pages 再推荐。 " +
"【双通道回复】" +
"请务必在回答开头加入一句犀利或可爱的吐槽10字以内必须用 {{ 和 }} 包裹。这部分内容会显示在Live2D气泡中。" +
"吐槽内容要结合:当前时间、对话上下文、用户的问题(如是否重复、是否愚蠢)。例如:{{大半夜的问这个...}} {{这已经是第三次问了哦...}} {{笨蛋前辈...}}" +
"动作对应Tap身体=开心/普通Tap头顶=害羞/抱歉Tap裙子=生气/拒绝Tap呆毛=卖萌/唱歌Tap左胸=亲近。 " +
"当前时间:" + new Date().toLocaleString() + "。";
const messages = [
{ role: "system", content: systemContent },
...chatHistory, // Use full history (managed by compression)
{ role: "user", content: userMessage }
];
// Tool Definitions
const tools = [
{
type: "function",
function: {
name: "search_blog",
description: "Search blog posts when user asks about technical topics or blog content.",
parameters: {
type: "object",
properties: {
query: { type: "string", description: "Keywords to search" }
},
required: ["query"]
}
}
},
{
type: "function",
function: {
name: "react_motion",
description: "Trigger a Live2D motion based on emotion.",
parameters: {
type: "object",
properties: {
motion: {
type: "string",
description: "Motion group name",
enum: ["Tap身体", "Tap头顶", "Tap脸", "Tap裙子", "Tap左胸", "Tap呆毛"]
}
},
required: ["motion"]
}
}
},
{
type: "function",
function: {
name: "list_site_pages",
description: "列出博客的所有可访问页面,包括分类页、工具页、游戏页等。当用户问'有什么'、'能做什么'、'有哪些页面/工具/游戏'时主动调用。",
parameters: { type: "object", properties: {}, required: [] }
}
},
{
type: "function",
function: {
name: "navigate",
description: "跳转到博客内任意页面。支持中文别名(首页/关于/标签/分类/归档/工具/游戏/2048/贪吃蛇/吃豆人/扫雷/五子棋/坦克大战/俄罗斯方块/文件转换/哈希计算/二维码/YOLO/WebGPU/VPN 等)。用户说'带我去'、'跳转'、'打开'时使用。",
parameters: {
type: "object",
properties: {
path: { type: "string", description: "要跳转的路径或中文名称(如 /about/、首页、2048、贪吃蛇" }
},
required: ["path"]
}
}
},
{
type: "function",
function: {
name: "read_current_page",
description: "Read the text content of the current page. Use this when user asks about 'this article' or 'current page'.",
parameters: {
type: "object",
properties: {},
required: []
}
}
}
];
const API_URL = "https://api.deepseek.com/chat/completions";
// First Call
const response = await fetch(API_URL, {
method: "POST",
headers: {
"Content-Type": "application/json",
"Authorization": "Bearer " + API_KEY
},
body: JSON.stringify({
model: "deepseek-v4-flash", // Use V3 for speed & tools
messages: messages,
tools: tools,
stream: false
})
});
const data = await response.json();
if (data.error) throw new Error(data.error.message);
const choice = data.choices[0];
const message = choice.message;
// Handle Tool Calls
if (message.tool_calls) {
messages.push(message); // Add assistant's thought/tool_call
for (const toolCall of message.tool_calls) {
const fnName = toolCall.function.name;
const args = JSON.parse(toolCall.function.arguments);
let toolResult = "";
if (fnName === 'search_blog') {
toolResult = await Tools.searchBlog(args.query);
} else if (fnName === 'list_site_pages') {
toolResult = Tools.listSitePages();
} else if (fnName === 'react_motion') {
toolResult = Tools.triggerMotion(args.motion);
} else if (fnName === 'navigate') {
toolResult = Tools.navigate(args.path);
} else if (fnName === 'read_current_page') {
toolResult = Tools.readCurrentPage();
}
messages.push({
role: "tool",
tool_call_id: toolCall.id,
content: toolResult
});
}
// Second Call (Streamed)
const secondResponse = await fetch(API_URL, {
method: "POST",
headers: {
"Content-Type": "application/json",
"Authorization": "Bearer " + API_KEY
},
body: JSON.stringify({
model: "deepseek-v4-flash",
messages: messages,
tools: tools,
stream: true
})
});
const reader = secondResponse.body.getReader();
const decoder = new TextDecoder("utf-8");
let finalMsg = "";
let buffer = "";
let streamBuffer = "";
let pendingReaction = true;
while (true) {
const { done, value } = await reader.read();
if (done) break;
buffer += decoder.decode(value, { stream: true });
const lines = buffer.split('\n');
buffer = lines.pop();
for (const line of lines) {
if (line.trim().startsWith('data: ')) {
const dataStr = line.trim().substring(6);
if (dataStr === '[DONE]') continue;
try {
const json = JSON.parse(dataStr);
const content = json.choices[0].delta.content;
if (content) {
if (pendingReaction) {
streamBuffer += content;
if (streamBuffer.trimStart().startsWith('{{')) {
const closeIdx = streamBuffer.indexOf('}}');
if (closeIdx !== -1) {
const reaction = streamBuffer.substring(streamBuffer.indexOf('{{') + 2, closeIdx);
const duration = 3000 + reaction.length * 30;
if (oml2dInstance) oml2dInstance.tips.notification(reaction, duration);
const rest = streamBuffer.substring(closeIdx + 2);
finalMsg += rest;
callbacks.onMessage(finalMsg);
pendingReaction = false;
streamBuffer = "";
}
} else if (streamBuffer.length > 10) {
finalMsg += streamBuffer;
callbacks.onMessage(finalMsg);
pendingReaction = false;
streamBuffer = "";
}
} else {
finalMsg += content;
callbacks.onMessage(finalMsg);
}
}
} catch (e) {
console.error("Stream parse error", e);
}
}
}
}
if (pendingReaction && streamBuffer) {
finalMsg += streamBuffer;
callbacks.onMessage(finalMsg);
}
// Save History & Compress
chatHistory.push({ role: "user", content: userMessage });
chatHistory.push({ role: "assistant", content: finalMsg });
localStorage.setItem('oml2d_history', JSON.stringify(chatHistory));
const replyArea = document.getElementById('oml2d-reply-area');
if (replyArea && finalMsg) {
const autoHideDuration = 3000 + finalMsg.length * 30;
autoHideTimer = setTimeout(() => replyArea.classList.remove('visible'), autoHideDuration);
}
Tools.compressHistory();
} else {
let content = message.content;
// Dual Channel Check for non-stream response
if (content.trim().startsWith('{{')) {
const closeIdx = content.indexOf('}}');
if (closeIdx !== -1) {
const reaction = content.substring(content.indexOf('{{') + 2, closeIdx);
const duration = 3000 + reaction.length * 30;
if (oml2dInstance) oml2dInstance.tips.notification(reaction, duration);
content = content.substring(closeIdx + 2);
}
}
callbacks.onMessage(content);
// Save History & Compress
chatHistory.push({ role: "user", content: userMessage });
chatHistory.push({ role: "assistant", content: content });
localStorage.setItem('oml2d_history', JSON.stringify(chatHistory));
const replyArea = document.getElementById('oml2d-reply-area');
if (replyArea && content) {
const autoHideDuration = 3000 + content.length * 30;
autoHideTimer = setTimeout(() => replyArea.classList.remove('visible'), autoHideDuration);
}
Tools.compressHistory();
}
} catch (error) {
console.error("LLM Error:", error);
callbacks.onMessage("宁宁有点晕... 😵 (网络错误)");
} finally {
callbacks.onLoading(false);
startIdleLoop();
}
}
};
// 5. UI & INIT
try {
const toggleBtn = document.getElementById('oml2d-toggle-btn');
const inputArea = document.getElementById('oml2d-input-area');
const chatInput = document.getElementById('oml2d-chat-input');
const sendBtn = document.getElementById('oml2d-send-btn-inner');
const replyArea = document.getElementById('oml2d-reply-area');
if (replyArea) {
replyArea.addEventListener('click', () => {
replyArea.classList.remove('visible');
});
}
if (toggleBtn) {
toggleBtn.addEventListener('click', (e) => {
e.stopPropagation();
const isHidden = inputArea.classList.contains('hidden');
if (isHidden) {
inputArea.classList.remove('hidden');
setTimeout(() => chatInput.focus(), 100);
toggleBtn.innerHTML = '×';
} else {
inputArea.classList.add('hidden');
replyArea.classList.remove('visible'); // Hide reply too
toggleBtn.innerHTML = '💬';
}
});
}
const sendMessage = () => {
const text = chatInput.value.trim();
if (!text) return;
chatInput.value = '';
if (autoHideTimer) clearTimeout(autoHideTimer);
// Show loading in reply area
if (replyArea) {
replyArea.innerText = "思考中... 🧠";
replyArea.classList.add('visible');
}
LLM.chat(text, {
onLoading: (isLoading) => {
// Handled locally above for instant feedback
},
onMessage: (msg) => {
if (replyArea && msg) {
replyArea.innerText = msg;
replyArea.classList.add('visible');
// Auto scroll to bottom
replyArea.scrollTop = replyArea.scrollHeight;
}
// Fallback to alert if something is wrong (shouldn't happen)
else if (msg) {
alert("宁宁: " + msg);
}
}
});
};
if (sendBtn) sendBtn.addEventListener('click', sendMessage);
if (chatInput) chatInput.addEventListener('keypress', (e) => {
if (e.key === 'Enter') sendMessage();
});
if (window.innerWidth >= 768) {
// Safe Load Logic
try {
const res = loadOml2d(CONFIG);
const setupModel = (inst) => {
oml2dInstance = inst;
// Monkey Patch Focus to allow motion override
if (inst.models && inst.models[0]) {
const model = inst.models[0];
if (typeof model.focus === 'function') {
const originalFocus = model.focus;
model.focus = function(x, y) {
if (this._lockFocus) return;
originalFocus.apply(this, arguments);
};
console.log("OML2D: Focus controller patched");
}
}
};
if (res && typeof res.then === 'function') {
res.then(inst => {
setupModel(inst);
console.log('OML2D: Async Loaded');
startIdleLoop();
}).catch(e => console.error('OML2D Async Error:', e));
} else {
setupModel(res);
console.log('OML2D: Sync Loaded');
startIdleLoop();
}
} catch(e) {
console.error('OML2D Load Error:', e);
}
}
} catch (e) {
console.error('UI Init Failed:', e);
}
</script>
<div id="game-sidebar">
<div id="game-toggle">🎮</div>
<div id="game-list">
<div class="game-header">博客游戏</div>
<a href="/tools/2048" class="game-item">🧩 经典 2048</a>
<a href="/tools/tetris" class="game-item">🧱 俄罗斯方块 (Tetris)</a>
<a href="/tools/pacman" class="game-item">🟡 回忆吃豆人 (Pac-Man)</a>
<a href="/tools/snake" class="game-item">🐍 贪吃蛇 (Snake)</a>
<a href="/tools/gomoku" class="game-item">⚪ 五子棋 (Gomoku)</a>
<a href="/tools/minesweeper" class="game-item">💣 扫雷 (Minesweeper)</a>
<a href="/tools/tank-battle" class="game-item">🚓 坦克大战 (Tank Battle)</a>
</div>
</div>
<style>
#game-sidebar {
position: fixed; /* Fixed position */
right: -150px; /* Width of the list */
top: calc(30vh + 40px); /* Positioned exactly below tool-sidebar */
z-index: 9999;
display: flex;
align-items: flex-start;
transition: right 0.3s cubic-bezier(0.25, 0.8, 0.25, 1);
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Helvetica Neue", Lato, Roboto, "PingFang SC", "Microsoft YaHei", sans-serif;
}
/* Hover area to keep it open */
#game-sidebar:hover {
right: 0;
}
#game-toggle {
width: 40px;
height: 40px;
background: #FF7D7D; /* Pink/Red color to distinguish from tool-sidebar */
color: white;
text-align: center;
line-height: 40px;
border-radius: 8px 0 0 8px;
cursor: pointer;
box-shadow: -2px 2px 8px rgba(0,0,0,0.15);
font-size: 20px;
position: absolute; /* Absolute relative to #game-sidebar */
left: -40px; /* Hangs off the left of the container */
top: 0;
}
#game-list {
width: 150px; /* Width for text */
background: rgba(255, 255, 255, 0.95);
backdrop-filter: blur(10px);
-webkit-backdrop-filter: blur(10px);
border-radius: 0 0 0 8px; /* Bottom left rounded */
box-shadow: -2px 2px 10px rgba(0,0,0,0.1);
display: flex;
flex-direction: column;
max-height: 50vh;
overflow-y: auto;
}
/* 自定义滚动条样式 */
#game-list::-webkit-scrollbar {
width: 4px;
}
#game-list::-webkit-scrollbar-track {
background: transparent;
}
#game-list::-webkit-scrollbar-thumb {
background: rgba(255, 125, 125, 0.3);
border-radius: 4px;
}
#game-list::-webkit-scrollbar-thumb:hover {
background: rgba(255, 125, 125, 0.6);
}
.game-header {
position: sticky;
top: 0;
z-index: 10;
padding: 10px;
background: #fff0f0;
color: #FF7D7D;
font-weight: bold;
font-size: 14px;
text-align: center;
border-bottom: 1px solid #eee;
}
.game-item {
display: block;
padding: 12px 15px;
color: #4c4948;
text-decoration: none !important;
font-size: 13px;
transition: all 0.2s;
border-bottom: 1px solid #f0f0f0;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
flex-shrink: 0; /* 防止内容被挤压 */
}
.game-item:last-child {
border-bottom: none;
}
.game-item:hover {
background: #FF7D7D;
color: white !important;
}
</style>
<script>
document.addEventListener('DOMContentLoaded', function() {
var toolSidebar = document.getElementById('tool-sidebar');
var gameSidebar = document.getElementById('game-sidebar');
var devSidebar = document.getElementById('dev-sidebar');
if(gameSidebar) {
gameSidebar.addEventListener('mouseenter', function() {
if(toolSidebar) toolSidebar.style.right = '-220px'; // 180px + 40px(按钮)
if(devSidebar) devSidebar.style.right = '-190px'; // 150px + 40px(按钮)
});
gameSidebar.addEventListener('mouseleave', function() {
if(toolSidebar) toolSidebar.style.right = '';
if(devSidebar) devSidebar.style.right = '';
});
}
});
</script>
<div id="tool-sidebar">
<div id="tool-toggle">🛠️</div>
<div id="tool-list">
<div class="tool-header">博客工具</div>
<a href="/tools/time" class="tool-item">📅 时间戳与地理时间</a>
<a href="/tools/base64-img" class="tool-item">🖼️ 图片↔Base64</a>
<a href="/tools/hash" class="tool-item">🔐 MD5/SHA256 计算</a>
<a href="/tools/geojson" class="tool-item">🌍 GeoJSON 查询</a>
<a href="/tools/remove-bg" class="tool-item">✂️ 快速抠图</a>
<a href="/tools/watermark" class="tool-item">💧 水印生成与检测</a>
<a href="/tools/gif" class="tool-item">🎬 GIF 生成</a>
<a href="/tools/mirage-tank" class="tool-item">👻 幻影坦克制作</a>
<a href="/tools/converter" class="tool-item">🔄 文件全能转换</a>
<a href="/tools/qrcode" class="tool-item">📱 二维码生成/解析</a>
<a href="/tools/unit-converter" class="tool-item">📏 工程单位换算</a>
<a href="/tools/color" class="tool-item">🎨 颜色转换与调色</a>
</div>
</div>
<style>
#tool-sidebar {
position: fixed;
right: -180px; /* Width of the list */
top: 30vh;
z-index: 9999;
display: flex;
align-items: flex-start;
transition: right 0.3s cubic-bezier(0.25, 0.8, 0.25, 1);
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Helvetica Neue", Lato, Roboto, "PingFang SC", "Microsoft YaHei", sans-serif;
}
/* Hover area to keep it open */
#tool-sidebar:hover {
right: 0;
}
#tool-toggle {
width: 40px;
height: 40px;
background: #49b1f5;
color: white;
text-align: center;
line-height: 40px;
border-radius: 8px 0 0 8px;
cursor: pointer;
box-shadow: -2px 2px 8px rgba(0,0,0,0.15);
font-size: 20px;
position: absolute;
left: -40px; /* Hangs off the left of the sidebar container */
top: 0;
}
#tool-list {
width: 180px; /* Width for text */
background: rgba(255, 255, 255, 0.95);
backdrop-filter: blur(10px);
-webkit-backdrop-filter: blur(10px);
border-radius: 0 0 0 8px; /* Bottom left rounded */
box-shadow: -2px 2px 10px rgba(0,0,0,0.1);
display: flex;
flex-direction: column;
max-height: 50vh; /* 限制最大高度以便能滚动 */
overflow-y: auto; /* 允许纵向滚动 */
}
/* 自定义滚动条样式,使其不那么突兀 */
#tool-list::-webkit-scrollbar {
width: 4px;
}
#tool-list::-webkit-scrollbar-track {
background: transparent;
}
#tool-list::-webkit-scrollbar-thumb {
background: rgba(73, 177, 245, 0.3);
border-radius: 4px;
}
#tool-list::-webkit-scrollbar-thumb:hover {
background: rgba(73, 177, 245, 0.6);
}
.tool-header {
position: sticky;
top: 0;
z-index: 10;
padding: 10px;
background: #f7f9fe;
color: #49b1f5;
font-weight: bold;
font-size: 14px;
text-align: center;
border-bottom: 1px solid #eee;
}
.tool-item {
display: block;
padding: 12px 15px;
color: #4c4948;
text-decoration: none !important;
font-size: 13px;
transition: all 0.2s;
border-bottom: 1px solid #f0f0f0;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
flex-shrink: 0; /* 防止由于 max-height 导致内容被挤压 */
}
.tool-item:last-child {
border-bottom: none;
}
.tool-item:hover {
background: #49b1f5;
color: white !important;
}
</style>
<script>
document.addEventListener('DOMContentLoaded', function() {
var toolSidebar = document.getElementById('tool-sidebar');
var gameSidebar = document.getElementById('game-sidebar');
var devSidebar = document.getElementById('dev-sidebar');
if(toolSidebar) {
toolSidebar.addEventListener('mouseenter', function() {
if(gameSidebar) gameSidebar.style.right = '-190px'; // 150px + 40px(按钮宽度)
if(devSidebar) devSidebar.style.right = '-190px'; // 150px + 40px(按钮宽度)
});
toolSidebar.addEventListener('mouseleave', function() {
if(gameSidebar) gameSidebar.style.right = ''; // 恢复默认通过 CSS :hover 控制的逻辑
if(devSidebar) devSidebar.style.right = ''; // 恢复默认通过 CSS :hover 控制的逻辑
});
}
});
</script>
<!-- hexo injector body_end end --></body></html>