Positron Supervisor 的 Kallichore WebSocket 消息协议:SocketMessage 类型体系与消息消费链路
开发工具代码编辑器数据科学【免费下载链接】positronPositron, a next-generation data science IDE项目地址https://gitcode.com/gh_mirrors/po/positron点击查看免费下载导读Kallichorekcserver是 Positron Supervisor 背后的多语言内核编排服务而客户端与服务器之间几乎所有实时通信——内核状态、标准输出、执行归属信息——都通过一条 WebSocket 连接承载。本文以 extensions/positron-supervisor/src/ws/ 目录下的 README 及其配套 TypeScript 源码为主线完整梳理 Kallichore WebSocket 消息的两大类别kernel与jupyter、消息类型的定义方式、客户端连接与分拣逻辑并沿调用链追踪消息最终如何被转换成 Positron 的LanguageRuntimeMessage呈现给用户。读完本文你将掌握该协议的消息格式、各字段含义以及从服务端收包到界面渲染的完整数据流。目录定位一份消息协议的契约文档extensions/positron-supervisor/src/ws/README.md用一句话定义了整个目录的职责该目录包含 Kallichore 服务器的 WebSocket 消息定义。这些消息是服务器与客户端通过 Kallichore 的 WebSocket 连接互相发送的内容。这段描述虽然简短但点明了三个关键事实消息方向服务器Kallichore→ 客户端Positron。README 明确指出这些是服务器与客户端之间发送的消息且 SocketMessage.ts 的注释进一步说明今天 Kallichore 只发送两种消息即这一协议当前是服务端单向推送为主传输载体WebSocket 长连接而非 HTTP 轮询协议边界消息分为Jupyter 协议消息与Kernel 元数据消息两大类。与 README 同目录的三个源文件构成了这份契约的完整实现分别是文件角色SocketMessage.ts消息根类型与kind判别字段KernelMessage.tsKernel 类消息的四种具体类型SocketSession.ts客户端 WebSocket 会话封装消息根类型SocketMessage与SocketMessageKind所有经 WebSocket 到达客户端的外层消息都实现SocketMessage接口。它只有一个字段kind用于判别消息类别SocketMessage.tsexport enum SocketMessageKind { /** Jupyter messages are messages conforming to the Jupyter protocol. */ Jupyter jupyter, /** Kernel messages are messages sent by Kallichore to deliver kernel status * and metadata. */ Kernel kernel, } export interface SocketMessage { /** The kind of message */ kind: SocketMessageKind; }这个判别字段是后续分拣逻辑的入口KallichoreSession.handleMessage()在收到每一条消息时首先检查data.kind是否存在然后据此走两条完全不同的处理路径KallichoreSession.tshandleMessage(data: any) { if (!data.kind) { this.log(Kallichore session ${this.metadata.sessionId} message has no kind: ${JSON.stringify(data)}, vscode.LogLevel.Warning); return; } switch (data.kind) { case kernel: this.handleKernelMessage(data); break; case jupyter: this.handleJupyterMessage(data); break; } }从源码结构看jupyter类消息承载的是符合 Jupyter 协议的通道流量iopub/shell 等而kernel类消息承载的是 Kallichore 自身的控制面信息。二者共用同一条 WebSocket 连接、共用同一个kind字段做路由这保证了协议扩展时只需要新增枚举值即可接入新的消息类别。Kernel 消息族状态、输出与执行归属KernelMessage.ts 定义了四种接口前三者直接实现SocketMessage第四个是嵌套的数据结构。它们对应的 JSON 载荷在handleKernelMessage()中通过hasOwnProperty逐个特征字段探测KallichoreSession.ts。1.KernelMessageStatus内核状态推送export interface KernelMessageStatus extends SocketMessage { status: string; }这是内核生命周期状态的最小载体。实际载荷中status是一个对象形如{ status: ..., reason: ... }客户端取出status.status与positron.RuntimeState枚举比对后驱动运行时状态迁移。源码中还存在两处去重逻辑当收到starting状态但当前运行时既非Uninitialized也非Exited时忽略避免重启场景下重复广播当收到ready但当前已是Idle时同样忽略。这类消息负责把内核正在启动/已就绪/忙碌/已退出等状态机事件推送给前端。2.KernelOutputMessage内核日志输出export interface KernelOutputMessage extends SocketMessage { /** * A 2-element array containing the stream name and the output text. */ output: [string, string]; }output是一个二元组第一个元素是流名称如stdout第二个是输出文本。客户端收到后将其原样追加到该会话专属的内核输出通道_kernelChannelKallichoreSession.ts。从类型设计看该消息用于呈现内核进程自身的日志输出与 Jupyter 协议中的stream消息面向代码执行结果职责分离。3.KernelExecutionRequestedMessage外部执行的归属宣告这是该协议中最有特色的消息。KernelExecutionRequestedMessage的载荷结构如下KernelMessage.tsexport interface KernelExecutionRequestedMessage extends SocketMessage { executionRequested: { /** The execute_request ID; the parent ID of everything it produces. */ msg_id: string; /** The code that is about to run. */ code: string; /** When the request was submitted, in ISO 8601 format. */ requested_at: string; /** Who requested the execution. */ attribution: KernelExecutionAttribution; }; }其中KernelExecutionAttribution镜像了 Kallichore 共享库kcshared中的ExecutionAttribution定义KernelMessage.tsexport interface KernelExecutionAttribution { /** The kind of actor that requested the execution, e.g. agent. */ source: string; /** The name the agent reported in the MCP clientInfo, e.g. claude-code. */ agent_name?: string; /** The version the agent reported in the MCP clientInfo. */ agent_version?: string; /** The MCP workspace whose token authorized the request. */ workspace_id: string; /** The MCP tool used, e.g. execute_code or evaluate_code. */ tool: string; }各字段的语义字段类型含义sourcestring发起执行的参与者类型例如agentagent_namestring可选Agent 在 MCPclientInfo中上报的名称例如claude-codeagent_versionstring可选Agent 在 MCPclientInfo中上报的版本号workspace_idstring授权该请求的 MCP workspace tokentoolstring所使用的 MCP 工具例如execute_code或evaluate_code这条消息出现的时机很有讲究它会在随之而来的 iopub 流量之前被发送。为什么需要它RuntimeMessageEmitter.ts 的注释给出了答案——Jupyter 协议本身无法告知客户端这段代码是谁执行的iopub 消息只携带 parent header不携带父消息的元数据。当外部 Agent 通过 supervisor 的 MCP 服务器提交了执行请求时Positron 仅凭 Jupyter 流量无法区分用户自己在 Console 里敲的代码和Agent 远程执行的代码。KernelExecutionRequestedMessage就是 supervisor 在 iopub 流量之前发来的预告让客户端能够正确归属并标记这段执行。4. 同类消息的扩展空间handleKernelMessage()中还存在resourceUsage、clientDisconnected、exited三个分支KallichoreSession.tsresourceUsage携带RuntimeResourceUsage客户端会补充内核的 OS 进程 ID 后触发资源占用事件新会话首次收到时还会惰性向 Kallichore API 拉取 PID并用 in-flight 标记防止并发刷接口clientDisconnected表明会话被转移给其他客户端本客户端关闭 socket、将运行时标记为Exitedreason 为Transferred并永久禁止重连exited触发onExited退出流程。这些分支当前并未在 KernelMessage.ts 中一一对应定义类型从源码结构看resourceUsage等字段直接透传为 Positron 侧类型这也印证了 README 中今天只有两种消息的表述——协议仍在演进中kind判别字段为后续扩展保留了清晰入口。Jupyter 消息流另一条通道与 Kernel 消息并列的jupyter类别承载标准 Jupyter 协议流量。其类型定义集中在 extensions/positron-supervisor/src/jupyter/ 目录该目录的 README 描述为Jupyter 消息的类型定义以及为 commands、requests、replies 增加结构的工具类。从目录内容可以看到消息类型覆盖了协议的主要面请求类ExecuteRequest、KernelInfoRequest、CommInfoRequest、DebugRequest、ShutdownRequest、IsCompleteRequest等命令/回复类CommOpenCommand、CommMsgCommand、CommCloseCommand、InputReplyCommand、RpcReplyCommand等事件类JupyterStreamOutput、JupyterDisplayData、JupyterExecuteInput、JupyterKernelStatus、JupyterInputRequest、JupyterErrorReply等。RuntimeMessageEmitter.emitJupyter()以msg.header.msg_type为键的巨型 switch 将各类 Jupyter 消息翻译为 Positron 的LanguageRuntimeMessageRuntimeMessageEmitter.ts例如stream→LanguageRuntimeStream、status→LanguageRuntimeState、input_request→LanguageRuntimePrompt、comm_open→LanguageRuntimeCommOpen。这意味着WebSocket 层只负责传输与分拣真正的协议翻译发生在RuntimeMessageEmitter层。客户端会话封装SocketSession与多传输支持SocketSession.ts 是协议的客户端落地实现本质是一个vscode.Disposable包装类export class SocketSession implements vscode.Disposable { public readonly userId: string; public readonly ws: WebSocket; constructor( public readonly uri: string, public readonly sessionId: string, public readonly channel: vscode.LogOutputChannel, headers?: { [key: string]: string } ) { this.ws createWebSocket(uri, undefined, { headers }); this.userId os.userInfo().username; } close() { this.ws.close(); } dispose() { this.close(); } }值得注意的细节构造时通过os.userInfo().username记录当前用户 ID源码注释说明它会附加到客户端发出的每条消息上用于服务端做同用户校验WebSocket 实例并非直接new WebSocket(...)而是经由createWebSocket()工厂创建NamedPipeHttpAgent.ts该工厂会识别wsnpipe://前缀并返回支持 Windows 命名管道的NamedPipeWebSocket。三种传输形态的 URI 构造Kallichore 的 API base path 可能对应 TCP、Unix 域套接字或 Windows 命名管道三种传输KallichoreSession.getWebsocketUri()分别构造 WebSocket URIKallichoreSession.ts传输URI 形态构造方式TCPws:///wss://由 HTTP base path 直接替换 scheme路径为/sessions/{sessionId}/channelsUnix 域套接字wsunix://{socketPath}:/api/channels/{sessionId}调用channelsUpgradeAPI 获取 socket 路径处理带/不带前缀两种情况Windows 命名管道wsnpipe://{pipeName}:/api/channels/{sessionId}同样经由channelsUpgrade获取管道名并补齐\\.\pipe\前缀NamedPipeWebSocket的实现方式是解析wsnpipe://URL、提取管道名与路径将其转换为ws://localhost{path}并注入自定义 HTTP AgentNamedPipeHttpAgent重写createConnection用net.connect直连命名管道从而复用标准ws库完成 WebSocket 握手。连接生命周期与重连屏障消息协议最终依赖一条健壮的连接。KallichoreSession.connect()KallichoreSession.ts展示了完整的生命周期管理前置校验_canConnect为 false 时拒绝重连防止转移给其他客户端的会话被本端重新拉起URI 解析调用getWebsocketUri()按传输类型构造 URI认证从 API configuration 的 baseOptions headers 中取出 Bearer token 作为 WebSocket 握手请求头缺失时仅记录 Warning 不中断事件挂钩onopen打开_connected屏障Barrier允许后续消息发送若此前发生过断线则触发_onDidReconnectonerror连接建立后出错则关闭屏障并弹窗报错未建立则 rejectonclose若允许重连则派发DisconnectedEvent依据运行时是否Exited决定 reason 为Exit还是Unknown并关闭屏障、清空 socket 引用onmessageJSON.parse后交给handleMessage()分拣解析失败只记错误日志不影响连接。屏障_connected机制是整个协议可靠性的核心所有向内核发送的请求sendRequest等都等待屏障打开后才真正发出断线期间发送方会等待而非直接失败会话被 dispose 或转移时屏障被 cancel发送方立即收到明确错误。重启场景下restart()屏障会被替换为新的实例保证对替换后内核的连接可以继续发送。消息消费链路全景综合以上源码一条内核消息从服务端到 UI 的完整链路可以归纳为Kallichore (kcserver) │ 通过 WebSocket 推送 SocketMessagekind: kernel | jupyter ▼ SocketSession.ws.onmessage ── JSON.parse ──► KallichoreSession.handleMessage() │ ├── kindkernel ──► handleKernelMessage() │ ├── status ──► onStateChange()运行时状态机 │ ├── output ──► _kernelChannel内核日志面板 │ ├── resourceUsage ──► _resourceUsage 事件 │ ├── executionRequested ──► RuntimeMessageEmitter.onExecutionRequested() │ └── exited / clientDisconnected ──► 退出/转移流程 │ └── kindjupyter ──► handleJupyterMessage() ──► RuntimeMessageEmitter.emitJupyter() └── 按 msg_type 翻译为 LanguageRuntimeMessage ──► Positron 前端其中onExecutionRequested的实现揭示了执行归属消息的最终用途RuntimeMessageEmitter.ts它将消息转换为LanguageRuntimeExecutionRequested把attribution映射为CodeAttributionSource.Agent并使用agentLabel()将 Agent 上报的名称格式化为其规范名称源码注释说明 Console 用该规范名标记代码而非 Agent 自称的名字连同版本号与工具名写入 metadata。这样当 Console 中执行了代码时用户可以明确看到这段代码是由某个 Agent 通过哪个工具、在哪个 workspace 授权下执行的。调试与验证从源码看这套协议在运行时提供了丰富的可观测手段KallichoreSession的所有 WebSocket 事件连接、收发、错误、关闭均通过vscode.LogOutputChannel记录内核消息收包有专门的 RECV [kernel]: {...}调试日志handleMessage对缺少kind的消息、handleKernelMessage对未知状态值都会输出 Warning便于定位协议不兼容关联测试位于 extensions/positron-supervisor/src/test/如handshakeSocket.test.ts、server.test.ts、restartExitOrdering.test.ts、sendAfterExit.test.ts覆盖握手 socket、服务状态与重启/退出时序等周边行为。小结extensions/positron-supervisor/src/ws/目录虽然只有一份六行的 README但它所描述的协议层却是 Positron 数据科学 IDE 多语言内核通信的主动脉SocketMessage.kind提供了可扩展的消息判别机制KernelMessage.ts定义了内核状态、日志输出与执行归属三类控制面消息SocketSession则以一个可复用的会话封装支撑了 TCP / Unix 域套接字 / Windows 命名管道三种传输形态。理解这套协议有助于开发者阅读 supervisor 源码、排查内核通信问题或在扩展开发中正确消费运行时事件。赞分享开发工具代码编辑器数据科学【免费下载链接】positronPositron, a next-generation data science IDE项目地址https://gitcode.com/gh_mirrors/po/positron点击查看免费下载相关推荐Positron Supervisor 执行输出模型 ExecuteOutput 完全指南Kallichore 客户端三类输出消息解析Positron Supervisor 执行输出模型 ExecuteOutput 完全指南Kallichore 客户端三类输出消息解析 导读 本文围绕 Pos开发工具代码编辑器数据科学Tendermint Consensus P2P 消息协议详解四大通道与九种消息类型Tendermint Consensus P2P 消息协议详解四大通道与九种消息类型 本文基于 Tendermint Core 共识引擎的 P2P 消息规范区块链共识算法Tendermint P2P 消息协议详解通道协商、消息类型与六大组件实现Tendermint P2P 消息协议详解通道协商、消息类型与六大组件实现 本篇技术指南以 Tendermint 规范文档 spec/p2p/messages区块链共识算法上一篇d2l-en 高斯过程Gaussian Processes专题函数空间视角、核函数与 GPyTorch 回归实战下一篇TPFanCtrl2ThinkPad 双风扇静音控制的完整上手指南创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

