<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>分享 node of Ruby China Forum</title>
    <link>https://ruby-china.org/</link>
    <description>Recent Topic in 分享 of Ruby China Forum.</description>
    <item>
      <title>发现一个提升效率的工具：软著申请材料 5 分钟自动生成</title>
      <description>&lt;p&gt;最近接了个外包项目，甲方要求提供软件著作权登记证书。以前办过一次，光是准备那 60 页的申报材料就折腾了整整一个周末。&lt;/p&gt;

&lt;p&gt;这次试了个新工具，直接用项目名和源代码生成全套申报材料，前后 5 分钟搞定，格式完全符合版权保护中心的要求。&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;工具叫 Code-Right&lt;/strong&gt;，是软著申报材料的自动生成工具：&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;输入项目名称和编程语言，自动生成 60 页完整申报材料&lt;/li&gt;
&lt;li&gt;自动提取源代码并格式化&lt;/li&gt;
&lt;li&gt;自动生成用户操作手册和设计说明书&lt;/li&gt;
&lt;li&gt;支持 Ruby、Rails、Python、JavaScript 等多种编程语言&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;网页版：&lt;a href="https://softcraft.cloud/code-right/" rel="nofollow" target="_blank"&gt;https://softcraft.cloud/code-right/&lt;/a&gt;
也支持通过 Hermes Agent 加载 code-right skill 在终端生成材料。&lt;/p&gt;

&lt;p&gt;之前自己做材料格式排版就耗了大量时间，自动化后省事不少。如果你也在准备软著申请，可以试试看。&lt;/p&gt;</description>
      <author>2673282975</author>
      <pubDate>Fri, 29 May 2026 10:07:12 +0800</pubDate>
      <link>https://ruby-china.org/topics/44587</link>
      <guid>https://ruby-china.org/topics/44587</guid>
    </item>
    <item>
      <title>AI 的经济账根本算不通</title>
      <description>&lt;p&gt;发现一篇有趣的文章  &lt;a href="https://baoyu.io/blog/2026-04-28/ais-economics-dont-make-sense" rel="nofollow" target="_blank" title=""&gt;AI 的经济账根本算不通&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;作者从当下的 AI 付费模式引出，通过计算各项实际财务成本，梳理从&lt;em&gt;按月付费&lt;/em&gt; 到 &lt;em&gt;按量付费&lt;/em&gt; 的底层逻辑。 &lt;/p&gt;

&lt;p&gt;其中文章中提到：&lt;/p&gt;

&lt;p&gt;这些服务有意隐藏 token 数量，也隐藏某项活动到底花了多少钱。结果就是，用户并不真正知道速率限制意味着什么。于是每一次突然调整速率限制，都会让客户手忙脚乱地试图弄清楚自己到底还能用这项服务完成多少实际工作。&lt;/p&gt;

&lt;p&gt;这是一种虐待式、操纵式、欺骗式的做生意方式。它存在的唯一原因，就是 Anthropic、OpenAI 和其他 AI 公司要扩大用户基数。因为大多数 AI 用户感受到的真实或想象中的收益，都建立在这样一个前提上：他们每支付 1 美元订阅费，就能烧掉 8 到 13.50 美元不等的 token。&lt;/p&gt;

&lt;p&gt;这种有意的欺骗只有一个目标：确保大多数人永远不会接触到生成式 AI 的真实成本。当《大西洋月刊》激情洋溢地把 Claude Code 描述成 Anthropic 的“ChatGPT 时刻”时，它讨论的是一个每月 20 美元的订阅，而不是 Anthropic 为提供这项服务在底层实际烧掉的 token 成本。也正因为如此，作者才会原谅模型犯下的“轻微错误”，或者原谅它在“更复杂的编程任务上卡住”。
如果那位作者支付的是自己真实烧掉的 token 成本，而且每次模型“卡住”都会带来 15 美元的 token 账单，我不认为她会对这些失败如此宽容。&lt;/p&gt;

&lt;hr&gt;

&lt;p&gt;感觉就像是之前网络爆火的 OpenClaw，当人们风靡使用时，发现耗费的成本远超过自己想象时，热度也就逐渐降低。
就好像打车去往某个目的地，我不能接受因为司机的愚蠢错误绕路，导致我的车费大幅上升。&lt;/p&gt;

&lt;hr&gt;

&lt;p&gt;LLM 就像赌场。你一直在用庄家的钱赌博，同时鼓励别人拿自己的钱下注，赌某个模型是否能产出一个工作单位。&lt;/p&gt;

&lt;p&gt;这是有意为之。它们从来不想让你思考成本，因为一旦你真的开始思考成本，整个事情就会显得有点疯狂。我真心相信，基于 LLM 的订阅服务将会彻底消失，至少对于任何生成代码的产品，只要做到一定规模，就会消失。而在这个过程中，Amodei 和 Altman 会结束他们的骗局，或者至少相信自己已经结束了。&lt;/p&gt;

&lt;hr&gt;

&lt;p&gt;推荐大家读原文，我这里的截取片段肯容易让人产生误解。&lt;/p&gt;</description>
      <author>qinsicheng</author>
      <pubDate>Sun, 17 May 2026 10:52:56 +0800</pubDate>
      <link>https://ruby-china.org/topics/44575</link>
      <guid>https://ruby-china.org/topics/44575</guid>
    </item>
    <item>
      <title>OpenClacky 1.0 正式发布 —— Ruby 圈第一个通用 Agent 来了</title>
      <description>&lt;p&gt;前段时间社区里一直有人在问：Python 那边 agent 框架一个接一个，Ruby 圈怎么就没一个拿得出手的通用 Agent？&lt;/p&gt;

&lt;p&gt;我们憋了两年，今天它来了。&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;OpenClacky 1.0.0 正式发布&lt;/strong&gt;，MIT 开源，纯 Ruby 写的。&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;GitHub：&lt;a href="https://github.com/clacky-ai/openclacky" rel="nofollow" target="_blank"&gt;https://github.com/clacky-ai/openclacky&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;官网（桌面安装包）：&lt;a href="https://www.openclacky.com/#install" rel="nofollow" target="_blank"&gt;https://www.openclacky.com/#install&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;img src="https://l.ruby-china.com/photo/lyfi2003/310ea7dc-890e-4b6f-8c52-250c31c926ea.png!large" title="" alt=""&gt;&lt;/p&gt;

&lt;p&gt;本文分两部分：先说是什么、怎么用；然后讲讲我们是怎么把 Token 成本打下来的 —— 后半段才是干货，欢迎直接跳到第三节。&lt;/p&gt;
&lt;h2 id="一、这是个什么东西"&gt;一、这是个什么东西&lt;/h2&gt;
&lt;p&gt;一句话：&lt;strong&gt;最省 Token 的开源通用 AI Agent&lt;/strong&gt;。&lt;/p&gt;

&lt;p&gt;能力上对齐 Claude Code，成本打到它的 &lt;strong&gt;0.8~1.2×&lt;/strong&gt;；相比其它开源 agent（如 OpenClaw、Hermes），大约便宜 &lt;strong&gt;50% ~ 3 倍&lt;/strong&gt;。&lt;/p&gt;

&lt;p&gt;两种用法，30 秒就能跑起来：&lt;/p&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# 安装&lt;/span&gt;
gem &lt;span class="nb"&gt;install &lt;/span&gt;openclacky

&lt;span class="c"&gt;# 命令行&lt;/span&gt;
openclacky

&lt;span class="c"&gt;# 或者跑 Web UI（多会话并行）&lt;/span&gt;
openclacky server    &lt;span class="c"&gt;# 默认 http://localhost:7070&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;BYOK，任意 OpenAI 兼容模型都支持：Claude / GPT / DeepSeek / Kimi / MiniMax / OpenRouter，或者任何自定义 endpoint。进去 &lt;code&gt;/config&lt;/code&gt; 填 API Key、Model、Base URL 就完事了。&lt;/p&gt;

&lt;p&gt;&lt;img src="https://l.ruby-china.com/photo/lyfi2003/0bf39a30-2b71-4fc7-98cc-1d712ebcfccb.png!large" title="" alt=""&gt;&lt;/p&gt;
&lt;h2 id="二、为什么我们又要再写一个"&gt;二、为什么我们又要再写一个&lt;/h2&gt;
&lt;p&gt;用过 Claude Code 的朋友应该都很惊艳，但三个问题一直没解：&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;闭源 + 订阅制，拿不到内部细节，也没办法定制&lt;/li&gt;
&lt;li&gt;只能用 Anthropic 自家模型，不能 BYOK&lt;/li&gt;
&lt;li&gt;对中国开发者来说，付费通路不顺畅&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;我们也试过 OpenClaw、Hermes 这些开源方案，能力是有的，但实测下来 Token 成本是 Claude Code 的 &lt;strong&gt;1.5× ~ 3×&lt;/strong&gt;。&lt;/p&gt;

&lt;p&gt;这是什么概念？一个中等规模的项目，一天下来 token 费可能就是几十到几百块，差 2~3 倍就是实打实的 RMB 差 2~3 倍。对个人开发者和小团队太贵了。&lt;/p&gt;

&lt;p&gt;所以我们自己做了一个。目标很明确：&lt;strong&gt;能力不输，成本打到最低。&lt;/strong&gt;&lt;/p&gt;
&lt;h2 id="三、怎么把 Token 成本打下来的（干货）"&gt;三、怎么把 Token 成本打下来的（干货）&lt;/h2&gt;
&lt;p&gt;先看对比表：&lt;/p&gt;
&lt;table class="table table-bordered table-striped"&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;th&gt;Agent&lt;/th&gt;
&lt;th&gt;相对成本&lt;/th&gt;
&lt;th&gt;工具数&lt;/th&gt;
&lt;th&gt;开源&lt;/th&gt;
&lt;th&gt;BYOK&lt;/th&gt;
&lt;th&gt;IM 集成&lt;/th&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Claude Code&lt;/td&gt;
&lt;td&gt;1.0×（基准）&lt;/td&gt;
&lt;td&gt;40+&lt;/td&gt;
&lt;td&gt;❌ 闭源&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;OpenClaw&lt;/td&gt;
&lt;td&gt;~1.5×&lt;/td&gt;
&lt;td&gt;23&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Hermes&lt;/td&gt;
&lt;td&gt;~3×&lt;/td&gt;
&lt;td&gt;52&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;OpenClacky&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;~0.8&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;16&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;✅ MIT&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;✅&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;✅&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;注：数据是内部常见 agent 任务的平均值，以 Claude Code 为基准。完整 benchmark 后续会放到 GitHub。&lt;/p&gt;

&lt;p&gt;不是靠砍功能，是靠&lt;strong&gt;每一层都做对选择，复利叠加下来的&lt;/strong&gt;。下面讲四个关键决策。&lt;/p&gt;
&lt;h3 id="3.1 缓存命中率接近 100%"&gt;3.1 缓存命中率接近 100%&lt;/h3&gt;
&lt;p&gt;这是最大的一块。Agent 类应用的对话上下文非常长，API 侧的 prompt caching 是省钱的核心。做对了，成本直接砍一半以上；做错了，基本等于没开。&lt;/p&gt;

&lt;p&gt;我们做了三件事：&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Session 不重启。&lt;/strong&gt; 很多 agent 每次启动或切换任务都会重建上下文，前缀一变 cache 全丢。OpenClacky 的 session 生命周期贯穿整个进程，工具调用、子 agent 调度、Skill 执行都挂在同一条上下文上。&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;双 cache marker。&lt;/strong&gt; OpenAI / Anthropic 家的 caching 都是按前缀对齐。我们在 system prompt 尾部和对话中段各打一个 marker，确保即使中段有动态插入，前半段仍然完整命中。&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Insert-then-Compress。&lt;/strong&gt; 这是关键。传统做法是上下文满了就"压缩 + 重写 system prompt"，一旦 system prompt 变了，前缀 cache 全失效，下一条消息变成冷启动。&lt;/p&gt;

&lt;p&gt;我们反过来：&lt;strong&gt;system prompt 永远不变&lt;/strong&gt;，压缩发生在对话区，用"插入一条总结 + 裁剪被总结的内容"的方式。system prompt 那段前缀的 cache 永远是热的。&lt;/p&gt;

&lt;p&gt;实测下来 &lt;strong&gt;cache 命中率接近 100%&lt;/strong&gt;。&lt;/p&gt;


&lt;h3 id="3.2 最小工具集：只有 16 个"&gt;3.2 最小工具集：只有 16 个&lt;/h3&gt;
&lt;p&gt;这点反直觉，我们反复测过 —— &lt;strong&gt;工具不是越多越好，是越精越好&lt;/strong&gt;。&lt;/p&gt;
&lt;table class="table table-bordered table-striped"&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;th style="text-align:center;"&gt;OpenClacky&lt;/th&gt;
&lt;th style="text-align:center;"&gt;Claude Code&lt;/th&gt;
&lt;th style="text-align:center;"&gt;OpenClaw&lt;/th&gt;
&lt;th style="text-align:center;"&gt;Hermes&lt;/th&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align:center;"&gt;&lt;strong&gt;16&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align:center;"&gt;40+&lt;/td&gt;
&lt;td style="text-align:center;"&gt;23&lt;/td&gt;
&lt;td style="text-align:center;"&gt;52&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;为什么？因为工具的 schema 是要塞进每一次请求的 system prompt 的。52 个工具意味着 schema 膨胀 3~4 倍，每次对话都要多烧这么多 token。更糟的是 schema 越大，模型选工具的准确率反而下降（这点我们跑过对照实验）。&lt;/p&gt;

&lt;p&gt;我们的做法是把所有非核心能力下沉到 &lt;strong&gt;Skill 体系&lt;/strong&gt;，主工具只保留一个 &lt;code&gt;invoke_skill&lt;/code&gt; 元工具。需要 PPT？有 skill。需要 SQL 调优？有 skill。需要内部规范？有 skill。&lt;/p&gt;

&lt;p&gt;工具数量不是指标，&lt;strong&gt;任务完成率才是&lt;/strong&gt;。&lt;/p&gt;
&lt;h3 id="3.3 空闲时间自动压缩"&gt;3.3 空闲时间自动压缩&lt;/h3&gt;
&lt;p&gt;这个功能用起来很爽。你去开会、喝咖啡、吃饭，agent 并不是闲着 —— 它在后台做两件事：&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;把长上下文做渐进式压缩&lt;/li&gt;
&lt;li&gt;预热压缩后的 cache&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;等你回来发第一条消息，直接命中热 cache。&lt;strong&gt;冷启动首 token 成本降低 50%+。&lt;/strong&gt;&lt;/p&gt;
&lt;h3 id="3.4 BYOK + 子任务路由"&gt;3.4 BYOK + 子任务路由&lt;/h3&gt;
&lt;p&gt;BYOK 大家都有，但我们多走了一步：主任务用 Claude，子 agent 的子任务可以路由到 DeepSeek / Kimi 这种便宜模型。能力不损失太多，成本再砍一大块。&lt;/p&gt;

&lt;p&gt;这四条叠起来，才是那个 0.8 的数字。&lt;/p&gt;
&lt;h2 id="四、Skill —— Agent 的灵魂"&gt;四、Skill —— Agent 的灵魂&lt;/h2&gt;
&lt;p&gt;Skill 是我们认为 Agent 下一个阶段的关键。简单讲就是可插拔的"领域技能包"。&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;/&lt;/code&gt; 直接召唤&lt;/strong&gt;：即时浏览、模糊搜索、直接调用，上百个 Skill 随手可用&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;自然语言创建&lt;/strong&gt;：你描述想要什么，agent 自己起草 &lt;code&gt;SKILL.md&lt;/code&gt;、拆步骤、跑验证，不用写代码&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;自我进化&lt;/strong&gt;：每次执行完，agent 根据执行过程和结果回写更新。下一次调用更稳、更准&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;开放兼容&lt;/strong&gt;：支持 Claude Skills / Markdown Pack / 自定义格式&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;可变现&lt;/strong&gt;：打磨好的 Skill 可以打包加密分发、License 管理、自定价格&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;现在已经有用户在上面做垂直专家 Skill 了 —— 法律、医疗、理财规划，都有人跑起来。创作者计划的细节可以看官网。&lt;/p&gt;

