一条人生建议,怎样变成随问随用的 AI Skill?从《高性价比人生指南》到 BM25F、RRF 与被动触发

一条人生建议,怎样变成随问随用的 AI Skill?从《高性价比人生指南》到 BM25F、RRF 与被动触发

专题导读。 这篇文章面向有 Python 基础、刚接触信息检索和 Agent 的读者。我们不是要抄一本人生建议手册,而是以 B站《人生高性价比指南skill》 为入口,研究一个实际可以阅读源码的小型工程:怎样把一份长期存在的知识资料,转化成在恰当时刻自动检索、给出引用且能够撤销的 AI Skill。本文技术事实以作者在 2026 年 10 月 10 日固定的源码和原始文档为基础;文中的图、算例和代码框架均为原创教学表达,非宣称重新完成了作者的实验。预计需要 35—50 分钟,可分章节阅读。

一、视频真正提出的问题:知识收藏了,为什么遇事还是想不起来?

很多人都有类似经历。看到一篇讨论睡眠、做事方法或财务风险的长文,读完觉得有道理,于是点击收藏。两个月以后遇到同样的问题,最先想到的却不是打开收藏夹,而是直接问 AI、询问朋友或按照习惯行动。这里的矛盾并不是文字不够好,也不一定是人缺乏自律,而是知识进入行动过程需要一种触发机制。文档被收藏,只代表它具备未来被访问的可能;并不意味着未来的行为会主动查阅它。

视频在 00:12—00:21 用日常语言表达了这一点:指南收藏了,真遇到事情还是想不起来。00:35—00:45 提出作者的方案,让知识跟随日常 AI 对话,根据提问的关键词查找匹配条目。00:57—01:46 又反过来提醒:指南是帮助自己做选择,不是把人变成只能按表格生活的机器。到 01:57—02:45,作者才开始解释技术实现:本地 Markdown 知识库、分窗口检索、BM25F 类词法排序、多路查询及融合,最后将完整原文交给 AI 判断是否适用。

这段视频的技术点不是“让 AI 随时给我鸡汤”,而是把一种知识使用过程搬到用户本来就在进行的工作流里。原来需要人主动做的操作是:想起指南、打开网站、输入关键词、筛选结果、判断适用条件。现在尝试让系统自动完成前面几步,最后只展示一条值得注意的提醒。用户问编译原理、软件工程或时间管理时,主问题依然应被正常回答;额外的知识检索不应该取代主任务。

但请马上注意一个尚未证明的假设:频繁提醒是否真的让人的决策更好?视频没有提供受控用户实验,也没有证明提醒越多越有效。技术上可实现“每轮调用”,并不等于心理学上已经证明“每轮提醒”有益。后文会把工具是否触发、条目是否正确、用户是否觉得有帮助,分成不同的验收指标。

二、先认清两个 GitHub 仓库:一本书与一个工具不能混算

第一层是原始资料,eternity4719/HowToLiveBetter,中文名《高性价比人生指南》。它以原始论文、官方文件和可追溯材料支持健康、时间、经济、法律及生活事项的具体建议。其主要资产是不断维护的正文、证据和目录,而不是什么神秘的大模型参数。可以把它看成一份结构化且不断增订的公开参考手册。它覆盖哪些主题、每条建议怎样写、哪些结果有争议,都应该以相应版本的原文为准。

第二层是视频中的衍生工程,yixinagqingyuan/life-guide-skill。视频最后明确给出搜索词 life-guide-skill。它把上游资料固定到一个本地快照,再增加查询脚本、索引、近义表达、结果融合、出处检查和 Skill 指令。这个仓库体积小、结构相对容易读懂,非常适合作为理解 RAG 和 Agent Skills 的入门源码。不能因为原手册拥有很多 Stars,就把上游的关注度和维护成果算成衍生 Skill 已经取得的检索性能。

更重要的是版本。衍生仓库明确将资料固定为 2026 年 10 月 10 日取得的版本,上游提交 SHA-1 为 bb25081b423091f9e22059aab6b4ed7343a2266d,包含 34 章和 676 个条目。以后上游新增条目、修改证据或调整政策信息,并不会神奇地进入这个离线快照。离线快照带来了可复现性,也付出了时效性代价。这正是工程选择,而不是非黑即白的优劣判断。

阅读资料还需要留意许可边界。上游正文按照 CC BY 4.0 提供,复用或改编需正确署名和链接许可;上游部分代码使用 MIT。我们可以自主绘制架构图、解释算法、复现小型教学算例,却不能因为 GitHub 项目公开就假定所有被链接的第三方论文图表和视频截图都能无条件转载。本文的三张图只表达自行理解的逻辑,不复制作者的原始图或视频画面。

三、从“文件夹有一堆 Markdown”到“问题能找到准确条目”

假设你有一个文件夹,里面存放几百篇 Markdown。单纯把它们交给 AI 读取,存在三个直接问题。第一是成本:每次问一句话,都把整个资料库塞进上下文,会消耗大量 Token;第二是干扰:真正相关的两句话可能被周围无关材料淹没;第三是可解释性:AI 回答得很流畅,但你很难判断究竟依据了哪一条原文。一个合格的检索系统,首先应解决这三个问题,而不是先追求模型越大越好。

这个 Skill 做了一个合理拆分:原始章节保存在 knowledge-base/chapters,拆出的完整条目和附加检索信息保存在 knowledge-base/entries,另有主题与场景索引。检索脚本搜索的是可定位的候选,回答时使用的仍是完整原文。如此一来,候选召回可以非常短,真正需要解释的时候却不会丢掉例外、备注和来源。

