OpenSpec:用结构化规范解决AI代码生成在团队协作中的一致性难题
1. 从“惊喜”到“惊吓”AI自由发挥的协作困境最近在团队里我们尝试用大模型来辅助生成一些代码片段和文档。一开始大家都觉得挺酷把需求描述扔给AI它就能“唰”地一下给你生成一段看起来像模像样的代码或者一篇结构清晰的文档草稿。这种“自由发挥”的模式在个人探索或者头脑风暴阶段确实能带来不少灵感火花。但当我们试图把AI的产出真正纳入到团队协作流程中时问题就开始接二连三地暴露出来。最典型的一个场景是我们让不同的AI工具或者同一工具的不同提示词去处理同一个“用户登录模块”的需求。A同事用ChatGPT生成了一套基于JWT的认证逻辑代码风格偏函数式B同事用Claude生成了一套基于Session的认证方案代码结构是经典的MVC分层而我用国内某个大模型生成的则是一套混合了OAuth2.0概念的奇怪缝合体。当我们需要把这些代码整合到一个项目里时灾难就开始了接口命名规范不统一、错误处理方式各异、甚至核心的业务逻辑都存在分歧。更麻烦的是后续的维护当需要修改登录逻辑时我们得同时理解三套不同的“方言”沟通成本直线上升代码评审变成了“大家来找茬”。这让我意识到在团队协作的语境下让AI“自由发挥”就像让一群才华横溢但未经训练的画家共同创作一幅壁画——每个人对主题的理解、使用的笔触和色彩都不同最终画面很可能是一片混乱而非杰作。AI缺乏对团队共享上下文和统一契约的理解。它不知道我们项目用的是RESTful还是GraphQL不知道我们的数据库ORM偏好更不知道团队内部约定的代码规范和设计模式。它的“发挥”是基于其训练数据中的海量公共知识而非我们项目这个具体、独特的“小宇宙”。因此问题的核心从“如何让AI更聪明地生成代码”转变为了“如何让AI的生成行为与团队的具体约束和目标对齐”。我们需要一个“指挥棒”来引导AI的创造力确保其输出在团队协作的框架内是可控、可预期、可集成的。这就是我接触到OpenSpec并将其视为解决这一协作困境关键工具的出发点。2. OpenSpec是什么不止是“规格”更是团队与AI的协作契约OpenSpec简单来说是一个用于定义和驱动AI生成行为的结构化规范框架。你可以把它理解为一套极其详细的“设计图纸”或“烹饪食谱”而AI则是那位技艺高超但需要明确指引的“大厨”。它不是一个具体的AI模型也不是一个集成开发环境IDE而是一个位于团队工作流程与AI能力之间的协调层。它的核心价值在于将原本存在于团队成员脑海中的、或散落在各种文档里的“团队共识”和“项目规范”转化为机器可读、可执行的“规格”Specifications。这些规格定义了AI在完成特定任务如生成代码、编写测试、撰写文档时必须遵循的边界条件、输出格式、质量标准和业务逻辑。举个例子在没有OpenSpec时你给AI的指令可能是“请生成一个用户注册的API接口”。结果可能千差万别。而使用OpenSpec后你的指令会变成“请根据项目user-service的api-spec.yaml中定义的POST /api/v1/users接口规范生成对应的Spring Boot控制器实现代码”。这个api-spec.yaml文件就是OpenSpec规格的一部分它可能明确定义了请求/响应格式请求体必须包含username、email、password字段其中password需加密成功响应必须返回201状态码及包含userId的JSON对象。验证规则username必须唯一email需符合正则表达式。错误处理用户名已存在返回409 Conflict邮箱格式错误返回400 Bad Request并附带标准化的错误信息结构。代码风格控制器类名需以Controller结尾使用RestController注解日志使用SLF4J的LoggerFactory。依赖关系必须使用项目定义的ResponseEntity工具类进行包装。通过这样的规格无论团队中哪位成员、使用哪款AI工具只要基于同一份OpenSpec生成的代码在功能、接口、风格上都是一致的。这从根本上解决了“自由发挥”带来的不一致性问题。OpenSpec通常包含几个关键部分任务目标描述用自然语言说明要做什么。上下文与约束提供项目背景、技术栈、依赖库版本、目录结构等。输入/输出规格严格定义输入的格式、类型以及输出的结构、必须包含的字段等。质量与验证规则定义代码覆盖率要求、性能指标、安全扫描规则如禁止某些函数等。示例与反例提供“好”的样本和“坏”的样本让AI更清晰地理解边界。它就像一个动态的、可执行的“团队开发手册”确保AI的每一次生成都是对团队既定目标和标准的一次精准对齐而非一次充满不确定性的“冒险”。3. 为什么是“规格驱动开发”超越提示词工程的协作范式在引入OpenSpec之前我们团队也尝试过用更精细的“提示词工程”Prompt Engineering来约束AI。比如写一个非常长的、包含各种要求的提示词模板。这种方法初期有效但很快遇到了瓶颈维护灾难提示词模板变得极其冗长复杂任何一点业务逻辑或技术栈的变更都需要手动更新所有相关提示词容易遗漏且难以保证一致性。难以复用为A项目精心调校的提示词很难直接应用到技术栈或规范不同的B项目。缺乏结构性纯文本的提示词难以清晰地表达复杂的、嵌套的约束条件比如“当条件X成立时采用方案A否则采用方案B但无论哪种方案都必须遵守规则C”。版本管理困难提示词散落在聊天记录、文档或个人笔记中无法像代码一样进行版本控制、差异对比和协同修改。OpenSpec倡导的“规格驱动开发”Specification-Driven Development正是为了解决这些问题。它将约束条件从非结构化的“提示词描述”升级为结构化的“规格定义文件”。这种转变带来了几个根本性的优势3.1 规格即单一可信源Single Source of Truth项目的所有开发规范、API契约、数据模型、部署配置等都被集中定义在一套OpenSpec文件中。无论是AI、新加入的开发者、还是自动化工具都以此为准。这消除了信息孤岛和口头传递导致的歧义。当业务规则变更时只需更新对应的规格文件所有基于此规格的AI生成和人工开发都会自动对齐到新标准。3.2 实现关注点分离开发者或产品经理可以专注于用自然语言描述“要做什么”业务需求而将“怎么做”技术实现约束交给OpenSpec规格来定义。AI则扮演一个严格的“执行者”它结合自然语言需求和机器可读的规格生成符合所有约束的产物。这大大降低了使用AI的门槛非技术成员也能通过描述需求来驱动开发只要规格定义得足够完善。3.3 支持自动化验证与集成结构化的规格可以被自动化工具链消费。例如可以在CI/CD流水线中增加一个环节用OpenSpec规格自动验证AI生成的代码或文档检查其是否完全符合所有预设的规则命名、接口、依赖等。这相当于为AI的产出增加了一道自动化的“质量门禁”确保只有合规的产物才能进入代码库。3.4 促进知识沉淀与团队成长编写OpenSpec规格的过程本身就是对团队最佳实践、设计决策和项目架构的一次系统性梳理和沉淀。这些规格文件成为了团队最宝贵的知识资产新成员可以通过阅读规格快速理解项目全貌而不是通过阅读可能已经过时或不全的文档。从“自由发挥”到“规格驱动”本质上是将AI从“一个需要不断用语言去指挥的聪明但粗心的助手”转变为“一个严格遵循标准化操作流程的可靠执行者”。这对于追求交付质量、可维护性和规模化协作的团队来说是至关重要的范式升级。4. 实战如何为你的团队搭建OpenSpec协作流程理解了OpenSpec的价值下一步就是将其落地。这里我结合自己的实践分享一个从零开始为中小型团队搭建OpenSpec协作流程的可行路径。这个过程不是一蹴而就的建议采用迭代的方式从一个小的、高价值的场景开始试点。4.1 第一步选择与定义初始规格场景不要试图一开始就为整个项目定义完整的规格。选择一个痛点明显、边界清晰、且AI能显著提升效率的场景作为切入点。例如场景A推荐RESTful API接口的开发。包括生成Controller、Service、DTO、Validation等代码。这个场景输入输出明确OpenAPI/Swagger规范本身就是一种雏形规格团队规范容易统一。场景B数据库实体Entity与仓库Repository层代码生成。基于已有的数据库表结构或ER图。场景C单元测试模板生成。为已有的业务方法生成符合团队测试框架如JUnit, Jest和Mock风格的测试用例骨架。我们团队选择了场景A作为起点。我们有一个相对稳定的技术栈Spring Boot MyBatis-Plus并且已经有一套不太完善的OpenAPI文档。4.2 第二步创建你的第一个OpenSpec文件OpenSpec本身没有绝对的官方标准格式核心思想是结构化和机器可读。你可以从简单的YAML或JSON开始。以下是针对“生成用户注册API”的一个极度简化的示例# spec/user-registration-api.yaml version: 1.0 task: “生成用户注册API的Spring Boot控制器和DTO代码” context: project: name: “user-service” tech-stack: language: “Java 17” framework: “Spring Boot 3.1.x” web: “Spring MVC” validation: “Jakarta Bean Validation 3.0” json: “Jackson” database: “MyBatis-Plus 3.5.x” package: “com.example.user” conventions: naming: “使用驼峰命名法。Controller类以Controller结尾DTO类以DTO结尾。” logging: “使用SLF4J Logger通过LoggerFactory获取。” response: “使用通用的ResponseEntityResultT包装所有HTTP响应。” input: requirement: “用户通过邮箱和密码进行注册邮箱需验证唯一性密码需加密存储。” api-contract: # 可以引用已有的OpenAPI片段或直接定义 path: “/api/v1/users” method: “POST” request: body: type: “object” required: [“email”, “password”] properties: email: type: “string” format: “email” description: “用户邮箱” password: type: “string” format: “password” minLength: 8 description: “用户密码” response: success: status: 201 body: type: “object” required: [“code”, “message”, “data”] properties: code: type: “integer” example: 201 message: type: “string” example: “用户注册成功” data: type: “object” properties: userId: type: “integer” description: “新创建的用户ID” errors: - status: 400 condition: “请求参数格式错误” - status: 409 condition: “邮箱已存在” output: artifacts: - type: “Java Class” name: “UserRegisterController” path: “src/main/java/com/example/user/controller/” template: | // 这里可以放置一个代码模板片段或者仅描述约束 RestController RequestMapping(“/api/v1/users”) Slf4j public class {{className}} { PostMapping public ResponseEntityResultLong register(Valid RequestBody {{requestDtoType}} request) { // 业务逻辑调用Service返回包含userId的Result } } rules: - “必须包含Valid注解对请求体进行验证” - “必须使用Slf4j注解注入日志” - “方法返回类型必须是ResponseEntityResultLong” - type: “Java Class” name: “UserRegisterDTO” path: “src/main/java/com/example/user/model/dto/” rules: - “类名必须为UserRegisterDTO” - “必须包含email和password字段并添加JSR 380验证注解如Email, Size” - “必须实现Serializable接口” - “字段必须使用Lombok的Data注解” validation: static-analysis: “生成的代码必须能通过项目配置的Checkstyle和SpotBugs检查” compilation: “生成的代码必须能通过mvn compile编译”这个示例虽然长但展示了规格的核心要素上下文、输入契约、输出要求及验证规则。在实际操作中你可以利用工具如自己编写脚本或使用早期的OpenSpec相关工具来解析这个YAML文件并将其与你的AI提示词动态结合。4.3 第三步将OpenSpec集成到你的AI工作流中这是最关键的一步。你需要一个“桥梁”将OpenSpec规格“喂”给AI。目前有几种方式手动拼接初期推荐写一个简单的脚本Python/Node.js皆可读取OpenSpec YAML文件将其关键部分如context,input.api-contract,output.rules转换成一段结构化的文本描述然后拼接到你的AI提示词前面。例如“你是一个Java专家请根据以下项目规格和API契约生成代码 项目上下文[从spec中提取的context内容] API契约[从spec中提取的input.api-contract内容] 代码生成规则[从spec中提取的output.artifacts.rules内容] 请生成符合以上所有规格的代码。”使用专用工具或插件关注像speckit,superpowers这类早期项目它们旨在提供OpenSpec的编辑、管理和与IDE/AI工具集成的能力。例如可能在VSCode或JetBrains IDE中安装一个插件右键点击OpenSpec文件即可调用配置好的AI模型生成代码。构建自定义流水线对于有工程能力的团队可以构建一个内部服务。开发者在前端界面选择任务类型如“生成API”和具体规格后端服务将规格渲染为强化提示词调用AI API如OpenAI, Claude等并将返回的代码直接放入项目指定位置甚至触发初步的验证。4.4 第四步建立规格的维护与演进机制版本控制将OpenSpec文件与代码一同存放在Git仓库中进行版本管理。评审流程像评审代码一样评审规格的变更。规格的修改可能影响所有未来的AI生成结果需要谨慎。持续迭代在生成代码后收集开发者的反馈。哪些规则太死板哪些约束遗漏了不断更新OpenSpec文件使其更贴合团队的实际需求和最佳实践。这个过程初期会有一些学习成本和工具链搭建的工作但一旦跑通对于提升团队协作效率和产出质量的效果是立竿见影的。5. 避坑指南OpenSpec实践中的常见挑战与应对在推广和使用OpenSpec的过程中我们踩过不少坑。把这些经验分享出来希望能帮你少走弯路。5.1 规格过于僵化 vs. 过于宽松这是一个平衡的艺术。如果规格定义得事无巨细像一本严格的编程手册可能会扼杀AI在合理范围内的灵活性甚至让生成变得困难。例如强制规定循环必须用for而不能用forEach可能并无必要。反之如果规格太宽松就失去了约束的意义不一致性依然存在。应对策略区分“强制规则”和“推荐模式”。将架构约束、接口契约、安全规范等设为强制规则如必须使用某个加密库、必须返回特定响应格式。将代码风格、局部实现细节设为推荐模式如建议使用Stream API但非强制。在规格文件中明确标注两者的区别。5.2 AI模型对复杂规格的理解偏差即使提供了清晰的规格不同的AI模型甚至同一模型的不同版本对复杂、嵌套规格的理解能力也不同。有时它会忽略某些规则或产生奇怪的“幻觉”生成不符合规格的代码。应对策略分而治之将复杂的生成任务拆解为多个步骤每个步骤对应一个更简单、专注的规格。例如先根据规格生成接口定义再根据接口定义和另一份规格生成实现类。提供“示例”在规格中附带1-2个完全符合要求的输入输出示例Few-Shot Learning。这对于引导AI理解复杂规则非常有效。后置验证与修正不要完全信任AI的一次性输出。建立自动化验证步骤如格式检查、编译测试、规则匹配扫描。对于未通过的产出可以尝试将“错误信息”和原始规格一起反馈给AI要求其修正。5.3 规格的维护成本随着项目发展业务规则和技术栈会变规格也需要更新。维护一套庞大的规格文件可能成为新的负担。应对策略模块化设计将规格按领域或层级拆分。例如global-context.yaml定义全局技术栈user-domain-spec.yaml定义用户领域的所有API和模型auth-spec.yaml定义认证相关规范。通过引用的方式组合使用避免重复。与现有工具链结合尽量从已有的、权威的源头派生规格。例如从OpenAPISwagger文档自动生成API相关的规格骨架从数据库Schema生成实体类规格。这样当源头更新时可以半自动地同步更新规格。确立负责人像代码模块有Owner一样为不同的规格域指定维护负责人确保变更有人评审和更新。5.4 团队接受度与学习曲线不是所有团队成员都愿意接受这种“约束式”的开发方式尤其是习惯了AI自由发挥的开发者可能会觉得被束缚了手脚。应对策略价值驱动而非强制通过实际案例展示OpenSpec如何减少合并冲突、降低评审成本、加速新成员上手用事实说服大家。降低使用门槛提供便捷的工具。如果使用规格需要复杂的命令行操作大家就会抵触。理想状态是在IDE中右键点击一个规格文件选择“生成代码”代码就出现在正确的位置。从试点开始先在核心模块或新项目中由技术骨干试点做出成功样板再逐步推广到全团队。OpenSpec不是银弹它引入了一种新的协作范式也带来了新的复杂性。但在我看来对于追求工程效能和软件质量的团队而言这种将模糊共识转化为明确规格的投入是迈向高效、可靠人机协同开发的必经之路。它让AI从一个“有趣的玩具”真正变成了团队中一个“可靠的成员”。

