企业微信外部群多账号轮巡推送:解决频控与打扰的工程实践
1. 为什么外部群自动化会被卡在“多发一条”上1.1 外部群与内部群的本质差异做企业微信自动化的朋友最先接触的往往是内部群。内部群里的成员都是同一组织的人账号权限、接口策略相对宽松机器人往群里发消息基本没有太多限制。等你把内部群的推送链路跑通准备把同样的方案搬到外部群时问题就来了。外部群和内部群最大的区别在于成员身份边界。外部群的用户既有企业内部的成员也有客户、供应商等外部联系人。企业微信对外部群的接口权限、消息频率、用户ID体系都做了专门限制目的就是防止外部群被滥用成营销工具。你会发现同一个机器人在内部群能正常推送在外部群要么发不出去要么频繁触发接口报错甚至群主收到提醒。另一个关键差异是会话用户ID的加密机制。在内部群里我们能直接拿到成员的userid跟通讯录对得上。但在外部群里拿到的往往是加密后的external_userid它跟openid一样是某个企业在某个应用维度下的唯一标识直接拿来当userid用必然踩坑。后面我会专门讲这个ID怎么解析、怎么用。1.2 从单账号到多账号轮巡到底解决什么问题单账号推送的方案很简单一个自建应用一个机器人一个群一个群发过去。这个方案在几十个群的规模下是完全够用的问题出现在两个点第一单账号的推送频率会被限制。企业微信对同一应用在同一时间段内的消息量有隐性约束集中推送几百个群大概率触发频控表现就是部分群成功、部分群失败失败原因写的是“请求频率过高”。你排查了半天发现代码逻辑没问题就是账号被限了。第二长期单账号高频推送会让群里的用户产生明显打扰感。外部群的客户对消息的敏感度远高于内部群一个账号一天在同一批群里连续出现多次被投诉和拉黑的概率会直线上升。多账号轮巡推送就是为了解决这两个问题用多个账号分担推送压力每个账号在一轮循环中只负责一部分群的推送并且通过轮巡调度让每个账号的活跃状态尽量均衡。我试下来在保持相同送达效果的前提下账号数量翻倍之后单账号的连续推送量至少能降一半以上群投诉率也明显下降。1.3 方案选型Webhook还是RPA外部群自动化的技术路线主流的就两条接口直连和RPA模拟操作。很多人在这一步纠结很久我的建议是可以直接放弃纠结先想清楚你要的是什么。接口直连走的是企业微信官方API稳定、可追踪、有完整的错误码体系。适合有开发能力的团队能拿到消息回执和发送记录出了问题可以回溯。RPA模拟操作则是通过自动化工具控制客户端界面门槛低不需要企业认证和接口权限但稳定性、速度、异常处理能力都比较差一旦客户端更新界面脚本就要跟着改。我的经验是优先走接口直连把RPA留着对付接口覆盖不到的场景比如“被动回复客户消息”这种需要客户端交互的操作。如果你的账号本身没有接口调用权限再考虑RPA否则它会成为你后期最大的维护负担。2. 多账号轮巡推送的核心设计拆解2.1 账号池与调度策略怎么设计账号池是整个轮巡系统的地基。你手里有几个可用账号每个账号能管哪些群必须提前规划清楚不能等代码写完了再拍脑袋。我建议用一个简单的配置表来管理账号与群的对应关系。表结构大致长这样字段含义示例account_id账号唯一标识account_01group_ids归属该账号的群列表group_a, group_b, group_cmax_push_per_round每轮最大推送数30interval_seconds单条消息间隔3~8秒随机enabled是否启用true为什么建议每个账号绑定固定的群列表而不是每次动态分配因为外部群对“同一账号突然出现在不相关群里”是有感知的一个客户如果同时存在于多个群看到同一个账号来回出现观感会非常差。固定绑定之后每个账号只会出现在它负责的那批群里行为模式更接近真人运营也方便后续针对单个账号做数据复盘。轮巡调度的核心逻辑是先分组、再排时间、最后加扰动。把全部群按账号分组之后每个账号在一轮循环中按照固定的组顺序依次推送时间上每个组之间要留足间隔避免所有账号在同一秒同时发起请求最后给每条消息加上随机延迟模拟人工发送的节奏。2.2 统一的推送接口与技术细节多账号推送最怕的是每个账号写一套代码。哪怕底层逻辑一模一样只要账号凭证的获取方式不同你就会被一堆分支逻辑拖死。所以从一开始就一定要抽一个统一的推送接口。接口不复杂入参就是账号标识、群标识、消息内容出参就是成功或失败的结果。内部逻辑根据账号标识去加载对应的凭证再调用企业微信的机器人Webhook。Webhook是企业微信机器人最方便的消息入口每一批群的配置里都会有一个webhook地址推送时对地址发POST请求body里带上消息类型和内容即可。有一个细节很多人会漏掉企业微信机器人的Webhook地址是会过期和失效的。当你更换机器人或重新生成Webhook时旧地址立刻失效代码里如果硬编码了地址那天晚上推送就会全挂。正确做法是把Webhook地址收进配置中心或数据库里统一管理更新时只改数据不动代码。消息内容的格式也得统一。文本消息的JSON结构很简单但如果你需要推送卡片、图片、文件每种消息类型都有独立的字段要求建议在接口层就做消息类型适配避免上层业务代码写满了if else。2.3 配置化驱动与日志链路多账号轮巡系统上线之后你会面临一个很现实的问题群里反馈“没收到消息”你根本不知道是哪个环节出了问题。是调度没触发是账号被限流是消息发到了群里但用户没看到没有日志你只能靠猜。配置化驱动在大方向上解决“改一个群配置就要发一版代码”的尴尬。账号增删、群增删、推送间隔调整这些都是高频操作全部放到配置平台上运营人员自己就能改开发人员不用参与每次变更。日志链路更关键我把整个链路切成四段调度日志记录什么任务在哪个时间点被触发、发送日志记录向哪个Webhook发了什么内容、响应日志记录企业微信返回的成功或失败状态、业务日志记录群和用户的上下文信息便于追溯。这四段日志串起来任何一条消息的生命周期都清晰可查。3. 从零搭建轮巡推送服务3.1 完整目录结构与配置说了这么多设计思路下面直接给一套可以跑的方案。我用Python实现核心依赖只有requests和APScheduler数据库用SQLite追求的是轻量和可复现。目录结构如下wecom-rotation/ ├── config.py # 全局配置 ├── models.py # 数据模型与存储 ├── scheduler.py # 轮巡调度器 ├── pusher.py # 统一推送接口 ├── id_resolver.py # external_userid 解析 ├── main.py # 入口 └── data/ └── rotation.db # SQLite 数据库config.py里放基础参数包括每个账号的Webhook地址、默认推送间隔、最大重试次数。models.py里放账号池和群组关系。scheduler.py负责轮巡调度。pusher.py是对外暴露的唯一入口。id_resolver.py负责处理外部联系人ID的解析与映射。数据库初始化时先建三张表account账号表、group_info群信息表、push_log推送日志表。结构如下CREATE TABLE account ( id INTEGER PRIMARY KEY AUTOINCREMENT, account_id TEXT UNIQUE, webhook_url TEXT, enabled INTEGER DEFAULT 1 ); CREATE TABLE group_info ( id INTEGER PRIMARY KEY AUTOINCREMENT, group_id TEXT, account_id TEXT, group_name TEXT ); CREATE TABLE push_log ( id INTEGER PRIMARY KEY AUTOINCREMENT, account_id TEXT, group_id TEXT, content TEXT, status TEXT, error_msg TEXT, created_at TEXT );3.2 核心代码实现先看调度器。我倾向于用APScheduler的IntervalTrigger配一个动态间隔每次触发时再计算下一次的推送时间。核心代码长这样# scheduler.py from apscheduler.schedulers.background import BackgroundScheduler from datetime import datetime, timedelta import random class RotationScheduler: def __init__(self, pusher, db): self.pusher pusher self.db db self.scheduler BackgroundScheduler() def start(self): # 每30秒检查一次是否有待推送任务 self.scheduler.add_job( self._round_robin, interval, seconds30, idrotation_check ) self.scheduler.start() def _round_robin(self): accounts self.db.get_enabled_accounts() for account in accounts: groups self.db.get_groups_by_account(account[account_id]) # 随机扰动每个账号每轮的推送顺序都不同 random.shuffle(groups) for group in groups: # 每条消息之间随机休眠3~8秒 delay random.uniform(3, 8) time.sleep(delay) content self._build_message() result self.pusher.push(account, group, content) self.db.log_push(account, group, content, result)这段代码的核心思路是每轮循环重新打乱群顺序避免每个账号永远从同一个群开始推送。连续几轮下来群与群之间的接收时间差会被抹平。再看统一推送接口。这个接口做了三件事加载账号配置、构造请求体、发送并处理异常# pusher.py import requests import json class Pusher: def push(self, account, group, content): webhook_url account[webhook_url] payload { msgtype: text, text: { content: content } } try: resp requests.post(webhook_url, jsonpayload, timeout10) data resp.json() if data.get(errcode) 0: return {status: ok, msg: data.get(errmsg)} else: return {status: fail, msg: data.get(errmsg)} except Exception as e: return {status: error, msg: str(e)}这里有一个容易踩的坑requests.post如果不加timeout当Webhook服务端异常挂起时整个线程会卡住后续排队的所有群全部推不出去。加了10秒超时之后单条消息最多阻塞10秒调度器仍然可以继续往下走。3.3 温湿度场景实战闭环光有推送框架还不够得有一个实际业务场景把链路串起来。我这里用温湿度监控推送讲一个完整闭环因为它在工业、仓储场景中最常见也最能体现自动化的价值。需求背景是车间里有多个温湿度传感器数据通过网关汇聚到平台。当某个区域的温度超过阈值时系统需要自动把告警消息推送到对应的企业微信外部群并且要求不同区域的告警由不同账号发送避免所有告警集中在一个账号上。实现思路如下温度传感器每30秒上报一次数据服务端检测到温度超过35度时生成一条告警文本根据传感器所在区域找到对应的群分组再从分组绑定的账号中选取当前轮巡的账号调用Pusher.push()发送消息推送结果写入push_log便于排查。告警文本示例【温湿度告警】A区-3号传感器 当前温度38.5℃阈值35℃ 当前湿度62%RH 时间2025-06-12 14:32:08 请相关人员及时到现场查看。这里有一个细节值得单独说同一个告警不能重复推送。传感器每30秒上报一次温度持续超标会连续触发多次。如果不做去重群里会收到几十条相同内容的告警客户体验极差。我的做法是在数据库里加一张alert_record表记录每个告警指纹传感器ID时间四舍五入到分钟是否已推送过只有新的指纹才触发推送。3.4 外部联系人识别与自动打标回到开头提到的那个核心问题外部群会话里拿到的用户ID是加密的怎么解析企业微信外部群接口返回的external_userid本质上是企业维度下的加密标识直接传给其他接口会报“invalid external_userid”。官方支持的解析路径是调用“客户联系”接口通过external_userid换取客户详情前提是这个用户是企业的外部联系人并且企业有客户联系功能的权限。具体做法是先通过回调或接口拉取外部联系人列表拿到external_userid后调用/cgi-bin/externalcontact/get接口传入external_userid返回客户姓名、备注、标签等详情。拿到详情后把external_userid和内部业务系统的用户ID做映射存到我们的id_resolver表里后续所有业务系统的用户标识都以这个映射为准。有一个值得特别注意的点external_userid在不同应用之间是不通用的但在同一企业不同应用下是保持一致的。这句话的意思是你用自建应用A拿到的external_userid在自建应用B里大概率可以直接用但如果你换了一家企业主体同一个客户会生成完全不同的external_userid。所以做数据迁移时千万不要直接搬ID一定要按企业主体重新映射。打标方面我推荐把外部联系人按群来源自动打上企业标签。比如从“A区客户群”进来的用户打上“A区-外部客户”标签。这个标签后续能用于群发消息的受众筛选也能帮运营人员快速识别身份。4. 上线后必看的避坑清单与排查速查4.1 我踩过的坑先说一个最常见的坑多个账号共用一个Webhook。有些团队为了省事把所有群都配到同一个机器人的Webhook上轮巡调度器虽然切换了账号身份但消息实际都是从同一个机器人发出去的。这样账号轮巡只是表面上的轮巡底层的发送通道完全没变限流和投诉问题一个都躲不掉。正确做法是每个账号独立建机器人生成独立的Webhook。第二个坑是重试机制写成了无限重试。我的推送接口里如果加了错误无限重试当某个Webhook地址失效时线程会一直卡在重试循环里调度器后面的任务全部被堵死。正确做法是限制重试次数比如最多重试3次每次间隔递增1秒、3秒、10秒重试3次仍然失败就不再尝试直接写失败日志等人工处理。第三个坑与时区有关。如果服务部署在海外节点系统默认时区不是你本地时区APScheduler的定时触发会跟你预期的时间差好几个小时。最稳妥的解决办法是在调度器初始化时明确指定时区比如pytz.timezone(Asia/Shanghai)所有日志时间也都统一用带时区的时间格式存储。4.2 常见问题排查速查表我把过去一段时间里最常遇到的线上问题整理成了速查表方便你直接对照排查。现象可能原因排查思路所有群都推送失败Webhook地址配置错误或已失效先手动curl一下Webhook验证是否返回正确部分群成功、部分群失败单账号被限流查看失败错误码是否包含频率限制相关提示消息发出去了但用户看不到该用户已不在群内或群已解散检查群成员列表确认用户仍在群中推送延迟严重前一条消息卡在重试循环中查看推送日志确认是否有异常阻塞同一群收到重复消息缺少告警去重机制检查数据库里的历史推送记录external_userid解析报错使用了错误的ID或跨企业主体确认ID来源应用是否一致排查时优先看推送日志上面我提到的四段日志要按时间顺序排查不要跳着看。大多数问题在日志里都能定位到具体环节。4.3 合规红线与道德边界最后这部分必须单独拿出来讲。多账号轮巡推送在技术上不难难的是分寸感。企业微信对外部群消息的管控逻辑非常清晰它允许企业触达自己的客户但不允许骚扰陌生用户。所以你在做推送时一定要确认推送对象是已经添加过的外部联系人而不是从群聊里临时抓取的用户消息内容要跟用户的实际需求相关不能是无差别广告推送频次也要控制不是“能推就推”而是“需要才推”。我个人的原则是每条推送都必须有明确的目的和价值。温湿度告警是有价值的因为你关机了客户会遭受损失无差别的营销推广是没有价值的因为用户根本没有预期。你可以用同样的技术框架去做营销推送但那种场景下用户授权和退订机制是必须前置的环节不能省略。另外提醒一点别把外群当私域流量池来轰炸每天推十条八条用户的投诉会直接反映到账号封禁上。企微对垃圾消息的判定和处罚力度逐年加强账号被封之后想解封的流程非常痛苦。合规不是额外的负担而是让这套系统能够长期稳定运行的前提。5. 这个方向后续还能怎么扩展写到这里多账号轮巡推送的主链路算是完整了。从调度策略、账号池设计、统一推送接口到ID解析和问题排查你手里已经有一套可以真正跑起来的方案。如果你希望在这个基础上继续做深我个人建议关注三个方向第一个方向是推送效果的量化分析。现在的推送只是“发出去了”至于用户看了没有、点没点链接其实一无所知。企业微信的消息回执接口和数据统计能力能帮你把推送链路变成数据闭环比如统计每个账号的送达率、阅读率、退群率。有了这些数据之后账号绑定群组的策略可以进一步优化。第二个方向是异常自愈机制。比如当某个Webhook连续失败达到一定次数系统自动把该Webhook标记为异常并从备用账号池中暂时接管对应的群同时通知管理员处理。这样即使某个账号出现故障用户侧的推送体验也不会中断。第三个方向是推送内容的差异化。不同群的用户属性不同推送内容可以基于标签和群特征做模板渲染。比如给A区客户群推送的文案带上A区的传感器编号给B区客户群推送的文案带上B区信息。模板渲染不复杂但对用户体验的提升非常明显。我在实际运行这套系统的过程中最大的体会是自动化不是替代人而是把人从重复劳动中解放出来去做更值得做的判断。轮巡调度、多账号管理、日志排查这些环节全部交给代码处理之后运营人员的精力可以完全集中在“这条消息该不该发、发给谁、什么时候发最合适”这些真正的业务问题上。如果你也正在做类似的项目希望这篇文章能帮你少走几步弯路。

