2026年3月

AI 和 LLM 的进步通常归因于三个方面的持续改进:模型、数据、计算。三者互相关联。要跑起那些参数量庞大的模型,就需要足够的计算资源来支撑。Llama 3 最大的模型超过 4000 亿参数在 16000 块 GPU 上训练了数周乃至数月,优化计算意味着在更低的成本下训练更大的模型。

本文将介绍 GPU 的核心特性,并据此讨论如何设计更快的算法。

GPU 与 CPU 的区别

CPU 的优化目标是单任务延迟,尽可能快地完成一个任务然后转向下一个,这对通用计算是非常合理的。但是GPU 则不同,它优化的是吞吐量追求的是同时完成多个并行任务。打个比方:CPU 像一个能力极强的工人,GPU 像一群普通工人同时干活。在 LLM 训练这种大规模并行处理场景下GPU 的架构天然占优。

继续用工厂来打比方。GPU 可以看作一个庞大的工厂城镇。城镇中有多个"工厂集群"(技术上叫流式多处理器,SM),每个集群包含多个工厂(流式处理器,SP)和一个小仓库(共享内存)。整个城镇里还有一个全局仓库(DRAM),离各集群更远但容量大得多。

类比虽然简化但说明了 GPU 中一条核心:集群内的小仓库访问速度远快于全局仓库,代价是容量小得多。

全局仓库的运输通道到底有多慢?过去 20 年间,硬件浮点运算能力(对应工厂车间的加工速度)提升了 60000 倍,DRAM 带宽只提升了 100 倍,互连带宽更是只有 30 倍。

过去的瓶颈在计算,但是现在的瓶颈在内存带宽。既然数据搬运才是真正的瓶颈,减少搬运次数和搬运量就是让 GPU 跑得更快的关键。以下五个技巧,都围绕这一思路展开,来自 CS336 课程。

技巧 1:低精度计算

矩阵乘法中,数字精度是可以选择的。精度越高,存储一个数字所需的字节越多:9.327595 比 9.33 占的空间大。用低精度数字意味着搬运的"货物"更少,在拥堵的"道路"上花费的时间也更短。

这意味着用 fp16 代替 fp32,但并非训练的所有阶段都需要低精度,只需在数据搬运阶段降到 fp16 即可。具体做法是:输入以 fp16 格式传入,矩阵乘法在 32 位精度下完成(计算并非瓶颈,而且高精度可以防止舍入误差的逐步累积),输出再降回 fp16 用于传输。

回到工厂类比:道路拥堵(下图红线),所以进出工厂的箱子越小越好。工厂内部空间充裕,可以在大空间中完成加工,加工完成后再打包成小箱子运出。

技巧 2:算子融合

假设工厂有三步操作:正方形变圆形,圆形变三角形,三角形变星形。如果每完成一步就把半成品送回仓库再取回来做下一步,那来回搬运的次数非常多。

算子融合的做法是把多步操作在工厂内一次性完成,省去中间产品的反复搬运。

实现方式有两种:手写低级代码控制融合细节,或者直接用 torch.compile 自动完成优化。

技巧 3:重计算

这个场景稍微复杂一些,假设工厂从仓库取了一个正方形,依次加工为圆形、三角形、星形。星形被送回仓库供后续使用。但到了最终步骤,四种形状全部要用——正方形、圆形、三角形、星形。工厂内部存不下东西,所有存储必须依赖仓库。

安排生产线有两条路:

  • 选项 1:加工过程中把圆形和三角形也送回仓库保管。需要的时候直接取回。
  • 选项 2:不保存中间形状,丢掉就丢掉。需要的时候从正方形重新加工一轮。

选项 1 省了重新加工的电力,但仓库搬运量增大。选项 2 搬运量小,但要额外消耗算力。这是一个内存与计算之间的权衡。

既然瓶颈在道路拥堵而非车间产能,重计算(选项 2)是更合理的选择:重新加工成本低,但从仓库搬运的成本可能高出几个数量级。用算力换内存带宽,划算。

技巧 4:内存合并访问

仓库有个特点:货物按板条箱整箱发出。工厂请求任何一件物品,仓库都会把整个板条箱送过来。优化的要点在于:把需要的物品尽量集中在同一个箱子里。

假设每箱 4 件,工厂需要 8 件。如果这 8 件集中在 2 个箱子里,取 2 箱就够了。如果散落在 8 个箱子中,就得搬 8 箱——搬运成本翻了四倍。

技术上,DRAM 以"突发模式"读取,每次读取返回一段连续字节。即使处理器只需要其中一个地址的数据,整个突发段也会被送过来。当所有线程的访问地址落在同一个突发段内时,只需一次 DRAM 请求,这种情况称为完全合并访问。

一个直接的推论:把维度(比如词汇表大小)对齐到 64 的倍数会带来可观的速度提升。

原因很简单:分块操作(见下一个技巧)需要沿突发段的边界读取数据,如果分块边界与突发段不对齐,读取次数会急剧增加。

技巧 5:分块

分块的核心思想:把大矩阵切成小块,加载到共享内存(集群内的小仓库)中,避免反复访问全局内存。

以两个 4x4 矩阵 A 和 B 的乘法为例,结果是 4x4 矩阵 C。计算 C 的某几个元素时,需要在 A 和 B 矩阵上多次跨行/跨列读取,每次读取都要访问全局内存。

分块的做法是将 A 和 B 各切成四块。小块可以整块加载到共享内存中。先加载红色块,计算部分和(图中橙色部分):

接着加载下一组块,继续累加部分和。总计算量不变,但每一步都在共享内存中完成而非反复访问全局内存,节省的时间相当可观。

FlashAttention

有了上面五个技巧做铺垫,可以来看 FlashAttention 了。

先简要回顾注意力机制。权重矩阵将隐藏向量投影为 Q、K、V,然后对每个词的 q 和 k 向量求点积(等价于 Q × K.T 的矩阵乘法),得到原始注意力分数——即每个查询词对各个键词的关注程度。对原始分数做 softmax 归一化,使其加和为 1。

数值稳定性方面,取指数之前先减去最大值。e¹² 已经是 162,755,超出 fp16 的上限 65,504,直接计算会溢出。减去最大值不改变 softmax 结果,但规避了溢出(详见附录)。

归一化后的 softmax 分数与每个词的"值"向量相乘、求和,得到最终的注意力输出。

回到 FlashAttention。Q 和 K 相乘产生一个 N × N 矩阵(N 为序列长度)。当上下文窗口很大时,这个矩阵无法整个放入共享内存。

解决方案是沿 N 维度分块。比如上下文窗口 1028,按 64 切块,每块可以载入共享内存。这样仍有完整的点积结果(无需计算部分和),只是逐块填充结果矩阵。

分块本身是标准操作,棘手的部分在于 softmax 和后续的值向量加权求和。计算 softmax 通常需要整行数据来做归一化,而访问整行意味着要回全局内存取数据。FlashAttention 的突破在于"在线 softmax"——softmax 计算和值向量加权求和可以在块内一次性完成,无需看到全行数据。关键条件是最终操作是加权求和,这给了逐块修正的数学余地。

下面用一个例子来说明。假设 QK 矩阵乘法产生了六个原始分数,表示某个查询词对六个其他词的关注度。常规做法是一次性对六个分数做 softmax 再与六个值向量加权求和,得到

A


但遍历整个长度 N 的序列在块内放不下。于是按"在线"方式进行:将六个分数分为三个块(每块 2 个元素),逐块处理。第一个块中只有两个原始分数,先基于这两个值做计算:

这一步不做归一化。虽然可以用当前的和(1+0.0082)归一化,但后续块会改变总和,到头来还得修正。所以更好的做法是记录归一化分母的累积值最后一步统一归一化。

进入第二个块。目标是得到与一次性看到所有四个值相同的结果。四个值的全局最大值是 12,第一个块需要把自己的最大值传递过来。累积的加权和与归一化分母也要一并传递。

到目前为止,如果只有四个值,取

A_(1+2)

除以归一化总和 1.3098 就能得到最终结果。

最后一个边界情况是:新块出现了更大的最大值。第三个块的最大值从 12 变成了 13,但之前的

A_(1+2)

是按 max=12 算的。要让结果与一次性看到全部六个值一致,就需要修正之前的计算——将所有旧指数乘以

e^(-1)

(即

e^(12-13)

),补偿最大值的变化。

不需要逐个回去修正每个指数值,只需将

A_(1+2)

和归一化分母整体乘以

e^(-1)

即可:

最后用累积分子

A_(1+2+3)

除以更新后的分母 1.4955,得到结果。整个过程从未回访之前的块:只要跟踪最大值和归一化分母,就能逐块完成 softmax。这些操作都在共享内存中进行,不必频繁访问全局内存。

效果如何?FlashAttention 原始论文显示,在 GPT-2 上注意力计算的耗时减少了数倍。

处理大规模模型时,内存放置策略,比如尽量在共享内存中完成计算对整体性能的影响远超我们的想象。

并行计算简介

以上讨论都局限在单 GPU 上,小模型没问题,但现代大型 LLM 根本装不进一块 GPU。Llama 3 用了 16K 块 GPU,核心问题变成了:如何将训练计算分配到多台机器上,再将结果汇总起来。

在展开不同的并行策略之前,先回顾训练流程。以一个 2 层神经网络为例,batch size 16,使用 Adam 优化器(为每个参数维护一阶和二阶矩估计)。

数据并行

拆分计算的第一种方式是拆分数据。假设有效 batch size 为 16,但每块 GPU 内存只够放 4 个样本。单 GPU 下需要跑 4 轮前向传播来累积梯度,再做一次反向传播,即梯度累积。

数据并行的做法:把 16 个样本分给 4 块 GPU,每块拿 4 个样本,各自并行执行前向传播。问题在于如何聚合梯度。

一种方式是汇集所有激活值来计算平均 loss 再求梯度,但更聪明的做法是在每块 GPU 上各自计算 4 个样本的梯度再求和——搬运的数据量更小,数学上完全等价。梯度求和后传回各机器,分别更新本地模型。

这个操作的技术术语是 all-reduce:每台机器贡献各自的梯度,合并后每台机器都拿到结果。虽然图示中画了一个"聚合器"(灰色方框),实际的 all-reduce 实现通常是环形传递——GPU 之间互相传梯度,最终全部拿到平均值。

4 块 GPU 并行,有效 batch size 仍然是 16,速度却快了很多。但有一个效率问题:每块 GPU 都在做完整模型的更新,要维护所有参数的 Adam 状态(一阶矩和二阶矩)。

内存充裕时这不成问题。但实际上每块 GPU 里复制了完整的模型参数、梯度、主权重以及 Adam 优化器状态。Adam 的状态量是模型参数量的两倍,内存占用很大。

对于大模型,内存成为硬瓶颈。ZeRO(Zero Redundancy Optimizer)针对的就是这个问题:一组内存优化技术,在保持数据并行的前提下大幅减少每块 GPU 的内存占用。

ZeRO Stage 1

核心思想是让每块 GPU 只负责更新一部分参数。比如将每层参数分成四份,GPU 1 负责 Part 1,GPU 2 负责 Part 2,以此类推。

走一遍流程:数据仍然拆分到四块 GPU 上,每块 GPU 基于自己看到的 4 个样本计算完整的梯度——到这里还是标准的数据并行。但梯度汇总后不再发回给所有人,而是按参数分片发送:每块 GPU 只收到自己负责那部分参数的梯度。术语上叫 reduce-scatter——每人只拿到合并结果的一个切片。

各 GPU 只更新自己负责的那部分参数,也只需要保留该部分的优化器状态。更新完成后,各 GPU 把自己的参数切片分享出去,拼接成完整模型。术语上叫 all-gather——每人贡献一个切片,每人拿到完整拼接结果。

ZeRO Stage 1

整个过程可以概括为两阶段:第一阶段按数据维度拆分,各 GPU 算全参数梯度再汇总;第二阶段按参数维度拆分,各 GPU 只更新自己负责的参数切片,最后拼接出完整模型。

效果是每块 GPU 只保留一小部分优化器状态,内存节省很可观。计算量方面,reduce-scatter 加 all-gather 的总通信量与朴素数据并行中的 all-reduce 等价,没有额外开销。

ZeRO Stage 2

ZeRO Stage 2 更进一步——不仅优化器状态分片,梯度本身也要分片。

关键在于反向传播是逐层进行的。每一层的梯度算完后,立刻将不属于自己管辖的部分发送给对应 GPU 并丢弃。不需要在任何时刻存储全部层的完整梯度。

在 ZeRO Stage 1 的流程中,要改变的是这一部分:

改为逐层处理梯度,红框中的部分变成如下流程:

第 2 层的梯度算完,把不负责的部分发出去、丢弃,然后处理第 1 层,重复同样的步骤。层数多的 LLM 从中获益明显——不需要同时存储所有层的梯度。代价是逐层通信带来少量额外开销。

ZeRO Stage 3,也称为完全分片数据并行(FSDP)

ZeRO Stage 3 把分片推到了极致——连模型权重都只存各自负责的那部分。这意味着前向传播也会受到影响。

流程同样是逐层进行的。到第 1 层时,执行 all-gather,各 GPU 各出自己的权重切片,拼出完整的第 1 层。每块 GPU 用完整的第 1 层权重和各自的数据计算激活值,算完后立刻丢弃不属于自己的权重切片。第 2 层同理。

反向传播与 ZeRO Stage 2 类似,但多了一步:每层计算梯度前要先 all-gather 把完整权重拼出来(因为本地没有完整权重),算完后再丢弃非本地切片。

本质上是按需逐层从各 GPU 拼出模型,任何时候都没有一块 GPU 持有全部权重。通信开销增加了,但内存节省巨大。对于给定的 GPU 配置,ZeRO Stage 3 能训练的模型规模远超前两个阶段。

CS336 课程给出的数据:8 块 A100 80GB GPU 上,不同策略可训练的最大模型尺寸差异很大。

同样的硬件配置下,ZeRO Stage 3 能训练的模型大了很多。

不过数据并行有一个约束条件:batch size。batch size 不能小于 GPU 数量:没法给一台机器半个样本。而 batch size 越大收益越低:大 batch 降低数据噪声方差,但超过一定阈值后边际收益接近于零。batch size 的"自然上限"直接限制了数据并行的扩展规模。

模型并行

除了按数据维度拆分,还可以按模型维度切分,即模型并行。这里介绍两种形式:流水线并行和张量并行。

模型并行:流水线并行

流水线并行沿深度方向切分模型,一层分配给一块 GPU。问题在于前向和反向传播都是逐层串行的——每层需要前一层的输出才能开始计算,GPU 在等待输入时空闲,形成"气泡"。

缩小气泡的方法是引入 mini-batch 级别的流水线:第二块 GPU 处理某个 mini-batch 的第二层时,第一块 GPU 可以开始处理下一个 mini-batch 的第一层。

流水线并行的优势在于内存节省,每个设备只存一层的参数以及通信模式简单,只需将激活值从一层传到下一层。这种简单的通信特性使它适合部署在跨集群等带宽较低的网络链路上。

张量并行

张量并行沿宽度方向切分,把单层内的矩阵乘法分配到多块 GPU 上并行执行,各自得到部分结果后再跨 GPU 求和。概念上类似于分块运算,区别在于分块是串行处理各块,张量并行是并发处理。

通信量很大——每层都要同步激活值。节点内部 NVLink 带宽在 600-900 GB/s,跨节点互连慢 10-20 倍。实践经验表明:张量并行扩展到 8 块 GPU 以上时,收益会急剧衰减。所以通常将张量并行限制在单个节点(最多 8 块 GPU)内。

张量并行有一个独特优势:不依赖 batch size。batch size 是数据并行和流水线并行共享的约束资源,张量并行与之正交,可以叠加使用而不消耗这项资源。

组合不同形式的并行

几种并行策略分别沿不同维度拆分计算:数据维度、模型深度维度、模型宽度维度。实际训练中通常是多种策略的组合。

经验法则很简单:先解决内存问题,确保模型能装进 GPU。装不下就用流水线并行、张量并行、ZeRO Stage 3 等节省内存的技术。模型能装下之后,再用数据并行等手段堆算力,加快每个 batch 的处理速度。

附录:Softmax 解释

softmax 将一组原始分数变换为加和为 1 的概率分布:对每个分数取指数,然后除以所有指数之和。

以三个分数(12, 7.2, 9.1)为例:

问题在于指数值增长极快。e¹² 已经是 162,755,超过 fp16 的最大值 65,504。理论值虽然正确,但计算过程中会溢出。解决办法是将分子和分母同时除以 e^(max),等价于从所有原始分数中减去最大值:

数学上结果完全一致,但避免了溢出。可能出现下溢(值太接近零),不过下溢时 0 已经是足够好的近似。这一数学技巧被几乎所有 LLM 的 softmax 实现采用。

总结

这篇文章从 GPU 架构讲到并行策略,涉及的是把模型从玩具规模拉到生产规模所必须面对的工程问题。在专业团队中,训练一个无法放入单块 GPU 的 LLM 是常态,优化训练成本也是日常工作的一部分。理解底层硬件和并行机制,是做好这些工作的前提。

https://avoid.overfit.cn/post/8b2888b82d7c40c3b60e7e8847dafc9f

by Joseph

电缆损坏目标检测数据集(1300张图片已划分、已标注)| AI训练适用于目标检测任务


一、前言

在电力系统的全生命周期管理中,输电电缆承担着核心能量传输任务。一旦发生断裂或雷击损伤,不仅会造成供电中断,还可能引发次生安全事故。传统人工巡检方式存在效率低、响应滞后、误检漏检率高等问题。随着深度学习与计算机视觉技术的成熟,基于目标检测模型的自动化巡检逐渐成为主流方案。

本篇文章将系统介绍一个专注于电缆损坏识别的目标检测数据集,并从数据结构、标注规范、模型适配性、工程落地价值等多个维度进行深入解析,帮助开发者快速完成从数据准备到模型训练的完整闭环。
在这里插入图片描述


数据集下载

链接:https://pan.baidu.com/s/1K1dNdAmQJ0eEEai9lk1Wow?pwd=xjic
提取码:xjic 复制这段内容后打开百度网盘手机App,操作更方便哦

电缆损坏目标检测数据集介绍

本数据集专注于电力系统中电缆损伤的目标检测任务,涵盖了电缆断裂及雷击损伤两类常见故障。数据集共包含 约1300张高质量图像,按训练、验证和测试集划分如下:

训练集(train/images):用于模型训练

验证集(valid/images):用于模型调参和验证

测试集(test/images):用于模型性能评估

数据集包含 2个类别:

断裂(break):反映电缆机械断裂情况

雷击损伤(thunderbolt):记录电缆受到雷击后的损伤痕迹

所有图像均标注了目标的边界框信息,可直接用于目标检测模型(如YOLO系列、Faster R-CNN等)训练与评估。数据集旨在支持电力设备巡检自动化、故障预警及智能维护研究,为电力行业的安全运行和智能化管理提供数据支撑。

二、数据集概述

本数据集面向电力巡检场景下的电缆损伤检测任务构建,聚焦两类典型故障形态:

  • break(断裂):电缆发生机械性断裂、物理破损
  • thunderbolt(雷击损伤):电缆因雷击导致的烧蚀或外皮损伤

数据规模与划分

数据集总规模约 1300 张高质量图像,已完成标准化划分:
在这里插入图片描述

train/images     # 训练集
valid/images     # 验证集
test/images      # 测试集

对应标签目录结构:

train/labels
valid/labels
test/labels

数据采用 YOLO 格式标注,每张图像均包含目标类别与归一化边界框坐标信息,可直接用于主流检测模型训练。

类别配置示例:

nc: 2
names: ['break', 'thunderbolt']

三、行业背景与技术意义

在新型电力系统建设背景下,电网运行的安全性与稳定性已成为能源数字化转型中的核心议题。输电电缆作为电力传输链路中的关键载体,其运行状态直接关系到供电连续性与公共安全。然而在复杂自然环境与长期负载作用下,电缆极易发生机械断裂、外皮破损、绝缘老化及雷击损伤等问题。尤其是在山区、高空或复杂地形区域,传统人工巡检方式不仅效率低下,而且存在较高的安全风险与漏检概率。随着无人机巡检、智能传感与计算机视觉技术的融合发展,基于深度学习的目标检测方法逐渐成为电力设备智能巡检的核心技术路径。

在众多检测框架中,以 Ultralytics 推出的 YOLO 系列模型为代表的单阶段检测算法,以及基于 Meta 研究提出的 Faster R-CNN 等两阶段检测算法,在工业缺陷识别领域表现出良好的泛化能力与部署适配性。它们通过端到端的特征提取与边界框回归机制,实现了对复杂背景下目标的高效识别。电缆损坏目标检测正是在这一技术背景下应运而生:通过构建高质量标注数据集,训练具备鲁棒性的检测模型,从而实现对电缆断裂与雷击损伤等典型故障的自动识别与风险预警。

本文所介绍的数据集围绕电缆损坏检测这一具体工程需求构建,强调场景真实性、类别定义清晰性与标注规范一致性,旨在为科研人员与工程开发者提供一个可直接用于模型训练与性能评估的标准化数据基础。通过系统化的数据组织结构与明确的类别划分,该数据集能够支持从模型验证、参数调优到工程部署的完整流程,推动电力巡检从“人工经验驱动”向“数据与算法驱动”转型。

1. 电缆故障的工程影响

电缆损伤问题在输配电系统中具有以下特征:

  • 隐蔽性强
  • 早期难以人工识别
  • 故障扩展速度快
  • 维修成本高

尤其是雷击损伤,往往表面破坏不明显,但内部绝缘层已遭破坏,极易引发后续击穿风险。

2. AI在电力巡检中的作用

通过引入目标检测算法,可实现:

  • 无人机巡检图像自动识别
  • 实时风险标记
  • 故障定位与统计分析
  • 远程运维决策支持

典型检测模型包括:

  • Ultralytics 发布的 YOLO 系列
  • Meta 提出的 Faster R-CNN
  • Microsoft 研究团队提出的 SSD 等

在小样本工业检测场景中,轻量级模型如 YOLOv5/YOLOv8 往往更具部署优势。


四、数据集详情分析

1. 图像特征

  • 分辨率适中,适合 640×640 或 1024×1024 输入
  • 覆盖不同光照条件
  • 包含复杂背景(山地、塔架、植被等)
  • 目标尺度差异明显

2. 标注质量

  • 边界框贴合目标轮廓
  • 类别定义清晰
  • 无明显漏标或误标
  • 适用于监督式训练
    在这里插入图片描述

3. 类别分布特性

两类目标存在明显视觉差异:

类别特征检测难点
break明显断裂、结构中断细小断口易被背景干扰
thunderbolt局部烧蚀或黑化颜色与阴影易混淆

建议训练时使用数据增强策略:

  • Mosaic
  • 随机裁剪
  • 色彩抖动
  • 随机翻转

五、模型训练建议

1. 推荐训练框架

  • Ultralytics YOLOv8
  • Pytorch 框架下的 Faster R-CNN
  • TensorFlow 目标检测 API

2. 训练参数建议

参数建议值
输入尺寸640
Batch size8~16
Epoch100~200
优化器SGD / AdamW
初始学习率0.01

3. 评估指标

  • mAP@0.5
  • mAP@0.5:0.95
  • Precision
  • Recall

在电力巡检场景中,更建议关注 Recall,降低漏检风险。


六、适用场景

本数据集适用于以下应用方向:

  1. 无人机电力巡检系统
  2. 智慧电网故障预警系统
  3. 输电线路安全评估
  4. 工业视觉检测算法研究
  5. 轻量化模型部署研究

可结合嵌入式设备或边缘计算平台,实现实时检测。


七、工程落地思路

完整落地流程可分为:

  1. 数据预处理
  2. 模型训练
  3. 模型压缩(剪枝/量化)
  4. 边缘部署
  5. 实时监测与告警系统集成

在无人机巡检场景下,可结合:

  • RTSP 视频流
  • 实时推理
  • 缺陷截图自动保存
  • 后端数据库统计分析

八、心得体会

在工业视觉检测场景中,数据质量远比数据规模更重要。虽然本数据集仅 1300 张图像,但由于类别清晰、标注规范,在小目标检测与特征差异明显场景中,依然可以获得较高精度。

实际工程中需要注意:

  • 类别不平衡问题
  • 背景复杂导致的误检
  • 雷击痕迹与阴影混淆
  • 数据增强强度控制

建议采用迁移学习策略,从 COCO 预训练权重微调,可显著提升收敛速度。


九、总结与展望

电缆损伤检测是电力智能巡检体系中的关键环节。通过构建标准化、高质量的目标检测数据集,并结合成熟的深度学习框架,可以显著提升巡检效率与安全保障能力。

未来可拓展方向包括:

  • 增加更多故障类别(绝缘老化、腐蚀等)
  • 引入语义分割任务
  • 融合红外图像数据
  • 多模态检测研究

随着人工智能技术不断成熟,基于视觉的电力设备智能运维将成为行业标准配置。本数据集为相关研究与工程实践提供了坚实的数据基础,也为电力行业智能化升级提供了可复制的技术路径。
在这里插入图片描述

