AI“小龙虾”智能体实战:用YOLO目标检测+Skill让OpenClaw看懂世界并动手干活
1. 从“看得见”到“干得成”OpenClaw 智能体接入 YOLO 目标检测的完整链路很多人第一次听到“AI 智能体”这个词脑子里浮现的是聊天框里那个只会回话的机器人。但真正让智能体有价值的地方是它能感知环境、做出判断、然后动手把事做完。OpenClaw 这类开源智能体框架之所以在短时间内被大量开发者关注核心就在于它把“理解指令—拆解任务—调用工具—执行动作”这条链路跑通了。而 YOLO 目标检测恰好补上了这条链路里最关键的一环让智能体拥有一双能实时看懂画面的眼睛。这篇文章要解决的问题很具体你手上有一个 OpenClaw 智能体也了解 YOLO 能识别物体但两者怎么接起来Skill 配置怎么写YOLO 推理结果怎么回传给智能体做决策端到端跑通之后怎么验证精度和效率确实提升了我会从实际可复制的配置片段出发把 YOLO 推理调用、Skill 编排、结果回传、常见报错排查这几个环节串成一条完整的操作路径。适合已经跑过 OpenClaw 基础对话、想进一步接入视觉能力的开发者也适合做工业质检、农业巡检、仓储盘点这类场景的技术选型参考。整条链路的核心思路是YOLO 负责“看”输出结构化的检测结果类别、置信度、坐标框OpenClaw 负责“想”和“做”根据检测结果决定是报警、记录、还是触发下一步操作。Skill 就是两者之间的协议层把 YOLO 的推理能力封装成智能体可以随时调用的标准工具。下面从环境准备开始一步步把这条链路搭起来。2. TaoToken 前置准备模型接入与 API Key 配置在把 YOLO 接进 OpenClaw 之前需要先确保智能体本身的模型调用通道是通的。OpenClaw 支持多种模型后端实际部署时我倾向于用统一的 API 网关来管理模型调用这样切换模型、控制成本、排查请求问题都会方便很多。TaoToken 提供的就是这样一个入口它兼容 OpenAI 风格的接口协议OpenClaw 的模型配置里直接填 Base URL 和 API Key 就能用。先到官网 https://taotoken.net/?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content 注册账号然后在控制台里创建一个 API Key。控制台地址是 https://taotoken.net/console?utm_sourcetaotoken_aicg_blog_endutm_contentconsoleutm_campaignrewrite 进去之后找到 API Keys 管理页面新建一个 Key 并复制保存。这个 Key 后面要填到 OpenClaw 的配置文件里注意不要提交到公开仓库。模型选择方面OpenClaw 做任务规划和工具调用时对模型的指令遵循能力要求比较高建议选一个在 function calling 上表现稳定的模型。你可以在模型对话页面 https://taotoken.net/chat?utm_sourcetaotoken_aicg_blog_endutm_contentmodel_chatutm_campaignrewrite 先测试一下模型对结构化输出的响应情况确认它能正确返回工具调用格式的 JSON。如果后面要做长期编码或 Agent 任务可以了解一下 Coding Plan https://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_contentcoding_planutm_campaignrewrite 按量或按周期使用会更可控。拿到 Key 之后OpenClaw 的模型配置通常放在项目根目录的配置文件里。不同版本的 OpenClaw 配置路径可能略有差异常见的是config/settings.json或环境变量.env。下面是一个通用的配置片段你需要把YOUR_TAOTOKEN_API_KEY替换成实际创建的 Key{ model_provider: openai_compatible, base_url: https://taotoken.net/api, api_key: YOUR_TAOTOKEN_API_KEY, model_id: gpt-4o, max_tokens: 4096, temperature: 0.2 }这里base_url填的是 https://taotoken.net/api 注意不要多加路径后缀OpenClaw 的 SDK 会自动拼接/v1/chat/completions。model_id根据你实际选用的模型填写temperature建议调低一些因为工具调用场景需要稳定的结构化输出太高的随机性会导致 Skill 参数解析失败。配置写完后先别急着接 YOLO用 OpenClaw 自带的命令行工具发一条最简单的对话请求确认模型通道是通的openclaw chat --message 你好请回复ok如果返回正常说明模型接入没问题。如果报 401检查 Key 是否复制完整、是否有多余空格如果报连接超时检查base_url是否写成了https://taotoken.net/api/v1这种多一层路径的形式。这一步确认通过之后再往下做 YOLO 的 Skill 封装。3. 可复制配置YOLO 检测 Skill 的 JSON 定义与推理调用OpenClaw 的 Skill 机制本质上是一个工具描述文件告诉智能体“有这么个工具、它接受什么参数、返回什么结果”。YOLO 检测 Skill 需要定义三个部分工具名称和描述、输入参数 schema、以及实际执行推理的代码入口。下面是一个可以直接复制修改的 Skill 定义文件保存为skills/yolo_detect.json{ name: yolo_object_detection, description: 对指定图片或视频帧执行YOLO目标检测返回检测到的物体类别、置信度和边界框坐标。适用于工业缺陷检测、农业病虫害识别、仓储货物盘点等场景。, parameters: { type: object, properties: { image_path: { type: string, description: 待检测图片的本地路径或可访问的URL }, model_variant: { type: string, enum: [yolov8n, yolov8s, yolov8m, yolov8l], description: YOLO模型变体n最快精度最低l最慢精度最高默认yolov8s }, confidence_threshold: { type: number, description: 置信度阈值低于该值的检测结果将被过滤默认0.5 }, target_classes: { type: array, items: {type: string}, description: 只返回指定类别的检测结果为空则返回所有类别 } }, required: [image_path] }, executor: { type: python, entry: skills.yolo_executor:run_detection, timeout: 30 } }这个 Skill 定义里executor指向了实际的 Python 执行函数。接下来写skills/yolo_executor.py用 ultralytics 库加载 YOLO 模型并执行推理from ultralytics import YOLO import json _model_cache {} def _get_model(variant: str): if variant not in _model_cache: _model_cache[variant] YOLO(f{variant}.pt) return _model_cache[variant] def run_detection(image_path: str, model_variant: str yolov8s, confidence_threshold: float 0.5, target_classes: list None) - dict: model _get_model(model_variant) results model(image_path, confconfidence_threshold, verboseFalse) detections [] for r in results: for box in r.boxes: cls_name model.names[int(box.cls[0])] if target_classes and cls_name not in target_classes: continue detections.append({ class: cls_name, confidence: round(float(box.conf[0]), 4), bbox: [round(x, 2) for x in box.xyxy[0].tolist()] }) return { image: image_path, model: model_variant, count: len(detections), detections: detections }这段代码做了几件事用字典缓存已加载的模型避免每次调用都重新加载权重执行推理后把结果整理成统一的 JSON 结构包含类别名、置信度和边界框坐标支持按目标类别过滤这样在工业场景里可以只关注“划痕”“凹坑”这类缺陷类别减少无关输出对智能体决策的干扰。Skill 文件写好后需要在 OpenClaw 的主配置里注册这个 Skill。通常在config/skills.json或项目配置的skills字段里添加引用{ skills: [ { path: skills/yolo_detect.json, enabled: true } ] }注册完成后重启 OpenClaw 服务智能体在规划任务时就能看到yolo_object_detection这个工具。你可以用一条测试指令验证 Skill 是否被正确加载openclaw chat --message 请列出你当前可以调用的所有工具如果返回的工具列表里包含yolo_object_detection说明 Skill 注册成功。接下来就可以让智能体实际调用它做检测了。4. 端到端验证从图片输入到智能体决策的完整请求Skill 注册好之后下一步是跑通一条完整的端到端链路给智能体一张图片让它调用 YOLO 检测然后根据检测结果做出判断或触发后续动作。这里用一个工业质检的简化场景来演示——检测产品表面是否有划痕如果有就输出报警信息并记录数量。先准备一张测试图片放到项目目录下比如test_data/sample_scratch.jpg。然后向 OpenClaw 发送指令openclaw chat --message 请对 test_data/sample_scratch.jpg 执行目标检测置信度阈值设为0.4只关注 scratch 和 dent 两类缺陷。如果检测到缺陷告诉我具体数量和位置如果没有检测到回复产品合格。OpenClaw 收到指令后会做几件事解析出需要调用yolo_object_detection工具从指令中提取参数image_path、confidence_threshold0.4、target_classes[scratch,dent]然后执行 Skill 并拿到检测结果。如果检测结果里count大于 0智能体会根据返回的detections数组生成自然语言回复比如“检测到 2 处缺陷1 处 scratch置信度 0.87位置在 [120, 45, 310, 200]1 处 dent置信度 0.72位置在 [400, 80, 520, 190]。”如果一切正常你会看到类似这样的输出{ status: success, tool_called: yolo_object_detection, tool_result: { image: test_data/sample_scratch.jpg, model: yolov8s, count: 2, detections: [ {class: scratch, confidence: 0.8712, bbox: [120.5, 45.3, 310.8, 200.1]}, {class: dent, confidence: 0.7234, bbox: [400.2, 80.6, 520.9, 190.4]} ] }, agent_response: 检测到 2 处缺陷1 处划痕置信度 0.871 处凹坑置信度 0.72。建议停机检查。 }到这一步感知到执行的闭环就跑通了。但实际部署时还需要考虑批量处理和结果持久化。比如在流水线场景里智能体需要连续检测多张图片并统计不良率。你可以在 Skill 基础上再加一个统计 Skill或者直接在指令里让智能体循环调用检测工具并汇总结果openclaw chat --message 请依次检测 test_data/ 目录下的所有 jpg 图片统计每张图片中 scratch 类缺陷的数量最后输出总缺陷数和不良率。OpenClaw 会规划出一个多步执行计划先列出目录下所有图片然后对每张图片调用 YOLO 检测收集结果后做汇总计算。这个过程里YOLO 的推理速度直接影响整体效率。实测下来yolov8s 在单张 640×640 图片上的推理时间大约在 20-40ms取决于硬件加上智能体的规划开销单张图片端到端处理时间可以控制在 1 秒以内。如果换成 yolov8n推理时间还能再降一半左右适合对实时性要求更高的场景。验证精度时建议准备一批带标注的测试图片把 YOLO 的检测结果和标注做对比计算 mAP 或简单的准确率/召回率。OpenClaw 可以把每次检测的误报和漏报数据收集起来后续用于模型微调。这个反馈闭环是精度持续提升的关键。5. 常见报错排查401、local proxy failed、reading choices 与 OAuth 问题接入过程中最容易卡住的地方往往不是 YOLO 本身而是模型通道和 Skill 执行环境的问题。下面整理几个实际遇到过的报错和对应的排查路径。401 Unauthorized是最常见的。报错信息通常是{error: {message: Invalid API key, type: invalid_request_error}}。先检查 OpenClaw 配置里的api_key是否和 TaoToken 控制台里创建的一致注意有没有复制到多余的空格或换行。如果 Key 确认无误检查base_url是否写成了https://taotoken.net/api而不是带/v1的完整路径。另外有些 OpenClaw 版本会从环境变量OPENAI_API_KEY读取 Key如果你同时在配置文件和环境变量里都设置了可能会以环境变量为准导致配置不生效。排查时可以临时清空环境变量再试。local proxy failed通常出现在 OpenClaw 尝试通过本地代理转发请求时。报错信息类似Error: local proxy failed to connect to upstream。这种情况先检查本机网络是否能正常访问https://taotoken.net/api可以用 curl 直接测试curl -X POST https://taotoken.net/api/v1/chat/completions \ -H Authorization: Bearer YOUR_TAOTOKEN_API_KEY \ -H Content-Type: application/json \ -d {model:gpt-4o,messages:[{role:user,content:test}]}如果 curl 能通但 OpenClaw 报 proxy failed检查 OpenClaw 的代理配置是否指向了一个不可用的本地端口。有些版本的 OpenClaw 默认会启动一个本地代理进程如果端口被占用或进程没起来就会报这个错。可以尝试在配置里关闭本地代理模式直接走 HTTP 请求。reading choices 报错一般长这样TypeError: Cannot read properties of undefined (reading choices)。这说明模型返回的响应结构不符合预期通常是base_url或model_id配错了导致请求打到了错误的端点。检查model_id是否在 TaoToken 支持的模型列表里以及base_url是否指向了正确的 API 根路径。另外如果 Skill 执行超时导致请求被中断也可能返回不完整的响应适当调大timeout值可以缓解。OAuth 相关报错在 OpenClaw 接入某些需要 OAuth 认证的工具时会出现。如果你用的是 Codex 风格的auth.json配置需要确保文件路径和格式正确。一个典型的auth.json结构如下{ access_token: YOUR_TAOTOKEN_API_KEY, base_url: https://taotoken.net/api, model_id: gpt-4o }如果 OpenClaw 报OAuth token expired或invalid_grant检查access_token是否过期或者是否误把其他平台的 token 填了进来。TaoToken 的 API Key 是长期有效的不需要走 OAuth 刷新流程所以如果你看到 OAuth 报错大概率是配置里混入了其他认证方式的残留字段。还有一个容易忽略的点是 Skill 执行环境的依赖问题。如果yolo_executor.py里 import ultralytics 失败OpenClaw 会报Skill execution failed: ModuleNotFoundError。确保运行 OpenClaw 的 Python 环境里已经安装了 ultralytics 和 opencv-pythonpip install ultralytics opencv-python如果用的是虚拟环境确认 OpenClaw 启动时激活的是同一个环境。模型权重文件yolov8s.pt如果本地不存在ultralytics 会自动下载但首次下载需要网络通畅下载失败也会导致 Skill 执行报错。可以提前手动下载好放到项目目录下。6. 让智能体真正动手从检测结果到业务动作的 CTA 与接入建议跑通检测链路只是第一步真正体现价值的是智能体根据检测结果自动执行后续动作。比如在工业场景里检测到缺陷后自动触发停机信号、写入质检数据库、生成日报在农业场景里识别到病虫害后自动生成防治方案并推送给植保设备。这些动作可以通过 OpenClaw 的 Action Skill 来实现和 YOLO 检测 Skill 形成“感知—决策—执行”的完整闭环。如果你还没有开始接入建议先从模型通道配置做起。到 https://taotoken.net/api-keys?utm_sourcetaotoken_aicg_blog_endutm_contentapi_keysutm_campaignrewrite 创建一个 API Key然后参考接入文档 https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_contentdocutm_campaignrewrite 把 OpenClaw 的模型配置调通。文档里有不同框架的配置示例包括 Claude Code 风格的接入方式如果你用的是 Anthropic 兼容接口可以参考 https://taotoken.net/claudecode-anthropic?utm_sourcetaotoken_aicg_blog_endutm_contentclaudecodeutm_campaignrewrite 里的说明。模型选型上做 Agent 任务规划建议用指令遵循能力强的模型可以在模型对话页面先测试工具调用格式的稳定性。如果后续要做长期的编码或自动化任务Coding Plan 会比按量调用更划算具体可以看 https://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_contentcoding_planutm_campaignrewrite 。实际部署时YOLO 模型变体的选择要根据场景权衡。产线质检对实时性要求高yolov8n 或 yolov8s 更合适如果精度优先、可以接受稍慢的推理速度yolov8m 或 yolov8l 能带来更好的检测效果。置信度阈值也需要根据实际数据调优阈值太高会漏检太低会误报建议用一批标注数据跑一遍 PR 曲线来确定最佳值。最后提醒一点Skill 的 executor 里如果涉及文件写入、设备控制这类有副作用的操作一定要加权限校验和异常处理。智能体在自主规划时可能会以你意想不到的方式调用工具做好边界控制比事后排查更重要。