相关新闻

Spring Boot医院管理系统实战:从数据库设计到部署上线全解析

Spring Boot医院管理系统实战:从数据库设计到部署上线全解析

做了几年的医疗信息化项目,大大小小的医院管理系统也经手过好几套。从早期用JSPServlet手撸的笨重老系统,到后来基于Spring Boot的轻量级微服务架构,中间踩过的坑、重构掉的代码,说多了都是泪。今天这篇没什么高大上的概念&#x…

2026/10/11 11:33:30 阅读更多 →
OpenClaw接MCP后token暴涨?底层原理与成本优化实战

OpenClaw接MCP后token暴涨?底层原理与成本优化实战

给 OpenClaw 接 MCP,我发现每次对话都在偷偷烧token 如果你最近在玩 OpenClaw,或者正打算把一堆 MCP 工具接进去,建议先看完这篇再动手。我是在本地把 OpenClaw 跑起来之后,顺手接了三四个 MCP server,刚开始觉得挺爽…

2026/10/12 21:34:32 阅读更多 →
EUI-NEO高性能的秘密:脏区渲染与Retained Layer缓存原理全解析

EUI-NEO高性能的秘密:脏区渲染与Retained Layer缓存原理全解析

EUI-NEO高性能的秘密:脏区渲染与Retained Layer缓存原理全解析 【免费下载链接】EUI-NEO EUI-NEO is a cross-platform, high-performance, low-overhead C17 GPUI framework 项目地址: https://gitcode.com/gh_mirrors/eui3/EUI-NEO EUI-NEO 是一个跨平台、…

