EvolveBench:量化大模型时间感知能力的评测集

大模型的知识截止日期我们已经很熟悉了,但“截止日期之后的知识变化,模型到底能不能跟上”这个问题,却很少有一个正经工具去量化。我最近参与构建了一组专门用来评估大模型时间感知能力的评测集,代号叫EvolveBench,核心就是盯着一件事:当世界上的知识在持续演化时,模型能不能感知到“时间”这个变量,并在回答里正确地反映出来。

这几年给模型做评测,我越来越觉得传统的静态题库不够用。它们能测出模型“记住了什么”,但测不出模型“知不知道事情已经变了”。EvolveBench就是冲着这个缺口去的。如果你平时的工作涉及模型评估、知识更新、检索增强或者模型迭代验收,这篇文章应该能给你一点可以直接抄作业的思路——包括怎么设计时间感知题目、怎么标注数据、怎么算分,以及我在实测中踩过的那些坑。

1. 静态评测掩盖了什么:时间感知为何成为大模型短板

先讲一个我在实际测试里反复遇到的场景。某个模型的知识截止时间是两年前,我去问它一个近两年内发生过标准答案变化的问题。如果问题是新版本标准,它能答对;如果我明确告诉它“请用两年前的标准回答”,它还是给出新版本标准。更夸张的是,我把问题里直接注明年份,它依然按最新知识作答,等于说时间戳在它那里根本不起作用。

这类现象说明一个问题:很多模型只学会了“知识本身”,没学会“知识在时间轴上的位置”。传统评测基准几乎不覆盖这个维度——大家更关心常识问答、数学推理、代码生成、逻辑推断,很少关心同一个知识点在不同时间点的标准答案会不一样。但真实世界里,知识的“保质期”比我们想象中短得多:编程框架会发新版本,医学指南会更新,科学共识会被推翻,机构名称会变更,曾经正确的答案可能今天就是错的。

这带来一个很实际的风险。用户问“现状如何”时,模型给出的是训练数据里某个时点的快照,而不是“现在”的答案。如果模型能感知到时间,至少它会意识到“我的知识可能过时了”,或者在接收时间戳之后切换对应时期的知识。EvolveBench想做的,就是把这种能力量化出来,让大家在评测模型时多一个可比较的维度。

和传统的静态基准相比,EvolveBench有几个明显不同。静态基准的核心逻辑是“答案对错分明”,而时间感知评测的核心逻辑是“答案依赖时间坐标”。同一个问题,放在不同年份,标准答案可能是不同的,甚至答案的对错会发生反转。这要求评测数据本身必须携带时间标注,也要求评估方式必须能区分“模型记住了更新后的知识”和“模型理解了这个知识只在某个时间段内成立”。

所以我跟团队在设计EvolveBench时,定的第一条原则就是:不追求题目数量庞大,追求每个知识点都能做到“前后对照”。也就是说,每个知识事件至少配备两个时间版本的问题,让评测能够区分模型究竟是在背答案,还是在真正使用时间信息。

2. EvolveBench的五个评测维度与题目形态

EvolveBench的设计不是从一个笼统的“时间感知”概念出发,而是拆成五个相对独立的评测维度。每个维度考察的模型能力不同,失败的表现形式也不同。下面这张表是我自己的理解,也是我们实际使用的框架。

评测维度考察核心题目形态举例主要失败表现
版本感知同一实体或概念的新旧版本差异某工具当前推荐版本是什么?旧版本有什么限制?新老版本信息混用
事件时序多个事件之间的先后关系与持续时间A事件和B事件哪个先发生?某事件持续了多久?时序倒置、时长错误
知识演化旧知识在时间推进后的状态变化两年前的标准答案是什么?现在是否有更新?只认最新知识,丢失旧知识
趋势外推根据历史时间序列判断未来倾向按照近几年的变化趋势,下一步最可能发生什么?无法利用时间序列,回答重复当前知识
时间定位给定无时间戳的问题,判断其所属时期这条说法最可能出自哪一年?把任何说法都归属到训练截止时间附近

