news 2026/10/23 1:23:06

Ollama+DeepSeek本地部署实战:从API成本到私有化推理全攻略

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Ollama+DeepSeek本地部署实战:从API成本到私有化推理全攻略

上个月有位做创业项目的朋友找到我,说想在自己的产品里接入大模型能力,但算了算几家平台的API报价,一个月光日常调试就要烧掉不少钱,更别说等用户量上来之后那个账单规模。他问我有没有什么办法先把功能跑通、成本又可控。我说你这种情况,最合适的其实不是去跟平台谈折扣,而是直接把模型请回自己机器上跑。于是我们花了半天时间,在他的工作站上用Ollama把DeepSeek系列模型部署了起来,当天晚上他的内部工具就已经正常调用了。这篇文章就是那次实战的完整复盘,包含所有安装步骤、模型选型思路、避坑记录和调优参数,照着做你也能在本地拥有一套不按字数收费的大模型服务。

不管你是开发者、产品经理、学生,还是单纯想折腾一下本地AI,这套方案都值得了解一下。它解决的核心问题有三个:持续上涨的API费用、数据隐私外泄的风险、以及外部服务不稳定时整个功能"断供"的尴尬。接下来我会从最基础的原理讲起,再到实操命令和调优技巧,整个过程尽量说人话,确保你跟着操作就能复现。

1. 先把账算明白:为什么本地跑模型值得折腾

1.1 API这种“按字收费”的模式,坑在哪里

先聊一个很容易被忽略的事实:很多人第一次接触大模型API,看到的都是"每百万Token多少钱"这种看起来很便宜的价格。几块钱一百万Token,感觉写个文章、做几个总结根本花不了多少。但等真正跑起来就会发现,费用根本不是线性增长的。

几个比较现实的成本点:

  • 上下文越长,单次请求越贵。一次输入5000字的材料再做总结,消耗的Token远超你的直觉。
  • 开发调试阶段的浪费很惊人。同一个问题你会反复调参、反复测试,每一次都要重新计费。
  • 如果做的是toB或者企业内部工具,并发请求一旦上来,账户余额消耗得像是漏水。
  • 平台通常还区分输入输出价格,输出Token往往比输入贵,而生成型任务恰恰输出量大。

我朋友那个项目第一天测试就跑了大概150万Token,按平台定价算下来虽然看起来不多,但考虑到后面每周都要持续做数据清洗、Prompt调优、效果验证,长期下来确实是一笔不小的固定支出。而且这只是测试,没有产生任何实际收入。

1.2 本地部署到底换来什么

把模型部署到本地,最直接的好处当然是不再按Token付费。一旦模型文件和运行框架装好,你每天跑多少轮对话、生成多少内容,边际成本几乎为零,只有电费和硬件损耗。这个账算下来,对于高频调用场景来说,本地部署基本是几个月就能回本的选择。

但我觉得比省钱更重要的是两个点。

第一个是数据隐私。当你把企业内部文档、客户信息、代码片段发送到外部API时,这些数据就离开了你的可控范围。虽然很多平台有隐私协议承诺,但"承诺"和"物理上可控"之间永远存在距离。本地部署则不同,everything happens inside your machine,数据不会出你的网线,这种确定性在很多行业是刚需。

第二个是稳定性。外部API偶尔会限流、升级、故障,甚至调整定价策略。一旦你把核心功能建在别人的API之上,对方任何一个风吹草动都会直接影响你的产品。本地部署之后,这个依赖就被砍掉了,你的模型服务想什么时候重启就什么时候重启,想调什么参就调什么参,完全自己做主。

1.3 哪些人适合这套方案,哪些人不适合

说实话,本地部署并不是对所有人都是最优解。它最大的软肋是硬件门槛和性能上限。如果你需要的是当前最顶级的通用智能能力,本地开源模型和商业闭源模型之间确实还有差距。所以我不建议无脑冲,先对号入座看看自己属于哪类。