&lt;p&gt;&lt;img src="https://l.ruby-china.com/photo/lyfi2003/fb902ce5-9588-4df5-aadb-c5290c6d6778.png!large" title="" alt=""&gt;&lt;/p&gt;
&lt;h2 id="五、用例示范"&gt;五、用例示范&lt;/h2&gt;
&lt;p&gt;今天 agent 能"问个项目问题"已经是及格线了，真正拉开差距的是能不能&lt;strong&gt;端到端交付一件事&lt;/strong&gt;。下面几个是我们自己和早期用户每天在跑的真实场景。&lt;/p&gt;
&lt;h3 id="用例一：从零交付一个 SaaS 原型（多 session 并行）"&gt;用例一：从零交付一个 SaaS 原型（多 session 并行）&lt;/h3&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;openclacky server
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;开三个 session 并行：&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Session A:&lt;code&gt;/new&lt;/code&gt; 生成 Rails 7 + Tailwind 项目，建好 User / Subscription 模型，接 Stripe 订阅&lt;/li&gt;
&lt;li&gt;Session B：写落地页文案、SEO meta、FAQ，同时用 Skill 调 PPT 生成器出一份投资人 deck&lt;/li&gt;
&lt;li&gt;Session C：跑用户访谈资料分析，输出 PMF 判断报告&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;三个 session 共享同一份 workspace 上下文，改完 A 的定价策略，B 的落地页文案自动跟上。以前这是三个人半天的活。&lt;/p&gt;
&lt;h3 id="用例二：给一个 20 万行的老项目加功能，并让它自己跑完回归"&gt;用例二：给一个 20 万行的老项目加功能，并让它自己跑完回归&lt;/h3&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;gt; 我要在订单模块加"部分退款"能力，退款后要同步更新财务对账表、
  触发用户邮件、并在 admin 后台补一个退款审核流程。
  跑完 rake test 确保所有测试通过再交付。
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;它会自己：读相关模块 → 列修改计划 → 写代码 → 跑测试 → 测试挂了自己修 → 再跑 → 通过后给你一份变更摘要。&lt;/p&gt;

&lt;p&gt;整个过程基本不用盯，&lt;strong&gt;空闲时它还在后台做 context 压缩&lt;/strong&gt;，你去吃个饭回来直接看结果。&lt;/p&gt;
&lt;h3 id="用例三：自己造一个垂直 Skill，让它永久变强"&gt;用例三：自己造一个垂直 Skill，让它永久变强&lt;/h3&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;gt; 我经常要做"Rails 项目性能体检"，固定看 7 个指标：
  N+1、慢查询、索引缺失、Puma 配置、内存占用、cache 命中、日志异常。
  帮我做成一个 Skill。
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;它会起草 &lt;code&gt;SKILL.md&lt;/code&gt;、拆步骤、跑一次验证、让你确认。之后 &lt;code&gt;/&lt;/code&gt; 搜 "体检" 直接召唤，跑一次自动进化一次，下次更准。好的 Skill 可以打包加密分发、定价出售 —— 我们已经有用户靠卖垂直 Skill 跑通商业闭环了。&lt;/p&gt;
&lt;h3 id="用例四：跨代码库迁移 / 大重构"&gt;用例四：跨代码库迁移 / 大重构&lt;/h3&gt;
&lt;p&gt;比如把一个 Rails 5.2 + Sprockets + jQuery 的老项目，迁到 Rails 7.2 + Importmap + Stimulus + Turbo。这种活以前外包报价 5 万起，而且没人愿意接。&lt;/p&gt;

&lt;p&gt;现在开一个 session 挂上去，分阶段跑：依赖升级 → Asset Pipeline 切换 → 前端重写 → 测试补齐。每一阶段都让它先出计划再动手，人只做把关。&lt;/p&gt;
&lt;h3 id="用例五：Web UI 当成"&gt;用例五：Web UI 当成"自己的研发中台"&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;openclacky server&lt;/code&gt; 起来的 Web UI 不止是聊天窗口，是一个&lt;strong&gt;常驻的多人 / 多项目协作平台&lt;/strong&gt;：&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;团队内几个人共享 session，接力干活&lt;/li&gt;
&lt;li&gt;跑 IM 集成（飞书 / 企微 / 微信），在群里 @ 它派任务，结果回群&lt;/li&gt;
&lt;li&gt;本机跑、或者扔一台服务器上 &lt;code&gt;--host 0.0.0.0&lt;/code&gt; 团队一起用&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;这一条是我们自己团队现在的日常 —— OpenClacky 自己就是用 OpenClacky 开发的。&lt;/p&gt;
&lt;h2 id="六、关于技术选型的一些闲话"&gt;六、关于技术选型的一些闲话&lt;/h2&gt;
&lt;p&gt;很多人问我们为什么坚持用 Ruby 做这个。&lt;/p&gt;

&lt;p&gt;其实 agent 这种场景，Rails 那套"convention over configuration"的哲学一样好使。迭代速度、元编程能力、gem 生态都是加分项。这两年我们三代架构、六个核心 harness 工程决策，反复推翻重来，Ruby 的表达力帮我们省了大量时间。&lt;/p&gt;

&lt;p&gt;我希望 Ruby 社区也有自己拿得出手的 AI 基础设施。不只是"能用"，而是"够硬、能打"。&lt;/p&gt;
&lt;h2 id="七、最后"&gt;七、最后&lt;/h2&gt;
&lt;p&gt;OpenClacky 1.0.0 正式发布了，来源 100% 开放（MIT），所有决策都可追溯。&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;GitHub：&lt;a href="https://github.com/clacky-ai/openclacky" rel="nofollow" target="_blank"&gt;https://github.com/clacky-ai/openclacky&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;官网 / 桌面安装包（macOS、Windows）：&lt;a href="https://www.openclacky.com/" rel="nofollow" target="_blank"&gt;https://www.openclacky.com/&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;欢迎 star、试用、提 issue、贡献 Skill，也欢迎直接在本帖回复交流。后续我会再写几篇详细技术博客：缓存命中率的工程细节、Skill 自进化的实现、子 agent 路由的 scheduling —— 每一篇都是这种干货。&lt;/p&gt;

&lt;p&gt;&lt;img src="https://l.ruby-china.com/photo/lyfi2003/cb2c1282-58b7-4356-a4d4-b605e56df0cb.png!large" title="" alt=""&gt;&lt;/p&gt;

&lt;p&gt;项目背后由奇绩创坛、真格基金、红杉中国、高瓴资本支持，特此致谢。&lt;/p&gt;

&lt;p&gt;希望本文对大家有所帮助。有问题欢迎交流。&lt;/p&gt;</description>
      <author>lyfi2003</author>
      <pubDate>Sat, 02 May 2026 11:50:26 +0800</pubDate>
      <link>https://ruby-china.org/topics/44565</link>
      <guid>https://ruby-china.org/topics/44565</guid>
    </item>
    <item>
      <title>show history for selection lines in Zed</title>
      <description>&lt;p&gt;相信使用过 JetBrains 产品的用户，对内置的 Git 操作都会觉得很方便。其中很重要的一个功能：选中某几行代码，鼠标右键，使用 &lt;code&gt;show history for selection&lt;/code&gt;。就能展示出这几行代码的 git 提交历史记录，这个功能真的太香了。&lt;/p&gt;

&lt;p&gt;这个功能在很多编辑器上都不支持，我目前在使用 Zed 编辑器，最开始对 Git 操作支持很少，我都是使用 &lt;code&gt;lazygit&lt;/code&gt; 来操作，但上面提到的功能无法实现。所以我就尝试编写脚本去实现这个功能。本质上就是使用 git 原生命令行操作：&lt;code&gt;git log -L &amp;lt;range:file&amp;gt;&lt;/code&gt;  。将内容输出到一个临时文件中，然后通过 zed 编辑器打开它，同时使用 &lt;code&gt;diff&lt;/code&gt; 语法展示高亮信息。&lt;/p&gt;
&lt;h3 id="效果展示："&gt;效果展示：&lt;/h3&gt;
&lt;p&gt;&lt;img src="https://l.ruby-china.com/photo/qinsicheng/c2c295e9-bedd-4833-b06f-9b6f2d0b7579.gif" title="" alt=""&gt;&lt;/p&gt;
&lt;h3 id="Fish代码"&gt;Fish 代码&lt;/h3&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function git_line_history --description "Show git history for specific lines in a file"
    # Validate argument count
    if test (count $argv) -ne 3
        echo "Usage: git_line_history &amp;lt;file_path&amp;gt; &amp;lt;start_line&amp;gt; &amp;lt;end_line&amp;gt;"
        return 1
    end

    set -l file_path $argv[1]
    set -l start_line $argv[2]
    set -l end_line $argv[3]

    # Verify the file exists
    if not test -f "$file_path"
        echo "Error: file '$file_path' does not exist"
        return 1
    end

    # Verify we are inside a git repository
    if not git rev-parse --is-inside-work-tree &amp;gt;/dev/null 2&amp;gt;&amp;amp;1
        echo "Error: current directory is not inside a git repository"
        return 1
    end

    # Create temporary files
    set -l temp_file (mktemp -t git_history.XXXXXXXXXX.diff)
    set -l raw_log_file (mktemp -t git_history.XXXXXXXXXX.raw)

    # Build the line range argument for git log -L
    set -l line_range "$start_line,$end_line:$file_path"

    # Fetch the line history
    git log --date=format:'%Y-%m-%d %H:%M:%S' -L $line_range &amp;gt;$raw_log_file 2&amp;gt;&amp;amp;1

    if test $status -ne 0
        echo "Error: failed to execute git log"
        if test -s $raw_log_file
            echo "Details:"
            cat $raw_log_file
        end
        rm -f $raw_log_file $temp_file
        return 1
    end

    # Process output: filter diff metadata and add separators between commits
    awk '
    BEGIN { in_commit = 0; has_content = 0; }
    /^commit / {
        if (in_commit &amp;amp;&amp;amp; has_content) print "\n--------------------------------------------------\n"
        in_commit = 1
        has_content = 1
        print
        next
    }
    /^diff --git|^index |^--- a\/|^\+\+\+ b\/|^@@ .* @@/ { next }
    {
        if (in_commit) print
        has_content = 1
    }
    ' $raw_log_file &amp;gt;$temp_file

    rm -f $raw_log_file

    # Check if the result is empty
    if not test -s $temp_file
        echo "Note: no matching commit history found"
        rm -f $temp_file
        return 0
    end

    # Choose an editor: prefer zeditor (Arch Linux), fall back to subl, then $EDITOR
    set -l editor_cmd
    if command -q zeditor
        set editor_cmd zeditor
    else if command -q zed
        set editor_cmd zed
    else if command -q subl
        set editor_cmd subl
    else if set -q EDITOR
        set editor_cmd $EDITOR
    else
        echo "Error: no suitable editor found"
        echo "Temporary file location: $temp_file"
        return 1
    end

    $editor_cmd "$temp_file"

    # Clean up old temporary files from previous runs
    function cleanup_git_history --on-event fish_exit
        # Clean up old temporary files from previous runs
        set -l tmpdir (dirname (mktemp -u))
        rm -f $tmpdir/git_history.*.diff 2&amp;gt;/dev/null
        rm -f $tmpdir/git_history.*.raw 2&amp;gt;/dev/null
    end

    return 0
end
&lt;/code&gt;&lt;/pre&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function zed_git_line_history --description "Zed editor wrapper for git_line_history"
    # Extract line range from Zed environment variables
    set -l start_line $ZED_ROW
    set -l selection "$ZED_SELECTED_TEXT"
    set -l line_count (printf '%s\n' "$selection" | wc -l | string trim)
    set -l end_line (math $start_line + $line_count - 1)
    set -l file_path "$ZED_FILE"

    git_line_history "$file_path" $start_line $end_line
end
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id="Zed 配置"&gt;Zed 配置&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;task&lt;/strong&gt;&lt;/p&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
   &lt;/span&gt;&lt;span class="nl"&gt;"label"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"git_line_history"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
   &lt;/span&gt;&lt;span class="nl"&gt;"command"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"zed_git_line_history"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
   &lt;/span&gt;&lt;span class="nl"&gt;"env"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
     &lt;/span&gt;&lt;span class="nl"&gt;"ZED_ROW"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"$ZED_ROW"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
     &lt;/span&gt;&lt;span class="nl"&gt;"ZED_SELECTED_TEXT"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"$ZED_SELECTED_TEXT"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
     &lt;/span&gt;&lt;span class="nl"&gt;"ZED_FILE"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"$ZED_FILE"&lt;/span&gt;&lt;span class="w"&gt;
   &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
   &lt;/span&gt;&lt;span class="nl"&gt;"hide"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"always"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
   &lt;/span&gt;&lt;span class="nl"&gt;"allow_concurrent_runs"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
   &lt;/span&gt;&lt;span class="nl"&gt;"use_new_terminal"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="err"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;keymap&lt;/strong&gt;&lt;/p&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"context"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"vim_mode == normal || vim_mode == visual"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"bindings"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"g h"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"task::Spawn"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"task_name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"git_line_history"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}],&lt;/span&gt;&lt;span class="w"&gt;
   &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;</description>
      <author>qinsicheng</author>
      <pubDate>Thu, 23 Apr 2026 22:20:47 +0800</pubDate>
      <link>https://ruby-china.org/topics/44558</link>
      <guid>https://ruby-china.org/topics/44558</guid>
    </item>
    <item>
      <title>procodile, 一款类似 foreman 的工具，但可运行在前台或后台，也支持定时任务</title>
      <description>&lt;h2 id="宣布发布 procodile 2.0.0-rc1"&gt;宣布发布 &lt;code&gt;procodile&lt;/code&gt; 2.0.0-rc1&lt;/h2&gt;
&lt;p&gt;我很高兴地宣布 &lt;code&gt;procodile&lt;/code&gt; 2.0.0-rc1 正式发布。自上一个版本以来，这是一次重大更新，累计包含了 130 多个 commit。&lt;/p&gt;

