agent-skills技能体系设计:从意图路由到执行编排的工程实践

1. 从"agent-skills"这个命名说起:它到底指什么

第一次看到"agent-skills"这个词,很多人会下意识地把它理解成"给智能体装上一堆技能包"。这个理解方向没错,但太粗了。真正做过智能体项目的人都知道,一个能跑起来的智能体系统,最难的从来不是"能不能调用工具",而是"在什么情况下该调用哪个工具、调用失败之后怎么办、多个技能之间怎么协同"。所以"agent-skills"这个标题背后,其实藏着一个更本质的问题:如何把一堆零散的能力,组织成一套智能体可以稳定依赖的技能体系。

我接触智能体相关开发有几年时间了,从最早的规则式对话机器人,到后来的工具调用框架,再到现在的多技能协同系统,踩过的坑不算少。这篇内容想聊的,就是围绕"agent-skills"这个主题,把技能体系的设计思路、落地步骤、常见坑点讲清楚。不管你是刚接触智能体开发的新手,还是已经做过几个Demo想往生产环境推进的开发者,应该都能从中找到对自己有用的部分。

需要先说明一点:由于原始输入里项目正文、关键词、摘要都是空的,所以这篇内容的核心框架是我基于"agent-skills"这个标题,结合智能体开发领域的常见实践来展开的。里面提到的具体方案、参数、步骤,都是行业里比较成熟、可复现的做法,我会尽量把"为什么这么做"讲透,而不是只丢一堆结论。

先给一个整体认知:agent-skills 本质上是一套"能力注册 + 意图路由 + 执行编排 + 结果校验"的闭环机制。技能本身只是素材,真正决定系统好不好用的,是这套机制怎么设计。下面我会从技能的定义方式、路由策略、执行编排、异常处理、测试验证几个维度,一层层拆开讲。

2. 技能不是函数:重新理解 agent-skills 的抽象层次

2.1 把技能当成"函数"是最常见的误区

很多人设计 agent-skills 的时候,第一反应是"一个技能就是一个函数"。比如查天气是一个函数,发邮件是一个函数,查数据库是一个函数。这个抽象在Demo阶段没问题,但一旦技能数量超过十个,问题就来了:函数签名是给程序员看的,不是给智能体看的。智能体需要知道的是"这个技能能解决什么问题、什么时候该用、输入大概长什么样、输出意味着什么",而不是"这个函数接收三个参数,返回一个字典"。

我见过一个项目,技能注册表里塞了四十多个函数,每个函数的描述就一行英文。结果智能体在路由的时候经常选错,因为描述信息太薄,模型根本分不清"查询订单状态"和"查询物流信息"这两个技能的区别。后来他们把每个技能的描述扩展成"适用场景 + 不适用场景 + 输入示例 + 输出示例"四段式,路由准确率直接上了一个台阶。

所以第一个要建立的认知是:技能是面向智能体的能力描述单元,不是面向程序员的函数封装。它的核心字段应该包括:

  • 技能名称:简短、唯一、语义清晰,避免用func_001这种无意义命名
  • 能力描述:用自然语言说清楚这个技能解决什么问题,最好带一两个典型场景
  • 触发条件:什么情况下应该考虑这个技能,什么情况下不应该
  • 输入规范:需要哪些参数,每个参数的含义和格式
  • 输出规范:返回什么结构,字段含义是什么
  • 失败模式:常见失败原因和对应的处理建议

这套字段看起来啰嗦,但它直接决定了智能体能不能"看懂"这个技能。你可以把它理解成给技能写一份"说明书",而且是写给一个聪明但完全不了解你系统的人看的。

2.2 技能粒度怎么切:太粗和太细都是坑

技能粒度是另一个容易翻车的地方。切得太粗,一个技能干太多事,智能体没法灵活组合;切得太细,技能数量爆炸,路由负担陡增。

