实时通信技术对比:短轮询、长轮询、SSE、WebSocket 与 TaoToken 统一接入实践
1. 从一次 AI 对话卡顿说起四种实时通信方案到底怎么选你调用大模型接口时有没有遇到过这种体验问题发出去界面转圈十几秒然后“啪”一下整段答案全冒出来中间没有任何逐字输出的过程。或者更糟页面直接超时你根本不知道模型是在思考还是已经挂了。这类问题的根子往往不在模型本身而在客户端和服务端之间用什么方式搬运数据。短轮询、长轮询、SSE、WebSocket 这四种方案本质上解决的是同一件事客户端怎么知道服务端有“新内容”了。短轮询是每隔固定时间问一次“好了没”长轮询是问一次然后挂住等SSE 是服务端主动推一条持久文本流WebSocket 则是双方拉一条双向通道随时互发。放到 AI 应用里模型流式输出天然适合 SSE因为它是服务端单向、持续吐 token 的场景而需要边生成边让用户打断、重新提问的交互WebSocket 更顺手。这篇内容面向正在做 AI 应用接入的开发者尤其是需要把多家模型统一到一个 Key、一个 API 通道上的人。我会把四种方案的延迟、开销、适用边界讲清楚然后结合 TaoToken 的统一接入通道给出可复制的服务端和客户端配置片段最后用浏览器 DevTools 和 curl 验证连接状态、消息时序和断线重连。你跟着做能直接判断自己的场景该用哪种方案以及怎么把流式输出稳定跑起来。先给一个直观的对照后面每一节再展开细节。特性短轮询长轮询SSEWebSocket通信方向客户端发起客户端发起服务端推送单向全双工双向协议HTTPHTTPHTTP 持久化WebSocketHTTP 升级延迟高取决于间隔较低非常低极低服务端开销高频繁请求中挂起连接中持久连接低一个持久连接数据格式HTTPHTTP文本流文本/二进制实现复杂度非常简单中等简单客户端较复杂典型场景简单状态检查旧系统实时性稍高实时通知、行情、AI 流式聊天、游戏、协作这张表不是让你背而是帮你建立判断顺序先看通信方向再看延迟要求最后看实现成本。AI 流式输出绝大多数落在 SSE 这一列但如果你要做语音对话、实时打断WebSocket 才是终点。2. TaoToken 统一接入前置一个 Key 打通多模型流式通道在讲具体配置之前得先把接入层说清楚。很多团队做 AI 应用时最烦的不是通信方案本身而是每接一家模型就要换一套 Base URL、换一个 Key、换一种流式格式。TaoToken 在这里扮演的角色是把多家模型的调用统一到一个 API 通道上你只需要维护一个 Key就能在同一个接口规范下切换模型流式输出的格式也保持一致。它的 API 地址是https://taotoken.net/api官网入口是https://taotoken.net/?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content。注意API 调用时用前者不带 UTM 参数官网浏览和注册用后者。这个区分很重要因为有些同学把带参数的地址直接塞进代码里结果请求路径多了查询串导致 404。统一接入带来的直接好处是你在做实时通信选型时不用为每家模型单独写一套 SSE 解析逻辑。TaoToken 的流式响应遵循标准的data:行格式和 OpenAI 兼容接口一致所以你的 SSE 客户端代码可以复用。下面是一个最小的流式请求示例你可以先用 curl 验证通道是否通curl -N https://taotoken.net/api/v1/chat/completions \ -H Authorization: Bearer $TAOTOKEN_API_KEY \ -H Content-Type: application/json \ -d { model: gpt-4o-mini, stream: true, messages: [{role: user, content: 用一句话解释 SSE}] }-N参数关闭 curl 的缓冲这样你能实时看到 token 一个个吐出来。如果通道正常你会看到类似这样的输出data: {choices:[{delta:{content:SSE}}]} data: {choices:[{delta:{content: 是}}]} data: {choices:[{delta:{content: 服务端}}]} ... data: [DONE]这里有几个关键点。第一stream: true是开启流式的开关不开的话就是一次性返回完整 JSON。第二每一行以data:开头最后以data: [DONE]结束这是 SSE 协议的标准结束标记。第三choices[0].delta.content是增量内容不是完整内容你需要在前端做拼接。如果你还没有 Key可以去 API Keys 页面创建https://taotoken.net/api-keys?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content。创建后把 Key 存到环境变量里不要硬编码在代码中。我见过太多把 Key 写死在 JS 里然后被爬走的案例这个坑一定要避开。统一通道的另一个价值是断线重连时不用改协议。SSE 自带重连机制浏览器在连接断开后会自动重试默认间隔约 3 秒。但如果你用的是长轮询重连逻辑得自己写WebSocket 也要自己处理心跳和重连。TaoToken 的流式接口在服务端保持连接稳定配合客户端的自动重连能覆盖大部分网络抖动场景。还有一点值得说模型切换。你可以在不改客户端代码的前提下把model字段从gpt-4o-mini换成别的模型流式格式不变。这意味着你的 SSE 解析层是通用的不用为每个模型写适配器。对于需要做多模型对比、A/B 测试的团队这一点能省掉大量重复工作。3. 可复制配置SSE 服务端与客户端完整片段这一节是全文的核心操作部分。我会给出一个完整的 SSE 服务端示例Node.js Express一个客户端示例浏览器 EventSource 和 fetch 两种写法以及一个 WebSocket 的对照配置。所有片段都可以直接复制运行路径和参数与 TaoToken 的接口保持一致。先看服务端。它的职责是接收前端请求转发给 TaoToken 的流式接口然后把上游的data:行原样推给前端。注意这里不要用普通的res.json()要用res.write()逐块写。// server.js import express from express; import fetch from node-fetch; const app express(); app.use(express.json()); const TAOTOKEN_API https://taotoken.net/api/v1/chat/completions; const API_KEY process.env.TAOTOKEN_API_KEY; app.post(/api/chat/stream, async (req, res) { res.setHeader(Content-Type, text/event-stream); res.setHeader(Cache-Control, no-cache); res.setHeader(Connection, keep-alive); res.flushHeaders(); const upstream await fetch(TAOTOKEN_API, { method: POST, headers: { Authorization: Bearer ${API_KEY}, Content-Type: application/json, }, body: JSON.stringify({ model: req.body.model || gpt-4o-mini, stream: true, messages: req.body.messages, }), }); upstream.body.on(data, (chunk) { res.write(chunk); }); upstream.body.on(end, () { res.write(data: [DONE]\n\n); res.end(); }); req.on(close, () { upstream.body.destroy(); }); }); app.listen(3000, () console.log(SSE server on :3000));这段代码里有三个容易出错的点。第一res.flushHeaders()必须调用否则响应头可能被缓冲前端迟迟收不到连接建立的事件。第二Content-Type必须是text/event-stream写成application/json浏览器不会按 SSE 处理。第三req.on(close)里要销毁上游连接否则用户关掉页面后上游还在跑浪费额度。再看客户端。浏览器原生EventSource只支持 GET 请求而我们的接口是 POST所以直接用EventSource会受限。有两种解法一种是把参数放 query string 用 GET另一种是用fetchReadableStream手动解析。推荐后者更灵活。// client-fetch.js async function streamChat(messages) { const response await fetch(/api/chat/stream, { method: POST, headers: { Content-Type: application/json }, body: JSON.stringify({ messages, model: gpt-4o-mini }), }); const reader response.body.getReader(); const decoder new TextDecoder(); let buffer ; while (true) { const { done, value } await reader.read(); if (done) break; buffer decoder.decode(value, { stream: true }); const lines buffer.split(\n); buffer lines.pop(); for (const line of lines) { if (!line.startsWith(data: )) continue; const payload line.slice(6).trim(); if (payload [DONE]) return; try { const json JSON.parse(payload); const delta json.choices?.[0]?.delta?.content; if (delta) process.stdout.write(delta); } catch (e) { // 忽略不完整 JSON } } } }这里的关键是buffer的处理。网络传输是分块的一个data:行可能被切成两半所以你要把最后一段不完整的行留在 buffer 里等下一块数据到了再拼。decoder.decode(value, { stream: true })的stream: true参数保证多字节字符不会被截断。如果你坚持用EventSource可以改成 GET 接口const es new EventSource(/api/chat/stream?q encodeURIComponent(question)); es.onmessage (e) { if (e.data [DONE]) { es.close(); return; } const json JSON.parse(e.data); console.log(json.choices[0].delta.content); }; es.onerror () { console.log(连接断开浏览器会自动重连); };EventSource的好处是自带重连坏处是不能自定义请求头也没法发 POST body。所以生产环境里fetch 手动解析更常见。最后给一个 WebSocket 的对照配置方便你理解差异。WebSocket 需要服务端用ws库升级连接// ws-server.js import { WebSocketServer } from ws; const wss new WebSocketServer({ port: 8080 }); wss.on(connection, (ws) { ws.on(message, async (raw) { const { messages } JSON.parse(raw); const upstream await fetch(TAOTOKEN_API, { method: POST, headers: { Authorization: Bearer ${API_KEY}, Content-Type: application/json, }, body: JSON.stringify({ model: gpt-4o-mini, stream: true, messages }), }); upstream.body.on(data, (chunk) { ws.send(chunk.toString()); }); upstream.body.on(end, () ws.send([DONE])); }); });客户端用new WebSocket(ws://localhost:8080)然后ws.onmessage接收。对比一下就能看出WebSocket 多了一层协议升级和心跳维护但换来的是双向通信能力。4. 验证请求与成功结果DevTools 与 curl 实操配置写完怎么确认它真的在工作这一节给你一套可执行的验证动作覆盖连接状态、消息时序和断线重连三个维度。先看 curl 验证。这是最直接的方式能排除前端代码的干扰。运行前面那条curl -N命令观察输出节奏。如果 token 是逐行出现的说明流式通道正常如果等了很久然后一次性全出来说明某处开了缓冲。常见原因是服务端没调flushHeaders()或者中间有反向代理开了proxy_buffering。Nginx 下需要加location /api/chat/stream { proxy_pass http://127.0.0.1:3000; proxy_buffering off; proxy_cache off; proxy_set_header Connection ; proxy_http_version 1.1; chunked_transfer_encoding off; }proxy_buffering off是关键不关的话 Nginx 会攒够一批才转发流式就变成了“批量式”。再看浏览器 DevTools。打开 Network 面板找到那个 SSE 请求点进去看 EventStream 标签页。你会看到每条data:消息带着时间戳逐条出现。这里能验证三件事第一连接是否保持Status 应该是 200 且一直 pending第二消息时序是否均匀如果间隔忽大忽小可能是上游限流第三[DONE]是否正常到达。如果 EventStream 标签页是空的但 Response 里有内容说明响应头不对浏览器没按 SSE 解析。检查Content-Type是否为text/event-stream。断线重连的验证稍微麻烦一点。你可以在 DevTools 的 Network 面板里右键那个请求选择 “Block request URL”模拟连接断开。对于EventSource你会看到它自动发起新的请求间隔约 3 秒。对于fetch手动解析你需要自己写重连逻辑async function streamWithRetry(messages, retries 3) { for (let i 0; i retries; i) { try { await streamChat(messages); return; } catch (e) { console.log(第 ${i 1} 次重连); await new Promise((r) setTimeout(r, 1000 * (i 1))); } } }指数退避比固定间隔更稳避免在服务端压力大时雪上加霜。还有一个验证技巧用curl的-w参数看连接耗时和首字节时间。curl -N -w \n首字节: %{time_starttransfer}s\n总耗时: %{time_total}s\n \ https://taotoken.net/api/v1/chat/completions \ -H Authorization: Bearer $TAOTOKEN_API_KEY \ -H Content-Type: application/json \ -d {model:gpt-4o-mini,stream:true,messages:[{role:user,content:你好}]}time_starttransfer是首字节到达时间正常应该在几百毫秒到一两秒之间。如果这个值很大说明上游排队或网络慢如果time_total和time_starttransfer很接近说明流式没生效数据被一次性返回了。成功的结果长这样curl 输出里 token 逐行出现DevTools 的 EventStream 里消息带时间戳逐条排列断开后能自动或手动重连并继续输出。三个都满足说明你的实时通道是健康的。5. 本篇常见错排查401、local proxy failed、reading choices、OAuth这一节把接入过程中最容易撞上的几个报错拆开讲。每个报错我都给出触发条件和修复动作你对照自己的日志定位。401 Unauthorized。这是最常见的原因通常是 Key 没传、传错或过期。检查三处请求头里Authorization: Bearer后面有没有空格Key 是不是复制时带了换行环境变量有没有正确加载。用echo $TAOTOKEN_API_KEY确认变量存在。如果是在浏览器里直接调注意不要暴露 Key应该走自己的服务端转发。local proxy failed。这个报错通常出现在你本地起了代理工具或者代码里配了HTTP_PROXY环境变量但代理不可达。先检查环境变量env | grep -i proxy如果有输出临时清掉再试unset HTTP_PROXY HTTPS_PROXY ALL_PROXY另外有些 Node.js 的 fetch 实现会读取系统代理设置可以在代码里显式指定agent或改用undici的ProxyAgent为空。这个报错和网络环境有关排查时优先看本地配置不要一上来就怀疑接口。reading choices。完整报错通常是Cannot read properties of undefined (reading choices)。这说明你拿到的响应体不是预期的 JSON 结构可能是错误响应被当成了正常响应解析。加一层判断if (!response.ok) { const err await response.text(); throw new Error(HTTP ${response.status}: ${err}); }还有一种情况是流式解析时某个data:行是空行或注释行JSON.parse失败后json是 undefined再取json.choices就炸了。前面客户端代码里的try/catch和json.choices?.[0]可选链就是防这个的。OAuth 相关报错。如果你用的是某些需要 OAuth 授权的客户端工具可能会遇到 token 过期或 scope 不足。这类问题的通用解法是重新走一遍授权流程确认 scope 包含模型调用权限。如果你用的是 API Key 方式一般不会碰到 OAuth但如果工具内部封装了 OAuth就要去它的配置里检查 token 刷新逻辑。还有一个隐蔽的坑模型 ID 写错。比如把gpt-4o-mini写成gpt-4o_mini接口会返回模型不存在。这类报错信息通常比较明确照着改就行。记住三件套要配对Base URL 是https://taotoken.net/apiKey 是你在 API Keys 页面创建的那串Model ID 要和平台支持的列表一致。三者任何一个不对都会报错。排查顺序建议是先看 HTTP 状态码再看响应体最后看解析逻辑。状态码 401 查 Key404 查路径429 查限流500 查上游。响应体里通常有error.message直接读它比猜快得多。6. 选型收尾与统一通道的长期价值回到选型本身。如果你只是做简单的状态检查比如“任务跑完没”短轮询够用但别把间隔设得太短2 秒一次已经算频繁了。如果你在维护老系统没法上 SSE 或 WebSocket长轮询是合理的降级方案但要注意服务端挂起连接的数量别把连接池占满。AI 应用的流式输出首选 SSE。它基于 HTTP不需要协议升级浏览器原生支持重连服务端实现也简单。唯一要注意的是同域名并发连接数限制浏览器一般允许 6 个所以别在一个页面开太多 SSE 连接。如果你的场景需要用户随时打断、重新提问或者要做语音双向对话那就上 WebSocket多出来的复杂度是值得的。TaoToken 在这个链路里的价值是把多模型的流式接口统一成一套规范。你不用为每家模型写不同的 SSE 解析也不用在切换模型时改客户端代码。一个 Key、一个 Base URL、一套流式格式配合前面给的配置片段能覆盖从原型到生产的多数场景。最后留一个实用建议把流式请求的超时和重试做成可配置的。网络抖动是常态与其让用户看到卡死的界面不如在断开后自动重连并在界面上给一个“正在重连”的提示。这个细节对体验的影响比选哪种通信方案更大。