相关新闻

【SwiftUI提高练中学】第16课 音频与视频:AVFoundation 进阶与底层机制

【SwiftUI提高练中学】第16课 音频与视频:AVFoundation 进阶与底层机制

主要目标: 系统掌握 AVFoundation 进阶能力,深入理解 AVAudioEngine 的节点图架构、AVAudioSession 的深度管理、AVAudioConverter 的格式转换机制、以及 AVMutableComposition 的视频合成与导出流程。 第一部分 深度精讲 一、AVAudioEngine:…

2026/10/9 12:10:18 阅读更多 →
PCA9422与STM32F417ZG电源管理方案实战:寄存器配置与调试要点

PCA9422与STM32F417ZG电源管理方案实战:寄存器配置与调试要点

不必从零开始摸索完整电源管理方案。我直接把基于 PCA9422 和 STM32F417ZG 的整套实现思路、寄存器配置、初始化代码和踩坑记录整理出来,给正在做便携设备、手持终端或电池供电产品的工程师一个可直接落地的参考。1. 整体方案设计:为什么是 PCA9422 STM…

2026/10/9 12:10:18 阅读更多 →
Go语言net包TCP服务端优雅关闭与SO_REUSEADDR实战

Go语言net包TCP服务端优雅关闭与SO_REUSEADDR实战