我的经验是遵循"单一意图原则":一个技能对应一类明确的用户意图。比如"发送邮件"和"查询邮件列表"是两个技能,因为它们是两类不同意图;但"发送邮件"和"发送带附件的邮件"可以合并成一个技能,因为附件只是参数差异,不是意图差异。

具体判断标准可以看这三条:

  1. 如果两个技能经常被同一个意图触发,考虑合并
  2. 如果一个技能内部有明显的条件分支决定做完全不同的事,考虑拆分
  3. 如果一个技能的描述需要超过三句话才能说清楚,大概率该拆了

举个实际例子。有个做客服智能体的团队,最初把"退换货"做成一个技能,结果这个技能内部要处理"退货""换货""退款""补发"四种情况,参数复杂到智能体经常传错。后来拆成四个独立技能,每个技能描述清晰,路由准确率反而提升了。这就是典型的"粗粒度陷阱"。

2.3 技能注册表的结构设计

技能注册表是整个 agent-skills 体系的地基。它不应该是一个简单的列表,而应该是一个带索引的结构化数据。我通常会用这样的组织方式:

字段作用是否必填
skill_id唯一标识,用于日志追踪是
name技能名称,语义化是
description能力描述,面向智能体是
triggers触发关键词或场景标签否
input_schema输入参数结构定义是
output_schema输出结构定义是
failure_modes常见失败模式列表否
priority冲突时的优先级否
enabled是否启用是

这个结构的好处是,它同时服务于三个环节:路由时用 description 和 triggers 做匹配,执行时用 input_schema 做参数校验,异常处理时用 failure_modes 做兜底决策。一张表把技能的全生命周期信息都覆盖了。

提示:技能注册表建议用配置文件或数据库管理,不要硬编码在代码里。技能是会频繁增删改的,硬编码会让每次调整都变成一次发版。

3. 意图路由:智能体怎么知道该用哪个技能

3.1 路由的本质是一个分类问题

技能注册好了,下一个问题就是:用户说一句话,智能体怎么知道该调用哪个技能?这本质上是一个分类问题,输入是用户意图,输出是技能集合。

常见的路由策略有三种,各有适用场景:

第一种是基于关键词匹配。简单粗暴,维护一个关键词到技能的映射表。优点是快、可控、可解释;缺点是覆盖不了表达多样性,用户换个说法就匹配不上。适合技能数量少、用户表达相对固定的场景。

第二种是基于语义向量检索。把技能描述和用户输入都转成向量,算相似度,取Top-K。优点是能处理表达多样性;缺点是需要维护向量库,且相似度阈值不好定,容易出现"看起来像但其实不对"的误匹配。

第三种是基于大模型的路由。把技能列表和用户输入一起给模型,让模型判断该用哪个技能。优点是灵活、准确率高;缺点是每次路由都要调模型,成本和延迟都上去了。

实际项目里,我通常用混合策略:先用关键词做快速筛选,缩小候选技能范围,再用语义或模型做精排。这样既保证了速度,又保证了准确率。

3.2 路由失败比路由成功更值得设计

大部分人设计路由的时候,只考虑"匹配成功怎么办",很少考虑"匹配失败怎么办"。但实际运行中,路由失败的比例往往不低,尤其是用户表达模糊或者技能覆盖不全的时候。

路由失败大概分三种情况:

  • 完全没匹配到技能:用户问的东西系统根本不支持
  • 匹配到多个技能,置信度接近:模型也拿不准该用哪个
  • 匹配到了但参数不全:技能选对了,但用户没提供必要参数

这三种情况的处理策略完全不同。第一种应该明确告知用户"这个能力暂不支持",而不是硬凑一个技能去执行;第二种应该向用户澄清意图,或者按优先级选一个并说明;第三种应该主动追问缺失的参数,而不是用默认值糊弄过去。

我见过一个反面案例:某智能体在参数缺失时,直接用空字符串填充,结果调用了一个删除接口,把用户数据清空了。这就是没有设计路由失败处理的代价。