&lt;p&gt;这次更新之所以非常重要，主要有以下几个原因：&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;这是第一个完整实现原始 Ruby 版本功能的 &lt;a href="https://github.com/adamcooke/procodile" rel="nofollow" target="_blank" title=""&gt;procodile&lt;/a&gt; 发布版本。&lt;/li&gt;
&lt;li&gt;它还修复了原始 Ruby 版本中存在的许多 bug 和边界情况问题。(感谢 Crystal 程序语言，让暴露和修复这些问题，相对于 Ruby 简单得多）&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;与此同时，2.0 版本在原始 Ruby 版本的基础上也有了显著增强，并引入了一些此前 Ruby 版本并不具备的新功能：&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;支持通过 &lt;strong&gt;&lt;code&gt;.env&lt;/code&gt; 文件&lt;/strong&gt;加载环境变量，这项功能基于 &lt;a href="/jwoertink" class="user-mention" title="@jwoertink"&gt;&lt;i&gt;@&lt;/i&gt;jwoertink&lt;/a&gt; 开发的 &lt;a href="https://github.com/luckyframework/lucky_env" rel="nofollow" target="_blank" title=""&gt;lucky_env&lt;/a&gt;。&lt;/li&gt;
&lt;li&gt;支持&lt;strong&gt;定时任务&lt;/strong&gt;。这是一次重要更新，使你可以在同一个地方同时管理长期运行的进程和定时任务。得益于 &lt;a href="/kostya" class="user-mention" title="@kostya"&gt;&lt;i&gt;@&lt;/i&gt;kostya&lt;/a&gt; 开发的 &lt;a href="https://github.com/kostya/cron_parser" rel="nofollow" target="_blank" title=""&gt;cron_parser&lt;/a&gt;，它不仅支持标准的五段式 crontab 表达式，还支持精确到秒级的 cron 调度。&lt;/li&gt;
&lt;li&gt;引入了 &lt;strong&gt;Runtime Issues&lt;/strong&gt;。当命令执行结束后如果检测到问题，你会立即在命令行中收到反馈。&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;请参阅 &lt;a href="https://github.com/crystal-china/procodile/wiki" rel="nofollow" target="_blank" title=""&gt;Wiki&lt;/a&gt;，其中提供了结构清晰且内容详尽的文档说明。&lt;/p&gt;</description>
      <author>zw963</author>
      <pubDate>Wed, 15 Apr 2026 15:33:12 +0800</pubDate>
      <link>https://ruby-china.org/topics/44552</link>
      <guid>https://ruby-china.org/topics/44552</guid>
    </item>
    <item>
      <title>我们开发了一个 resend 的替代品</title>
      <description>&lt;p&gt;大家好，我们是一个 3 人的小团队，经历数月，终于完成了&lt;a href="https://sendflare.com" rel="nofollow" target="_blank" title=""&gt;Sendflare&lt;/a&gt;的开发&lt;/p&gt;

&lt;p&gt;Sendflare 是一个对标 resend 的替代品，定价比 resend 更加合理，同时支持营销邮件和交易电子邮件&lt;/p&gt;

&lt;p&gt;后续我们还会支持邮件自动化功能&lt;/p&gt;

&lt;p&gt;目前刚刚上线，可能多多少少有一点小问题，希望大家在给我们一点时间&lt;/p&gt;

&lt;p&gt;免费用户支持添加 2 个域和每月 3000 封邮件&lt;/p&gt;

&lt;p&gt;访问地址：&lt;a href="https://sendflare.com" rel="nofollow" target="_blank"&gt;https://sendflare.com&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src="https://cdn-bun.stardots.io/v2ex/sendflare.png" title="" alt="sendflare.png"&gt;&lt;/p&gt;</description>
      <author>1556469348</author>
      <pubDate>Fri, 06 Mar 2026 15:19:27 +0800</pubDate>
      <link>https://ruby-china.org/topics/44505</link>
      <guid>https://ruby-china.org/topics/44505</guid>
    </item>
    <item>
      <title>2026 年国内 AI Coding Plan 怎么选？5 大平台横评帮你省钱</title>
      <description>&lt;p&gt;最近半年，国内各大 AI 平台纷纷推出了 Coding Plan 编程订阅套餐。只要按月付费，就能在 Claude Code、Cursor、Cline 等主流编程工具里直接用国产大模型，不用再按 token 算钱了。&lt;/p&gt;

&lt;p&gt;但问题来了——智谱 GLM、MiniMax、Kimi、火山引擎方舟、阿里云百炼，5 家平台各有各的定价和玩法，套餐名字也五花八门，选起来真的头大。&lt;/p&gt;

&lt;p&gt;我花了点时间把这几家的套餐信息整理到了一个对比网站上：&lt;a href="https://codingplan.org" rel="nofollow" target="_blank" title=""&gt;codingplan.org&lt;/a&gt;，方便大家一目了然地做选择。&lt;/p&gt;
&lt;h3 id="简单说几个结论"&gt;简单说几个结论&lt;/h3&gt;
&lt;p&gt;入门体验的话，MiniMax Starter 只要 ¥29/月，是目前最便宜的月付方案。如果想更低成本试水，火山引擎和阿里云百炼都有首月特惠，最低 ¥7.9 就能用一个月。&lt;/p&gt;

&lt;p&gt;模型丰富度方面，火山引擎方舟支持 6 款模型自由切换（豆包、DeepSeek、Kimi、GLM 都有），还有 Auto 模式自动调度，适合想多试几个模型的同学。&lt;/p&gt;

&lt;p&gt;智谱 GLM 的亮点是免费送 MCP 工具（视觉理解、联网搜索、网页读取），GLM-5 在 SWE-bench Verified 上也排进了第一梯队。&lt;/p&gt;

&lt;p&gt;追求推理速度的话，MiniMax 极速版能跑到 100+ TPS，体感非常快。&lt;/p&gt;

&lt;p&gt;Kimi 的 Code Plan 除了编程额度，还附带 Kimi 会员权益（AI 建站、AI 文档等），适合 Kimi 生态的深度用户。&lt;/p&gt;
&lt;h3 id="各平台入门价一览"&gt;各平台入门价一览&lt;/h3&gt;&lt;table class="table table-bordered table-striped"&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;th&gt;平台&lt;/th&gt;
&lt;th&gt;入门价&lt;/th&gt;
&lt;th&gt;首月特惠&lt;/th&gt;
&lt;th&gt;核心模型&lt;/th&gt;
&lt;th&gt;链接&lt;/th&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;智谱 GLM&lt;/td&gt;
&lt;td&gt;¥49/月&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;td&gt;GLM-5, GLM-4.7, GLM-4.6&lt;/td&gt;
&lt;td&gt;&lt;a href="https://codingplan.org" rel="nofollow" target="_blank" title=""&gt;查看详情&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;MiniMax&lt;/td&gt;
&lt;td&gt;¥29/月&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;td&gt;M2.5, M2.5-highspeed&lt;/td&gt;
&lt;td&gt;&lt;a href="https://codingplan.org/plans/minimax" rel="nofollow" target="_blank" title=""&gt;查看详情&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Kimi&lt;/td&gt;
&lt;td&gt;¥49/月&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;td&gt;Kimi K2.5&lt;/td&gt;
&lt;td&gt;&lt;a href="https://codingplan.org/plans/kimi" rel="nofollow" target="_blank" title=""&gt;查看详情&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;火山引擎方舟&lt;/td&gt;
&lt;td&gt;¥40/月&lt;/td&gt;
&lt;td&gt;¥8.91&lt;/td&gt;
&lt;td&gt;豆包 · DeepSeek · Kimi · GLM 等&lt;/td&gt;
&lt;td&gt;&lt;a href="https://codingplan.org/plans/volcengine" rel="nofollow" target="_blank" title=""&gt;查看详情&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;阿里云百炼&lt;/td&gt;
&lt;td&gt;¥40/月&lt;/td&gt;
&lt;td&gt;¥7.9&lt;/td&gt;
&lt;td&gt;千问系列 + GLM + Kimi&lt;/td&gt;
&lt;td&gt;&lt;a href="https://codingplan.org/plans/aliyun" rel="nofollow" target="_blank" title=""&gt;查看详情&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;更详细的套餐档位、用量限制、支持工具列表，可以到 &lt;a href="https://codingplan.org" rel="nofollow" target="_blank" title=""&gt;codingplan.org&lt;/a&gt; 查看完整对比。&lt;/p&gt;
&lt;h3 id="几点提醒"&gt;几点提醒&lt;/h3&gt;
&lt;p&gt;编程工具里一次提问通常会触发多次模型调用（5-30 次），所以实际可用次数比你想的要少，别被数字迷惑。&lt;/p&gt;

&lt;p&gt;大部分平台用的是滚动 5 小时窗口限额，额度会自动恢复，不用等固定时间重置。
建议从低档套餐开始试，大部分平台不支持退款。&lt;/p&gt;

&lt;p&gt;如果你也在纠结选哪家，去 &lt;a href="https://codingplan.org" rel="nofollow" target="_blank" title=""&gt;codingplan.org&lt;/a&gt; 看看，应该能帮你省不少比较的时间。有信息过期或者遗漏的地方，也欢迎评论反馈。&lt;/p&gt;</description>
      <author>junbaor</author>
      <pubDate>Wed, 04 Mar 2026 23:58:11 +0800</pubDate>
      <link>https://ruby-china.org/topics/44504</link>
      <guid>https://ruby-china.org/topics/44504</guid>
    </item>
    <item>
      <title>开源 BI 工具 - Metabase 实战指南</title>
      <description>&lt;h2 id="Metabase 实战指南"&gt;Metabase 实战指南&lt;/h2&gt;
&lt;p&gt;Metabase 是一个开源的 BI 工具，特点是上手简单，界面友好，使用符合直觉。下面讲讲怎么用它搭建数据看板。&lt;/p&gt;

&lt;p&gt;&lt;img src="https://l.ruby-china.com/photo/ThxFly/58b42941-53b6-485e-a02a-1445f44fcb6a.png!large" title="" alt="Metabase 界面示例"&gt;&lt;/p&gt;

&lt;hr&gt;
&lt;h2 id="整体流程一览"&gt;整体流程一览&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;连上数据库&lt;/strong&gt; —— 把 Metabase 跟你现有的数据源打通&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;建集合&lt;/strong&gt; —— 相当于文件夹，把东西归类放好&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;建模型&lt;/strong&gt;（推荐）—— 把常用的表封装成模型，方便非技术人员理解和使用&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;做指标&lt;/strong&gt; —— 在集合里创建「问题」，也就是你要查询的数据&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;搭看板&lt;/strong&gt; —— 把指标组装成一个可交互的监控面板&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;置顶发布&lt;/strong&gt; —— 让重要的看板更容易被找到&lt;/li&gt;
&lt;/ol&gt;

&lt;hr&gt;
&lt;h2 id="第一步：连接数据库"&gt;第一步：连接数据库&lt;/h2&gt;
&lt;p&gt;首先得让 Metabase 认识你的数据。&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;点右上角 &lt;strong&gt;齿轮图标&lt;/strong&gt; → &lt;strong&gt;管理设置&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;左侧选 &lt;strong&gt;数据库&lt;/strong&gt; → &lt;strong&gt;添加数据库&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;填写连接信息：

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;显示名称&lt;/strong&gt;：起个好认的名字，比如「生产数据库」&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;数据库类型&lt;/strong&gt;：MySQL、PostgreSQL、ClickHouse、StarRocks 等&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Host、Port、数据库名、用户名、密码&lt;/strong&gt;：按实际情况填写&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;建议打开两个选项：

&lt;ul&gt;
&lt;li&gt;✅ &lt;strong&gt;Sync schema&lt;/strong&gt;：自动同步表结构&lt;/li&gt;
&lt;li&gt;✅ &lt;strong&gt;Cache field values&lt;/strong&gt;：缓存字段值，筛选器加载会快很多&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;点保存，状态显示绿色即表示连接成功&lt;/li&gt;
&lt;/ol&gt;

&lt;hr&gt;
&lt;h2 id="第二步：创建集合"&gt;第二步：创建集合&lt;/h2&gt;
&lt;p&gt;集合相当于文件夹，可以帮你把不同业务的数据分门别类。&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;点左上角 &lt;strong&gt;「+ 新建」&lt;/strong&gt; → &lt;strong&gt;「集合」&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;命名建议：

&lt;ul&gt;
&lt;li&gt;一级目录按业务域划分，如「交易」「用户」「财务」&lt;/li&gt;
&lt;li&gt;二级目录按主题划分，如「交易/日常监控」「交易/活动复盘」&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;想建子目录？先进去该集合，再按同样方法创建即可&lt;/li&gt;
&lt;li&gt;还可以设置权限——点右上角 &lt;strong&gt;「...」&lt;/strong&gt; → &lt;strong&gt;「编辑集合」&lt;/strong&gt; 即可管理谁能看、谁能改&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;img src="https://l.ruby-china.com/photo/ThxFly/1c90620f-e7de-4d77-8cfe-61ceb07b052f.png!large" height="300px" alt="创建集合界面"&gt;&lt;/p&gt;

&lt;hr&gt;
&lt;h2 id="第三步：创建模型（推荐）"&gt;第三步：创建模型（推荐）&lt;/h2&gt;
&lt;p&gt;这是 Metabase 区别于 Superset 的特色概念。&lt;strong&gt;模型 (Model)&lt;/strong&gt; 是对一张或多张表的封装，比普通表更「聪明」：&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;可以添加描述和元数据，让非技术人员也能看懂&lt;/li&gt;
&lt;li&gt;可以在模型层面设置缓存策略&lt;/li&gt;
&lt;li&gt;创建指标时，模型会出现在更显眼的位置&lt;/li&gt;
&lt;li&gt;可以简单理解为 SQL 里视图的概念&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="什么时候用模型？"&gt;什么时候用模型？&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;这张表会被频繁复用&lt;/li&gt;
&lt;li&gt;字段名过于技术化，需要给业务人员解释（如 &lt;code&gt;stts_cd&lt;/code&gt; → 「订单状态」）&lt;/li&gt;
&lt;li&gt;想统一管理某类数据的刷新策略&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="怎么创建模型？"&gt;怎么创建模型？&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;进入目标集合 → &lt;strong&gt;「+ 新建」&lt;/strong&gt; → &lt;strong&gt;「模型」&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;选择数据源（一张表，或写一个 SQL 定义虚拟表）&lt;/li&gt;
&lt;li&gt;添加元数据：

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;显示名称&lt;/strong&gt;：业务友好的名字&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;描述&lt;/strong&gt;：这张表是干什么用的&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;字段标签&lt;/strong&gt;：把技术字段名改成业务名（如 &lt;code&gt;ord_stts&lt;/code&gt; 改成「订单状态」）&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;字段类型&lt;/strong&gt;：告诉 Metabase 哪个是日期、哪个是金额&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;过滤/分组&lt;/strong&gt;：标记哪些字段适合筛选、哪些适合分组&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;保存&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;把常用的表（如订单表、用户表）做成模型，后续业务人员用起来会顺手很多。如需修改，点右上角 &lt;strong&gt;「...」&lt;/strong&gt; → &lt;strong&gt;「编辑模型详情」&lt;/strong&gt; 即可。&lt;/p&gt;

&lt;p&gt;&lt;img src="https://l.ruby-china.com/photo/ThxFly/4350bcbb-acd3-4c3e-918f-317c863a9f50.png!large" title="" alt="创建模型界面"&gt;&lt;/p&gt;

&lt;hr&gt;
&lt;h2 id="第四步：创建指标（问题）"&gt;第四步：创建指标（问题）&lt;/h2&gt;
&lt;p&gt;在 Metabase 里，你创建的查询都叫「问题」(Question)，也就是我们说的「指标」。&lt;/p&gt;

&lt;p&gt;先进到目标集合，点 &lt;strong&gt;「+ 新建」&lt;/strong&gt; → &lt;strong&gt;「问题」&lt;/strong&gt;。&lt;/p&gt;
&lt;h3 id="方式 A：图形化拖拽"&gt;方式 A：图形化拖拽&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;选一张表，或者直接选一个模型（如果有的话）&lt;/li&gt;
&lt;li&gt;配置数据：点击 &lt;strong&gt;「+ 筛选」&lt;/strong&gt; 添加条件，如「状态 = 已支付」；点击 &lt;strong&gt;「+ 汇总」&lt;/strong&gt; 选择计算方式，如计数、求和、平均值；按需要的维度分组，如「创建时间 - 天」&lt;/li&gt;
&lt;li&gt;配置可视化：右上角切换图表类型（折线图、柱状图、饼图、数字卡等）&lt;/li&gt;
&lt;li&gt;点 &lt;strong&gt;「可视化」&lt;/strong&gt; 预览效果，点 &lt;strong&gt;「保存」&lt;/strong&gt;，记得选对集合，名字起清楚，如「每日支付订单量」&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;img src="https://l.ruby-china.com/photo/ThxFly/a0751204-d5ba-4f6d-a41a-7719d2e02bb0.png!large" width="500px" alt="数据配置示例"&gt;
&lt;img src="https://l.ruby-china.com/photo/ThxFly/3d48cca3-2410-4c70-9ffb-5ea13e5c6059.png!large" width="500px" alt="图表类型示例"&gt;&lt;/p&gt;
&lt;h3 id="方式 B：写 SQL"&gt;方式 B：写 SQL&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;点 &lt;strong&gt;「+ 新建」&lt;/strong&gt; → &lt;strong&gt;「SQL 查询」&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;选择数据库（第一步配置的那个）&lt;/li&gt;
&lt;li&gt;写你的 SQL。如果需要动态参数，用 &lt;code&gt;{{变量名}}&lt;/code&gt; 语法：
&lt;code&gt;sql
SELECT COUNT(*) AS total_users
FROM users
WHERE {{created_at_filter}}
&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;右侧边栏可以配置变量类型：文本、数值、日期、布尔值……如果是字段筛选器，还需映射到具体字段&lt;/li&gt;
&lt;li&gt;写完点 &lt;strong&gt;「运行」&lt;/strong&gt;（或 &lt;code&gt;Cmd + Enter&lt;/code&gt;），点 &lt;strong&gt;「保存」&lt;/strong&gt;，选好集合和名字&lt;/li&gt;
&lt;li&gt;然后同方式 A 配置图表类型&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;img src="https://l.ruby-china.com/photo/ThxFly/0dc51b99-2113-4786-9be2-cc22ad6a8241.png!large" title="" alt="SQL 查询界面"&gt;&lt;/p&gt;

&lt;p&gt;不管用哪种方式，保存好的「问题」就是可复用的指标了，后面直接拖到看板里就能用。&lt;/p&gt;

&lt;hr&gt;
&lt;h2 id="第五步：搭建仪表板（看板）"&gt;第五步：搭建仪表板（看板）&lt;/h2&gt;
&lt;p&gt;把指标组合在一起，配上过滤条件，就是一个可以看的监控大盘了。&lt;/p&gt;
&lt;h3 id="创建看板"&gt;创建看板&lt;/h3&gt;
&lt;p&gt;进入目标集合 → &lt;strong&gt;「+ 新建」&lt;/strong&gt; → &lt;strong&gt;「仪表板」&lt;/strong&gt;，起个名字，如「交易核心监控大盘」。&lt;/p&gt;
&lt;h3 id="添加指标"&gt;添加指标&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;点看板右上角的 &lt;strong&gt;➕&lt;/strong&gt; 进入编辑模式&lt;/li&gt;
&lt;li&gt;勾选想放的指标&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id="调整布局"&gt;调整布局&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;拖拽&lt;/strong&gt;：按住卡片标题拖到想放的位置&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;缩放&lt;/strong&gt;：拖动右下角调整大小，支持跨列&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;排版建议&lt;/strong&gt;：关键数字放顶部，趋势图放中间，明细表放底部&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;img src="https://l.ruby-china.com/photo/ThxFly/7c510647-5c0d-4f02-a40c-cde0bc8f335a.png!large" title="" alt="看板编辑界面"&gt;&lt;/p&gt;
&lt;h3 id="配置过滤条件（重点！）"&gt;配置过滤条件（重点！）&lt;/h3&gt;
&lt;p&gt;这是让看板活起来的关键。&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;编辑模式下，点顶部工具栏的 &lt;strong&gt;漏斗图标&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;添加一个全局过滤器：

&lt;ul&gt;
&lt;li&gt;选择类型：如时间范围、下拉列表、搜索框&lt;/li&gt;
&lt;li&gt;命名：如「业务日期」「城市」&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;把过滤器跟卡片关联起来：

&lt;ul&gt;
&lt;li&gt;点过滤器下方的箭头 → &lt;strong&gt;「编辑关联」&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;把全局的「时间」映射到卡片 A 的 &lt;code&gt;created_at&lt;/code&gt;、卡片 B 的 &lt;code&gt;paid_at&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;注意：SQL 创建的卡片需要 SQL 中包含 &lt;code&gt;{{变量名}}&lt;/code&gt; 才能生效&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;如果某张卡只需独立过滤，不跟全局联动，可在卡片的 &lt;strong&gt;「...」&lt;/strong&gt; → &lt;strong&gt;「编辑」&lt;/strong&gt; 中单独设置&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id="完成"&gt;完成&lt;/h3&gt;
&lt;p&gt;点右下角 &lt;strong&gt;「完成编辑」&lt;/strong&gt; 退出编辑模式。&lt;/p&gt;

&lt;p&gt;&lt;img src="https://l.ruby-china.com/photo/ThxFly/30b065cc-1437-489d-ae5c-64b3b9f94d7c.png!large" title="" alt="过滤器配置示例"&gt;&lt;/p&gt;

&lt;hr&gt;
&lt;h2 id="第六步：置顶与分享"&gt;第六步：置顶与分享&lt;/h2&gt;
&lt;p&gt;辛辛苦苦做的看板，可别让它淹没在列表里。&lt;/p&gt;
&lt;h3 id="置顶"&gt;置顶&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;在看板页面点右上角 &lt;strong&gt;「...」&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;选择 &lt;strong&gt;「置顶」&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;选择位置：

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;集合顶部&lt;/strong&gt;：仅在当前集合内置顶&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;全局置顶&lt;/strong&gt;：所有人登录后首页都能看到（需管理员权限）&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id="验证"&gt;验证&lt;/h3&gt;
&lt;p&gt;回到首页或集合页，确认看板出现在最上方的「已置顶」区域。&lt;/p&gt;
&lt;h3 id="分享（可选）"&gt;分享（可选）&lt;/h3&gt;
&lt;p&gt;点 &lt;strong&gt;「分享按钮」&lt;/strong&gt;，可以生成公开链接、导出 PDF 或设置邮件订阅。&lt;/p&gt;

&lt;hr&gt;
&lt;h2 id="真实示例"&gt;真实示例&lt;/h2&gt;
&lt;p&gt;&lt;img src="https://l.ruby-china.com/photo/ThxFly/8341d41d-5084-44e1-b662-8486f6509a33.png!large" title="" alt=""&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src="https://l.ruby-china.com/photo/ThxFly/00827756-a35a-421e-8dcf-b7d038216c3a.png!large" title="" alt=""&gt;&lt;/p&gt;

&lt;hr&gt;
&lt;h2 id="常用快捷键"&gt;常用快捷键&lt;/h2&gt;&lt;h3 id="全局"&gt;全局&lt;/h3&gt;&lt;table class="table table-bordered table-striped"&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;th&gt;操作&lt;/th&gt;
&lt;th&gt;快捷键&lt;/th&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;创建问题&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;c&lt;/code&gt; &amp;gt; &lt;code&gt;q&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;创建 SQL 查询&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;c&lt;/code&gt; &amp;gt; &lt;code&gt;n&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;创建仪表板&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;c&lt;/code&gt; &amp;gt; &lt;code&gt;d&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;创建集合&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;c&lt;/code&gt; &amp;gt; &lt;code&gt;f&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;创建模型&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;c&lt;/code&gt; &amp;gt; &lt;code&gt;m&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;创建指标 (Metric)&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;c&lt;/code&gt; &amp;gt; &lt;code&gt;k&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;浏览数据库&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;g&lt;/code&gt; &amp;gt; &lt;code&gt;d&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;浏览模型&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;g&lt;/code&gt; &amp;gt; &lt;code&gt;m&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;浏览指标&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;g&lt;/code&gt; &amp;gt; &lt;code&gt;k&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;打开个人空间&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;g&lt;/code&gt; &amp;gt; &lt;code&gt;p&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;打开回收站&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;g&lt;/code&gt; &amp;gt; &lt;code&gt;t&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;切换侧边栏&lt;/td&gt;
&lt;td&gt;&lt;code&gt;[&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;进入管理后台&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;g&lt;/code&gt; &amp;gt; &lt;code&gt;a&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;进入用户设置&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;g&lt;/code&gt; &amp;gt; &lt;code&gt;u&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;返回首页&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;g&lt;/code&gt; &amp;gt; &lt;code&gt;h&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;h3 id="仪表板"&gt;仪表板&lt;/h3&gt;&lt;table class="table table-bordered table-striped"&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;th&gt;操作&lt;/th&gt;
&lt;th&gt;快捷键&lt;/th&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;进入编辑模式&lt;/td&gt;
&lt;td&gt;&lt;code&gt;e&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;添加过滤器&lt;/td&gt;
&lt;td&gt;&lt;code&gt;f&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;添加问题侧边栏&lt;/td&gt;
&lt;td&gt;&lt;code&gt;a&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;添加图形化问题&lt;/td&gt;
&lt;td&gt;&lt;code&gt;q&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;添加 SQL 问题&lt;/td&gt;
&lt;td&gt;&lt;code&gt;n&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;保存仪表板&lt;/td&gt;
&lt;td&gt;&lt;code&gt;s&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;切换仪表板信息&lt;/td&gt;
&lt;td&gt;&lt;code&gt;]&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;收藏/书签看板&lt;/td&gt;
&lt;td&gt;&lt;code&gt;o&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;切换 Tab&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;1&lt;/code&gt;, &lt;code&gt;2&lt;/code&gt;, &lt;code&gt;3&lt;/code&gt;...&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;删除仪表板&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;Ctrl/Cmd&lt;/code&gt; + &lt;code&gt;Backspace&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;h3 id="问题/查询"&gt;问题/查询&lt;/h3&gt;&lt;table class="table table-bordered table-striped"&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;th&gt;操作&lt;/th&gt;
&lt;th&gt;快捷键&lt;/th&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;切换到编辑器&lt;/td&gt;
&lt;td&gt;&lt;code&gt;e&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;打开筛选器下拉&lt;/td&gt;
&lt;td&gt;&lt;code&gt;f&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;打开汇总侧边栏&lt;/td&gt;
&lt;td&gt;&lt;code&gt;s&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;收藏/书签问题&lt;/td&gt;
&lt;td&gt;&lt;code&gt;o&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;打开问题详情&lt;/td&gt;
&lt;td&gt;&lt;code&gt;]&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;刷新数据&lt;/td&gt;
&lt;td&gt;&lt;code&gt;r&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;切换可视化类型&lt;/td&gt;
&lt;td&gt;&lt;code&gt;v&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;切换可视化设置&lt;/td&gt;
&lt;td&gt;&lt;code&gt;y&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;切换图表类型菜单&lt;/td&gt;
&lt;td&gt;&lt;code&gt;t&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;运行查询&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;Cmd + Enter&lt;/code&gt;（Mac） / &lt;code&gt;Ctrl + Enter&lt;/code&gt;（Windows）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;保存&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;Cmd + S&lt;/code&gt;（Mac） / &lt;code&gt;Ctrl + S&lt;/code&gt;（Windows）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;删除问题&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;Ctrl/Cmd&lt;/code&gt; + &lt;code&gt;Backspace&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;h3 id="管理员"&gt;管理员&lt;/h3&gt;&lt;table class="table table-bordered table-striped"&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;th&gt;操作&lt;/th&gt;
&lt;th&gt;快捷键&lt;/th&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;切换管理后台 Tab&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;1&lt;/code&gt;, &lt;code&gt;2&lt;/code&gt;, &lt;code&gt;3&lt;/code&gt;...&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;hr&gt;
&lt;h2 id="开源版 vs 商业版"&gt;开源版 vs 商业版&lt;/h2&gt;
&lt;p&gt;根据 &lt;a href="https://www.metabase.com/pricing/" rel="nofollow" target="_blank" title=""&gt;官方定价页面&lt;/a&gt; 的信息整理：&lt;/p&gt;
&lt;h3 id="开源版（免费）"&gt;开源版（免费）&lt;/h3&gt;&lt;table class="table table-bordered table-striped"&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;th&gt;类别&lt;/th&gt;
&lt;th&gt;功能&lt;/th&gt;
&lt;th&gt;说明&lt;/th&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;数据查询&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;✅ Query Builder（图形化查询）&lt;/td&gt;
&lt;td&gt;可视化拖拽构建查询&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;✅ SQL Editor&lt;/td&gt;
&lt;td&gt;支持原生 SQL&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;✅ Models（模型）&lt;/td&gt;
&lt;td&gt;封装表结构，添加元数据&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;✅ 基础缓存&lt;/td&gt;
&lt;td&gt;Query and model caching&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;❌ Metabot AI&lt;/td&gt;
&lt;td&gt;需付费 ($100/月起)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;可视化&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;✅ 无限图表/看板&lt;/td&gt;
&lt;td&gt;折线图、柱状图、饼图、数字卡等&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;✅ 看板过滤&lt;/td&gt;
&lt;td&gt;支持全局过滤&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;✅ 交互式钻取&lt;/td&gt;
&lt;td&gt;点击穿透查看详情&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;✅ X-Ray 自动报告&lt;/td&gt;
&lt;td&gt;自动生成数据概览&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;⚠️ 邮件订阅&lt;/td&gt;
&lt;td&gt;需配置 SMTP，带 Metabase 水印&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;⚠️ Slack 订阅&lt;/td&gt;
&lt;td&gt;带 Metabase 水印&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;⚠️ PDF 导出&lt;/td&gt;
&lt;td&gt;带 Metabase 水印&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;✅ 公开链接分享&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;权限管理&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;✅ 集合权限&lt;/td&gt;
&lt;td&gt;按集合分配查看/编辑权限&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;❌ 行级/列级权限&lt;/td&gt;
&lt;td&gt;需 Pro 版&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;❌ 沙箱 (Sandbox)&lt;/td&gt;
&lt;td&gt;需 Pro 版&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;认证&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;✅ Google Auth&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;⚠️ LDAP&lt;/td&gt;
&lt;td&gt;仅支持基础认证（登录）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;❌ SAML / SSO&lt;/td&gt;
&lt;td&gt;需 Pro 版&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;❌ JWT&lt;/td&gt;
&lt;td&gt;需 Pro 版&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;❌ SCIM 自动账号同步&lt;/td&gt;
&lt;td&gt;需 Pro 版&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;嵌入&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;⚠️ Guest Embeds&lt;/td&gt;
&lt;td&gt;仅基础嵌入，带 "Powered by Metabase" 水印&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;❌ White-label（去水印）&lt;/td&gt;
&lt;td&gt;需 Pro 版&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;❌ 交互式嵌入 (Full-app)&lt;/td&gt;
&lt;td&gt;需 Pro 版&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;组织&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;✅ 集合/个人空间&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;❌ 官方集合 (Official Collections)&lt;/td&gt;
&lt;td&gt;需 Pro 版&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;❌ 审核问题 (Moderated questions)&lt;/td&gt;
&lt;td&gt;需 Pro 版&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;❌ 验证模型 (Verified models)&lt;/td&gt;
&lt;td&gt;需 Pro 版&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;数据源&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;✅ 20+ 数据库连接器&lt;/td&gt;
&lt;td&gt;MySQL、PostgreSQL、ClickHouse 等&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;✅ CSV 上传&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;部署&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;✅ 自托管&lt;/td&gt;
&lt;td&gt;需自己维护服务器&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;❌ 多区域托管&lt;/td&gt;
&lt;td&gt;需 Starter 版&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;❌ Serialization（配置导出/导入）&lt;/td&gt;
&lt;td&gt;需 Pro 版&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;支持&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;社区论坛&lt;/td&gt;
&lt;td&gt;&lt;a href="https://discourse.metabase.com" rel="nofollow" target="_blank" title=""&gt;discourse.metabase.com&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;许可证&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;AGPL&lt;/td&gt;
&lt;td&gt;商用需注意开源协议&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;h3 id="商业版 (Starter / Pro / Enterprise)"&gt;商业版 (Starter / Pro / Enterprise)&lt;/h3&gt;&lt;table class="table table-bordered table-striped"&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;th&gt;版本&lt;/th&gt;
&lt;th&gt;价格&lt;/th&gt;
&lt;th&gt;定位&lt;/th&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Starter&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;$100/月 + $6/月/人&lt;/td&gt;
&lt;td&gt;全托管云版，含官方支持&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Pro&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;$575/月 + $12/月/人&lt;/td&gt;
&lt;td&gt;细粒度权限、White-label、嵌入、Usage Analytics&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Enterprise&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;$20,000/年 起&lt;/td&gt;
&lt;td&gt;大客户专属成功工程师、合规需求&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;blockquote&gt;
&lt;p&gt;小团队用开源版就够用了；想把看板嵌入到自家产品里，需要买商业版。&lt;/p&gt;
&lt;/blockquote&gt;