2026/10/11 6:42:45 阅读更多 →

最新新闻

金融时间序列建模全流程:从平稳性检验到GARCH波动率预测

金融时间序列建模全流程:从平稳性检验到GARCH波动率预测

1. 从第一节课到第四章:金融时间序列到底在研究什么如果你正在啃金融相关的课程,大概率会在一门叫《金融时间序列分析》或类似名字的课上卡住。这门课和传统统计学、计量经济学都不一样,它研究的是股票收益率、汇率波动、债券利差这类有“先后…

2026/10/14 0:48:55 阅读更多 →
AgenticOps工程:企业自动化运维的自主决策革命

AgenticOps工程:企业自动化运维的自主决策革命

1. AgenticOps Engineering 的本质与价值AgenticOps Engineering 正在重新定义企业自动化运维的边界。与传统自动化工具不同,这种新型工程范式通过赋予系统自主决策能力,使企业IT基础设施能够像拥有"数字员工"一样主动感知环境变化、预测问题并…

2026/10/14 0:48:55 阅读更多 →
用插件重构知识工作流:浏览器、编辑器与知识库的自动化实践

用插件重构知识工作流:浏览器、编辑器与知识库的自动化实践

知识工作者这个词听起来有点抽象,但落到日常就非常具体:你可能天天在写方案、查资料、写代码、记笔记、做汇报,一天结束回头一看,真正用在"思考"上的时间反而不多,大量时间被复制粘贴、切换窗口、找文件、重…