这里要说明一下,第五个维度“时间定位”跟传统的时间问答不太一样。时间问答是“某事件发生在哪一年”,而时间定位是给出一段陈述,让模型判断它是哪个时期的主流观点。这点很关键,因为它测试的是模型能不能从语言风格和事实内容反推出知识的年代坐标,本质上是在测模型对“知识演化轨迹”的表征能力。

我们给每个维度配套了具体的题目模板。以“版本感知”为例,一道典型的题目长这样:

问题:某软件框架在2023年发布了2.0版本,相对于1.0版本,它在API设计上最重要的变化是什么? 选项:A. 所有接口改为异步调用 B. 移除了对旧浏览器的支持 C. 引入了插件系统 D. 没有明显变化 标准答案:B 关联旧版问题:该框架1.0版本最被用户诟病的问题是什么?

这种成对设计是为了测出“模型是不是只记住了新版本的一堆介绍,而完全丢失了旧版本的核心特性”。很多模型能答对新版问题,但一问旧版就露馅,甚至会把新版才有的特性安到旧版头上。

事件时序维度我们用了不少“排序题”。给定三到四个事件,要求模型按时间先后排序。这类题目看起来简单,但非常考验模型对时间词汇和事件内在逻辑的理解。比如一个事件是“某标准草案发布”,另一个是“该标准正式生效”,两者时间差可能只有几个月,但模型经常把顺序搞反。

趋势外推维度是最有争议的一个维度,因为它涉及预测,而预测本身没有唯一答案。我们在设计时只保留了那些“趋势非常明确”的事件,比如某个指标连续五年增长,且没有明显的周期性波动。这样即使选项里有干扰项,标准答案也相对可辩护。

3. 构造评测数据的完整流程:从知识事件到双盲标注

EvolveBench的数据构造流程,我认为是整个项目中最耗时、也最决定评测质量的部分。这块要是做得糙,后面指标再精细都白搭。

第一步是收集“知识事件”。候选知识事件需要满足几个硬性条件:有权威来源、有明确的时间节点、新旧答案之间存在清晰差异、并且这种差异不是观点的微小偏移而是实质性变化。不符合条件的直接丢掉。比如某个编程语言发了一个小版本,修复了几个bug,这种不算知识事件,因为新旧差异不足以形成可判定的答案。

第二步是划分时间片。我们按自然年切分,覆盖周期大约从2015年到最近一年。每个知识事件都需要标注“旧知识有效期”和“新知识生效时间”。事件进入哪个时间片,取决于它对应的标准答案在那个时间片内是否成立。这一步很容易出错,因为有些知识变更不是一刀切式的。比如某标准在2022年发布修订版,但给了行业两年的过渡期,那2023年的正确答案到底是什么?这种灰色地带,我们一律不收录,只保留“答案切换时间基本明确”的事件。

第三步是生成题目。为了让模型不能靠简单的模式匹配过关,我们要求每个知识事件都生成多个视角的问题:直接问新知识、直接问旧知识、混合问演变原因、给出时间戳问对应状态。题目的表述要做一定程度的改写,避免标注者或模型看到题干就能猜到答案类型。

第四步是双盲标注。标注者先阅读知识事件说明书,然后在不被告知标准答案的情况下独立作答。如果两个标注者对同一题的答案不一致,这道题进入复核池。复核时再加一个资深审核人,三人讨论后决定保留、修改还是删除。这个流程我们后期统计下来,大概删掉了初始候选题量的两成左右,主要删的都是“新旧答案都能算对”的歧义题。

一个数据样例如下:

{ "id": "evb-2024-0037", "dimension": "version_awareness", "knowledge_event": "某开源数据库在2023年发布8.0版本,默认事务隔离级别从可重复读调整为读已提交。", "questions": [ { "text": "该数据库8.0版本的默认事务隔离级别是什么?", "timestamp": 2023, "correct": "读已提交", "distractors": ["可重复读", "串行化", "读未提交"] }, { "text": "该数据库7.0及更早版本的默认事务隔离级别是什么?", "timestamp": 2022, "correct": "可重复读", "distractors": ["读已提交", "串行化", "读未提交"] } ], "source": "官方发布公告", "verification": "双盲标注一致" }