&lt;hr&gt;
&lt;h2 id="关于汉化的一个问题"&gt;关于汉化的一个问题&lt;/h2&gt;
&lt;p&gt;Metabase 自带中文翻译，但有些翻译比较生硬，甚至让人误解。比如：&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;某些功能名翻译不够准确&lt;/li&gt;
&lt;li&gt;某些词过于直译，看不懂&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;如果你们的 Metabase 启用了中文界面，创建用户时，&lt;strong&gt;名字写全名，姓留空&lt;/strong&gt;。这样在仪表板、问题等处显示的就是完整名字，不会出现「小明 李」这类情况。&lt;/p&gt;

&lt;p&gt;热心的小伙伴可以创建 PR 给到官方，帮忙优化翻译。&lt;/p&gt;
&lt;h2 id="其他"&gt;其他&lt;/h2&gt;
&lt;p&gt;我也用过 Superset，对比下来 Metabase 用起来更舒服，很多操作比较符合直觉，看起来是个更不错的 BI 工具。&lt;/p&gt;</description>
      <author>ThxFly</author>
      <pubDate>Mon, 02 Mar 2026 14:45:19 +0800</pubDate>
      <link>https://ruby-china.org/topics/44500</link>
      <guid>https://ruby-china.org/topics/44500</guid>
    </item>
    <item>
      <title>[送码] OpenTIL：我用 Rails 8 做了个为 AI Agent 而建的博客平台</title>
      <description>&lt;p&gt;市面上不缺 AI 写作工具，但它们的思路都是：&lt;strong&gt;人打开编辑器 → 叫 AI 帮忙 → 人发布&lt;/strong&gt;。&lt;/p&gt;