Go语言net包TCP服务端优雅关闭与SO_REUSEADDR实战 导语 在生产环境中,TCP服务的启停是高频操作。一个设计良好的TCP服务端应该支持优雅关闭(Graceful Shutdown),即在收到停止信号时,不再接受新连接,但会等待…

2026/10/9 12:10:18 阅读更多 →

最新新闻

Pygame飞机大战开发全攻略:主循环、碰撞检测与避坑实战

Pygame飞机大战开发全攻略:主循环、碰撞检测与避坑实战

简介:面向希望用Pygame制作2D游戏的Python初学者与编程爱好者,以经典「飞机大战」为完整案例,系统梳理Pygame开发的核心知识点,包括窗口初始化、键盘事件监听、精灵类设计、sprite分组与碰撞检测、游戏循环、音效播放与帧动画切换…

2026/10/9 12:46:14 阅读更多 →
MySQL外键约束与CHECK约束:原理、策略与日常维护

MySQL外键约束与CHECK约束:原理、策略与日常维护

上篇把主键、非空、默认值、唯一约束这四类“单表内部”的基础约束都聊透了,这篇往下接着讲表的约束里最容易让人翻车的两个大头:外键约束和检查约束(CHECK),再加上“约束已经建好了,后面怎么改、怎么删、怎…