适合的人:

  1. 高频调用者:每天调用API十几次到上百次的开发者、研究者。
  2. 数据敏感场景:企业内部工具、医疗/金融/政务相关项目、代码库分析等。
  3. 学习研究型用户:想理解大模型是怎么被部署、加载、推理的。
  4. 长期成本敏感的个人开发者:想把AI能力持续嵌入个人工作流。

不太适合的人:

  1. 偶尔用一次的普通用户:不太需要折腾本地环境,网页版可能更方便。
  2. 追求顶级生成质量的重度用户:如果你要靠模型产出高质量长文、复杂推理,闭源大模型仍可能更香。
  3. 只有老旧轻薄本、内存小于8GB的用户:跑起来会非常吃力,体验容易劝退。

先认清自己的需求,后面做的所有配置才有意义。

2. Ollama怎么想:一条命令背后做了哪些事

2.1 Ollama的定位与工作原理

Ollama本质上是一个本地的开源大模型运行框架,它把"下载模型权重——加载到内存——提供推理接口——管理多个模型"这些步骤全部封装成了简单的命令行操作。在没有这类工具之前,你想在本地跑一个模型,需要手动下载几个GB到几十GB的权重文件,自己编写Python推理脚本,处理显卡驱动、CUDA、内存对齐一堆问题,光是环境配置就能折腾一整天。

Ollama把这些事全部收拢成一条命令。它的底层实际上还是调用了llama.cpp这类高性能推理引擎,同时自己实现了模型管理、并发调度、上下文管理、API服务等层。你用ollama run拉起来的模型,本质上是经过了它特定格式打包的GGUF量化权重。

这里有个很重要的点:Ollama不是重新发明了模型推理,而是重新组织了模型推理的体验。它把底层复杂的算子、内核调度、硬件适配尽量隐藏起来,让普通用户也能在个人电脑上几分钟内跑起一个正经可用的模型。对于不需要研究底层推理细节的绝大多数使用者来说,这个抽象层刚刚好。

2.2 技术栈里的一次关键取舍

有人会问:为什么不直接用原版Python推理框架?我的回答是:在产出效率和可维护性面前,Ollama的开箱即用优势太大了。

当你用Python框架部署时要面对什么?先是版本地狱:Python版本、CUDA版本、PyTorch版本、transformers版本,任何一个不匹配都可能导致import报错。然后是长尾问题:显存不够要怎么办?显存够但内存不够怎么办?量化格式对不上怎么办?每一个问题都需要时间和经验去堆。

而Ollama的思路是把这些决策都替你做掉,或者用几个环境变量就能调。比如模型自动按空闲显存选择加载,比如统一使用GGUF量化格式压缩体积,比如内置的并发队列自动处理同时进来的多个请求。对99%的使用场景来说,这套默认策略已经够聪明。

当然,这也带来了一个限制:你对底层控制的自由度变低了。如果要做研究性质的自定义算子、新架构验证、特殊采样策略,Ollama未必合适。但那不是我们普通用户需要操心的事。

2.3 硬件要求:先掂量自己的机器

这是你在动手之前必须搞清楚的一件事。本地跑大模型,本质是"用空间换性能"和"用内存装模型"的游戏。模型越大,效果越好,但占用的内存/显存也越多。

我结合DeepSeek系列常见尺寸给一个参考表,不同参数量对应的大致内存需求基于当前量化格式,实际以版本为准:

模型尺寸约需内存/显存适合人群运行体验
7B级别6~8GB入门、日常对话CPU也能勉强跑
14B级别12~16GB追求更好质量推荐至少8GB显存
32B级别24~32GB进阶用户需要较好显卡或大内存
70B级别48~64GB探索极限建议多卡或纯CPU大内存

如果你的机器是16GB内存的笔记本,没有独立显卡或者显卡显存只有4~6GB,我建议从7B~8B级别开始用。这个级别在CPU模式下做问答、总结、代码生成已经能看,就是慢一些。如果手头有16GB以上显存的显卡,14B甚至32B级别用起来就是完全不同的体验。