一个条目至少有几个不同类型的信息:行动标题、成本、以日常语言解释的结论、具体收益、证据标签、来源和备注。它们不能随意互换。例如“这个条目文字和用户问题很像”只能说明检索相关性,不代表建议对用户安全;“证据等级较高”也不等于收益对每个人一样。类似地,所谓性价比极高,是该指南按自己定义的成本与收益量级得出的档位,不是统计学显著性,更不是将生命、金钱和自由换算成统一数值的通用经济学结论。

上游原始知识、局部索引、候选融合和完整核验之间的关系

图一|原创架构图。真实原文是一份有版本的资料,而不是一组被模型“记住”的常识;候选搜索成功后,还必须读回完整条目。

如果把这套思想搬到科研知识库,原文相当于论文与实验报告,条目相当于有明确结论与适用条件的证据卡。模型可以先通过简短索引定位到电价预测的某次实验,但必须回到训练时间、数据口径、对照和失败原因,才能对新数据作建议。索引负责让你找得到,原文负责告诉你能不能相信和如何使用。

四、为什么不能只保存搜索到的那一小段文字?

工程里常把长文切成数百字的小块,方便索引。这样确实能够降低搜索范围,却也可能产生断章取义。例如一个条目正文前半部分写“某种做法可能有益”,后半部分备注“特定人群不适用”。如果搜索结果只返回前面的小块,AI 就会漏掉最重要的例外。对图形学课程这类低风险概念,误差可能只是理解偏差;对用药、法律和财务场景,代价就可能很严重。

life-guide-skill 的做法是把“用于搜索的小窗口”和“用于回答的完整父条目”分开。源码文档显示,窗口主要从成本、通俗解释、收益与备注等字段生成,窗口最多 600 个字符,相邻重叠 100 个字符,不能跨字段。固定快照共得到 2776 个窗口。每个窗口都保留所属父条目的标识及它在正文里的字符位置;查询结束后可以从局部窗口追溯到完整条目。

为什么要重叠?设一段重要文字恰好跨越两个窗口的边界。如果完全不重叠,这段话会被截成前后两半,两个窗口都可能缺乏足够上下文。适度重叠降低边界切断重要表达的风险。当然,重叠太大又会产生重复候选、增加索引与计算开销。600 和 100 是该仓库的工程参数,不是通过跨数据集优化得到的通用最优常数。

这个项目还只让一条建议的最好窗口代表其父条目参与一条召回路径的排序。这样一个写了十个窗口的长条目,不会因为文本长就占有十次投票机会。是否绝对公平仍取决于窗口划分、字段长度和 BM25F 的归一化规则;但至少它意识到了“切得多不应等于更相关”的问题。在文献检索里,同一篇论文的十个摘要片段也不该自动击败只有一个摘要片段的另一篇论文。

五、中文检索第一难题:用户不说书里的原词怎么办?

英文检索通常可以相对方便地按空格拆词;中文没有天然空格。用户说“下午犯困想趴一会儿”,原文可能写的是“午睡”。如果检索系统只接受完全相同的字符串,这两个意思很接近的表达不一定会命中。使用大模型做向量检索是一种办法,但并非唯一办法;这个项目选择了无需下载安装语义模型的轻量词法路线。

第一层是 Unicode 规范化。不同的全角、半角符号,或某些视觉上相似的字符,会造成字符串不一致。NFKC 规范化可以消除部分形式差异,让检索程序少犯这种低级错误。第二层是中文二字和三字片段,也就是常说的二元、三元字符片段。例如“午休安排”可以产生“午休”“休安”“安排”,以及“午休安”“休安排”。这种方式不依赖复杂的分词器,也能在大量短文本里工作。

它的缺点同样明显:字符片段未必是真正的词。“休安”可能只是两个词的边界拼接;两个无关概念可能共享相同的短字串。项目用人工整理的长短语和近义表达补充这种盲点,让“午休”“午睡”“下午犯困”等表达能够通过规范主题词发生联系。固定版本包含若干组近义关系;扩展词赋予小于原词的权重,是为了避免人工词表过度盖过用户真实表达。

让我们用一个反例理解为什么需要保留原词。用户问“怀孕之后能不能吃布洛芬”。检索过程中“怀孕”可能扩展出很多相关主题。如果只保留扩展后的宽泛主题,结果就可能变成普通孕期建议,反而丢掉那个最值得核对的药名。一个可用系统必须同时保留“特定词精确命中”和“口语表达扩展”两种能力。前者减少漏掉关键实体的风险,后者改善用户词汇与作者词汇不一致的问题。

这里还有一个常被忽视的事实:近义词不等于医学或法律同义词。两种说法在口语里接近,不代表它们在专业定义里可以互相替换。比如“被辞退”“主动离职”“劳动合同到期”在聊天中都可能被描述为“没工作了”,但涉及补偿时条件不同。词表帮助找候选,不应该替代阅读原文和判断事实条件。

六、BM25 是什么:先理解一条文档为什么得分高

BM25 是一个经典的词法检索方法。你可以把它理解成:对每个查询词,统计它在候选文档里出现了多少次、这个词在整个文档集合里有多稀有,再适度考虑文档长短。常见写法是

BM25⁡(q,d)=∑t∈qIDF⁡(t)f(t,d)(k1+1)f(t,d)+k1(1−b+b ∣d∣Lavg).\operatorname{BM25}(q,d) =\sum_{t\in q} \operatorname{IDF}(t) \frac{f(t,d)(k_1+1)} {f(t,d)+k_1\left(1-b+b\,\frac{|d|}{L_{\mathrm{avg}}}\right)}.