相关新闻

当 AI 开始“自己干活“:自主智能体这一年到底发生了什么

当 AI 开始“自己干活“:自主智能体这一年到底发生了什么

去年这个时候,大家还在比谁的聊天机器人更会聊天。今年画风彻底变了——你不再需要一句句问,AI 直接接管一整段任务:查资料、写代码、发邮件、整理表格,一气呵成。这种能"自己动手"的 AI,圈内叫它 Agent&…

2026/10/9 4:08:22 阅读更多 →
2026年股权纠纷律所挑选参考:从控制权争夺、对赌回购案件办理经验维度筛选专业法律服务机构

2026年股权纠纷律所挑选参考:从控制权争夺、对赌回购案件办理经验维度筛选专业法律服务机构

2026年股权纠纷律所挑选参考:从控制权争夺、对赌回购案件办理经验维度筛选专业法律服务机构一、股权纠纷律所服务领域的常见法律问题与风险防范随着2024年新《公司法》正式施行,股权类纠纷的数量与复杂程度持续上升,不少当事人在遭遇控制权争…

2026/10/16 7:55:37 阅读更多 →
智能办公时代的新抉择:TRAE Work 与 WorkBuddy 深度对比与选型建议

智能办公时代的新抉择:TRAE Work 与 WorkBuddy 深度对比与选型建议

