Java开发者如何抓住AI应用红利:从Spring AI到LangChain4j的落地实践
1. AI应用开发红利期Java开发者的机会窗口先说结论AI应用开发这波红利绝不是Python开发者的专属饭。某知名市场研究机构2025年发布的行业报告显示AI应用层开发的市场规模正在以远超预期的速度膨胀而这里面最缺的恰恰是具备企业级工程能力的开发者——这正是Java开发者最擅长的领域。别被网上一堆“AI时代Java要完”的论调带偏那是贩卖焦虑博眼球用的。真实情况是大量传统企业的业务系统跑在Java技术栈上他们想接入AI能力但Python团队不懂业务系统AI团队不懂事务一致性桥接两端的角色严重空缺。这份报告里有一个数据特别值得关注企业AI应用开发中超过六成的落地场景属于业务流程增强、数据决策辅助、系统自动化运维这类“传统AI”融合场景而不是从零训练大模型那种纯研究型项目。这意味着Java开发者不需要去卷算法、卷模型训练只要掌握怎么把现成的大模型能力接入到企业系统里就能吃到这波红利。我周围已经有不少朋友靠着Spring Boot AI接口的组合给公司做了内部知识库问答、工单自动分派这类工具有的甚至成了部门核心项目。再说适合谁。如果你是刚入门的小白正在纠结学Java还是转Python这篇文章能帮你理清Java在AI时代的生态位如果你是工作了几年的Java程序员担心技术栈被淘汰这篇文章会给你一条明确的转型路径。我把自己的实践经验、踩过的坑、以及当前Java AI生态里真正能落地的工具方案都拆开讲清楚按照这篇文章的路线走你完全可以在一到两周内做出第一个能用的AI应用。2. 技术选型为什么Java迁AI应用开发比你想象的顺2.1 Java AI生态的成熟度盘点很多人提到AI开发就默认要用Python原因是AI框架和大模型SDK大多优先支持Python。但那是模型训练层的逻辑到了应用开发层情况完全不一样。应用层要解决的是接口调用、数据格式转换、业务逻辑编排、权限控制、结果持久化这些问题——这些都是Java的看家本领。2025年的今天Java侧的AI开发工具链已经很完整。Spring官方推出了Spring AI项目专门做大模型集成LangChain4j把LangChain的那套链式调用、Agent机制、记忆管理搬到了JVM生态Hugging Face的Java客户端、Ollama的Java API也都稳定可用。更别说JDK 21带来的虚拟线程处理并发AI请求时性能直追Go这让Java在AI应用层的竞争力又上了一个台阶。从实际招聘需求来看我观察到的一个趋势是懂大模型API调用、会写提示词、能把这些能力集成进Spring Cloud微服务体系的Java工程师报价普遍比同级别的纯业务开发高出30%到50%。市场要的不是能训练模型的算法天才而是能把模型能力变成稳定业务功能的工程人才。2.2 对比Python路线的真实优劣势网上总有人拿“Python写AI更简单”说事这句话半对半错。如果你的目标是做数据分析和模型微调Python确实更顺手但如果你的目标是把AI能力嵌入到已有的Java系统中坚持用Python意味着你要维护两套技术栈中间还得靠HTTP服务或者消息队列做桥接复杂度反而上去了。我举一个实际例子。某公司有个老旧的库存管理系统全套Spring Boot架构现在想加一个“智能补货建议”功能。如果用Python你得单独起一个FastAPI服务处理鉴权、跨域、数据同步一堆破事两个服务之间还要考虑数据一致性。但直接用Spring AI你可以在原项目里加一个类、写几个方法调大模型接口返回补货建议跟原有的事务管理、权限体系无缝集成。两种方案的工作量差距非常明显。当然Java路线也有痛点。最典型的是AI相关的Python库生态实在丰富Java侧能找到的现成组件相对少一些有时得自己动手封装。另外网上AI开发的教程大量基于PythonJava开发者想找参考资料辛苦很多。但随着Spring AI和LangChain4j的文档逐渐完善这个问题正在被快速解决。3. 三条切入路径Java开发者怎么迈出第一步3.1 首选Spring AI企业级集成的正统方案如果你已经在用Spring Boot那切入AI开发最平滑的方式就是Spring AI。这个项目的思路是把大模型封装成类似JdbcTemplate那样的组件开发者不需要关心底层API细节只需要注入一个接口就能调用模型能力。我建议先做这么一个小实验创建一个Spring Boot项目引入spring-ai-openai-spring-boot-starter或者对应你所用模型的starter在application.yml里配置好API Key和模型名称然后写一个Controller调用ChatClient接口。前后不到半小时你就能体验到“在Java代码里调用大模型”的爽感。这和当年从JDBC过渡到MyBatis的体验很像——底层原理没变但开发效率提升明显。这里有一个关键建议刚开始不要执着于搭建复杂的Agent框架先用最简单的方式跑通一个对话接口理解请求参数、响应结构、Token计费这几个核心概念再逐步加功能。3.2 进阶LangChain4j复杂AI逻辑的编排利器当你的需求从“单轮问答”升级到“多步骤推理”时Spring AI那种直来直去的调用方式就不够用了。比如你想做一个“智能招聘助手”它需要先解析简历PDF再提取候选人关键信息接着与职位要求做匹配打分最后生成面试问题——这是一个多步骤、有依赖关系的流程需要编排能力。LangChain4j在JVM生态里填补的就是这个空缺。它的核心概念包括AiServicesAI服务接口、Memory对话记忆、Tool工具调用、RAG检索增强生成。我看到很多团队给业务系统做智能客服时就是用它把知识库检索、上下文管理、答案生成的流程串起来稳定性相当不错。需要提醒的是LangChain4j的接口设计一直在快速迭代版本升级偶尔会有破坏性变更。我自己的习惯是锁定一个稳定版本使用不要频繁追新避免踩到兼容性坑。3.3 本地化部署私有化AI应用的低成本方案还有一条越来越多人关注的路径本地化部署模型。原因很简单有些企业对数据隐私要求极高不允许把业务数据发送到外部大模型接口。这时候就轮到Ollama这类工具出场了。在Java里调用Ollama本质上就是一次HTTP请求Ollama提供了标准的REST API返回格式与OpenAI兼容。我在实际项目中用Spring的RestClient封装过Ollama的调用代码量极少效果却很好。跑一个7B甚至13B的量化模型在32G内存的机器上做内部问答响应速度完全能接受。这条路线的成本优势非常明显不需要按Token付费一次性硬件投入可以反复使用。但代价是你需要自己处理模型选择和调优的问题——模型太小回答质量差模型太大硬件跑不动。我的经验是从qwen2.5:7b这类性价比高的模型起步优先满足业务需求。4. 实战记录我如何用Java搭出一个AI知识库助手4.1 项目结构与核心代码解析理论铺垫得差不多了下面分享一个我最近完成的实战项目一个基于Spring AI RAG方案的企业内部知识库助手。它能回答员工关于公司制度、技术文档的问题。说下整体思路先离线把知识文档进行向量化处理存入向量数据库用户提问时先做相似度检索把相关文档片段和问题一起交给大模型最终生成带依据的回答。项目结构非常清晰核心模块只有三个。文档处理模块负责读取PDF和Word文件并切分成片段检索模块使用向量数据库存储和检索嵌入对话模块负责组装上下文并调用大模型。关键代码大致是这样// 文档加载与向量化 Bean public VectorStore vectorStore(EmbeddingModel embeddingModel) { return new SimpleVectorStore(embeddingModel); } // 启动时自动导入文档 Component public class DocImporter { private final VectorStore vectorStore; private final SimpleDocumentReader reader; public void importDocs(ListPath paths) { ListDocument docs paths.stream() .map(reader::read) .flatMap(List::stream) .toList(); vectorStore.add(docs); } } // 问答接口 RestController public class ChatController { private final ChatClient chatClient; private final VectorStore vectorStore; PostMapping(/ask) public String ask(RequestBody String question) { // 向量检索相关文档 ListDocument related vectorStore .similaritySearch(SearchRequest.query(question) .withTopK(3)); // 组装提示词系统指令 文档片段 用户问题 Prompt prompt buildPrompt(question, related); return chatClient.call(prompt).getResult().getOutput().getContent(); } }这里我踩过的一个大坑是文档切分。一开始我用固定字符数切分文档结果经常把一段完整语义拦腰截断导致检索效果很差。后来改用按段落切分、再按语义合并的策略——简单说就是尽量保持自然段完整超过最大长度再从句子边界切。就这一个改动回答质量肉眼可见地提升了一个档次。4.2 参数调优与成本控制的实操经验AI应用和传统应用一个最大的区别每一次调用都在产生成本而且随着调用量增长成本不是线性的。我在这个项目里总结了三层成本控制手段。第一层是模型选择。日常问答用轻量模型复杂推理才用大模型。我通过一个简单的关键词匹配规则做分流——问题里带“报销流程”“年假制度”这类明确主题词时直接走小模型带“综合分析”“给出建议”这类开放表述时才调用大模型。效果很好成本直接砍掉一半以上。第二层是缓存策略。对于相似的查询短时间内没必要重复调用大模型。我用Spring Cache做个简单缓存Key是问题内容的哈希值TTL设置为5分钟。这在内部工具场景下特别有效因为大家问的问题重复度很高。实测缓存命中率能达到三成左右。第三层是Token预算管理。在提示词层面我会显式限定回答长度例如“控制在200字以内”并设置maxTokens参数。这是一道硬保险。而且我建议在Spring AI的配置里把maxTokens设置为一个合理的上限防止某次异常输入导致大额Token消耗。4.3 用户体验设计流式输出的正确姿势如果AI应用回答一个问题要等十几秒才有结果用户的体感会非常差。先不说业务方满不满意你自己在调试过程中就会烦躁。解决方案是流式输出Streaming也就是让模型边生成边返回内容用户看到的是逐字输出的效果。Spring AI对流式输出的支持非常友好核心就一句话把ChatClient的call方法换成stream方法方法返回Flux对象再通过WebFlux的SseEmitter把内容推给前端。我体验下来改造工作量很小对用户体验的提升立竿见影。这里有个建议即使你的后端是传统的Spring MVC也不建议为了AI应用强行引入WebFlux全家桶。轻量做法是直接用ResponseBodyEmitter配合生产端逐块发送前端拿EventSource接收即可。还有一个容易被忽略的细节超时时间。普通HTTP接口超时设置个30秒没问题但流式接口可能持续输出一两分钟网关层和HTTP客户端的超时阈值都要调大。因为这个我线上踩过坑——压测时发现用户那边回答到一半断了排查半天才发现是Nginx的proxy_read_timeout默认60秒在作怪。5. Java开发AI应用的高频坑我踩过的都在这5.1 模型响应格式不稳定的处理思路大模型默认返回的是自然语言文本但很多业务系统需要的是结构化数据。比如你想让模型从一条工单描述里提取“紧急程度”“故障类型”“责任部门”三个字段直接问可能得到“高#网络#IT部”这种格式跟预期的JSON完全不同。我的应对方案有两个。第一是在提示词里给出严格的格式说明和示例明确要求“只输出JSON不要任何解释”。经过调优大部分情况下模型都会乖乖按格式输出。第二才是重点——不要相信模型100%按格式输出代码里一定要做容错处理。我用Jackson解析返回结果时会先尝试正常解析失败再清洗文本中的标记符号后二次解析还不行就返回一个默认结构并打日志。注意提示词里加示例是最有效的引导手段成本为零但效果显著。宁可多写几个示例也不要指望模型凭空理解你的格式要求。5.2 并发控制与流量冲击我把应用上线第一天就迎来了一个“惊喜”办公时间大家同时使用瞬间几十个并发请求涌进来。大模型接口的响应速度比较慢每个请求平均占用连接三五秒线程池直接被占满后续请求全部排队接口响应时间从1秒飙升到15秒。事后复盘我做了三个改进。一是给AI接口单独配置线程池避免和业务接口互相抢占资源。二是引入信号量限流高峰期直接拒绝超量请求并返回提示。三是对外部模型API调用加了重试机制自动处理瞬时的超时和限流错误。这块的配置大致如下spring: ai: openai: base-url: https://your-model-endpoint api-key: ${AI_API_KEY} chat: options: model: your-chat-model temperature: 0.7 max-tokens: 1024 # 自定义线程池 ai: thread-pool: core-size: 10 max-size: 20 queue-capacity: 50这里有一个很重要的理念转变AI应用和普通接口不一样你不能指望它像查询数据库一样快速返回。把外部AI调用当成一次“慢操作”来设计整个调用链隔离线程池、设置合理超时、预留队列这些措施缺一不可。5.3 提示词工程的日常调试心得我对提示词工程的态度是它是一门“经验科学”没有绝对的对错只有反复调试后的相对最优。所以我的习惯是建一个提示词测试笔记本每一条提示词都记录版本号、测试问题和调整原因。不要觉得这很麻烦等出问题需要回退版本时你会感谢自己当初的这个习惯。给大家分享一个我常用的提示词模板适用于绝大多数企业内部的问答场景你是公司的智能助手负责回答员工关于公司制度和流程的问题。 回答要求 1. 只根据提供的资料回答资料中不存在的信息不要编造 2. 如果资料不足请明确说“建议咨询人事部门” 3. 回答控制在200字以内 4. 用简洁、正式的中文表达 相关资料 {检索到的文档片段} 用户问题 {用户的问题}这个小模板解决了三个问题知识来源可控不编造、边界清晰何时该转人工、输出长度可控省钱又省阅读时间。根据我的经验初版提示词不用追求完美先跑起来再根据实际效果迭代调整效率更高。6. 常见问题排查速查表我盘点了一下这几个月帮社区朋友看过的AI应用问题发现大部分坑都特别集中。这里统一整理成一张速查表希望能帮大家少走弯路。症状常见原因处理办法调用接口报连接超时网络策略限制外部域名访问检查服务所在网络的公网访问权限配置代理或改用内网模型网关返回内容带问号或乱码模型输出非UTF-8字符传输层编码设置错误检查HTTP客户端编码设置统一使用UTF-8请求头加charset回答内容明显答非所问检索召回的相关文档不准确调高TopK值检查文档切分逻辑优化查询关键词提取同一问题有时好有时差模型采样参数Temperature过高对事实类问题把Temperature降到0.1到0.3之间Token消耗异常快上下文无限制累积、提示词过于冗余设置上下文窗口大小定期裁剪历史消息精简系统提示词大量请求排队堆积线程池过小或外部模型限流增大线程池核心线程数或引入队列消峰必要时启用熔断降级流式输出中间中断网关超时或客户端连接被重置调大代理超时时间前端做好断线重连和错误提示这张表不是标准答案但覆盖了我在真实项目中反复遇到的高频问题。如果你恰好碰上表里的场景照方抓药基本能解决问题如果没解决多半是环境层面的特殊问题需要结合日志具体分析。7. 长期视角Java开发者在AI时代的路线图建议聊完了具体技术和踩坑经验最后说点更长期的东西。很多人关心Java开发者在AI时代会不会被边缘化我的观察是不会被边缘化但“只会写CRUD的Java开发者”确实会越来越被动。关键在于你要让自己从“业务代码执行者”升级为“业务AI能力整合者”。我建议按三个季度来规划能力升级。第一个季度重点掌握大模型API调用和提示词工程基础把所有相关概念Token、Embedding、Temperature、TopP搞明白能够独立做出一个对话机器人Demo。第二个季度重点掌握RAG检索增强生成和服务集成学会向量数据库的使用把AI能力嵌入到真实的业务模块中。第三个季度重点掌握Agent机制和复杂工作流编排接触LangChain4j的更多高级功能尝试独立设计一个多步骤的智能业务助手。这条路线不要求你成为算法专家但需要你持续保持对新技术的好奇心。我的经验是每周抽几个小时看看Java AI生态的更新日志比临时抱佛脚高效得多。另外说句掏心窝的话如果你的团队已经有项目在尝试接入AI能力哪怕只是做个内部小工具挤进去参与一下都值。AI开发这片区域纯理论学习和实际做项目之间的距离比想象中要大得多。只有真实踩过那些超时、乱码、Token超预算的坑你才算真正入了门。