如果你正在进行目标检测研究,或从事电力巡检系统开发,这套数据集将是一个高价值的实验与工程起点。
在这里插入图片描述
总体而言,电缆损坏目标检测数据集虽然规模约为1300张图像,但在工业视觉应用语境下,其价值并不取决于数据量的绝对大小,而在于数据的工程相关性与标注质量的可控性。本数据集围绕“断裂(break)”与“雷击损伤(thunderbolt)”两类高频故障展开构建,类别定义明确,边界框标注规范统一,数据划分合理,具备良好的训练可复现性与实验对比价值。在目标检测任务中,这种结构清晰、问题聚焦的数据集往往比大规模泛场景数据更适合用于工业算法验证与模型优化研究。

从技术实现角度看,该数据集可直接适配基于 Pytorch 或 TensorFlow 构建的检测框架,并可在 Ultralytics YOLOv5/YOLOv8 等轻量化模型上进行迁移学习微调。在工程落地过程中,可结合无人机图像采集、边缘设备实时推理以及后台告警系统,实现“采集—识别—标记—统计—预警”的完整闭环。通过合理的数据增强、类别平衡策略以及精细化超参数调整,即使在中小规模数据条件下,也能够获得具有实际应用价值的检测精度。

更重要的是,这类数据集为电力行业的智能化升级提供了方法论示范:以具体业务问题为中心,构建高质量标注数据,选择适配的检测模型,形成可迭代优化的算法体系。未来若在此基础上扩展更多故障类别、引入多模态图像(如红外成像)或结合时序分析方法,将进一步提升系统对早期隐患的识别能力与预测能力。可以预见,随着深度学习算法与电力巡检业务的持续融合,基于视觉感知的智能运维将逐步成为行业标准配置,而此类专业化数据集正是支撑这一变革的关键基础设施。

前前后后搞了一个多月注册 Apple 开发者账号,每次都是失败。
基本每次流程就是两个错误:第一次说是图像不清晰(其实非常清晰,任何一个字都能清晰看到),再试一次就是未知错误。
发邮件给 Apple 寻求支持,几天一回,按邮件说明的要求试了,还是一样,真心想跪了,求求有经验的
(对了,我是使用 HK id 注册港区开发者)

之前发表的文章分享了一个免费部署在海外vercel的免费服务,上个月就发邮件告诉我,免费额度用光了,之前团队进行AI改革,没空管这个。最近抽时间弄了一下。分享一下如果要在海外做项目,建议前端用vercel + cloudflare的 worker,vercel前期方便,但是一旦有些流量,你会发现超级坑,会不知不觉收到一些天价账单,会有阴影的。

回归正题
之前在其他社区分享的帖子,有网友强烈支持更多平台,最近趁着有空弄了一下,多增加了一个节点来支持小红书视频下载,后续有时间在做更新吧,目前主流的的基本上都有了,其余的看社区反馈,需要支持我抽时间弄一下。

目前支持

  • tiktok视频在线下载
  • 抖音视频在线下载
  • 西瓜视频在线下载
  • youtube视频在线下载
  • twitter(x)视频在线下载
  • 小红书视频在线下载
  • 哔哩哔哩视频下载

节点一
节点二

MySQL是一款由Oracle旗下公司开发的开源关系型数据库管理系统,核心特色包括开源免费、高性能、标准化和高可靠性。它兼容多种编程语言,适用于网站后台数据存储、企业管理系统及数据分析仓库等领域。

一、准备工作

安装包下载:https://pan.quark.cn/s/f165d2901083 ,先下载好 MySQL 9.0 安装包(解压后含 Setup.exe文件),保存到电脑里。

二、安装 MySQL 9.0

  1. 解压安装包

    找到下载的安装包,右键点击 → 选择【解压到当前文件夹】。

  2. 运行安装程序

    打开解压后的文件夹,双击 Setup.exe

  3. 按向导操作

    • 点【Next】→ 勾选“I accept the...”同意协议 → 点【Next】。
    • 选择【Custom(自定义)】安装类型 → 点【Next】。
  4. 修改安装路径(可选)

    • 点【Browse】→ 将路径首字符 C改为 D(如 C:\Program Files\MySQL→ D:\Program Files\MySQL)→ 点【OK】→ 点【Next】。
  5. 开始安装

    点【Install】→ 等待进度条完成(期间可喝口茶~)→ 点【Finish】。

三、配置 MySQL 9.0

  1. 基础配置

    连续点【Next】三次(默认配置即可)。

  2. 设置 root 密码

    • 输入两次相同密码(务必记住!)→ 点【Next】。
  3. 执行配置

    一路点【Next】直到出现【Execute】→ 点【Execute】等待配置完成 → 再点【Next】→ 点【Finish】。

四、创建快捷方式并验证

  1. 创建桌面快捷方式

    • 点击任务栏【开始图标】→【所有应用】→ 展开【MySQL】文件夹 → 将【MySQL 9.0 Command Line Client】拖到桌面。
  2. 启动并验证

    • 双击桌面快捷方式 → 输入步骤 2 设置的密码 → 按【Enter】。
    • 若成功进入命令行界面(显示 mysql>提示符),说明安装配置完成!

我在每个月发工资的时候,会统计所有的投资账户,银行卡余额。
但是这样有个坏处,就是发现这三个月总资产基本没变化。
🫠🫠
投资亏损把工资收入抹平了,瞬间就没动力上班了,一股白干的感觉。。。

redis-6.2.6.tar.gz是 Redis 数据库的 6.2.6 版本源码压缩包。Redis 是一个开源的内存键值数据库,特点是速度快、支持多种数据结构(字符串、哈希、列表、集合等),常用于缓存、会话存储、消息队列等场景。

一、准备编译环境

Redis 6.2.6 需要从源码编译,得先装好编译工具和依赖库。直接一条命令搞定:

sudo yum install gcc make tcl -y
  • gcc:C 语言编译器,必须装。
  • make:编译工具,用来执行 Makefile。
  • tcl:测试 Redis 用的,不装的话 make test会报错。

二、下载并解压安装包

安装包下载:https://pan.quark.cn/s/9e2adfdbc762

下载完解压:

tar -zxvf redis-6.2.6.tar.gz

解压后会多一个 redis-6.2.6文件夹,进去:

cd redis-6.2.6

三、编译源码

在 redis-6.2.6目录下执行编译命令:

make

这一步会花几分钟,等着就行。编译完成后,可以用 make test跑一下测试(可选,但推荐):

make test

测试没问题就可以安装了,默认装到 /usr/local/bin

sudo make install

四、配置 Redis(可选但重要)

Redis 默认配置不适合生产环境,建议改一下配置文件。先把源码目录里的 redis.conf复制到 /etc/redis/

sudo mkdir /etc/redis
sudo cp redis.conf /etc/redis/

然后编辑配置文件:

sudo vi /etc/redis/redis.conf

改这几个地方:

  • daemonize no→ daemonize yes(后台运行)
  • bind 127.0.0.1→ 如果想远程访问,改成 bind 0.0.0.0(或者注释掉这行,但生产环境要配密码)
  • requirepass foobared→ 取消注释,改成自己的密码,比如 requirepass your_password

五、启动 Redis

用配置文件启动 Redis:

redis-server /etc/redis/redis.conf

启动后可以用 ps命令看看进程在不在:

ps -ef | grep redis

能看到 redis-server的进程就说明启动成功了。

六、测试连接

用 redis-cli连上去试试:

redis-cli

如果设置了密码,先认证:

auth your_password

然后随便敲个命令测试,比如:

set test "hello redis"
get test

能正常返回 hello redis就没问题了。

七、常见问题

  1. 编译报错“jemalloc/jemalloc.h: No such file or directory”

    执行 make distclean清理一下,再重新 make

  2. *启动时报“Creating Server TCP listening socket  :6379: bind: Address already in use”

    端口被占用了,用 netstat -tlnp | grep 6379找到占用进程杀掉,或者改配置文件里的 port

  3. 远程连不上

    检查防火墙(sudo firewall-cmd --add-port=6379/tcp --permanent && sudo firewall-cmd --reload),还有配置文件里的 bind和密码是否正确。

这样就完成了 Redis 6.2.6 的安装和配置,适合本地开发或者服务器部署用。

Cisco Secure Firewall Management Center Virtual 7.7.12 - 思科防火墙管理中心 (FMCv)

Firepower Management Center Software for ESXi & KVM

请访问原文链接:https://sysin.org/blog/cisco-fmc-7/ 查看最新版。原创作品,转载请保留出处。

作者主页:sysin.org


Cisco Secure Firewall Management Center

利用单一管理平台掌控全局

实现管理任务的集中化、简化和整合

集中化并简化您的防火墙管理和入侵防御。能够全面监控不断变化的全球网络,您可以实时管理现代应用和恶意软件爆发。

简化日常防火墙任务

Cisco Secure Firewall Management Center (之前称为 Firepower Management Center)

  • 更高可视性,更胸有成竹

    在多项任务之间轻松切换,包括管理数以百计的防火墙、控制应用以及阻止入侵尝试和恶意软件传播。

    Firewall Management Center sysin

  • 广范围实施规则

    编写策略并在网络内的多项安全控制机制中实施该策略。

    Firewall Management Center sysin

  • 简化保护

    对防火墙、应用、入侵防御以及文件和恶意软件防护进行统一管理和控制。

    Firewall Management Center sysin

  • 提供各种外型规格

    利用思科的本地硬件或从您首选的任何虚拟环境全面管理您的防火墙。在您的公有云基础设施上灵活部署相同的管理器,或利用思科的云交付解决方案进一步提高工作效率。

    Firewall Management Center sysin

新增功能

Management Center Features in Version 7.7.12

这是一个维护版本,无新增功能,修复了若干已知问题。

Management Center Features in Version 7.7.11

这是一个维护版本,取代了 7.7.10,无新增功能,修复了若干已知问题。

Management Center Features in Version 7.7.10

来自早期维护版本的功能

版本 7.7.10 还包括:

  • 将部分 Firepower 4100/9300 型号迁移到 Secure Firewall 3100/4200 (7.6.1)
  • 通过代理将 Umbrella 与防火墙管理中心集成 (7.6.1)

通用零信任网络访问(Universal ZTNA)通用零信任网络访问(Universal ZTNA)

通用零信任网络访问(Universal ZTNA)是一套综合解决方案,根据用户身份、信任和姿态提供对内部网络资源的安全访问。它确保对单个应用的访问不会自动授予对整个网络的访问权限(与远程访问 VPN 不同)。

  • 新/修改界面:策略 > 零信任应用(Policies > Zero Trust Application)
  • 要求:需要 Cisco Secure Access 和 Security Cloud Control
  • 部署限制:不支持集群设备、容器实例或透明模式
  • 支持平台:Secure Firewall 1150、3100、4100、4200 以及 Firewall Threat Defense Virtual

Management Center Features in Version 7.7.0

Firewall Management Center Demo

下面仅列出新增功能的摘要描述,限于篇幅,详细描述请参看官方文档。

平台

  • 安全防火墙 1210CP IEEE 802.3bt 支持(PoE++ 和 Hi-PoE)。
  • AWS、Azure 和 GCP 的实例。
  • 使用基于 ISO 的 cloud-init 种子为 VMware 提供无人值守的威胁防御虚拟配置。

平台迁移

  • 从 Firepower 管理中心 4600 迁移到适用于 VMware 的安全防火墙管理中心虚拟 300。

设备管理

  • 恢复配置模式用于紧急设备上配置和管理中心上的带外配置检测。
  • 使用添加到设备的基本初始配置通过注册密钥添加设备(向导)。

接口

  • 同步设备现在是同步接口。

高可用性 / 可扩展性

  • 管理中心高可用性增强。
  • 通过冗余管理器访问数据接口支持威胁防御高可用性。
  • 针对 Azure 群集的威胁防御虚拟进行自动缩放。

VPN:远程访问

  • 基于地理位置的 RA VPN。
  • 轻松配置动态访问策略的姿态评估标准。

路由

  • BGP AS 覆盖。

访问控制:威胁检测和应用程序识别

  • 根据 TLS 版本和服务器证书状态轻松阻止流量。
  • 使用 EVE(加密可视性引擎)轻松绕过与可信 URL 的低风险连接的解密。
  • 新的 EVE(加密可视性引擎)例外。
  • EVE(加密可视性引擎)仪表板增强功能。

事件记录和分析

  • 连接事件中来自 ClientHello 消息的 SNI 信息。
  • 新的连接事件原因 “待定规则匹配”。

