实战:写一个Mysql MCP Server,把本地数据库接进 AI 工具链
1. 为什么要把 MySQL 接进 AI 工具链先说清楚我们在解决什么问题。你平时用 Cline、Claude Code 或者 CC Switch 这类 AI 编程助手时模型对数据库的理解基本靠猜——它会根据你项目里的 ORM 定义、SQL 迁移文件去推断表结构然后给你写查询语句。问题是真实数据库里往往有历史遗留字段、命名不规范的列、甚至和代码里对不上的索引。模型猜错了你复制粘贴执行报错来回折腾。MCP Server 就是来解决这个断层的。MCPModel Context Protocol是 Anthropic 提出的一套开放协议定义了大模型和外部工具之间的标准连接方式。你可以把它理解成 AI 世界的 USB-C 接口不管你要接的是数据库、文件系统还是第三方 API只要双方都遵循 MCP 规范就能即插即用。整个架构只有两个角色MCP Client 跑在 AI 助手这一侧负责和模型交互MCP Server 是你写的独立进程暴露具体的工具能力两者通过 JSON-RPC over stdio 通信。用 stdio 而不是 HTTP 的好处是零网络配置、不开放端口本地开发场景下特别省心。这篇要带你从零写一个可运行的 MySQL MCP Server然后把它接进 Cline MCP 或 CC Switch 这类支持 MCP 的工具里让模型能直接DESCRIBE表结构、执行SELECT查询、拿到真实数据。适合谁看有 Node.js 基础、想让 AI 助手真正看见本地库的后端和全栈同学。全程给可复制的配置片段、工具注册代码和一次真实查询的验证步骤跟着做就能跑通。技术栈选型上我用 Node.js 18 配 TypeScript用tsx直接运行不用编译MCP 部分用modelcontextprotocol/sdk的McpServer高级 API数据库驱动用mysql2的连接池输入校验用zod。项目用 ESM 模块type: module启动命令就是npx tsx src/server.ts。2. TaoToken 前置准备与 API Key 获取在动手写 Server 之前得先把 AI 工具这一侧的大脑接好。我用的方案是通过 TaoToken 统一管理模型调用这样 Cline、CC Switch、Claude Code 这些工具可以共用一套 Key 和 Base URL切换模型不用改一堆配置。TaoToken 在这里扮演的是模型接入网关的角色它把不同厂商的模型能力收敛成统一的 OpenAI 兼容接口。你需要先拿到 API Key然后配置到各个 AI 工具里。具体操作路径是这样打开官网 https://taotoken.net/?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content 注册登录后进入控制台 https://taotoken.net/console?utm_sourcetaotoken_aicg_blog_endutm_contentconsoleutm_campaignrewrite 在 API Keys 页面 https://taotoken.net/api-keys?utm_sourcetaotoken_aicg_blog_endutm_contentapi-keysutm_campaignrewrite 创建一个新的 Key复制保存好。拿到 Key 之后不同工具的配置方式略有差异但核心三件套是一样的Base URL、API Key、Model ID。Base URL 统一填https://taotoken.net/api注意这个地址不加 UTM 参数是纯 API 端点。Model ID 根据你要用的模型填比如claude-sonnet-4-5或者gpt-4o这类。如果你不确定有哪些模型可用可以先去模型对话页面 https://taotoken.net/chat?utm_sourcetaotoken_aicg_blog_endutm_contentchatutm_campaignrewrite 试一下确认 Key 能正常调用再往下走。这里有个坑要提醒Cline 和 CC Switch 对 Base URL 的格式要求不完全一样。Cline 通常要求填到/v1结尾也就是https://taotoken.net/api/v1而 CC Switch 和 Claude Code 这类走 Anthropic 协议的工具Base URL 填https://taotoken.net/api就行不需要/v1。填错了会报 404 或者model not found这个后面排障章节会细说。如果你打算长期跑编码任务或者做 Agent 自动化建议看一下 Coding Plan https://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_contentcoding-planutm_campaignrewrite 它针对高频调用场景做了额度优化比按量付费划算。接入文档在 https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_contentdocutm_campaignrewrite 里面有各工具的详细配置示例遇到不确定的地方可以对照查。3. 可复制的 MySQL MCP Server 配置与工具注册现在进入正题开始写 Server。先建项目目录初始化package.jsonmkdir mysql-mcp-server cd mysql-mcp-server npm init -y npm install modelcontextprotocol/sdk mysql2 zod npm install -D typescript tsx types/node然后在package.json里加上type: module并配置启动脚本{ name: mysql-mcp-server, version: 1.0.0, type: module, scripts: { start: tsx src/server.ts }, dependencies: { modelcontextprotocol/sdk: ^1.0.0, mysql2: ^3.11.0, zod: ^3.23.0 }, devDependencies: { typescript: ^5.6.0, tsx: ^4.19.0, types/node: ^22.0.0 } }项目结构规划成这样mysql-mcp-server/ ├── package.json ├── tsconfig.json ├── connections.json # 数据库连接配置记得加 .gitignore ├── src/ │ ├── db.ts # 连接池管理、查询执行、安全校验 │ └── server.ts # MCP Server 主体注册工具 └── README.mdconnections.json里配置多个数据库连接每个连接独立一个池{ main: { host: 127.0.0.1, port: 3306, user: readonly_user, password: your_password, database: main_db }, analytics: { host: 10.0.0.5, port: 3306, user: readonly_user, password: your_password, database: analytics_db } }接下来写src/db.ts核心是连接池管理和安全校验。安全这块必须做足因为模型生成的 SQL 不可控白名单、LIMIT 上限、敏感列检测、频率限制一个都不能少import mysql from mysql2/promise; import fs from fs; import path from path; type ConnConfig { host: string; port: number; user: string; password: string; database: string; }; const pools new Mapstring, mysql.Pool(); const rateMap new Mapstring, number[](); function loadConnections(): Recordstring, ConnConfig { const file path.resolve(process.cwd(), connections.json); return JSON.parse(fs.readFileSync(file, utf-8)); } export function getPool(name: string): mysql.Pool { if (pools.has(name)) return pools.get(name)!; const configs loadConnections(); const cfg configs[name]; if (!cfg) throw new Error(Unknown connection: ${name}); const pool mysql.createPool({ ...cfg, waitForConnections: true, connectionLimit: 5, namedPlaceholders: true, }); pools.set(name, pool); return pool; } const SENSITIVE /(password|secret|token|api_key)/i; export function validateSql(sql: string): string { const trimmed sql.trim(); if (!/^(SELECT|SHOW|DESCRIBE)\s/i.test(trimmed)) { throw new Error(Only SELECT/SHOW/DESCRIBE allowed); } if (trimmed.includes(;) trimmed.indexOf(;) trimmed.length - 1) { throw new Error(Multiple statements not allowed); } if (SENSITIVE.test(trimmed)) { throw new Error(Query contains sensitive column); } if (!/\bLIMIT\b/i.test(trimmed)) { return trimmed LIMIT 500; } return trimmed.replace(/LIMIT\s(\d)/i, (_, n) LIMIT ${Math.min(parseInt(n, 10), 500)} ); } export function checkRate(sql: string): void { const fingerprint sql.replace(/\d/g, ?); const now Date.now(); const arr (rateMap.get(fingerprint) || []).filter(t now - t 60000); if (arr.length 10) { throw new Error(Rate limit exceeded (max 10 queries per minute)); } arr.push(now); rateMap.set(fingerprint, arr); } export async function runQuery(connName: string, sql: string) { const safeSql validateSql(sql); checkRate(safeSql); const pool getPool(connName); const [rows] await pool.query(safeSql); const json JSON.stringify(rows); if (json.length 100 * 1024) { const arr rows as any[]; return { truncated: true, rows: arr.slice(0, 100), message: 结果集过大超过 100KB请添加更严格的 WHERE 条件或减小 LIMIT, }; } return { truncated: false, rows }; }然后是src/server.ts注册四个工具list_connections、list_tables、describe_table、query。每个工具的description要写清楚帮模型判断什么时候用import { McpServer } from modelcontextprotocol/sdk/server/mcp.js; import { StdioServerTransport } from modelcontextprotocol/sdk/server/stdio.js; import { z } from zod; import { getPool, runQuery } from ./db.js; const server new McpServer({ name: mysql-mcp, version: 1.0.0 }); server.tool( list_connections, 列出所有已配置的数据库连接名称用于选择要查询的库, {}, async () { const fs await import(fs); const path await import(path); const cfg JSON.parse( fs.readFileSync(path.resolve(process.cwd(), connections.json), utf-8) ); return { content: [{ type: text, text: Object.keys(cfg).join(\n) }], }; } ); server.tool( list_tables, 列出指定连接下的所有表名, { connection: z.string().describe(连接名称如 main) }, async ({ connection }) { const pool getPool(connection); const [rows] await pool.query(SHOW TABLES); return { content: [{ type: text, text: JSON.stringify(rows, null, 2) }], }; } ); server.tool( describe_table, 查看指定表的结构包括字段名、类型、是否可空、键信息, { connection: z.string(), table: z.string().describe(表名), }, async ({ connection, table }) { const pool getPool(connection); const [rows] await pool.query(DESCRIBE \${table}\); return { content: [{ type: text, text: JSON.stringify(rows, null, 2) }], }; } ); server.tool( query, 执行只读 SQL 查询仅支持 SELECT/SHOW/DESCRIBE自动追加 LIMIT 500, { connection: z.string(), sql: z.string().describe(要执行的 SQL 语句), }, async ({ connection, sql }) { try { const result await runQuery(connection, sql); return { content: [{ type: text, text: JSON.stringify(result, null, 2) }], }; } catch (err: any) { return { content: [{ type: text, text: Error: ${err.message} }], isError: true, }; } } ); const transport new StdioServerTransport(); await server.connect(transport);写完跑一下npx tsx src/server.ts如果没报错就说明 Server 能正常启动。接下来把它接进 AI 工具。4. 接入 Cline MCP 与 CC Switch 并验证真实查询先接 Cline。Cline 的 MCP 配置在 VS Code 的设置里找到 Cline 的 MCP Servers 配置项添加一个 local 类型的 server。配置片段长这样{ mcpServers: { mysql: { command: npx, args: [tsx, /Users/yourname/mysql-mcp-server/src/server.ts], env: { MYSQL_CONNECTIONS: {\main\:{\host\:\127.0.0.1\,\port\:3306,\user\:\readonly_user\,\password\:\your_password\,\database\:\main_db\}} } } } }注意args里的路径要换成你本机的绝对路径。env里的MYSQL_CONNECTIONS是把 JSON 压缩成一行并转义双引号后的结果如果你不想用connections.json文件也可以走环境变量这条路。接 CC Switch 的话配置方式类似但 CC Switch 走的是 Anthropic 协议需要在配置里指定 Base URL 和 API Key。CC Switch 的配置文件通常在~/.cc-switch/config.json加上 MCP 部分{ providers: { taotoken: { baseUrl: https://taotoken.net/api, apiKey: sk-your-taotoken-key, model: claude-sonnet-4-5 } }, mcpServers: { mysql: { command: npx, args: [tsx, /Users/yourname/mysql-mcp-server/src/server.ts] } } }这里三件套要写全Base URL 是https://taotoken.net/apiAPI Key 是你从控制台拿到的那个Model ID 填你要用的模型。CC Switch 的好处是可以在多个 provider 之间切换MCP Server 配置是共用的。配置保存后重启 AI 工具然后在对话里让它调用工具。我实测下来直接问帮我看看 main 库有哪些表就能触发list_tables。模型会返回类似这样的结果------------------ | Tables_in_main_db | ------------------ | users | | orders | | products | ------------------接着问users 表的结构是什么它会调describe_table返回字段列表。最后让它执行一次真实查询比如查一下 users 表里前 5 条记录模型会生成SELECT * FROM users LIMIT 5经过我们的安全校验后执行返回真实数据。整个过程你能在 Cline 的工具调用日志里看到完整的 JSON-RPC 请求和响应。验证成功的标志是模型不再编造字段名而是基于DESCRIBE的真实结果来写查询。如果它查了一个不存在的列数据库会报ER_BAD_FIELD_ERROR这个错误会原样返回给模型它就能自我纠正。5. 常见报错排查401、local proxy failed 与 reading choices接入过程中最容易踩的坑集中在几个报错上我一个个说。401 Unauthorized这个基本是 API Key 的问题。先确认 Key 有没有复制完整前后有没有多余空格。然后检查 Base URL 格式Cline 要求https://taotoken.net/api/v1CC Switch 和 Claude Code 要求https://taotoken.net/api填错了会 401 或者 404。如果 Key 是对的但还报 401去控制台看一下 Key 是不是被禁用或者额度用完了。local proxy failed / connection refused这个通常是 MCP Server 进程没起来。先在终端手动跑npx tsx src/server.ts看有没有报错。常见原因是connections.json路径不对或者数据库连不上。如果 Server 能起来但工具里报这个错检查args里的路径是不是绝对路径相对路径在不同工作目录下会找不到文件。reading choices of undefined这个报错一般出现在模型返回格式不符合预期的时候。如果你用的是 OpenAI 兼容接口检查请求体里model字段填的对不对。有些工具会把 Anthropic 格式的请求发到 OpenAI 端点导致响应结构对不上。解决办法是确认工具走的协议和 Base URL 匹配Anthropic 协议走/apiOpenAI 协议走/api/v1。OAuth 相关报错Claude Code 这类工具首次接入会走 OAuth 流程如果卡在授权页面检查网络能不能正常访问授权端点。有时候是浏览器缓存问题换个无痕窗口重试。如果一直失败可以改用 API Key 直连的方式在配置里直接填 Key 跳过 OAuth。MCP Server 启动了但工具列表为空检查server.tool()的注册代码有没有执行到await server.connect(transport)有没有加。另外确认 SDK 版本modelcontextprotocol/sdk1.0 之后的 API 和早期版本有差异McpServer的导入路径是modelcontextprotocol/sdk/server/mcp.js。查询返回结果被截断这是正常的我们的安全机制在结果超过 100KB 时会截断并提示。让模型加上更严格的WHERE条件或者减小LIMIT就行。排障的时候建议开两个终端一个跑 Server 看日志一个在 AI 工具里操作对照着看请求和响应。MCP 的 JSON-RPC 消息在 stdio 上是明文传输的调试起来其实很方便。6. 把数据库能力沉淀为 AI 工具链的标准组件走到这里你已经有了一个能跑的 MySQL MCP Server模型可以真实地查表结构、执行只读查询。这套东西的价值不在于单次查询而在于它把数据库操作变成了 AI 可调用的标准能力——你写一次 ServerCline、CC Switch、Claude Code 都能接换工具不用重写。几个实战建议。第一数据库账户一定要用只读权限GRANT SELECT ON main_db.* TO readonly_user%这样配从源头杜绝写操作风险。第二connections.json加进.gitignore密码不要提交到仓库。第三生产环境用 PM2 守护 Server 进程pm2 start npx tsx src/server.ts --name mysql-mcp避免进程挂了工具调不通。如果你想让模型在编码时自动带上数据库上下文可以在项目根目录放一个.mcp.json或者对应的工具配置文件把 MCP Server 配置写进去这样团队其他人拉代码就能直接用。模型 ID 和 Base URL 这些走 TaoToken 统一管理换模型只改一处配置。最后留个可操作的收尾打开你的 AI 工具问它帮我分析一下 orders 表里最近一周的订单趋势看它会不会自动调describe_table再生成查询。如果它做到了说明整条链路通了。接下来你可以照着同样的模式把 Redis、MongoDB 甚至内部 API 都包成 MCP Server让 AI 助手真正成为你技术栈里的一个成员。

