LangChain FewShotPromptTemplate:用少样本示例稳定LLM输出
做 LLM 应用开发的朋友多少都吃过提示词不稳定的亏同样一个任务零样本让模型直接回答格式随缘、语气漂移。今天这一篇我来聊聊 LangChain 的 Model IO 组件里一个专门解决这个问题的提示词模板——FewShotPromptTemplate。简单说它负责把“少样本示例”规整拼进提示词里让模型照着例子输出不再上天。文章会讲清楚它的设计原理、五个核心参数、完整可跑的代码、动态示例选择以及我实际踩过的几个坑适合正在用 LangChain 搭应用、又不想在提示词上反复试错的工程师。1. FewShotPromptTemplate 到底在解决什么问题1.1 为什么给几个示例比说一百句指令都管用你直接问模型“这段文本是好评还是差评”它能回答可一旦任务变成批量处理、格式必须统一模型就开始放飞自我这一条输出“好评”下一条输出“情感好评置信度0.98”再下一条直接写一段小作文。问题不在模型笨在于你只交代了任务没有交代“输出到底长什么样”。少样本提示的做法是给模型看几组现成的输入输出让它照着样例的样子来。FewShotPromptTemplate 在 LangChain 里把这个过程从“手工拼字符串”升级成了“声明式配置”。类比一下你教一个新同事做数据标注口头说一百句规则不如甩给他两份已经标好的表格。模型也一样它对格式的“理解”更多来自对示例的模仿而不是对抽象规则的推理。少样本提示之所以有效是因为它同时给了模型两样东西任务边界和输出样例。FewShotPromptTemplate 要帮你处理的就是这两样东西的组织方式。1.2 它在 Model IO 组件里的定位Model IO 是 LangChain 的核心抽象之一管的是模型进出的整条链路提示词模板负责把用户的原始输入转成有结构、有上下文的模型输入模型负责生成结果输出解析器再把结果转回程序能用的结构化数据。FewShotPromptTemplate 是提示词这一层的进阶选手属于 PromptTemplate 家族里的一个专门实现。它适合的场景通常有几个共同点输出格式相对固定比如情感分类、意图识别、实体抽取、文本改写任务可以用少量示例描述清楚业务要求结果稳定可复现。如果你只是简单问一句“给我讲个笑话”用不上 FewShot但如果你在做一个面向业务系统的自动化工单分类FewShotPromptTemplate 几乎是标准答案。1.3 自己写 f-string 拼一下不就行了吗说实话两三个静态示例自己拼字符串也没多麻烦。但问题出在工程化示例要换、业务要加字段、输入的当前问题来自不同接口、有些场景还要根据相似度动态挑示例。手写字符串很快就会变成一连串 if else 和 replace还容易漏空格少换行。用模板把组装逻辑固定下来改示例只需要改配置不用动调用代码。这也是 LangChain 提供各类 PromptTemplate 的核心价值提示词本身变成了可以版本管理、可以测试、可以动态生成的独立对象。2. 把 FewShotPromptTemplate 拆开看2.1 五个核心参数逐个说清楚要真正吃透 FewShotPromptTemplate得先看它最常用的几个参数examples示例列表每个元素是一个字典。比如有一个输入字段叫text输出字段叫label那一个示例就是{text: 这家餐厅的菜真不错, label: 好评}。examples 是静态示例集合也是最直观的部分。example_prompt用来把每个示例字典渲染成一段文本的小模板。它本身也是一个 PromptTemplate内部定义了示例展示成什么样的格式。这个参数非常关键因为它决定了所有示例的统一“观感”。prefix放在所有示例前面的任务描述相当于“开场白”。你可以在这里写清楚角色、任务规则、输出要求。它会被最先拼进提示词。suffix放在最后面的引导句通常拼接当前输入并留出生成位置。它决定了模型“从哪里开始输出”。input_variables最终拼装时需要的变量名列表。这里最容易出错的是它和 examples 里的键名不是一回事它对应的是 suffix 里那个新输入变量。另外还有一个可选参数example_selector动态示例选择器可以替代静态 examples后面我会专门讲。这些参数组合起来逻辑上是“前缀 若干示例文本 后缀”其中示例文本由 example_prompt 逐个渲染完成。2.2 一个最小可跑的示例直接看代码比看概念快得多。下面这段目标是让模型判断一段文本是好评还是差评from langchain.prompts import PromptTemplate, FewShotPromptTemplate examples [ {text: 这家餐厅的菜真不错, label: 好评}, {text: 服务态度太差了, label: 差评}, ] example_prompt PromptTemplate( input_variables[text, label], template文本{text}\n评价{label}\n, ) prompt FewShotPromptTemplate( examplesexamples, example_promptexample_prompt, prefix你是电商评论分类助手请对下面文本给出好评或差评。\n, suffix文本{input}\n评价, input_variables[input], ) text prompt.format(input快递晚了两天才到) print(text)这段代码会拼出下面这段提示词你是电商评论分类助手请对下面文本给出好评或差评。 文本这家餐厅的菜真不错 评价好评 文本服务态度太差了 评价差评 文本快递晚了两天才到 评价注意最后一行“评价”后面没有内容这就是留给模型生成的位置。模型看到前面的成对示例会顺着这个格式续写一个“好评”或“差评”。我在实际项目里第一次跑通时就觉得这个设计比零样本稳定太多了。2.3 为什么 suffix 要这么设计suffix 的功能是让模型知道“现在该你输出了”。示例拼完之后必须有一个清晰的边界否则模型可能把最后一个示例当作提示词的一部分继续“复读”。这里有个细节suffix 通常写成“目标文本{input}\n评价”末尾刻意以“评价”收尾相当于给模型递了半句话模型只需要补全后半句。这在提示词工程里叫“引导生成”能显著减少格式漂移。你可能注意到 examples 里的template末尾加了换行符\n这不是随手写的。FewShotPromptTemplate 在拼接示例时会保持模板的原始换行和空格缺少换行可能导致两个示例挤在一起模型就容易分不清边界。类似的细节我在第五节会统一讲。3. 实操搭建一个情感分类 FewShot Prompt3.1 环境准备这里默认你用的是当前较新的 LangChain 版本。装依赖就三行pip install langchain pip install langchain-openai pip install langchain-communitylangchain是核心框架langchain-openai是模型接入包langchain-community里包含很多第三方集成比如后面要用的向量存储。如果你不需要示例选择器只有前两个包也够跑。装完之后你可以直接用 Python 交互环境试下面的代码。3.2 固定示例版完整流程先把静态示例的完整链路跑通。这里我以一个电商评论情感分类为例完整代码会包含模型调用from langchain.prompts import PromptTemplate, FewShotPromptTemplate from langchain_openai import ChatOpenAI examples [ {text: 这家餐厅的菜真不错, label: 好评}, {text: 服务态度太差了, label: 差评}, {text: 包装很严实没有破损, label: 好评}, {text: 价格有点贵但质量还行, label: 中性}, ] example_prompt PromptTemplate( input_variables[text, label], template文本{text}\n评价{label}\n, ) prompt FewShotPromptTemplate( examplesexamples, example_promptexample_prompt, prefix你是电商评论分类助手请对下面文本给出好评、中性或差评。\n, suffix文本{input}\n评价, input_variables[input], ) llm ChatOpenAI(modelgpt-4o-mini, temperature0) res llm.invoke(prompt.format(input快递晚了两天才到不开心)) print(res.content)这里我把分类从二分类扩成了三分类多了一个中性类别examples 也对应扩充为四个。这么做是因为分类越多模型越需要更多示例来“锚定”各类别的判断尺度。temperature 调到 0保证分类结果尽量确定。跑完之后正常会输出“差评”。如果输出“差评”之外的东西第一件事不是怪模型而是打印prompt.format(...)去看拼出来的提示词多半是示例格式或分类标签不一致。3.3 动态示例选择只挑最相关的示例给模型固定示例有个局限所有输入都共享同一批示例。举个例子如果你在做一个多意图客服机器人示例里同时有“退货”“开票”“物流查询”三类那当用户问“我的发票为什么没开”时模型面对上一堆不相关的退货示例注意力会被分散。这时候就该上 SemanticSimilarityExampleSelector。它做的事情可以概括为把每个示例的输入文本转成向量存进一个向量数据库当新的输入来到时计算输入向量和所有示例向量的相似度挑出最相似的 k 个示例来拼提示词。这样每个输入看到的示例都是“定制”的。看代码from langchain.prompts import PromptTemplate, FewShotPromptTemplate from langchain.prompts.example_selector import SemanticSimilarityExampleSelector from langchain_community.vectorstores import FAISS from langchain_openai import ChatOpenAI, OpenAIEmbeddings examples [ {text: 这台手机电池不行, label: 退货}, {text: 发票一直没收到, label: 开票}, {text: 我的包裹卡在转运中心了, label: 物流}, {text: 衣服尺码偏小想换一件, label: 换货}, # 更多示例... ] example_prompt PromptTemplate( input_variables[text, label], template用户问题{text}\n意图{label}\n, ) selector SemanticSimilarityExampleSelector.from_examples( examples, embeddingsOpenAIEmbeddings(), vectorstore_clsFAISS, k2, ) prompt FewShotPromptTemplate( example_selectorselector, example_promptexample_prompt, prefix你是客服系统意图分类器请从以下选项中判断用户意图。\n, suffix用户问题{input}\n意图, input_variables[input], ) llm ChatOpenAI(modelgpt-4o-mini, temperature0) res llm.invoke(prompt.format(input请问我的发票什么时候能开)) print(res.content)当输入是“请问我的发票什么时候能开”时选择器会计算它和所有示例的相似度挑出“发票一直没收到”和另一个最相近的示例而不是把所有示例全塞进去。k2表示只选两条。这在示例库变大之后效果差距非常明显。我自己的体会是示例库超过十来个以后静态 FewShot 的输出质量就开始波动而换上动态选择器之后提示词变短了准确率反而上去了原因是模型接收到的上下文更聚焦。3.4 调试思路先看拼出来的提示词别急着看模型输出无论你用静态还是动态示例最重要的一步都是“确认模型到底看到了什么”。直接在代码里打印print(prompt.format(input请问我的发票什么时候能开))把拼出来的完整提示词贴进任何聊天工具里人工看一遍。你会发现很多问题其实一眼就能看出来示例里有错别字、某个类别的示例全挤在一起、前缀和示例之间少了个空行。我在项目里养成的习惯是所有 PromptTemplate 都要留一个“导出提示词”的调试入口方便线上排查时把模板转成普通文本查看。这个习惯帮我省了很多定位问题的时间。4. 高频踩坑与排查实录4.1 input_variables 没填对直接 KeyErrorFewShotPromptTemplate 内部因为有前缀、示例、后缀三段结构变量关系比普通 PromptTemplate 复杂一些。常见报错是KeyError: input或者ValueError: Missing some input variables。这通常是因为input_variables里只写了[input]但 suffix 里还用了别的变量或者反过来模板里用了{input}但input_variables漏掉了它。解决办法是始终让input_variables和 suffix 中的变量名保持一致。如果你有多个变量比如input和language那 suffix 写成“请用{language}回答{input}”input_variables 就写[input, language]。一定要记住examples 字典里的键和input_variables没有任何关系前者是给 example_prompt 用的后者是给最终拼接用的。4.2 版本升级之后导入路径对不上LangChain 迭代很快早期版本里很多东西都能从langchain.prompts导入现在langchain_core单独拆包之后提示词基类的位置也变了。比如FewShotPromptTemplate在部分版本里位于langchain.prompts.few_shot在另一些版本里又推荐从langchain_core.prompts导入。我的建议很简单不要背路径在你当前环境的文档里搜“FewShotPromptTemplate”以安装版本的 API 为准。代码里优先从langchain.prompts导入如果发现导不进去再检查一下langchain-core的版本。这类问题报错信息一般很明确看 ImportError 的提示就能解决。4.3 示例之间的换行和空格比你想的更敏感提示词模板里的空格和换行会原样传给模型这跟写普通 Python 代码不一样。之前我碰到过一个很诡异的现象输入“好评”的样本时模型正常输入“差评”的样本时模型偶尔会多输出一段解释。后来把拼出来的提示词打印出来发现第二个示例的模板换行格式跟第一个不一致模型就把差异当成了一种隐含信号。处理方法是让所有示例模板保持完全相同的结构。如果你在模板里写了“文本xxx\n评价xxx\n”那就让每个示例都严格遵循这个格式甚至末尾换行符都要统一。FewShotPromptTemplate 本身不会自动校正你的示例格式它只负责按模板机械拼接。4.4 示例太长或者太多把上下文窗口塞满少样本提示不是越多越好。每个示例都要消耗 token示例太多会导致两层问题一是超过模型的上下文窗口直接被截断二是即使没截断长提示词的推理速度和成本也会上升。我见过有人为了保险一次性塞了三十个长示例结果提示词本身有四五千 token普通小模型的上下文一下就顶到上限了。经验上静态 FewShot 的示例数控制在两到四个每个示例尽量短。如果示例库很大就改用动态选择器并设置合理的 k比如二到三。不要试图让模型“学习”大量规则少样本提示的定位是给模型做示范不是给它灌知识。4.5 常见问题速查表问题现象常见原因处理方式报 KeyError提示缺变量input_variables 与 suffix/模板变量不对应统一变量名保证 input_variables 覆盖所有模板变量导入 FewShotPromptTemplate 失败版本更新包路径变化查看当前安装版本的官方文档按文档路径导入模型输出格式时好时坏示例内部格式不一致或缺少换行打印拼好的提示词检查示例模板的换行和缩进提示词太长请求失败示例过多或单个示例过长减少示例数量改用动态示例选择器控制长度分类结果总是偏向某个类别示例类别不均衡调整 examples让每个类别的示例数量大致均衡temperature 是 0 但结果还漂移提示词里缺少明确输出边界检查 suffix 是否以固定短语收尾引导模型续写这些坑我基本都踩过一遍尤其是第一个和第三个。很多时候模型表现不稳定不是模型的错是提示词里肉眼看不到的地方乱了。5. 从能用变好用我的几条私人建议5.1 示例质量大于数量类别要均衡少样本提示的核心是“样本”。如果示例本身写得模棱两可模型模仿出来的自然也好不到哪去。我见过有人从线上日志里随机抓几条文本当示例里面混杂着错误标注最后模型输出也跟着错。正确做法是人工挑选或清洗一批高质量示例确保每个类别的示例条数差不多并且示例的难度有梯度既有简单的也有稍微带点模糊判断的这样模型学到的判断能力更均衡。5.2 动态选择器的 k 值怎么定k 值没有绝对标准我的习惯是先设 2 到 3再根据效果上下调。任务越复杂样本差异越大越需要多一点的示例覆盖可以适当加大到 4如果任务比较单一1 到 2 就够了。还有一个容易被忽略的点k 值加大之后虽然提示词变长了但相似度选择的容错率也更高。你要是发现某个分类频繁错误可以把那类示例多写几条而不是简单加 k。5.3 别忘了和输出解析器配合使用FewShotPromptTemplate 负责把提示词拼好但模型输出的“好评”是不是一定能被下游代码正确读取是另一件事。建议在链路里搭一个输出解析器或结构化输出组件把模型文本转成正式的枚举值或 JSON 字段。分类任务还好一旦涉及抽取任务比如从文本里抽“商品名”“金额”“日期”解析器就是必需品。提示词给模型框定格式解析器给程序框定格式两边一起用才闭环。5.4 时刻保持用温度参数控制随机性分类、抽取这类任务temperature 请直接调 0避免模型在临界样本上犹豫反复。生成类任务比如文案续写、创意写作才需要调高到 0.7 甚至 1.0。有个容易被忽视的细节即使 temperature 是 0模型输出仍可能因为提示词格式问题而漂移所以不要觉得调了 0 就万事大吉还是要把提示词结构稳住。我个人在实际项目里最常用的一套组合是两三个高质量示例加上 k2 的动态选择配合 temperature0再用输出解析器收口。这套搭起来之后模型输出基本不会再出现乱七八糟的格式变体后续要改示例也只需要改配置链路代码基本不用动。你自己跑一遍把 format 出来的提示词打印出来看两次就能理解为什么我会说 FewShotPromptTemplate 是整个 Model IO 提示词层里最值得先学会的一个模板。

相关新闻

协处理器系统集成:地址空间、中断与功耗的全栈协同设计

协处理器系统集成:地址空间、中断与功耗的全栈协同设计

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

2026/10/18 16:54:48 阅读更多 →
QGC二次开发:从自定义面板到MAVLink消息

QGC二次开发:从自定义面板到MAVLink消息

简介:这是一份面向初学者的QGC(QGroundControl)二次开发入门项目代码,适合具备少量C与QT基础、希望掌握无人机地面站定制与功能扩展的开发者。压缩包内共3个文件,包含inscode项目配置、html说明页面及gitignore文件&am…

2026/10/18 16:53:47 阅读更多 →
BrowserSkill:Chrome 浏览器原生 CLI 编程工具

BrowserSkill:Chrome 浏览器原生 CLI 编程工具

1. 项目概述:BrowserSkill 是什么,它解决的不是“浏览器自动化”,而是开发者工作流的物理层重构BrowserSkill(常缩写为 bsk)不是又一个 Selenium 封装库,也不是 Puppeteer 的 CLI 包装器。我第一次在内部工…

2026/10/18 16:53:47 阅读更多 →

最新新闻

用AI辅助开题报告写作:从选题到成稿的四层实战工作流

用AI辅助开题报告写作:从选题到成稿的四层实战工作流

深夜十一点,电脑前摊着导师三天前批回来的开题报告初稿,红笔批注比正文还长。最扎眼的那句写着:"你的研究意义写得太空,文献综述像课程作业,方法部分看不出你到底要怎么做。"屏幕的光映在脸上,脑…

2026/10/18 18:23:57 阅读更多 →
Huffman编码的字节对齐与MFC内存序列化实战

Huffman编码的字节对齐与MFC内存序列化实战

简介:本资源是一套基于C与MFC框架实现的Huffman无损压缩/解压缩完整工程,面向C初学者及Windows桌面应用开发学习者,解决数据压缩原理落地难、GUI交互缺失、工程结构不清晰等常见学习痛点。压缩包共46个文件,涵盖6个头文件&#xf…

2026/10/18 18:23:57 阅读更多 →
Absolute Database v7.90 多用户版部署与故障排查指南

Absolute Database v7.90 多用户版部署与故障排查指南

简介:这是一套面向Delphi开发者与数据库中间件学习者的Absolute Database多用户版源码资源,适用于需要深度定制本地嵌入式数据库行为、研究多线程并发访问机制或适配老旧Delphi项目(如BCB5、XE2、VS2010等)的中高级开发人员。资源…

2026/10/18 18:23:57 阅读更多 →
SSH三层架构毕设项目:真实可运行的时装设计交流网

SSH三层架构毕设项目:真实可运行的时装设计交流网

简介:本资源是一套面向本科毕业设计与Java课程设计的完整Web应用系统,基于SSH框架(StrutsSpringHibernate)与MySQL数据库实现,适用于Java Web开发初学者及毕设选题阶段的学生。项目聚焦时装原创设计交流场景&#xff0…

2026/10/18 18:23:57 阅读更多 →
ML307R OpenCPU SDK实战:嵌入式AI模型部署与烧录全链路指南

ML307R OpenCPU SDK实战:嵌入式AI模型部署与烧录全链路指南

简介:ML307R-OpenCpu-sdk包是移远ML307R模组官方OpenCPU二次开发的核心SDK资源,面向嵌入式IoT开发者、模组应用工程师及低功耗终端设备研发人员,用于快速实现通信协议定制、传感器数据采集、远程OTA升级等边缘侧功能开发。资源共2000个文件&a…

2026/10/18 18:23:57 阅读更多 →
ASP图书馆管理系统:轻量Web开发的原理与实践

ASP图书馆管理系统:轻量Web开发的原理与实践

简介:这是一套基于ASP技术开发的轻量级Web图书管理系统源码,面向Web开发初学者与高校课程设计学生,用于实践动态网页开发、数据库交互及基础业务逻辑实现。系统以Access为后端数据库,完整覆盖图书查询、借阅登记、归还处理、读者管…

2026/10/18 18:22:57 阅读更多 →

日新闻

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

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

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

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

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

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

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

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

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

2026/10/18 0:00:55 阅读更多 →

周新闻

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

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

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

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

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

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

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

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

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

2026/10/18 0:00:55 阅读更多 →

月新闻

我发现了一个新思路:用 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/18 0:55:02 阅读更多 →
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/17 17:22:31 阅读更多 →
黑夜航拍船只数据集训练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/18 12:16:16 阅读更多 →