很多人会忽略一个细节:题目里如果没有时间戳,模型默认应该答“最新状态”;如果给了时间戳,模型就应该切换对应的知识状态。我们在数据里对每个问题都明确标注了这个“默认行为”,评测时也会据此区分不同场景。

4. 指标怎么算才算数:时间准确率与混淆指数的读数方法

EvolveBench不是只出一个总分就完事,那样会把很多有价值的失败信息掩盖掉。我们设计了几个互补性比较强的指标,分别从不同角度反映模型的时间感知水平。

第一个指标是“时间准确率”。把所有问题按时间戳归属到不同时间片,分别计算每个时间片上的答题正确率。如果模型在近年知识上的准确率很高,在旧年知识上的准确率很低,那就说明它存在“旧知识被大量覆盖”的问题。反过来,如果模型在旧年知识上表现好,但对新知识更新不及时,那就说明它学习新信息的效率不够。

第二个指标是“更新采纳率”。它专门考察模型收到明确时间戳之后,能不能切换到对应版本的知识。算法很简单:对同一道知识事件题,分别给出两个时间戳版本,只要模型有一版答错就记为失败。例如某个事件的新知识在2023年出现,那么“问题+2022时间戳”应该答旧知识,“问题+2023时间戳”应该答新知识,两个都答对才算通过。

第三个指标是“旧知识保留率”。这个指标和更新采纳率是镜像关系。它只统计那些“旧知识仍然正确”的事件——注意,不是所有旧知识都会被新知识替代,有些知识是长期稳定的。如果模型在“长期稳定知识”上的准确率也很低,可能说明模型的更新机制过于激进,删掉了不该删的东西。

第四个指标我称之为“新旧混淆指数”。计算方式是:对每个成对知识事件,看模型把新知识用到旧时间戳上的次数,以及把旧知识用到新时间戳上的次数,取两者之和作为分子,除以该类问题的总次数。混淆指数越高,说明模型在时间维度上的边界越模糊。

举一个简化版的得分计算例子。假设对某模型测试了100道成对题,结果如下表:

指标数值说明
时间段一准确率82%2015-2019年
时间段二准确率65%2020-2022年
时间段三准确率41%最近两年
更新采纳率38%双时间戳都答对的占比
旧知识保留率71%长期稳定知识的答对占比
新旧混淆指数0.47每道成对题平均近一半出现混用

如果把总分平均一下,这个模型可能看起来有六成多以上的正确率,好像还能用。但一拆开看,最近两年知识准确率只有41%,更新采纳率只有38%,说明它“看起来还行”的现象完全是被早期大量知识撑起来的。这个反差就是EvolveBench希望评测用户能看到的。

评估代码我们做成了一批脚本。核心逻辑并不复杂,这里给出一个简化的伪代码框架:

def evaluate_temporal_awareness(questions, answers): results = { "time_accuracy": {}, "update_adoption": 0, "old_knowledge_retention": 0, "confusion_index": 0.0, } pair_count = 0 confusion_count = 0 for q in questions: if q["type"] == "single_timestamp": acc = correctness(q, answers[q["id"]]) results["time_accuracy"][q["year"]] = ( results["time_accuracy"].get(q["year"], 0) + acc ) elif q["type"] == "paired_timestamp": pair_count += 1 newer_correct = correctness(q["newer_question"], answers[q["newer_id"]]) older_correct = correctness(q["older_question"], answers[q["older_id"]]) if newer_correct and older_correct: results["update_adoption"] += 1 if newer_correct and not older_correct: confusion_count += 1 if older_correct and not newer_correct: confusion_count += 1 results["update_adoption"] /= max(pair_count, 1) results["confusion_index"] = confusion_count / (2 * max(pair_count, 1)) return results

