news 2026/9/19 11:19:31

YOLOv5s目标检测实战:从数据标注到ONNX部署全流程

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
YOLOv5s目标检测实战:从数据标注到ONNX部署全流程

做目标检测的朋友应该都听说过YOLOv5s,尤其是刚入坑或者需要快速落地一个检测任务时,YOLOv5s几乎是绕不开的选项。它属于YOLOv5系列里体积最小、速度最快的一个变体,模型参数量只有7.2M左右,但在COCO数据集上仍能保持约37.2的mAP,兼顾了精度和推理速度。我自己在多个项目里用过YOLOv5s,从安防摄像头的人形检测到工厂流水线的缺陷识别,再到边缘设备上的实时检测,它都能比较稳地扛住任务。这篇文章我想把YOLOv5s从数据准备到实战检测的完整流程讲透,包括标注规范、目录结构、训练参数、日志分析、断点续训、ONNX导出,以及我踩过的坑和排查方法。不管你是刚开始接触目标检测,还是已经跑通过官方示例但想自己训练业务数据,都可以跟着这套流程走一遍。

1. 先搞清楚YOLOv5s到底能干什么

1.1 为什么选YOLOv5s而不是其他版本

YOLOv5官方仓库提供了n、s、m、l、x这几种不同规格的模型,数字越小模型越小,速度越快,但精度也相对低。YOLOv5s正好是中间偏轻量的选择,它在精度和速度之间的平衡点非常经典。很多人一上来就用YOLOv5x,觉得精度越高越好,但实际部署时往往发现GPU扛不住,或者视频流处理帧率只有个位数。YOLOv5s在RTX 3060上跑1080p视频,批量推理能达到80到120 FPS,在CPU上也能勉强跑到10到20 FPS,这个表现对于大多数原型验证和中小型项目来说完全够用。

我选择YOLOv5s还有一个原因:它是我见过最容易“调好”的模型。这里不是说它不用调参,而是相对大模型来说,YOLOv5s对学习率、batch size的波动不那么敏感,训练更容易收敛。如果你是在自己的业务数据上训练,YOLOv5s即使只训练几十个epoch,也能得到一个基本可用的权重,这对快速验证需求非常有价值。当然,如果检测目标特别小或者遮挡严重,可以后续再切到YOLOv5m或YOLOv5l,但起步阶段从YOLOv5s开始是最稳妥的。

1.2 检测任务的基本流程

目标检测任务本质上要解决两个问题:目标在哪里,目标是什么。YOLOv5s的做法是把输入图片划分成网格,每个网格负责预测若干边界框,同时输出每个框内目标的类别概率。训练阶段,我们给模型看大量已经标注好的图片,让它学会从像素中提取特征并回归出边界框位置。推理阶段,模型只需要一次前向传播就能输出所有检测结果,这也是YOLO系列“You Only Look Once”的由来。

完整的训练全流程可以拆成四步:数据准备、环境搭建、模型训练、模型部署。每个环节都有自己的坑。数据准备决定模型的上限,训练参数影响收敛速度,部署方式则直接关系到实际效果。后面我会按照实际操作顺序一步步展开,每个命令和参数都会解释为什么这么写,方便大家根据自己项目的情况做调整。

2. 数据准备:训练前80%的工作量都在这

2.1 数据采集与标注规范

很多教程喜欢直接跳到训练命令,但我必须强调,数据准备才是整个项目里最花时间也最影响结果的环节。你采集的数据直接决定了模型能不能在真实场景里用起来。采集时要注意场景多样性、光照变化、角度变化、目标尺度变化。如果只拍同一批角度和背景的图片,训练出来的模型换个环境就废了。

标注这一步,推荐使用LabelImg或X-AnyLabeling。LabelImg是老牌工具,界面简单,支持PascalVOC和YOLO格式导出。X-AnyLabeling集成了多种AI辅助标注功能,可以先用预训练模型自动打框,再人工修正,能节省大量时间。我自己在大规模数据标注时通常先用一个初步训练的模型做预标注,然后人工校准,效率能提升3倍以上。

