从Demo到生产:Spring AI Alibaba Admin工程化实践
做了三年AI应用我的感受是Demo和产品之间隔着一整条生产线。朋友圈里炫的AI聊天机器人、RAG问答神器绝大多数都停在了玩具阶段——本地跑得欢一上生产就崩。这不怪模型怪工程。真正让我觉得AI应用从玩具变成工具的转折点是上个月把一套客服知识库系统完整跑在Spring AI Alibaba Admin这套工程化栈上的时候。这篇文章不聊概念只聊我为什么选它、怎么落地、踩了哪些坑。如果你是那种已经用Python写过几个LangChain脚本、但发现生产环境根本没有脚本容身之地的开发者或者你正在为一个AI项目做技术选型这篇经验贴应该能帮到你。它解决的核心问题只有一个AI应用怎么从能跑变成能上线、能维护、能控制成本。1. 先搞清楚一个事玩具和工具的分界线到底在哪1.1 Demo时代的三宗罪先说说我自己的第一个AI项目。2023年底我用开源模型微调了一个文档问答机器人给同事演示的时候效果炸裂——领导当场拍板要上线。结果呢上线第一个月模型接口超时、Token费用超预算三倍、向量库同步失败导致回答过期、用户问了几个敏感词直接触发幻觉输出了一堆不该有的内容。Collapse这就是典型的玩具级应用。它的特点很一致模型在本地或API上孤零零地跑旁边没有任何工程设施。没有超时控制没有降级方案没有Prompt版本管理没有上下文长度约束没有数据和模型的权限隔离。最致命的是所有的能力都是写死在代码里的——换一个模型要改代码换一套Prompt要改代码连调一个温度参数都要重新打包部署。我后来总结了一句话玩具应用是在伺候模型工具应用是在管理模型。你如果把模型当成一个永远正确的黑盒那它迟早会给你颜色看。工程化不是给模型加补丁而是把模型当成一个不可靠的组件像对待外部API一样做好容错、监控、隔离和降级。1.2 工程化的核心需求清单经历了那次翻车之后我做任何AI项目都会先列一份工程化需求清单。这份清单今天看起来像废话但在实际选型时每一条都会卡掉一堆方案模型层可替换不能和某一个模型供应商深度绑定至少能在大模型、开源模型、多厂商API之间切换上下文和记忆管理会话状态、窗口长度、长期记忆要做成可配置、可观测的组件不能靠手写拼接知识库接入RAG流程要标准化向量库的索引、召回、重排序要有统一抽象请求治理超时、重试、限流、熔断一个都不能少Prompt管理Prompt要能版本化、能动态模板化最好可以在后台改而不用发版可观测性每一次调用都要能追踪Token消耗、延迟、反馈质量安全与权限模型能访问什么数据、谁有权限发起调用必须可控用这个清单去对比市面上的方案你会发现纯粹的大模型API调用、LangChain式脚本、以及某些强调Agent编排的低代码平台都各有短板。它们要么管不住模型层要么管不住数据层要么根本不考虑运维视角。1.3 为什么Spring Boot成了AI工程化的自然土壤在Java生态里做AI应用Spring Boot几乎是绕不开的基座。原因不复杂Java企业应用积累的治理能力太完整了。你随便找一个跑了两年的Spring Boot系统里面一定有现成的鉴权、配置中心、监控告警、限流熔断、链路追踪。把AI能力接进这样的系统等于给模型穿上了一层生产级铠甲。而Spring AI的出现让这件事变得顺理成章。它学的是Spring Data那套思路不同数据库有不同方言但对业务代码暴露的Repository是一样的。Spring AI把不同模型厂商的差异封装成了统一的ChatClient、EmbeddingModel接口业务代码只依赖接口不依赖厂商。Spring AI Alibaba则在国内模型接入、灵活配置方面做了更贴近实际场景的增强加上Admin管理端的思路正好补上了运维治理这块短板。2. 方案选型我为什么没选LangChain也没选纯自研2.1 三种路线的真实对比选型那两周我把主流路线都跑了一遍结论用一张表说清楚方案模型接入工程治理上手成本生产可用度直接用SDK调大模型API强依赖一家厂商几乎没有全要自己写低低LangChain / LlamaIndex多厂商支持但抽象过重比较弱偏研究和原型中中Spring AI Spring AI Alibaba Admin统一接口多云可切换强有运维后台和治理组件中高高LangChain的问题不在于不好用而在于它骨子里还是研究工具。它给了你一万个组件但你得自己证明这些组件在生产环境能扛住并发。我不否认有团队用LangChain做出了生产系统但代价是花费大量精力去补工程短板会话管理、持久化、监控、重试策略每一样都要额外找方案。纯自研就更不必说了光是多模型适配、RAG管线和后台管理这三块就够一个小组忙半年。选Spring AI Alibaba Admin我看中的是模型能力和工程能力的匹配度Spring Boot的成熟生态提供治理底座Spring AI提供统一抽象Spring AI Alibaba补齐国内模型接入和增强功能Admin管理后台解决可观测和配置管理的最后一公里。2.2 Spring AI Alibaba Admin 到底解决了什么很多人第一次看到这个名字会问这不就是一个管理后台吗把它当成后台就理解窄了。Admin在我实际使用中的定位是AI应用的中控台。模型路由规则、Prompt模板、知识库文件、Token额度预警、调用链路追踪这些分散在各系统里的东西在这里集中展示和配置。举一个真实场景上线初期业务方反馈回答风格太生硬希望更口语化。传统做法是改代码里的System Prompt走开发、测试、上线流程半个工作日没了。而在这个框架下Prompt以模板形式存在配置中心运营人员在后台改一条文案刷新即生效。AI应用的迭代速度第一次追上了业务需求的变化速度这件事对生产力的提升比模型本身大得多。2.3 用它就是选了一个标准答案说句实在话选择这个技术栈还有一个隐性收益标准统一。团队里的初级工程师也能照着统一的Controller模板、统一的服务层规范去写AI功能而不是今天学这一段、明天发明那一段。代码的可维护性有时候比技术本身的前沿性重要得多。3. 实操落地五步把AI功能接入企业级应用3.1 环境准备和依赖引入实操部分我用Spring Boot 3.3 Spring AI Alibaba Admin作为基础版本组合项目结构是标准的Maven多模块工程。引入依赖的时候要注意Spring AI相关的starter必须统一版本否则容易出现组件兼容问题我建议直接用Spring父POM统一管理相关依赖版本避免手工记版本号。dependencyManagement dependencies dependency groupIdorg.springframework.ai/groupId artifactIdspring-ai-bom/artifactId version1.0.0/version typepom/type scopeimport/scope /dependency /dependencies /dependencyManagement实际的AI功能依赖最核心的是模型接入starter和管理端依赖dependency groupIdorg.springframework.ai/groupId artifactIdspring-ai-starter-model-dashscope/artifactId /dependency dependency groupIdcom.alibaba.cloud.ai/groupId artifactIdspring-ai-alibaba-admin-starter/artifactId /dependency注意管理端后台如果不需要可以只引入模型starter。Admin的定位是治理不是强制组件它拆得很干净这点在工程上非常友好。3.2 配置文件里的门道第一次配置时最容易踩的坑是把所有配置写成固定值。我的建议是API Key或者密钥必须走环境变量模型名称、温度、最大Token等参数放进配置文件并且区分多环境。这里给一份参考配置spring: application: name: ai-customer-service ai: dashscope: api-key: ${DASHSCOPE_API_KEY} chat: options: model: qwen-plus temperature: 0.7 max-tokens: 1024 # RAG向量库配置 embedding: type: dashscope options: model: text-embedding-v3 datasource: url: jdbc:mysql://localhost:3306/ai_admin_console username: ${DB_USERNAME} password: ${DB_PASSWORD}这里有一个关键点很多教程会把temperature写成0.3甚至0这其实是照搬了追求准确的惯性思维。实际做客服场景时0.7的随机性反而让回答更自然。不要把模型参数当成可以一劳永逸的定值不同场景要单独设置。Admin后台一个很方便的功能就是按应用维度管理这些参数而不是写死在代码里。3.3 编写第一个工程化Controller工程化和Demo代码最大的区别是Controller不再直接暴露ChatClient。在我的实践里业务侧调用AI能力要走统一的Service层加上超时控制和结果格式化RestController RequestMapping(/api/ai) public class AiChatController { private final AiChatService aiChatService; public AiChatController(AiChatService aiChatService) { this.aiChatService aiChatService; } PostMapping(/chat) public AiChatResponse chat(RequestBody AiChatRequest request) { // 统一入参校验、鉴权、限流都在这一层完成 return aiChatService.chat(request.getSessionId(), request.getPrompt()); } }Service层内部才去使用Spring AI的ChatClientService public class AiChatService { private final ChatClient chatClient; private final ChatMemory chatMemory; public AiChatService(ChatClient.Builder builder, ChatMemory chatMemory) { this.chatClient builder .defaultSystem(你是企业客服助手回答要求简洁专业不要编造事实。) .build(); this.chatMemory chatMemory; } public AiChatResponse chat(String sessionId, String prompt) { // 业务上通过sessionId管理会话记忆 return chatClient.prompt() .user(prompt) .chatMemory(chatMemory) .sessionId(sessionId) .call() .entity(AiChatResponse.class); } }这段代码看着简单但它是从玩具走向工具的关键一步。所有企业级能力身份识别、参数校验、会话管理、限流熔断都在ChatClient调用之前完成了。模型在这里只是最内层的一个可替换组件。3.4 让RAG真正能用于生产知识库问答是AI应用最常见的落地场景但Demo阶段的RAG几乎都有同一个毛病文档切完就扔进去从来没有考虑过切分质量和召回效果。我在接入Spring AI Alibaba Admin的文档管理功能后才真正把RAG做成了一条可控的流水线。核心环节包括文档解析、文本切分、向量化、索引存储、召回、重排序。这里有一个很多人不重视的重排序步骤初期不做重排序召回Top5文档里经常混着无关片段回答自然不靠谱。我接入了重排序模型后回答准确性肉眼可见地提升。成本上虽然增加了一次调用但换来的是用户信任这笔账很划算。另外要强调的是知识库不是灌进去就完事。文档更新后必须同步刷新向量索引这个链路如果没有Admin后台的索引管理页面靠手工跑脚本迟早会出数据不一致的事故。3.5 Prompt模板的管理方式我之前做Demo时Prompt是拼字符串拼出来的。而工程化的做法是把Prompt定义成模板并且支持变量注入public final class PromptTemplates { public static final String CUSTOMER_SERVICE 你是{role}你的任务是回答用户关于{product}的问题。 回答要求 1. 语气{tone} 2. 如果知识库中没有答案明确告知用户需要人工介入 3. 禁止编造数据 用户问题{question} 参考知识{context} ; }这样的模板配合Admin后台就能做到同一个Agent在不同业务线之间复用。我见过太多团队每个业务线各写一套Prompt最后改动一个需求要同步改五六个项目苦不堪言。4. 工程化最硬的骨头可观测、降级与成本控制4.1 每一次调用都要有迹可循AI应用最大的运维噩梦是用户反馈回答不对但你根本不知道模型当时收到了什么。传统日志打一条调用成功没有任何意义必须把完整的请求上下文记录下来用户问题、系统Prompt版本、模型参数、返回结果、Token消耗、耗时。Spring AI Alibaba Admin内置了调用链追踪我在实际使用中最常用的是按会话ID查一次完整对话的上下文还原。这功能在排查为什么用户生气了的时候简直是救命稻草。没有这个能力客服场景的AI系统根本谈不上维护。我用一个切面来统一记录这些关键信息Aspect Component public class AiCallAuditAspect { Around(annotation(aiCallAudit)) public Object auditAround(ProceedingJoinPoint pjp, AiCallAudit aiCallAudit) throws Throwable { long start System.currentTimeMillis(); try { Object result pjp.proceed(); long cost System.currentTimeMillis() - start; auditService.record(aiCallAudit.bizType(), AiCallStatus.SUCCESS, cost); return result; } catch (Exception e) { auditService.record(aiCallAudit.bizType(), AiCallStatus.FAILED, System.currentTimeMillis() - start); throw e; } } }4.2 模型不可用时系统不能瘫痪生产环境一定会遇到模型服务商抖动、限流甚至故障。好的系统设计要有自动降级能力。我的降级策略分三层第一层模型服务不可达时自动切换到备用模型供应商。Spring AI的统一接口让切换成本降到了最低只需要改配置。第二层AI能力整体不可用时回落到人工客服或者说返回预设的兜底文案而不是让用户看到一个异常报错页。第三层对关键业务场景设置超时熔断。曾经有一次模型供应商大规模故障我的系统因为降级策略用户体验只是从智能回答变成了我们收到了您的问题客服会尽快联系您。如果没有这层设计那天的线上事故报告够我写三页。4.3 Token费用的失控是最隐蔽的坑AI应用的成本大头不是服务器是Token。很多团队上线AI功能的时候连一次会话的平均Token成本都没算过。我的经验是两步第一步在Admin后台设置单会话Token上限和月度预算告警第二步对Prompt模板做Token节省优化比如删除不必要的历史消息、限制知识库召回的上下文长度。我做过一个客服系统优化通过裁剪历史消息、动态设定最大上下文长度单次调用的Token消耗下降了大约40%。这笔节省在月调用量达到百万级时就是实实在在的利润。4.4 安全管控不能靠模型自觉AI应用最容易忽视的安全问题包括提示词注入、敏感数据外泄、越权访问知识库。我的底线原则是模型不可信一切进出都要校验。用户输入要进行敏感词过滤AI返回结果要经过内容安全审核知识库目录要按角色权限隔离绝不能把全量知识库暴露给所有用户。在实际项目中我用了一套双保险请求侧做输入合规检查和权限校验返回侧做敏感信息检测和越权数据拦截。5. 常见问题与排查技巧实录5.1 模型回答幻觉严重怎么办先说结论幻觉不可能完全消除但可以控制在可接受范围。我的排障顺序是一查知识库召回的内容是否相关二看用户问题是否超出知识库覆盖范围三检查System Prompt是否允许模型推测。对应措施提升重排序精度、对无法回答的问题设置明确话术、降低temperature。5.2 并发一高就超时、报错AI API的响应速度远慢于普通HTTP接口高并发下必须做线程池隔离。我用了一个独立线程池处理AI调用并设置信号量限流保证AI服务的慢请求不会拖垮主业务的Tomcat线程。spring: task: execution: pool: core-size: 8 max-size: 32 queue-capacity: 1005.3 向量库召回效果差优先检查切分策略。一个几百K的PDF如果按固定1024字符切分很多语义被切断召回必然差。我改用了按标题结构切分并且让相邻片段保留部分重叠召回率提升明显。5.4 后台管理配置不生效注意配置的加载顺序。Admin后台做的动态修改有时会被启动时的本地配置覆盖。解决办法后台修改的配置要明确标记为运行时配置并把本地配置文件里的相同项删除或注释避免两处不同配置打架。5.5 调用链追踪日志太多全量记录会产生海量日志。我的策略是正常调用记录精简摘要失败和长耗时调用记录完整上下文。同时在日志中打上traceId方便快速关联。6. 最后说点我的真实体会我见过太多团队在AI项目上重蹈当年大数据项目的覆辙——技术选型时被各种Agent框架迷花眼最后落不了地。如果你问我现在还想不想用ChatClient来造一个DEMO当然想。但如果你问我要不要用它做生产项目我强烈建议把工程化能力放在第一位。Spring AI Alibaba Admin让我感觉最舒服的地方是它给了模型一个稳定、可治理的家而不是让模型光着脚在生产环境里裸奔。如果你正在纠结选型我给你一个最朴素的建议先列出你自己的治理清单然后拿这个清单去对照每个候选方案看哪些能开箱即用、哪些要自己补。补的东西越多项目离死亡越近。我自己已经把球队的几套知识库系统都迁到了这个技术栈上后面打算把Agent编排也接进来。AI应用这条路还很长但至少现在路线图是清楚的。