相关新闻

204-Spring AI Alibaba MCP Manual 示例:把 MCP 服务端配置改到 TaoToken

204-Spring AI Alibaba MCP Manual 示例:把 MCP 服务端配置改到 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/9 5:36:55 阅读更多 →
AI 编程工具的四层能力体系:Skills、MCP、Rules、Agents 完全指南(TaoToken 统一 Key 接入版)

AI 编程工具的四层能力体系:Skills、MCP、Rules、Agents 完全指南(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/7 23:55:59 阅读更多 →
Agent Harness 解析:智能体架构深度拆解与 TaoToken 统一接入实践

Agent Harness 解析:智能体架构深度拆解与 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/7 23:55:58 阅读更多 →

最新新闻

最新IPA在线签名系统源码 全开源版本

最新IPA在线签名系统源码 全开源版本

源码下载:download.csdn.net/download/m0_66047725/93654842简介:最新IPA在线签名系统源码 全开源版本基于Thinkphp8.0VUE3开发 配合Zsign工具签名前台vue 后台使用art design pro管理框架后台带软件源自动拉取支持自助签名 支持在线签名测试环境&…

2026/10/9 5:36:41 阅读更多 →
2026最新版短视频去水印+视频号去水印小程序版本源码

2026最新版短视频去水印+视频号去水印小程序版本源码

源码下载:download.csdn.net/download/m0_66047725/93654835简介:2026最新版短视频去水印+视频号去水印小程序版本源码图片:安装教程:环境:PHP7.4MySQL5.7域名:必须备案,申请SSL证书…

2026/10/9 5:36:41 阅读更多 →
【ENSP】技巧

【ENSP】技巧

ENSP文章合集: https://wwaul.lanzout.com/b01gid75ah 密码:4r01 设备可视化操作 连线 通常,我们使用auto自动链接,但他没法选择端口及线的类型,比如交换机和路由器之前的链接,默认使用了交换机的e 0/0/3口交换机的g 0…

2026/10/9 5:36:41 阅读更多 →
GitHub日榜高效刷法:从star陷阱到技术选型的避坑指南

GitHub日榜高效刷法:从star陷阱到技术选型的避坑指南

每天早上到工位,我第一件事不是查邮件,而是先打开GitHub的Trending页面,看一遍日期最接近的日榜。这个习惯保持了一两年,从中挖到过不少能直接落地到项目的库,也踩过不少看起来很美、实际中看不中用的坑。GitHub热榜说…

2026/10/9 5:36:41 阅读更多 →
随机化学算法在电网连锁故障N-k分析中的Matlab实现

随机化学算法在电网连锁故障N-k分析中的Matlab实现

电网连锁故障分析这件事,做过的人都知道有多头疼。系统规模一上来,想判断哪几种故障组合最容易把电网拖入大停电,暴力枚举几乎不可行,蒙特卡洛又慢得让人失去耐心。去年我在做 N-k 安全分析时接触到了“随机化学”这个思路&#x…

2026/10/9 5:36:41 阅读更多 →
学Simulink——基于反电动势过零检测的直流无刷电机(BLDC)无感控制仿真

学Simulink——基于反电动势过零检测的直流无刷电机(BLDC)无感控制仿真

目录 手把手教你学Simulink——基于反电动势过零检测的直流无刷电机(BLDC)无感控制仿真 一、 引言:当“霍尔传感器”成为过去式——反电动势过零检测如何成就真正的“无感”BLDC? 二、 问题本质:反电动势过零的“物理机制”与“协同逻辑” 1. 核心物理机制 2. 协同逻辑…

2026/10/9 5:35:40 阅读更多 →

日新闻

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/8 10:10:36 阅读更多 →

月新闻

我发现了一个新思路:用 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/7 13:34:55 阅读更多 →