这里 q 是查询,d 是一个候选文档,t 是其中一个查询词,f(t,d) 是词频,|d| 为文档长度,平均长度记为 L_avg。k1 控制词频饱和速度,b 控制长度归一化。请不要把这个式子当成“两个字符串的相似度概率”,它只是一种排序分数。一个候选得到高分,并不能说明其中的建议适合用户,更不能说明结论是真的。

首先看稀有程度。比如“工作”在很多建议里出现,区分力较弱;一个具体的药物名或者特殊权益名称可能只出现在少数条目,检索时更有辨识性。IDF 就是在调整这种差别。其次看词频饱和:一个词出现两次可能比出现一次更有用,但出现二十次未必应该比出现两次的文档强十倍,否则可以靠重复关键词刷排名。最后看文档长度:在一篇特别长的文章里出现一次关键词,和一个短标题里出现一次,通常不该获得相同解释。

例如两个候选:A 的标题直接是“如何安排午睡”,正文只有几百字;B 是一篇上万字的作息概览,在末尾偶然提到一次午睡。未经字段区分的简单词频检索可能不够稳健;BM25 会通过词频与长度做调整。但它仍然不知道“午睡的建议是不是有医学适用条件”,也不知道用户刚才是否在说反话。检索与理解是分层的,不要让一个数学公式承担它没有被设计来解决的问题。

七、为什么要从 BM25 升级到 BM25F?标题、备注不该一视同仁

BM25F 的 F 可以理解为 Fields,也就是字段。与其把“标题、成本、说明、收益、备注”直接拼成一大段文字,不如分别考虑这些位置的检索价值。同一个词出现在标题中,通常更能说明这条建议的主题;出现在很长的备注里,可能只是某种背景条件。如果不区分字段,搜索会受到大量次要文字干扰。

项目公开的检索说明给出了一组具体参数:标题、辅助关键词、通俗解释和正文窗口的字段权重分别为 4、1.5、2、1;各字段分别有自己的长度归一化系数,词频饱和参数 k1 为 1.2。实现会对字段中的匹配贡献进行归一化,再加权和饱和。它不是神经网络学习出来的注意力权重,而是工程作者制定并用开发样例调整的规则。

可以先用一个非正式计算体会字段思想。假设条目 A 的标题命中“午睡”一次,正文命中一次;条目 B 只有正文命中两次。如果只算次数,两者都命中两次;如果给标题更高权重,A 的主题相关性便会更突出。真实 BM25F 还要经过各字段长度归一化和词频饱和,所以不能把“四倍标题权重”直接理解成“最终评分一定四倍”。真正产生结果的是多个因素共同作用。

这种设计在其他领域非常好用。例如搜索科研论文时,论文标题、摘要、方法名、实验设置、结论和参考文献显然不应获得完全相同的关键词权重。搜“时序预测信息泄漏”时,如果某篇论文只有参考文献标题里出现这些词,不能因此排在专门研究泄漏的论文前面。一个精简的工程检索器可以先对字段做有意义的约束,再决定是否有必要引入更复杂的向量模型。

当然,字段权重也可能过拟合。如果每次遇到错误样例都把权重往有利方向调,最终你得到的是一套非常适合当前二十个问题的参数,却不一定适合全新的生活提问。可靠测试应包含未参与调参的新表述、长问句、否定句和真正范围外的问题。原项目有一定意识,后文会认真审查它的评估结果,而不是把漂亮的数字直接当作泛化结论。

八、为什么它要检索三次,而不是只运行一遍 BM25F?

我们现在已经有了一个字段加权检索器,可是它仍然可能遇到用户的长问题。自然语言往往包含大量背景:“我昨天没有睡好,下午要开会,早上咖啡喝多了,午休能不能改善精神?”这段问题里有多个细节,但核心检索主题可能是“午睡与午后困倦”。如果直接把所有词混在一起检索,某个更长、包含更多背景词的无关条目也可能排上来。

life-guide-skill 使用三路查询。第一路保留原始问题,防止丢掉用户明确的细节;第二路在原问题基础上加入近义表达,同时降低扩展词的权重;第三路只保留整理出的规范主题词,以免长背景把真正的问题稀释。若没有匹配的扩展组,系统不会为了形式而强行制造三条路线。分别检索之后,每条路线都可以拿到不同的候选列表。

这种设计体现了一个重要取舍:不要把所有的信息都压成唯一表示。原查询记录用户的真实措辞,扩展查询处理字词差异,主题查询强调核心意图。它们并不互相取代,而是提供多份可能互补的排名。哪个更好,取决于样例。如果用户给出了特殊的法律条款号码,原查询通常更关键;如果用户说了非常口语化的表达,规范主题可能更有帮助;如果问题太宽泛,三条路线也可能一起跑偏。

用科研检索类比就很直观。要查“预测日前实时价差的负价异常”,原词路线可以保留术语与地区;扩展路线加入“电价尖峰”“市场价差”等文献用法;主题路线关注“负电价与概率分布变化”。三路都能扩大找到正确资料的机会,但最终必须用目标预测任务与数据边界筛选。如果没有这种最后的检查,“找到了三条相似论文”仍然不能等于“找到了适用于该市场的可部署方法”。

原查询、扩展问题和规范主题三路检索后,用RRF融合并读回原文

图二|原创召回流程图。三路不是三个大模型,而是同一类词法检索器在不同查询表示上的调用;分路融合以后仍需读回原文。

九、RRF 为什么按名次融合?请自己算一次

不同检索路线返回的原始分数通常不可直接比较。原查询可能有十个词,扩展查询有二十个词;即使底层算法相同,分数的量级也可能不同。直接把三路分数相加,很容易让词更多的一路获得不合理的优势。RRF 的思想很朴素:不直接比原始得分,而是看一个候选在各路线里排第几名。