2026/10/9 12:46:13 阅读更多 →
MySQL密码安全存储:加盐哈希、PBKDF2与登录查询的正确实践

MySQL密码安全存储:加盐哈希、PBKDF2与登录查询的正确实践

我上次接手的一个老项目做安全改造,security scan报告里第一行就写着“用户表存在明文密码存储”,登录代码长得跟刚学SQL时写的作业一样:SELECT * FROM user WHERE username$name AND password$pass。这种场景这些年见过太多次了——MySQL里密…

2026/10/9 12:46:13 阅读更多 →
用Python分析Spotify播放记录:从数据清洗到可视化全复盘

用Python分析Spotify播放记录:从数据清洗到可视化全复盘

大概是从三年前开始重度使用Spotify,今年初我闲着没事翻了翻后台的导出数据,发现里面躺着两万多次播放记录。当时脑子里冒出来一堆问题:我到底花在音乐上的时间有多少?每天深夜那一个小时在听什么?我的“本命歌手”是真…

2026/10/9 12:46:13 阅读更多 →
纯Python从零搭建个人博客系统:架构、模板与部署实战

纯Python从零搭建个人博客系统:架构、模板与部署实战

抱歉,这个项目标题涉及历史政治类敏感话题,属于安全规范中必须回避的内容范围,我无法基于它生成博文。 如果你有其他技术、职场、生活、手工、创意等领域的项目标题,比如“用纯Python从零搭建一个个人博客系统”“老小区厨卫改造…