评分脚本本身不复杂,真正复杂的是怎么读懂分数背后的原因。这也是下一节想聊的重点内容。

5. 实测里的四种典型翻车场景与归因实验设计

在把EvolveBench跑过多个模型之后,我总结了四种特别典型的“翻车模式”。如果你准备对自家模型做时间感知评测,可以拿这四个模式当对照线索,排查问题会快很多。

模式一:无视时间戳,默认输出最新知识。这是最普遍的现象。给模型一个明确的时间戳,例如“截止2019年”,它依然会用到训练数据中的新知识。这往往不是没有读懂时间戳,而是模型在训练时根本没有建立“时间条件生成”的能力,时间词对它来说只是个与答案无关的噪声标记。要验证这一点,可以做一个简单测试:把同一道题目的时间戳随机替换成几个不同的年份,如果模型的输出几乎不变,那基本可以断定时间戳没被利用。

模式二:张冠李戴,把新旧知识内容杂糅。有些模型知道“知识发生过变化”,但说不清具体的分界点。比如问某个技术标准在2022年的状态,模型可能会说“旧版本已废弃,新版本开始实施”,这个回答放在2022年中也许对,放在2022年初就不对。模型往往倾向于输出一个模糊的折中答案,因为它试图同时满足新旧两种知识表达,结果哪个时间片也不完全准确。

模式三:过度更新,把不该变的知识也改了。这一点很容易被忽略。有些知识事件属于“旧知识依然有效,只是新增了补充内容”,比如某个领域的经典理论并没过时,但多了一个新的应用场景。模型如果对“旧知识保留程度”把握不好,就会在新时间戳下把旧理论也一并否定了。我们在“旧知识保留率”这个指标上看到过很夸张的下跌,说明更新机制可能过于激进。

模式四:对训练截止时间之后的未知事件强行作答。模型面对出现在训练截止之后的知识事件,本来应该表现出不确定性,但它往往会一本正经地编造一个看起来合理的答案。在评测里,这一类错误对“时间准确率”的拖累很大,因为题目本身给出的知识事件确实是发生在现实中的,模型的训练数据里根本没有。如果模型能诚实地说“我无法回答”,反而不会影响更新采纳率的统计。

归因实验设计上,我的经验是把控制变量做细。不要只对比“有时间戳”和“没时间戳”,那样组间差异太模糊。更推荐做三组对比:第一组给真实时间戳,第二组给随机打乱的时间戳,第三组不给时间戳。通过三组的得分差异,能大致区分出模型是“靠时间戳做题”还是“靠额外的知识线索做题”。如果第二组和第三组得分差不多,都明显低于第一组,说明模型确实在读时间戳;如果三组得分差不多,说明时间戳根本没起作用,模型的强项纯靠别的手段在撑。

再补充一个特别有用的验尸方法:错误答案聚类。把模型所有答错的题按维度聚合,看是不是集中在某一种维度上。我实测过的多个模型里,大部分失败集中在“事件时序”和“时间定位”这两个维度,而不是“版本感知”。这其实反映了一个问题——许多模型擅长记忆“是什么”,但不擅长推理“什么时候、什么顺序”。知道了这一点,后续的微调方向就会明确很多。

6. 把EvolveBench移植到自己的评测流水线

最后聊一点落地经验。并不是每个团队都需要完整复刻EvolveBench,但把它的核心思想移植到自己的评测流水线里,是可行且收益比较高的。

第一步,建立一个小的“时间敏感知识事件库”,不追求大而全,先收集五十到一百个你自己业务领域内的知识变更事件。比如你是做开发工具的,就找编程语言版本变化、框架生态变化、推荐实践变化;你是做医疗健康相关的,就找权威指南的更新记录。关键是这些事件要有清楚的时间点,并且你在业务上确实会用到这些变化。这一步的好处是,评测数据跟真实业务强相关,得分高低直接反映模型在你这个场景里的可用性。

