JSON格式输出控制:让AI返回结构化数据
JSON格式输出控制让AI返回结构化数据前面几篇文章我们讲了如何组织输入——用分隔符、Markdown、XML标签来结构化你的指令。但还有一半的功力在控制输出上。在很多实际场景中——特别是你打算把AI的输出对接给程序处理时——你需要AI的输出不是一段自由文本而是一个结构化的JSON对象。精确控制AI输出JSON格式的数据是提示词工程中从能用到好用的关键一步。今天我们来全面掌握这门连接AI输出和程序输入的桥梁技术。一、为什么需要JSON格式输出1.1 自由文本 vs 结构化数据 自由文本输出适合给人看结构化数据输出适合给程序处理。假设你让AI分析一段用户反馈自由文本输出适合人阅读根据分析这段用户反馈的情感倾向为负面主要是因为用户对产品的 加载速度和客服响应时间不满。用户提到的功能问题包括登录失败、 数据同步异常。建议优先处理登录问题这是影响用户使用的最大障碍。JSON格式输出适合程序处理{sentiment:negative,sentiment_score:-0.72,issues:[{type:performance,description:加载速度慢,severity:high,mentioned_count:3},{type:support,description:客服响应时间长,severity:medium,mentioned_count:2},{type:bug,description:登录失败,severity:critical,mentioned_count:5},{type:bug,description:数据同步异常,severity:high,mentioned_count:2}],recommended_actions:[{action:修复登录失败问题,priority:1,impact:解决用户量最大的障碍},{action:优化加载速度,priority:2,impact:提升整体用户体验}]}同样的分析内容JSON格式输出可以被程序直接解析无需从自然语言中提取信息按字段精确取值不会出现解析歧义方便存储到数据库、触发后续流程、生成数据可视化 当你构建一个AI驱动的应用如AI客服系统、AI数据分析工具、AI内容审核系统JSON格式输出是必须品不是可选项。1.2 JSON输出的典型应用场景场景需要的JSON输出原因AI客服分单{department: 售后, priority: high}下游系统根据JSON自动路由情感分析{sentiment: positive, score: 0.85}批量分析结果存入数据库信息提取{entities: [{name: 张三, type: person}]}结构化提取结果供搜索/索引内容审核{is_safe: false, violations: [色情, 暴力]}自动化审核决策数据转换{sql: SELECT * FROM ...}程序直接执行生成的SQL报表生成{metrics: [{name: DAU, value: 15000}]}数据直接绑定到前端图表二、让AI输出JSON的基本方法2.1 方法一直接指令格式说明最简单的做法——在提示词中明确要求JSON格式并给出格式说明。请分析以下用户反馈判断情感倾向并以JSON格式输出。 输出格式 { sentiment: positive/negative/neutral, confidence: 0.0到1.0之间的数值, keywords: [提取的关键词] } 用户反馈这个App真的太好用了界面漂亮功能齐全。⚠️ 这种方法的成功率大约在80-90%。对于简单JSON结构效果不错但复杂JSON结构可能出现格式错误缺少引号、多余逗号、字段类型不匹配等。2.2 方法二提供完整的JSON Schema 对于复杂的JSON输出需求最可靠的方法是在提示词中提供一个完整的JSON Schema示例。请分析以下对话记录提取所有的行动项Action Items 并以JSON格式输出。 请严格按照以下JSON Schema生成输出 json { total_actions: 0, actions: [ { id: action_001, assignee: 负责人姓名, deadline: YYYY-MM-DD格式的截止日期, task: 具体的任务描述, priority: high/medium/low, source_line: 对话中该行动项出现的位置第几句, dependencies: [依赖的其他action的id如果没有则为空数组] } ], extraction_confidence: 0.85, notes: 提取过程中的备注如果对话中没有明确的行动项请在此说明 }Schema要求所有字段必须存在不允许省略字符串字段如果没有值使用空字符串数值字段如果没有值使用0数组字段如果没有值使用空数组[]不要添加Schema中未定义的额外字段对话记录[待处理的对话文本] 完整的JSON Schema 字段规则说明能将格式正确率提升到95%以上。 ### 2.3 方法三少样本示例引导 结合少样本提示的方法用示例示范期望的JSON输出。请将以下自然语言查询转换为SQL。以JSON格式输出。 示例1 输入查询所有年龄大于18岁的用户输出{sql:SELECT * FROM users WHERE age 18,tables:[users],filters:[{field:age,operator:,value:18}],confidence:0.95} 示例2 输入查询张三最近的10个订单按时间倒序输出{sql:SELECT * FROM orders WHERE user_name 张三 ORDER BY created_at DESC LIMIT 10,tables:[orders],filters:[{field:user_name,operator:,value:张三}],order_by:{field:created_at,direction:DESC},limit:10,confidence:0.92} 你的任务 输入统计各部门的平均工资只显示平均工资大于10000的部门输出 少样本示例展示了什么样的输入对应什么样的JSON输出AI会模仿示例的JSON结构、字段名风格和嵌套方式。 --- ## 三、JSON输出的精确控制技巧 ### 3.1 定义字段的强制规则 只给出JSON Schema还不够你需要明确每个字段的行为规则——特别是对于枚举值、空值处理和数据类型。JSON输出规则必须严格遵守① 枚举字段只能使用指定的值不能自创正确priority: high错误priority: urgent或priority: 高② 空值表示字符串为空使用空字符串不是null也不是无数组为空使用[]空数组数值未知使用-1作为未知标记如果0是有效值③ 数据类型必须精确count: 42数字不是count: 42is_active: true布尔值不是is_active: truescore: 0.85保留两位小数④ 不要添加注释错误name: 张三 // 这是用户名正确name: 张三⑤ 不要输出JSON之外的任何内容不要加这是你的JSON输出这样的前缀不要加希望这个JSON对你有帮助这样的后缀只输出纯JSON让程序可以直接JSON.parse()### 3.2 处理必须确定但不确定的情况 在JSON输出中有时会遇到这个字段必须填但你可能不确定该填什么的矛盾情况。你需要给AI一个明确的处理规则。对于不确定的信息按以下规则处理① 如果字段是必填的但你确实不知道答案填写你的最佳猜测同时将confidence字段设为低于0.5在uncertain_fields数组中添加该字段名和不确定的原因② 如果字段可以推断但不完全确定填写你的推断值confidence设为0.5-0.8在notes中说明推断依据③ 绝对不能因为不确定而省略字段Schema要求的所有字段必须出现编造一个看起来很真的假数据用不确定未知等中文文本代替数据结构示例{user_age:30,user_age_confidence:0.4,uncertain_fields:[{field:user_age,reason:对话中用户只提到我是90后推测年龄约30岁,possible_range:[25,35]}]}### 3.3 嵌套结构的控制 当JSON涉及嵌套结构时数组内嵌对象、对象内嵌数组等需要在Schema中明确每个嵌套层的结构。不清晰的嵌套说明输出一个包含用户信息的JSON包括他们的订单列表。❌ AI可能输出各种不同的嵌套结构。清晰的嵌套说明请严格按照以下结构输出{user:{id:用户ID字符串,name:用户姓名字符串,orders:[{order_id:订单号字符串,amount:订单金额数字保留两位小数,items:[{product_name:商品名称字符串,quantity:数量整数,unit_price:单价数字,subtotal:小计数量×单价数字}],total:该订单的总金额数字status:已完成/待发货/已取消}],total_spent:所有订单的总金额数字}}特别注意orders是一个数组如果用户没有订单用空数组[]items是orders内每个订单对象的数组total是每个订单对象的一级字段不是items里的total_spent是user对象的一级字段不是orders里的--- ## 四、JSON输出的验证与容错 ### 4.1 在提示词中内置验证逻辑 你可以在提示词中要求AI在输出JSON之前进行自我验证。在输出JSON之前请执行以下自我验证① Schema完整性检查输出中是否包含了Schema定义的所有字段有没有多出Schema未定义的字段② 数据类型检查每个字段的数据类型是否正确数值字段是否真的是数字而非字符串形式的数字布尔字段是否真的是true/false而非true/false字符串③ 值合法性检查枚举字段的值是否在允许的范围内数值是否在合理的范围字符串是否为空如果该字段要求非空④ JSON语法检查是否有尾随逗号所有字符串是否用双引号包裹花括号和方括号是否匹配如果发现任何问题请修正后再输出。最终输出必须是合法的JSON。### 4.2 程序端的容错处理 ⚠️ 即使提示词设计得再好仍然可能有5-10%的概率AI输出的JSON存在微小格式问题。你的程序需要具备一定的容错能力。 python import json import re def safe_json_parse(ai_response: str) - dict: 安全地解析AI输出的JSON具备容错能力 # 尝试1直接解析 try: return json.loads(ai_response) except json.JSONDecodeError: pass # 尝试2提取json...代码块中的内容 json_match re.search(r(?:json)?\s*\n?(.*?)\n?, ai_response, re.DOTALL) if json_match: try: return json.loads(json_match.group(1)) except json.JSONDecodeError: pass # 尝试3找到第一个{和最后一个}之间的内容 first_brace ai_response.find({) last_brace ai_response.rfind(}) if first_brace ! -1 and last_brace ! -1 and last_brace first_brace: try: return json.loads(ai_response[first_brace:last_brace 1]) except json.JSONDecodeError: pass # 尝试4修复常见问题后重试 cleaned ai_response # 移除尾随逗号 cleaned re.sub(r,\s*}, }, cleaned) cleaned re.sub(r,\s*], ], cleaned) # 修复单引号 # 注意这个替换过于简单在实际代码中需要更精细的处理 try: return json.loads(cleaned) except json.JSONDecodeError: raise ValueError(f无法解析AI输出的JSON: {ai_response[:200]}...) 这个容错函数使用了渐进式解析策略——先尝试最理想的情况直接解析如果失败就逐步尝试各种降级方案。在生产环境中这个函数可以挽救大量差一点就正确的JSON输出。4.3 使用JSON Mode模型提供时⚠️ 越来越多的AI平台提供JSON Mode功能——在API调用时设置一个参数强制模型以JSON格式输出。如果可用这应该是你的首选方案。但要注意即便使用了JSON Mode你仍然需要在提示词中描述你想要的JSON结构。JSON Mode只是保证输出是合法的JSON但不保证结构符合你的预期。五、复杂JSON输出的实战案例5.1 案例一多层级信息提取场景从一篇新闻报道中提取结构化的事件信息。提示词请仔细阅读以下新闻报道提取其中的关键信息并严格按照以下 JSON Schema输出。 json { event: { title: 事件的简短标题不超过30字, type: 政治/经济/科技/社会/体育/娱乐, date: 事件发生日期YYYY-MM-DD格式如果不确定具体日期使用YYYY-MM或YYYY, location: { country: 国家名称, city: 城市名称如果未提及则为空字符串, specific_place: 具体地点如果未提及则为空字符串 }, summary: 事件概要100字以内 }, participants: [ { name: 参与者名称个人或组织, role: 在该事件中的角色如发起者/受害者/回应者/旁观者, type: individual/organization/government, statements: [ { content: 该参与者说的话或发表的声明直接引用, is_direct_quote: true } ] } ], impacts: [ { area: 影响领域如经济/外交/环境/民生, description: 具体影响描述, scale: local/national/global, certainty: confirmed/speculated/expected } ], context: { background: 事件的背景信息, related_events: [相关事件描述数组如果没有则为空数组], is_developing: true }, metadata: { extraction_confidence: 0.0, information_completeness: high/medium/low高大部分信息齐全中有部分缺失低信息严重不足, uncertain_fields: [不确定的字段名列表] } }输出规则所有字段必须存在即使是空字符串或空数组字符串必须用双引号如果信息完全缺失且无法推断字符串用数组用[]布尔用false只输出JSON不要任何前缀或后缀文字新闻报道[粘贴新闻全文]### 5.2 案例二嵌套数组的精确控制 **场景**生成一个包含多层嵌套数组的复杂JSON——课程大纲。请为以下主题生成一份课程大纲严格按照以下JSON Schema输出。{course:{title:课程标题,description:课程简介50字以内,target_audience:目标学员描述,total_lessons:10,estimated_hours:20},modules:[{module_number:1,title:模块标题,description:模块简介30字以内,lessons:[{lesson_number:1,title:课时标题,duration_minutes:45,content_type:lecture/demo/exercise/quiz/project,key_points:[知识点1,知识点2,知识点3],learning_objectives:[学习目标1,学习目标2],resources:[{type:video/reading/code/external_link,title:资源标题,description:资源描述}]}],module_quiz:{total_questions:5,passing_score:60,question_types:[multiple_choice,true_false]}}],final_project:{title:毕业项目标题,description:项目要求描述,evaluation_criteria:[{criterion:评估标准,weight:25}],estimated_hours:10}}课程主题Python数据分析入门面向零基础学员共10课时 这个Schema有4层嵌套course/modules/lessons/resources如果没有明确的SchemaAI几乎不可能生成正确的结构。 --- ## 六、JSON输出的常见问题与解决 ### 6.1 问题一AI输出美化版JSON ⚠️ AI有时会在JSON外面包裹解释性文字这是提取的结果{sentiment:positive}希望对你有帮助**解决方法**在提示词中明确要求只输出纯JSON不要Markdown代码块标记json任何前缀文字如这是你的JSON输出任何后缀文字如希望对你有帮助任何注释输出应该可以直接被JSON.parse()解析。### 6.2 问题二字段值用中文代替英文枚举 ⚠️ AI有时会在枚举字段中用中文而非规定的英文值期望priority: high实际priority: 高**解决方法**在Schema中标注每个枚举字段的允许值并用少样本示例强化。 ### 6.3 问题三数组元素类型不一致 ⚠️ 有时AI会混淆数组内元素的结构期望“tags”: [“AI”, “机器学习”, “深度学习”]实际混淆“tags”: [{“name”: “AI”}, {“name”: “机器学习”}]**解决方法**在Schema中明确标注数组元素的类型。 ### 6.4 问题四数值变成字符串 ⚠️ 这是最常见的JSON格式问题——AI把数值写成字符串。期望score: 85实际score: 85**解决方法**在Schema中明确标注每个数值字段加上验证指令。 --- ## 七、从JSON到生产系统的完整流程 ### 7.1 设计阶段① 定义所需的JSON Schema② 确定每个字段的数据类型、是否必填、默认值、允许值范围③ 编写提示词包含Schema 字段规则 少样本示例④ 用10-20个测试case验证输出### 7.2 生产阶段 python import json import anthropic from typing import Optional def structured_ai_query( client, prompt_template: str, input_data: dict, expected_schema: dict, max_retries: int 3 ) - Optional[dict]: 生产级的AI结构化查询函数 特点 - 自动将input_data填充到prompt模板 - 解析AI输出的JSON - 验证JSON是否符合expected_schema - 失败时自动重试 # 填充模板 prompt prompt_template.format(**input_data) for attempt in range(max_retries): try: # 调用AI response client.messages.create( modelclaude-sonnet-4-20250514, max_tokens4000, temperature0.1, # JSON输出建议用低温度 messages[{role: user, content: prompt}] ) # 解析JSON raw_output response.content[0].text result safe_json_parse(raw_output) # 使用前文的容错解析函数 # 验证Schema if validate_schema(result, expected_schema): return result else: # Schema验证失败在下一次重试时加一条提示 prompt f\n\n上一次输出的JSON不符合Schema要求请严格按照Schema重新输出。 except Exception as e: if attempt max_retries - 1: raise # 重试 prompt f\n\n上一次解析失败错误{str(e)}请确保输出是合法的JSON。 return None def validate_schema(data: dict, schema: dict) - bool: 验证JSON数据是否符合预期的Schema for field, rules in schema.items(): # 检查必填字段 if rules.get(required, False) and field not in data: return False # 检查数据类型 if field in data: expected_type rules.get(type) if expected_type and type(data[field]).__name__ ! expected_type: return False # 检查枚举值 allowed_values rules.get(enum) if allowed_values and data[field] not in allowed_values: return False return True7.3 监控与迭代① 记录每次AI输出的JSON解析成功率 ② 分析解析失败的原因格式错误Schema不符字段缺失 ③ 根据失败模式优化提示词 ④ 定期更新Schema以适应需求变化核心要点总结✅JSON输出的核心价值将AI的输出从给人看变成给程序处理。当AI的输出需要对接下游系统数据库、API、前端、工作流引擎时JSON格式输出是必需品而非可选项。✅三种基本方法①直接指令格式说明成功率约80-90%适合简单JSON②完整JSON Schema字段规则成功率95%适合复杂JSON③少样本示例引导成功率最高但需要准备示例。三种方法可以组合使用。精确控制的五个关键①每个字段要有明确的强制规则特别是枚举值和空值处理②处理不确定但必填的矛盾用confidenceuncertain_fields标记③嵌套结构要逐层定义清晰④在提示词中内置自我验证逻辑⑤程序端要具备容错解析能力渐进式解析策略。生产级最佳实践①设计阶段用10-20个测试case验证Schema的稳定性②低temperature0.1-0.3更适合JSON输出减少随机性带来的格式错误③构建safe_json_parse容错函数代码块提取→花括号定位→常见问题修复④失败时自动重试retry with feedback。⚠️四大常见问题①AI在JSON外包裹解释性文字要求只输出纯JSON②枚举值用中文代替英文Schema中标注少样本强化③数组元素类型不一致Schema中明确标注④数值被写成字符串Schema中标注类型验证指令。完整生产链路Schema设计→提示词编写→测试验证→容错解析→Schema验证→失败重试→监控迭代。每一环都不可或缺共同保证AI结构化输出的可靠性。