标注规范有几个必须遵守的点。第一,边界框要尽量贴合目标边缘,不要留太多背景,也不要把目标截断。第二,类别标签不要有歧义,比如“人”和“行人”不要混用。第三,标注文件里一张图如果有多个目标,每行一个目标,格式是“class x_center y_center width height”,其中x_center、y_center、width、height都是相对于图片宽高的归一化值。举个例子,一张640x640的图片,某个目标中心点位于(320, 320),框宽为80,高为160,那么标注行就是:0 0.5 0.5 0.125 0.25。这里0是类别编号。这一点特别容易错,很多人写成绝对像素坐标或者没归一化,训练时就会报错或者loss直接崩掉。

2.2 数据集目录结构与label格式

YOLOv5官方仓库对数据集目录结构有明确要求,我建议严格按官方规范来,这能避免很多后期路径问题。最基础的目录结构是这样的:

dataset/ ├── images/ │ ├── train/ │ ├── val/ │ └── test/ ├── labels/ │ ├── train/ │ ├── val/ │ └── test/ └── dataset.yaml

images和labels下的train、val、test文件夹要一一对映。图片文件名和标注文件名必须完全相同,只是后缀不同。比如图片是photo_001.jpg,对应标注文件就是photo_001.txt。一旦文件名对不上,训练的时候这张图就无法读取,容易报warning,影响训练效率。

另外要注意,不同版本的YOLOv5对目录名是否区分大小写有一定要求,建议统一使用小写。如果你的数据是在Windows上标注后拷到Linux服务器训练,一定要检查路径里的反斜杠和盘符,最好把数据集完整上传到服务器并重新校验一遍。

2.3 数据集划分与配置文件

数据划分一般按训练集、验证集、测试集6比2比2或者8比1比1来分。测试集是最后评估用的,训练过程中不要碰它。验证集用于每个epoch后评估模型效果,帮助调整超参数和选择最佳模型。划分时可以写个小脚本,也可以用YOLOv5自带的split工具,但最简单的还是随机打乱后按比例分配。需要注意的是,同一个场景的连续帧图片如果同时出现在训练集和验证集里,会导致验证结果虚高,模型实际泛化能力并没有那么好。所以在划分之前,最好先按帧序列分组,再整组划分。

配置文件dataset.yaml是整个训练的关键,它告诉YOLOv5数据在哪里、有几类、类别名是什么。内容很简单:

path: /home/user/dataset train: images/train val: images/val test: images/test nc: 2 names: ['person', 'car']

这里path是数据集根目录的绝对路径,train和val可以写相对路径,也可以写图片文件夹的完整路径。值得注意的是,有些初学者在path里写了相对路径,但训练时工作目录不在项目根目录,就会导致“No labels found”的报错。我建议path直接写绝对路径,省心。nc是类别数,必须和标注里的类别编号范围一致。比如类别有3类,编号就是0、1、2,nc就填3。names列表里的顺序也必须和标注文件里的编号逻辑一致,否则模型学出来类别全乱了。

3. 环境搭建与模型配置

3.1 安装依赖与验证环境

训练YOLOv5s需要的Python版本建议3.8到3.10,PyTorch版本建议1.8以上。我目前常用的是PyTorch 2.0.1 + CUDA 11.8的组合,跑yolov5s非常稳定。安装命令在官方README里有,建议用conda创建新环境,避免污染系统Python。我这里列一个完整流程:

conda create -n yolov5 python=3.9 -y conda activate yolov5 cd yolov5 pip install -r requirements.txt

requirements.txt里包含torch、torchvision、opencv-python、numpy等依赖。如果你已经有安装好的PyTorch,可以跳过自动安装PyTorch,避免版本冲突。装完后先验证一下GPU是否可用:

import torch print(torch.cuda.is_available()) print(torch.cuda.get_device_name(0))

如果输出True和显卡型号,环境就基本没问题了。很多同学卡在装环境这一步,主要原因是网络问题导致包下载慢。建议用国内镜像源,比如阿里云或清华源,pip install的时候加上-i参数。另外,如果是在公司内网环境,还要看是否有代理墙的限制,不过这点就属于网络配置的常规操作了,略过不提。

3.2 修改data和yaml文件