随着人工智能和智能体(Agent)技术的爆发式增长,协同办公和知识工作已经从单点式的“对话问答”演进为深度嵌入工作流的“系统性协作”。在这一背景下,TRAE Work 与 WorkBuddy 作为国内极具代表性的两款 AI 办公和 Agent 工具&…

2026/10/11 2:15:42 阅读更多 →

最新新闻

STM32+FreeRTOS+W5500+MQTT工业级通信栈实战

STM32+FreeRTOS+W5500+MQTT工业级通信栈实战

简介:本资源是一套基于STM32F103RET6的物联网终端完整嵌入式开发工程,面向嵌入式初学者与IoT项目开发者,解决MCU端多任务调度、以太网接入及云端MQTT通信集成难题。工程深度融合FreeRTOS实时调度、W5500硬件TCP/IP协议栈与轻量级MQTT客户端&a…

2026/10/16 13:37:12 阅读更多 →
TG记账群发机器人源码解析:消息监听、指令解析与统计汇总全链路

TG记账群发机器人源码解析:消息监听、指令解析与统计汇总全链路

简介:这是一套面向Telegram平台开发者的统计机器人源码合集,聚焦群发、账单统计与自动记账三大核心功能,适合有一定PHP与前端基础、希望快速搭建TG记账或群发工具的中高级开发者。压缩包共收录约2000个文件,以688个PHP后端脚本、3…

