金融知识图谱实战:从图模型构建到多跳关系查询与反欺诈应用
简介知识图谱技术在金融领域的应用是近年金融科技发展的热点话题。这份PDF系统梳理了知识图谱从2010年学术萌芽、2016年引发广泛关注到FinKG等行业会议推动落地的发展脉络并结合信用监控、数据集成、风控、财务建模、自动化报告及公告研报数据提取等真实案例说明其如何提升金融机构的数据整合与决策效率内容还涉及创投类数据库、公众公司基本面与行情数据、舆情和企业信息等应用方向。面向金融分析师、AI产品经理、数据挖掘和知识图谱学习者也适合关注智能投顾、智能风控、产业链分析等方向的从业者作为入门参考。资源为单个PDF文件约10.86MB共1个文件可按章节直接阅读。目前已有369人学习浏览覆盖概念、发展历程、产业应用与趋势展望可帮助读者快速建立金融知识图谱应用的全景认知。1. 知识图谱在金融领域的分析与应用先看懂这张图再谈落地在反欺诈、企业尽调、关联交易识别这类场景里用传统关系型数据库做多跳关系分析往往会发现单表 JOIN 的复杂度根本撑不住——你查的是「A 通过 B 间接持股 CC 又和 D 有资金往来」这种跨三层的关系SQL 写出来长不说跑起来更是煎熬。知识图谱的核心价值就是把实体之间的关系显式建模让「多跳查询」从几十行 JOIN 变成一条图查询语句。这份《知识图谱在金融领域的分析与应用》讲的就是这条路径先定义实体和关系再构建图谱最后把风控、尽调、反欺诈的分析逻辑落到查询上。适合三类人做风控建模的数据工程师、需要理解图模型的业务分析师、以及想评估图谱投入产出的技术负责人。先给个反直觉的结论知识图谱在金融场景里最大的价值不是可视化大屏而是「多跳关系查询」的能力本身。2. 金融知识图谱的构成实体、关系、属性与四类常用图模式2.1 实体与关系的粒度选择为什么金融场景要先定边界很多团队搭建金融知识图谱一上来就想把所有数据都塞进去结果图变得无比庞杂查询性能直线下降业务方也看不懂。我一般建议先想清楚「实体」和「关系」的粒度。在金融领域常见的实体类型无非是自然人、企业、产品信贷产品、理财产品、账户、交易、合同、担保物。这些实体可以放在一张图里也可以拆分到不同子图关键在于关系。关系是知识图谱的灵魂常见的关系有持股、投资、担保、借贷、交易、任职、亲属、控制。每个关系都有方向、属性和权重。方向在金融场景里特别重要——「A 控股 B」和「A 被 B 控股」是两个完全不同的风险信号。属性方面需要记录的维度包括时间关系生效时间、失效时间、金额、占比、频次。这些属性决定了后续分析时的过滤条件比如「只看最近 90 天内的交易关系」。从业务边界来说我建议把图谱拆成几个子图企业股权关系子图、个人与企业任职关系子图、资金交易子图、担保关系子图。子图之间通过「企业」「个人」这类共享实体做连接。这样做的好处是建图时可以分模块迭代查询时也可以把搜索范围限定在某个子图里避免全图扫描。2.2 金融图谱里最常用的四类图模式在金融知识图谱的实际落地中有四类图模式出现频率最高几乎可以作为起步模板。第一类是企业股权穿透图。以「企业」和「自然人」为节点「持股」为关系边边的属性是持股比例。做穿透分析时可以一层层向上找实际控制人或者向下找关联企业。这类图建模简单但查询价值的密度很高银行对公尽调、同业授信都会用到。第二类是资金交易图。节点是「银行账户」或「交易对手」边是「转账」或「交易」边的属性包括金额、时间戳、交易渠道。这类图是洗钱识别、异常交易监控的核心载体核心分析手法是「环检测」和「异常高频交易」。第三类是担保圈网络图。节点是「企业」边是「担保关系」形成的是一种多企业互保结构。这类图谱在信贷风险预警里非常关键因为担保圈一旦出现局部违约风险会沿着担保关系链式传导。分析重点包括「最大连通子图」「环状担保结构」「集中度」。第四类是关联方关系图。以「自然人」和「企业」为节点整合任职、亲属、投资、交易等多种关系。这类图常用在反欺诈的关联团伙识别中核心分析方法是「社群发现」——用 Louvain 类算法把用户分成一个个社群社群内部往往隐藏着团伙欺诈特征。理解了这四类图模式再回头看《知识图谱在金融领域的分析与应用》里的分析框架就会清楚很多——所谓「分析」绝大多数跑不脱「找路径」「找环」「找社群」「算中心度」这几类算法。3. 从原始金融数据到图模型抽取、对齐与入库的落地步骤3.1 数据抽取与实体对齐从交易流水和工商数据到三元组建图谱的第一步不是导入图数据库而是从原始数据里抽取「实体—关系—实体」三元组。以最常见的场景为例手头有两类数据源一是银行内部的对公客户信息和交易流水二是外部采购的工商数据和司法涉诉数据。数据抽取我用 Python 做预处理。假设有一份模拟交易流水表transactions.csv字段包括from_account、to_account、amount、tx_time。我需要把它转成图谱需要的 CSV 格式节点文件一份、关系文件一份。如下是一段常见做法import pandas as pd # 读取原始交易流水 trans pd.read_csv(transactions.csv, parse_dates[tx_time]) # 节点表账户维度 accounts set(trans[from_account]) | set(trans[to_account]) node_df pd.DataFrame({account_id: list(accounts)}) node_df[node_type] ACCOUNT node_df.to_csv(nodes_accounts.csv, indexFalse) # 关系表转账关系 rel_df trans[[from_account, to_account, amount, tx_time]].copy() rel_df.columns [source, target, amount, tx_time] rel_df[rel_type] TRANSFER # 过滤掉金额过小的噪音交易 rel_df rel_df[rel_df[amount] 1000] rel_df.to_csv(rels_transfer.csv, indexFalse) print(node_df.shape, rel_df.shape)这段代码的逻辑是先收集所有出现过的账户作为节点再抽取转入转出关系作为边。向外写出的节点文件与关系文件直接对应 Neo4j 的批量导入格式。参数说明amount 1000这个阈值按业务场景调整——如果做反欺诈小额高频才是重点不建议一刀切过滤如果做对公关联分析小额噪音反而会影响图结构。实体对齐这一步容易被低估同一家企业在不同数据源里可能叫「某某科技有限公司」和「某某科技公司」两者要归一成一个实体通常的解法是用统一社会信用代码作为唯一键否则图里会出现重复节点导致查询结果虚高。3.2 图数据库写入Neo4j 批量导入与关键参数设置抽取完成之后就到了入库动作。金融团队最常用的图数据库是 Neo4j原因在于 Cypher 查询语言在关系遍历上的表达能力足够强而且生态成熟、工具链齐全。数据量在千万级以内时单机版 Neo4j 完全可以扛住超过这个量级再考虑分布式图数据库。批量导入我推荐用 Cypher 的LOAD CSV而不是逐条走驱动写入后者的性能瓶颈在事务提交频率上。下面的导入语句是常见的初始化写法// 导入账户节点 LOAD CSV WITH HEADERS FROM file:///nodes_accounts.csv AS row CREATE (a:Account {id: row.account_id, node_type: row.node_type}); // 导入转账关系使用 MERGE 避免重复边 LOAD CSV WITH HEADERS FROM file:///rels_transfer.csv AS row MATCH (from:Account {id: row.source}) MATCH (to:Account {id: row.target}) MERGE (from)-[r:TRANSFER {amount: toFloat(row.amount), tx_time: row.tx_time}]-(to);这段 Cypher 的逻辑分两步先用CREATE无条件写入节点再用MATCH找到边的两端节点最后MERGE建立关系。参数说明MERGE和CREATE的差别在于——MERGE会检查关系是否已经存在避免重复导入造成的关系膨胀toFloat()显式转型保证金额字段被识别为数值而不是字符串。有一个实践中容易忽略的细节LOAD CSV的默认文件路径在 Neo4j 的import目录下放错位置会直接报找不到文件需要把 CSV 文件放到与服务端dbms.directories.import对应的目录下。导入完成后建议立即做一次基数检查统计节点数和关系数并抽查几个已知关系的查询确保没有实体缺失。这里的坑在于如果某个账户只出现在交易流水的收款方但未出现在付款方节点文件里的accounts集合设计能覆盖。用UNION做集合收集时漏掉某一方是新手最容易翻车的地方。4. 把分析跑起来关联风险发现与尽调场景的查询实现4.1 反欺诈场景的图谱查询环形交易与路径发现图谱建好后重点来了——如何在金融场景里把「分析」从 PPT 变成实际可跑的查询。以反欺诈为例团伙欺诈有一个常见特征资金在几个账户之间来回转圈形成闭环交易。传统 SQL 需要自连接好几次才能找出长度为 3 的环而图查询可以直接用定长路径加环判断。在 Neo4j 里检测长度为 3 的转账环路的常见写法如下// 找出 A - B - C - A 的三方转账闭环 MATCH p (a:Account)-[:TRANSFER]-(b:Account)-[:TRANSFER]-(c:Account)-[:TRANSFER]-(a) WHERE a.id b.id AND b.id c.id WITH p, [n IN nodes(p) | n.id] AS account_path, reduce(s 0.0, r IN relationships(p) | s r.amount) AS total_amount WHERE total_amount 50000 RETURN account_path, total_amount ORDER BY total_amount DESC LIMIT 50这段查询的逻辑是声明一个长度为 3 的路径模式起点与终点都是同一个账户a从而形成闭环。a.id b.id AND b.id c.id这一组条件用来去重——如果不加这个过滤同一个环会被重复枚举 3 次。参数说明total_amount 50000是人工设定的阈值用于过滤掉小额的自转账噪音在实际生产中这个阈值一般结合历史欺诈样本的金额分布去定而不是拍脑袋。查询结果中的account_path字段就是整个环路的账户 ID 序列可以直接推送进人工复核队列。4.2 尽调场景中的多跳关联与风险传导分析尽调分析——尤其是判断两家企业是否通过隐性关联方产生利益输送——通常会走到多跳关联查询。这类查询最典型的写法是「可变长度路径」加「中间节点类型约束」。// 找出两个自然人之间的 1~4 跳关联路径 MATCH p (p1:Person {id: P001})-[:HOLDS|DIRECTORS|GUARANTEE*1..4]-(p2:Person {id: P002}) WHERE p1 p2 RETURN p, length(p) AS hop_count ORDER BY hop_count ASC这里*1..4是可变长度模式表示关系可以穿透 1 到 4 跳。参数说明关系类型列表HOLDS|DIRECTORS|GUARANTEE限定了只走这三类关系避免「交易关系」把路径带偏——尽调里如果你把所有关系都放开查出来的路径往往到处都是反而看不出重点。length(p)返回跳数优先看跳数少的路径因为跳数越多关联的置信度越低。我常用的进一步分析是对返回的每条路径统计路径上的中间节点和关系类型分布。比如两条路径跳数相同但一条穿透了「担保关系」另一条只穿透了「任职关系」前者在信贷风险视角下的权重更高因为担保意味着法律责任。这种权重化处理在业务落地阶段很有价值直接影响到后续的评分卡模型。4.3 社群发现团伙识别的基本操作除了路径和环团伙识别还需要「社群发现」。Neo4j 的 GDSGraph Data Science库提供了 Louvain 算法可以直接跑社团检测。常用写法分两步先建投影图再跑算法。// 第一步在内存中创建图投影 CALL gds.graph.project(fraud_graph, Account, TRANSFER, {relationshipProperties: amount}); // 第二步执行 Louvain 社群发现 CALL gds.louvain.stream(fraud_graph, {relationshipWeightProperty: amount}) YIELD nodeId, communityId RETURN gds.util.asNode(nodeId).id AS account_id, communityId ORDER BY communityIdgds.graph.project的参数含义是图的名称叫fraud_graph节点取Account标签关系取TRANSFER类型并把关系上的amount属性作为权重加载。louvain.stream中relationshipWeightProperty指定金额作为权重——金额越大两个账户的关联强度越高。结果里communityId相同的账户属于同一个社群这就是团伙候选集。需要注意Louvain 算法对随机种子敏感不同批次跑出来的社群边界会有细微差异。实际生产里我会把社群结果写回 Neo4j并用多个随机种子跑多次取交集作为高置信度团伙避免把偶发聚类当成必然信号。这一步做完整个「分析」环节就已经从查询语句变成了可交付的业务结果。5. 金融图谱落地避坑清单五类高频问题与排查思路5.1 实体对齐不彻底导致「同人不同节点」现象查询「某公司的关联方」时漏掉了大量本应关联上的企业打开图一看同一家企业出现了两个节点名称一个带「有限公司」一个不带。原因不同数据源写入时未按统一社会信用代码对齐图数据库里被当成两个实体。解决入库之前把外部数据的工商主体字段统一映射到社会信用代码并以代码作为实体唯一 ID。写入节点创建唯一性约束避免后续再出现重复节点。5.2 关系方向定义混乱导致分析结果失真现象查询「企业之间的持股关系」时发现方向的语义与业务理解不一致本该是「A 持股 B」图里却存成了「B 持股 A」。原因图建模阶段没有把方向的业务含义定义清楚——「持股」关系的方向应该始终从股东方指向被投资方存数据时如果把 CSV 的 source 和 target 列顺序接反整张图的关系就全反了。解决建图脚本里显式定义关系方向并在入库后立即用抽样查询验证 3~5 条已知关系的方向而不是等分析阶段才暴露。5.3 全图扫描导致查询卡死或超时现象一条在测试环境跑得好好的路径查询上线后发现经常超时日志里显示扫描了上亿个节点。原因查询条件里没有指定起点实体的索引属性图数据库被迫从所有节点开始匹配。解决为高频查询的过滤字段如Account.id、Person.id创建索引限制起点数量同时用PROFILE查看执行计划确认查询走的是索引查找而不是全表扫描。5.4 业务方不信任图谱结果图谱变成「大屏摆设」现象图谱平台搭好了、也导入了数据但风控团队在审批时还是主要看 Excel查询结果只是截图展示一下。原因业务侧缺少「图谱结果与业务结论之间的解释链路」——他们看到一条关联路径但不知道这个路径意味着什么风险、置信度多少、依据是什么。解决在查询结果里输出风险解释摘要比如「A 与 B 在 90 天内有 5 笔转账合计 120 万元且双方共享同一法定代表人」让业务人员拿到结果直接能用。6. 从查询到风控策略验证指标、效果评估与进阶技巧图谱查询能做出来是一回事能让业务方持续用起来是另一回事。我习惯在每个分析场景上线前建立一张效果评估表至少包含四个指标准确率查询结果中有问题的实体占命中总数的比例、覆盖率图谱中识别出的问题实体占已知黑样本的比例、平均响应时间、人工复核通过率。其中人工复核通过率最真实——一线风控人员确认需要进一步调查的图谱结果比例这个数字低于 20% 就说明查询逻辑定得太宽了需要收紧关系类型的范围或提高阈值条件。进阶方向上有两个技巧值得提一是把时间窗口属性融入到图模式里。比如资金交易关系加上时间戳后可以用WHERE r.tx_time datetime(2024-01-01)过滤出「近期发生的交易」避免历史陈旧关系干扰判断。二是把图查询结果特征化后接入风控规则引擎——将路径长度、环的数量、社群规模、中心度指标作为特征与传统的规则评分叠加使用。这样知识图谱不再是孤立的分析工具而是进入了风控决策的主链路。我自己踩过不少坑最初做图谱项目时花了大量时间在「可视化美化」上后来才明白业务方真正关心的是「这一条路径为什么触发预警」。从那以后我的习惯是每写一个查询都同时写一段人话解释逻辑。这段附加解释虽然不直接影响算法效果却决定了业务人员愿不愿意每天打开这个系统。希望这条经验也能帮你在知识图谱金融场景落地的路上少绕弯把分析做扎实把应用做长效。本文还有配套的精品资源点击获取