在本项目的三路设置中,可以把融合式概括为

R(d)=∑r∈R(d)wr60+rank⁡r(d).R(d)=\sum_{r\in\mathcal R(d)} \frac{w_r}{60+\operatorname{rank}_r(d)}.

d 是候选条目,集合 R(d) 包含将其召回的查询路线,w_r 是该路线权重,rank 从一开始计数。作者为原词路线与纯主题路线设置权重 1,为混合扩展路线设置 0.7。分母的 60 是常见的排名平滑常数。这个式子决定的是优先阅读哪些候选,不是“这条建议正确的概率为多少”。

我们手算一个简化例子。条目 A 在原查询排第一、扩展查询排第四、主题路线没有入围,则其得分约为 1/61 + 0.7/64,即约 0.0273。条目 B 在原查询排第五、扩展查询排第一、主题路线排第二,则约为 1/65 + 0.7/61 + 1/62,合计约 0.0430。尽管 B 不是原始问题的第一名,它在三路中都有较好表现,因此融合后可能超过 A。

这恰恰是多路检索的价值:一条路线犯错,其他路线有机会纠正。但也要认识到三路的错误可能高度相关。例如三个查询都被一个歧义词误导,融合只会强化那个错误。RRF 无法发现医学禁忌、法律例外或过时资料;更不能把三条有偏差的检索结果自动升级为三份独立科研证据。三条路线分享的是同一资料库与许多相同词法规则,它们不是三个完全独立的观察者。

因此融合之后,作者还增加标题覆盖、规范词覆盖、精确长词保护和优先章节等规则重排。代码里会区分原始词与规范词对标题的覆盖情况。它们可以帮助“布洛芬”这类精确词避免被泛化主题挤掉,但依然属于文本匹配,不是自动识别实体与关系,也没有模型理解否定和讽刺的能力。这里要保持清楚的能力边界。

十、检索结果不是答案:完整条目、备注和交叉引用的最后一道门

设想检索返回“某类医疗检查能带来好处”,短片段里包含一个漂亮的百分比。真正需要决定是否适用时,你至少要继续问:这个数字的研究对象是谁?是相对风险还是绝对风险?随访多长时间?是否适用于当前年龄?相关禁忌是否写在备注中?若没有这些上下文,即便检索命中完全正确,最终回答仍可能错误。

该 Skill 的查询命中后,会根据窗口携带的父条目 ID 找回完整正文,还能沿作者明确设置的交叉引用补读少量相关条目。这是一个可以重复执行的工程流程,而不是向模型发出“请认真”的口头请求。若字符预算不足,脚本会报告被省略的条目,而不是悄悄截断完整正文。阅读者可以随后使用单条展示功能补读,降低因为上下文截断造成的隐性错误。

源码中还有逐字引文核验的入口,可以检查某句话确实存在于所指条目,以及本地文件哈希与固定版本一致。这里必须区分三道门:文本存在、文本被正确解释、文本事实仍然有效。哈希能证明文件没有在本地悄悄改变;逐字核对能证明引用存在;但它们都不能替代当前最新的医学指南或具体地区的政策查询。把文件一致性说成“内容真实可靠”,是知识库产品最容易出现的错误之一。

对科研工程也一样。一个实验报告的 SHA-256 完全一致,只能证明你取到了同一份报告;如果报告原本用了未来信息,哈希再可靠也救不了结论。真正的证据链应该从源文件身份,延伸到实验协议、数字复算、数据划分和结论范围。这个小项目把“检索以后再读回原文”做成了代码层面的动作,是比单纯宣称“支持 RAG”更值得学习的部分。

十一、什么叫“被动 Skill”?别把全局配置和模型自觉混为一谈

视频最容易让人误解的表述,是“像影子一样陪着你,每次对话都有提醒”。初学者可能以为,只要把一个 SKILL.md 放到某个目录,AI 就会在所有聊天里自动运行它。实际并非如此。至少存在三个环节:文件是否安装、宿主能否发现并加载、每轮用户问题是否触发规则及真实检索。任何一步没有发生,最终都可能没有提醒。

这个衍生项目非常有意思,因为它不仅给出 Skill 描述,还编写了 scripts/configure_global.py。这个程序会找到 Codex 当前用户配置目录,在生效的 AGENTS.md 或 AGENTS.override.md 中插入一段带独立标记的全局规则,要求新会话主动读取 life-guide 的原版说明,然后正常完成当前任务,并在最后检索一条相关提醒。这与单纯把文件放进用户技能目录不同:目录解决发现能力,全局指令解决默认调用意图。

作者很注意配置变更的可逆性。脚本只维护自己的成对标记,遇到标记缺失、重复、错序或意外编码会拒绝乱改;修改之前检查文件现状,写入时使用临时文件和替换,保留原有配置内容。还有 —status、—disable 和 —dry-run,便于检查实际生效路径、撤销功能和预览将要发生的变化。对于经常安装多个 Skill 的工程师,这种精确可撤销机制,比一条粗暴覆盖用户全局指令的安装命令可靠得多。

不过“配置存在”依然不等于“每轮绝对执行”。Codex 是对全局指令进行解释并调用工具的智能宿主;若遇到严格格式请求、当前模型没有正确读取文件、上下文不足、工具失败或指令冲突,都可能不输出提醒。作者也在 SKILL.md 中设置了用户明确关闭本轮提醒、要求严格 JSON 输出等例外。因此最好的工程叙述不是“百分之百强制触发”,而是“具备默认启用、可观测验证和关闭的宿主层引导”。