除dataset.yaml外,模型结构文件models/yolov5s.yaml里通常不需要动,保持默认即可。训练时通过--data参数指定dataset.yaml,--cfg参数指定模型结构yaml,--weights指定预训练权重或断点权重。

有一个容易忽略的点:YOLOv5里有“anchors”的概念,官方预训练用的anchor是在COCO数据集上聚类出来的。如果你训练的类别是大目标或小目标,直接沿用默认anchor可能效果不佳。YOLOv5提供--noautoanchor参数关闭自动anchor,但默认情况下训练前会自动计算当前数据集的anchor。如果你的数据目标尺度很特殊,可以先用--noautoanchor跑一次训练,然后在训练日志里查看建议的anchor,再手动填进模型yaml里。不过对于大多数项目,自动anchor已经够用,先别折腾这个。

3.3 预训练权重与冻结训练策略

YOLOv5s最核心的优势就是有在COCO上预训练好的权重。这些权重已经学到了通用特征,比如边缘、纹理、形状等。使用预训练权重可以大幅加快收敛速度,甚至可以将训练时间缩短到原来的十分之一。下载方式有两种:一是训练时直接加--weights yolov5s.pt,如果本地没有,脚本会尝试从官方下载;二是手动下载后放到weights目录。我建议手动下载,因为官方服务器在国外,训练过程中断网会影响体验。

wget https://github.com/ultralytics/yolov5/releases/download/v6.0/yolov5s.pt -P weights/

下载后,训练命令里的--weights weights/yolov5s.pt。如果你的数据集跟COCO类别差异非常大,或者你需要修改类别数,加载预训练权重时模型最后一层输出维度会不匹配,YOLOv5会自动处理这种情况,提示你“Transferred x/y layers”,它不加载最后一层权重。这里的“x/y”表示从y层中成功转移了x层,不必担心那个警告。

冻结训练是指训练初期固定backbone层的参数,只训练head部分。这样可以节约显存,加快速度,也能防止小数据集过拟合。有个经验值:当数据集每个类别只有几百张图片时,冻结backbone前10层能显著提升稳定性。用YOLOv5训练时,我看training命令有--freeze参数。比如要冻结前10层,可以加--freeze 10。注意这个参数是冻结模型的前N个模块,而不是全部backbone。实践中我建议先用freeze=10训练50个epoch,再解冻全部层微调,效果往往比一次性训练更好。

4. 训练过程与监控

4.1 训练命令与关键参数解析

训练YOLOv5s的标准命令长这样:

python train.py --data dataset.yaml --weights yolov5s.pt --epochs 100 --batch-size 16 --img 640 --device 0

这个命令里边每个参数都有讲究。--epochs别设太大,也不要太小。100轮在大多数中规模数据集上够用,如果数据复杂可以增加到200。--batch-size受显存限制,YOLOv5s在16G显存上可以开64,但建议先设为16试一下。如果显存不够,把batch降到8,但如果你发现loss波动很大或mAP很低,往往是因为batch太小,梯度更新不稳定。--img是输入图片分辨率,默认640。我建议训练和推理保持相同输入尺寸,否则部署时可能有性能差异。如果你的目标是大物体,可以适当缩小到416提高速度;如果小目标多,可以尝试896来保留更多细节,但显存和速度会翻倍。

训练时建议再加一个--project和--name参数,用来指定输出路径。很多新手把所有实验结果都放在yolov5/runs/train/exp几个默认目录里,结果分不清哪个模型对应哪次训练。我一般这样写:

python train.py --data dataset.yaml --weights yolov5s.pt --epochs 100 --batch-size 16 --img 640 --device 0 --project runs/train --name person_car_v1

这样输出目录就是runs/train/person_car_v1,里面会自动生成weights、results.csv和训练日志。长期做项目一定养成这个习惯,后面找模型时非常方便。

4.2 训练日志与曲线怎么看

训练过程中控制台会打印每一轮的信息,包括GPU利用率、box_loss、cls_loss、obj_loss、mAP等。很多人只看最终mAP,其实中间过程更有参考意义。刚开始训练时loss会快速下降,然后逐渐平缓。如果box_loss一直在下降,mAP也在缓慢上升,说明模型还在学习,别急着停。如果loss降到某个值后震荡,而且已经跑了大量epoch,说明模型基本收敛,可以停了。