相关新闻

Slack自主AI代理实战:从被动问答到主动处理团队工作流

Slack自主AI代理实战:从被动问答到主动处理团队工作流

不少人应该有过这种体验:团队里的 Slack 群聊永远是红点轰炸现场,问个问题没人理、催个进度半天没回音、跨部门协作更是像在玩拼图。大多数团队部署的 AI 机器人,本质是个“问答盒子”,你问一句它答一句,你不问它绝不开…

2026/10/10 8:55:31 阅读更多 →
Web应用架构深度解析:从三层架构到微服务的演进与实践

Web应用架构深度解析:从三层架构到微服务的演进与实践

这套东西其实是从上世纪90年代一路演进过来的,经历了CGI、Servlet、JSP、Struts、Spring MVC、前后端分离、微服务这么几个大阶段,但不管壳怎么换,里面的核心骨架始终没变——就是表现层、业务层、数据层的三层职责切分,以及在Web…

2026/10/10 8:55:31 阅读更多 →
办公用品直售推荐系统全栈实战:SpringBoot+Vue前后端分离设计

办公用品直售推荐系统全栈实战:SpringBoot+Vue前后端分离设计

1. 项目概述1.1 核心需求解析办公用品直售系统这个方向其实一直很有搞头。大多数企业采购日常办公用品的流程还很原始——行政翻商品目录、人工比价、邮件审批、月底对账,效率低不说,采购记录还不透明。平时咱们做管理系统做得多了,这次我决定…