健康监测

  • 在服务认证证书过期之前收到警报。
  • 独立配置物理接口和子接口的健康监测。

升级

  • 可以访问互联网的设备从互联网下载升级包。
  • 无需手动检查就绪情况即可升级威胁防御或底盘。
  • 升级管理中心无需手动检查就绪情况。
  • 跳过管理中心的升级后部署。
  • SRU 更新已移出管理中心升级。

管理

  • 取消威胁防御备份,查看详细备份状态。
  • 将管理中心 SAML SSO 登录限制到子域。
  • 清除磁盘空间实用程序。
  • 新的深色主题和主题名称更改。

性能和弹性

  • 更快的故障转移,实现高可用性威胁防御。
  • 安全防火墙 3100/4200 的动态流卸载。
  • 高带宽加密应用程序流量可绕过不必要的入侵检查。
  • 使用 GCP 威胁防御虚拟上的环回接口接收来自 GCP 负载均衡器的健康探测。
  • 使用 FlexConfig 配置威胁防御从块耗尽自动恢复。
  • 安全防火墙 1200 出口整形器。

故障排除

  • CPU 分析器包括应用程序识别统计数据
  • 处理连接事件中的统计信息。
  • 新的 IP 流量统计。
  • Cisco RADKit 集成。

安全和强化

  • Threat Defense CLI Basic 用户的有限用户权限。

已弃用的功能

  • 已弃用:Snort 2。
  • 已弃用:访问控制策略旧接口。

下载地址

Secure Firewall Management Center Virtual Release 7.7.12

请访问:https://sysin.org/blog/cisco-fmc-7/

File InformationFile NameRelease DateSize
Firepower Management Center upgrade Do not untarCisco_Secure_FW_Mgmt_Center_Upgrade-7.7.12-3.sh.REL.tar17-Feb-20261780.14 MB
FMCv300: KVM install packageCisco_Secure_FW_Mgmt_Center_Virtual300_KVM-7.7.12-3.qcow217-Feb-20262595.19 MB
FMCv300: VMware install package for ESXi 6.5, 6.7, 7.0, 8.0Cisco_Secure_FW_Mgmt_Center_Virtual300_VMware-7.7.12-3.tar.gz17-Feb-20262407.17 MB
FMCv: KVM install packageCisco_Secure_FW_Mgmt_Center_Virtual_KVM-7.7.12-3.qcow217-Feb-20262536.50 MB
FMCv: VMware install package for ESXi 6.5, 6.7, 7.0, 8.0Cisco_Secure_FW_Mgmt_Center_Virtual_VMware-7.7.12-3.tar.gz17-Feb-20262404.84 MB

相关产品:


更多:Cisco 产品下载链接汇总

更多:Firewall 产品链接汇总

原文地址 https://feinterview.poetries.top/blog/tailwind-react-native-g...

最近在公司接手了一个React Native项目,打开代码的那一刻我整个人都不好了。上千行的StyleSheet,命名从container1container27,找个样式比找对象还难。更要命的是,改个颜色要翻三个文件,调个间距得祈祷别影响其他页面。那一刻我就在想:2026年了,咱们真的还要这么写样式吗?

后来偶然接触到了Tailwind CSS在React Native上的实现方案twrnc,说实话,刚开始我是拒绝的。又是一个新轮子?学习成本会不会很高?但用了两周之后,我真香了。今天就来聊聊,为什么说Tailwind CSS能重塑React Native的开发效率。

传统React Native样式开发的痛点

先说说传统开发模式到底痛在哪。不吐不快。

样式和组件分离带来的心智负担

在传统的React Native开发中,我们通常会这样写:

import { StyleSheet, View, Text } from 'react-native'


function UserCard({ name, bio }) {
  return (
    <View style={styles.container}>
      <View style={styles.header}>
        <Text style={styles.name}>{name}</Text>
      </View>
      <Text style={styles.bio}>{bio}</Text>
    </View>
  )
}


const styles = StyleSheet.create({
  container: {
    backgroundColor: '#ffffff',
    padding: 16,
    borderRadius: 8,
    marginBottom: 12,
    shadowColor: '#000',
    shadowOffset: { width: 0, height: 2 },
    shadowOpacity: 0.1,
    shadowRadius: 4
  },
  header: {
    marginBottom: 8,
    borderBottomWidth: 1,
    borderBottomColor: '#e5e5e5',
    paddingBottom: 8
  },
  name: {
    fontSize: 18,
    fontWeight: 'bold',
    color: '#333333'
  },
  bio: {
    fontSize: 14,
    color: '#666666',
    lineHeight: 20
  }
})

看起来挺规范的对吧?但问题来了:

  1. 上下反复横跳:写组件的时候要不停地在顶部和底部来回滚动,看看styles.container到底定义了啥。写着写着就忘了自己要改哪个样式。
  2. 命名焦虑症containerwrapperinnercontent......到底该叫啥?每次起名字都要纠结半天。最后项目里出现container2containerNewcontainerFinal这种鬼名字。
  3. 样式复用困难:想复用一个样式?要么把它提取到单独的文件,要么就复制粘贴。提取文件吧,感觉小题大做;复制粘贴吧,后面维护要哭。

响应式设计的噩梦

移动端适配是另一个大坑。假设你要根据屏幕尺寸调整布局:

import { Dimensions, Platform } from 'react-native'


const { width } = Dimensions.get('window')
const isSmallScreen = width < 375


const styles = StyleSheet.create({
  container: {
    padding: isSmallScreen ? 12 : 16,
    fontSize: isSmallScreen ? 14 : 16
  }
  // 还得监听屏幕旋转...
})

这还只是简单的场景。如果要处理横竖屏切换、平板适配,代码量会指数级增长。而且这种动态计算的样式,每次组件重新渲染都得算一遍,性能也是个问题。

主题切换的灾难现场

现在App没个深色模式都不好意思上架。传统方案是这样的:

import { useColorScheme } from 'react-native'


function MyComponent() {
  const colorScheme = useColorScheme()


  const styles = StyleSheet.create({
    container: {
      backgroundColor: colorScheme === 'dark' ? '#1a1a1a' : '#ffffff',
      borderColor: colorScheme === 'dark' ? '#333333' : '#e5e5e5'
    },
    text: {
      color: colorScheme === 'dark' ? '#ffffff' : '#333333'
    }
  })


  return (
    <View style={styles.container}>
      <Text style={styles.text}>Hello</Text>
    </View>
  )
}

看着就头大。每个组件都要这么写,每个颜色都要判断一遍。更恐怖的是,如果产品经理说:"我们要支持自定义主题色,让用户可以选10种颜色",那基本就是重写整个项目的节奏。

团队协作的混乱

多人协作的时候更乱。小王定义了一个#3b82f6的蓝色,小李又定义了一个#2563eb,结果项目里出现了十几种蓝色。想统一?得一个个文件去改。

还有间距问题。有人喜欢用8的倍数,有人喜欢10的倍数,最后整个App看起来参差不齐,强迫症看了想摔手机。

Tailwind CSS + twrnc:一剂良药

说了这么多痛点,那Tailwind CSS是怎么解决这些问题的呢?

Tailwind CSS的核心思想

Tailwind CSS的理念很简单:用原子化的工具类来构建界面。什么是原子化?就是把样式拆成最小的单元,每个类只做一件事。

比如:

  • p-4:padding为16px
  • bg-blue-500:背景色为蓝色
  • rounded-lg:圆角为8px
  • shadow-md:中等阴影

用这些小积木,你可以搭建出任何界面。就像搭乐高一样,每块积木功能单一,但组合起来能创造无限可能。

为什么Tailwind适合React Native

有人会问:Tailwind不是给Web用的吗?确实,Tailwind最初是为Web设计的,但它的思想完美适配移动端开发:

  1. 快速原型:不用起名字,不用来回跳转,看着组件就能写样式
  2. 一致性:设计系统内置,团队自然会用统一的间距和颜色
  3. 响应式:内置断点系统,适配不同屏幕很简单
  4. 主题切换:天生支持,切换主题就是改个配置的事

关键是,有了twrnc这个库,我们可以在React Native中无缝使用Tailwind的语法。

twrnc快速上手:让代码飞起来

安装和基础配置

安装非常简单,一行命令搞定:

yarn add twrnc
// 全局配置
// libs/tailwind.ts
import { create } from 'twrnc'


// create the customized version...
const tw = create(require(`../../tailwind.config.js`)) // <- your path may differ


// ... and then this becomes the main function your app uses
export default tw

然后在项目中引入:

import tw from '@/libs/tailwind.ts'


function MyComponent() {
  return (
    <View style={tw`bg-white p-4 rounded-lg shadow-md mb-3`}>
      <Text style={tw`text-lg font-bold text-gray-800`}>你好,世界</Text>
    </View>
  )
}

就这么简单!不需要任何配置,开箱即用。

实战:重构一个用户卡片组件

让我们用实际例子感受一下差异。这是传统写法和Tailwind写法的对比:

传统写法(30行+):

function UserCard({ avatar, name, role, followers }) {
  return (
    <View style={styles.card}>
      <Image source={{ uri: avatar }} style={styles.avatar} />
      <View style={styles.info}>
        <Text style={styles.name}>{name}</Text>
        <Text style={styles.role}>{role}</Text>
        <View style={styles.stats}>
          <Text style={styles.followers}>{followers} 关注者</Text>
        </View>
      </View>
    </View>
  )
}


const styles = StyleSheet.create({
  card: {
    flexDirection: 'row',
    backgroundColor: '#fff',
    padding: 16,
    borderRadius: 12,
    marginBottom: 12,
    shadowColor: '#000',
    shadowOffset: { width: 0, height: 2 },
    shadowOpacity: 0.1,
    shadowRadius: 8
  },
  avatar: {
    width: 60,
    height: 60,
    borderRadius: 30,
    marginRight: 12
  },
  info: {
    flex: 1,
    justifyContent: 'center'
  },
  name: {
    fontSize: 18,
    fontWeight: '600',
    color: '#1a1a1a',
    marginBottom: 4
  },
  role: {
    fontSize: 14,
    color: '#666',
    marginBottom: 8
  },
  stats: {
    flexDirection: 'row'
  },
  followers: {
    fontSize: 12,
    color: '#999'
  }
})

Tailwind写法(14行):

import tw from 'twrnc'


function UserCard({ avatar, name, role, followers }) {
  return (
    <View style={tw`flex-row bg-white p-4 rounded-xl mb-3 shadow-lg`}>
      <Image source={{ uri: avatar }} style={tw`w-15 h-15 rounded-full mr-3`} />
      <View style={tw`flex-1 justify-center`}>
        <Text style={tw`text-lg font-semibold text-gray-900 mb-1`}>{name}</Text>
        <Text style={tw`text-sm text-gray-600 mb-2`}>{role}</Text>
        <Text style={tw`text-xs text-gray-400`}>{followers} 关注者</Text>
      </View>
    </View>
  )
}

看到没?代码量直接砍半,而且一眼就能看出这个组件长什么样。不用上下翻滚,不用猜styles.info到底定义了啥。

条件样式的优雅处理

真实项目中,样式经常要根据状态变化。twrnc处理起来也很舒服:

function Button({ text, disabled, variant = 'primary' }) {
  return (
    <TouchableOpacity
      style={tw`
        px-6 py-3 rounded-lg
        ${variant === 'primary' ? 'bg-blue-500' : 'bg-gray-500'}
        ${disabled ? 'opacity-50' : 'opacity-100'}
      `}
      disabled={disabled}
    >
      <Text style={tw`text-white font-medium text-center`}>{text}</Text>
    </TouchableOpacity>
  )
}

用模板字符串配合三元运算符,逻辑清晰,改起来也方便。

响应式布局变得简单

twrnc虽然不像Web版Tailwind那样有sm:md:这些前缀,但我们可以用自己的方式实现响应式:

import { useWindowDimensions } from 'react-native'
import tw from 'twrnc'


function ResponsiveGrid({ children }) {
  const { width } = useWindowDimensions()
  const isSmall = width < 375
  const isMedium = width >= 375 && width < 768


  return (
    <View
      style={tw`
      ${isSmall ? 'grid-cols-2' : ''}
      ${isMedium ? 'grid-cols-3' : ''}
      ${width >= 768 ? 'grid-cols-4' : ''}
      gap-4 p-4
    `}
    >
      {children}
    </View>
  )
}

或者更进阶的,可以自定义样式:

import tw from 'twrnc'


// 根据屏幕宽度动态计算
const getResponsiveStyle = (width) => {
  if (width < 375) return tw`p-2 text-sm`
  if (width < 768) return tw`p-4 text-base`
  return tw`p-6 text-lg`
}


