1. 从账单说起为什么每次调用大模型钱包都在悄悄“漏气”如果你用过几家主流大模型厂商的API大概率见过这样的价目表输入Input/Prompt每百万Token收xx元输出Output/Completion每百万Token收xx元。乍看之下只是两个数字但你把它们放一起算就会发现一个耐人寻味的现象——几乎所有厂商的输出单价都是输入单价的3到5倍常见的就是4倍。这不是厂商拍脑袋定价背后其实是算力、显存带宽和交互模式三重因素叠加的结果。也正是因为“输出比输入贵4倍”这个事实很多团队在做成本预估时翻过车有人按“提示词多长”来估算调用成本结果实际账单出来高出一大截有人以为缓存只是锦上添花结果它在某些场景下直接决定了项目能不能跑下去。这篇文章我想把这块掰开揉碎讲清楚。文章的内容围绕三件事展开第一为什么输出比输入贵贵在哪儿第二在真实业务里输入输出到底怎么影响总成本应该怎么算才靠谱第三关于缓存的三个经常被误解的“真相”——它什么时候能救你什么时候只是心理安慰以及什么场景千万别用缓存。不管你是刚接LLM API做Demo的开发者还是已经在生产环境里优化成本的工程师这篇文章都值得花十分钟看完。它能帮你少踩几个坑更重要的是让你在向老板解释“为什么账单又超了”的时候有理有据。2. 输出比输入贵4倍这个定价背后的物理与逻辑2.1 贵在哪预填充与解码的算力不对称要理解输出为什么贵先得知道大模型生成文本的两阶段过程。Transformer架构的推理大致分成两块预填充阶段Prefill和解码阶段Decode。预填充阶段处理的是你输入的Prompt。这个阶段的特点是高度并行——整个输入序列可以一次性喂进去GPU的矩阵乘法单元能够同时处理大量token的计算效率极高。换句话说预填充吃的是“并行吞吐”算得快单位成本自然低。解码阶段生成的是输出token。它是一步步来的每生成一个token都要把之前所有token的隐状态重新过一遍注意力机制而且这个过程是串行的无法并行。更关键的是每一步都要把模型权重从显存HBM搬到计算单元SM里走一趟这个“搬权重”的带宽开销极大。业内管这个叫内存带宽瓶颈——算力够用但数据搬运的速度卡住了脖子。用个生活化的类比预填充像复印一叠文件整叠一起过机器一分钟搞定解码像手写回信每写一个字都要重新看一眼前面所有内容写100个字就得看100遍。所以输出token的“生产成本”天然比输入token高厂商定价翻几倍是物理决定的。2.2 输入输出计价方式不同Prompt是一口气输出是一步步除了物理成本计费模式也放大了价格差。输入端你发送的Prompt通常是一次性的模型只需要“读一遍再理解”读完就开始生成。输出端则不同模型每吐一个token都伴随一次完整的前向传播计算而且这个计算量会随上下文长度增长而增长。即便是同样的token数量输出的实际计算量也比输入大得多。另一个经常被忽略的点是KV Cache的内存占用。在解码阶段每个输出token都会追加到KV Cache里KV Cache越大单次解码需要搬运的缓存数据越多显存占用越高这也直接推高了单位输出token的成本。也就是说输出不仅贵而且随着对话变长会越来越贵。2.3 算一笔真实的账4倍价差在业务里意味着什么为了让你直观感受这个4倍价差的杀伤力我拿一组典型价格算笔账。假设某主流模型的定价是输入15元 / 百万Token输出60元 / 百万Token场景A一次简单的单轮问答。用户发20个token的问题模型回200个token的答案。费用算下来输入费用 20 / 1000000 × 15 0.0003元 输出费用 200 / 1000000 × 60 0.012元看起来输出费用是输入的40倍。总费用0.0123元其中输出占了97.5%。这就是为什么我说在单轮交互里你的成本几乎完全由输出长度决定。场景B一个多轮对话应用系统提示词很长比如500个token的指令用户每次发30个token模型回300个token。连续对话10轮。注意每轮交互系统提示词都会重新发送一次除非用缓存这里先不展开输入总量 500 × 10 30 × 10 5300 token 输出总量 300 × 10 3000 token 输入费用 5300 / 1000000 × 15 0.0795元 输出费用 3000 / 1000000 × 60 0.18元输出费用依然是输入的2倍以上。如果把系统提示词拉到2000个token输入费用会涨到0.3元左右这时输入占比才明显上升。这两个场景说明一个核心规律在绝大多数交互式应用里输出长度才是成本的决定性变量输入长度的影响取决于提示词规模和是否启用缓存。如果你在设计产品时能让模型“少说话”省下的钱比优化Prompt还多。2.4 开源模型也一样为什么本地部署同样“输出贵”有人会想我用开源模型自己部署总该没有定价问题了吧生产环境中模型本身确实没有“输出贵4倍”的计费规则但物理成本仍然不对称。本地部署时成本体现在GPU占用时间和电费上。同样的显卡跑预填充可以同时处理大量请求因为并行度高但跑解码时每个请求都在排队等显存带宽同一个GPU同时只能服务少数几个并发请求。结果就是输出越多的应用单卡吞吐越低平摊到每个请求的硬件成本越高。如果你在Finetune或部署LLaMA系模型时做过压测会发现token生成速度峰值通常远低于输入处理速度就是这个原因。所以从计费和物理两个角度“输出贵”都是一条绕不开的规律。理解了这一点再来看缓存的价值会更清楚它在什么环节省钱、省多少。3. 缓存的三个真相它省钱但不是万能的3.1 真相一Prompt Cache只缓存“公共前缀”不是所有输入都缓存市面上主流的大模型API比如Anthropic的Prompt Caching、OpenAI的自动缓存、以及各类网关层的语义缓存都属于前缀缓存。所谓前缀就是你Prompt中从头开始、连续且不变的部分。举个例子。你构造了一个Prompt你是客服助手请根据以下对话记录回答用户问题。 对话记录... 用户问题...如果对话记录和用户问题经常变化那么每次只有开头那句“你是客服助手”是公共前缀缓存命中率会非常低。正确的做法是把能复用的系统提示词、Few-shot示例、固定的背景材料全部放在Prompt最前面并且保证它们一字不改。我曾经见过一个团队把Few-shot示例放在Prompt末尾用户问题插入在中间——结果每次请求的“公共前缀”只有开头的系统提示词缓存命中率不到5%省了个寂寞。后来把可变内容全部移到Prompt尾部命中率直接拉到80%以上。这里有个细节很多人不知道前缀缓存的“前缀”是按token级别计算的。你改一个标点、换一个空格都可能导致缓存失效。所以凡是想让缓存生效的Prompt部分必须做到字节级稳定连“换行符”都不能乱动。类型命中条件典型场景实际效果前缀缓存Prompt从开头起连续匹配固定系统提示词 长Few-shot命中率高需稳定前缀完整缓存整个Prompt完全一致重复提交同一任务命中率低业务中少见语义缓存语义相似即可命中相似问题查询效果依赖相似度算法有误判风险3.2 真相二缓存省的是“输入费用”对输出几乎无能为力这是我对团队说得最多的一句话缓存最直接的收益是降低输入计价部分的成本但对输出计价几乎无能为力。为什么因为输出token是模型实时生成的每一轮都不一样没有“公共前缀”可言。你哪怕把Prompt完全缓存住了模型照样要一步步解码生成答案输出费用一分不少。所以在评估缓存收益时得先算清楚自己的成本结构中输入占比有多大。以我前面的场景B为例如果启用前缀缓存假设命中率70%那么输入费用直接打三折输入费用有缓存 输入费用无缓存 × (1 - 命中率) ≈ 0.0795 × 0.3 ≈ 0.024元 总费用从 0.2595 降到 0.204元节省约21%但如果你的应用是单轮问答输入只有几十个token输出有几百个token——这时候输入费用本来就低缓存省下来的钱几乎可以忽略不计。我见过有人为了省几厘钱花两周时间重构Prompt结构、接缓存系统最后算下来ROI非常难看。一句话总结缓存救的是“大输入小输出”的场景比如文档问答、长上下文分析、多轮Agent救不了“小输入大输出”的场景。先算自己属于哪一种再决定要不要上缓存。3.3 真相三缓存不是“免费的午餐”它有延迟、容量与失效成本第三个真相最容易被忽略缓存是有代价的而且代价不低。延迟代价虽然命中缓存能减少重复计算但在某些API实现里缓存命中的请求仍然要走一遍完整网络链路。有些厂商的缓存命中延迟甚至比未命中还高因为要额外匹配缓存键只是费用更低。所以在做性能优化时不要把“缓存命中”等同于“响应变快”——它更像“同样的成本下单位时间能处理的请求变多了”而不是单个请求更快了。容量代价Prompt Cache需要在服务器端保存KV Cache这部分显存不是免费的。如果你用的是自建网关做语义缓存还得考虑向量数据库的存储和检索成本。当缓存规模做大之后这部分开销会反噬你的收益。失效成本前缀缓存的失效是“从失效点开始全部失效”。如果你的Prompt前缀在第100个token处改变那么前100个token的缓存依然有效但从第101个token开始后续所有数据都要重新计算。这意味着如果公共前缀中间夹了任何动态内容比如时间戳、随机数、用户ID整段缓存基本报废。我自己的原则是把动态内容从Prompt前缀中彻底隔离能放进API参数就放进API参数能放在上下文末尾就放在末尾绝不让它出现在公共前缀区。4. 实战如何精确估算LLM调用成本并优化到最低4.1 先建一个成本计算模型不只是单价×数量为了把前面聊的规律用起来我建议做一个简单的成本计算器用电子表格或者代码都可以。核心变量包括模型单价输入、输出分别计平均每请求输入token数含系统提示词平均每请求输出token数日均请求量缓存命中率KV Cache命中后的折扣费率部分API对缓存命中输入Token有更低价格公式长这样每日成本 日请求量 × (输入Token × 未命中率 × 输入单价 输入Token × 命中率 × 缓存输入单价 输出Token × 输出单价)注意这里输出Token没有“未命中”的概念它始终按全价计。我见过有人把输出Token也乘一个“未命中率”去算结果成本被低估了30%以上。我建议用下面的表格字段做记录每周对比一次实际账单和预估之间的偏差参数数值说明输入Token/请求1200含系统提示词与历史上下文输出Token/请求350模型回答平均长度输入单价15元/M厂商报价输出单价60元/M厂商报价缓存输入单价7.5元/M部分厂商折扣价日请求量50000生产环境均值缓存命中率75%取决于前缀稳定性日成本约1317元计算见下计算过程每日输入Token 50000 × 1200 60000000 60M 未命中输入Token 60M × 25% 15M 命中输入Token 60M × 75% 45M 输入费用 15M × 15 45M × 7.5 225 337.5 562.5元 每日输出Token 50000 × 350 17500000 17.5M 输出费用 17.5M × 60 1050元 总成本 562.5 1050 1612.5元这个例子里输出费用占总成本的65%。如果你把输出Token降到200总成本会降到562.5 50000×200/1000000×60 562.5 600 1162.5元省了28%。这就是“控制输出长度”的价值。4.2 降低输出成本的四个实操手段手段一限制max_tokens参数这招最直接。很多模型API默认允许输出很长你不设上限模型就可能啰嗦。根据业务类型设一个合理的max_tokens上限比如客服问答300、摘要任务500、代码生成800一上线就能看到输出Token均值下降。手段二Prompt里明确要求“简洁回答”在系统提示词里加一句“请用不超过X字回答不要输出解释过程”实测能减少20-40%的输出长度。这个效果在不同模型上差异较大但值得一试。需要注意2025年之后的模型对这类指令的遵从度更高早期模型效果不稳定。手段三使用结构化输出JSON Mode / Function Calling当你只需要模型返回一个结果时让它输出JSON或直接调用函数参数比让它写一段自然语言回复便宜得多。因为结构化输出会约束解码空间而且你不需要它“礼貌寒暄”。一个常见的优化是把“请用自然语言回复”改成“请输出JSON字段包括status, result, message”。手段四做输出压缩的后处理如果模型已经输出了长文本而你的业务只需要其中关键信息可以在服务端做一层后处理比如截断、提取摘要。这属于“事后补救”但有些场景下能显著降低你传给下一个模型作为上下文的token量间接降低下一轮成本。4.3 提高缓存命中率的落地方法Prompt模板工程化既然缓存命中率的提升能直接拉低输入成本那就有必要把Prompt模板纳入工程化管理。我的做法有三条第一条把模板拆成“静态块”和“动态槽位”。静态块包括系统提示词、角色设定、业务规则、Few-shot示例动态槽位包括用户输入、实时数据、检索结果。拼接时固定顺序静态块全部在前动态槽位全部在后。这样一来静态块就是天然的长公共前缀。第二条模板版本化但变更要克制。但凡修改静态块的任何内容之前积累的缓存全部失效。所以模板升级要走灰度先在低流量时段切换避免高峰期缓存集体失效导致成本飙升。第三条用统一的Token化管道。不同客户端传入的换行符、空格、Unicode编码如果不同会导致缓存键无法匹配。你在服务端做一层标准化把所有文本统一为同一编码再拼接Prompt能大幅提高命中率。这个小技巧经常被忽略但对缓存命中率的提升非常明显。4.4 实测数据一个生产项目的缓存收益复盘为了不被“理论省钱”误导我拿去年做过的一个知识库问答项目举例。初始状态下Prompt结构是系统提示词(800 token) 检索结果(平均2000 token) 用户问题(平均100 token) Few-shot示例(3条约600 token)这个结构里Few-shot示例放在用户问题后面意味着每次请求只有开头的“系统提示词检索结果”可能命中缓存而检索结果本身是动态的所以实际命中率只有20%左右。后来我把结构调整为系统提示词(800 token) Few-shot示例(3条600 token) 检索结果(2000 token动态) 用户问题(100 token动态)静态前缀变成“系统提示词Few-shot示例”约1400个token是稳定的命中率提升到70%以上。日输入成本大约下降了60%。整个改动只花了一个下午但每个月省下来的钱够买一台不错的开发机。这个例子想说明缓存的收益不是模型能力问题而是工程问题——你Prompt怎么写直接决定缓存能不能吃到。你在模板结构上花的时间比在模型选择上花的时间更值钱。5. 常见问题排查与避坑指南5.1 为什么我开了缓存账单还是没降这是最常见的问题。排查顺序检查前缀稳定性确认你的Prompt前部是否有任何动态内容。用脚本跑一遍历史请求比较所有请求的前N个token是否完全一致。检查厂商缓存生效条件部分API要求Prompt超过一定长度才启用缓存比如某些服务要求至少1024个token太短的Prompt根本不会走缓存。检查计费字段确认账单里的“cached input”字段是否真的出现了。如果完全没有这个字段说明你的请求根本没触发缓存。5.2 为什么同一段Prompt有时候命中缓存有时候不命中大概率是文本标准化问题。不同来源的客户端可能在文本末尾加上不同的换行符或者在Unicode字符上做了不同编码全角半角、直引号弯引号。我建议在所有请求入口统一做一次文本规范化把全角符号转半角或者统一成全角保持一致即可并统一换行符为\n。5.3 缓存的KV Cache会不会导致数据泄露这是一个值得关注的工程问题。Prompt Cache依赖于服务端存储你的输入内容以KV形式存在缓存区如果你处理的文本涉及敏感数据而厂商的缓存策略是跨用户共享的理论上存在别人撞前缀命中你缓存的可能性。主流API的缓存区通常是租户隔离的但如果你对数据安全要求极高建议关闭缓存功能或者只对脱敏后的内容开启缓存。5.4 使用第三网关做“语义缓存”值不值得我试过用向量数据库搭语义缓存用于拦截“相似问题”。结论是在FAQ类场景有点用在复杂推理场景作用有限。因为语义匹配无法精确判断“这次输入和上次是否会产生同样的输出”一旦误判命中、返回了不相关的结果用户体验的损失往往大于省下的那几分钱。如果你要做建议只在确定性高的场景比如天气查询、固定表单问答里开并且给缓存结果设置较短的过期时间。5.5 遇到“输出比预期长很多成本爆表”怎么办优先排查Prompt里是否写了“请详细说明”、“请逐步思考”等诱导长输出的指令。其次是检查是否误开了“详细推理模式”部分模型有reasoning/thinking模式输出token数量会激增3-5倍。如果你确实需要Reasoning能力建议只在需要复杂推理的请求里临时开启并且对输出长度设置严格上限。6. 一条个人经验成本优化是一个持续迭代的过程做了这么多LLM成本优化项目我最大的体会是成本不会自己变低它只会在你不断量化、调整、再验证的过程中降下来。量化是所有优化的起点。先把自己的成本模型建起来知道每一分钱花在输入还是输出上再针对占比最高的部分动手。很多时候你不需要换更便宜的模型——只要把输出长度控制住、把缓存命中率提上去、把多余的Reasoning关掉成本就能降一半。还有一点值得注意模型价格一直在变厂商经常调整价格策略和缓存规则。每过一个季度我都会重新读一遍各家API的计费文档把自己项目的成本模型更新一遍。那些“上季度还划算”的用法这个季度可能就变了。最后分享一个小技巧在生产环境里挂一个简单的成本监控面板把每小时的输入Token、输出Token、缓存命中率、估算费用四个指标画出来。当某个指标突然异常时你能第一时间发现是Prompt模板被改了、还是有人把max_tokens调大了。这个面板不需要多复杂一个脚本加一张表就够但它的价值远远超过写它的那半天时间。如果你也在做LLM应用的商业化落地希望这篇文章能帮你少走几步弯路。成本这件事越早算清楚越早有主动权。
企业数字化 ERP 产品动态
相关推荐
改进遗传算法求解分布式柔性作业车间调度问题 1. 项目背景与问题定义在制造业数字化转型浪潮中,分布式柔性作业车间调度问题(Distributed Flexible Job Shop Scheduling Problem, DFJSP)已成为制约生产效率提升的关键瓶颈。该问题需要同时处理三类约束:(1)工序在多工厂间的任务分配 (2)工序在可选设备… · 2026/11/2 18:32:45
AI辅助硕士论文写作:提升效率与质量的方法论 1. 硕士论文写作的AI辅助方法论 当面对硕士论文写作时,许多研究生都会经历从选题迷茫到写作焦虑的全过程。传统论文写作模式往往存在几个典型痛点:研究构想模糊不清、文献综述耗时费力、数据分析门槛高、写作过程效率低下。而现代AI工具的出现࿰… · 2026/10/31 23:47:50
深入理解Context Mode:AI上下文模式原理与工程实践 最近这一年,“context-mode”这个词在我日常工具链里出现得越来越频繁。简单说,它就是 AI 工作时能感知、利用的上下文信息模式——你给它多少背景,它就还你多少水准。很多朋友跑来问我,为什么同一个 AI,在别人手里像资… · 2026/10/31 23:47:50
PLFM_RADAR:基于脉冲线性调频的雷达信号处理验证平台 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/2 18:32:24
基于MAX14431BAEE+与PIC18F65K40的隔离SPI通信设计与实现 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/2 18:32:24
从零搭建毫米波雷达感知平台:FMCW信号处理与目标检测全解析 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/2 18:32:24
工业SPI隔离设计实战:MAX14431BAEE+与PIC18F57Q43协同优化 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/2 18:32:24
SPI隔离设计实战:MAX14431BAEE+与dsPIC30F4011的工业级链路方案 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/2 18:31:23
PLFM_RADAR:开源48通道10.5GHz相控阵雷达平台 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/2 18:31:23
双极步进电机控制实战: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/2 13:10:28
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/2 4:42:45
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/2 5:17:18
雷达信号调制技术解析:从LFM到伪线性调频原理与应用 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/2 1:01:15
基于MAX14431与TM4C123的工业SPI隔离电路设计全攻略 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/2 1:01:15
PLFM_RADAR:相位线性调频雷达信号处理框架 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/2 1:01:15
双极步进电机控制实战: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/2 13:10:28
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/2 4:42:45
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/2 5:17:18