相关新闻

Learn-Web-Hacking 深入解析:PHP 流(Streams)体系、封装协议与 php://filter 安全利用

Learn-Web-Hacking 深入解析:PHP 流(Streams)体系、封装协议与 php://filter 安全利用

文档网络安全教程 【免费下载链接】Learn-Web-Hacking Study Notes For Web Hacking / Web安全学习笔记 项目地址: https://gitcode.com/gh_mirrors/le/Learn-Web-Hacking 点击查看 免费下载 导读:PHP 流(Streams)自 PHP 4.3 引入…

2026/10/13 4:07:00 阅读更多 →
Flask实战:从零搭建在线教育平台的核心实现与避坑指南

Flask实战:从零搭建在线教育平台的核心实现与避坑指南

去年做模拟项目X的时候,接了一个比较完整的活儿:从零搭一个python网络课程在线学习平台。这类项目听起来好像就是“课程列表视频播放”,但真正动手才发现,一个能被老师真正拿去用、学生愿意天天打开的平台,背后牵扯的模…

2026/10/13 4:06:00 阅读更多 →
工业条码打印机与云标签平台协同:标签模板、权限与数据对接的落地实践

工业条码打印机与云标签平台协同:标签模板、权限与数据对接的落地实践

很多人以为标签打印就是把标签纸塞进打印机,点一下打印就完事。真在企业里跑过一轮就明白,事情远没有这么简单:仓库要资产标签、生产线上要料号标签、电商发货要面单和合格证、行政固定资产要贴标……每套标签格式不一样,模板分散…