function MyComponent() {
  const { width } = useWindowDimensions()


  return (
    <View style={getResponsiveStyle(width)}>
      <Text>响应式内容</Text>
    </View>
  )
}

主题切换:从噩梦到美梦

主题切换是最让人头疼的需求之一,但有了twrnc,这变成了一件轻松的事。

基础的深色模式实现

twrnc内置了对useColorScheme的支持,可以直接用dark:前缀:

import { useColorScheme } from 'react-native'
import tw from 'twrnc'


function ThemedCard() {
  const colorScheme = useColorScheme()


  return (
    <View
      style={tw`
      bg-white dark:bg-gray-800
      border border-gray-200 dark:border-gray-700
      p-4 rounded-lg
    `}
    >
      <Text
        style={tw`
        text-gray-900 dark:text-gray-100
        text-lg font-semibold
      `}
      >
        自动适配的主题
      </Text>
      <Text style={tw`text-gray-600 dark:text-gray-400 mt-2`}>系统切换深色模式时,这里会自动变化</Text>
    </View>
  )
}

但这里有个小技巧。twrnc默认的dark:支持需要手动开启。我们需要配置一下:

// context/themeProvider.tsx
import React, { createContext, useCallback, useContext, useEffect, useMemo } from 'react'
import { useColorScheme } from 'react-native'
import type { ClassInput, RnColorScheme } from 'twrnc'
import { useAppColorScheme, useDeviceContext } from 'twrnc'


import { KEY_DIRECTION, KEY_THEME } from '@/constants'
import { useAsyncStorage } from '@/hooks/useLocalStorage'
import tw from '@/libs/tailwind'
import { lightTheme } from '@/theme/theme.config'
import { darkTheme } from '@/theme/theme.config.dark'


// export type IThemeMode =
//   /** 亮 */
//   | 'light'
//   /** 夜间 */
//   | 'dark'
//   /** 跟随系统 */
//   | 'device'


export type IDirection =
  /** 0绿涨红跌 */
  | 0
  /** 红涨绿跌 */
  | 1


export interface IThemeProps {
  /** 主题变量 */
  theme: {
    /** 主题颜色 */
    colors: typeof lightTheme
    /** 0绿涨红跌 1 红涨绿跌 */
    direction: IDirection
    /** 涨 颜色 */
    up: string
    /** 跌 颜色 */
    down: string
    /** 用戶配置的主题模式 */
    mode: RnColorScheme
    /** 是否是黑色主题 */
    isDark: boolean
    /** 實際在用的主题模式 实际在用的主题模式: mode ?? useColorScheme() */
    colorScheme: RnColorScheme
  }
  /** 设置主题 */
  setMode: (key: RnColorScheme) => void
  /** 切换主题 */
  toggleTheme: () => void
  cn: (...inputs: ClassInput[]) => any
  /** 设置绿涨红跌、红涨绿跌 */
  setDirection: (key: IDirection) => void
}


// 主题上下文
const ThemeContext = createContext<IThemeProps>({} as IThemeProps)


interface iProps {
  children: React.ReactNode
}


export const ThemeProvider = ({ children }: iProps) => {
  // 当前主题
  const [mode, setMode] = useAsyncStorage(KEY_THEME, 'light') as [RnColorScheme, React.Dispatch<React.SetStateAction<RnColorScheme>>]
  const [direction, setDirection] = useAsyncStorage(KEY_DIRECTION, 0) as [IDirection, React.Dispatch<React.SetStateAction<IDirection>>]


  // 要启用需要运行时设备数据的前缀,例如暗模式和屏幕尺寸断点等,您需要将 tw 函数与设备上下文信息的动态源连接。该库导出一个名为 useDeviceContext 的 React hook 来为您处理这个问题。它应该包含在组件层次结构的根部一次
  // <View style={tw`bg-white dark:bg-black`}>
  // 默认情况下,如果您如上所述使用 useDeviceContext() ,您的应用程序将响应设备配色方案中的环境变化(在系统首选项中设置)。如果您希望通过某些应用内机制显式控制应用的配色方案,则需要稍微不同的配置:
  useDeviceContext(tw, {
    // 1️⃣  opt OUT of listening to DEVICE color scheme events
    observeDeviceColorSchemeChanges: false,
    // 2️⃣  and supply an initial color scheme
    initialColorScheme: 'light' // 'light' | 'dark' | 'device'
  })


  // 3️⃣  use the `useAppColorScheme` hook anywhere to get a reference to the current
  // colorscheme, with functions to modify it (triggering re-renders) when you need
  const [colorScheme, toggleColorScheme, setColorScheme] = useAppColorScheme(tw)


  //  4️⃣ use one of the setter functions, like `toggleColorScheme` in your app
  // <TouchableOpacity onPress={toggleColorScheme}>


  const theme = useMemo(() => {
    const colors = colorScheme === 'dark' ? darkTheme : lightTheme
    return {
      colors, // 全部动态主题颜色,根据colorScheme变化
      direction, // 0绿涨红跌 1红涨绿跌
      up: direction === 1 ? colors.red.DEFAULT : colors.green.DEFAULT, // 涨的颜色
      down: direction === 1 ? colors.green.DEFAULT : colors.red.DEFAULT, // 跌的颜色
      mode, // 主题模式
      isDark: mode === 'dark', // 是否暗色模式
      colorScheme
    }
  }, [direction, mode, colorScheme])


  const setTheme = (mode: RnColorScheme) => {
    setMode(mode)
  }


  const nativeColorScheme = useColorScheme()
  useEffect(() => {
    setColorScheme(mode ?? nativeColorScheme)
  }, [nativeColorScheme, mode])


  // 动态设置tailwindcss主题变量
  const cn = useCallback(
    (...inputs: ClassInput[]) => {
      return tw.style(...inputs)
    },
    [colorScheme, tw, theme]
  )


  const values = {
    /** 当前主题的所有配置项 */
    theme,
    cn,
    toggleTheme: () => {
      setTheme(mode === 'light' ? 'dark' : mode === 'dark' ? null : 'light')
    },
    /** 主题模式 */
    setMode: (mode: RnColorScheme) => {
      setTheme(mode)
    },
    /** 红涨绿跌方向 */
    setDirection: (direction: IDirection) => {
      setDirection(direction)
    }
  } as IThemeProps


  return <ThemeContext.Provider value={values}>{children}</ThemeContext.Provider>
}


// 获取主题
export const useTheme = () => useContext(ThemeContext)

自定义主题颜色

更强大的是,我们可以自定义主题配置。创建一个tailwind.config.js

// tailwind.config.js
module.exports = {
  theme: {
    extend: {
      colors: {
        primary: {
          light: '#60a5fa',
          DEFAULT: '#3b82f6',
          dark: '#2563eb'
        },
        secondary: {
          light: '#a78bfa',
          DEFAULT: '#8b5cf6',
          dark: '#7c3aed'
        },
        background: {
          light: '#ffffff',
          dark: '#1a1a1a'
        },
        text: {
          light: '#1f2937',
          dark: '#f9fafb'
        }
      }
    }
  }
}

然后在代码中使用:

// libs/tailwind.ts
import { create } from 'twrnc'


// 加载自定义配置
const tw = create(require(`../../tailwind.config.js`)) // <- your path may differ


// ... and then this becomes the main function your app uses
export default tw
import tw from '@/libs/tailwind'


function CustomThemedButton({ text }) {
  return (
    <TouchableOpacity
      style={tw`
      bg-primary dark:bg-primary-dark
      px-6 py-3 rounded-full
    `}
    >
      <Text
        style={tw`
        text-white dark:text-gray-100
        font-bold text-center
      `}
      >
        {text}
      </Text>
    </TouchableOpacity>
  )
}

实现多主题切换

如果要支持用户自选主题(不只是深浅色),可以结合Context实现:

import React, { createContext, useContext, useState } from 'react'
import tw from 'twrnc'


const ThemeContext = createContext()


const themes = {
  blue: {
    primary: '#3b82f6',
    secondary: '#8b5cf6',
    accent: '#06b6d4'
  },
  green: {
    primary: '#10b981',
    secondary: '#059669',
    accent: '#14b8a6'
  },
  purple: {
    primary: '#a855f7',
    secondary: '#9333ea',
    accent: '#c084fc'
  }
}


export function ThemeProvider({ children }) {
  const [currentTheme, setCurrentTheme] = useState('blue')


  const theme = themes[currentTheme]


  return <ThemeContext.Provider value={{ theme, setCurrentTheme, currentTheme }}>{children}</ThemeContext.Provider>
}


export function useTheme() {
  return useContext(ThemeContext)
}


// 使用
function ThemedComponent() {
  const { theme, setCurrentTheme, currentTheme } = useTheme()


  return (
    <View style={tw`flex-1 p-4`}>
      <View style={[tw`p-4 rounded-lg`, { backgroundColor: theme.primary }]}>
        <Text style={tw`text-white text-lg font-bold`}>当前主题:{currentTheme}</Text>
      </View>


      <View style={tw`flex-row gap-2 mt-4`}>
        {Object.keys(themes).map((themeName) => (
          <TouchableOpacity
            key={themeName}
            style={[tw`px-4 py-2 rounded-full`, { backgroundColor: themes[themeName].primary }]}
            onPress={() => setCurrentTheme(themeName)}
          >
            <Text style={tw`text-white`}>{themeName}</Text>
          </TouchableOpacity>
        ))}
      </View>
    </View>
  )
}

这样就实现了灵活的多主题切换,而且代码结构清晰,维护起来也方便。

深入浅出:twrnc的核心原理

讲了这么多用法,咱们来聊聊twrnc到底是怎么工作的。理解原理之后,用起来会更有底气。

Tailwind类名到RN样式的转换

twrnc的核心任务就是把Tailwind的类名转成React Native能理解的样式对象。比如:

'bg-blue-500 p-4 rounded-lg'

要转换成:

{
  backgroundColor: '#3b82f6',
  padding: 16,
  borderRadius: 8,
}

这个转换过程是怎么实现的呢?

第一步:解析类名

twrnc会把字符串按空格分割,得到一个类名数组:

const classNames = 'bg-blue-500 p-4 rounded-lg'.split(/\s+/)
// ['bg-blue-500', 'p-4', 'rounded-lg']

第二步:查表转换

twrnc内部维护了一个映射表,把每个Tailwind类对应到RN的样式:

const styleMap = {
  'bg-blue-500': { backgroundColor: '#3b82f6' },
  'p-4': { padding: 16 },
  'rounded-lg': { borderRadius: 8 }
  // 还有几千个...
}

实际上这个映射表是动态生成的,不是写死的。twrnc会根据类名的模式来计算对应的样式值。

第三步:合并样式

最后把所有样式对象合并成一个:

const finalStyle = Object.assign({}, styleMap['bg-blue-500'], styleMap['p-4'], styleMap['rounded-lg'])

样式缓存机制

你可能会担心:每次渲染都要解析类名,性能会不会有问题?

twrnc的作者想到了这一点,内部实现了缓存机制。第一次遇到某个类名组合时,会解析并缓存结果。后续再遇到相同的类名,直接返回缓存的样式对象。

// 简化版的缓存逻辑
const cache = new Map()


function tw(classNames) {
  // 检查缓存
  if (cache.has(classNames)) {
    return cache.get(classNames)
  }


  // 解析样式
  const style = parseClassNames(classNames)


  // 存入缓存
  cache.set(classNames, style)


  return style
}

这样的设计保证了性能。即使在列表中渲染几百个item,每个item使用相同的类名,也只需要解析一次。

响应式和条件样式的处理

对于条件样式,比如:

tw`bg-white ${isActive ? 'bg-blue-500' : 'bg-gray-200'}`

twrnc会先计算出完整的类名字符串,然后再解析。这是利用了JavaScript模板字符串的特性。

但这里有个小细节:因为条件可能变化,所以这类样式的缓存key会包含动态部分。twrnc会智能地判断哪些部分是静态的(可以缓存),哪些是动态的(需要重新计算)。

自定义配置的实现

当你提供tailwind.config.js时,twrnc会读取这个配置并生成对应的映射表。比如你定义了:

colors: {
  brand: '#ff6b6b',
}

twrnc会自动生成:

  • bg-brand: { backgroundColor: '#ff6b6b' }
  • text-brand: { color: '#ff6b6b' }
  • border-brand: { borderColor: '#ff6b6b' }

甚至还会生成不同透明度的变体:

  • bg-brand/50: { backgroundColor: 'rgba(255, 107, 107, 0.5)' }

这些都是在库初始化时预计算好的,不会影响运行时性能。

单位转换的小秘密

Web端的Tailwind使用rem和px,但React Native只支持数字(代表dp/pt)。twrnc是怎么处理的?