相关新闻

SpringBoot+Vue校园兼职系统开发实践

SpringBoot+Vue校园兼职系统开发实践

1. 项目概述这个基于SpringBoot的大学生兼职管理系统是一个面向高校学生群体的实用型Web应用。我在开发过程中发现,校园兼职市场存在信息不对称、管理混乱等问题,而传统的人工登记方式效率低下且容易出错。这套系统正是为了解决这些痛点而设计的。系统采…

2026/10/15 9:50:47 阅读更多 →
HyperFrames实战:用多帧堆叠提升夜景信噪比与动态范围

HyperFrames实战:用多帧堆叠提升夜景信噪比与动态范围

作为一个常年拍夜景、又不愿意每次都扛三脚架出门的人,我有一段时间被“高ISO噪点”和“单帧动态范围不够”这两件事反复折磨。后来干脆花几个周末写了一个命令行小工具,名字就叫 HyperFrames。它的思路特别朴素:既然单帧照片在短时间内只有那…

2026/10/15 9:49:45 阅读更多 →
设备树开发实战:从dts编译、内核加载到调试避坑

设备树开发实战:从dts编译、内核加载到调试避坑

简介:面向Linux内核与嵌入式开发学习者,讲解设备树(Device Tree)在启动时提供硬件平台信息、替代内核arch目录中板级细节代码的背景,并系统梳理dts语法与内核加载dtb的完整流程。资源为单个PDF,约293KB&…