&lt;p&gt;OpenTIL 反过来：&lt;strong&gt;Agent 是第一作者，人是审稿人。&lt;/strong&gt;（OpenTIL = Open + TIL，TIL 即 "Today I Learned"）&lt;/p&gt;

&lt;p&gt;你不需要打开任何编辑器。Agent 在你的工作流里——编程、调试、查文档——全程陪着你。它发现值得记的东西，自己写好，自己发布。你只需要在对话中点个头。&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;正确的打开方式：Agent 写，网站编辑。&lt;/strong&gt;&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;┌──────────────────┐     ┌──────────────┐
│  你的 AI Agent    │     │   OpenTIL    │
│                  │────→│   Web 端     │
│  /til 创建内容   │ API │  编辑 / 调整  │
│  💡 自动发现     │     │  主题 / 设置  │
└──────────────────┘     └──────────────┘
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;从第一天起，整个系统就是围绕"Agent 怎么写博客"来设计的：&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Skill 注入&lt;/strong&gt;——Agent 通过一份 Markdown 文件学会 &lt;code&gt;/til&lt;/code&gt; 命令，不需要装插件&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Auto-detection 状态机&lt;/strong&gt;——Agent 自己判断什么时候该提醒，什么时候该闭嘴&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;MCP 知识库接口&lt;/strong&gt;——Agent 能读你之前写过的 TIL，积累的知识反哺下一次编程&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;永不丢内容&lt;/strong&gt;——所有 API 失败都先存本地，Agent 替你兜底&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;The blog platform built for AI agents.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id="一键安装"&gt;一键安装&lt;/h2&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;npx @opentil/cli@latest
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;自动检测你装了哪些 Agent（Claude Code、OpenClaw、Cursor、Codex、Copilot、Windsurf、Gemini CLI 等），一键装好。&lt;/p&gt;

&lt;p&gt;&lt;img src="https://l.ruby-china.com/photo/biao29/d6ab1545-2900-4906-b788-2052023838cf.png!large" title="" alt=""&gt;&lt;/p&gt;
&lt;h2 id="使用方法"&gt;使用方法&lt;/h2&gt;&lt;h4 id="方式一：主动记录"&gt;方式一：主动记录&lt;/h4&gt;
&lt;p&gt;写代码时发现了个有用的东西，直接在对话里说：&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/til Rails 8 的 Solid Queue 可以完全替代 Sidekiq，不需要额外的 Redis
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src="https://l.ruby-china.com/photo/biao29/ad1e50ea-fd59-4bfe-993e-1553b01a2e52.png!large" title="" alt=""&gt;&lt;/p&gt;

&lt;p&gt;Agent 自动补上下文、加代码示例、打标签、生成摘要，直接发布。继续干活，flow 不断。&lt;/p&gt;

&lt;p&gt;&lt;img src="https://l.ruby-china.com/photo/biao29/d02ee49f-66a4-40b8-b152-ca1716e56d9a.png!large" title="" alt=""&gt;&lt;/p&gt;
&lt;h4 id="方式二：Agent 帮你留意"&gt;方式二：Agent 帮你留意&lt;/h4&gt;
&lt;p&gt;你不说，Agent 也会主动留意。调试完一个 bug、发现一个技巧，它会在回复末尾轻轻一句：&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;💡 TIL: ActiveRecord 的 strict_loading 可以在开发环境提前发现 N+1
   Tags: rails, performance · 记录一下？(yes/no)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;点头就存，摇头就过。&lt;/p&gt;
&lt;h4 id="方式三：对话结束前提炼"&gt;方式三：对话结束前提炼&lt;/h4&gt;
&lt;p&gt;聊了半天，直接敲 /til（不带参数），Agent 会从对话中提炼出值得记的知识点，列出来让你选。&lt;/p&gt;

&lt;p&gt;&lt;img src="https://l.ruby-china.com/photo/biao29/4cc37e4f-3b98-4fdf-91a2-9e7ed47686b2.png!large" title="" alt=""&gt;&lt;/p&gt;

&lt;p&gt;三种方式从主动到被动，覆盖了所有使用场景。每种都有具体例子，读者一看就懂。&lt;/p&gt;
&lt;h2 id="实现"&gt;实现&lt;/h2&gt;&lt;h4 id="用到的技术栈"&gt;用到的技术栈&lt;/h4&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Ruby + Rails 8
PostgreSQL
Hotwire（Turbo + Stimulus）
Tailwind CSS 4.1 + esbuild
Kamal 2 部署
&lt;/code&gt;&lt;/pre&gt;&lt;h4 id="背后的实现"&gt;背后的实现&lt;/h4&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;┌─────────────────────────────────────────────────┐
│  你的 AI Agent (Claude Code / Cursor / Codex…)  │
│                                                 │
│  ┌───────────┐  ┌──────────┐  ┌──────────────┐ │
│  │ SKILL.md  │  │ 状态机   │  │ MCP 知识库   │ │
│  │ 学会 /til │  │ 该提醒时 │  │ 读你之前的   │ │
│  │ 命令      │→ │ 才提醒   │  │ TIL 反哺编程 │ │
│  └───────────┘  └──────────┘  └──────┬───────┘ │
└──────────────────────────────────────┼─────────┘
                                       │
                    POST /api/entries   │  GET /mcp
                                       ↓
                              ┌────────────────┐
                              │    OpenTIL      │
                              │  opentil.ai/@你 │
                              └────────────────┘
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;一份 Markdown，40+ Agent 通吃。&lt;/strong&gt; 主流 Agent 都支持「技能注入」——往指定目录放一个 SKILL.md，Agent 就学会了 &lt;code&gt;/til&lt;/code&gt;。安装器自动检测你装了哪些 Agent，一键搞定。&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Agent 自己判断什么时候该提醒。&lt;/strong&gt; 背后是 session 级状态机——只在任务边界建议，拒绝一次整个 session 不再打扰，接受后冷却 15 轮。不需要写代码，LLM 自己就是状态机的执行引擎。&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;知识形成正循环。&lt;/strong&gt; 通过 MCP 协议，Agent 不只帮你写 TIL，还能读你之前写过的。积累的知识反哺下一次编程。&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;永不丢内容。&lt;/strong&gt; API 挂了先存本地，下次连上自动同步。这是设计原则，不是容错。&lt;/p&gt;

&lt;p&gt;全程 Claude Code 结对开发，欢迎交流技术细节。&lt;/p&gt;
&lt;h2 id="博客托管服务"&gt;博客托管服务&lt;/h2&gt;
&lt;p&gt;注册即开站，不用买域名、不折腾部署：&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Markdown 全功能（代码高亮、KaTeX 公式、Mermaid 图）&lt;/li&gt;
&lt;li&gt;多套主题 + 暗色模式，支持自定义 CSS&lt;/li&gt;
&lt;li&gt;自定义域名（Pro）&lt;/li&gt;
&lt;li&gt;内置访问统计&lt;/li&gt;
&lt;li&gt;AI 文本润色&lt;/li&gt;
&lt;li&gt;RSS + Sitemap&lt;/li&gt;
&lt;li&gt;数据导入导出，不绑架内容&lt;/li&gt;
&lt;li&gt;持续开发新功能&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;img src="https://l.ruby-china.com/photo/biao29/382e1f3a-45ec-41dd-a836-a92c7d4f0186.png!large" title="" alt=""&gt;&lt;/p&gt;
&lt;h2 id="送码"&gt;送码&lt;/h2&gt;
&lt;p&gt;30 个 30 天 Pro 体验码，Ruby China 专属：&lt;strong&gt;&lt;code&gt;RUBYCHINA2026&lt;/code&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;兑换：&lt;a href="https://opentil.ai/redeem?code=RUBYCHINA2026&amp;amp;ref=ruby-china" rel="nofollow" target="_blank" title=""&gt;https://opentil.ai/redeem?code=RUBYCHINA2026&amp;amp;ref=ruby-china&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;项目地址：&lt;a href="https://opentil.ai?ref=ruby-china" rel="nofollow" target="_blank" title=""&gt;https://opentil.ai&lt;/a&gt;&lt;/p&gt;</description>
      <author>biao29</author>
      <pubDate>Sat, 28 Feb 2026 19:43:18 +0800</pubDate>
      <link>https://ruby-china.org/topics/44497</link>
      <guid>https://ruby-china.org/topics/44497</guid>
    </item>
    <item>
      <title>图片是怎么被搜索出来的？</title>
      <description>&lt;p&gt;相信大伙平时都有搜索图片的经验，我们只要输入文字，就能通过搜索引擎搜索出相关的图片。&lt;/p&gt;

&lt;p&gt;&lt;img src="https://l.ruby-china.com/photo/lanzhiheng/d8e580b9-0487-4042-afa7-a5cfa75bc1ee.png!large" title="" alt=""&gt;&lt;/p&gt;

&lt;p&gt;这是因为网站上很多的图片其实都被标签化了，我们搜索图片的时候实际上是匹配它们的标签，本质上是通过语义化的匹配来实现。&lt;/p&gt;

&lt;p&gt;不知道大家有没有发现，其实我们的相册也有类似的功能。&lt;/p&gt;

&lt;p&gt;&lt;img src="https://l.ruby-china.com/photo/lanzhiheng/a2b013f1-1407-434f-bea8-ccf31d82ab00.png!large" title="" alt=""&gt;&lt;/p&gt;

&lt;p&gt;这就有点神奇了哈，我们并没有对我们的照片进行标签化，机器是怎么做到对我们的照片进行自动归类的？&lt;/p&gt;

&lt;p&gt;以我有限的认知来说，其实可以通过语义化向量的方式去实现。我们抛开大模型的能力先不讨论，毕竟粗暴一点其实我们完全可以让大模型去遍历所有图片，然后从文字总结中抽取标签。然而这种方式成本太高了，目前效率也比较低。&lt;/p&gt;

&lt;p&gt;针对图片的向量化，我们其实可以借助目前比较流行的 CLIP，它是一个能够同时理解图片以及文字的预训练模型，&lt;strong&gt;主要是通过对比学习（Contrastive Learning）的方式。&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;其实你可以把它看成是一个经过训练，并且能理解图片内容的一个模型，它以“文字”的形式（语义）对图片的内容进行总结。&lt;/p&gt;

&lt;p&gt;CLIP 可以通过向量化的方式把图片的语义进行存储，有点类似我们熟悉的标签。当然这种“文字”对普通用户来说是黑盒子，我们无从得知。我们把“cat”当作一个语义，下次遇到语义相近的图片，就能把它们归成一类。&lt;/p&gt;

&lt;p&gt;这里我准备三张图片：&lt;/p&gt;

&lt;p&gt;&lt;img src="https://l.ruby-china.com/photo/lanzhiheng/d42ab07d-d7cf-407d-848d-7dce7c3dca97.png!large" title="" alt=""&gt;&lt;/p&gt;

&lt;p&gt;分别是大草坪，猫咪还有一个玉石。根据 CLIP 的官方文档，我们可以通过编写 Python 脚本对图片进行向量化。&lt;/p&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;torch&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;clip&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;PIL&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Image&lt;/span&gt;

&lt;span class="n"&gt;device&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;cuda&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;torch&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;cuda&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;is_available&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;cpu&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;preprocess&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;clip&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;load&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;ViT-B/32&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;device&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;device&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# 分别读取3张图，预处理
&lt;/span&gt;
&lt;span class="n"&gt;image1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;preprocess&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Image&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;./image/image1.jpg&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)).&lt;/span&gt;&lt;span class="nf"&gt;unsqueeze&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;to&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;device&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;image2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;preprocess&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Image&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;./image/image2.jpg&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)).&lt;/span&gt;&lt;span class="nf"&gt;unsqueeze&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;to&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;device&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;image3&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;preprocess&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Image&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;./image/image3.jpg&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)).&lt;/span&gt;&lt;span class="nf"&gt;unsqueeze&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;to&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;device&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# 将所有图片合并成一个批次
&lt;/span&gt;&lt;span class="n"&gt;images&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;torch&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;cat&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="n"&gt;image1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;image2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;image3&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;dim&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# 搜索关键词 cat
&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;clip&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;tokenize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;cat&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;to&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;device&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="n"&gt;torch&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;no_grad&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="c1"&gt;# 获取图片和文字的特征
&lt;/span&gt;    &lt;span class="n"&gt;image_features&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;encode_image&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;images&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;text_features&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;encode_text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c1"&gt;# 归一化后的余弦相似度
&lt;/span&gt;    &lt;span class="n"&gt;image_features_norm&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;image_features&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="n"&gt;image_features&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;norm&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;dim&lt;/span&gt;&lt;span class="o"&gt;=-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;keepdim&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;text_features_norm&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;text_features&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="n"&gt;text_features&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;norm&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;dim&lt;/span&gt;&lt;span class="o"&gt;=-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;keepdim&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;cosine_similarities&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;image_features_norm&lt;/span&gt; &lt;span class="o"&gt;@&lt;/span&gt; &lt;span class="n"&gt;text_features_norm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;squeeze&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="c1"&gt;# 用 tensor 计算 logits
&lt;/span&gt;    &lt;span class="n"&gt;logit_scale&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;logit_scale&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;exp&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="n"&gt;logits&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;logit_scale&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;cosine_similarities&lt;/span&gt;

    &lt;span class="c1"&gt;# 转换为 numpy 用于打印