2026/10/13 4:06:00 阅读更多 →

最新新闻

AI画图总翻车?四万星开源项目教你用约束策略告别Mermaid Slop

AI画图总翻车?四万星开源项目教你用约束策略告别Mermaid Slop

1. 当AI画的架构图开始“辣眼睛”,这个四万星项目到底在解决什么如果你最近一年用过任何主流大模型来生成架构图、流程图或者时序图,大概率经历过这样一种崩溃:你满怀期待地输入一段描述,AI 信心满满地吐出一大段 Mermaid 代码&am…

2026/10/13 4:55:17 阅读更多 →
Agent技能体系设计:从技能注册、路由到容错与评测的工程实践

Agent技能体系设计:从技能注册、路由到容错与评测的工程实践

1. 从"技能"这个词说起:为什么Agent需要一套技能体系第一次看到"agent-skills"这个组合词,很多人会下意识地把它理解成"给智能体加几个工具函数"。我一开始也是这么想的,直到真正动手把一个只会聊天的智能体改…

2026/10/13 4:55:17 阅读更多 →
litellm实战:搭建大模型统一网关,实现多模型接入与成本控制

litellm实战:搭建大模型统一网关,实现多模型接入与成本控制

litellm 这个项目,我第一次注意到它是因为实在被“多模型调用”这件事烦到了。手头同时维护着几个大模型平台的接入:各自的路由地址不一样,鉴权头不一样,错误码五花八门,连流式返回的字段都对不齐。每次产品想换个模型…