3.3 多技能协同的路由策略

有些用户意图不是单个技能能搞定的,需要多个技能协同。比如"帮我查一下上个月的订单,然后把金额超过一千的退掉",这涉及"查询订单"和"发起退款"两个技能,而且第二个技能依赖第一个技能的输出。

这种场景下,路由不能只输出一个技能,而要输出一个技能执行计划。计划里要标明技能的执行顺序、依赖关系、数据传递方式。

实现上,我通常会让路由层输出一个结构化的计划对象,类似这样:

{ "plan_id": "plan_001", "steps": [ { "step": 1, "skill": "query_orders", "params": {"month": "last"}, "depends_on": [] }, { "step": 2, "skill": "refund_order", "params": {"order_id": "$step1.orders[?amount>1000].id"}, "depends_on": [1] } ] }

这里的$step1.xxx是数据引用语法,表示从第一步的输出里取值。执行引擎按顺序执行,遇到依赖就先等前置步骤完成。这套机制听起来复杂,但它是多技能协同的基础,没有它,智能体就只能做单步操作。

4. 执行编排:技能调用的顺序、并发与回滚

4.1 串行、并行、条件分支怎么选

技能执行计划拿到之后,执行引擎要决定怎么跑。三种基本模式:

串行执行:一个接一个跑,前一个的输出作为后一个的输入。适合有强依赖关系的场景。优点是逻辑清晰、易于调试;缺点是慢。

并行执行:多个无依赖的技能同时跑。适合独立查询类操作,比如同时查天气、查日程、查邮件。优点是快;缺点是要处理并发结果合并和部分失败。

条件分支:根据前一步的结果决定下一步走哪条路。适合有判断逻辑的场景,比如"如果订单状态是已发货,就查物流;否则就查库存"。

实际项目里,这三种模式经常混用。一个执行计划里,可能第一步并行查三个数据源,第二步根据结果串行执行两个操作,第三步再并行发两个通知。

我的建议是:默认串行,确认无依赖再并行。因为并行带来的复杂度(结果合并、异常传播、资源竞争)往往比它节省的时间更值钱。除非某个环节确实是性能瓶颈,否则不要过早优化。

4.2 参数传递与数据映射

技能之间传递数据是执行编排里最容易出错的地方。前一个技能输出的字段名,和后一个技能需要的字段名,往往对不上。这时候需要一个映射层。

映射层要做三件事:

  1. 字段重命名:把order_id映射成orderId
  2. 类型转换:把字符串"1000"转成数字1000
  3. 结构提取:从嵌套结构里取出需要的字段

我通常用声明式的映射配置,而不是写代码。比如:

mapping: - from: "$step1.result.order_id" to: "orderId" type: "string" - from: "$step1.result.amount" to: "refundAmount" type: "number"

这样做的好处是,映射关系可视化、可配置、可测试,不用改代码就能调整。

注意:映射配置一定要做空值检查。前一步输出可能因为异常而缺少某个字段,直接映射会导致后一步报错。建议在映射层加默认值或跳过逻辑。

4.3 失败回滚:不是所有技能都能回滚

技能执行到一半失败了怎么办?这是生产环境必须面对的问题。回滚策略取决于技能的性质:

  • 只读技能(查询类):不需要回滚,直接重试或跳过
  • 幂等写技能(设置状态类):可以重试,因为重复执行结果一样
  • 非幂等写技能(创建订单、发送消息):不能盲目重试,需要补偿操作

补偿操作是回滚的核心。比如"扣款"的补偿是"退款","发送消息"的补偿是"发送撤回通知"。但补偿操作本身也可能失败,所以需要记录补偿日志,支持人工介入。

我的经验是:能设计成幂等的技能,尽量设计成幂等。比如创建订单时带一个客户端生成的唯一ID,服务端根据ID去重。这样即使重试也不会产生重复订单,省去了大量回滚逻辑。

5. 异常处理:技能调用失败之后的那五分钟

