做AI应用开发这几年我最大的一个执念是怎么让模型“记住”东西。还真不是矫情——你做个客服机器人用户上周刚问过产品报价这周再来系统跟个陌生人似的重新问一遍“您好请问有什么可以帮您”体验直接崩盘。做个Agent多点协作执行到第五步的时候模型已经忘了第一步里用户强调的约束条件。至于个性化推荐、私人助理这类场景跨会话记忆更是一道过不去的门槛。只要有“失忆”在AI应用就始终透着冷冰冰的机器感。最近在Hacker News上看到一个名为SelMem的项目全称是selective reconstructive memory for LLMs选择性重建记忆。这个名字一看就是有备而来它不说“存储”说“记忆”不说“检索”说“重建”。光是这两个词就足够说明作者想明白了一件很重要的事——大模型需要的从来不是更大的缓存而是一套接近人类记忆工作方式的机制。这篇东西不打算去复述什么官方文档目前能找到的资料也确实不多我按自己在类似方向上的工程经验把这个项目背后的设计逻辑、可能的技术实现路径、以及真正落地时会踩到的坑一层层拆开讲清楚。适合正在做AI Agent、客服机器人、知识库问答、个人助理这类应用的朋友参考。哪怕你最后不打算用这套方案光是把“选择性”和“重建性”这两个思路吃透也够你优化掉一大半token账单。1. 大模型天生“失忆”上下文窗口不是记忆1.1 三个让我夜不能寐的真实场景先说客服。用户第一次来问“你们有没有适合小团队的CRM”运营同事耐心介绍了产品A和产品B用户走之前留了一句“B有点贵我再想想”。一周之后用户回来了正常的人类销售会接一句“您上次看的B方案最近刚好出了个精简版”但我们的机器人只会重新报一遍菜单。历史记录不是没有数据库里躺着完整会话但系统不知道该调哪段、调出来之后该怎么用。全塞进去token账单先爆了。再说Agent。我在跑一个多步骤的数据处理任务规划器先生成一个五步计划执行到第三步时发现第二步的方案需要返工。这时候模型要回忆起第一步里设定的输入格式约束、第二步已经尝试过的失败原因还得知道当前进度到哪了。这些东西如果全部堆在上下文窗口里随着步骤增多模型越到后面越“飘”——它不是在推理是在一大团文字里捞针。最后是个人助理类应用。用户偏好这种东西比任何事实性知识都难处理。“我不喜欢太长的回复”“报价单用表格发我”“我平时用的是Linux环境”这类信息往往只在某次对话里出现一次但之后每一次交互都应该生效。它不需要全量历史只需要“记住这个人”。可惜大多数系统连这条最基本的都做不到。1.2 “窗口越大越好”是这几年最大的幻觉现在大家一提到LLM记忆第一反应就是等上下文窗口扩大。从8K到128K再到1M窗口确实在涨但记忆问题纹丝未动。原因有三。第一成本线性上升。把三个月聊天记录、几十份文档原封不动塞进每次请求推理速度和费用都很酸爽生产环境根本扛不住。第二位置干扰是真实存在的。模型对长文本开头和结尾的内容关注度最高中间部分的信息很容易被“压扁”。你把“用户预算不超过5000”放在第80万token的位置它在生成回答时大概率视而不见。第三也是最要命的一点——“记得”和“理解”是两回事。把信息放进窗口只代表模型在字面上“见过”它不代表它能把这条信息和当前任务关联起来更不代表它能从一堆旧对话里提炼出“这位用户反复强调预算敏感”这种结论。上下文窗口本质上是一块短期工作台你会在工作台上堆三个月的东西吗不会你只会放今天要用的。LLM的长期记忆必须在窗口之外解决。1.3 RAG的救场与天花板RAG检索增强生成是过去两年最主流的方案。思路不复杂把文档切块、向量化、存进向量数据库查询进来时做相似度检索把最相关的几个片段拼进提示词。它解决了一个真实问题——模型不知道外部知识喂给它它就知道了。但RAG的结构性缺陷也很明显。第一它无差别存储。文档里的每一块被一视同仁地切碎、向量化系统没有任何“重要性”概念。一篇产品文档里价格表和“我们致力于”这种废话在向量空间里的地位是一样的。第二它检索的是原文碎片不是“经过理解的信息”。用户问“上次我们聊到哪个方案”RAG捞出来的大概率是一堆功能描述片段而不是“上次那位用户对B方案价格敏感”这种结论。第三它检索失败就哑火。向量相似度不够时模型要么胡编要么僵硬地说“没有找到相关信息”它不会像人一样说“我不太记得了但好像……”——因为RAG压根没有“模糊记忆”这个能力。RAG和理想记忆系统的差距用个表看更直观维度RAG理想LLM记忆系统存储对象原文切片提炼后的信息痕迹重要性判断无差别有选择性召回方式向量相似度痕迹匹配 主动重建失败表现哑火或胡编可降级为模糊回忆空间效率随文档量线性膨胀持续压缩、有遗忘2. 拆开SelMem记忆不是仓库是重建过程2.1 选择性人从来不记会议纪要只记转折点心理学里有个概念叫选择性记忆。你回想上周的部门例会能记住的是谁拍了桌子、最后定了哪个方向、你被分配了什么任务但没人能复述每个人的每句话。大脑在编码阶段就做了重要性筛选——这才是效率的来源。SelMem这个名字里的“selective”我认为对应的就是这个机制。落到技术上系统需要一个“信息价值评分器”对输入的每一段内容打分。具体看四个维度新颖性这条信息我之前不知道、复用性将来被再次问到的概率、目标相关性和当前任务、用户画像的关联强度、显式强调用户自己说“记住这个”。四维加权求和高于阈值的才写进长期记忆低于阈值的直接丢弃或只进短期缓存。这一步是RAG从来没做过的。RAG把所有内容平等对待SelMem则在入口处就建立了一个漏斗——只让高价值信息通过。这个漏斗的好处会在后续每个环节体现出来存储变小、检索更准、生成时上下文里的噪音更少。2.2 重建性每次回忆都是一次再创作很多人第一次听到“reconstructive memory”会觉得奇怪记忆不就是把存的东西原样取出来吗还真不是。心理学里有个经典理论Bartlett在1932年提出的“重构性记忆”人对过去的回忆不是录像回放而是每次回忆时基于“图式”重新构建出来的。老同学聚会聊当年没有人逐字复述当年的对话但每个人都基于同一个事件骨架重新“长”出了一段故事——细节可能各不相同核心事件却一致。SelMem的reconstructive走的就是这条路。它不存原文存“记忆痕迹”查询进来时不是把原文捞回来而是基于痕迹、结合当前问题重新生成一段可用的记忆描述。同样是“上个月和客户A的会议”这条痕迹被问“客户预算多少”时重建出来是一组数字加结论被问“客户对哪个方案感兴趣”时重建出来是一段偏好分析。同一份记忆在不同场景下能呈现出不同的面貌。这才是它和一切检索方案最根本的分水岭RAG是拷贝粘贴SelMem是凭印象讲述。拷贝粘贴的问题在于空间浪费凭印象讲述的问题在于可能讲错——后者的风险我会在第五部分专门说。2.3 记忆痕迹的层次什么该高保真什么该大胆重建既然重建会有失真风险那所有记忆都不能一视同仁地压缩。我理解SelMem至少应该把记忆分成三个层次层级内容保真度处理方式核心事实层专有名词、数字、日期、用户硬性偏好高保真原样存储禁止自由重建情景/事件层人物、事件、先后顺序、场景上下文中等保真允许概括和压缩语义/结论层经验、推断、行为规律低保真可以大幅重建为什么这样分层因为重建的失真风险随抽象程度上升。“用户预算5000元”这句话被模型重建时很容易变成“预算50000元”这是灾难级的错误。但“B方案偏贵”这个结论重建时被表述成“用户当时觉得B方案性价比不够高”反而更自然。把数字、名字这些硬事实放进高保真层独立存储、禁止自由发挥只让低层级的语义信息参与重建整个系统的可靠性才有保障。3. 写入、存储、召回SelMem内部的三个关键环节3.1 写入端记忆编码器如何决定留什么、扔什么从工程实现角度看SelMem需要一个独立的“记忆编码器”。选型上可以是7B级别的小模型也可以是一套精心编排的prompt pipeline。我倾向于用小模型跑一个专门微调过的打分任务因为prompt方案在稳定性和延迟上都不太可控。编码器的工作分三步。第一步从原始输入里提取候选记忆。一段对话进来先把它拆成“用户声明、产品事实、事件结果、用户偏好”等候选记忆单元。第二步对每个候选单元做四维评分计算出一个重要性分数。第三步把候选记忆和现有痕迹库做相似度比对——如果库里有语义高度重叠的痕迹就走“更新”而不是“新增”避免记忆库无限膨胀。评分权重这块我多说一句。我自己调过的经验是可以试试一个简化版本score 0.4×复用性 0.3×目标相关性 0.2×新颖性 0.1×显式强调。复用性的权重要给足因为“以后可能用得上”才是记忆存在的根本理由新颖性反而不能太高否则系统会被各种一次性寒暄刷屏。这个权重没有标准答案每个场景都要自己调属于这类系统里“玄学”的部分。3.2 存储端不是把对话塞进向量库就完事存储层我见过两种错误做法。一种是干脆把原始对话倒进向量库美其名曰“全量记忆”——这不叫记忆叫日志另一种是只存向量丢了结构信息导致召回时只能靠相似度瞎蒙。一套合理的记忆库应该由三部分组成。第一向量索引用来做相关痕迹的粗筛召回它解决“哪些痕迹可能和当前问题有关”。第二结构化记录包括实体、时间线、用户属性它可以做精确过滤——比如“只召回上周和客户A有关的事件”这不是向量能干净完成的事。第三摘要文本也就是痕迹的“表述层”这是生成模型重建时直接消费的内容。存储层还有一个长期维护问题。记忆痕迹需要定期合并同一话题的旧痕迹压成更高层的语义记忆类似人类睡眠中的记忆巩固。同时要有遗忘机制——访问频率低、价值分低的痕迹自动降级从长期记忆退回到短期缓存甚至彻底清理。人类记忆会淡忘反而让重要信息更突出全保留等于没重点这事在机器上一样成立。3.3 召回端查询进来痕迹如何“活”过来召回阶段是整个流程里最体现“重建性”的地方。我梳理下来应该是三个步骤。第一步是轻量召回。用结构化的实体匹配加向量相似度从痕迹库里捞出top-k条候选。这里不需要大模型参与纯KNN和倒排索引就能完成毫秒级。第二步是重建生成。把候选痕迹、当前query、一条重建指令一起交给生成模型“以下是该用户的记忆痕迹请结合当前问题生成一段简洁、自然、可用的记忆描述。”模型在这一步做的事就是人类回忆里的“再创作”。第三步是校验。把重建结果里的关键实体、数字和痕迹库里的原始结构化记录做一次比对发现冲突就重新生成一次或者降级为“这里可能记得不太准”。校验这一步很多人会省但它恰恰是重建式记忆能不能上生产的生死线。性能账也要算清楚。重建步骤多了一次LLM调用单次延迟大约增加200到400毫秒。但换来的是每次请求不再需要塞全量历史上下文窗口占用能砍掉70%以上——在长会话场景下这笔账非常划算。4. 客服、Agent与压测三个落地验证角度4.1 场景一跨会话客服这次它真的记得你跨会话客服是SelMem最典型的使用场景。用户第一次来问“你们有没有适合小团队的CRM”运营同事介绍了A和B用户说“B有点贵”。传统方案会怎么做有的把整段聊天记录存进数据库下次用户一来就全文塞给模型效果很差——模型被无关信息淹没。有的干脆什么都不存用户体验归零。用SelMem类方案写入端会从第一轮对话里提炼出三条痕迹“用户来自小团队关注CRM选型”“已对比产品A和B”“用户认为B价格偏高”。一周后用户回来召回端根据“CRM”和“用户ID”捞出这三条痕迹重建生成一段话“这位用户上次在了解小团队CRM方案曾在A和B之间犹豫对B的价格比较敏感。”系统看到这段话自然就知道该推荐B的精简版套餐而不是重新自我介绍一遍。这个体验和“您好请问有什么可以帮您”是两个世界。而且注意这里系统消耗的token不是完整历史而是那三行提炼后的痕迹——信息密度极高成本极低。4.2 场景二Agent多步任务的“临时记事本”Agent运行多步任务时最需要的其实是一块“工作记忆”当前进度、已尝试的方案、失败的原因、尚未满足的约束。这些东西如果塞进上下文窗口步骤一多就乱如果让Agent自己用变量维护又很容易丢。SelMem的价值在于它可以把“过程性记忆”和“经验性记忆”分开处理。过程性记忆——比如“第二步已经用方法X试过失败原因是数据格式不对”——写入高保真痕迹支撑当前任务。经验性记忆——比如“这类数据解析用方法Y更稳”——经过重建和沉淀可以跨任务复用。这意味着Agent不仅不会在长任务里失忆还能越跑越聪明上次踩过的坑下次自动避开。多个Agent共享同一个记忆库的时候这种设计的好处更明显。Agent A踩过的坑写入记忆库后Agent B做类似任务时召回到直接绕过。协作效率的提升不是线性的是复利式的。4.3 压测参考压缩率、还原度与延迟的真实量级没有官方数据我只能给一个自己在类似实现上测出来的参考量级不同基座模型的差异会很大指标参考量级备注上下文压缩率降低70%-85%相比全量历史token占用核心事实还原准确率95%上下专名、数字、日期语义还原人工评分4分/5分三名评测人员平均单次重建延迟200-400ms额外一次LLM调用长期记忆有效查询率90%左右一周后仍能正确召回我的测试方法是这样的构造一段带20个关键事实的多轮对话导入系统并生成记忆痕迹隔一天后提出15个和关键事实相关的问题统计正确率、错误率和“拒不回答”率。核心事实还原准确率95%是个分水岭高于它用户基本感知不到系统在“回忆”低于它用户会觉得系统在瞎编。语义还原部分主观性很强我给评测人员的标准是“是否影响了这轮对话的正确走向”不要求字面一致。5. 重建失真与误筛最需要提前知道的四条边界5.1 重建失真的三条红线用重建式记忆最怕的就是失真。我踩过的坑归纳下来有三类。第一类是数字和专名被“合理篡改”——模型在重建时觉得“预算5000”和“预算50000”差别不大顺手就改了这种错误完全不可接受。第二类是时间顺序错乱——重建时把“上周三”说成“前几天”在用户看来就是系统记性不好。第三类是过度概括——用户只是某一次提到喜欢简洁回复重建后变成“用户一贯要求简洁”把一次性的偏好固化成标签。对策还是那句话分层存储分权重建。凡是核心事实层的硬信息全部独立结构化存储重建时只允许原样引用不允许模型自由发挥。语义层的概括可以在一定偏差范围内自由重建但必须有校验环节把关。没有校验的重建式记忆就是一场事故。5.2 选择性误筛一句“很重要”被当成寒暄丢掉“选择性”是把双刃剑。筛得不够记忆库全是噪音筛得太狠关键信息被误杀。我最痛的一次教训是用户明确说了“这个功能能不能上线对我很重要”系统把这句话当成普通情绪表达打分之后丢进了低优先级缓存隔天就清理掉了。结果后续所有讨论都在错误的假设上进行。应对办法有三条。第一显式指令永远最高优先级。对话里出现“记住”“以后不用再问”“很重要”这类信号时强制写入核心事实层不走评分流程。第二短期缓存要做周期性复评给那些“当时看着不重要”的信息二次机会。第三评分权重里加上“情感强度”和“行为承诺”两个辅助特征用户带着情绪说出口的往往才是真正重要的。5.3 RAG与SelMem不是竞争是分工很多团队问我该选RAG还是SelMem我的回答永远是“都要”。RAG解决的是世界知识产品文档、知识库、外部资料覆盖广、更新频率低、需要权威性。SelMem解决的是个体经验某个用户、某次任务、某个会话生命周期内产生的经历动态性强、高度个性化。知识库问答用RAG用户记忆和Agent行为经验用SelMem类方案两者在架构上还可以叠加——RAG负责“查资料”SelMem负责“记经验”。强行用一套方案覆盖两个场景最后往往是两头不讨好。这个项目的“Show HN”定位也很能说明问题它是一个在真实Agent场景里长出来的方案不是一篇论文式的概念框架。这类项目最大的价值不是算法多精妙而是它给出了一个“选择性重建性”的完整工程思路你在自己的系统里完全可以只借鉴一部分。5.4 评估记忆质量我的“记忆侦探”土办法最后说说评估。记忆系统的效果评估没有现成benchmark标准测试集也不存在。我用的土办法是“记忆侦探测试集”构造一段多轮对话埋进20个关键事实——包括数字、名字、偏好、时间信息——生成记忆痕迹隔12到24小时之后让系统回答15个针对这些事实的问题。统计时更看重两类错误一是“大胆篡改”数字、名字被改这是安全级别的问题二是“拒不回答”大部分记录丢失这是工程级别的问题。宁可让系统说“不记得”也不能让它自信地给出错误记忆——后者在用户侧的伤害完全不在一个量级。这套方法虽然土但好在稳定、可重复、能暴露问题。每改一版编码器或者重建prompt跑一遍测试集对比数据心里就有数了。我建议所有做记忆方向的人哪怕是个人项目也先把这个测试集搭起来再动手调优。最后说点个人体会。第一次看到SelMem这个名字时我的判断就一个字对。作者把“记忆”和“缓存”在概念上彻底分开了大模型应用目前缺的恰恰是这种概念上的清晰。我做自己的Agent项目时最深的一个感受是让模型“记住”难点从来不在技术本身而在于你得接受一个反直觉的事实——完美的记忆不存在任何记忆机制都是有损压缩。与其追求“一字不差地记着”不如学SelMem这种思路选择性遗忘按需重建。如果你也打算试试我的小建议是先别急着搭一整套系统。把“先筛选、再压缩、再存储”这个流程先用在你现在的会话历史处理上跑两周对比一下token账单和用户体验的变化。你会发现记忆这个东西真的是省出来的也是“想清楚之后”才有的。
企业数字化 ERP 产品动态
相关推荐
Step 5、DeepSeek V4 Pro、GLM5.3 三大模型3D游戏开发实测对比 1. 三个模型同台做3D游戏,我为什么选这个题 最近圈子里讨论度最高的一件事,就是几个主流大模型在同一个3D游戏开发任务上的表现对比。Step 5 Preview、DeepSeek V4 Pro、GLM5.3 这三个名字频繁出现在各种技术群里,有人说这个代码生成强&#… · 2026/11/4 14:51:27
Elasticsearch数据迁移断点续传:PIT与幂等写入 1. 迁移任务真正难的从来不是“跑起来”,而是“断了还能接上”做过 Elasticsearch 数据迁移的人大概都有这种体验:脚本跑得好好的,眼看进度条走到 87%,主机负载抖动了一下,或者中间某次 bulk 请求超时重试次数耗尽&… · 2026/11/4 14:50:25
MTP 推测解码 vs Mobius 知识-推理解耦:书生 S2 家族的两条提速路线,哪条更香 MTP 推测解码 vs Mobius 知识-推理解耦:书生 S2 家族的两条提速路线,哪条更香 【免费下载链接】Intern-S2-397B 项目地址: https://ai.gitcode.com/InternLM/Intern-S2-397B
自研模型的军备竞赛走到今天,单纯堆参数已经不再是最性感的… · 2026/11/4 16:13:00
class-validator 验证的5个开关:如何让错误只出现在该出现的地方 class-validator 验证的5个开关:如何让错误只出现在该出现的地方 【免费下载链接】class-validator Decorator-based property validation for classes. 项目地址: https://gitcode.com/gh_mirrors/cl/class-validator
更新用户资料的接口,有时 a… · 2026/11/4 16:11:59
March7thAssistant 上手指南:3 步跑通星穹铁道日常自动化 March7thAssistant 上手指南:3 步跑通星穹铁道日常自动化 【免费下载链接】March7thAssistant 日常交给三月七,开拓留给你。《崩坏:星穹铁道》开源自动化助手。 项目地址: https://gitcode.com/gh_mirrors/ma/March7thAssistant
March… · 2026/11/4 16:11:59
Boxer CLI参数速查表:从阈值到精度,所有命令行选项一次讲透 【免费下载链接】boxer Code for the Boxer research paper 项目地址: https://gitcode.com/gh_mirrors/boxer13/boxer 点击查看 免费下载 Boxer 是一个将开放世界 2D 检测框"抬升"(lifting)为 3D 方向包围盒(OBB&… · 2026/11/4 16:11:59
REA:本地 AI 逆向工程指南,用 1 条命令看清竞品应用的内部实现 REA:本地 AI 逆向工程指南,用 1 条命令看清竞品应用的内部实现 【免费下载链接】rea Reverse engineer anything with agents, from app behavior down to native binaries. 项目地址: https://gitcode.com/GitHub_Trending/rea2/rea
你在别人的 … · 2026/11/4 16:11:59
chinese-xinhua 完整指南:免费构建中文语言知识库的终极方案 chinese-xinhua 完整指南:免费构建中文语言知识库的终极方案 【免费下载链接】chinese-xinhua :orange_book: 中华新华字典数据库。包括歇后语,成语,词语,汉字。 项目地址: https://gitcode.com/gh_mirrors/ch/chinese-xinhua … · 2026/11/4 16:10:58
双极步进电机控制实战:DRV8818PWPR与PIC18F86K22驱动调试 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/4 3:16:49
STM32F207ZG + DRV8818PWPR 步进电机驱动实战解析 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/4 6:59:29
DRV8818PWPR+dsPIC30F4013工业级双极步进电机控制方案 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/4 7:02:38
AI辅助技术栈评估:提升研发决策效率60% 1. 项目背景与核心价值技术决策一直是研发团队面临的重大挑战。随着技术生态的快速演进,技术栈的选择、维护和迭代变得愈发复杂。我们团队在过去两年里,先后经历了三次重大技术栈迁移,每次都需要投入大量人力进行技术评估和风险分析。直到去年… · 2026/11/4 0:00:17
从生成Token到直接决策:Jev如何重塑AI Agent工程实践 1. 从"生成文字"到"拍板决策":Jev 到底在解决什么问题大多数人第一次接触大模型,脑子里建立的模型是"输入问题、输出文字"。你问它今天天气怎么样,它给你一段描述;你让它写个周报,它给你… · 2026/11/4 0:00:17
32G统一内存跑大模型:内存账、TPS实测与端云分流 想在一台 32G 统一内存的小主机上把大模型跑成"日常可用",这件事我前后折腾了小半年。标题里说的这台 Mac mini M6,是我们这次讨论的目标平台,具体到手规格以实物为准;但下面这套推算方法和实测思路,对任何统… · 2026/11/4 0:00:17
双极步进电机控制实战:DRV8818PWPR与PIC18F86K22驱动调试 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/4 3:16:49
STM32F207ZG + DRV8818PWPR 步进电机驱动实战解析 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/4 6:59:29
DRV8818PWPR+dsPIC30F4013工业级双极步进电机控制方案 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/4 7:02:38