对网页端 ChatGPT 来说,边界更加明显。网页版不会自动读取你 Windows 用户目录。只有经授权的本地连接器真实暴露了读取能力,网页端才有可能访问这个 Skill;即使能够读取,也不意味着网页端每次聊天都会自动发现并执行。我们应该把“当前某次 MCP 文件读取成功”与“所有会话都建立了被动触发机制”分开测量。这里讨论的是通用原理,不代表本文已经在你的电脑上安装或启动了 life-guide。

Codex原生全局指令与网页端MCP读取Skill是不同链路

图三|原创宿主对比图。文件安装、默认调用和真实每轮执行是独立验收阶段;通过 MCP 读到文件,不等于每条未调用 MCP 的聊天都能自动获取它。

十二、为什么作者没有直接套一层大模型向量数据库?

看到 RAG,人们常想到向量数据库、Embedding、重排神经网络以及很多新的服务。但对于几百条按主题组织清楚、中文标题简短、资料结构固定的知识库,轻量 BM25F 并不丢人。它可以在本地用 Python 标准库工作,不依赖上传个人生活问题到第三方索引服务,也无需长期维护专门的向量数据库进程。对一个人的电脑来说,少一个长期服务往往意味着少一个端口、凭据、升级和故障排查点。

这并不是说向量检索没有价值。用户用非常含蓄的比喻表达想法,或者同一概念有完全不同的语言表达时,仅靠词表与字面窗口可能召回失败。向量方法通过语义表示可以覆盖一部分词面不重合的情况。但它也可能把语义相近、事实条件却不同的条目混在一起。例如同一法律问题中,不同主体、不同时间或不同合同类型会改变答案,单靠“含义类似”并不足以确认适用条件。

选择工具应先看数据特点。若知识总量不大、词汇相对固定、关键词精确度高、需要容易解释的结果,建议先做可复现的词法基线。若真实错误分析显示大量同义表达漏召回,再增加查询扩展。只有当词法系统已在独立问题集上表现出明确且难以修补的语义召回问题时,才考虑引入向量索引,并在相同测试集、相同来源约束下比较真实收益。不要因为“RAG 标准架构图上画了向量数据库”,就默认每一个 Skill 都应该多部署一个。

更要区分“检索模型复杂度”和“最后回答的推理能力”。这个项目用规则找候选,仍然依赖宿主 AI 读完整条目、理解用户情境并组织自然语言。把检索算法从 BM25F 升级到一个复杂的神经网络,并不保证宿主能够更正确地理解证据。改进应该对应错误来源,而不是只增加组件数量。

十三、项目报告的提升有多大?为什么还不能叫通用准确率

作者公开了一份 2026 年 10 月 10 日的开发样例对比:20 个预设了目标条目的问题,另有 3 个范围外问题。旧检索 v1 的首条命中率为 60%,前五命中为 70%;只补充近义词的 v1-expanded 首条达到 90%,前五达到 100%;完整 BM25F 流程在这组开发样例上首条和前五均为 100%。对应 MRR@5 从 0.633、0.942 到 1.000。报告同时列出了逐题排名和本机总耗时,说明作者至少认真比较了不同实现。

我们先用算术理解它。20 个有答案的问题中,首条命中 60% 表示正确条目在第一位的有 12 题;90% 对应 18 题;100% 对应 20 题。相比旧版,完整方案在这 20 个问题上多把 8 题的正确答案排到了第一位。前五命中衡量的是正确条目是否出现在前五名,而不是 AI 最终回答是否正确。MRR 则给排名靠前的相关条目更高权重;它们是检索指标,不能互相替代。

但作者在报告中已经明确提醒:近义表达与排序规则针对这些开发问题进行了修改,这不是独立盲测。也就是说,漂亮的 20/20 结果只能说明这套规则已经适应了这些问题,不能推断任意陌生用户、任意问法、任意法律医学内容都能准确处理。更不能把“找到对应条目”写成“建议必然正确”“已经证明对用户有帮助”。三道完全不同的门必须独立记录:检索命中、引用支持、最终决策适用性。

还有一个很好的可研究问题:究竟是谁带来了大部分改进?从旧版 60% 到只加近义词 90%,已经解释了相当大的收益;再升级到完整 BM25F 得到开发样例 100%。如果论文或博客只写“BM25F 让检索从 60% 提升到 100%”,便错误地把近义词扩展、三路查询和规则重排的效果全部归给一个算法。正确的消融应该至少包括固定词表旧版、只扩词旧版、只改字段权重、只增加查询路线、只加重排以及完整方案,且最后另留一组未参与迭代的新问题。

十四、从“午休”到正确条目:一次不依赖新大模型的完整例题

我们以一个技术流程示例走完所有步骤,但不把例子当成对个人健康的医疗建议。输入问题是:“下午总犯困,中午休息一会儿有什么思路?”第一步不要直接生成一段看似专业的建议,而是将用户问题作为需要定位证据的查询。规范化字符后,我们保留“下午”“犯困”“中午”“休息”等原始表达,并尝试从近义表中识别“午休”“午睡”等规范主题。

第二步,运行三路 BM25F。原问题一路可能匹配到睡眠、精力和工作休息相关条目;扩展问题一路加强与午睡关联的词;规范主题一路减少长句里“下午总是”等常见背景词的干扰。每路内部再对标题、关键词、解释和窗口作字段加权。此时还没有回答用户的问题,程序做的只是给候选排序。没有任何理由把第一名直接叫作最适合这位用户的健康方案。