2026/10/10 8:55:30 阅读更多 →

最新新闻

Java+Selenium驱动Chrome 118.0.5958.0实战指南

Java+Selenium驱动Chrome 118.0.5958.0实战指南

简介:本资源是一套面向Java开发者与自动化测试初学者的Selenium爬虫实战教学包,聚焦浏览器自动化采集场景,解决Chrome版本与驱动器严格匹配难、环境配置易出错、代码调试无参照等常见痛点。资源共56个文件,涵盖9个核心Java源码、9…

2026/10/10 10:20:06 阅读更多 →
边缘AI视频分析网关16路部署实战:从算力选型到场景落地全记录

边缘AI视频分析网关16路部署实战:从算力选型到场景落地全记录

做边缘AI视频分析这行有几年了,手头经手的盒子少说也有几百台。前两天刚给一个施工现场部署完一台领嵌的16路边缘AI云盒子,趁着热乎劲儿,把从选型到落地的完整过程梳理一遍。这玩意儿现在在工地、社区、校园、加油站这几个场景里用得越来越多…

2026/10/10 10:20:05 阅读更多 →
PLC能ping通却下载失败?MTU排查顺序与远程维护实战经验

PLC能ping通却下载失败?MTU排查顺序与远程维护实战经验

做PLC远程维护的人,几乎都遇到过这种“半通不通”的怪问题:设备在本地调试时一切正常,一旦放到远程链路里,PLC明明能ping通,组态软件却下载程序失败,要么提示“目标站无响应”,要么卡在进度条某…