&lt;/span&gt;    &lt;span class="n"&gt;cosine_similarities_np&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;cosine_similarities&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;cpu&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;numpy&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;归一化的余弦相似度&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;image1: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;cosine_similarities_np&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="si"&gt;:&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;image2: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;cosine_similarities_np&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="si"&gt;:&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;image3: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;cosine_similarities_np&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="si"&gt;:&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c1"&gt;# Softmax概率分布
&lt;/span&gt;    &lt;span class="n"&gt;probs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;torch&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;softmax&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;logits&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;dim&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;cpu&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;numpy&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Softmax概率分布&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;image1: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;probs&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="si"&gt;:&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; (&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;probs&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="si"&gt;:&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;%)&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;image2: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;probs&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="si"&gt;:&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; (&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;probs&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="si"&gt;:&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;%)&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;image3: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;probs&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="si"&gt;:&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; (&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;probs&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="si"&gt;:&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;%)&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;在上述代码中，我分别对三张图片进行向量化，假设我的搜索关键词是“cat”，那么关键的代码就是&lt;/p&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;cosine_similarities&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;image_features_norm&lt;/span&gt; &lt;span class="o"&gt;@&lt;/span&gt; &lt;span class="n"&gt;text_features_norm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;squeeze&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;大致可以理解成，从图片的角度来看（有三张图片）我跟“cat”这个单词的匹配度如何。最终打印出来的结果大概是这样：&lt;/p&gt;

&lt;p&gt;&lt;img src="https://l.ruby-china.com/photo/lanzhiheng/93f6984e-0840-4b04-9795-86f81238499f.png!large" title="" alt=""&gt;&lt;/p&gt;

&lt;p&gt;从归一化余弦相似度来看，image2 的得分最高，觉得自己跟“cat”这个单词较为匹配。更直观的我们可以看下面的 softmax，image2 有 99.94% 的几率跟“cat”匹配。&lt;/p&gt;

&lt;p&gt;我们只要设置一个合适的阀值，就能把其他两个不相干的筛掉，留下 image2，作为“cat”搜索的结果。&lt;/p&gt;

&lt;p&gt;假设说我们能够把图库里面所有图片都进行语义的向量化，构建一个本地的向量数据库，其实就能够比较容易地构建出一个图片搜索工具了。&lt;/p&gt;

&lt;p&gt;当然，这只是计算机视觉比较基础的应用场景，后面我会分享更多的心得体会。几天前我用 Cursor 生成了一个图片搜索工具，具体可以参考我的 Github: &lt;a href="https://github.com/lanzhiheng/vm_search" rel="nofollow" target="_blank"&gt;https://github.com/lanzhiheng/vm_search&lt;/a&gt; 。&lt;/p&gt;

&lt;hr&gt;

&lt;p&gt;公众号：CXO 成长记&lt;/p&gt;</description>
      <author>lanzhiheng</author>
      <pubDate>Tue, 17 Feb 2026 15:08:10 +0800</pubDate>
      <link>https://ruby-china.org/topics/44481</link>
      <guid>https://ruby-china.org/topics/44481</guid>
    </item>
    <item>
      <title>5 分钟快速入门 AI 辅助编程：基于 OpenCode 与免费版 MiniMax M2.1</title>
      <description>&lt;p&gt;基于 OpenCode + 免费版 MiniMax M2.1，手把手带你 5 分钟快速上手 AI 辅助编程。&lt;/p&gt;
&lt;h2 id="操作指南"&gt;操作指南&lt;/h2&gt;&lt;h3 id="步骤一: 安装opencode最新版"&gt;步骤一：安装 opencode 最新版&lt;/h3&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;brew &lt;span class="nb"&gt;install &lt;/span&gt;anomalyco/tap/opencode
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id="步骤二: 终端运行opencode"&gt;步骤二：终端运行 opencode&lt;/h3&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cd &lt;/span&gt;项目根目录
opencode 
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id="步骤三: 切换模型"&gt;步骤三：切换模型&lt;/h3&gt;
&lt;p&gt;&lt;img src="https://l.ruby-china.com/photo/ThxFly/50608e59-c1e7-4c64-9070-481c30e2e149.png!large" title="" alt=""&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src="https://l.ruby-china.com/photo/ThxFly/cae32701-58f5-4c4c-b451-2947c928f953.png!large" title="" alt=""&gt;&lt;/p&gt;
&lt;h3 id="步骤四: 终端授权"&gt;步骤四：终端授权&lt;/h3&gt;
&lt;p&gt;iterm2 会弹出一些授权警告，正常授权即可。&lt;/p&gt;
&lt;h3 id="步骤五: 开始AI编程"&gt;步骤五：开始 AI 编程&lt;/h3&gt;
&lt;p&gt;示例：帮我新增一个功能：在列表页右上角支持表结构。&lt;/p&gt;

&lt;p&gt;&lt;img src="https://l.ruby-china.com/photo/ThxFly/07fadad4-2bcc-4880-8cd4-e6f7ab96e9da.png!large" title="" alt=""&gt;
&lt;img src="https://l.ruby-china.com/photo/ThxFly/99883029-e699-413b-bcb1-4def594da37f.png!large" title="" alt=""&gt;
&lt;img src="https://l.ruby-china.com/photo/ThxFly/ea0cf331-13dd-4912-b93d-d06ec362b049.png!large" title="" alt=""&gt;
&lt;img src="https://l.ruby-china.com/photo/ThxFly/791a8eed-c9a7-4743-a217-f37edce97843.png!large" title="" alt=""&gt;
&lt;img src="https://l.ruby-china.com/photo/ThxFly/c538229d-2f62-4162-8193-50f19a4c7ebb.png!large" title="" alt=""&gt;
&lt;img src="https://l.ruby-china.com/photo/ThxFly/2f7f22c0-d905-4616-9053-7e881cef5022.png!large" title="" alt=""&gt;
&lt;img src="https://l.ruby-china.com/photo/ThxFly/b26bf383-f5fb-4ccd-afa3-1d9ef8a9d7d4.png!large" title="" alt=""&gt;
&lt;img src="https://l.ruby-china.com/photo/ThxFly/d02bd1fc-7c40-46cd-94c2-bde6ee80bee7.png!large" title="" alt=""&gt;
&lt;img src="https://l.ruby-china.com/photo/ThxFly/ed9d8fe6-8c39-49f5-a51d-dd23cb7dcdc7.png!large" title="" alt=""&gt;
&lt;img src="https://l.ruby-china.com/photo/ThxFly/16154a6b-7ad3-48ab-8f07-1d92bf59cb8b.png!large" title="" alt=""&gt;
&lt;img src="https://l.ruby-china.com/photo/ThxFly/2a5b6aae-04f3-46de-8b41-91d52cd5ae54.png!large" title="" alt=""&gt;
&lt;img src="https://l.ruby-china.com/photo/ThxFly/c7b639f1-f0e6-4167-a74f-c67bad6a91ab.png!large" title="" alt=""&gt;&lt;/p&gt;
&lt;h2 id="最终预览效果"&gt;最终预览效果&lt;/h2&gt;
&lt;p&gt;&lt;img src="https://l.ruby-china.com/photo/ThxFly/38817420-5444-483c-a9bd-f9bc52dbd54e.png!large" title="" alt=""&gt;
&lt;img src="https://l.ruby-china.com/photo/ThxFly/0ad9731a-abb8-4643-acc2-dafcc9f19b84.png!large" title="" alt=""&gt;&lt;/p&gt;

&lt;p&gt;ps: 花了约 1 个多小时，通过与 OpenCode 交互 10 来轮，才最终实现当前效果。过程中包括：导入数据库、插入管理员账号、修改管理员密码、修复 Bug，以及新增“显示 CREATE SQL”等功能。执行一次较复杂的完整流程，大约需要 4 分钟。正常自然语言询问即可。毕竟是白嫖的模型，偶尔也会遇到需要等待的情况。&lt;/p&gt;</description>
      <author>ThxFly</author>
      <pubDate>Tue, 10 Feb 2026 12:29:31 +0800</pubDate>
      <link>https://ruby-china.org/topics/44475</link>
      <guid>https://ruby-china.org/topics/44475</guid>
    </item>
    <item>
      <title>给回流技术部门的第三封信</title>
      <description>&lt;p&gt;&lt;img src="https://l.ruby-china.com/photo/lanzhiheng/19695f5a-4257-407d-ba9a-e735f647a26a.png!large" title="" alt=""&gt;&lt;/p&gt;

&lt;hr&gt;

&lt;p&gt;也挺久没给部门的人写信了，该表达的，今天开会的也通过语音表达过了。以免大伙忘记，方便回顾，所以整理成信件形式，方便大伙及自己翻阅。&lt;/p&gt;
&lt;h2 id="没有年终奖"&gt;没有年终奖&lt;/h2&gt;
&lt;p&gt;2025 年已经确定是没有年终奖的了，不过公司会适当发放过节费。有些新同事可能不知道，年终奖在回流是稀罕物，我们在回流这么多年，能拿年中奖金的年份也是屈指可数。&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;不过我之前也给大伙讲过了，你们没有，那我也不可能会有。&lt;/strong&gt;这次的过节费会根据入职年限来发放，老员工可能多一些，新员工会少一些。&lt;/p&gt;

&lt;p&gt;钱虽少，也算是公司一点心意吧。这也侧面反映，其实公司的情况并没有大伙想象的那么好，请大伙不要把这当成养老的地方。&lt;/p&gt;
&lt;h2 id="学习对象"&gt;学习对象&lt;/h2&gt;
&lt;p&gt;前不久友进问我，年底了能不能少点事情？我的回答是：想都别想。我知道深圳办公室的同事看到其他部门可能没那么忙的样子，也想着产研这边是不是也可以轻松点。&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;那是绝对不可能的，其他部门也不是我们该学习的对象。&lt;/strong&gt;他们忙不忙有他们自己的安排，跟我们有啥关系？产研部门都是干到最后一天的。&lt;/p&gt;

&lt;p&gt;产研部门对比起其他部门来说已经是有点特权性质的了。大伙可以回看整个公司的其他部门，有几个部门能远程办公，弹性上下班，团建的时候老板们也赏脸参加，年会即便不参加也没有强制性要求的？反正我是没发现这种部门了，除了咱们之外。&lt;/p&gt;

&lt;p&gt;正是因为有这种相互之间的信任存在，我才要求大伙的专业度要持续在线，工作尽可能饱和。我们真要学习为什么不参考国外的优秀的技术团队呢？还要更轻松的话，那都不用干活了。&lt;/p&gt;
&lt;h2 id="“老虎”没了牙？"&gt;“老虎”没了牙？&lt;/h2&gt;
&lt;p&gt;前不久杰哥跟我说，好久没听我骂人了，觉得有点不习惯。确实，今年来说我的骂人次数屈指可数，脾气呢看着是好些了，然而并不代表我底线都丢了。&lt;/p&gt;

&lt;p&gt;小艾有时候也说我，管理太过于“柔”，可以强硬点。她觉得宽松可以，但是底线必须得亮出来。&lt;/p&gt;

&lt;p&gt;今天我也想给大伙亮一下我的底线，我个人是希望能够在一个简单，宽松的氛围下工作的。没有那么多勾心斗角，斤斤计较，大伙能够针对某个事情，一起去解决一个个的问题。这也要求大伙能够在工作中培养相互之间的信任。&lt;/p&gt;

&lt;p&gt;宽松的环境容易滋生懒惰，这点我很清楚，我也理解没有人能一直状态绝佳，偶尔状态下滑是人之常情。我就希望当某个同事状况不佳的时候，工作不够积极的时候，相互间能够提个醒。如果冥顽不灵，最后被我这边发现了，那就没那么客气了。&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;一个人持续的状态不佳，态度消极，不愿意配合他人工作，容易拖垮整个团队，导致团队渐渐失去凝聚力跟创造力，我断难容忍，这也是我的底线所在。&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;不管大伙信不信，我对这个团队的重视程度远超公司的其他，甚至超过马总跟新哥他们，所以我希望在这点上大伙不要试探我的底线。&lt;/p&gt;

&lt;p&gt;当然，如果老员工出现仗着自己资格老欺负新员工，拒绝配合新员工工作的情况，也请反馈给我，这点绝不姑息。&lt;/p&gt;
&lt;h2 id="刺头"&gt;刺头&lt;/h2&gt;
&lt;p&gt;我是不希望团队里面引入刺头的，一般来说刺头可能有一定的能力，但是自视甚高，会给团队带来极其负面的影响。&lt;/p&gt;

&lt;p&gt;我曾经跟兴民一起面试过一个图像搜索的工程师，他看着比较有经验，能回答出很多问题。然而我们发现此人不够诚恳，套路多，时间观念很差（约了三次才约上），习惯性让他人配合他工作。&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;我们并不想招聘一个大爷来供着，最后没有接纳。&lt;/strong&gt;毕竟我们不相信一个不愿意配合他人，没有同理心的人，专业能力能出色到哪里去。&lt;/p&gt;

&lt;p&gt;即便他专业能力再出色，如果不是一个愿意配合的人，也不太可能在日常工作中产生出色成果。&lt;/p&gt;

&lt;p&gt;我明白，现在很多国外的职场故事都让我们要有一定的容忍度，尤其是对那种天赋型人才，要允许他们有发挥自己个性的地方。&lt;/p&gt;

&lt;p&gt;然而，我以为，&lt;strong&gt;个性并不等于可以随性&lt;/strong&gt;，如果一个人个性过分突出，导致会伤害到其他人，我很难相信他能对团队产生什么正向收益。&lt;/p&gt;
&lt;h2 id="新方向的探索"&gt;新方向的探索&lt;/h2&gt;
&lt;p&gt;说句实在话，我感觉老同事在新技术，新领域的探索度确实力度不够。我们这帮人也没有年轻一辈那样对新技术充满热情。&lt;/p&gt;

&lt;p&gt;我觉得这并不是一个好的信号，当然了，每个人性格都不同，有些老同事可能对新技术不够敏感，但是能把事情做得非常出色。&lt;/p&gt;

&lt;p&gt;就拿云逸来说，他很早之前就给我提过，他不怎么喜欢做调研性的工作，他会很纠结，很痛苦。然而如果我们把一个笃定的技术路线，庞大的业务功能交给他，基本上可以不用操心任何事情，他能把东西完成得相当漂亮，还能发现很多我们之前没想到的漏洞。&lt;/p&gt;

&lt;p&gt;即便如此，我还是希望老一辈的同事明年开始能够多去探索一些新的技术，一些新的方向，前提当然是要自己感兴趣的。如果这些兴趣能够用在公司的产品上，那就更好了。&lt;/p&gt;

&lt;p&gt;在新技术探索这块，我感觉锐新就做得比较好，值得我们老一辈的同事学习。他很乐于接触并分享一些新的东西，所以明年我想让锐新去给兴民打一段时间的下手，在那里，他能够在实战中运用一些新的模型，算法，说不定大有裨益。&lt;/p&gt;
&lt;h2 id="AI时代"&gt;AI 时代&lt;/h2&gt;
&lt;p&gt;AI 时代来了，我们该如何自处呢？虽然我每次都要求大伙能够拥抱 AI，更多地依赖 AI 编程，然而我知道真正能够奋力去拥抱的，还是少数。&lt;/p&gt;

