恒美微站
首页
关于我们
建站服务
主题模板
案例展示
资讯中心
联系我们
Numpy、Pandas、Matplotlib在大模型数据处理中的实战指南
首页
资讯中心
/
Numpy、Pandas、Matplotlib在大模型数据处理中的实战指南
Numpy、Pandas、Matplotlib在大模型数据处理中的实战指南
发布时间:2026/10/10 10:15:35
做AI大模型应用开发绕不开一件事喂给模型的数据得先变成模型能理解的样子模型吐出来的结果也得能转成我们能分析的东西。这个过程中Numpy、Pandas、Matplotlib就是最趁手的三件基础工具。这篇内容不是讲枯燥的API文档而是结合我实际做数据处理时的场景聊聊这三个库在大模型开发里到底怎么用、为什么这么用、踩过哪些坑以及如何用它们搭建一套从数据清洗到结果可视化的完整工作流。适合刚入门大模型开发、又对数据处理不太熟的朋友参考也欢迎老手一起交流。1. 为什么大模型开发绕不开这三个数据工具1.1 数据工具在大模型项目中的位置很多人一提到大模型应用开发第一反应是调API、写Prompt、搭Agent觉得数据处理是传统机器学习的事。但实际上大模型项目里的数据工作比想象中多得多。以微调一个开源大模型为例前期的数据收集、清洗、格式转换、样本筛选直接决定了最终的效果上限垃圾数据进去再强的模型也白搭。即使只是做RAG应用文档切分后也要做向量化前的结构整理Embedding结果要批量计算相似度检索结果要排序过滤这些全是数组和表格的活儿。我一般把数据工作理解成四个环节数据获取、数据清洗、数据运算、数据可视化。Numpy负责数据运算中最核心的数值计算部分比如向量、矩阵、批量数学操作Pandas负责把各种格式的数据统一整理成表格结构清洗、筛选、分组、聚合一条龙Matplotlib负责把最终的分析结果用折线图、柱状图画出来直观判断效果。三者配合起来基本覆盖了从原始数据到可视化结论的全部链路。1.2 三件套的分工逻辑与选型思考这三个库各有侧重也各有不可替代的地方。Numpy的核心是ndarray也就是多维数组。它比Python原生列表强在哪儿向量化运算。同样的批量加法、乘法用列表写for循环可能慢上几十倍而Numpy直接用C语言级别的底层实现一行代码搞定。在大模型场景里Embedding向量的批量相似度计算、数据归一化、矩阵乘法等需求没有Numpy几乎寸步难行。Pandas的价值则在于“结构化”。它把数据抽象成DataFrame类似Excel表格但是带索引、支持复杂筛选和聚合。实际开发中API返回的JSON、爬下来的CSV、日志文件等格式五花八门Pandas可以把它们统一读进来做完清洗和转换再输出成模型训练需要的格式。尤其是做指令微调数据时经常要把问题、回答、上下文等字段整理成统一的JSONL格式Pandas的操作效率非常高。Matplotlib则是“最后一公里”。很多时候模型评估结果是一堆数字光看数字很难发现问题。把Token消耗、Loss下降、各类指标对比画成图一眼就能找到异常点。比如训练Loss出现震荡、某个类别准确率明显偏低通过可视化能快速定位问题。从选型角度看这三个库是大模型开发的第一层基石。这套组合的好处是生态成熟、资料多、代码随便一搜都是一大片案例遇到问题不愁没人踩过。而且后续如果需要更高级的功能比如交互式图表Plotly、深度学习框架PyTorch它们的基本数据结构和Numpy、Pandas是打通的学习成本能平滑过渡。2. 环境搭建与安装避坑指南2.1 Python环境与虚拟环境准备工欲善其事必先利其器。我建议先用虚拟环境隔离项目依赖强烈不建议直接往系统Python里装一堆包。因为大模型开发经常会涉及PyTorch、Transformers等框架它们对Numpy版本有严格限制装混了很容易出现“版本不匹配”的怪病。推荐用conda或者venv创建独立环境。以conda为例conda create -n ai-data python3.10 conda activate ai-dataPython版本我一般选3.9到3.11之间太老的版本对部分库兼容性差太新的版本偶尔会遇到个别依赖还没跟上。实测下来Python 3.10是当前最稳妥的选择绝大多数深度学习相关库都兼容。2.2 安装三件套的正确姿势环境激活后安装三个库非常简单pip install numpy pandas matplotlib如果只需要安装某一个比如Numpypip install numpy这里需要注意pandas和matplotlib依赖numpy安装pandas时会自动拉取匹配的numpy版本无需单独操心。但如果你之前装过某个特殊版本的numpy再装pandas时可能出现依赖冲突报错信息里会明确提示这时候最简单的办法是让pip自己统一解决版本关系pip install --upgrade numpy pandas matplotlib不要硬保留旧版本。类似的还有PyTorch和Numpy之间的版本配合问题如果先装了某个特定numpy再装torch时pip会尝试调整numpy来匹配。如果调不动就得手动指定兼容版本。常规做法是先装torch再按它的要求装numpy等依赖。2.3 国内镜像源与清华源报错解析安装时最常遇到的就是网络超时或者找不到包。比如报错ERROR: Could not find a version that satisfies the requirement pandas (from versions: none) ERROR: No matching distribution found for pandas这个报错通常有三层原因。第一层是网络问题默认的PyPI源在部分网络环境下极其不稳定安装包下载一半就超时第二层是Python版本与pandas版本不兼容pip找不到能匹配的版本第三层是本地pip版本太旧解析能力弱。解决办法就是用国内镜像源。我自己一直用清华源配置一次全局生效pip config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple之后所有pip安装都会走清华源速度和稳定性都大幅提升。如果只想临时用一次也可以不修改全局配置pip install pandas -i https://pypi.tuna.tsinghua.edu.cn/simple镜像源也不是永远不出问题。偶尔清华源的同步会滞后导致最新版本的包暂时找不到。这时候换阿里源或者中科大源试试pip install pandas -i https://mirrors.aliyun.com/pypi/simple/另外如果pip版本太老可以先升级pip再安装pip install --upgrade pip这套流程我反复用了很多次基本上能把九成以上的安装问题解决掉。2.4 版本管理与验证安装完之后进Python环境验证一下import numpy as np import pandas as pd import matplotlib.pyplot as plt print(np.__version__) print(pd.__version__) print(matplotlib.__version__)如果导入没有报错就说明基础环境没问题了。这里提醒一个细节pandas和numpy的版本不要追求“最新”而是要追求“稳定兼容”。实际项目中如果pandas版本突然跳到2.x部分旧代码可能有行为变化。锁定版本可以这样pip install numpy1.26.4 pandas2.2.2 matplotlib3.8.4这个组合是我近期实测比较稳的搭配当然也要根据自己项目依赖特别是torch版本灵活调整。3. Numpy实战用数组计算能力支撑模型数据处理3.1 从列表到数组ndarray与dtypeNumpy的核心是ndarray对象。创建一个数组非常简单import numpy as np data np.array([1, 2, 3, 4, 5]) print(data) print(data.shape) print(data.dtype)输出结果类似[1 2 3 4 5] (5,) int64这里的关键区别在于dtype。原生列表里的元素类型是灵活的而ndarray要求所有元素类型一致好处是计算时内存连续、效率极高。如果你希望数组里存浮点数data_float np.array([1, 2, 3], dtypenp.float32)在大模型开发中dtype直接影响到内存占用。比如一个1万条、每条768维的Embedding向量矩阵用float64存储需要约122MB转成float32只需要约61MB。批量处理时这个差距非常明显。3.2 向量化运算与广播机制Numpy的精髓在于向量化运算。举个例子要给所有Embedding向量做归一化如果没学过Numpy可能会写成嵌套循环for i in range(len(vectors)): for j in range(len(vectors[i])): vectors[i][j] vectors[i][j] / np.linalg.norm(vectors[i])用Numpy的话几行搞定norms np.linalg.norm(vectors, axis1, keepdimsTrue) vectors_norm vectors / norms这背后的逻辑是广播机制Broadcasting简单理解就是维度不匹配时Numpy会自动把小维度的数组扩展到能运算的形状。生活化类比你把一个杯子里的水倒进一排杯子不需要一个个倒提起壶沿着一排杯子均匀倒就行。Numpy的广播就是“自动倒水”。广播机制虽然方便但也很容易踩坑。最常见的错误是数组维度不匹配。比如A形状是(25, 768)B形状是(768,)直接用A B没问题广播会沿第一维展开但如果B形状是(1, 768)和(768, 1)混用就得出完全不同的结果。我自己的习惯是运算前用assert a.shape b.shape或者先reshape统一维度避免“想当然”的运算错误。3.3 大模型数据场景的典型应用Numpy在大模型开发里的主要场景有几个。第一个就是Embedding相似度计算。比如做RAG时把用户查询向量和文档向量矩阵做批量余弦相似度def cosine_similarity(query_vec, doc_matrix): query_norm query_vec / np.linalg.norm(query_vec) doc_norms np.linalg.norm(doc_matrix, axis1, keepdimsTrue) doc_normed doc_matrix / doc_norms return np.dot(doc_normed, query_norm)这段代码返回每个文档与查询的相似度排序后取top-k就是检索结果。整个过程没有写一个for循环数据量上万条也能秒级完成。第二个场景是数据统计分析。比如分析Prompt中Token长度分布可以把所有样本的Token数量放到一个Numpy数组里直接计算均值、分位数、标准差token_counts np.array([120, 230, 180, 90, 300, 150]) print(token_counts.mean()) print(np.percentile(token_counts, [25, 50, 75]))这些统计量在决定上下文窗口设置、判断数据是否存在过长样本时非常有用。第三个场景是批量数据增广。比如对向量做随机扰动、拼接、截断等操作Numpy的随机模块提供了丰富的APInoise np.random.normal(0, 0.01, sizevectors.shape) vectors_aug vectors noise这个操作在样本数量不足时很有用但要注意扰动幅度不能太大否则会改变语义。3.4 索引、切片与聚合统计的常用套路Numpy的索引和切片是处理矩形批数据的利器。比如你有一个训练集向量矩阵形状是(N, 768)其中第0列是样本ID1~767列是向量内容。切出向量部分vec_part data[:, 1:]随机抽取一批样本sample_idx np.random.choice(len(data), size32, replaceFalse) sample_data data[sample_idx]聚合统计也很常用比如按行求均值、按列求maxrow_mean data.mean(axis1) col_max data.max(axis0)这里的axis参数很多人第一次用时容易蒙。我的记忆习惯是axis1表示把每一行的元素拉通统计axis0表示把每一列的元素拉通统计。比如一个类似Excel表格的数组axis0就是竖着看axis1就是横着看。4. Pandas实战把零散数据变成可用的训练数据4.1 DataFrame与Series用表格思维整理数据Pandas最核心的两个数据结构是Series和DataFrame理解起来非常简单Series是一列数据DataFrame是多列数据组成的表格。实际开发中我大多数时间都在和DataFrame打交道。创建一个DataFrame非常灵活import pandas as pd data { query: [什么是大模型, 如何微调模型, RAG是什么], answer: [大模型是以海量参数..., 微调是指..., RAG是检索增强生成...], token_count: [25, 20, 10] } df pd.DataFrame(data) print(df.head())输出如下query answer token_count 0 什么是大模型 大模型是以海量参数... 25 1 如何微调模型 微调是指... 20 2 RAG是什么 RAG是检索增强生成... 10这个结构天然适合做指令微调数据集。每个样本是“问题-回答-元信息”的结构修改、筛选、导出都非常方便。4.2 数据读取CSV、JSON与API返回结果的整理大模型开发的数据来源通常是CSV、JSON、JSONL或者API返回。Pandas读取这些格式都很方便。读取CSVdf pd.read_csv(samples.csv)读取JSONdf pd.read_json(samples.json)读取JSONL也就是每行一个JSON对象的数据集df pd.read_json(samples.jsonl, linesTrue)比较特殊的情况是API返回的结构化数据。比如调用一个模型接口返回数据是嵌套的JSON比如列表里套字典、字典里套列表。可以先用json库把数据转成Python对象再用pd.json_normalize把它展平成表格import json import pandas as pd with open(api_result.json, r, encodingutf-8) as f: result json.load(f) df pd.json_normalize(result)这是一个非常常用但很多人不知道的技巧。模型返回结构复杂时用json_normalize能省下大量手写解析逻辑的时间。4.3 数据清洗与类型转换数据清洗是Pandas用得最多的场景也是热搜词里常提到的“pandas 数据类型转换”。拿到原始数据后第一件事是看结构print(df.info()) print(df.describe()) print(df.isnull().sum())info()会列出每列的非空数量、数据类型、内存占用isnull().sum()会输出每列的缺失值数量非常直观。最常见的类型转换场景是某列明明是数值但加载进来却是字符串导致无法计算。比如一个“回复耗时”列的原始数据里混入了“0.5s”这样的带单位文本Pandas会把它读成object类型。处理办法df[latency] df[latency].str.replace(s, , regexFalse) df[latency] pd.to_numeric(df[latency], errorscoerce)pd.to_numeric是数据类型转换的一个关键APIerrorscoerce表示无法转换的数值变成NaN方便后续统一处理。注意这里的str.replace会原样替换字符串里的s操作前最好确认数据的格式统一。另一个常用场景是批量把某个字段从字符串转为datetimedf[timestamp] pd.to_datetime(df[timestamp])转成datetime后就能按时间做排序、筛选、聚合比如统计每小时调用量。4.4 结构化转换与批量构建PromptPandas不仅能清洗数据还能批量生成和转换结构化训练数据。比如你有用户问题和标准答案两个字段需要生成一个带Prompt模板的新列def build_prompt(row): return f用户提问{row[query]}\n请给出专业、简洁的回答。 df[prompt] df.apply(build_prompt, axis1)apply配合axis1表示逐行处理这是Pandas里扩展性非常强的功能。如果处理逻辑简单也可以用列表推导式df[prompt] [f用户提问{q}\n请给出专业、简洁的回答。 for q in df[query]]后者通常更快但可读性略差。数据量大时我会优先用列表推导式处理几万行数据也不会有明显卡顿。合并多个数据源也是常见操作。比如把向量文件和原始文本文件按ID合并df_text pd.read_csv(texts.csv) df_vec pd.read_csv(vectors.csv) df_merged pd.merge(df_text, df_vec, onsample_id, howleft)howleft表示以左边的表为主右边没有匹配到的数据补NaN这个语义在多表合并时非常常用。导出的格式也很关键。生成微调数据集时经常要导出为JSONL格式df.to_json(train.jsonl, orientrecords, linesTrue, force_asciiFalse)force_asciiFalse用来保留中文字符否则全都会被转成\uXXXX的Unicode转义序列虽然读取没问题但查数据时极不友好。5. Matplotlib实战把模型结果画成看得懂的图5.1 折线图训练Loss曲线的绘制模型训练过程中最关心的就是Loss下降是否正常。用Matplotlib画一张Loss曲线信息一目了然。import matplotlib.pyplot as plt epochs [1, 2, 3, 4, 5] train_loss [1.2, 0.8, 0.6, 0.45, 0.32] val_loss [1.3, 0.95, 0.75, 0.6, 0.5] plt.plot(epochs, train_loss, labeltrain_loss) plt.plot(epochs, val_loss, labelval_loss) plt.xlabel(Epoch) plt.ylabel(Loss) plt.legend() plt.grid(True) plt.show()这里的核心逻辑是plt.plot(x, y)x轴对应训练轮数y轴对应该轮的Loss值。加label之后plt.legend()会自动生成图例。加上plt.grid(True)后网格线能帮助更精细地对比数值变化我一般都会开。训练过程中另一个常见的需求是在每个Epoch结束后往列表里追加Loss值最后一并画图train_losses [] val_losses [] for epoch in range(1, 6): # 假设train_one_epoch返回本轮训练loss t_loss train_one_epoch() v_loss evaluate() train_losses.append(t_loss) val_losses.append(v_loss) plt.plot(range(1, len(train_losses)1), train_losses, markero) plt.plot(range(1, len(val_losses)1), val_losses, markers)加marker参数是为了让数据点更明显尤其在样本点较少时非常有效。5.2 柱状图模型效果对比柱状图最常见的使用场景是多个模型或多项指标对比。比如三个模型在准确率、召回率、F1上的对比import numpy as np models [ModelA, ModelB, ModelC] accuracy [0.87, 0.91, 0.89] recall [0.82, 0.88, 0.90] f1 [0.84, 0.89, 0.89] x np.arange(len(models)) width 0.25 plt.bar(x - width, accuracy, width, labelAccuracy) plt.bar(x, recall, width, labelRecall) plt.bar(x width, f1, width, labelF1) plt.xticks(x, models) plt.legend() plt.show()柱状图的细节在于x - width、x、x width的偏移。这样三根柱子才不会重叠在一起每组柱子之间也能留出自然间距。用np.arange(len(models))生成x轴位置是这类分组柱状图的标准写法。如果需要在柱子上显示具体数值可以配合plt.text实现。比如for xi, val in zip(x, accuracy): plt.text(xi, val, f{val:.2f}, hacenter, vabottom, fontsize9)这里hacenter控制水平居中vabottom让文字位于柱子顶部偏上一点。对于需要写报告的场景这个细节很加分。5.3 样式调整与颜色配置Matplotlib默认的样式比较朴素而且不同版本之间的默认色系还有差别。好在我们能手动控制颜色。颜色参数可以写成多种格式plt.plot(x, y1, colorred) plt.plot(x, y2, color#3498db) plt.plot(x, y3, color(0.2, 0.6, 0.8))第一种是颜色名称第二种是十六进制HEX值第三种是RGB元组。实际画图时我喜欢从项目的品牌色或者专业配色站点取色统一指定。比如用一套蓝、橙、绿的配色对比时非常清晰。如果需要画出多条颜色差异大、又兼顾色盲友好的曲线可以用Matplotlib自带的colormapcmap plt.cm.viridis colors [cmap(i / 9) for i in range(10)] for i in range(10): plt.plot(x, data[i], colorcolors[i], labelfline_{i})viridis、plasma、cool这些colormap都有很好的视觉区分度比手动硬凑十种颜色靠谱多了。另有一个常用细节是plt.tight_layout()它能让图例、坐标轴标签等元素自动调整布局避免图片边缘被截断。我在出图最后一刻总会加上这一行。5.4 中文字体处理与图片、动画导出Matplotlib默认不支持中文标签里出现中文时会显示成一个个方框。处理方法非常简单在画图前指定中文字体plt.rcParams[font.sans-serif] [SimHei, Microsoft YaHei, PingFang SC] plt.rcParams[axes.unicode_minus] False第一行指定可用的中文字体第二行解决负号显示异常的问题。我长期在Windows和macOS之间切换配置里一般会同时写上多个字体候选代码拿到任何机器上都能显示中文。如果系统里没有SimHei或微软雅黑Linux下可以装Noto Sans CJK SC并同样把名字加进候选列表。导出图片用plt.savefigplt.savefig(loss_curve.png, dpi150, bbox_inchestight)dpi150可以保证图片在文档里放大后依然清晰。bbox_inchestight会自动裁剪掉多余的留白非常实用。如果画布尺寸不合适还可以在画图前指定plt.figure(figsize(8, 5))figsize的单位是英寸我一般用(8, 5)或者(10, 6)比例接近黄金分割视觉上比较舒服。除了静态图片有时候还想把训练过程录制成动画比如持续追加新的Loss点、保存为GIF。Matplotlib配合matplotlib.animation.FuncAnimation可以做到from matplotlib.animation import FuncAnimation from IPython.display import HTML fig, ax plt.subplots() def update(frame): ax.clear() ax.plot(epochs[:frame1], train_loss[:frame1], color#3498db) ax.set_title(fEpoch {frame1}) return ax anim FuncAnimation(fig, update, frameslen(train_loss), interval500) anim.save(loss_animation.gif, writerpillow, fps2)生成GIF需要安装pillow库pip install pillow这种方式适合做训练过程的可视化演示效果非常直观。但要注意帧数太多时GIF文件会很大建议控制帧数或者降低fps。6. 实践中的常见问题与排查实录6.1 安装与版本类问题我把踩过的坑整理成一张速查表方便对照排查问题现象可能原因解决方案pip报No matching distribution镜像源同步滞后、pip版本过旧加--upgrade pip换阿里源/中科大源导入numpy报DLL load failednumpy与Python版本不匹配卸载重装对应Python版本的numpypandas操作时提示Version mismatch某个依赖库如Numpy被手动改过版本pip install --upgrade numpy pandas统一版本torch与numpy冲突两者版本要求不一致先装torch后按提示装指定numpy版本特别提醒如果项目里同时使用深度学习框架安装顺序很关键。我自己是先把torch装好再装numpy、pandas、matplotlib。因为torch在安装时会自动选择兼容的numpy版本之后其他库再去适配这个numpy版本冲突概率小很多。6.2 pandas类型转换与读数据踩坑数据处理时最让人头疼的三个坑我逐个说。第一个是CSV编码问题。读取CSV时如果包含中文直接pd.read_csv经常报UnicodeDecodeError因为默认编码不是UTF-8。解决办法df pd.read_csv(file.csv, encodingutf-8)如果还是报错就尝试encodinggbk或者encodingutf-8-sig。utf-8-sig专门处理带BOM头部的UTF-8文件Excel导出的CSV经常有这个头。第二个是astype和pd.to_numeric的选择问题。很多人喜欢用astype直接转类型df[col] df[col].astype(float)如果这一列里混入了一个非数值字符会直接抛异常。而pd.to_numeric(errorcoerce)则会把异常值变成NaN后续可以用fillna、dropna处理明显更稳健。我的习惯是数据来源干净时才用astype任何可能不干净的数据都用to_numeric。第三个是JSONL数据的嵌套结构。读进来后经常发现某个字段是“列表套字典”要展开才能分析。处理办法是用pd.json_normalizedf_expanded pd.json_normalize(df[raw_json].apply(json.loads))或者用df.explode()把列表拆成多行。比如每条样本有多个标签就能拆成一行一个标签方便分组统计。6.3 matplotlib中文乱码与图片清晰度中文乱码的根因是matplotlib默认字体库不含中文字形。前面提过的配置plt.rcParams[font.sans-serif] [SimHei, Microsoft YaHei, PingFang SC] plt.rcParams[axes.unicode_minus] False如果配置了还是不生效可以打印出当前可用字体列表看看候选名是否正确import matplotlib.font_manager as fm fonts [f.name for f in fm.fontManager.ttflist] print(SimHei in fonts)优先级上SimHei黑体在绝大多数Windows环境都能用macOS环境用PingFang SCLinux下有人装了Noto Sans CJK SC也可以直接用。还有一个终极办法直接用英文标签避免字体问题但在中文项目文档里观感差一些不推荐首选。图片清晰度方面保存时dpi设置过低会导致图片放大后模糊。我一般输出给PPT或文档用的图都设150-200 dpi输出给打印材料则用300 dpi。同时配合bbox_inchestight裁剪边缘图片看起来更专业。6.4 性能和内存相关的经验数据量大的时候性能和内存也是不能忽视的。有几个实操经验第一尽量使用向量化运算代替循环。Pandas里能一行写清楚的聚合、筛选操作尽量不要用自定义函数配合iterrows()逐行处理两者性能差距是数量级的。第二读取大CSV时可以先看看文件有多大然后只读取需要的列df pd.read_csv(large.csv, usecols[query, answer, score])usecols参数能显著减少内存占用读取速度也快很多。第三对于超大语料可以考虑用chunksize分块读取边读边处理chunk_iter pd.read_csv(huge.csv, chunksize10000) for chunk in chunk_iter: process(chunk)第四Numpy数组如果确定只读可以主动设置setflags(writeFalse)在某些场景下能提升处理效率但这个是锦上添花最关键的还是避免不必要的数据拷贝。6.5 数据一致性检查清单最后分享一个我每次做完数据清洗都会过的检查清单很笨但很有效用df.info()检查每列数据类型是否符合预期object类型过多的列重点关注用df.isnull().sum()确认缺失值情况决定是删行还是填充用samples[token_count].describe()检查数值分布尤其看min和max是否存在异常用df[query].str.len()检查文本长度是否符合预期尤其是0长度样本是否出现用df.drop_duplicates()删除重复样本重复样本会让模型对某些模式过拟合导出前用head()抽查几条数据确认内容没有错乱这套流程下来能过滤掉绝大部分“脏数据”。我有一次在微调模型前没有检查文本长度分布结果里面混入了几个长度为1的极端样本训练时Loss直接飙升。后来加了这一步检查再也没出过类似问题。最后再分享一个小技巧在做数据清洗时每完成一步转换就顺手保存一份中间结果。比如清洗完存一份clean.csv类型转换完再存一份typed.csv。这样即使后续步骤出错也不需要从头开始。我见过太多人辛苦清洗了一半结果一个误操作全部丢失又得重来。这个过程本身也是在积累一套可复用的数据处理流水线对大模型项目开发来说比单纯写Prompt要实在得多。