5.1 失败分类:可重试、不可重试、需人工

技能调用失败,第一件事是判断失败类型。我通常分三类:

失败类型典型原因处理策略
可重试网络超时、限流、临时不可用指数退避重试,最多3次
不可重试参数错误、权限不足、资源不存在直接失败,返回明确错误
需人工业务规则冲突、数据不一致记录日志,转人工处理

分类的关键是看错误码和错误信息。所以技能实现时,一定要返回结构化的错误信息,而不是一个笼统的"调用失败"。错误信息里至少要包含:错误码、错误描述、是否可重试、建议处理方式。

5.2 重试策略:指数退避不是万能药

重试是处理临时故障的常用手段,但重试策略设计不好,反而会加剧问题。比如所有请求同时重试,会把下游服务打垮。

我通常用指数退避 + 抖动的策略:

import random import time def retry_with_backoff(func, max_retries=3, base_delay=1.0): for attempt in range(max_retries): try: return func() except RetryableError as e: if attempt == max_retries - 1: raise delay = base_delay * (2 ** attempt) jitter = random.uniform(0, delay * 0.1) time.sleep(delay + jitter)

这里的抖动(jitter)很关键,它让不同请求的重试时间错开,避免"重试风暴"。base_delay 设为1秒,三次重试的等待时间大约是1秒、2秒、4秒,加上抖动,总耗时在7到8秒左右。这个时长对大多数场景是可接受的。

5.3 降级方案:技能不可用时的备选路径

有些技能是核心链路,不可用会直接影响用户体验。这时候需要降级方案。

降级有两种思路:

一是切换到备用技能。比如主用的天气服务挂了,切到备用服务。这要求技能注册表支持"同能力多实现"的配置。

二是返回缓存或默认值。比如推荐服务挂了,返回热门榜单。这要求技能实现时考虑缓存策略。

降级方案要提前设计、提前测试,不能等故障发生了才临时想。我见过太多团队,故障发生时手忙脚乱,就是因为没有预案。

6. 测试与验证:怎么证明技能体系是可靠的

6.1 单元测试:每个技能单独验证

技能体系的测试,第一层是单元测试。每个技能都要有独立的测试用例,覆盖正常输入、边界输入、异常输入。

正常输入测试不用多说。边界输入容易被忽略,比如空字符串、超长字符串、特殊字符、极大极小数值。异常输入测试要验证技能在参数错误时是否返回了正确的错误码,而不是抛出一个未捕获的异常。

我通常要求每个技能的单元测试覆盖率不低于80%,核心技能要求90%以上。这个标准不算高,但能挡住大部分低级错误。

6.2 集成测试:技能之间的协作验证

单元测试过了,不代表技能之间能协作。集成测试要验证的是:路由能不能选对技能、参数能不能正确传递、多技能计划能不能按序执行、失败能不能正确回滚。

集成测试的用例设计,我建议从用户场景出发,而不是从技能出发。比如"用户查询订单并退款"是一个场景,对应"查询订单技能 + 退款技能"的组合。这样设计的用例更贴近真实使用,也更容易发现协作问题。

6.3 混沌测试:主动制造故障

生产环境的故障往往不是单一原因,而是多个小问题叠加。混沌测试就是主动注入故障,看系统能不能扛住。

常见的注入方式:

  • 让某个技能随机超时
  • 让某个技能随机返回错误
  • 让某个技能返回格式错误的数据
  • 模拟下游服务完全不可用

混沌测试的目的是验证异常处理逻辑是否真的生效。很多团队的异常处理代码写了但从来没跑过,一到真故障就发现全是bug。混沌测试能提前暴露这些问题。

提示:混沌测试建议在预发环境做,不要直接在生产环境搞。如果非要在生产做,一定要有快速回滚机制。

7. 我在实际项目里踩过的几个坑

7.1 技能描述写得太"技术",模型看不懂