2026/10/16 13:37:12 阅读更多 →
VCU开发源码包实战指南:从工程骨架到CAN协议验证

VCU开发源码包实战指南:从工程骨架到CAN协议验证

简介:本资源为电动汽车整车控制器(VCU)的完整开发套件,面向嵌入式工程师、新能源汽车控制系统学习者及高校相关专业师生,解决VCU软硬件协同开发、控制策略理解与实车系统集成等核心问题。压缩包共477个文件&#xff0c…

2026/10/16 13:37:12 阅读更多 →
IDEA Services面板配置指南:SpringCloud多服务启动管理

IDEA Services面板配置指南:SpringCloud多服务启动管理

1. 为什么一个“窗口面板”值得单独写一篇笔记 如果你正在跟着教程搭建一套基于 SpringCloud 2020 版本的微服务示例工程,大概率会遇到这样一个场景:辛辛苦苦把注册中心、网关、若干个业务服务都建好了,每个服务都能单独启动,但每…

2026/10/16 13:37:12 阅读更多 →
Ubuntu 18.04双显卡笔记本NVIDIA驱动循环登录问题排查与修复指南

Ubuntu 18.04双显卡笔记本NVIDIA驱动循环登录问题排查与修复指南

1. 双显卡笔记本装完驱动就循环登录,问题到底出在哪如果你手上有一台带核显加独立显卡的笔记本,兴冲冲装完 Ubuntu 18.04,接着按网上教程装 NVIDIA 驱动,重启之后卡在登录界面——输入密码,屏幕一黑,又弹回…