第二步,做一套“双时间戳”验证集。不用一开始就做几百题,可以先做二三十个成对问题,跑通评测流程。用上一节说的三组对比法,快速判断模型的软肋。如果模型在加时间戳之后得分显著提升,说明它具备时间感知的基础能力,只是平时调用得不够;如果加了时间戳也没变化,那就要考虑是不是需要通过数据增强或提示词干预来补课。

第三步,把时间感知分数纳入模型迭代的验收标准。我发现很多团队做模型更新的时候,只看“新版在标准集上有没有掉点”,完全不管新版模型对旧知识的保留情况。这样很容易出现一种情况:新版本模型整体能力上升,但在“旧知识保留率”上明显退步。短期看无伤大雅,长期看会造成一种“知识漂移”,导致模型对历史问题的回答越来越不可靠。所以在模型更新时同时看“更新采纳率”和“旧知识保留率”这一对指标,能有效防止单边优化。

第四步,持续维护评测集本身。这里想特别提醒一句:EvolveBench如果构建完之后就一直不动,它自身也会变成一套静态基准。因为现实世界的知识还在推陈出新,去年正确的新知识,今年可能又被替代了。所以评测集必须定期加入新事件,并且把事件库做成增量更新的形式。我们实际采用的办法是每个月拨出半天时间,集中收集当月业务相关的知识变更事件,筛选后合入评测集。这件事本身不复杂,难在坚持下去。

另外一个小经验是,评测时最好记录模型在每题上的置信度分数。实践中我们发现,时间感知能力较弱的模型,往往对错误答案也给出很高的置信度。这种“自信地犯错”在真实产品里特别危险,所以把置信度和准确率联合起来看,比单看准确率更能反映模型在这个维度上的投入程度。

最后再分享一个我自己的体会:一开始做EvolveBench的时候,我以为最大的难点是设计题目,后来发现题目其实还好,真正的重活是维护“时间坐标”——确保每道题的标准答案确实对应正确的时间片。这个过程非常磨人,但磨完之后你会对评测集的信心强很多。现在每次发布模型评测报告,我都会附带时间维度上的拆分结果,这件事已经变成团队例行流程的一部分。如果你也在做模型评估,与其纠结要不要上复杂框架,不如先拿二十道双时间戳题测试一下自己的模型。可能你会和我一样,发现一个之前完全没注意到的问题。

相关新闻

基于STM32的三相逆变器变频变压程序设计与实现

基于STM32的三相逆变器变频变压程序设计与实现

拿到一块三相逆变器控制板,直流母线电压已经稳定在540V,六个功率管全部就位,接下来的重头戏就是让程序把直流变成频率可调、电压跟得上频率的三相交流输出。很多人拿到这种板子第一件事是到处找能直接烧录的逆变程序,可一旦涉及变…

2026/10/22 12:26:56 阅读更多 →
Linux批量用户管理:从脚本到权限治理的工程实践

Linux批量用户管理:从脚本到权限治理的工程实践

1. 为什么“批量增删用户”不是脚本题,而是权限治理的起点在某高校实验室的运维日志里,我翻到一段被反复修改的 bash 脚本片段:for user in $(cat users.txt); do useradd -m $user; done。它看起来干净利落,但上线第三天就触发了…

2026/10/22 11:50:11 阅读更多 →
MyCoWork:可嵌入、可审计的行业智能体工作台底座

MyCoWork:可嵌入、可审计的行业智能体工作台底座

1. 这不是又一个“AI办公套件”,而是一套可拆解、可嵌入、可演进的业务智能体底座“开源了!给业务装上 AI 团队:MyCoWork 的多智能体与行业工作台”——这个标题里藏着三个被多数人忽略的关键动词:“装上”“多智能体”“工作台”…

2026/10/21 8:34:02 阅读更多 →

最新新闻

Electron桌面应用开发实战:从环境搭建到打包发布全流程

Electron桌面应用开发实战:从环境搭建到打包发布全流程

做前端这些年,我大部分时间都在跟浏览器标签页打交道,直到第一次把桌面应用跑起来,才发现原来自己一直被限制在地址栏和刷新按钮围起来的框框里。Electron这个词,最开始是在某段时间频繁出现在同事的讨论里,一个用HTML…