2026/10/10 10:20:05 阅读更多 →
3亿token批量生成实战:大模型自动化管线与PV创意项目拆解

3亿token批量生成实战:大模型自动化管线与PV创意项目拆解

1. 从“3亿token”这个数字说起:它到底意味着什么第一次看到“花费3亿token”这个说法,我的反应和大多数人一样——这数字听着唬人,但到底是个什么量级?如果你平时只是拿大模型聊聊天、写写周报,可能对token没什么概念…

2026/10/10 10:20:05 阅读更多 →
跨平台存储适配实战:从设计到排查的完整指南

跨平台存储适配实战:从设计到排查的完整指南

1. 跨平台存储适配为什么总被低估1.1 一个真实到让人头疼的场景去年我帮一个朋友处理过一个项目,他们做了一款本地优先的笔记工具,在桌面端跑得挺稳,用户量也慢慢起来了。后来团队决定做移动端,想着“逻辑都是现成的,U…

2026/10/10 10:20:05 阅读更多 →
MySQL数值函数详解:ROUND、TRUNCATE、CEIL、FLOOR与精度避坑指南

MySQL数值函数详解:ROUND、TRUNCATE、CEIL、FLOOR与精度避坑指南

写SQL的人,没有一天能绕开数值处理。上一篇文章把字符串函数过了一遍,这篇轮到数值函数。你别觉得数值函数就是加减乘除加个四舍五入,真到用的时候,round、truncate、ceil、floor这几个函数到底谁是谁,金额对不上账、评…