YOLOv5会在输出目录里生成results.png,包含多个子图:train/box_loss、train/obj_loss、train/cls_loss、val/box_loss、val/obj_loss、val/cls_loss、metrics/precision、metrics/recall、metrics/mAP_0.5、metrics/mAP_0.5:0.95。这些曲线能帮助你判断训练状态。我判断过拟合的一个重要经验:如果val loss曲线一路下降后再明显反弹,而train loss还在下降,说明模型在“背题”而不是在“学规律”,此时应该用早停或增大数据增强。YOLOv5默认开启早停(patience=100),如果验证指标连续100轮没有提升会自动停止,这个机制很实用。

4.3 中断恢复与断点续训

训练任务经常因为断电、显卡报错或服务器重启而中断。YOLOv5提供的断点续训非常简单,只需要在训练命令里把--weights指定为上一次训练的last.pt即可。比如:

python train.py --data dataset.yaml --weights runs/train/person_car_v1/weights/last.pt --epochs 200 --batch-size 16 --img 640 --device 0

此时epochs要填总共需要的轮数,YOLOv5会读取last.pt中记录的上次已训练轮数,自动从断点处继续,直到达到你设置的总epoch数。除了权重,优化器状态、学习率、随机种子也都会被恢复,所以续训结果和连续训练几乎一样。我建议每个项目都要养成每10个epoch存一次检查点的习惯,可以用--save-period 10参数控制。万一训练中断,最多损失10个epoch的工作量。

5. 模型评估与实用性调优

5.1 指标解读:mAP、Precision、Recall

训练结束后,weights目录下会有best.pt和last.pt。best.pt是验证集上表现最好的模型,last.pt是最后一个epoch的模型。一般部署时用best.pt。评估指标主要看验证集上的mAP_0.5和mAP_0.5:0.95。mAP_0.5表示IOU阈值取0.5时的平均精度,比较宽松;mAP_0.5:0.95则表示从0.5到0.95不同IOU阈值下的平均精度,更严格,也更考验边界框回归精度。

Precision(精确率)表示模型预测为正样本的结果中,真实为正样本的比例。Recall(召回率)表示真实正样本中被模型找出来的比例。这两个指标往往此消彼长。如果你的任务更关心“漏检率要低”,就优先提高Recall;如果更关心“误检要少”,就优先提高Precision。可以通过调整置信度阈值来权衡。YOLOv5的detect.py里通过--conf-thres控制置信度阈值,默认是0.25。调低阈值会提高Recall,调高阈值会提高Precision。在部署阶段,根据实际业务需求调一下这个参数,往往比重训模型更有效。

5.2 常见过拟合、欠拟合与数据增强调整

如果训练集上mAP很高但验证集或测试集效果很差,几乎可以断定过拟合。解决办法有几个:增加数据量、调高数据增强、引入dropout或weight decay、冻结部分层。YOLOv5内置了丰富的数据增强,包括马赛克增强、随机仿射变换、HSV色域变换、翻转等。数据增强默认是开启的,但可以调整超参数。在data/hyps/hyp.scratch-low.yaml或hyp.scratch-high.yaml里可以设置。比如hyp.scratch-high.yaml里hsv_h等参数会调高,增强更强,适合小数据集。如果你的数据本身已经非常丰富,增强太强反而会“矫枉过正”,导致模型学不动。遇到这种情况,把增强参数适当降低即可。

欠拟合的表现是训练集和验证集loss都很高,mAP上不去。此时多半是模型容量不足,或者训练轮数不够。可以先排除数据集标注错误问题,再看是不是分类太难,最后考虑换更大的模型YOLOv5m。另外,学习率太大也会导致loss下不去,可以用默认学习率训练,不要一开始手动改得很夸张。

5.3 剪枝、量化与模型导出

训练好后,为了部署,一般需要导出模型格式。常见的导出格式有ONNX、OpenVINO、TensorRT等。YOLOv5自带的export.py就支持多种格式,一行命令即可。例如导出ONNX:

python export.py --weights runs/train/person_car_v1/weights/best.pt --include onnx --img 640 --batch-size 1