2026/10/22 10:18:38 阅读更多 →
滑盖智能锁T109深度解析:结构原理、安装调试与故障排查

滑盖智能锁T109深度解析:结构原理、安装调试与故障排查

简介:亚太天能T109滑盖智能锁产品说明书是一份PDF格式的官方技术文档,主要面向智能锁安装人员、终端用户及售后维护者,帮助快速掌握产品安装、配置与常见故障处理。全包仅1个PDF文件,大小4.37MB,内容结构清晰&#xff…

2026/10/22 11:01:53 阅读更多 →
PMSM弱磁控制原理与Simulink建模:高速AGV驱动系统设计指南

PMSM弱磁控制原理与Simulink建模:高速AGV驱动系统设计指南

上个月我在调试一台高速AGV的驱动系统,整车要求空载跑到8m/s,电机转速已经拉到额定点,驱动器的输出电压也顶到了母线电压极限附近。再往上踩速度指令,转速纹丝不动,三相电流反而开始震荡。那会儿我的第一反应就是&…

2026/10/22 9:44:47 阅读更多 →
C++核心知识点:从内存管理到STL的实战指南

C++核心知识点:从内存管理到STL的实战指南

C 这门语言我前前后后折腾了十几年,用它写过嵌入式驱动、做过游戏服务端,也搭过基础组件库。每次看到新人一头扎进"C 核心知识点"这个搜索词,我其实挺感慨的——这门语言的难点从来不是语法多,而是知识点之间的耦合太深…

2026/10/22 10:42:00 阅读更多 →
T109滑盖智能锁怎么装?安装调试与故障排查全攻略

T109滑盖智能锁怎么装?安装调试与故障排查全攻略

简介:亚太天能T109滑盖智能锁产品说明书以PDF格式发布,适合智能锁用户、安装人员与售后维修人员阅读。内容围绕T109系列指纹密码刷卡锁展开,先介绍前面板、后面板、锁体、机械钥匙、电池盒盖等部件名称与功能,再给出完整安装步骤&…

2026/10/22 10:40:08 阅读更多 →
LLM知识降熵:从信息垄断到理解权下放

LLM知识降熵:从信息垄断到理解权下放

你有没有过这种经历:翻开源码注释、论文摘要或者一份专业报告,每个字都认识,连在一起却像天书。想找人聊聊,身边要么没人懂,要么懂的懒得跟你解释。后来我试着把同一段内容丢给一个大语言模型,几秒钟之后&a…

2026/10/22 10:56:37 阅读更多 →

日新闻

周新闻

基于GMM的语音识别系统原理与MATLAB实现详解

基于GMM的语音识别系统原理与MATLAB实现详解

说到基于高斯混合模型(GMM)的语音识别系统,很多人第一反应就是一堆数学公式,觉得门槛很高。但如果你真的在MATLAB里把它落地跑通,会发现核心其实就是三件事:把声音变成特征向量,用GMM给每个类别…

2026/10/22 1:47:45 阅读更多 →
数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理这四个字听起来挺唬人,但落到具体操作上,无非就是让计算机按你的想法“摆弄”像素。我在一个模拟项目X里用了一套特别经典的基础处理流程:对图像做反白、改调色板、彩色转灰度,最后把像素数据导出成txt文件。单看每一…

2026/10/21 21:32:28 阅读更多 →
机器人大脑技术盘点:具身智能的感知、决策与数据闭环

机器人大脑技术盘点:具身智能的感知、决策与数据闭环

如果你的信息流最近也天天刷到“机器人大脑”这个词,你会发现一个很有意思的现象:每个人说的“大脑”根本不是同一个东西。有人指的是大语言模型,有人指的是运动控制系统,还有人指的是能理解物理世界的端到端模型。在2026年这个时…

2026/10/22 5:12:39 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/21 21:50:56 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/21 21:51:55 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/21 16:24:48 阅读更多 →