2026/10/13 4:55:17 阅读更多 →
时序差分控制算法详解:从Sarsa到双Q学习的原理与实战

时序差分控制算法详解:从Sarsa到双Q学习的原理与实战

1. 从动态规划到无模型控制:为什么需要时序差分如果你已经啃过强化学习的基础部分,大概率会有一种割裂感:动态规划那一章讲得头头是道,策略迭代、值迭代推导得严丝合缝,但一合上书就发现一个致命问题——它要求你完全知…

2026/10/13 4:55:17 阅读更多 →
litellm统一大模型调用接口:架构解析与部署实践

litellm统一大模型调用接口:架构解析与部署实践

1. 项目概述与核心定位1.1 这个项目到底解决什么问题第一次接触 litellm 是在一个多模型混用的项目里。当时团队同时接入了好几个不同厂商的大模型服务,每个平台的接口规范、鉴权方式、返回结构都不一样,代码里到处是 if-else 分支,维护起来非…

2026/10/13 4:55:17 阅读更多 →
litellm 统一模型调用中间层:多模型路由与成本优化实战

litellm 统一模型调用中间层:多模型路由与成本优化实战

1. 为什么一个接口层能省下我一半的对接时间第一次接触 litellm 是在一个多模型混用的项目里。当时业务侧要求同时接入好几家不同厂商的大模型服务,有的走 OpenAI 风格接口,有的走自家私有协议,还有的只提供流式输出。最开始的方案是给每家写…