导出ONNX后可以使用onnxruntime推理,CPU上也能跑,方便后续跨平台部署。如果要上TensorRT,可以先导出engine文件,在NVIDIA显卡上实现更低延迟。量化是另一个方向,比如使用INT8量化可以把模型体积缩小四倍,推理速度提升明显,但精度会有一定损失。我的建议是,先确保模型效果满足需求,再考虑量化和优化,不要一上来就压缩模型。

6. 实战检测:用训练好的权重跑起来

6.1 单张图片、视频和摄像头的检测

拿到best.pt后,最直接的验证方式是用detect.py脚本跑推理。参考命令:

python detect.py --weights runs/train/person_car_v1/weights/best.pt --source data/images/test.jpg --img 640 --conf-thres 0.25

--source参数既可以传图片路径,也可以传视频文件路径,还可以传摄像头设备号,比如--source 0表示本机第一个摄像头。输入为图片时,结果保存在runs/detect/exp目录下,标注好识别框和置信度。输入为视频时,会逐帧检测再合成视频文件。我在实际项目中最常用的是cam feed,把Source设为摄像头,跑起来帧率还挺满意。需要注意的是,如果摄像头分辨率很高,建议先缩放到640输入,因为YOLOv5s本身输入尺寸是固定正方形的,内部会做letterbox填充,直接输入原始高分辨率反而增加耗时。

6.2 在Python脚本中调用模型进行实时检测

除了命令行,我们经常需要在自己的程序里调用模型。YOLOv5官方训练好的权重可以非常方便地被torch.hub加载,但如果你想加载自己的权重,推荐使用以下方式:

import torch import cv2 model = torch.hub.load('ultralytics/yolov5', 'custom', path='runs/train/person_car_v1/weights/best.pt', force_reload=True) model.conf = 0.25 model.iou = 0.45 img = cv2.imread('data/images/test.jpg') results = model(img) results.print() results.show()

这个用法适合快速测试。但如果你要部署到生产环境,我建议把模型导出为ONNX,然后用onnxruntime推理,这样不依赖PyTorch和YOLOv5仓库代码,部署自由度更高。一个简单的ONNX推理逻辑如下:

import onnxruntime as ort import cv2 import numpy as np session = ort.InferenceSession('best.onnx', providers=['CPUExecutionProvider']) input_name = session.get_inputs()[0].name input_shape = session.get_inputs()[0].shape img = cv2.imread('data/images/test.jpg') # 预处理:letterbox + normalize # 这里省略具体实现,核心是把图像resize到640x640并归一化 # 输出形状为 (1, 25200, 85),再通过NMS过滤低置信度框

ONNX模型输出的是原始预测张量,后处理需要自己写NMS。YOLOv5官方导出ONNX时通常会附上后处理部分,但为了更可控,很多场景下我们会在模型侧只保留头部输出,自己实现解码。这块需要花点时间,但调试一次后就能建立起完整的部署链路。

6.3 轻量化部署:从PC到边缘设备

如果你的目标设备是树莓派5、Jetson Nano或RK3588这类边缘设备,模型体积和推理速度就变得非常关键。树莓派5上跑YOLOv5s,CPU模式下单帧推理大约在200到300毫秒,如果使用NCNN或者RKNN的NPU加速,可以降到30到50毫秒。我试过在树莓派5上部署自己训练的YOLOv5s模型,第一步就是转换为ONNX,再用NCNN转换为.param和.bin文件。转换过程中要注意YOLOv5的anchor和输出层,NCNN自带yolov5示例,很多坑都补过了。

部署到边缘设备时,输入尺寸可以选择320或416来提速,但要注意这会降低检测精度,尤其是小目标会损失严重。还有一点,模型量化到FP16或INT8后,在边缘设备上效果会有所变化,建议量化前先做一个包含各种场景的验证集,对比量化前后mAP,如果精度下降超过可接受范围,就考虑用INT8混合量化或退回FP16。

7. 常见问题与排查技巧实录

7.1 数据集路径和标签格式报错

