1. 从“湖生万物”说起这个平台到底在解决什么问题第一次看到“云栖2026湖生万物助力 AI — 面向 Agent 的全模态数据平台”这个标题我脑子里蹦出来的第一个念头是终于有人把 Agent 的数据层单独拎出来讲了。过去两年大家聊 Agent 基本都在聊框架、聊编排、聊提示词工程但真正落地过 Agent 项目的人都知道最让人头疼的从来不是模型调用本身而是数据——Agent 要读的文档、要看的图、要听的音频、要调的结构化表散落在十几个系统里格式五花八门权限各管各的最后 Agent 要么“饿死”在数据荒里要么“撑死”在上下文窗口里。“湖生万物”这四个字其实点得很透。湖指的是数据湖生万物指的是这个平台不只是存数据而是让数据在 Agent 场景下“活”起来——能被检索、能被理解、能被编排、能被安全地消费。全模态则意味着它不挑食文本、图像、音频、视频、结构化记录统统接得住。而“面向 Agent”这个定语才是它和传统数据平台最大的分水岭传统数据平台是给人用的报表、看板、SQL 查询这个平台是给 Agent 用的它要解决的是 Agent 怎么发现数据、怎么理解数据语义、怎么在推理链路里按需取数、怎么保证取数过程不越权不泄露。适合谁来关注这个内容三类人。第一类是正在做 Agent 应用落地的开发者尤其是那些卡在“数据接不进来、接进来用不好”阶段的团队第二类是数据平台方向的工程师想看看面向 AI 消费场景的数据架构该怎么演进第三类是对 Agent 技术栈有整体认知需求的技术管理者需要判断这个方向值不值得投入。我会尽量把架构思路、关键取舍、实操中容易踩的坑都摊开讲不堆术语讲人话。2. 全模态数据平台的核心设计思路拆解2.1 为什么 Agent 需要“全模态”而不是“多模态”多模态和全模态一字之差但工程含义完全不同。多模态通常指模型能处理多种输入类型比如 GPT-4V 能看图、Whisper 能听音频。但全模态数据平台指的是数据的接入、存储、索引、检索、权限、生命周期管理全部按模态统一对待而不是文本走一套、图片走另一套、音频再走一套。我见过太多团队的做法是文本丢进向量库图片丢进对象存储音频丢进另一个桶然后 Agent 要用的时候靠一堆胶水代码去拼。这种“拼凑式多模态”在 demo 阶段能跑一旦数据量上来、模态交叉查询变多维护成本指数级上升。全模态平台的核心价值就在于用一套元数据体系管所有模态用一套权限模型控所有模态用一套检索接口服务所有模态。具体来说它需要做到几件事。第一统一的数据抽象层不管底层是 Parquet 文件、S3 对象、还是关系型数据库的行在上层都表现为“可被 Agent 消费的数据资产”。第二跨模态的语义索引文本有文本的 embedding图像有图像的 embedding但它们要能映射到同一个语义空间里这样 Agent 才能用一句自然语言同时召回相关文档和相关图片。第三模态感知的权限控制比如某张图只对特定角色可见那么 Agent 在检索时就必须被这个权限约束住不能因为“Agent 是系统级调用”就绕过。2.2 “湖”的定位不只是存储而是 Agent 的数据供给站传统数据湖的核心指标是存储成本、查询延迟、吞吐量。面向 Agent 的数据湖核心指标变成了数据可发现性、语义可理解性、消费安全性。可发现性指的是 Agent 怎么知道湖里有哪些数据。传统做法是靠人写文档、维护数据目录但 Agent 不会读你的 Confluence 页面。所以这个平台必须提供机器可读的数据目录每个数据资产要有结构化的描述它是什么模态、什么内容主题、什么更新频率、什么权限等级、适合什么场景消费。这些描述本身也要能被检索。语义可理解性指的是数据不只是“存着”还要有语义标注。一份 PDF 不只是 PDF它要被解析出章节结构、表格、关键实体一张图不只是像素它要有 caption、有 OCR 文本、有物体标签。这些语义层是 Agent 能“看懂”数据的前提。消费安全性则是最容易被忽视但最致命的一环。Agent 一旦接入数据湖它就有了一个“超级账号”的潜力。如果权限控制不到位一个提示词注入就可能让 Agent 把不该取的数据取出来。所以平台必须在数据访问层做细粒度控制而不是依赖 Agent 框架自己约束。2.3 面向 Agent 的接口设计从“人查数据”到“Agent 取数”传统数据平台给人用接口是 SQL、是 REST API、是 BI 工具。Agent 用数据的方式完全不同它是在推理链路中按需取数而且取数请求是自然语言驱动的、上下文相关的、可能多轮的。这意味着接口设计要满足几个条件。第一支持自然语言到数据查询的映射但不是简单的 text-to-SQL而是 text-to-任何模态的检索。第二支持渐进式取数Agent 可以先拿摘要觉得相关再拿全文再拿细节而不是一次性把整个文档塞进上下文。第三支持取数结果的模态自适应Agent 要文本就给文本要图就给图要结构化数据就给 JSON。我实测下来渐进式取数这个设计特别关键。很多 Agent 项目失败不是因为模型不行而是因为上下文被一次性塞爆了。一个 50 页的 PDF 直接丢进去模型注意力被稀释关键信息反而找不到。如果平台能提供“先给目录、再给章节、再给段落”的分层取数能力Agent 的推理质量会明显提升。3. 核心细节解析与实操要点3.1 数据接入层怎么让“万物”都能进湖数据接入是全模态平台的第一道坎。不同模态的数据接入方式差异很大但平台要做的不是为每种模态写一套独立流程而是抽象出统一的接入管道。文本类数据相对简单但要注意编码、分块策略、元数据抽取。分块不是越细越好我一般建议按语义边界分比如按章节、按段落而不是按固定 token 数硬切。硬切会导致语义断裂Agent 检索到半句话反而误导推理。图像类数据要处理的是格式归一化、缩略图生成、OCR 文本抽取、视觉 embedding 生成。这里有个坑很多团队只做 OCR不做视觉 embedding结果 Agent 只能用文字搜图搜不了“类似这张图的风格”这种需求。视觉 embedding 和文本 embedding 要同时建索引才能支持跨模态检索。音频类数据的关键是转写和分段。转写质量直接决定后续可用性建议用带时间戳的转写这样 Agent 取数时可以定位到具体时间段。分段则要按说话人、按话题切而不是按固定时长切。结构化数据接入相对成熟但要注意 schema 演进的兼容性。Agent 取数时如果遇到 schema 变更要有降级策略不能直接报错。实操心得接入层一定要做“接入即标注”数据进来的同时就把元数据、语义标签、权限标记一起写好。事后补标注的成本是事前的五到十倍而且容易漏。3.2 索引与检索层跨模态语义对齐怎么做索引层是全模态平台的技术核心。文本用向量索引图像用向量索引音频转写后用文本索引这些都好理解。难的是跨模态语义对齐怎么让“找一张关于日落的图”这句话能同时召回图片和描述日落的文档。常见做法是训练一个跨模态对齐模型把不同模态的 embedding 映射到同一空间。但训练成本高小团队玩不起。更务实的做法是用现成的多模态模型生成统一 embedding比如用 CLIP 类模型处理图文用文本模型处理纯文本然后在检索层做融合排序。融合排序的策略可以是加权的也可以是学习的初期用加权就够了。检索接口的设计要注意支持模态过滤、支持权限过滤、支持时间范围过滤、支持相似度阈值。Agent 取数时这些过滤条件往往比相似度本身更重要。比如 Agent 明确只要 2025 年之后的文档你返回一堆 2020 年的高相似度结果反而干扰推理。3.3 权限与安全层Agent 不能是“超级用户”这是我最想强调的部分。Agent 接入数据平台权限模型必须重新设计。传统 RBAC 是给人设计的人有角色角色有权限。但 Agent 是代表用户行事的它的权限应该是用户权限的子集而不是系统权限的超集。具体怎么做第一Agent 的每次取数请求都要携带用户身份上下文平台根据用户权限过滤数据。第二支持数据脱敏敏感字段在返回给 Agent 前就要脱敏而不是指望 Agent 自己处理。第三审计日志要记录 Agent 的每一次取数行为包括取数原因如果 Agent 能提供的话、取数结果、使用场景。注意千万不要给 Agent 配一个“万能账号”。我见过真实案例Agent 因为提示词注入把内部薪酬文档检索出来并总结给了不该看的用户。事后追责发现 Agent 用的是管理员权限。这个坑一次就够毁掉整个项目。3.4 数据生命周期管理湖不能变成“沼泽”数据湖最大的风险是变成数据沼泽——什么都往里扔没人清理没人维护最后没人敢用。面向 Agent 的数据平台生命周期管理要更主动。建议策略按数据热度分级高频被 Agent 消费的数据放高性能存储低频的放冷存储按数据新鲜度分级过期数据自动降级或归档按数据质量分级质量差的数据打标Agent 取数时可以过滤掉。还要有“数据退役”机制明确哪些数据不再维护、不再保证质量避免 Agent 取到过期信息。4. 实操过程与核心环节实现4.1 环境准备与基础组件选型假设我们要搭一个最小可用的全模态数据平台原型面向 Agent 提供取数能力。基础组件选型如下。存储层对象存储用 MinIO 或同类兼容 S3 协议的服务结构化数据用 PostgreSQL向量索引用 Milvus 或 Qdrant。选 Milvus 的理由是它支持多向量字段适合全模态场景选 Qdrant 的理由是部署简单小团队上手快。接入层用 Python 写接入管道文本用 LangChain 的文档加载器图像用 Pillow 做预处理音频用 Whisper 做转写。注意 Whisper 有大中小多个版本实测 medium 版本在中文场景下性价比最高large 版本精度高但推理慢小规模场景不划算。索引层文本 embedding 用 BGE 或同类中文友好的模型图像 embedding 用 CLIP 类模型。如果预算有限可以用 API 调用现成的 embedding 服务但要注意数据出域的安全问题。权限层用 Open Policy Agent 或同类策略引擎把权限规则写成策略文件Agent 取数时实时鉴权。4.2 数据接入管道的搭建步骤第一步定义统一的数据资产 schema。每个数据资产至少包含资产 ID、模态类型、原始来源、接入时间、内容摘要、语义标签、权限等级、质量评分。这个 schema 用 JSON Schema 定义接入时校验。第二步写模态适配器。每个模态一个适配器负责把原始数据转成平台内部格式。文本适配器做分块和元数据抽取图像适配器做格式转换、缩略图、OCR、视觉 embedding音频适配器做转写、分段、时间戳对齐。第三步接入即索引。数据写入存储的同时触发索引构建。这里要注意异步处理不要阻塞接入流程。用消息队列解耦接入完成发消息索引服务消费消息后建索引。第四步元数据注册。索引完成后把数据资产的元数据写入目录服务供 Agent 发现。# 简化的接入管道示例 def ingest_asset(raw_data, modality, metadata): # 1. 模态适配 adapted adapters[modality].process(raw_data) # 2. 存储 storage_id storage.save(adapted) # 3. 发索引消息 queue.publish({storage_id: storage_id, modality: modality}) # 4. 注册元数据 catalog.register({ id: storage_id, modality: modality, summary: adapted.summary, tags: metadata.get(tags, []), permission: metadata.get(permission, internal) }) return storage_id4.3 Agent 取数接口的实现与参数调优Agent 取数接口建议设计成三个层次发现接口、摘要接口、详情接口。发现接口接收自然语言查询返回匹配的数据资产列表每个资产只返回 ID、模态、摘要、相关度分数。这个接口的 top_k 建议设 10 到 20太少容易漏太多干扰 Agent 判断。摘要接口接收资产 ID返回该资产的摘要信息比如文档的目录、图像的低分辨率版本、音频的转写摘要。这个接口的目的是让 Agent 在不消耗大量上下文的情况下判断是否值得深入。详情接口接收资产 ID 和具体需求返回精确内容。比如 Agent 说“我要这份文档第三章关于财务的部分”接口就只返回那部分内容。参数调优方面相似度阈值建议设在 0.7 左右低于这个值的结果噪声太大。但阈值不是固定的要根据模态调整图像检索的阈值通常比文本低因为视觉相似度的分布更分散。4.4 权限校验的落地实现权限校验要嵌入到每个取数接口里而不是放在接口外面。具体做法接口接收请求时从请求上下文里提取用户身份然后调用策略引擎鉴权。def retrieve(query, user_context, modality_filterNone): # 1. 鉴权 allowed_assets policy.filter_allowed(user_context) # 2. 检索 results index.search(query, filter{asset_id: {$in: allowed_assets}}) # 3. 脱敏 results [desensitize(r, user_context) for r in results] # 4. 审计 audit.log(user_context, query, results) return results这里的关键是鉴权要在检索之前做而不是检索之后过滤。检索之后过滤的问题是Agent 可能通过相关度分数推断出被过滤数据的存在造成信息泄露。5. 常见问题与排查技巧实录5.1 检索结果不相关怎么办这是最高频的问题。排查思路按顺序来先看 embedding 模型是否适合当前语言和领域中文场景用英文模型效果通常很差再看分块策略是否合理分块太碎会导致语义不完整分块太大又会导致噪声多再看相似度阈值是否合适阈值太低会引入噪声太高会漏掉相关结果最后看是否有模态过滤条件写错比如把图像过滤成了文本。我踩过的一个坑是图像 embedding 和文本 embedding 用了不同维度的模型结果跨模态检索时维度对不上直接报错。后来统一了维度才解决。所以选模型时一定要确认输出维度一致。5.2 Agent 取数超时怎么优化Agent 取数超时通常有三个原因检索太慢、返回内容太大、权限校验太复杂。检索慢的优化给向量索引加 HNSW 参数调优或者加缓存层高频查询直接走缓存。返回内容大的优化强制走摘要接口详情接口限制返回大小。权限校验复杂的优化把权限规则预编译避免每次请求都重新解析策略文件。实操心得给取数接口设一个硬超时比如 3 秒超时后返回降级结果比如只返回摘要而不是让 Agent 一直等。Agent 的推理链路对延迟很敏感宁可给不完整的结果也不要卡住。5.3 数据更新后索引不同步怎么办这是分布式系统的经典问题。常见原因是索引构建是异步的数据更新后索引还没更新Agent 取到旧数据。解决方案第一给数据资产加版本号Agent 取数时可以指定版本第二索引构建完成后发通知更新目录服务里的版本信息第三对时效性要求高的数据走实时索引通道不走批量索引。排查时先确认消息队列有没有积压再看索引服务的消费日志最后看目录服务的版本更新记录。大部分情况下是消息队列积压导致的。5.4 常见问题速查表问题现象可能原因排查动作解决方向检索结果不相关embedding 模型不匹配检查模型语言和领域适配性换用领域适配模型跨模态检索报错向量维度不一致检查各模态 embedding 维度统一维度或加投影层取数超时检索慢或返回大看检索耗时和返回大小加缓存、走摘要接口索引不同步消息积压或消费失败看队列深度和消费日志扩容消费者、加告警权限校验失败策略文件错误或身份缺失看策略引擎日志和请求上下文修正策略、补全身份数据质量差接入时未做质量校验抽查接入数据质量加接入校验、打质量标签5.5 几个容易被忽视的避坑点第一个坑不要用 Agent 的对话历史当数据缓存。我见过团队为了省事把 Agent 取过的数据存在对话上下文里结果多轮对话后上下文爆炸而且数据更新后上下文里的还是旧数据。正确做法是每次取数都走平台接口平台层做缓存。第二个坑不要忽略模态之间的关联。一份报告可能同时有文本和图表如果接入时把它们当成两个独立资产Agent 取数时可能只取到文本漏掉图表里的关键信息。建议接入时就建立模态关联取数时支持关联召回。第三个坑不要给所有数据都建向量索引。向量索引有成本冷数据、低价值数据建索引不划算。建议按数据热度分级热数据建向量索引冷数据只建元数据索引需要时再按需建向量索引。第四个坑不要忽视 Agent 取数的可解释性。Agent 为什么取这条数据、取了之后怎么用的这些信息对调试和优化至关重要。建议在取数接口里要求 Agent 传入取数意图平台记录意图和结果的对应关系方便后续分析。6. 这个方向后续可以怎么扩展从我个人经验看全模态数据平台面向 Agent 的演进接下来会往几个方向走。一是取数意图的主动理解现在还是 Agent 主动来取未来平台可能根据 Agent 的任务上下文主动推送相关数据。二是数据质量的自动治理用模型自动检测数据质量问题并修复减少人工维护。三是跨平台的数据联邦Agent 不只从一个湖取数而是从多个湖联邦取数平台层做统一抽象。如果你正在做 Agent 项目我的建议是先把数据接入和权限控制做扎实这两块是地基地基不稳后面全是坑。检索和索引可以先用现成方案跑通了再优化。不要一上来就追求全模态先把文本模态做透再逐步加图像、音频。每加一个模态都要重新审视权限模型和检索策略不能简单复制。最后分享一个小技巧给 Agent 取数接口加一个“解释模式”返回结果时附带为什么选这条数据的理由比如“匹配关键词财务报告匹配模态文本相关度0.85”。这个信息对调试特别有用而且能让 Agent 在推理时更有依据。我实测下来加了解释模式后Agent 取数的准确率有明显提升因为它能根据理由判断是否真的相关。
企业数字化 ERP 产品动态
相关推荐
小米MiMo-V2.6终端大模型全链路技术解析 1. 项目概述:这不是又一个“开源模型”宣传稿,而是一次真实技术落地的复盘小米 MiMo-V2.6 系列不是贴着“国产大模型”标签蹭热度的演示项目,它是一套在真实终端侧、边缘侧、轻量化场景中跑通了推理—训练—部署全链路的模型体系。我从去年底… · 2026/11/5 1:47:07
OpenClaw推理优化:投机解码与级联架构详解 1. OpenClaw模型推理优化技术解析OpenClaw作为当前热门的智能体训练框架,其推理效率直接影响实际应用成本。在模型部署环节,开发者最关心的两个核心问题是:如何降低单次推理的耗时?如何减少计算资源的消耗?这就引出了我… · 2026/11/5 8:22:26
GPU利用率低?从数据供给到通信同步的六层瓶颈排查指南 1. 先搞清楚:GPU利用率低到底卡在哪一层1.1 为什么“利用率低”是个伪命题,得先拆开看很多人一看nvidia-smi里 GPU-Util 只有 30%,第一反应就是“显卡没吃满,肯定是代码写得烂”。这个判断太粗糙了。GPU 利用率这个指标本身是个“… · 2026/11/5 12:28:43
EasyU优启通PE维护盘实战指南:制作、启动与核心操作全解析 1. 为什么一个PE维护盘值得单独拿出来聊装系统、修引导、救数据、清病毒,这些活儿但凡干过几次的人都知道,真正决定效率的往往不是你手速多快,而是手边那套PE环境靠不靠谱。EasyU(圈内习惯叫优启通)就是在这个场景下被… · 2026/11/5 16:49:35
Rust原来很简单二:所有权系统 Part 2 核心篇 —— 所有权系统
本篇覆盖 第 6 ~ 10 章:所有权、借用与引用、生命周期、字符串与切片、内存模型。 ⚠️ 这是全书最重要的一篇。 把它吃透,Rust 从此“很简单”;跳过它,你会处处碰壁。请慢下来,动手敲每一段代码。 第 6 章 所有权:Rust 的第一性原理
6… · 2026/11/5 16:26:08
基于Hadoop+Spark的民宿智能推荐系统设计与实现 1. 项目概述:大数据时代的民宿智能推荐这个毕业设计项目融合了当前大数据领域最主流的技术栈,构建了一个完整的民宿推荐系统解决方案。作为一名长期从事大数据系统开发的工程师,我认为这个选题非常贴合实际应用场景——随着旅游业的复苏和共享… · 2026/11/5 14:59:25
ADS122U04IPWR+STM32F427ZI工业级温度测量信号链设计 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/5 14:10:41
UART接口24位ADC搭配RS485,解决远距离温度监控难题 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/5 14:10:41
UART接口24位ADC搭配PIC18F46K22的RTD与热电偶测温实践 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/5 14:10:41
双极步进电机控制实战: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/5 10:27:59
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/5 10:28:03
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/5 10:28:07
多智能体协作系统架构设计与实践优化 1. 多智能体协作系统的时代背景2017年Transformer架构的诞生彻底改变了人工智能的发展轨迹。当行业还沉浸在单一大模型带来的性能突破时,Anthropic的研究团队已经将目光投向了更前沿的领域——如何让多个智能体通过协作产生超越单体能力的系统智能。这就像交响乐团中… · 2026/11/5 0:00:39
大模型系统性入门实战指南:从原理到部署微调的全链路路线 提到大模型的系统性入门,我先说个结论:这事真不难,难的是资料太散、路线太多,今天这个框架明天那个工具,新人很容易在“收藏夹吃灰”和“教程看到一半放弃”之间反复横跳。市面上关于大模型的内容少说有几十万篇&#… · 2026/11/5 0:00:39
鸿蒙文件系统沙箱机制解析与开发实践 1. 鸿蒙文件系统沙箱机制深度解析作为一名从Android转向鸿蒙开发的工程师,我深刻体会到文件系统访问是迁移过程中最先遇到的"拦路虎"。在Android上运行良好的文件读写代码,在鸿蒙真机环境却频频出现文件写入后神秘消失或直接抛出权限拒绝错误的… · 2026/11/5 0:00:39
双极步进电机控制实战: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/5 10:27:59
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/5 10:28:03
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/5 10:28:07