相关新闻

Server最佳实践:我从20个MCP Server中总结的经验,附TaoToken统一Key配置

Server最佳实践:我从20个MCP Server中总结的经验,附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/9 15:52:50 阅读更多 →
安顺装修公司装修哪家好

安顺装修公司装修哪家好

安顺地处黔中,气候湿润多雨,业主装修最怕防潮不到位、中途增项、工期拖沓、售后找不到人。面对本地大大小小几十家装修公司,很多业主不知道怎么选。本文整理了3家不同类型的热门装企——本土深耕15年的速垒匠造装饰(九根藤装饰&am…

2026/10/10 16:00:43 阅读更多 →
semi-colon expected css(css-semicolonexpected)报错解决:从定位到修复的完整排查路径

semi-colon expected css(css-semicolonexpected)报错解决:从定位到修复的完整排查路径

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

2026/10/10 16:00:40 阅读更多 →

最新新闻

热电联产机组联合优化调度:Matlab+YALMIP建模风电消纳与储热电锅炉算例

热电联产机组联合优化调度:Matlab+YALMIP建模风电消纳与储热电锅炉算例

1. 冬季供暖季的弃风困局:热电联产机组到底卡在哪每年供暖季一过,风电场的同事就开始盯着调度曲线叹气:白天风光还好,一到后半夜风速上来了,风电场却得压出力,甚至有整场停机的时候。而另一边,热…

2026/10/10 16:01:52 阅读更多 →
用AI高效阅读鸿蒙源码:仓库定位、调用链与实战技巧

用AI高效阅读鸿蒙源码:仓库定位、调用链与实战技巧

简介:面向鸿蒙OS平台的“阅读”应用鸿蒙版仓库源码,特别适合鸿蒙应用开发者、对小说阅读器实现感兴趣的工程师,以及希望复用书源管理方案的技术人员。工程基于ArkTS编写主要页面与业务逻辑,并搭配svg、png等图标与图片资源&#x…

2026/10/10 16:01:52 阅读更多 →
Java IO流深度解析:字节流字符流、缓冲流与序列化实战指南

Java IO流深度解析:字节流字符流、缓冲流与序列化实战指南

1. 别被IO流的类图吓到:先搞懂设计骨架做Java开发几年后回头看,IO流其实是整个Java生态里设计最经典、也最劝退新手的模块之一。所谓“Java进阶--IO流”,不是让你把几十个类的名字背下来,而是先看清这套体系背后的两个核心设计思想…

2026/10/10 16:01:52 阅读更多 →
Vector v0.51.0 版本深度解析:OTLP 编解码、file source 去遗留化与遥测可靠性加固

Vector v0.51.0 版本深度解析:OTLP 编解码、file source 去遗留化与遥测可靠性加固

可观测性数据工程数据集成日志分析 【免费下载链接】vector A high-performance observability data pipeline. 项目地址: https://gitcode.com/GitHub_Trending/vect/vector 点击查看 免费下载 Vector v0.51.0(发布于 2025-11-04)是面向可观…

2026/10/10 16:01:52 阅读更多 →
Spring AI 2.x 深度技术解析:从架构重构到企业级落地,TaoToken 统一 Key 接入实践

Spring AI 2.x 深度技术解析:从架构重构到企业级落地,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/10 16:01:52 阅读更多 →
探索AI工具——我的Cursor初体验:从Base URL改到TaoToken

探索AI工具——我的Cursor初体验:从Base URL改到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/10 16:00:51 阅读更多 →

日新闻

卫星轨道分类全解析:从LEO到GEO的选型逻辑与工程实践

卫星轨道分类全解析:从LEO到GEO的选型逻辑与工程实践

1. 从“卫星轨道分类”这个标题说起:为什么值得花时间搞懂第一次接触“卫星轨道分类”这个概念,很多人会觉得它离自己很远——不就是天上的星星怎么转吗?但如果你正在做航天任务规划、遥感数据接收、星座设计,甚至只是准备一场航天…

2026/10/10 0:00:39 阅读更多 →
Spring AOP 核心原理与实战:从概念到日志切面落地

Spring AOP 核心原理与实战:从概念到日志切面落地

1. 从一个真实痛点说起:为什么你的代码里到处都是重复逻辑刚入行那会儿,我写过一个用户管理模块,注册、登录、改密码、注销四个接口。每个接口里都塞了几乎一样的日志打印、参数校验、事务开启和提交。当时觉得没什么,能跑就行。直…

2026/10/10 0:00:40 阅读更多 →
Python招聘数据采集与分析可视化:从采集清洗到薪资技能城市可视化全链路

Python招聘数据采集与分析可视化:从采集清洗到薪资技能城市可视化全链路

简介:这是一套面向计算机相关专业学生与项目实战学习者的Python数据采集与分析可视化完整项目,以Boss直聘岗位数据为对象,适合用作毕业设计、课程设计或期末大作业。资源包共38个文件,约246KB,以13个py源码文件为核心&…

2026/10/10 0:00:40 阅读更多 →

周新闻

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/10 11:14:25 阅读更多 →
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/10 1:36:08 阅读更多 →
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/10 11:14: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/10 5:23:50 阅读更多 →
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/9 21:32:20 阅读更多 →
黑夜航拍船只数据集训练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/10 10:38:42 阅读更多 →