它有一套单位转换规则:

  • p-4:padding为 4 * 4 = 16(默认1单位=4dp)
  • text-base:fontSize为16
  • w-1/2:width为'50%'

你也可以自定义这个比例:

tw.config = {
  theme: {
    spacing: {
      1: 8, // 现在1单位=8dp
      2: 16
      // ...
    }
  }
}

最佳实践和踩坑指南

用了一段时间twrnc,也踩了不少坑。分享一些经验。

保持类名简洁

虽然Tailwind让我们可以在标签里写很多类,但不要滥用。如果一个组件的类名超过10个,就该考虑拆分组件或者提取样式了。

不好的做法:

<View style={tw`flex-row items-center justify-between bg-white p-4 mx-4 my-2 rounded-xl shadow-lg border border-gray-200 w-full`}>

好的做法:

const cardStyle = tw`flex-row items-center justify-between bg-white p-4 mx-4 my-2 rounded-xl shadow-lg border border-gray-200`;


<View style={cardStyle}>

或者更好的,拆分成子组件。

性能优化技巧

虽然twrnc有缓存,但在长列表中还是要注意:

// 不好:每次渲染都创建新对象
function ListItem({ item }) {
  return <View style={tw`p-4 ${item.isActive ? 'bg-blue-500' : 'bg-white'}`}>{/* ... */}</View>
}


// 好:预定义样式
const baseStyle = tw`p-4`
const activeStyle = tw`p-4 bg-blue-500`
const inactiveStyle = tw`p-4 bg-white`


function ListItem({ item }) {
  return <View style={item.isActive ? activeStyle : inactiveStyle}>{/* ... */}</View>
}

与第三方库的配合

有些第三方库(比如react-native-paper)有自己的样式系统。可以混用:

import { Button } from 'react-native-paper'
import tw from 'twrnc'
;<Button
  mode="contained"
  style={tw`mt-4`} // twrnc处理外边距
  contentStyle={tw`py-2`} // 内部样式
>
  点击我
</Button>

类型安全(如果用TypeScript)

twrnc支持TypeScript,但智能提示有限。可以结合一些类型定义来增强体验:

import tw from 'twrnc';


type TailwindStyle = ReturnType<typeof tw>;


interface CardProps {
  style?: TailwindStyle;
  children: React.ReactNode;
}


function Card({ style, children }: CardProps) {
  return (
    <View style={[tw`bg-white p-4 rounded-lg`, style]}>
      {children}
    </View>
  );
}

总结:开发效率的质变

回顾这一路,从传统的StyleSheet到Tailwind+twrnc,这不仅仅是工具的升级,更是开发思维的转变。

我们获得了什么

1. 开发速度的提升 不用再纠结命名,不用来回跳转文件,组件和样式融为一体。原来要半小时的界面,现在10分钟就能搞定。而且改起来更快,不用担心牵一发动全身。

2. 代码质量的改善 样式一致性自然就有了,因为大家用的是同一套工具类。团队新人上手也快,看看别人怎么写,照着写就行。代码审查的时候,样式问题也少了很多。

3. 维护成本的降低 想改个颜色?搜索替换就行。想调整间距?批量改类名。主题切换?加个dark:前缀就完事。再也不用在上千行的StyleSheet里找bug了。

还有哪些局限

当然,twrnc不是银弹,也有一些局限:

  • 学习成本:团队成员需要熟悉Tailwind的类名,刚开始可能要查文档
  • 样式复杂度:某些特别复杂的样式(比如复杂动画),还是得用StyleSheet
  • 包体积:虽然不大,但毕竟是额外的依赖

但这些问题相比带来的好处,都可以接受。

给初学者的建议

如果你还在犹豫要不要尝试,我的建议是:

  1. 新项目直接上:别犹豫,直接用twrnc开发,你会爱上这种感觉
  2. 老项目渐进式迁移:别一口气重写,从新页面开始,慢慢替换
  3. 保持开放心态:一开始可能不习惯,但坚持两周,你就回不去了

最后

写样式本应该是一件快乐的事,而不是折磨。Tailwind CSS和twrnc让我们重新找回了这种快乐。不用为命名发愁,不用为主题切换头疼,不用为团队协作吵架。

2026年了,是时候告别那些让我们抓狂的样式写法了。用twrnc,让代码更简洁,让开发更高效,让自己更快乐。

凌晨两点,谁还在帮你盯数据?

场景一:DDL变更中的惊魂时刻

周三凌晨两点,你正在执行一个关键的DDL变更——给orders表加一个索引。这是和业务方约好的维护窗口,必须在这个时间点完成。

突然,手机震动。一条短信告警:「prod-mysql-01 磁盘使用率 92%,预计30分钟内写满」。

你陷入两难:DDL变更不能中断,但磁盘告警又不能不管。你一边盯着变更进度条,一边手忙脚乱地登录跳板机,敲命令查慢查询日志、找大文件、确认空间释放……

DDL终于跑完了,磁盘危机也暂时解除。但你用了四十分钟才重新睡着。

场景二:被告警吵醒的夜晚

另一个周三凌晨,你被一条告警短信吵醒——某业务库磁盘即将写满。

你揉着眼睛打开电脑,登录跳板机,敲了一串命令清理慢查询日志,顺手跑了个 df -h 确认空间释放,然后在群里回了句"已处理"。

整个过程不到十分钟,但你用了四十分钟才重新睡着。

如果你是 DBA、后端开发、或者带数据的技术负责人,这些场景一定不陌生:不是操作有多难,而是它总在不该出现的时候出现,一次又一次地消耗你的注意力。

现在,这些事可以安排给你的7*24小时助理来完成。

DMS OpenClaw:你的专属数据助理

阿里云 DMS(数据管理服务)上推出了 OpenClaw 托管版,内置 DMS 数据管理、安全、审计、Meta Agent、DAS Agent 等多项 Skills,一个不只会聊天的 AI 数据助理。它不是那种"帮你写个 SQL 就完事"的工具——它能真正替你干活:提工单、跑变更、做审批预审、定时巡检、盯盘盯变更,甚至在一个需求里自动串联查询、订正、验证等多步操作,跨库跨集群都行。

简单说,它是一个能 7×24 值守的数据操作员,而你是它的老板。

先看一个真实场景

你在群里说了句:"把 orders 表里 3 月之前 pending 的订单全部改成 cancelled"

OpenClaw 接到指令后,自动完成了这些事:

  1. 识别目标库表 —— prod-mysql-01 / orders_prod.orders,生成对应的 UPDATE 语句
  2. 预估影响 —— 2,341 行,自动生成回滚方案
  3. 创建变更工单 —— #4825 已提交审批你只需要点一下"确认"。

但更厉害的是,如果你补一句"改完后查一下确认没有遗漏",它会自动把这个需求拆成三步——先改、再查、最后验证,全部串联执行,完成后把结果推送到你的钉钉/飞书。

这就是 OpenClaw 的多任务编排能力:你描述最终目标,它自动拆解执行路径。

再看一个更"安静"的场景

你给 OpenClaw 设了一个心跳任务:

"每天早上 9 点,检查所有生产库的连接数、慢查询 Top10、磁盘使用率和主从延迟,生成日报推送到钉钉群"

从那天起,你每天到工位时,钉钉里已经躺好了一份数据健康日报。哪个实例连接数逼近上限、哪条慢查询昨晚又飙了、哪台从库延迟超过阈值——一目了然。

而当某项指标真的异常时,OpenClaw 不只是报个数字,它会同时给出诊断建议:是该加索引、该清理连接池、还是该扩容。

你不再需要每天花半小时手动巡检,也不用担心某个隐患在周末悄悄恶化。OpenClaw 不只是在你叫它的时候干活,它能自己主动替你看着。

九项硬功能,不是花活

DMS OpenClaw 内置 DMS 数据管理、安全、审计、Meta Agent、DAS Agent 等多项 Skills,覆盖了数据管理的完整生命周期,每一项都是实打实省时间的能力:

  • 自然语言提工单 — 不用再填复杂表单,用一句话描述变更需求,AI 自动生成 SQL、填写字段、提交审批。
  • 智能数据查询与分析 — 用自然语言描述查询意图,支持多轮追问,还能直接生成可视化报表。
  • 多任务编排 — 一句话串联查询→订正→验证→通知的完整工作流,跨库跨集群。
  • 审批智能预审 — 自动评估 SQL 风险等级、影响范围和回滚方案,让审批人秒级决策。
  • SQL 任务托管 — 长时间运行的任务交给 AI 全程监控,异常自动诊断重试,完成后主动通知。
  • 定时巡检与主动汇报 — 每天自动检查慢查询、索引健康度、磁盘容量,发现异常直接推送到 IM。
  • 文档智能处理 — 自动生成变更报告、数据字典、巡检日志,也能理解需求文档并转化为数据库操作。
  • 智能运维报告 — 融合 DMS Meta Agent Skill(业务语义理解)与 DAS Agent Skill(慢 SQL 深度诊断),让运维报告说"人话"。不再只告诉你"某条 SQL 耗时 12 秒",而是直接说清"这是下单时的库存校验查询,高峰期每秒 800 次,导致支付链路延迟上升 40%"。讲业务影响,业务方才愿意配合优化。
  • 深度分析洞察 — DMS Meta Agent Skill 理解库表和业务语义,Data Agent Skill 用自然语言驱动数据分析,两者协同让洞察结果直达根因。问"最近一周 GMV 为什么下降",它不只给折线图,而是关联到取消率异常和某地区物流超时激增,一步到位。

    还有更多数据相关Skills和场景等你来探索!

    安全这件事,我们没有妥协

你可能会想:让 AI 碰生产库,安全怎么保证?

答案是:DMS 多年沉淀的安全管控体系在 OpenClaw 下完整生效。 细粒度权限控制、敏感列自动脱敏、操作审计、高危变更拦截——AI 不会绕过任何一条安全规则,你授权什么它才能碰什么。

更重要的是,所有数据查询结果、工单内容、巡检报告均在本地存储和处理,AI 模型调用仅传输必要的指令上下文,不会上传你的业务数据到云端。

几分钟上手,零成本

体验配置通知渠道(钉钉/飞书)→ 填入凭证授权访问 → 选装你需要的 Skills → 开始使用。就这么简单。DMS 数据技能开箱即用,你也可以按需安装更多社区技能来扩展能力。而且——公测期间,免费体验。与其在凌晨两点被告警叫醒,不如让 OpenClaw 替你值这个班。

让重复劳动交给 AI,把时间留给真正重要的事。

免费体验 DMS OpenClaw

欢迎扫码加入微信群或钉钉群申请免费试用

加入微信交流群


加入钉钉交流群

因为使用到 macbook 的 ai 功能,用了 clash 做分流,clash 分流规则如下:
rules:
- 'DOMAIN-SUFFIX,apple-relay.akamaized.net,AKY-JAPAN'
- 'DOMAIN-SUFFIX,synology.com,DIRECT'
- 'DOMAIN-SUFFIX,synology.me,DIRECT'
- 'DOMAIN-SUFFIX,apple-relay.apple.com,AKY-JAPAN'
- 'DOMAIN-SUFFIX,apple-relay.cloudflare.com,AKY-JAPAN'
- 'DOMAIN-SUFFIX,apple-relay.fastly-edge.com,AKY-JAPAN'
- 'DOMAIN-SUFFIX,apple-relay.mask.apple-dns.net,AKY-JAPAN'
- 'DOMAIN-SUFFIX,cp4.cloudflare.com,AKY-JAPAN'
- 'DOMAIN-SUFFIX,gspe1-ssl.ls.apple.com,AKY-JAPAN'
- 'DOMAIN-SUFFIX,guzzoni.apple.com,AKY-JAPAN'
- 'DOMAIN-SUFFIX,guzzoni.smoot.apple.com,AKY-JAPAN'
- 'DOMAIN-SUFFIX,smoot.apple.com,AKY-JAPAN'
- 'DOMAIN,apple-relay.apple.com,AKY-JAPAN'
- 'DOMAIN,apple-relay.cloudflare.com,AKY-JAPAN'
- 'DOMAIN,apple-relay.fastly-edge.com,AKY-JAPAN'


我开启了规则模式之后,去 appstore 下载软件,点击获取之后一直转圈,关闭 clash 之后才正常,猜测是某条规则分流的问题?

2011 年就来北京了,到今年已经 15 年了,依然没有北京的房产、车牌和户口

2011 年住单位的合租房,三居的房子住十几个人,虽然那会收入不高,感觉挺有奔头,但是不知道能在北京待多久,没想着在北京买房。