前面提过,技能描述是给智能体看的。但很多人写描述的时候,习惯用技术语言,比如"调用订单服务的query接口,传入用户ID,返回订单列表"。这种描述对模型来说信息量很低,因为模型不知道"订单服务"是什么,也不知道"query接口"和"查询订单"有什么区别。

正确的写法是用业务语言:"查询指定用户的订单记录,返回订单编号、金额、状态、下单时间。适用于用户想了解自己订单情况的场景。"

7.2 忽略了技能的"副作用"标注

有些技能是只读的,有些技能会修改数据。这个区别对智能体很重要,因为修改类技能需要更谨慎的路由和确认。

我建议在技能注册表里加一个side_effect字段,标明这个技能是否有副作用。路由时,如果候选技能里有副作用技能,应该提高确认门槛,比如要求用户二次确认。

7.3 日志埋点不足,出问题查不到原因

技能体系出问题时,最怕的是"不知道哪一步错了"。所以日志要埋得足够细:路由决策日志、技能调用日志、参数传递日志、异常日志,一个都不能少。

日志里要包含 trace_id,把一次完整请求的所有环节串起来。这样排查问题时,能顺着 trace_id 看到完整的执行链路。

7.4 技能版本管理缺失,更新后旧调用失败

技能是会迭代的。如果技能更新了输入输出格式,但调用方没同步更新,就会失败。所以技能注册表要支持版本管理,调用时指定版本号,新版本上线时保留旧版本一段时间,给调用方迁移的时间。

8. 从Demo到生产:agent-skills 体系的演进路径

8.1 阶段一:单技能验证

最开始不要贪多,先做一个技能,把注册、路由、执行、异常处理的完整链路跑通。这个阶段的目标是验证架构可行性,不是功能丰富度。

8.2 阶段二:多技能路由

单技能跑通后,加到三到五个技能,重点验证路由准确性。这个阶段要开始积累路由测试用例,建立准确率基线。

8.3 阶段三:多技能协同

技能数量上到十个以上,开始出现多技能协同需求。这个阶段要重点做执行编排和参数映射,把计划执行引擎做扎实。

8.4 阶段四:生产加固

上生产之前,补齐异常处理、降级方案、监控告警、混沌测试。这个阶段的工作量往往比前面三个阶段加起来还大,但它是系统能不能稳定运行的关键。

9. 关于 agent-skills 的一点个人体会

做了几个智能体项目之后,我最大的体会是:技能体系的难点不在技能本身,而在技能之间的"关系"。单个技能写得好不好,是工程能力问题;技能之间能不能协同、路由准不准、异常处理全不全,是架构设计问题。前者靠经验积累,后者靠提前规划。

另一个体会是,不要追求一步到位。我见过太多团队,一开始就想设计一个"万能技能框架",结果框架还没搭完,需求已经变了。更好的做法是先用最小可用架构跑起来,在真实使用中发现问题,再逐步演进。技能体系是长出来的,不是设计出来的。

最后分享一个小技巧:给每个技能写一个"使用示例",就是一段模拟的用户输入和期望的技能调用。这些示例可以直接作为路由测试用例,也可以作为技能描述的补充材料。一举两得,值得试试。

相关新闻

YOLOv11嵌入式部署实战:模型压缩与推理加速全流程指南

YOLOv11嵌入式部署实战:模型压缩与推理加速全流程指南

简介:这份文档系统梳理了工业质检场景下基于YOLOv11实现零漏检目标的完整技术路线,涵盖模型压缩与嵌入式部署两大核心环节,适合从事缺陷检测、边缘AI开发的技术人员阅读。资源为单个PDF文件,约2.09MB,共30页&#xff0…

2026/10/21 7:02:48 阅读更多 →
AI辅助期刊论文写作全攻略:从选题到投稿避坑指南

AI辅助期刊论文写作全攻略:从选题到投稿避坑指南