判断标准很简单:你的硬件决定了你适合哪个模型,而不是你的需求。别一开始就冲最大的模型,跑不动只会白白消耗你的耐心。

3. 全平台安装:Windows、macOS、Linux 一次说清

3.1 Windows 安装与验证

Windows端的安装方式可以说是无脑装。先去Ollama官网下载Windows安装包,下载回来是一个exe文件,双击运行,一路默认设置装完就行。安装包会自动帮你配置好命令行工具和后台服务,不需要你手动加环境变量。

装完之后重新开一个终端窗口,先检查一下工具是否正常识别:

ollama --version

如果输出版本号,比如ollama version 0.x.x,就说明安装成功。没有的话,先检查安装路径是否写入了PATH,或者重启一下终端窗口再试。

Windows用户的显存检测也建议做一下。用下面命令看你的显卡信息,确认驱动是否正常:

nvidia-smi

如果这个命令没输出,说明你的显卡驱动有问题,或者你的显卡不支持CUDA。前者去更新驱动,后者就只能用CPU模式跑了,模型选小一号就行。

3.2 macOS 安装与验证

macOS用户分两种情况。Intel芯片的机器,直接在官网下载对应的安装包,拖到Applications目录即可。Apple Silicon芯片的机器,我更推荐用Homebrew安装,方便后续管理和升级:

brew install ollama

装完同样验证一下:

ollama --version

Apple Silicon是跑本地模型的一把好手,统一内存架构意味着你的内存可以作为显存用。M系列芯片配16GB以上内存跑7B~14B模型,效果相当不错。需要注意的是,Intel芯片的老款MacBook跑稍大的模型会比较吃力,建议从7B级别起步。

3.3 Linux 服务器部署

如果你想把模型部署在一台无显示器的服务器上,Linux安装方式也很简单。官方提供了一键脚本:

curl -fsSL https://ollama.com/install.sh | sh

这个脚本会自动识别你的发行版、下载对应安装包、配置systemd服务。安装完成后,服务默认监听在127.0.0.1:11434,你可以随时通过ollama serve手动启动,或者直接使用后台服务。

服务器部署最关键的一步是确认服务状态:

systemctl status ollama

如果是active (running),说明后台服务已经起来了。这时候在服务器本机试跑一个模型,确认GPU或者CPU推理都正常。

3.4 安装后第一时间该做的事

环境装完,先别急着满世界下载模型,先做三件事:

  1. 确认默认模型目录。Ollama会把下载的模型放在用户目录下的.ollama/models里面。如果你想存到别的盘或别的路径,通过设置OLLAMA_MODELS环境变量改变。
  2. 确认是否开启了外部访问。如果只是本机用,默认配置就好。如果需要局域网内其他机器访问,必须把服务监听地址改到0.0.0.0:11434,这个下面API部分会讲到。
  3. 检查磁盘空间。一个7B模型大约4~6GB,14B模型大约9~12GB,磁盘太紧会很被动。

这三件事搞完,安装阶段的活就算干彻底了。

4. 模型选型与下载运行实战

4.1 不同尺寸模型怎么选

现在Ollama的模型库里有大量DeepSeek系列的版本,主要区别就是参数量。我在前面提过,参数量越大,内存占用越高,质量也越好。但在实际选型时,除了内存,你还要想清楚自己的用途。

我的建议很简单:

  • 日常聊天、文本总结、写邮件、辅助思考:7B~8B足够了,速度最快,响应也流畅。
  • 代码生成、逻辑分析、中等复杂任务:14B是甜点位,质量明显上台阶,硬件要求也不算过分。
  • 深度推理、长文写作、复杂任务:32B以上,前提是你的硬件能撑住。

还有一个很多人忽略的因素:中文能力。DeepSeek系列本身就是中文友好的模型,即便小尺寸的7B版本,在处理中文时也远比其他一些英文为主的模型自然得多。这也是我推荐它做本地中文助手的重要原因。

4.2 下载模型的完整流程

模型下载其实非常简单,核心命令就一行:

ollama run deepseek-r1:7b

第一次执行时,Ollama会自动去官方模型库下载对应的权重文件,下载过程中终端会显示进度条。等待下载完成后,它会直接进入一个交互式对话界面,你可以在里面输入问题聊天。

如果想预先把模型下载好,不启动对话,可以用ollama pull:

ollama pull deepseek-r1:14b

这会让模型文件下载到你本地,之后再用ollama run就秒进了。

我建议第一次跑模型之前,先看一下当前已经下载了哪些模型:

ollama list

然后查看当前加载情况:

ollama ps

ollama ps能看到模型是否已经加载到内存/显存、当前上下文大小、正在处理的请求数,这个在排查性能问题时经常用。

4.3 首次运行体验与常用交互技巧

当你进入ollama run的交互界面之后,可以直接输入文字提问。但很多人不知道一个基本逻辑:这里的模型默认没有记忆能力,它只基于你当前这一轮上下文来回答。如果想要长期对话,必须让每次请求携带历史消息,这也是后面讲API时非常关键的一点。

交互界面下有几个实用的快捷键和命令:

  • /bye退出对话面板。
  • /set查看当前会话的模型参数。
  • /set parameters temperature 0.7调整生成随机性。
  • 重新输入问题继续对话即可。

第一次用的时候,我建议你测几个典型的任务类型:写一段代码、总结一篇文章、翻译一段文字、做一次逻辑推理。通过这几类测试,你能很快判断这个尺寸的模型是否满足你的核心需求。如果发现质量差强人意,再考虑换更大尺寸的版本,或者调高temperature获得更多样化的回答。

5. 把一个本地模型变成“私有API服务”

5.1 OpenAI兼容API的本地调用方式

跑交互式对话只是第一步,很多人真正需要的是把本地模型作为后端API来用,这样自己的项目代码就能像调用外部接口一样调用本地模型,同时完全不用改业务逻辑。

Ollama内置的这个功能就很关键:它在本地启动服务之后,默认暴露了一套与OpenAI格式兼容的API接口。这意味着,只要你原本的代码是用OpenAI SDK写的,只需要把base_url改成http://localhost:11434/v1,把API key随便填一个占位符,代码几乎不需要其他改动就能切到本地模型。

Python代码示例:

from openai import OpenAI client = OpenAI( base_url="http://localhost:11434/v1", api_key="ollama" ) resp = client.chat.completions.create( model="deepseek-r1:7b", messages=[ {"role": "system", "content": "你是一个专业的中文写作助手。"}, {"role": "user", "content": "帮我写一段产品介绍,200字左右。"} ], stream=True ) for chunk in resp: print(chunk.choices[0].delta.content or "", end="")

跑起来之后,你的程序就跟连了外部分大模型API一样工作,区别只是请求全部发生在本地。响应速度受硬件影响,但没有任何计费逻辑。

5.2 让局域网内的设备也能访问

很多人的需求不止于本机,还想让同一局域网内的其他电脑、手机也能调用。这时需要做两个设置。

第一步,启动Ollama服务时指定监听地址:

OLLAMA_HOST=0.0.0.0:11434 ollama serve

Windows用户要注意,如果Ollama已经作为后台服务在运行,直接用命令行启动可能会冲突。你需要先在系统托盘退出Ollama,然后再用命令行启动。或者更推荐的做法是,将环境变量OLLAMA_HOST设为0.0.0.0,然后重启Ollama服务。

第二步,其他设备调用时,base_url改成服务器在局域网内的IP,比如:

http://192.168.1.100:11434/v1

这样局域网内的每台设备都能把模型当共享服务使用。但要注意,这样配置意味着同网段的任何人都能访问你的API,如果要在不可信网络环境运行,建议通过防火墙做IP白名单限制。我自己的习惯是:本机开发用默认的127.0.0.1,真正共享时才开0.0.0.0,用完及时关掉。

5.3 并发与上下文配置调优