&lt;p&gt;明年开始我会督促大伙的，我会要求同样时间内有更高的产出，当然我也会安排更多 AI 相关的工作给到大伙，尽量让每个人都能在实战中接触 AI。&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;AI 时代的来临，是生产力的解放，但我们更应该拥抱作为人类最重要的创造力。创造力才是我们人类最宝贵的东西。&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;就目前来说，很多产品运营的新想法，都是来源于产品设计同学，这点是不够的，在座的各位都是聪明人，我相信你们都有很多奇思妙想，只是羞于表达。&lt;/p&gt;

&lt;p&gt;希望明年大伙能够从公司维度提出更多可以优化的新想法。比如说这次佳哥提出的弹性首页优化方案，就是个相当不错的做法，让我们首页日后的定制能力更强。&lt;/p&gt;
&lt;h2 id="不要焦虑，也不要飘"&gt;不要焦虑，也不要飘&lt;/h2&gt;
&lt;p&gt;大伙不要焦虑，不要觉得 AI 来了，可能会威胁到自己的饭碗。&lt;/p&gt;

&lt;p&gt;我知道市面上有太多鼓吹 AI 的媒体，会让我们觉得自己落后于时代。总觉得自己不会 XX 工具，就要落后于人。&lt;/p&gt;

&lt;p&gt;我们应该把它当成一个工具，一个寻常的工具，有了它我们能少干很多体力活，有更多的思考空间。&lt;/p&gt;

&lt;p&gt;我们可以更多地考虑业务，考虑流程，考虑架构，希望你们明年能更多地跟产品同学，跟我探讨一些新技术方案的可行性，然后一起去落地。&lt;/p&gt;

&lt;p&gt;AI 应该是创造力激发工具，我们有更多时间去思考真正重要，需要人类去解决的事情，它并不是人类的终结者。&lt;/p&gt;

&lt;p&gt;另外一个需要警惕的是，AI 以后人人都可以用，并不是什么值得吹嘘的东西。这玩意我妈都会用，我们作为技术人，真的没什么大不了的。&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;所以千万不要觉得我们会用 AI，我们做了几个 AI 的功能就觉得自己多了不起。千万不要有这种想法。针对 AI 我希望大伙能够以平常心看待。&lt;/strong&gt;&lt;/p&gt;
&lt;h2 id="最后"&gt;最后&lt;/h2&gt;
&lt;p&gt;平时我很少给大伙讲这么多，这次我说话也说得比较直，有点凶，但这也是我原本的样子。希望今天说的大伙都能听进去。&lt;/p&gt;

&lt;p&gt;新同事可以进一步了解一下我们团队是什么样的，老同事，尤其是远程的同学，不要以养老的心态来对待往后的工作。&lt;/p&gt;

&lt;p&gt;后面我们会更忙的，希望大伙还是能以创业团队的心态来对待后续的工作。如果要养老的话，这个团队并不适合你。&lt;/p&gt;

&lt;hr&gt;

&lt;p&gt;博客链接： &lt;a href="https://step-by-step.tech/posts/the-third-letter-for-huiliu-tech-team" rel="nofollow" target="_blank"&gt;https://step-by-step.tech/posts/the-third-letter-for-huiliu-tech-team&lt;/a&gt;
公众号：CXO 成长记&lt;/p&gt;</description>
      <author>lanzhiheng</author>
      <pubDate>Fri, 06 Feb 2026 22:23:48 +0800</pubDate>
      <link>https://ruby-china.org/topics/44474</link>
      <guid>https://ruby-china.org/topics/44474</guid>
    </item>
    <item>
      <title>全球首个支持微信支付的 Claude Code 购买渠道</title>
      <description>&lt;p&gt;目前使用 claude code 性价比最高的方式就是订阅 $100/$200 的套餐，但支付方式对国内朋友来说一直都是个问题，于是我上线了一个使用微信支付直接购买 Claude Code 的服务，购买后邮箱会收到一张礼品卡，然后在官方页面激活礼品卡即可，不再需要绑定信用卡。有需要的朋友可以看看。&lt;/p&gt;

&lt;p&gt;页面：&lt;a href="https://meiguo.app/claude-code" rel="nofollow" target="_blank"&gt;https://meiguo.app/claude-code&lt;/a&gt;&lt;/p&gt;</description>
      <author>Folyd</author>
      <pubDate>Mon, 26 Jan 2026 15:58:05 +0800</pubDate>
      <link>https://ruby-china.org/topics/44467</link>
      <guid>https://ruby-china.org/topics/44467</guid>
    </item>
    <item>
      <title>花了 2 个小时 vibe coding 了一个添加单词到墨墨背单词的 chrome 插件</title>
      <description>&lt;h3 id="功能如下"&gt;功能如下&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;选中的单词或者短语，调用 deepseek chat(DeepSeek-V3.2) 来进行语义归一化处理。&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;提示词如下：&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;你是一个以英语为母语的使用者。
我会给你一个英文单词或短语。
请将其规范化，使其中的词形可以在标准英语词典中直接查询到。

处理规则如下：
通用规则：
不要解释含义，仅对词形进行规范化处理。
不要臆造新词，不要添加或删除词（除非去除所有格）。
保持原有词序。

如果输入是单个单词：
按下面的词形规范化规则处理。

如果输入是短语（包含多个词）：
将短语拆分为单个词。
对内容词（名词、动词、形容词、副词）分别应用词形规范化规则。
对功能词（介词、冠词、连词等）保持不变。
将处理后的词按原顺序重新组合为短语。

词形规范化规则：
1. 名词复数 → 单数
2. 动词第三人称单数 → 原形
3. 动词过去式或过去分词 → 原形
4. 动词 -ing 形式 → 原形
5. 形容词比较级或最高级 → 原级
6. 名词所有格 → 去除所有格
7. 已是词典基本词形 → 保持不变
8. 词性歧义 → 选择词典中最常见词条
9. 非专有名词的大写 → 小写
10. 不进行语义猜测

只输出处理后的单词或短语，不要输出任何解释或额外内容。
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;归一化后的单词/短语，先在墨墨词库中查询，如果存在就在选择的云词本中去重后加入&lt;/li&gt;
&lt;li&gt;另外支持创建云词本/选择云词本，查看云词本中的单词。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="github repo"&gt;github repo&lt;/h3&gt;
&lt;p&gt;&lt;a href="https://github.com/prettybot/maimemo-notebook-extension" rel="nofollow" target="_blank"&gt;https://github.com/prettybot/maimemo-notebook-extension&lt;/a&gt; &lt;/p&gt;
&lt;h3 id="感悟"&gt;感悟&lt;/h3&gt;
&lt;p&gt;只是一个初步版本，起码满足了我的需求，没有加获取释义是因为我觉得豆包的 AI 划词工具栏的翻译更好用&lt;/p&gt;

&lt;p&gt;希望对有需要的朋友有用，欢迎提建议~&lt;/p&gt;</description>
      <author>mumuxizzz</author>
      <pubDate>Thu, 22 Jan 2026 21:20:29 +0800</pubDate>
      <link>https://ruby-china.org/topics/44464</link>
      <guid>https://ruby-china.org/topics/44464</guid>
    </item>
    <item>
      <title>钢琴转谱工具 ｜AI 探金社区 更多 AI 工具资讯案例</title>
      <description>&lt;p&gt;钢琴转谱工具 - AI 探金社区&lt;/p&gt;

&lt;p&gt;&lt;a href="https://aitanjin.ai-51.com/topic/41926" rel="nofollow" target="_blank"&gt;https://aitanjin.ai-51.com/topic/41926&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src="https://l.ruby-china.com/photo/aicoder/5a97f0f7-1da3-41f7-b54a-1949632e5c30.png!large" title="" alt=""&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://aitanjin.ai-51.com" rel="nofollow" target="_blank"&gt;https://aitanjin.ai-51.com&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;欢迎使用体验，还有更多的 AI 工具到 AI 探金社区，欢迎入驻社区：&lt;a href="https://aitanjin.ai-51.com/tools" rel="nofollow" target="_blank"&gt;https://aitanjin.ai-51.com/tools&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src="https://l.ruby-china.com/photo/aicoder/de7ac64a-4bfd-4c2c-b00e-3ccf1a79f8a7.png!large" title="" alt=""&gt;&lt;/p&gt;</description>
      <author>aicoder</author>
      <pubDate>Wed, 07 Jan 2026 00:31:48 +0800</pubDate>
      <link>https://ruby-china.org/topics/44440</link>
      <guid>https://ruby-china.org/topics/44440</guid>
    </item>
    <item>
      <title>AI 工具分享｜AI 音乐生成器</title>
      <description>&lt;p&gt;AI 音乐生成器，有免费试用机会
&lt;img src="https://l.ruby-china.com/photo/runup/39dbe86f-49ae-48d4-9987-8914ec8eaea6.png!large" title="" alt=""&gt;&lt;/p&gt;

&lt;p&gt;链接：&lt;a href="https://ai-music-gen.com/" rel="nofollow" target="_blank"&gt;https://ai-music-gen.com/&lt;/a&gt;
&lt;a href="https://ai-music-gen.com/" rel="nofollow" target="_blank" title=""&gt;直接生成&lt;/a&gt;&lt;/p&gt;</description>
      <author>runup</author>
      <pubDate>Mon, 29 Dec 2025 07:35:10 +0800</pubDate>
      <link>https://ruby-china.org/topics/44435</link>
      <guid>https://ruby-china.org/topics/44435</guid>
    </item>
    <item>
      <title>AI 工具分享｜一键人像抠图换背景 - AI 探金社区</title>
      <description>&lt;p&gt;一键人像抠图换背景：&lt;a href="https://aitanjin.ai-51.com/topic/41527" rel="nofollow" target="_blank"&gt;https://aitanjin.ai-51.com/topic/41527&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;欢迎大家使用&lt;/p&gt;

&lt;p&gt;&lt;img src="https://l.ruby-china.com/photo/aicoder/e9179fed-df86-4ea1-8425-2fd253b2c4f7.png!large" title="" alt=""&gt;&lt;/p&gt;

&lt;p&gt;AI 探金社区 &lt;a href="https://aitanjin.ai-51.com" rel="nofollow" target="_blank"&gt;https://aitanjin.ai-51.com&lt;/a&gt;&lt;/p&gt;</description>
      <author>aicoder</author>
      <pubDate>Mon, 29 Dec 2025 00:18:22 +0800</pubDate>
      <link>https://ruby-china.org/topics/44434</link>
      <guid>https://ruby-china.org/topics/44434</guid>
    </item>
    <item>
      <title>大模型之后是什么？从《哥德尔、巴赫、艾舍尔》看 AI 的下一步</title>
      <description>&lt;p&gt;如果你最近在做 AI 产品，可能会深陷于一种&lt;strong&gt;“认知分裂”&lt;/strong&gt;：&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Demo 越来越惊艳&lt;/strong&gt;：发布会上能力列表越拉越长，多步推理、复杂编程信手拈来。&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;业务频繁“翻车”&lt;/strong&gt;：一旦进入真实业务场景，逻辑断层、幻觉频发，在看似简单的问题上表现得像个“智力断崖”的巨婴。&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;模型看起来无所不知，却又不像真的懂。&lt;/p&gt;

&lt;p&gt;一个终极拷问开始被反复提起：&lt;strong&gt;大语言模型，究竟是在逼近“智能”的本质，还是仅仅把“概率拟合”玩到了极致？&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;重读神作《哥德尔、巴赫、艾舍尔》（GEB）后，我产生了一些启发，与各位交流。&lt;/p&gt;
&lt;h2 id="一、 我们得到了“能力”，但没有得到“理解”"&gt;一、我们得到了“能力”，但没有得到“理解”&lt;/h2&gt;
&lt;p&gt;从工程角度看，大模型的成就毋庸置疑：语言生成、代码补全、流程编排。但当你真正将其产品化时，会发现一个核心断层：&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;模型很会“说正确的话”，但它并不知道“为什么是对的”。&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;它更像一个反应极快、表达力极强的系统，而非一个真正理解世界的智能体。一个自然的工程假设是：&lt;strong&gt;“再堆一点算力，模型大到一定程度，会不会就‘自然懂了’？”&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;GEB 给出的启示是：&lt;strong&gt;不一定，而且很可能不会。&lt;/strong&gt; 因为理解不仅仅是信息的累加，更是结构的涌现。&lt;/p&gt;
&lt;h2 id="二、 杨立昆的批评：文本智能的“天花板”"&gt;二、杨立昆的批评：文本智能的“天花板”&lt;/h2&gt;
&lt;p&gt;杨立昆（Yann LeCun）曾多次直言：现有模型本质上是在处理文本的“表面统计”，它们从未真正理解物理世界的因果律。&lt;/p&gt;

&lt;p&gt;这指向了认知科学中经典的&lt;strong&gt;符号接地问题（Symbol Grounding Problem）&lt;/strong&gt;：&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;大模型的“重力”&lt;/strong&gt;：源于数万亿 Token 的统计相关性。它知道“重力”常和“下落”出现在同一个句子。&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;五岁孩子的“重力”&lt;/strong&gt;：源于无数次看见物体掉落，以及自己摔跤时的切肤之痛。&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;这两种“理解”的来源完全不同。&lt;/p&gt;
&lt;h2 id="三、 关键不在模型，而在数据形态"&gt;三、关键不在模型，而在数据形态&lt;/h2&gt;
&lt;p&gt;如果将不同智能系统的“输入”进行对比，你会发现 LLM 缺失了最关键的补丁：&lt;/p&gt;
&lt;table class="table table-bordered table-striped"&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;th&gt;数据类型&lt;/th&gt;
&lt;th&gt;信息密度与学习方式&lt;/th&gt;
&lt;th&gt;认知价值&lt;/th&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;文本语料&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;约 30 万亿 Token (阅读 50 万年)&lt;/td&gt;
&lt;td&gt;掌握社会习俗、逻辑表达与显性知识&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;感官流 (视频/触觉)&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;四岁儿童积累约 100 万亿字节&lt;/td&gt;
&lt;td&gt;构建物理常识、直觉物理学与空间意识&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;具身交互&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;实时因果反馈 (Action → Response)&lt;/td&gt;
&lt;td&gt;习得操控物体、运动控制与因果推断&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;&lt;strong&gt;文本数据的“聪明”，无法自动转化为对世界的“直觉”。&lt;/strong&gt; 这解释了为什么模型能写出优美的诗歌，却会在简单的物理常识（比如：把瓶子倒转，里面的水会怎样）上犯错。&lt;/p&gt;
&lt;h2 id="四、 世界模型：从“语言连续”走向“因果连续”"&gt;四、世界模型：从“语言连续”走向“因果连续”&lt;/h2&gt;
&lt;p&gt;这正是为什么“大模型之后”的共识，正在转向 &lt;strong&gt;World Models（世界模型）&lt;/strong&gt;。&lt;/p&gt;

&lt;p&gt;尤其是杨立昆提出的 &lt;strong&gt;JEPA（联合嵌入预测架构）&lt;/strong&gt;。其核心思想是：&lt;strong&gt;不再预测“下一个 Token”，而是预测“世界状态的演化”。&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;这是从“语言智能”走向“环境智能”的关键一步。只有当模型能够预测“如果我这样做，世界会发生什么”时，它才开始拥有真正的理解。&lt;/p&gt;
&lt;h2 id="五、 哥德尔不完备性：为什么系统需要“元认知”"&gt;五、哥德尔不完备性：为什么系统需要“元认知”&lt;/h2&gt;
&lt;p&gt;GEB 的第一条主线来自哥德尔不完备性定理。将其工程化，可以得到一个结论：&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;任何足够复杂的系统，都存在它在系统内部无法证明的真理。&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;映射到 AI 系统中：模型越强，覆盖的问题空间越大，它就越不可能仅靠内部概率来判断“自己是否在胡说”。&lt;/p&gt;