第三步,RRF 合并。若同一个午睡条目在多个路线中靠前,它的融合排名可能提升。第四步,查看标题覆盖和规则重排,特别注意不要因为另一个条目里恰好提到“下午晒太阳”就把它错当作午休指南。第五步,用父条目 ID 获取完整正文,检查建议是否只讨论普通日常作息、有没有针对特殊情境的备注,以及该条的证据等级与成本如何记录。

第六步才轮到 AI。它先回答用户的实际问题,再决定是否在最后附上一个简短的指南提醒。若用户说正在赶报告,只需要了解工作流程,额外提醒不应夺走主要篇幅;若用户明确要求“只输出 JSON”,就不应追加一块 Markdown。若资料中没有可证明适用的条目,应当说明没有匹配证据。即使作者设置了无直接命中时改选通用条目的策略,也不能把一个勉强相关的通用提醒伪装成对当前专业问题的证据回答。

这个例子的关键不在于得到一句“可以午睡”,而是每一步的结果都可检查:查询经过了哪些转换、哪些窗口命中、每路排名是多少、为何融合后靠前、完整备注写了什么、最后展示的标题有没有与原文一致。没有这些中间环节,一个模型可能碰巧回答对,却无法帮助你定位下次为什么会错。

十五、反例:什么情况下“每轮提醒一次”会变成打扰?

设想一名程序员正在排查生产系统的数据库故障。他连续问了五个具体的问题:锁等待、慢查询、连接池、回滚、监控告警。如果每个回答结尾都机械附上一条与“注意休息”有关的生活建议,前一两次也许尚可接受,后面就可能成为噪声。原本用于提高知识使用频率的机制,反而降低了任务焦点和阅读效率。这说明触发率可以越高越容易统计,却不一定是最值得优化的目标。

另一个反例是专业风险。用户问某个处方药是否能与已有药物合用,Skill 也许找到了一个含有相同药名的条目,但该条的条件并不覆盖用户情况。此时,错误的做法是因为系统已经自动检索就硬附上结论;更稳健的做法是说明资料不足,避免将检索命中误当医疗判断。如果资料涉及现实急症,还必须优先给出获得专业帮助的建议,不能让普通检索过程拖延必要行动。

更隐蔽的问题是隐私。一个随时分析用户对话的 Skill,可能为了“更懂你”而倾向记录财务、家庭、健康和个人处境。视频的技术实现主要讲本地资料检索,但“本地”不自动代表“什么个人信息都可以永久保存”。查询词、日志、知识库命中和最终提醒是四类不同数据;实现者要回答哪些信息只在本轮内存使用、哪些会写入文件、保留多久、能否关闭。默认被动调用不应成为默认建立长期个人画像的理由。

因此,评估被动 Skill 至少需要三个指标:在应该触发的场景里是否触发,在不应该触发的场景里是否克制,以及每条提醒的证据是否充分。只测第一项会鼓励到处插入提醒,只测第二项会让系统永远不工作,只测第三项又可能忽略它造成的打扰。真正好的机制应该在完成原任务的前提下增加有意义的信息,而不是为了展示存在感而牺牲主线。

十六、全局脚本为什么值得看:幂等、撤销和不碰别人配置

从软件工程角度,scripts/configure_global.py 的价值甚至可能不低于检索算法。很多开源 Skill 的安装说明不过是一句“将这段文字复制到 AGENTS.md”,结果不同项目争相在全局指令里追加内容。几个星期以后,配置文件充满相互冲突的要求,用户甚至不知道哪条规则来自哪个项目。开发者想关闭某个 Skill 时,只能凭记忆手动删除,风险与维护成本都在增加。

这个脚本采用了托管区块的办法。启用时写入自己的开始与结束标记;如果已经存在标记,只替换这一块;关闭时只删除由自己管理的内容;若标记损坏或出现重复,则直接拒绝执行。它还先判断实际生效的是 AGENTS.override.md 还是 AGENTS.md,防止把规则写进一个根本不会被读取的文件。对非 UTF-8 内容、符号链接和中途被修改的文件,源码也有明确的防护和失败路径。

这是值得迁移到其他 Skill 管理场景的设计:要把每个安装包对全局配置的影响限定为可识别、可审核、可回滚的最小修改,避免整个文件的无条件覆盖。你以后做 DevSpace 的自动技能发现,也可以借鉴这种粒度:发现路径、加载版本、命中原因、失败状态和用户撤销分别有记录,而不是只有“当前已启用”一个布尔值。

但不要把这个脚本的防错设计直接扩展为“运行后百分百成功”或“所有宿主都支持”。它面向本机 Codex 配置,不会自动改变网页版 ChatGPT、另一台电脑、其他用户账户或别的编辑器。源码里出现检查与回退逻辑,只代表作者尝试处理这些情况;除非在你的操作系统、Codex 版本与真实插件连接上做端到端测试,否则仍然不能把源代码自述等同于部署验收。

十七、这个小仓库的测试做到了哪一步,还缺什么?

仓库提供了几类有用的验证入口。validate_kb.py 用于检查知识库条目和文件来源的一致性;test_retrieval.py 收集典型短问句、长问句、近义表达与负例;test_global_config.py 在独立的用户配置目录里验证启用、重复启用和关闭规则;benchmark_retrieval.py 用同一固定资料比较检索方案。它们的分工很合理:不能让“脚本成功运行”代替“检索结果相关”,也不能让“检索相关”代替“全局配置不会破坏用户设置”。

如果现在由我们接手,我首先会建立四组验收。第一组是资料一致性:同一条原文、来源文件和固定提交是否相符,文件被悄悄修改后是否停止使用。第二组是检索鲁棒性:短问题、长问题、专业名词、同义词、反问、错别字、否定表达以及范围外话题,各自有独立标签。第三组是宿主触发:新开会话是否默认加载,切换工作区是否仍有效,关闭提醒是否成功,严格格式输出是否尊重要求。第四组是最终回答:用户真正要求的任务有没有被正确完成,附加提醒是否支持主问题,医学法律等情境有没有遗漏限制。