2026/10/16 13:37:12 阅读更多 →
语义分割数据增强实战:imgaug图像与掩码同步增强指南

语义分割数据增强实战:imgaug图像与掩码同步增强指南

1. 语义分割任务里,数据增强到底在解决什么问题做过语义分割的人都有一个共同感受:模型效果上不去,八成不是网络结构不够花哨,而是标注数据太少、太单一。语义分割和图像分类不一样,分类一张图只有一个标签&#xff0c…

2026/10/16 13:36:10 阅读更多 →

日新闻

个人 AI Agent 平台接入 TaoToken:统一 Key 与 API 通道的配置大纲

个人 AI Agent 平台接入 TaoToken:统一 Key 与 API 通道的配置大纲

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

2026/10/16 0:00:05 阅读更多 →
信号与系统频域分析作业解题指南

信号与系统频域分析作业解题指南

1. 作业背景与核心要求解析信号与系统作为电子信息类专业的核心基础课,其作业设计往往直接关联课程的核心知识框架。2026年春季第六次作业的布置,通常对应着课程进展到频域分析的关键阶段。根据常规教学进度推测,本次作业可能涉及以下核心内容…

2026/10/16 0:00:05 阅读更多 →
Django MVT实战:从零构建图书借阅系统,彻底搞懂Model-View-Template分层

Django MVT实战:从零构建图书借阅系统,彻底搞懂Model-View-Template分层

1. 从一个"四不像"的练手项目说起如果你已经看完了Django的官方教程前几章,跟着敲完了投票应用,大概会有一种"我好像会了,又好像什么都不会"的割裂感。教程里每个知识点都是拆开的——这一章讲模型,下一章讲视…

2026/10/16 0:00:05 阅读更多 →

周新闻

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

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

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

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

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

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

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

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

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

2026/10/15 13:48:15 阅读更多 →

月新闻

我发现了一个新思路:用 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/15 0:14:36 阅读更多 →
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/16 3:49:43 阅读更多 →
黑夜航拍船只数据集训练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/15 9:49:14 阅读更多 →