相关新闻

LDA主题模型实战指南:从原理到gensim落地与调参避坑

LDA主题模型实战指南:从原理到gensim落地与调参避坑

简介:面向需要主题建模实战参考的Python开发者,这份LDA主题模型实现代码包围绕gensim库给出了可运行的训练脚本,覆盖文本预处理、词典构建、语料转换、LdaModel训练与主题分布输出等核心步骤。资源包共12个文件,压缩后仅10KB&…

2026/10/18 21:46:11 阅读更多 →
Python+PySide6打造桌面透明悬浮窗:金价监控小工具全解析

Python+PySide6打造桌面透明悬浮窗:金价监控小工具全解析

简介:面向日常盯盘与上班摸鱼场景,这款黄金金价监控气泡工具能把内外金价实时浮在电脑右下角,与系统时间并列显示,每60秒自动刷新,无需频繁打开网页或手机即可掌握最新行情。工具采用Python编写,纯悬浮气泡…

2026/10/18 21:46:11 阅读更多 →
增量索引实战:新文档怎么做到分钟级可检索

增量索引实战:新文档怎么做到分钟级可检索

个人主页&#xff1a;> for_ever_love__ <&#xff08;欢迎各位大佬莅临&#x1f60a;&#xff09; 其他栏目: > 大模型开发从0到1 < 其他栏目: > iOS项目总结大全 < 其他栏目: > 我想学python了 < 其他栏目: > iOS UI < 文章目录增量索引实战&a…