部署完成后,很多人会遇到一个问题:为什么并发一高就报错,或者模型回答突然变慢?这往往不是模型本身的问题,而是Ollama的默认配置没有针对你的场景调整。

几个常用的环境变量如下:

环境变量作用我的建议
OLLAMA_MAX_LOADED_MODELS同时驻留内存的模型数量1,避免显存被多个模型瓜分
OLLAMA_NUM_PARALLEL每个模型并行处理请求数4~8,过高会导致显存溢出
OLLAMA_KEEP_ALIVE模型加载后保持驻留的时间5m或10m,频繁调用建议设更长
OLLAMA_MAX_QUEUE请求排队上限512,防突发请求拖垮服务
OLLAMA_CONTEXT_LENGTH默认上下文长度根据内存调整,7B设4096起步

关于上下文长度,这是一个重要但不常被提及的参数。上下文越长,模型能记住的历史信息越多,但显存和内存占用也越高。如果你的模型经常回答到一半出现"不记得前面说了什么",往往是上下文长度设置太小,可以适当调大。相反,如果显存占用总是接近上限,适当减小上下文长度是最快的解法。

另外,OLLAMA_KEEP_ALIVE特别值得提。默认模型在处理完请求后会在内存里驻留一段时间,如果在这个窗口内再次收到请求,就不用重新加载权重,响应速度会快很多。对于交互频繁的场景,把keep-alive时间拉长可以有效避免反复加载带来的卡顿。

5.4 利用量化参数换取速度

你可能会发现同一个模型在Ollama里可能有好几个版本,典型的如deepseek-r1:7b和deepseek-r1:7b-q4_K_M。后缀里的q4_K_M表示量化精度。量化本质上是把模型的权重从高精度压缩到低精度,体积变小、占用变少、速度变快,代价是质量可能略有下降。

对绝大多数本地部署场景,我推荐使用带q4_K_M或q5_K_M后缀的量化版本,它们是在体积、速度和效果之间最平衡的选择。全精度版本(不带后缀)非常适合那些图形卡显存极其充足、追求极限质量的用户。如果你在16GB显存上跑14B模型觉得紧张,试一下量化版本,显存占用立刻会低一个档次。

顺带提一下,Ollama下载时默认会拉取tag里标记的版本,不同tag之间下载内容是独立的,跑之前用ollama list看清你拉的是哪个版本,别到时候怀疑自己模型装错了。

6. 常见问题与排查实录

6.1 安装失败:命令行不识别怎么办

Windows上最容易遇到这个问题。明明是双击安装包装完了,打开终端输ollama却提示"不是内部或外部命令"。原因基本就是安装目录没有写进PATH,或者你安装之后没有重新打开终端。

处理办法:手动找到Ollama的安装目录,通常是%LOCALAPPDATA%\Programs\Ollama,然后把该目录加到系统PATH里,加完重启终端。Linux用户如果curl | sh脚本执行中途断了,重新执行一次脚本通常就修复了。

6.2 模型下载慢或者中途失败

这是国内网络环境下最常遇到的问题,现象就是进度条卡在某个百分比不动,或者等了好久终于下载完,运行时提示文件损坏。模型文件动辄好几GB,加上网络不稳定,很容易出问题。

我实测有效的几个办法:

  1. 下载过程中保持终端唤醒,别让电脑休眠。
  2. 如果中途失败,先执行ollama rm删除半成品,再重新ollama pull,不要在原错误文件基础上继续。
  3. 多次失败后,尝试从本地快速下载好的镜像源或缓存服务器获取模型文件。
  4. 更稳妥的做法:直接用ollama create从GGUF文件导入模型,你可以先从开源模型社区下载GGUF权重,再用下面的命令生成模型:
ollama create mymodel -f ./Modelfile

Modelfile的写法很简单:

FROM ./deepseek-r1-7b.gguf

这种方式的好处是下载走普通文件下载工具,可以断点续传和校验,明显比让Ollama内部下载更可控。亲测对大文件非常管用。

6.3 显存不足:模型怎么都加载不进显卡怎么办