相关新闻

Power BI主题模板终极指南:3步打造专业级数据可视化报表 [特殊字符]

Power BI主题模板终极指南:3步打造专业级数据可视化报表 [特殊字符]

Power BI主题模板终极指南:3步打造专业级数据可视化报表 🚀 【免费下载链接】PowerBI-ThemeTemplates Snippets for assembling Power BI Themes 项目地址: https://gitcode.com/gh_mirrors/po/PowerBI-ThemeTemplates 还在为Power BI报表设计头疼…

2026/10/21 21:58:06 阅读更多 →
STM32 BM8563 RTC时间乱跳问题:硬件排查与软件容错实战

STM32 BM8563 RTC时间乱跳问题:硬件排查与软件容错实战

1. 项目概述:当你的时钟开始“跳舞” 最近在调试一个基于STM32和BM8563 RTC(实时时钟)模块的项目时,遇到了一个让人头皮发麻的问题:设备运行一段时间后,读取到的时间会毫无规律地“乱跳”。比如&#xff0c…

2026/10/22 1:42:39 阅读更多 →
黑苹果网络驱动终极指南:从BCM94360Z4到DW1820A的完整解决方案

黑苹果网络驱动终极指南:从BCM94360Z4到DW1820A的完整解决方案

黑苹果网络驱动终极指南:从BCM94360Z4到DW1820A的完整解决方案 【免费下载链接】Hackintosh Hackintosh long-term maintenance model EFI and installation tutorial 项目地址: https://gitcode.com/gh_mirrors/ha/Hackintosh 对于黑苹果用户来说&#xff0…

2026/10/22 3:46:31 阅读更多 →

最新新闻

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/22 21:33:42 阅读更多 →
机器人大脑技术盘点:具身智能的感知、决策与数据闭环

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

如果你的信息流最近也天天刷到“机器人大脑”这个词,你会发现一个很有意思的现象:每个人说的“大脑”根本不是同一个东西。有人指的是大语言模型,有人指的是运动控制系统,还有人指的是能理解物理世界的端到端模型。在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/22 22:56:44 阅读更多 →
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/22 22:56:12 阅读更多 →
黑夜航拍船只数据集训练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/22 19:06:46 阅读更多 →