2026/10/18 21:45:10 阅读更多 →

最新新闻

Chaste细胞群体动力学仿真实操:从项目搭建到结果可视化

Chaste细胞群体动力学仿真实操:从项目搭建到结果可视化

上一篇文章讲完 Chaste 的安装和基础概念&#xff0c;后台不少同行留言说&#xff1a;环境装好了&#xff0c;可真正打开一个仿真项目时还是很懵&#xff0c;不知道从哪里下手。这篇我就把自己用 Chaste 跑细胞群体动力学仿真的完整操作路径梳理一遍&#xff0c;从项目结构到核…

2026/10/18 22:46:51 阅读更多 →
Python技术报告:多端协同与全局记忆架构的实现路径

Python技术报告:多端协同与全局记忆架构的实现路径

随着人工智能技术的快速发展&#xff0c;智能体&#xff08;Agent&#xff09;在办公场景中的应用日益广泛。然而&#xff0c;当前跨系统数据协同的使用率仅为14.3%&#xff0c;远低于B端用户对其长期价值的预期。本报告深入探讨多端协同与全局记忆成为重要趋势的背景&#xff…

2026/10/18 22:46:51 阅读更多 →
数据结构——选择排序

数据结构——选择排序

1. 引言 上篇博客我们聊了插入排序&#xff0c;那种像打扑克牌一样&#xff0c;把新牌一张张插到合适位置的感觉&#xff0c;相信大家还记忆犹新。今天&#xff0c;我们换个思路&#xff0c;来聊聊另一种同样经典的基础排序算法——选择排序。 如果说插入排序是"边摸牌边整…