2026/10/10 10:19:04 阅读更多 →

日新闻

卫星轨道分类全解析:从LEO到GEO的选型逻辑与工程实践

卫星轨道分类全解析:从LEO到GEO的选型逻辑与工程实践

1. 从“卫星轨道分类”这个标题说起:为什么值得花时间搞懂第一次接触“卫星轨道分类”这个概念,很多人会觉得它离自己很远——不就是天上的星星怎么转吗?但如果你正在做航天任务规划、遥感数据接收、星座设计,甚至只是准备一场航天…

2026/10/10 0:00:39 阅读更多 →
Spring AOP 核心原理与实战:从概念到日志切面落地

Spring AOP 核心原理与实战:从概念到日志切面落地

1. 从一个真实痛点说起:为什么你的代码里到处都是重复逻辑刚入行那会儿,我写过一个用户管理模块,注册、登录、改密码、注销四个接口。每个接口里都塞了几乎一样的日志打印、参数校验、事务开启和提交。当时觉得没什么,能跑就行。直…

2026/10/10 0:00:40 阅读更多 →
Python招聘数据采集与分析可视化:从采集清洗到薪资技能城市可视化全链路

Python招聘数据采集与分析可视化:从采集清洗到薪资技能城市可视化全链路

简介:这是一套面向计算机相关专业学生与项目实战学习者的Python数据采集与分析可视化完整项目,以Boss直聘岗位数据为对象,适合用作毕业设计、课程设计或期末大作业。资源包共38个文件,约246KB,以13个py源码文件为核心&…

2026/10/10 0:00:40 阅读更多 →

周新闻

KT148A语音芯片外挂8002D功放的工程实践指南

KT148A语音芯片外挂8002D功放的工程实践指南

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

2026/10/8 15:26:32 阅读更多 →
LLC谐振变换器增益公式推导:从FHA等效到完整归一化表达式

LLC谐振变换器增益公式推导:从FHA等效到完整归一化表达式

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

2026/10/10 1:36:08 阅读更多 →
ARM架构深度解析:从RISC设计理念到交叉编译实战

ARM架构深度解析:从RISC设计理念到交叉编译实战

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

2026/10/9 10:11:06 阅读更多 →

月新闻

我发现了一个新思路:用 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/10 5:23:50 阅读更多 →
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/9 21:32:20 阅读更多 →
黑夜航拍船只数据集训练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/9 6:17:20 阅读更多 →