&lt;p&gt;下一步的关键不是“更准”，而是&lt;strong&gt;知道什么时候不确定&lt;/strong&gt;。这正是搜索增强、强化学习和推理校验（Reasoning）的真正价值——它们不是让模型更聪明，而是为系统引入了&lt;strong&gt;元认知（Meta-cognition）&lt;/strong&gt;。&lt;/p&gt;
&lt;h2 id="六、 神经符号智能：给“醉酒诗人”装上“刹车”"&gt;六、神经符号智能：给“醉酒诗人”装上“刹车”&lt;/h2&gt;
&lt;p&gt;当前 AI 圈正在经历一场“神经符号复兴”。用 GEB 的隐喻来说：&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;LLM 像“醉酒诗人”&lt;/strong&gt;：联想丰富、生成迅速，但偶尔逻辑混乱。&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;未来的 AI 需要一位“严肃会计师”&lt;/strong&gt;：逻辑严谨、可校验、可解释。&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;这对应了丹尼尔·卡尼曼的框架：&lt;strong&gt;系统 1（直觉/联想）与系统 2（逻辑/校验）&lt;/strong&gt;。今天的大模型是极致的系统 1，而神经符号方法本质上是在为 AI 引入系统 2。&lt;/p&gt;
&lt;h2 id="七、 巴赫与艾舍尔：从“模式模仿”到“自我闭环”"&gt;七、巴赫与艾舍尔：从“模式模仿”到“自我闭环”&lt;/h2&gt;
&lt;p&gt;巴赫的音乐告诉我们：创造力不来自规则的缺失，而来自&lt;strong&gt;在极端约束下的结构构建&lt;/strong&gt;。&lt;/p&gt;

&lt;p&gt;而艾舍尔的“怪圈”则揭示了“自我”的来源：当一个系统开始&lt;strong&gt;描述自己、影响自己、并根据这种描述调整行为&lt;/strong&gt;时，真正的智能才会出现。&lt;/p&gt;

&lt;p&gt;目前的大多数 AI 依然是“失忆”的：&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;没有稳定的自我边界。&lt;/li&gt;
&lt;li&gt;没有连续的行为历史。&lt;/li&gt;
&lt;li&gt;没有针对错误的自我修正机制。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="八、 Agent"&gt;八、Agent&lt;/h2&gt;
&lt;p&gt;很多人会觉得：
Agent 不就是给 LLM 包一层流程吗？&lt;/p&gt;

&lt;p&gt;但如果从 GEB 的视角看，Agent 的意义完全不同。&lt;/p&gt;

&lt;p&gt;Agent 是第一次在工程层面，把三件事放在了一起：&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;反思与不确定性&lt;/strong&gt;（哥德尔）&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;结构化规划与组合&lt;/strong&gt;（巴赫）&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;系统作用于自身&lt;/strong&gt;（艾舍尔）&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;这不是能力升级，而是&lt;strong&gt;结构升级&lt;/strong&gt;。&lt;/p&gt;
&lt;h2 id="结语"&gt;结语&lt;/h2&gt;
&lt;p&gt;《哥德尔、巴赫、艾舍尔》帮我们看清了一件事：&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;智能，从来不等于“可证明的正确性”。&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;真正的智能系统，是明知自己不完备，却仍然能够行动；是在反馈中修正，在不确定中前进。大模型只是这趟长征的起点。&lt;strong&gt;真正的挑战，是构建一个能“看见自己”的系统。&lt;/strong&gt;&lt;/p&gt;</description>
      <author>flingjie</author>
      <pubDate>Sat, 27 Dec 2025 10:14:00 +0800</pubDate>
      <link>https://ruby-china.org/topics/44431</link>
      <guid>https://ruby-china.org/topics/44431</guid>
    </item>
    <item>
      <title>一次 Agent 项目失利手记</title>
      <description>&lt;p&gt;今年上半年，我接手了一个让我心潮澎湃的项目：为一家业务飞速扩张的公司构建一套内部智能 Agent 系统。我们的愿景很宏大——希望 Agent 能自主处理部分工单、高效汇总业务信息，甚至智能触发内部流程。那时候，AI 圈子正热得发烫，人人都在谈 Agent，我也觉得自己站在了风口浪尖。&lt;/p&gt;

&lt;p&gt;然而，现实却狠狠地泼了一盆冷水。项目非但没有跑出预期的曲线，反而像一连串的“技术地雷”，接二连三地爆炸。&lt;/p&gt;

&lt;p&gt;直到项目被紧急叫停的那一刻，我才恍然大悟：许多看似纯粹的技术难题，实则根植于我们对工程化理念的忽视。&lt;/p&gt;

&lt;p&gt;这篇文字，是我对那段经历的一次痛彻心扉的回顾。&lt;/p&gt;
&lt;h3 id="一、项目开局"&gt;一、项目开局&lt;/h3&gt;
&lt;p&gt;说实话，项目的启动阶段顺利得有些过分。&lt;/p&gt;

&lt;p&gt;我们迅速选用了当时最新的大模型，搭建了一个简洁的对话界面，并初步绑定了几项核心业务工具。仅仅两周时间，一个像模像样的 Demo 就成功跑通了几个典型的工单处理流程。&lt;/p&gt;

&lt;p&gt;领导和客户看了 Demo，赞不绝口。那一刻，我心头升起一股傲气，觉得凭我们团队的能力，这次 Agent 落地定能一帆风顺。&lt;/p&gt;

&lt;p&gt;然而，正是这种盲目的乐观，为后来的急转直下埋下了伏笔。当我们将系统接入真实的业务数据环境时，好戏才真正开场。&lt;/p&gt;
&lt;h3 id="二、第一次“撞墙”"&gt;二、第一次“撞墙”&lt;/h3&gt;
&lt;p&gt;灰度上线的第一天，系统刚运行没几个小时，我们后台的监控告警就开始疯狂闪烁。&lt;/p&gt;

&lt;p&gt;原因听起来有些啼笑皆非：Agent 本应根据用户输入的关键词，准确判断工单是售后问题还是物流咨询。但在某些特定场景下，它会错误地将工单识别为“未知类型”，随即陷入一个“怪圈”——反复调用同一个查询工具，频率之高，一度让我们以为系统正遭受 DDoS 攻击。&lt;/p&gt;

&lt;p&gt;那天晚上，我盯着日志，看到怀疑人生：&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;调用：工单查询 → 发现没结果 → 尝试改写问题 → 再次工单查询 → 仍然没结果 → 又一次改写...&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;它就像一个被困在房间里的机器人，固执地、一遍又一遍地敲击着同一扇根本打不开的门。我们后来形象地称之为“围墙式死循环”。&lt;/p&gt;
&lt;h3 id="三、Agent 开始“胡乱发号施令”"&gt;三、Agent 开始“胡乱发号施令”&lt;/h3&gt;
&lt;p&gt;进入第二周，一个更为棘手的事故发生了。&lt;/p&gt;

&lt;p&gt;在某些复杂的边缘场景下，Agent 再次做出了错误的选择，这次它误选了一个用于触发“审批提醒”的工具，导致两个毫不相关的部门突然收到了莫名其妙的审批通知。&lt;/p&gt;

&lt;p&gt;谢天谢地，这只是一个低风险的提醒流程，没有造成真正的生产事故，但却在公司内部引起了不小的混乱。客户那边来电话质询时，我脑子里的第一反应不是恐慌，而是茫然：“怎么又是 Agent？我们不是刚修好了那个死循环吗？”&lt;/p&gt;

&lt;p&gt;深入排查后，我们才摸清了症结：&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;工具命名风格混乱：&lt;/strong&gt; 缺乏统一的规范。&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;返回数据结构不一致：&lt;/strong&gt; 各个工具的输出五花八门。&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;调用约定模糊：&lt;/strong&gt; 不同的工具调用方式差异大。&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;当工具数量从最初的 8 个迅速膨胀到 20 多个时，Agent 的内部决策逻辑彻底陷入了混乱。那一刻我才醍醐灌顶：&lt;strong&gt;我们根本没有建立起一套健全的“工具治理体系”！&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;回想起来，将几十个未经规范和约束的工具一股脑地扔给一个 AI 智能体自由调用，这和放任一个不了解业务的实习生随意操作上百个内部 API 几乎没有区别——甚至可能更加危险。&lt;/p&gt;
&lt;h3 id="四、信心开始动摇"&gt;&lt;strong&gt;四、信心开始动摇&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;有一段时间，我们团队几乎每天都在为新的边缘案例焦头烂额，而且越到后期，修补的难度越大。&lt;/p&gt;

&lt;p&gt;前端同事抱怨 Agent 的行为模式难以预测，导致界面交互频繁出错。后端同事则深陷于错综复杂的调用日志，感觉像在迷宫里探索。而最直接的业务方，客户，也反馈体验越来越“怪异”。&lt;/p&gt;

&lt;p&gt;在项目组的会议上，我们常常听到一句令人扎心，却又无法反驳的话：&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“你们能不能把它弄得稳定一点？”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;这句话像一根针，直插我们内心最脆弱的地方。&lt;/p&gt;
&lt;h3 id="五、项目暂停"&gt;五、项目暂停&lt;/h3&gt;
&lt;p&gt;项目正式被叫停那天，我与项目负责人进行了一次深谈。他皱着眉问我：“核心问题到底出在哪？你们不是说大模型本身没问题吗？”&lt;/p&gt;

&lt;p&gt;我反复思索，给出的答案是：&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;并非模型能力不足。&lt;/li&gt;
&lt;li&gt;并非代码质量不高。&lt;/li&gt;
&lt;li&gt;并非工具库不够丰富。&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;我们最大的症结，在于&lt;strong&gt;项目前期对工程化考量的严重不足&lt;/strong&gt;：&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;缺乏一套明确的工具规范。&lt;/li&gt;
&lt;li&gt;没有划定清晰的能力边界。&lt;/li&gt;
&lt;li&gt;未曾建立稳健的稳定性策略。&lt;/li&gt;
&lt;li&gt;遗漏了严谨的验证路径。&lt;/li&gt;
&lt;li&gt;缺失了有效的风险回退机制。&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;简单来说：&lt;strong&gt;我们对 AI 能力的信任，超越了对工程严谨性的重视。&lt;/strong&gt;&lt;/p&gt;
&lt;h3 id="六、涅槃重生"&gt;六、涅槃重生&lt;/h3&gt;
&lt;p&gt;项目虽然暂停了，但我们并没有放弃。团队痛定思痛，决定从根本上重构架构和流程：&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; &lt;strong&gt;重建工具治理体系&lt;/strong&gt;
我们投入大量精力，统一了：&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;- &lt;strong&gt;工具的输入输出结构&lt;/strong&gt;，确保数据流转清晰无误。
    - &lt;strong&gt;工具分类与能力标签&lt;/strong&gt;，让 Agent 能更智能地选择合适工具。
    - &lt;strong&gt;工具版本与变更记录&lt;/strong&gt;，避免意外的兼容性问题。
    - &lt;strong&gt;安全边界与权限隔离&lt;/strong&gt;，严格控制 Agent 对内部系统的访问。
      现在，Agent 再也不会在无关工具之间胡乱“迷路”了。&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; &lt;strong&gt;将 LLM 视为概率系统来对待&lt;/strong&gt;
我们清醒地认识到 AI 的非确定性，并在设计中加入了：&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;- &lt;strong&gt;严格的输入输出校验&lt;/strong&gt;，过滤不合规数据。
    - &lt;strong&gt;行为约束&lt;/strong&gt;，为 Agent 划定行动红线。
    - &lt;strong&gt;规则化兜底机制&lt;/strong&gt;，在 AI 决策失败时提供确定性路径。
    - &lt;strong&gt;回退策略与人工确认点&lt;/strong&gt;，确保关键流程万无一失。
      模型不再是“想怎么做就怎么做”，而是被纳入一个可控的框架。&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; &lt;strong&gt;分阶段稳健推进&lt;/strong&gt;
我们彻底告别了“一键接全链路”的激进模式，转而采取小步快跑、逐步验证的策略：

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;先确保单个任务的闭环稳定运行。&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;再在一个部门内部进行灰度验证。&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;工具能力逐个扩容，每次都进行充分测试。&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;最后才考虑跨部门和全流程的集成。&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;这套全新的方法论，后来在公司的另一个业务线成功落地。&lt;/p&gt;

&lt;p&gt;数据是最有力的证明：&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;工具错误率从 24% 直线下降到&lt;strong&gt;3%&lt;/strong&gt;。&lt;/li&gt;
&lt;li&gt;通过能力标签优化，工具调用冗余减少了&lt;strong&gt;40%&lt;/strong&gt;。&lt;/li&gt;
&lt;li&gt;Agent 的决策稳定性有了&lt;strong&gt;显著提升&lt;/strong&gt;。&lt;/li&gt;
&lt;li&gt;在多部门灰度测试中，连续三周&lt;strong&gt;未出现任何重大事故&lt;/strong&gt;。&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;那一刻，我才真正长舒了一口气。两次项目，底层技术基本相同，&lt;strong&gt;但工程纪律和边界控制的改进，却带来了天壤之别。&lt;/strong&gt;&lt;/p&gt;
&lt;h3 id="七、写在最后"&gt;七、写在最后&lt;/h3&gt;
&lt;p&gt;这次失败的项目，对我个人的职业生涯影响深远。&lt;/p&gt;

&lt;p&gt;它让我深刻意识到：&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Agent 所谓的“聪明”，有时只是一种表象。&lt;/li&gt;
&lt;li&gt;系统的稳定性，根植于扎实的工程实践，而非模型能力的无限拔高。&lt;/li&gt;
&lt;li&gt;对工具缺乏治理，最终必然导致灾难性的后果。&lt;/li&gt;
&lt;li&gt;Demo 永远是最容易迷惑人的东西，它无法替代真实场景的严酷检验。&lt;/li&gt;
&lt;li&gt;AI 并非万能灵药，真正的系统基石始终是工程框架和流程。&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;我们常说“大模型技术升级带来了颠覆性变化”，但这次经历告诉我：&lt;strong&gt;真正的成功，往往来源于那些看似“无聊”、琐碎，甚至不那么“AI”的工程细节和严谨管理。&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;希望这份带着痛楚的反思，能为你正在进行的 Agent 项目提供一点借鉴。如果你也在探索这条道路，愿你少走一些我曾经踩过的弯路。&lt;/p&gt;</description>
      <author>flingjie</author>
      <pubDate>Sat, 27 Dec 2025 10:11:46 +0800</pubDate>
      <link>https://ruby-china.org/topics/44430</link>
      <guid>https://ruby-china.org/topics/44430</guid>
    </item>
    <item>
      <title>一个 AI 语音克隆神器 - AI 探金社区</title>
      <description>&lt;p&gt;语音克隆神器 - AI 探金社区：&lt;a href="https://aitanjin.ai-51.com/topic/39052" rel="nofollow" target="_blank"&gt;https://aitanjin.ai-51.com/topic/39052&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src="https://l.ruby-china.com/photo/aicoder/63dc4837-1dfe-4720-83ae-6696ac4d93fd.png!large" title="" alt=""&gt;&lt;/p&gt;

&lt;p&gt;欢迎使用&lt;/p&gt;</description>
      <author>aicoder</author>
      <pubDate>Sun, 14 Dec 2025 00:45:17 +0800</pubDate>
      <link>https://ruby-china.org/topics/44418</link>
      <guid>https://ruby-china.org/topics/44418</guid>
    </item>
  </channel>
</rss>