2026/10/18 22:46:51 阅读更多 →
MFC多线程进度条不卡死:PostMessage消息驱动UI更新实践

MFC多线程进度条不卡死:PostMessage消息驱动UI更新实践

简介&#xff1a;面向Windows桌面开发者的MFC多线程编程示例&#xff0c;演示如何通过继承CWinThread并重写Run方法创建后台工作线程&#xff0c;利用PostMessage发送自定义进度消息&#xff0c;由主线程接收后调用SetPos实时更新对话框进度条&#xff0c;有效避免后台任务阻塞…

2026/10/18 22:46:51 阅读更多 →
codex怎么预定义提示词?例如中文回复:用 AGENTS.md 固化默认行为

codex怎么预定义提示词?例如中文回复:用 AGENTS.md 固化默认行为

/* 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 22:46:51 阅读更多 →
AI Agent Harness 多终端同步管控:把 Codex auth.json 改到 TaoToken 的实操大纲

AI Agent Harness 多终端同步管控:把 Codex auth.json 改到 TaoToken 的实操大纲

/* 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 22:45:50 阅读更多 →

日新闻

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

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

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

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

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

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

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

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

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

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

周新闻

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

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

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

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

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

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

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

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

如果你的信息流最近也天天刷到“机器人大脑”这个词&#xff0c;你会发现一个很有意思的现象&#xff1a;每个人说的“大脑”根本不是同一个东西。有人指的是大语言模型&#xff0c;有人指的是运动控制系统&#xff0c;还有人指的是能理解物理世界的端到端模型。在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 阅读更多 →