2026/10/13 4:54:17 阅读更多 →

日新闻

物联网系统集成避坑指南:从选型到验收的关键要点

物联网系统集成避坑指南:从选型到验收的关键要点

做了这么多年物联网系统集成的项目,我最大的感受是,大部分坑不是出在技术前沿,而是出在一些看起来很平常的地方。设备选了便宜的、协议没问清楚、现场没摸透、验收标准写得含糊——这些细枝末节,最后都会变成延期、超支和扯皮的大…

2026/10/13 0:00:57 阅读更多 →
ESP32舵机控制全攻略:从PWM原理到高级玩法与常见故障排查

ESP32舵机控制全攻略:从PWM原理到高级玩法与常见故障排查

如果你玩ESP32有一阵子了,很难不碰到舵机控制这道坎。做智能小车要转方向,做机械臂要抬关节,做云台要偏航俯仰,背后都是同一个东西在干活:舵机。而我见过太多人卡在“代码能编译、舵机就是不听话”这个阶段&#xff0c…

2026/10/13 0:00:57 阅读更多 →
CAN总线原理与STM32实战:抗干扰、仲裁、错误处理全解析

CAN总线原理与STM32实战:抗干扰、仲裁、错误处理全解析

1. 为什么CAN总线至今仍是工业现场的“硬通货”?——从汽车底盘到智能温室的真实需求你有没有拆过一辆老款燃油车的中控台?或者调试过某高校实验室里那台跑着Modbus协议却频频丢帧的PLC控制柜?又或者,在某个农业物联网项目里&…

2026/10/13 0:00:57 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/13 2:54:56 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/12 0:16:38 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/13 1:58:08 阅读更多 →

月新闻

我发现了一个新思路:用 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/12 21:05:09 阅读更多 →
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/12 14:48:49 阅读更多 →
黑夜航拍船只数据集训练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/12 18:11:17 阅读更多 →