2026/10/15 9:49:45 阅读更多 →

最新新闻

学Simulink——储能变流器(PCS)中 PWM 整流器的恒流充放电(CC Charge / CC Discharge)仿真

学Simulink——储能变流器(PCS)中 PWM 整流器的恒流充放电(CC Charge / CC Discharge)仿真

目录 手把手教你学Simulink——储能变流器(PCS)中 PWM 整流器的恒流充放电(CC Charge / CC Discharge)仿真 一、为什么储能 PCS 要做 恒流(CC)充放电双向 PWM 整流器 二、PCS 双向控制与 CC 模式原理** 2.1 功率平衡估算(用于 idref​折算) 2.2 模式定义 三、关键…

2026/10/15 10:38:32 阅读更多 →
TaoToken 视角下的示波器使用:measure/acquire/storage/cursor 四步实测

TaoToken 视角下的示波器使用:measure/acquire/storage/cursor 四步实测

/* 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 10:38:32 阅读更多 →
学Simulink——三相 PWM 整流器在船舶岸电系统(Shore-to-Ship Power, Cold Ironing)中的并网控制仿真

学Simulink——三相 PWM 整流器在船舶岸电系统(Shore-to-Ship Power, Cold Ironing)中的并网控制仿真

目录 手把手教你学Simulink——三相 PWM 整流器在船舶岸电系统(Shore-to-Ship Power, Cold Ironing)中的并网控制仿真 一、为什么船舶岸电系统要用 三相 PWM 整流器/并网变流器 二、岸电系统典型参数(教学模型)** 三、Simulink 建模(手把手)** 3.1 Step 1️⃣ —— 港…

2026/10/15 10:38:32 阅读更多 →
PP-HumanSeg Lite + NCNN C++ 部署实战:精准版本对齐与边缘落地

PP-HumanSeg Lite + NCNN C++ 部署实战:精准版本对齐与边缘落地

简介:本资源是一套面向嵌入式与移动端开发者的轻量级人像分割部署方案,聚焦PP-HumanSeg Lite模型在NCNN框架下的C端高效落地,适用于视频会议背景虚化、AR换装、实时抠图等低延迟场景,适合具备C基础和一定CV部署经验的中高级开发者…

2026/10/15 10:38:32 阅读更多 →
OpenGL正背面剔除与深度测试:原理、配置与穿模问题排查

OpenGL正背面剔除与深度测试:原理、配置与穿模问题排查

1. 从一个“穿模”现象说起:为什么需要正背面剔除与深度测试但凡做过3D渲染的人,几乎都遇到过这样的场景:一个封闭的立方体或者角色模型,旋转到某个角度后,本该被挡住的背面却透了出来,或者两个物体交叠的地…

2026/10/15 10:38:32 阅读更多 →
企业WordPress定制开发:核心价值与选型指南

企业WordPress定制开发:核心价值与选型指南

1. 为什么企业需要专业的WordPress定制开发服务 在数字化浪潮席卷各行各业的当下,企业官网已从简单的"电子名片"升级为集品牌展示、客户服务和业务转化于一体的核心平台。WordPress作为全球占比43%的内容管理系统,凭借其开源特性、丰富的插件生…

2026/10/15 10:37:31 阅读更多 →

日新闻

Docker Compose 容器化部署 ChirpStack LoRaWAN 网络服务器实战

Docker Compose 容器化部署 ChirpStack LoRaWAN 网络服务器实战

1. 为什么选择容器化方式部署 LoRa 网络服务LoRa 物联网项目落地时,网络服务器是整个链路的核心枢纽。它负责接收网关上报的数据包、完成去重与解密、再把有效载荷分发给上层应用。早期大家习惯把网络服务器直接装在物理机上,依赖一堆系统库和特定版本的…

2026/10/15 0:00:46 阅读更多 →
共享LLM服务下的跨模型自动扩缩容:Kubernetes实战与避坑指南

共享LLM服务下的跨模型自动扩缩容:Kubernetes实战与避坑指南

1. 共享推理服务里,扩缩容到底难在哪做过大模型推理服务部署的人,大概都经历过这样的场景:一个团队共用一套推理集群,A 业务跑的是 7B 的小模型,B 业务跑的是 72B 的大模型,C 业务白天流量高、晚上几乎归零…

2026/10/15 0:00:46 阅读更多 →
Systemd 启动阶段根文件系统只读之谜:fstab 与 remount-fs 服务深度解析

Systemd 启动阶段根文件系统只读之谜:fstab 与 remount-fs 服务深度解析

1. 引子:一次内核恐慌引发的追查先从一个真实场景说起。某次我给一台老旧的嵌入式设备折腾系统裁减,为了把启动时间压进两秒以内,我手贱地把一串自认为“没用”的 systemd 服务给 disable 了,其中就包括systemd-remount-fs.servic…

2026/10/15 0:00:46 阅读更多 →

周新闻

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

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

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

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

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

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

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

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

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

2026/10/14 3:29:58 阅读更多 →

月新闻

我发现了一个新思路:用 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/14 22:45:47 阅读更多 →
黑夜航拍船只数据集训练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 阅读更多 →