2026/10/14 0:48:55 阅读更多 →
ABAP单元测试效率提升:ADT工具链实战

ABAP单元测试效率提升:ADT工具链实战

1. 项目概述:当ABAP单元测试遇上效率革命在SAP开发领域,ABAP Unit作为核心测试框架已经存在多年,但真正能将其融入日常开发的团队却不多见。问题不在于框架本身,而在于传统测试流程中存在太多效率断层——从编写测试用例到执行测试…

2026/10/14 0:48:55 阅读更多 →
Python远程批量关机实战:WinRM/WMI/SMB三路径选型与避坑

Python远程批量关机实战:WinRM/WMI/SMB三路径选型与避坑

简介:本资源是一份面向Windows系统管理员与IT运维人员的Python自动化脚本工具包,解决多台设备集中管理场景下的远程批量关机需求,适用于机房巡检、课室终端维护、故障应急处置等实际运维任务。压缩包共3个文件(923B)&a…

2026/10/14 0:48:55 阅读更多 →
尖叫声音样本数据集eva:从包结构到训练基线的完整实践

尖叫声音样本数据集eva:从包结构到训练基线的完整实践

简介:EVA尖叫声音样本数据集是一份面向音乐信息检索(MIR)与音频分类研究的人声尖叫样本库,由台湾清华大学MIR课程项目整理,旨在为尖叫检测、异常声音识别、SVM分类等实验提供稀缺的领域数据。压缩包共63个文件&#xf…