学术圈里有个说法,论文写作是“九十九死一生”:想清楚一个能发表的研究问题很难,把研究过程讲清楚更难,最后过审稿人那关更是难上加难。我见过太多人,实验做得漂漂亮亮,数据也扎实,结果卡在“不…

2026/10/21 7:01:48 阅读更多 →
可解释多层时间序列预测:TFT架构原理与实战解析

可解释多层时间序列预测:TFT架构原理与实战解析

1. 为什么序列预测项目最后都卡在了"解释不清"这一步做时间序列预测的同行应该都有同感:模型效果调上去了,业务方一开会就问"为什么这个月预测值突然涨了15%?""模型到底看了哪些特征做判断?"——如…

2026/10/21 7:01:48 阅读更多 →

最新新闻

Electron桌面应用开发实战:从环境搭建到打包发布全流程

Electron桌面应用开发实战:从环境搭建到打包发布全流程

做前端这些年,我大部分时间都在跟浏览器标签页打交道,直到第一次把桌面应用跑起来,才发现原来自己一直被限制在地址栏和刷新按钮围起来的框框里。Electron这个词,最开始是在某段时间频繁出现在同事的讨论里,一个用HTML…

2026/10/22 10:18:38 阅读更多 →
滑盖智能锁T109深度解析:结构原理、安装调试与故障排查

滑盖智能锁T109深度解析:结构原理、安装调试与故障排查

简介:亚太天能T109滑盖智能锁产品说明书是一份PDF格式的官方技术文档,主要面向智能锁安装人员、终端用户及售后维护者,帮助快速掌握产品安装、配置与常见故障处理。全包仅1个PDF文件,大小4.37MB,内容结构清晰&#xff…

2026/10/22 11:01:53 阅读更多 →
PMSM弱磁控制原理与Simulink建模:高速AGV驱动系统设计指南

PMSM弱磁控制原理与Simulink建模:高速AGV驱动系统设计指南

上个月我在调试一台高速AGV的驱动系统,整车要求空载跑到8m/s,电机转速已经拉到额定点,驱动器的输出电压也顶到了母线电压极限附近。再往上踩速度指令,转速纹丝不动,三相电流反而开始震荡。那会儿我的第一反应就是&…

2026/10/22 9:44:47 阅读更多 →
C++核心知识点:从内存管理到STL的实战指南

C++核心知识点:从内存管理到STL的实战指南

C 这门语言我前前后后折腾了十几年,用它写过嵌入式驱动、做过游戏服务端,也搭过基础组件库。每次看到新人一头扎进"C 核心知识点"这个搜索词,我其实挺感慨的——这门语言的难点从来不是语法多,而是知识点之间的耦合太深…

2026/10/22 10:42:00 阅读更多 →
T109滑盖智能锁怎么装?安装调试与故障排查全攻略

T109滑盖智能锁怎么装?安装调试与故障排查全攻略

简介:亚太天能T109滑盖智能锁产品说明书以PDF格式发布,适合智能锁用户、安装人员与售后维修人员阅读。内容围绕T109系列指纹密码刷卡锁展开,先介绍前面板、后面板、锁体、机械钥匙、电池盒盖等部件名称与功能,再给出完整安装步骤&…

2026/10/22 10:40:08 阅读更多 →
LLM知识降熵:从信息垄断到理解权下放

LLM知识降熵:从信息垄断到理解权下放

你有没有过这种经历:翻开源码注释、论文摘要或者一份专业报告,每个字都认识,连在一起却像天书。想找人聊聊,身边要么没人懂,要么懂的懒得跟你解释。后来我试着把同一段内容丢给一个大语言模型,几秒钟之后&a…

2026/10/22 10:56:37 阅读更多 →

日新闻

周新闻

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

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

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

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

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

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

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

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

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

2026/10/22 5:12:39 阅读更多 →

月新闻

我发现了一个新思路:用 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/21 21:50:56 阅读更多 →
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/21 21:51:55 阅读更多 →
黑夜航拍船只数据集训练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/21 16:24:48 阅读更多 →