这四组需要不同的统计量。资料一致性可测哈希通过率与来源追溯率;检索可测 Hit@1、Recall@5、MRR@5;触发可测应触发成功率与不应触发时的误触发率;回答则需要人工或明确的判定程序审查正确性、引用支持和不适用场景。在开发样例里看到 100% Hit@1,不意味着其余三组也都是 100%。

如果要写成科研论文,最有价值的不是宣称“新 BM25F 完胜”,而是区分词表扩充、字段建模、三路检索、RRF 和完整上下文分别解决了哪类错误,并在独立数据上验证。很多看似新颖的工程组合其实沿用了成熟算法,创新点应来自任务设计、可识别的失败机制与具有说服力的实测证据,而不是把通用公式重新起名。

十八、从零做一个玩具复现,不需要先学大型 RAG 框架

想自己理解这套系统,最好的起点不是克隆几百个 Markdown 后立即运行所有脚本,而是准备五张自己写的知识卡,每张只有一个标题、一段说明、一条例外备注。比如卡 A 是“如何保护深度工作时间”,卡 B 是“定时处理通知”,卡 C 是“如何规划短时间休息”,卡 D 是“不要被沉没成本绑架”,卡 E 是“怎样核对引用出处”。这些都是教学构造,不代表原手册的具体条目。

第一轮只写最简检索器。将五个标题与用户问题转成二字片段,计算交集,查看哪个标题最相近。你很容易观察到:含有常见词的卡片可能误命中,同一个词重复很多次会不合理地拉高简单计数。第二轮加入类似 IDF 的权重,让稀有词更有区分力;第三轮加入长度与频率饱和;第四轮把标题和正文拆开加权。做到这一步,即使你的实现还不是严格的 BM25F,也已经可以理解它试图解决的偏差。

第五轮只为两个确实观察到的口语差异增加近义词。记下修改前的失败问题,修改后重新测试,同时加入一个新反例,防止改一个问题破坏另一个问题。第六轮运行原词与扩词两路查询,用 RRF 融合。最后让检索返回一条完整知识卡,检查例外备注是否仍在。整个过程不需要 GPU,也不必启动向量数据库,最复杂的是把评估问题和失败原因记录清楚。

这里有一段表达流程的伪代码,它不是原仓库源码,也没有提供医学或金融建议:

def answer_with_evidence(question, cards):
    original = normalize_and_tokenize(question)
    expanded = expand_known_phrases(original)
    ranked_a = rank_fields(original, cards)
    ranked_b = rank_fields(expanded, cards)
    candidates = rrf_merge([ranked_a, ranked_b])
    for candidate in candidates:
        full_card = read_parent_card(candidate.card_id)
        if evidence_and_conditions_match(full_card, question):
            return full_card.title, full_card.citation
    return None, "没有足够的可核验条目"

这段代码的意义是展示模块之间的关系,而不是鼓励直接把 evidence_and_conditions_match 交给一个未经验证的语言模型。尤其在高风险决策中,条件匹配需要明确规则、可靠来源和必要的人类专业判断。你应该能够解释每个模块为什么存在、替换哪一部分会改变什么输出,才算真正学会。

十九、迁移到科研知识库时,哪些值得借鉴,哪些不该照搬?

我们以后会处理数百次电价预测实验、论文段落、开源项目笔记和软件调试记录。life-guide-skill 提供了四个可以直接借鉴的工程思路。第一是固定来源版本。研究结果必须知道对应哪个数据集、哪次配置和哪份原始报告,不能只保存一段没有源头的结论。第二是检索窗口与完整证据分离。搜索阶段可以短,但正式使用前必须读到结论的适用条件和反例。第三是多路检索的错误互补。用户用市场术语、模型名或自然语言提问时,可以尝试不同查询表示,却不应该假定多路一定优于强词法基线。第四是可撤销的全局配置管理。共享 Skill 的生效范围和版本应该可查,不应该悄悄污染所有宿主。

不能照搬的是“每个工作任务最后强行追加一条人生提醒”的产品行为。科研助手处理论文修改、实验复现和代码审查时,最重要的是主任务质量。向某个专业科研任务自动追加与它无关的生活条目,往往只会增加噪声。因此这套 Skill 可以作为明确选择开启的个人助手能力,但不应被误当成所有 Agent 必备的底层规范。

从架构上看,也没有必要把这份人生资料逐条导入我们的正式科研结论知识库。生活建议是独立内容领域,科研实验知识又是另一个领域;共享 Skill 注册机制可以共用,资料权限与检索空间未必需要混在一起。真正优秀的共享平台不是把所有知识塞进一个桶里,而是能按任务精确找到所需来源,并知道哪些来源暂时不应该被取用。

二十、认真挑错:四种会让小型 Skill 看似成功的假象

第一种是假命中。模型最终回答很像正确答案,但检索结果实际上没有支持它。因为大模型本身记住了很多一般知识,完全可能在没有找到正确原文时碰巧说对。所以必须记录检索输出、原文和最终回答,检查是否真的建立了证据联系。第二种是测试集重复使用。开发者发现某个问句没命中,于是改近义词表,重新测试后全对了;如果再把同一批问题宣称为独立测试集,结论就会高估泛化能力。