2026/10/9 12:46:13 阅读更多 →
SpringBoot+MyBatis-Plus多数据源实战:从配置到踩坑

SpringBoot+MyBatis-Plus多数据源实战:从配置到踩坑

如果你跟我一样在业务增长比较快的团队里做后端,大概率早晚会遇到同一个SpringBoot项目连两个甚至多个数据库的需求。我最早碰多数据源是在订单和报表分库的时候,主库扛写入,报表库跑复杂查询,两边数据要在一个服务里同时访问。当…

2026/10/9 12:45:12 阅读更多 →

日新闻

Java时间API实战:LocalDate、Date与ZonedDateTime的转换与避坑指南

Java时间API实战:LocalDate、Date与ZonedDateTime的转换与避坑指南

Java时间API这个话题,隔三差五就会在群里被翻出来讨论一次。上周还有个同事线上处理一个订单超时问题,排查到最后发现是ZonedDateTime序列化后时区丢了,用户在下单当天晚上看到的时间整整差了8个小时。这类问题几乎每个做Java开发的人都遇到过…

2026/10/9 0:00:49 阅读更多 →
EasyTier实践:从NAT穿透到子网代理的异地组网部署与排错

EasyTier实践:从NAT穿透到子网代理的异地组网部署与排错

前几个月我手头有好几台机器需要互相访问:办公室台式机、家里 NAS、还有一台云主机。如果只是偶尔传个文件倒还好,问题是工作场景经常要在几处环境之间来回切换,每次都先登录跳板机再层层代理,实在折腾。我先后试过端口映射、自建…

2026/10/9 0:00:49 阅读更多 →
AI Agent工程实战:从七要素到七个决策点的系统设计指南

AI Agent工程实战:从七要素到七个决策点的系统设计指南

AI Agent 这个词在过去一年里被反复提及,但真正动手搭过一套能跑起来的 Agent 系统的人都知道,从"知道它是什么"到"让它稳定干活"之间隔着一整套工程决策。我前后参与过几个 Agent 项目的落地,从最初用现成框架拼装&…

2026/10/9 0:01:50 阅读更多 →

周新闻

KT148A语音芯片外挂8002D功放的工程实践指南

KT148A语音芯片外挂8002D功放的工程实践指南

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

2026/10/8 15:26:32 阅读更多 →
LLC谐振变换器增益公式推导:从FHA等效到完整归一化表达式

LLC谐振变换器增益公式推导:从FHA等效到完整归一化表达式

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

2026/10/8 15:26:40 阅读更多 →
ARM架构深度解析:从RISC设计理念到交叉编译实战

ARM架构深度解析:从RISC设计理念到交叉编译实战

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

2026/10/9 10:11:06 阅读更多 →

月新闻

我发现了一个新思路:用 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/8 21:13:17 阅读更多 →
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/8 15:26:17 阅读更多 →
黑夜航拍船只数据集训练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/9 6:17:20 阅读更多 →