训练时最常见的两个报错:一是“No labels found in ...”,二是“AssertionError: train: No labels in ...”。这通常是因为labels目录下找不到对应txt文件,或者图片和txt文件名不匹配。排查顺序是:检查labels/train目录是否存在;检查txt文件里是否每一行有5个数值;检查图片格式是否是jpg、png等YOLOv5支持的格式。还有一个坑,标注文件的路径检查,使用LabelImg保存时如果设成了PascalVOC格式,生成的.xml文件就不能直接用,必须先转换为txt。转换脚本网上很多,但是一定要核对归一化坐标是否在0-1之间。

7.2 CUDA out of memory

这是最普遍的报错,我的应对办法是按优先级降级:先把batch-size降到8或4,如果还不行就把--img从640降到416,再不行就把workers数调低,比如--workers 0。另外,使用--device 0指定GPU,避免同时占用多卡。有时候即使batch很小也OOM,可能是由于日志或验证阶段缓存了太多数据,可以尝试关闭--cache-images参数。还有一个容易被忽略的点,如果你的显卡显存只有6G,就不要在训练时开着TensorBoard显卡可视化工具,它也会占一部分显存。

7.3 训练效果差但不知道从哪查

当模型mAP一直很低时,我一般按这个顺序排查。先随机抽样标注好的图片,用可视化脚本把标签框画出来看是否正确。很多问题其实出现在标注阶段,比如标注框严重偏移,或类别编号错乱。如果标注没问题,就看是不是数据量太小,少于500张图片的训练集很难让模型达到高精度。再看训练曲线,如果loss不下降,考虑学习率问题。最后再看模型是不是压根没加载预训练权重,如果--weights路径写错,模型就从零开始训练,收敛会很慢。

这里可以整理一个速查表:

现象可能原因处理办法
训练时找不到标签目录结构或文件名不对检查images/labels对应关系
显存不足batch_size过大降低batch_size或分辨率
loss不下降学习率过大或数据没加载对检查数据加载,恢复默认学习率
val loss反弹过拟合增加数据增强或提前停止
mAP很低标注错误或数据太少可视化标注,扩充数据

这类问题我几乎每个项目都遇到过,按套路排查能节省很多时间。建议每次实验都保留训练日志和曲线图,这样即使隔了几天再回头看,也能快速定位问题。

YOLOv5s的整个训练链路并不复杂,但真正做到稳定可靠,需要在数据、参数、部署上反复打磨。我个人最喜欢YOLOv5s的一点是,它的调试成本低,出错时提示信息也足够清晰,非常适合作为业务落地的基础模型。希望这篇流程解析能帮你少踩一些坑,如果你的数据集准备得足够扎实,按照这套流程走下来,第一次跑出可用模型应该不成问题。后面我也会把ONNX部署到边缘设备的完整代码整理出来,到时候可以继续聊。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/19 11:18:20

Open FPV VTX与Betaflight的MSP协议深度对齐指南

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

作者头像 李华
网站建设 2026/9/19 11:17:37

Hugging Face:Kimi K2.7 Code 接到 TaoToken

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

作者头像 李华
网站建设 2026/9/19 11:17:29

京东博士组多级库存LP建模方法论解析

简介:本资源是一份聚焦京东供应链管理体系的深度解析型PPT课件,面向高校管理类、物流与电子商务专业师生,以及企业供应链从业者,用于理解大型电商平台供应链运作逻辑与实践路径。课件共35页,以博士研究组视角系统梳理京…

作者头像 李华
网站建设 2026/9/19 11:17:01

AS13004标准解读:从PFMEA到控制计划的风险闭环实践

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

作者头像 李华
网站建设 2026/9/19 11:16:33

学术出版场景在线聊天客服系统自研实战:架构设计与核心实现

1. 爱思维尔在线聊天客服到底是个什么系统第一次接触“爱思维尔在线聊天客服”这个需求,是在一个学术数据库运维群里。有人问:出版社那边的在线咨询窗口,能不能自己搭一套类似的?当时群里讨论得很热闹,但真正动手做的人…

作者头像 李华
网站建设 2026/9/19 11:13:37

把 Cursor 的 Base URL 改到 TaoToken 之后,RB2310/RB2401 价差图这样生成

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

作者头像 李华