后来认识我现在的老婆,结婚、跳槽、生娃、养娃,娃上学,逐渐稳定下来了,生活开始变成两点一线。

刚工作的那几年收入比较低,北京郊区的房价不算高,北七家好像只有 2 万,没远见,为了娶媳妇在老家买了一套二居房子,期间经历过跌涨,在房子最高位的时候没出手,现在基本上回到了买房时候的价格

17 年有资格摇号了,那会电动车发展比较初期,没什么好车,同事劝我换电标,我心想我刚摇上就换,还是想搞一辆油车,结果摇了 8 年没中,25 年换成电标,毕竟电标还有个盼头。即使排到 10 年后我主要一直在北京有社保就能拿到。

18 年的时候跟风和大家去天津买房置业,那几年刚把老家的房贷还完,又继续贷款买房,期间老婆怀孕、放弃工作带娃,我一个人在北京挣钱养家,过着双城生活,那段时间生活太拮据了,我们俩 5 年没出去旅过游,一直到 24 年吧全部贷款还清,才如释重负了,这时候孩子也大了,靠着公租房和居住证我们上了北京公立的幼儿园和小学,但是最终还得的回到天津高考。

2025 年想把天津的房子出手,此时天津的房子已经腰斩,我这 7 年的收入全部打了水飘,房子卖了亏的多,不卖出租和自住。

今天看着抖音上一个小姑娘辞去了北京的工作,回昆明老家的视频颇有感慨,设想自己当年要是也回到那个四线城市的老家,生活会怎么样,比现在过得好还是差?如果过几年全家都去天津又将如何生活。

中国这么大。为什么只有北京这么不接纳外籍人员,住房、上学、就医、行使都要限制的死死的,一点点的把外籍人员赶出北京。有时候很羡慕那些放弃北上广大厂丰厚待遇的年轻人,他们回到小城市眼睛里是有光的,而我们这些牛马整天就是在拉磨,转到什么时候才能过上正常人的生活呢

以下四个词每天练五遍 :
1.班干部管班干部
2.榴莲牛奶
3.粉红凤凰
4.出租车司机

这 4 组是针对性解决普通话高频发音难点(n/l 不分、f/h 不分、平翘舌混淆、塞音切换不稳)的经典绕口令,也是告别嘴瓢的入门黄金素材。

全文链接:https://tecdat.cn/?p=45116
原文出处:拓端数据部落公众号
封面

关于分析师

在此对Pin Vi对本文所作的贡献表示诚挚感谢,她是一名热衷于数据科学和机器学习的爱好者,拥有扎实的数据分析、机器学习算法和编程基础。她有建模、管理混乱数据和解决现实问题的实践经验。她的目标是运用数据驱动的洞察,创造能够带来成果的切实可行的解决方案。她渴望在协作环境中贡献技能,同时继续在数据科学、机器学习和自然语言处理领域学习和成长。

    • *

引言

作为一名分析师,我经常面对企业客户这样的困惑:“我们拥有海量数据,却很难快速从中提取 actionable insights。” 传统的数据分析流程往往需要人工编写SQL、手动绘制图表,效率低下且容易出错。而在谷歌开发团队与高校实验室的交叉实践中,我们发现:群体智能(Swarm Intelligence) 的协作模式可以完美解决这一痛点——让多个AI代理像蚁群一样分工协作,各自发挥专长,最终输出高质量的分析结果。

本文内容改编自过往客户咨询项目的技术沉淀并且已通过实际业务校验,该项目完整代码与数据已分享至交流社群。阅读原文进群获取更多最新AI见解和行业洞察,可与900+行业人士交流成长;还提供人工答疑,拆解核心原理、代码逻辑与业务适配思路,帮大家既懂“怎么做”,也懂“为什么这么做”;遇代码运行问题,更能享24小时调试支持。

本文将带领读者从零构建一个基于 LangGraph Swarm 的多智能体系统,其中包含两个核心代理:

  • 数据分析代理:将自然语言查询转换为SQL,从银行数据库中提取数据。
  • 数据可视化代理:将分析结果转化为业务级图表,并给出可解释的洞察。

通过一个银行客户分层分析的端到端案例,我们将展示群体代理如何以去中心化、角色专精的方式协同工作,最终输出可直接用于决策的图表与结论。全文脉络如下:

用户查询
   ↓
协调代理(入口)
   ↓
数据分析代理(Text-to-SQL)
   ↓
数据可视化代理(EDA绘图)
   ↓
结果输出(图表+洞察)
    • *

1. 群体智能代理概述

1.1 什么是群体代理?

群体代理(Swarm Agents)是指一组自治的AI实体,每个实体执行特定的子任务,并通过结构化通信共同完成复杂目标。这种设计模仿了自然界中的蚁群或蜂群:没有中央指挥官,但个体通过简单规则和局部信息交互,涌现出全局智能。

在数据分析场景中,我们可以将任务拆分为“数据获取”、“数据清洗”、“统计分析”、“可视化”等多个环节,每个环节由一个专门的代理负责。代理之间通过预定义的切换工具(handoff tools)传递上下文,从而实现流水线式的协作。

1.2 核心设计原则

成功的群体代理系统通常遵循以下原则:

  • 去中心化决策:每个代理独立运行,没有单一故障点。代理之间通过消息共享信息,实现灵活的任务分配。
  • 角色专精:每个代理只关注自己擅长的领域,例如数据分析代理只处理SQL查询,可视化代理只负责绘图。职责清晰可提高效率。
  • 结构化通信:代理之间通过标准化的切换工具进行交互,共享上下文(如查询语句、中间结果),确保信息一致。
  • 容错与可扩展:工作负载分散在多个代理上,单个代理失效不影响整体流程。新增代理只需定义其角色和通信方式即可。
    • *

2. 系统架构设计

2.1 代理角色与职责

本系统包含两个核心代理和一个隐式协调者(由LangGraph Swarm框架自动管理):

  • 数据分析代理(Data Analyst Agent)
    职责:接收用户查询,解析为SQL语句,从数据库中提取数据,并返回结构化结果(如表格)。
    工具:SQL数据库工具包(SQLDatabaseToolkit),包含查询数据库、获取表结构等函数。
  • 数据可视化代理(EDA Visualizer Agent)
    职责:接收分析结果,选择合适的图表类型(如条形图、折线图),使用Python绘图库生成图表,并附带业务洞察。
    工具:Python REPL工具,用于执行绘图代码。
  • 协调代理(Orchestrator)
    由LangGraph Swarm内置,负责根据用户查询激活合适的代理,并在代理之间传递上下文。它相当于一个智能路由器。

2.2 数据流与协作机制

代理之间的协作通过切换工具(handoff tools)实现。当一个代理完成其任务后,可以主动调用切换工具,将控制权转交给另一个代理。整个数据流如下:

  1. 用户提交查询(例如:“按省份统计客户数,并绘制条形图”)。
  2. 协调代理启动,默认激活数据分析代理。
  3. 数据分析代理解析查询,执行SQL,返回结果表格。
  4. 数据分析代理调用切换工具,将结果传递给可视化代理。
  5. 可视化代理读取结果,生成图表并输出。
  6. 如有需要,可视化代理可再次切换回数据分析代理进行更深层次分析。

这种动态切换机制使得系统能够处理多轮迭代查询。

    • *
    • *

相关文章(后面要换一行)

DeepSeek、LangGraph和Python融合LSTM、RF、XGBoost、LR多模型预测NFLX股票涨跌|附完整代码数据

原文链接:https://tecdat.cn/?p=44060

    • *

3. 基于LangGraph Swarm的实现

3.1 环境配置与依赖

首先安装所需Python库。我们使用LangChain生态的LangGraph Swarm模块来构建多代理系统。

pip install langchain==1.2.4 \
            langgraph==1.0.6 \
            langgraph-swarm \
            langchain-openai==1.1.4 \
            langchain-community==0.4.1 \
            langchain-experimental==0.4.0

此外需要SQLite支持(本例使用本地银行数据库banking_insights.db)。

# 导入必要模块
from langchain_openai import ChatOpenAI
from langgraph_swarm import create_swarm, create_handoff_tool, SwarmState
from langgraph.checkpoint.memory import MemorySaver
from langchain_community.utilities import SQLDatabase
from langchain_community.agent_toolkits import SQLDatabaseToolkit
from langchain_experimental.utilities import PythonREPL
# 初始化大语言模型
model = ChatOpenAI(model="gpt-4.1-mini", temperature=0)
# 连接数据库
database = SQLDatabase.from_uri("sqlite:///banking_insights.db")
# 创建SQL工具包
sql_tools_kit = SQLDatabaseToolkit(db=database, llm=model)
sql_tools = sql_tools_kit.get_tools()

3.2 代理提示词设计

每个代理需要明确的系统提示词来限定其行为。

# 数据分析代理提示词
DATA_ANALYST_PROMPT = """
你是一位数据分析专家,精通零售银行业务的SQL查询。
你的主要任务:
- 将用户的问题转换为正确的SQL语句
- 从数据库中准确提取数据
- 提供简洁的事实性摘要
- 当需要可视化时,将结果交给EDA可视化代理
"""
# 可视化代理提示词
EDA_VISUALIZER_PROMPT = """
你是一位EDA可视化专家,擅长数据分析和图表绘制。
你的职责:
- 创建清晰、业务就绪的图表
- 使用Python进行绘图
- 返回支持决策的可视化洞察
"""

3.3 切换工具与代理创建

代理之间通过切换工具进行通信。

现在创建两个代理实例。

获取完整代码请阅读原文加入社群。

3.4 构建群体工作流

使用create_swarm将两个代理组合成群体,并指定默认激活代理。

最后定义一个执行函数作为对外接口。

    • *

4. 银行数据分析案例

4.1 查询执行与结果

我们用一个典型的多层下钻查询来测试系统:从省份维度开始,逐层深入到支行和账户类型,统计账户数量。

执行过程中,代理会自动完成SQL编写、数据提取和图表绘制。以下是部分输出摘要:

获取完整代码请阅读原文加入社群。

4.2 可视化输出与解读

可视化代理生成了分组条形图,展示了各省份、支行、账户类型的账户数量分布。

可视化代理进一步提供了业务洞察:

......

获取完整代码请阅读原文加入社群。

5. 结论与展望

本文展示了如何利用LangGraph Swarm框架构建一个由数据分析代理和可视化代理组成的群体智能系统。通过将复杂查询拆解为SQL提取与图表绘制两个子任务,并让专业代理各司其职,系统实现了:

  • 自动化端到端分析:从自然语言到业务图表,全程无需人工干预。
  • 可解释性:代理生成的图表附带文字洞察,帮助用户理解数据背后的含义。
  • 可扩展性:未来可加入更多代理,如数据清洗代理、异常检测代理等,进一步增强系统能力。

这一模式已在多个咨询项目中验证其有效性,特别适合需要快速响应、多维度下钻的数据分析场景。随着大语言模型能力的不断提升,群体智能代理将成为企业数据决策的核心引擎。

封面

    • *

数据集成是企业数据治理的核心环节。面对市场上琳琅满目的ETL工具,技术决策者常常陷入两难:选择开源工具担心技术支持不足,选择商业产品又面临高昂的成本压力。本文将从功能完备性、易用性、性能、成本、技术支持等维度,对当前主流的ETL工具进行深度横向评测。

一、评测对象与评测维度

本次评测选取了市场上最具代表性的六款ETL工具:

0d029813-9de0-472f-ad3b-7fb7474b0b35.png

评测维度说明

  • 功能完备性:离线ETL、实时CDC、调度编排、数据服务API等核心能力
  • 易用性:学习曲线、可视化程度、操作便捷性
  • 性能表现:数据处理吞吐量、资源消耗、稳定性
  • 成本结构:软件授权费、实施成本、运维成本
  • 技术支持:文档质量、社区活跃度、厂商响应速度

二、逐个深度评测

1.Kettle (Pentaho Data Integration)

Kettle是Pentaho旗下的开源ETL工具,在国内拥有广泛的用户基础。其最大的优势在于完全免费开源,社区资源丰富,适合预算有限的中小企业。

优势:

  • 完全免费,无授权成本
  • 插件生态丰富,扩展性强
  • 社区活跃,问题容易找到解决方案
  • 支持多种数据源,通用性好

劣势:

  • 性能瓶颈明显,大数据量处理吃力
  • 实时数据同步能力弱,缺乏原生CDC
  • 界面相对陈旧,用户体验一般
  • 无官方技术支持,问题解决依赖社区
  • 集群部署复杂,企业级特性缺失

适用场景:中小规模数据处理、预算有限的项目、对实时性要求不高的场景。

2.DataX