第三种是资料过期。固定版本的引用链非常完整,条目标题、作者来源和哈希都能对上,但医学研究或地区政策已经发生变化。哈希核验反而可能让人产生虚假的安全感。解决办法不是取消版本固定,而是分开报告“资料是哪个版本”和“这个事实最后一次通过权威来源复核的时间”。第四种是强制提醒带来的指标错觉。每一轮都出现一句提醒,触发率看起来满分,用户却越来越不愿意看。没有监测用户认可、误触发和任务完成质量,就不能证明自动化带来了收益。

还有一个尤其适合技术读者的小问题:检索评分和性价比评分是两个不同系统。BM25F/RRF 排的是候选与提问的词法相关程度;原指南中的性价比档位依据成本与收益标签计算。一个条目的检索排名第一,不意味着它的性价比一定高;性价比极高,也不意味着它正是这位用户当前需要的东西。把两套评分在界面里混成一个数字,会让输出显得精准,却丧失正确解释。

上述四种误差会在真实产品中相互影响。比如某条过时建议因为标题特别贴合问题被排到第一,模型又依据熟悉的常识生成正确表述,用户看见自动提醒就认为整个系统可靠。因此我们更需要分阶段的可观测证据,而不是把所有成功压缩成“AI 答对率”。

二十一、如果只花一个下午复现,应该怎么验收?

我建议把下午分成几个有明确停止条件的小阶段。先花少量时间阅读 README、SKILL.md 和来源文件,确认作者视频里讲的东西实际存在。接着只运行知识库一致性检查,确保缺文件、改文件会报错。然后选三类问题:明确的关键词、口语化改写、知识库范围外的问题。把三类结果保存下来,并能解释为什么被召回或拒绝召回。

完成检索检查之后,再阅读字段加权和三路融合实现。不要一上来重新训练一个向量模型;若你连原版候选顺序都无法解释,替换底层检索器只会让问题更难诊断。最后在隔离的测试用户目录里检查全局配置脚本的 —dry-run、—enable、—status 和 —disable,确认重复开启不增加重复规则、关闭不会破坏用户原有指令。没有测试环境之前,不建议把这个脚本直接运行在日常使用的全局配置上。

从验证角度,可以给自己设一张极小的记录表:问题、预期相关条目、首条命中、前五命中、原文条件是否完整、默认提醒是否出现、用户是否想保留这条提醒。十个问题足以让你暴露第一批工程缺陷,虽然绝不足以证明产品质量。重点是每一个失败都能被归因到来源、词表、字段权重、融合、条目读回、触发或用户体验中的某一层。

如果所有小样例都通过,再从你没有用来调整规则的新任务中抽取更多问题。遇到无法解释的失败,先核对索引和原文,最后才动算法;若某次改动只是让开发样例涨分、未改善新的独立问题,就应暂停推广。这样的学习方法能帮助你更快理解代码,也能避免把项目维护变成永远增加功能和配置项的游戏。

二十二、读完这篇文章,你应该真正带走什么?

最值得记住的第一件事是:好的知识资料与好的检索工具不是同一件事。上游《高性价比人生指南》负责积累有来源的内容,衍生 life-guide-skill 负责把它做成能够在用户提问时被找到、被核对和被显示的局部流程。内容积累依赖证据质量,检索工程依赖召回与排序,最后的建议依赖具体情境;三种职责需要单独验证。

第二件事是:BM25F、查询扩展和 RRF 并不是晦涩的黑盒。它们各自解决一个常见问题:字段价值不同、用户语言与原文不同、不同查询路线的原始分数不可直接相加。把这三个问题讲清楚,你已经能够读懂相当多的企业知识库和科研检索系统。之后增加向量检索、Cross-Encoder 或查询理解模型时,你也会知道新组件应该证明解决了什么缺陷,而不是凭流行程度判断是否先进。

第三件事是:被动 Skill 的核心不是提示词喊得更响,而是宿主发现路径、默认指令、文件读取、真实检索、撤销与审计之间有可执行的关系。安装一个 SKILL.md 不等于每轮触发;搜到一个条目不等于事实正确;能把提醒追加到所有回答不等于用户获益。这些区别是做可靠 Agent 比“又找到了一个神奇开源项目”更重要的收获。

资料来源与边界

  1. B站《人生高性价比指南skill》:2026 年 10 月 11 日发布,约 171 秒。本文依据已取得的本地音轨转写与有限画面核验理解项目动机和演示结构;ASR 存在明显错词,不把自动字幕当作逐字真实引语,也未宣称全部 35 张候选画面经过完整人工语义审阅。
  2. yixinagqingyuan/life-guide-skill:主要研究对象,阅读 README、SKILL.md、retrieval.md、retrieval-evaluation.md、知识来源说明与全局配置脚本。所述代码参数、检索流程及测试数字来自作者公开文档;本文没有独立重跑作者的 20+3 问检索实验。
  3. eternity4719/HowToLiveBetter:上游公开指南。衍生项目固定使用 2026 年 10 月 10 日所取提交 bb25081b423091f9e22059aab6b4ed7343a2266d 的 34 章、676 条版本,不能把此计数与未来新增条目混淆。
  4. BM25F 原始研究 与 Reciprocal Rank Fusion 原始论文:说明字段检索与名次融合的已有研究基础。本文公式是帮助理解的方法表达,不意味着该衍生项目发明了这两种经典方法。
  5. Agent Skills 文件格式:说明技能说明、脚本和参考资源的关系。具体被动加载效果必须由 Codex 或其他宿主的真实发现、读取及行为检查证明。
  6. 本文三张 SVG 及模拟计算为原创教学材料,未复制视频画面、上游书籍章节或第三方论文插图。涉及医学、法律、医保和政策的具体决策应核对现行权威来源,不能直接使用历史快照给出个体诊断或法律结论。

评论

评论加载中……