2026/10/14 0:47:55 阅读更多 →

日新闻

AnyPS5通用适配层设计:兼容性与性能的工程取舍

AnyPS5通用适配层设计:兼容性与性能的工程取舍

1. 从"AnyPS5"这个名字说起:它到底想解决什么问题第一次看到"AnyPS5"这个标题,我脑子里冒出来的第一个念头是:这大概率是一个围绕"跨平台运行"或者"通用适配"做文章的项目。名字里的"Any"…

2026/10/14 0:00:41 阅读更多 →
Flutter跨平台开发实战:二手交易应用与HarmonyOS适配

Flutter跨平台开发实战:二手交易应用与HarmonyOS适配

1. 项目概述:Flutter跨平台二手交易应用开发作为一名长期从事移动应用开发的工程师,我最近完成了一个基于Flutter框架的二手物品交易平台项目。这个项目最吸引我的地方在于它完美结合了Flutter的跨平台优势与HarmonyOS的生态特性,实现了"…

2026/10/14 0:00:41 阅读更多 →
DFS算法解决飞机降落调度问题实战

DFS算法解决飞机降落调度问题实战

1. 项目背景与核心思路飞机降落问题是一个经典的调度优化场景,也是算法竞赛和面试中的高频题目。这个题目要求我们合理安排多架飞机的降落顺序和时间,确保所有飞机都能安全着陆而不发生冲突。在实际航空管制中,这类问题直接关系到飞行安全和机…

2026/10/14 0:00:41 阅读更多 →

周新闻

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

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

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

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

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

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

2026/10/13 16:22:04 阅读更多 →
影刀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/13 22:01:27 阅读更多 →
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/13 14:57:39 阅读更多 →
黑夜航拍船只数据集训练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 阅读更多 →