DataX是阿里巴巴开源的异构数据源同步工具,以其高性能著称。作为DataWorks的数据同步核心引擎,DataX在离线批量数据同步场景表现优异。

优势:

  • 单机性能优异,千万级数据秒级完成
  • 架构简洁,配置化程度高
  • 支持主流关系型数据库和大数据生态
  • 阿里背书,技术可靠性有保障

劣势:

  • 仅支持离线同步,无实时CDC能力
  • 无可视化界面,完全依赖JSON配置
  • 缺乏调度编排能力,需搭配其他工具
  • 学习曲线陡峭,对技术人员要求高
  • 社区维护不够活跃,问题解决周期长

适用场景:大批量离线数据迁移、数据仓库加载、有较强技术能力的团队。

3.Informatica PowerCenter

Informatica是全球数据集成领域的领导者,PowerCenter是其旗舰产品。作为企业级ETL标杆,Informatica在金融、电信等行业拥有极高的市场占有率。

优势:

  • 功能最完备,覆盖ETL全生命周期
  • 性能强大,支持PB级数据处理
  • 企业级特性完善(元数据管理、数据质量、血缘分析)
  • 全球化技术支持体系成熟
  • 行业最佳实践丰富

劣势:

  • 授权费用极其高昂,百万级起步
  • 实施周期长,项目成本居高不下
  • 国产化替代背景下,供应链风险凸显
  • 技术架构相对传统,云原生支持有限
  • 本地化服务响应不够及时

适用场景:大型金融机构、跨国企业、对数据治理有极高要求的组织。

4.IBM DataStage

DataStage是IBM InfoSphere平台的核心组件,在大型企业数据仓库建设中应用广泛。其与IBM产品生态的深度集成是其主要卖点。

优势:

  • 并行处理能力强大
  • 与IBM数据库、BI工具无缝集成
  • 企业级稳定性和可靠性
  • 复杂转换逻辑支持能力强

劣势:

  • 成本高昂,不仅软件贵,硬件要求也高
  • 学习曲线极陡,专业人才稀缺
  • 配置部署复杂,运维成本高
  • 同样面临国产化替代压力

适用场景:IBM生态用户、大型数据仓库项目、对并行处理有极致要求的场景。

5.FineDataLink (帆软FDL)

FineDataLink是帆软推出的数据集成产品,主打与帆软BI产品的联动优势。对于已使用帆软BI的企业,FDL是一个自然的选择。

优势:

  • 与帆软BI无缝集成
  • 界面友好,上手门槛低
  • 本土化服务响应及时
  • 价格相对国际厂商有优势

劣势:

  • 产品成熟度有待提升
  • 大数据量场景性能表现一般
  • 功能覆盖面不如专业ETL工具全面
  • 生态独立性较弱,绑定帆软体系

适用场景:帆软BI用户、中小规模数据集成需求、对实时性要求不高的场景。

6.ETLCloud(谷云科技)

ETLCloud是谷云科技推出的新一代数据集成平台,集离线ETL、实时CDC、调度编排、数据服务API于一体。其最大的亮点是提供功能完整的社区免费版,让企业可以零成本体验企业级数据集成能力。

0d7310448024bba14372f79ca14062d4.png

优势:

  • 社区版完全免费,功能无阉割
  • 可视化零代码操作,学习成本极低
  • 原生支持CDC实时数据集成
  • 内置调度引擎,支持复杂依赖编排
  • 数据服务API一键发布,快速构建数据中台
  • 国产自主可控,信创兼容性好
  • 本地化技术支持响应迅速

劣势:

  • 品牌知名度不如国际大厂
  • 社区生态仍在建设中
  • 极限性能场景下与Informatica有差距

适用场景:各类规模企业的数据集成需求,尤其适合追求性价比、注重国产化、希望快速落地的项目。

三、核心指标对比表

指标KettleDataXInformaticaDataStageFDLETLCloud
离线ETL★★★★☆★★★★★★★★★★★★★★★★★★☆☆★★★★★
实时CDC★☆☆☆☆☆☆☆☆☆★★★★☆★★★☆☆★★☆☆☆★★★★★
调度编排★★★☆☆☆☆☆☆☆★★★★★★★★★☆★★★☆☆★★★★★
数据服务API☆☆☆☆☆☆☆☆☆☆★★★★☆★★★☆☆★★☆☆☆★★★★★
可视化程度★★★☆☆★☆☆☆☆★★★★☆★★★☆☆★★★★☆★★★★★
易用性★★★☆☆★★☆☆☆★★★☆☆★★☆☆☆★★★★☆★★★★★
性能表现★★★☆☆★★★★★★★★★★★★★★★★★★☆☆★★★★☆
成本友好度★★★★★★★★★★★☆☆☆☆★☆☆☆☆★★★☆☆★★★★★
国产化支持★★★★☆★★★★★★☆☆☆☆★☆☆☆☆★★★★★★★★★★

四、场景化选型建议

场景一:创业公司/初创项目

推荐:ETLCloud社区版 > Kettle > DataX

预算有限是核心约束。ETLCloud社区版提供完整功能且零成本,可视化操作降低人力成本,是性价比最优解。若团队有较强技术能力且仅需离线同步,DataX也是不错选择。

场景二:中型企业数据仓库建设

推荐:ETLCloud商业版 > FineDataLink > Informatica

需要平衡功能、成本和易用性。ETLCloud提供企业级能力同时成本可控;若已使用帆软BI,FDL可考虑;预算充足且追求极致能力,Informatica仍是标杆。

场景三:大型金融/电信企业

推荐:Informatica > DataStage > ETLCloud企业版

对稳定性、安全性和合规性有极致要求。Informatica的行业实践和全球支持体系仍是首选。但在国产化背景下,建议评估ETLCloud企业版作为替代方案。

场景四:实时数据集成需求

推荐:ETLCloud > Informatica > FineDataLink

CDC实时集成是关键能力。ETLCloud原生支持CDC,配置简单,性价比最高。Informatica CDC模块功能强大但成本高昂。其他工具实时能力相对薄弱。

场景五:国产化替代项目

推荐:ETLCloud > FineDataLink > Kettle

信创兼容和国产自主是硬性要求。ETLCloud和FDL都是国产产品,符合信创要求。Kettle虽开源但生态依赖国外,存在一定风险。

五、总结与建议

核心观点

  • 没有"最好"的工具,只有"最合适"的工具——选型需结合企业规模、预算、技术能力、业务场景综合判断。
  • 国产化趋势不可逆——在信创政策推动下,国产ETL工具将迎来黄金发展期,ETLCloud等国产产品值得关注。
  • 功能完整性日益重要——单一能力的ETL工具已难满足现代数据集成需求,离线+实时+调度+API一体化是趋势。
  • 零成本试用是最佳实践——ETLCloud等提供免费版本,建议先试用验证,再决定采购。

最后,无论选择哪款工具,建议遵循"需求驱动、小步快跑、持续迭代"的原则。数据集成是长期工程,工具选型只是起点,持续优化才是关键。

领英(LinkedIn)是一个全球知名的职业社交平台,分为国内版和国际版,但是国内版功能有限做不了外贸客户开发,对于外贸业务员来说,领英国际版是一个重要的客户开发的渠道,所以一般都是需要使用国际版。然而,由于网络环境的限制,国际版的领英在国内不能使用,所以本篇内容为大家介绍国际版领英在国内的使用方法。一起来看看吧!

一、准备工具

1、科学上网工具(建议使用OSDWAN加速工具)

2、Gmail邮箱和可以接收验证码的手机号;

二、下载领英

安卓设备 :可以在Google Play商店下载领英APP,如果下载不了的可以找我们领取一个领英APK文件安装包。

苹果设备 :需要登录一个美国ID,然后在App Store下载领英APP。如需购买美国ID,也可以找我们。

三、注册领英国际版账号

下面也网页版为例:

1、直接注册国际版

步骤1:使用科学上网工具(推荐使用美国IP,如果没有可以找我们买一个),打开全局模式,访问领英国际版官网:www.linkedin.com
科学上网工具:OSDWAN。

步骤2:滑到页面最后,切换语言到“English”,只有这样输入名字的时候才能是英文的。
image.png

步骤3:点击“Join now”,使用Gmail谷歌邮箱注册,填写姓名和密码。
image.png

步骤4:完成邮箱验证,点击邮件中的验证邮箱“Confirm your email”链接。

步骤5:填写个人信息(如地址、职位等),建议使用与身份一致的国家/地区信息。

步骤6:完成注册后,完善个人资料,上传职业头像。

2、通过国内领英注册国际版

步骤1:先不打开科学上网工具,访问国内领英官网注册页面:https://www.LinkedIn.cn

步骤2:填写邮箱、密码和真实中文姓名,完成手机号验证。(也可切换为英语语言,就可以填写英文名字了)

步骤3:注册完成后,使用邮箱验证,点击里面的链接打开,这里需要使用科学上网工具(全局模式)访问www.linkedin.com,用注册的邮箱和密码登录。

需要注意的是:电脑访问领英建议使用无痕模式,一旦访问了国内版,就会自动跳

image.png

以上就是领英LinkedIn在中国使用的方法了,如果不会注册或者收不到验证码的小伙伴可以咨询我们的选型顾问,进行一对一咨询。

OSDWAN作为国内专业的跨境网络服务商,为出海企业提供合规、高速、稳定的网络解决方案,支持硬件、软件方案灵活部署。

OSDWAN在全球的数据中心节点50个,POP节点超过200个,可以为出海企业提供海外加速、SaaS加速、SD-WAN组网、跨境组网、云专线等产品服务,助力中国企业开拓国际市场。

目前 cursor 用的是老的计费模式,也就是一个月 500 次请求。

不确定升级 pro+ 给的 3x 用量到底是不是 500 * 3 ,发邮件给 cursor ,回复的是 AI 助手,说从 2026 年 2 月 17 开始都是按量计费,但是我又发截图说我的控制台显示的是按次计费,并且还有加入新定价的按钮,AI 回复说是 UI 显示问题。

有没有尝试过的或者了解这个的兄弟来说一下的。

如果换其他的推荐哪个呢。

前面用过很长一段时间 msys2+zsh ,无奈太卡了,和 windows 相性不合。
前段时间发现 msys2+fish 的速度比 zsh 快不少,但 msys2 环境下的路径问题总还是存在,另外经常碰到环境变量、Windows 和 msys2 命令冲突之类的奇奇怪怪的问题,尤其在 opencode 这类环境下。
看到有推荐 nushell ,pwsh 之类的,试用了一下,总感觉很别扭,学习成本有点高。

[内测抽奖] 0.2 元起的 Claude ,让 OpenClaw/Claude Code 实现 Token 自由

各位 V 友,

最近 OpenClaw 这类开源工具确实爽,但这些工具扫描一次项目就要吞掉几十万 Token ,官方价格用起来实在肉疼。

为了自用爽,我搭建了一个中转站:api.aiyahmm.com ,专门解决“想用重度工具又怕烧钱”的痛点。

🚀 为什么说这里是 OpenClaw / Claude Code 的绝配?

  1. 极致特价区 ($0.2 / 刀):价格只有官方的几分之一。特别适合跑 OpenClaw 、Aider 这种全项目扫描工具,怎么扫都不心疼。
  2. 生产力 Max 区 ($1.2 / 刀):官方正版 Tier 4/5 渠道,支持 Prompt Caching (缓存预填充)。配合 Claude Code 使用,不仅响应更稳,而且越用越省。
  3. 针对性适配:完美支持官方配置格式,国内直连不 403 。

🛠️ 官方标准 JSON 配置 (一键接入):

你可以直接将以下配置填入你的 config 文件:

{
"env": {
"ANTHROPIC_API_KEY": "你的 API 密钥",
"ANTHROPIC_BASE_URL": "https://api.aiyahmm.com"
},
"apiKeyHelper": "echo '你的 API 密钥'"
}

🎁 专属内测福利与抽奖:

  • 内测加额度:由于目前是人工审核内测,请在注册后在本帖回复你的用户名或 ID ,我会手动为您发放 $1.0 初始体验金额度。
  • 随机楼层抽奖:截止开奖时间,我将使用随机数生成器在评论区抽取 5 位老哥,每人赠送价值 9.9 元的体验套餐!
  • 规则说明:为公平起见,同一 ID 多次回复仅计第一次,若抽中楼主本人或重复楼层则顺延至下一楼。
  • 开奖时间:帖子发布 48 小时后,将在本帖更新名单并私信发放。

站点地址: https://api.aiyahmm.com


📢 老实交代:
目前是流量验证期,服务器带宽有限。如果大家测下来觉得不错,注册人数多,我立马换高配服务器!欢迎各位老哥轻喷并提供建议。