如果你用的是独立显卡,显存是8GB,却非要跑14B甚至更大模型,Ollama会退回到CPU模式,速度让人崩溃。这不算错误,但体验极差。

一种方法是更换量化程度更高的版本,显存占用会明显下降。另一种方法是接受CPU推理的现实,把模型留给后台慢慢跑,只做非实时任务。最实用的一种方法是设置部分层加载到GPU:

`OLLAMA_USE_GPU=0` 全用CPU,不推荐。

其实Ollama会自动根据显存决定层分配,但有时它判断不够聪明,可以用ollama ps观察实际加载了多少层到GPU,如果全部在CPU,那基本就是显存完全不够。这时不如直接换小模型。

6.4 回答速度慢:优化操作系统的硬件调度

同样一个模型,在不同机器上速度差好几倍,原因往往不在模型,而在调度配置。这里说几个有效的提速思路:

  • 优先用GPU推理,避免把模型全压在CPU上。想办法让模型权重尽可能多地驻留在显卡显存里。
  • CPU模式时,尽量保证电脑没有其他大型任务抢CPU资源。
  • 调整上下文长度,上下文越短,单次推理耗时越少。
  • 使用流式输出,第一个Token出来的速度直接影响使用体验,流式会好很多。

顺带提一个经验:如果机器内存偏小,尽量关闭浏览器里大量标签页再跑模型,避免系统因为内存紧张开始使用交换分区,那会严重拖慢运行速度。

6.5 想要一个更好看的聊天界面

命令行交互虽然够用,但很多人希望有一个像网页版那样的聊天界面。Ollama本身不带图形界面,但有现成的开源方案可以直接接上。

比较常用的做法是用Open WebUI这类组件,它可以部署在本地,连接到Ollama的API,提供类似网页版的分栏式对话体验。启动后你在浏览器访问,就能选模型、管理对话历史、调整参数。如果只是临时想体验,也可以先继续用命令行交互。这两者之间并没有冲突,完全可以并存。

我喜欢的一个组合是:命令行应付日常快速测试,网页端承担深度对话和管理长会话,再配合前面说的API接入业务系统,一套模型三个入口,各自干各自最擅长的活。

最后再分享几个实际心得

这套东西我前后搭过好几遍,踩过的坑比写出来的多。一次最典型的经历是在一台只有16GB统一内存的笔记本上,我一开始直接拉了一个14B模型,Ollama倒是顺利加载了,但整个系统卡到鼠标都飘。后来老老实实换成7B量化版,整个体验流畅到像换了一台电脑。这件事之后我给自己定了一条规矩:先看硬件容量再定模型尺寸,而不是先定目标再硬扛。

还有一点值得提醒:不要追求一次部署到位的完美主义。先用小模型把整条链路跑通,再从模型列表里换更大的版本,是一个更理性的路径。部署链路本身没问题后,后续升级模型只是一条命令的事。

如果你后续想把这个能力扩展到团队内部使用,我建议把局域网访问和基础鉴权早早地做好,越早越好。等到业务真的跑起来再补这些基础设施,那才是真的手忙脚乱。希望这篇实战记录能让你少走一点弯路,把大模型的能力稳稳地握在自己手里。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/23 1:21:45

MoE大模型本地量化部署实战:2位到6位精度选择与llama.cpp调优

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

作者头像 李华
网站建设 2026/10/23 1:21:31

局域网互联与VLAN:从交换机、STP到骨干网实战

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

作者头像 李华
网站建设 2026/10/23 1:21:18

Visual Studio调试快捷键详解:提升代码排查效率的实战指南

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

作者头像 李华
网站建设 2026/10/23 1:20:57

Windows开机时间溯源:四层时间锚点与Fast Startup陷阱

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

作者头像 李华
网站建设 2026/10/23 1:20:54

Windows运行库修复原理与安全实践指南

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

作者头像 李华
网站建设 2026/10/23 1:20:31

手写滑动验证码:前端Canvas生成缺口与后端行为风控实战

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

作者头像 李华