
做这个项目之前我其实已经帮几个汽车经销商集团做过零散的报表需求。每次都是同样的流程销售数据散在厂家DMS系统、汽车垂直媒体后台、自家Excel台账里月底要花三四天人工汇总再做一堆透视表。领导问一句“这个月哪个车型的线索转化率为什么掉了”又得翻半天数据。后来我干脆把整条链路做成了一套自动化系统——用Python爬公开数据、Hive存数、Spark跑分析、大模型自动读数据写报告最后落到可视化大屏上。这篇文章把我完整的技术方案和路上的坑都梳理一遍给准备做类似大数据项目的朋友一个参考。1. 系统定位不做报表工具做销售决策链路先说清楚这个系统到底要解决什么问题否则后面所有设计都容易跑偏。汽车销售行业的数据源特别碎。以我接触的经销商集团为例每天要面对的数据包括各车型的厂商指导价、终端优惠幅度、销量排行、线索量、试驾量、成交价、库存周转天数等等。这些数据分散在至少三个地方厂家系统DMS、第三方平台汽车之家、懂车帝这些垂直媒体的公开数据、门店自己的CRM。很多门店管理者的日常是月底导出Excel用VLOOKUP把几张表拼在一起再手动做数据透视。一套流程走完新的销售周期又开始了。这套系统要解决的不是“把数据存起来再看”而是真正打通一条链路自动采集公开数据 → 统一清洗落数仓 → 多维度分析 → 大模型辅助解读 → 可视化呈现。这五个环节对应了标题里的Python爬虫、Hive、Spark、大模型和可视化系统。需要注意的是这里“爬取”的数据必须限定在公开且合规的范围内。汽车垂直媒体的车型参数、公开销量榜单、厂商官方发布的指导价这些是可以合法获取的公开信息。但涉及具体经销商内部报表、未授权的个人数据绝对不能碰。我们系统主数据源就是公开的车型参数和销量榜单内部数据由企业自己通过API或文件导入两条线在数仓里汇合。合规是红线这个不能含糊。整个系统跑起来之后一个门店管理者看到的不再是几十个Excel文件而是一个驾驶舱页面本月销量目标达成率、各车型线索转化漏斗、库存结构预警、竞品优惠幅度异动。他想知道“为什么某款车这个月销量下滑”可以直接在系统里问大模型会从数仓里提取相关数据生成分析结论。这才是这个项目的核心价值——不只是把数据变成图表而是把图表变成可执行的判断。2. 数据采集层Python爬虫的设计与合规边界数据采集是整个系统最前面的环节也是实际跑起来最容易出幺蛾子的环节。2.1 数据源分析与选型我先列一下数据源做项目第一步一定是盘数据源不能上来就写爬虫脚本。数据源类别具体内容获取方式更新频率车企官方车型参数、指导价、配置表官网公开页面 / 公开API月度垂直媒体销量榜、关注度、口碑评分页面解析日度行业统计市场总体销量、渗透率公开报告 / 统计网站季度内部系统门店线索、成交、库存CRM/DMS导出或API实时/日度从技术角度前两类适合用Python爬虫做增量抓取第三类可能只需要周期性下载PDF或表格文件第四类走内部接口。我当时花了不少时间在媒体站点的页面结构分析上因为销量榜单的数据通常不是直接写死在HTML里而是通过Ajax异步加载接口返回JSON。这就得用抓包工具去看真实的接口地址和参数。2.2 爬虫框架选型为什么用ScrapyPlaywright组合爬虫框架我用了两套组合。常规的静态页面和JSON接口用Scrapy就够基于Twisted的异步机制性能很好三五个节点能撑起日百万级的请求量。但有些目标站点的数据是动态渲染出来的甚至有的用了反爬策略需要真实浏览器环境才能拿到完整数据这时候ScrapyRequests的方案就不够用了。我在这个项目里的做法是Scrapy负责调度和数据处理Playwright负责动态页面渲染。Playwright是无头浏览器可以模拟真实用户操作拖拽滚动、点击翻页都能执行。最典型的场景是某些车型对比页面数据是前端JavaScript渲染的直接抓HTML源码什么都拿不到必须用Playwright渲染完再提取。用Playwright配合Scrapy有个经典写法# pipelines.py 里特殊处理动态渲染页面 from playwright.sync_api import sync_playwright def fetch_dynamic_page(url: str) - str: with sync_playwright() as p: browser p.chromium.launch(headlessTrue) page browser.new_page() page.goto(url, wait_untilnetworkidle, timeout30000) # 滚动页面触发懒加载 for _ in range(5): page.mouse.wheel(0, 800) page.wait_for_timeout(500) html page.content() browser.close() return html这种写法很笨重但对动态页面有效。注意生产环境不要频繁启动浏览器要做一个Playwright浏览器实例池否则内存会暴涨。2.3 反爬策略与请求调度反爬是我在这个项目里被磨得最多的部分。汽车垂直媒体的风控不算特别变态但也不是裸奔能抓的。真正有效的策略其实是这几条限速这点最基础也最重要。单IP请求频率控制在1~2秒一次波动式限速而不是固定频率模仿人的操作节奏不要每个请求之间间隔完全一样。代理池准备一个可用代理池按域名级别的规则来调度。注意别让代理的质量拖累抓取速度垃圾代理比直连更容易触发验证码。Cookie管理部分页面需要登录态才能看完整数据Cookie有效期短要做好自动刷新机制。指纹伪装把TLS指纹伪装和UA轮换结合使用。只有Scrapy默认的UA是远远不够的Headers里面Referer也必须要带对有些站点会校验。我踩过一个特别深的坑某站点对同一IP的请求频率限制不是403封禁而是返回“数据加载失败”的假页面。爬虫照常跑状态码全是200但解析下来的结果全是空。当时排查了很久最后是加了响应内容长度校验才发现的。所以爬虫的数据质量校验机制必须前置不要等入库了才发现数据是空的。2.4 数据清洗源头脏数据处理爬下来不代表能用。汽车销量数据常见的脏数据情况车型名称不统一比如“朗逸”和“朗逸PLUS”在不同页面写法不同、销量数值带单位“1.2万”需要转成12000、缺字段、重复数据。我在清洗模块里做了几件事统一车型名称映射表这是最有效的办法。建一张车型标准名称表和别名的映射关系清洗时做标准化替换。数值格式统一正则提取数字并转换中文单位。去重逻辑以“数据源业务日期车型ID”作为唯一键去重。空值处理策略有些字段为空在业务上是有意义的比如某车型没有四驱版本不能一律填0需要配合数据字典做规则判断。清洗后的数据写入Kafka再消费进Hive。为什么不直接写Hive因为Kafka起到削峰填谷和缓冲的作用后面接Spark Streaming做实时计算也更方便。这是我后来才加的中间层早期是直接写ODS表一到爬虫高峰期Hive就会因为并发写入太多而卡顿。3. Hive数仓分层从ODS到ADS的四层设计很多工程背景的人做数仓容易犯一个毛病——上来就建表不管分层。小数据量的时候无所谓数据一多、业务一复杂你就知道分层有多重要了。这套数仓的完整链路是Kafka数据 → ODS原始数据层 → DWD明细数据层 → DWS服务数据层 → ADS应用数据层。3.1 各层职责与建模逻辑ODS层原始数据层保持和源头数据一样的结构不做任何加工每张表都加上dt日期分区和source来源标识字段。这层的意义是保留原始痕迹万一后面发现数仓数据有问题还能回溯原始数据比对。DWD层明细数据层做清洗、规范化、维度退化。比如把车型名称统一、把多个数据源的表做合并、把JSON字段拆成结构化字段。这层是数据工程师花时间最多的地方ETL的绝大部分逻辑都在这里。关键设计是维表与事实表的粒度对齐。比如销售事实表的粒度是“车型_日期_经销商”那所有关联维度都要能在这个粒度上唯一确定。DWS层汇总数据层按主题做轻度汇总。比如“日车型销量汇总表”“月经销商销售目标达成表”。这层的数据已经满足90%的日常查询需求Spark分析的大部分SQL直接查这一层。ADS层应用数据层面向具体业务场景加工比如可视化大屏需要的指标宽表、大模型需要的数据快照表。这一层的数据已经高度聚合通常是宽表结构字段很多一行记录就是一个业务实体的全维度指标。3.2 表设计的关键细节Hive表设计的细节决定了你后面分析顺不顺这里有几个经验分区策略按日期分区是标配。如果数据量再大可以再加一层品牌分区。注意分区粒度不要太细否则小文件问题会让人崩溃。我就遇到过按“品牌日期”双层分区后每天产生上千个小文件Spark读取时频繁task调度慢得离谱。存储格式生产环境我用ORC格式做存储压缩比高、查询性能好。ODS层用TextFile或Parquet也可以但DWD以上直接ORC配合Hive的向量化查询性能提升非常明显。桶表设计如果经常需要做Join操作的表按关联键做分桶可以大幅减少Shuffle。我们的事实表和维度表都按model_id做了分桶跑Join任务时速度快了不少。数据更新策略Hive天然不适合行级更新。对于需要更新的业务表我用分区覆盖写入的策略。每天全量刷新当天分区而不是去变更历史数据。3.3 ETL调度与任务编排ETL调度我试过三种方案Crontab脚本、Azkaban、Apache DolphinScheduler。小项目用Crontab就行但一旦任务多了依赖关系复杂了Crontab就是噩梦。后来换成DolphinScheduler主要看重它的DAG依赖管理和失败重试机制。这个项目的任务编排大概是这样的ODS数据同步 → DWD清洗任务 → DWS汇总任务 → ADS指标计算 → 数据导出 → 大模型报告生成任务之间的依赖关系必须明确。比如DWS层任务必须等所有DWD任务跑完才能启动否则数据缺一块算出来的指标就是错的。3.4 分区覆盖写与数据回溯做数仓最怕什么源头数据有问题修完要重刷数据。我们的做法是保留最近30天的数据分区一旦发现某天的数据错误可以重新拉取源数据并覆盖对应分区。早期没有这个机制某天的数据被改错了只能手动写SQL去找补极其痛苦。所以分区覆盖写是这个系统的底线机制后面做任何数据修正都要靠它。4. Spark分析引擎从“能算”到“算得快、算得准”Hive负责存数Spark负责算数。为什么用Spark不用纯Hive SQL因为业务部门的需求经常变化临时要按“地理区域价格区间车型级别”交叉统计的时候Hive SQL跑一次二十分钟根本等不起。Spark的DataFrame API配合内存计算同样逻辑五分多钟就能跑完这种体验差异在业务侧感知特别明显。4.1 Spark在系统中的三个角色Spark在整个系统里承担三类任务批处理任务每日凌晨对前一天的全量数据做汇总统计。比如计算各车型的日销量、线索量、转化率、市场份额、同环比变化。这些指标会写入ADS层第二天一早大屏和报告直接读取。即席查询业务人员在前端页面选择维度和指标Spark Thrift Server接收SQL请求秒级返回结果。这块我用的是Spark SQL通过JDBC接口提供服务。实际使用中要注意并发控制不能让人人都直接跑大查询否则会把资源池打满。指标口径统一计算这是Spark最重要的角色。同一个指标比如“线索转化率”让销售部和技术部分开定义结果可能不一样。我们在DWS层用Spark把这些指标的口径固化下来所有人看到的是同一个算法算出来的结果。这一步是把数据分析从“手工取数”推向“统一口径”的关键。4.2 核心分析场景与代码实现举一个最常用的分析场景车型销量排名与增长趋势分析。from pyspark.sql import SparkSession from pyspark.sql.functions import col, row_number, rank, sum, desc from pyspark.sql.window import Window spark SparkSession.builder \ .appName(CarSalesMonthlyAnalysis) \ .enableHiveSupport() \ .config(spark.sql.shuffle.partitions, 200) \ .getOrCreate() # 从DWS层读取月度销量汇总表 sales_df spark.table(dws.dws_car_monthly_sales) # 按月份和车型排名 window_spec Window.partitionBy(month).orderBy(desc(sales_volume)) ranked_df sales_df.withColumn(rank, row_number().over(window_spec)) # 只保留每个月的TOP20车型 top20_df ranked_df.filter(col(rank) 20) # 计算与上月对比的增长率 sales_lag_df top20_df.withColumn( prev_month_sales, col(sales_volume).lag() # 这里实际需要按车型分组排序简化写法仅为示例 )真正生产环境的代码会更复杂核心思路是窗口函数做同环比计算这是销售分析里最重要的功能。同环比为什么重要它回答的是“这个月到底是涨了还是跌了、相对什么基准涨跌”的问题。没有同环比绝对数值看不出趋势。4.3 性能调优的三个关键参数Spark任务跑得慢大部分情况不是集群不够大是代码和参数没调好。几个实战经验动态资源分配要开spark.dynamicAllocation.enabled设为true空闲时释放executor高峰期再拉起来资源利用率高很多。Shuffle分区数要调默认200个分区在数据量大的时候容易产生大量小task数据量小的时候又造成浪费。根据数据规模动态调整一般控制在200到1000之间比较合适。大表Join用Broadcast如果一个小表比如维度表小于一定阈值使用broadcast join可以完全避免Shuffle性能提升是数量级的。Pyspark里只要在小表上调用broadcast()即可。我在实际项目中还踩过一个坑Spark SQL跑某个复杂查询时会出现某个executor内存溢出。原因是数据倾斜——某个品牌的车型销量数据比其他品牌大很多导致分配到那个分区的数据量过大。解决办法是加盐salting给热点key加随机后缀分散到不同分区。这是Spark调优的经典场景遇到倾斜问题时优先想到这个方法。4.4 从统计指标到业务归因只做统计不是分析。分析的下一个阶段是归因——看到“某车型销量下降20%”要找到原因。归因逻辑我做了一部分规则引擎价格因素对比该车型近30天终端优惠幅度的变化如果优惠收窄而竞品没有那大概率是价格导致。竞品因素同期竞品车型是否有新车上市或大促销。线索因素垂直媒体的线索量是否同步下滑如果是说明是入口流量问题而非销售端问题。库存因素该车型的库存周转天数是否异常升高导致主机厂发货减少。这些规则引擎的输出会成为大模型生成报告的重要输入。规则引擎能快速锁定方向但把“方向”变成“完整可读的业务结论”还需要大模型来组织语言、结合上下文给出综合判断。这也是这个项目里大模型存在意义的核心分析师给规则大模型负责把规则结论变成人话。5. 大模型接入从数据到业务报告的最后一公里说实话最开始接大模型我身边不少人是质疑的——数据分析系统搞什么大模型是不是蹭热点但做完之后我理解了大模型解决的是“数据到结论”的表达问题这在传统BI里其实一直没有好的解决方案。BI工具能出图表但图表本身不会告诉你“这意味着什么、下一步该怎么办”。5.1 大模型在系统中的定位大模型不是替代Spark做计算它的角色是“数据分析师助理”。系统跑完Spark分析后会把指标计算结果、规则引擎的归因结论、历史同期对比数据等结构化信息拼装成上下文提交给大模型让它生成经营分析报告或回答自然语言问题。举个例子商家问系统“为什么5月份XX车型销量降了”后台逻辑是从数据库查该车型5月销量、4月销量、去年同期销量。查询规则引擎的归因结论价格、竞品、线索、库存四个维度的状态。把这几个查询结果拼成提示词发给大模型。大模型生成回答“5月份该车型销量环比下降18%主要原因有三一是终端优惠较上月收窄3000元性价比优势减弱二是同价位竞品新车型上市分流了部分关注度三是垂直媒体线索量下降25%流量入口收窄。建议关注竞品动向适当调整优惠策略。”整个流程里大模型只做了一件它最擅长的事把结构化的数据变成有逻辑、有语言组织的分析结论。5.2 提示词工程的实际经验大模型输出质量的好坏一半在提示词设计。我总结了这套系统里的提示词设计思路打造“数据分析师”人设 输入结构化 输出规范约束。实测有效的提示词模板你是资深汽车行业销售数据分析师。请根据以下数据指标和分析要点生成经营分析报告报告需包含 1. 总体判断用一两句话概括核心结论 2. 三个关键发现每条必须引用具体数值作为依据 3. 风险提示指出数据中可能存在的异常或隐忧 4. 行动建议基于数据给出下一步可执行的动作 数据指标 {结构化指标JSON} 分析要点 {规则引擎归因结论} 要求 - 语言专业但平实不使用“赋能”等空洞词汇 - 每个结论必须有数据支撑禁止凭空推测 - 报告总字数控制在800字以内有几个细节要特别注意上下文长度控制不要一次性塞太多数据大模型容易忽略中间内容把关键指标放在上下文前面和末尾效果最好。指令明确“禁止”明确告诉模型不能做什么比让模型做什么更重要。数据分析领域最怕模型编数据、瞎猜结论一定要强约束“结论必须有数据支撑”。少样本示例在提示词里给一到两个“指标-结论”的对应示例模型输出质量会明显提升。5.3 端到端工程衔接大模型接起来不难难的是工程化。模型调用会失败、会超时、会返回格式不对。所以我做了几个保护机制Json格式强制校验让模型输出JSON结构然后程序解析解析失败自动重试一次。降级方案大模型服务不可用时直接输出规则引擎的结论文本页面不报错。缓存机制同一天相同问题的报告结果缓存到Redis不再重复调用大模型既省钱又提速。异步生成经营日报这类报告异步生成生成完成后再推送通知避免用户傻等。一个实际的调用链路大概是用户提问 → 后端解析意图 → 组装数据查询 → 查询结果拼装提示词 → 调用大模型接口 → 校验输出 → 渲染前端。5.4 模型选型与部署方式模型选型方面我曾尝试过两条路线一是直接调用成熟的商业模型API省事但费用高且数据出域有合规风险二是私有化部署开源大模型比如Qwen系列、Llama系列的中文版本数据完全在本地但需要GPU资源和模型微调的投入。这个项目最终采用的是混合模式常规交互问答走私有化部署的开源模型确保敏感数据不出内网复杂逻辑推理或报告精修场景调用商业API辅助但会做数据脱敏处理。混合模式的好处是兼顾数据安全和效果坏处是维护成本高两套链路都要监控。大模型的效果评估也很重要别只看一两个例子。我建了一个基础的评测集收录了二十个典型经营问题销量下滑原因、库存预警、定价建议等每次调整提示词或换模型后拿这个评测集跑一遍人工打分对比。有了这个机制优化就变得有方向了而不是凭感觉调整。6. 可视化大屏与前端联动数据最终要能“看得懂”前面所有的存储、计算、推理最后都要落到可视化上。一套系统如果前端展示做得不行即使后端再强大业务方也不会用。6.1 可视化技术选型可视化方案我评估过几套自研基于EChartsVue的大屏用开源BI工具Superset、Metabase或者用商业产品帆软。对比下来方案优点缺点适用场景ECharts Vue自研灵活度高、交互可控、酷炫效果开发成本高、图表组件要自己封装有前端开发能力的团队Superset配置快、SQL直连、权限管理完善交互深度有限、大屏布局不如自研灵活内部报表、探索分析帆软功能全面、财务级报表能力强贵、二次开发受限大型企业我这边最终选了EChartsVue自研因为要和大模型问答界面做深度整合自研更灵活。大屏右侧放深度分析结论卡片是自定义组件商业工具做不到这个效果。6.2 大屏布局与图表选择逻辑大屏设计不是把图表堆上去就行要考虑信息层级。我采用的布局思路是顶部核心KPI指标条总销量、总销售额、线索量、库存周转天数。这几个指标是管理者每天最关心的放在最显眼位置。中部左侧销量趋势折线图、车型销量排行柱状图。回答“整体走势和结构”的问题。中部中间地图展示区域销售分布、目标达成率热力图。回答“地域差异”的问题。中部右侧大模型自动生成的今日经营分析简报图文结合辅助决策。底部细颗粒度的数据明细表、异动预警滚动列表。图表选型的原则是趋势用折线、排名用柱状、占比用饼图或环形图、地域分布用地图、关系用桑基图。不要为了好看用花哨的图表类型信息传达效率是第一位的。6.3 数据链路与实时刷新大屏的数据不是直接连Hive的那样延迟太高。我的做法是Spark计算完成后把ADS层数据同步到MySQL/ClickHouse前端通过后端API查询这个库。这样查询响应控制在几百毫秒内。刷新频率上核心指标大屏每五分钟轮询一次数据明细表每次操作手动刷新不需要真正的实时推送。实时推送WebSocket会显著增加系统复杂度对销售分析这个场景收益不大反而容易引入问题。6.4 权限设计与多角色视图可视化系统上线后权限设计必须跟上。不同角色看到的内容完全不同集团高管看全局指标、品牌结构、区域表现有下钻权限。门店经理只看本店的线索、成交、库存有对比竞品门店的权限。一线销售看个人绩效达成、单品转化趋势没有跨店权限。权限控制有两个层面数据权限行级比如门店经理只能查store_id自己门店的数据操作权限按钮级比如只有分析人员能导出数据。我之前吃过亏权限只做了菜单显隐结果数据接口是通用的用户换个URL就能看到所有数据。后来在API层统一加了用户上下文过滤把user_id映射到数据范围才堵住这个洞。这种问题在内部系统里尤其要重视权限设计不是做不做的问题而是什么时候做——上线前就得做完否则出了事再补就晚了。7. 踩坑实录数仓、调度和模型这三件事最折磨人技术方案说完了把实际运行中最折磨人的几类问题集中梳理一下。这些问题单看都不难但叠加起来足以让一个项目从“能跑”变成“天天救火”。7.1 数仓数据不一致的元凶数据不一致的问题排查起来最费时间。我有一次发现可视化大屏上的“总销量”和日报邮件里的“总销量”差了300台查了半天发现原因是两边的SQL逻辑里对“销量”的定义不一致——一个把“退车”也计入销量另一个没有。后来我把所有关键指标的定义沉淀成一份数据字典文档并在数仓计算层统一由Spark任务加工报表直接读计算结果不允许多头定义。这个问题的本质是“数据口径”的管理问题不是技术问题。但必须靠技术手段去固化否则业务一换人口径又乱了。7.2 调度系统的连锁故障调度系统在某次数据源接口升级时出了大问题。源站的字段从price改成了discount_price爬虫没有及时适配清洗后所有价格字段都为空。但调度任务照常往下跑DWD、DWS、ADS一层层算下去最后大屏上所有价格相关的指标全部异常。当时人不在电脑前等发现时已经浪费了三天数据。这件事给我的教训是每个ETL环节都要做数据质量校验异常时立即告警并停止下游任务。后来我在清洗模块里加入了空值率监控——当某个字段的空值率超过阈值比如5%自动触发告警并暂停调度。此外DolphinScheduler里的失败重试也要谨慎配置如果数据源问题没解决无脑重试只会把垃圾数据重复算一遍。7.3 大模型输出的幻觉问题大模型在数据分析里最大的坑是“一本正经地胡说八道”。明明数据里没有的结论它会根据训练语料的先验知识补一个出来。举个例子我让它分析某车型销量下滑原因结果它给出了“国家政策调整导致新能源汽车购买需求下降”这种基于常识但不基于本系统数据的总结。这个结论放在宏观上可能成立但放到这个特定车型、这个特定月份的场景里完全可能是没根据的猜测。我应对的方法有三个一是强约束提示词要求结论必须引用输入数据中的具体数值二是提供“数据引用模板”让模型输出“根据数据该车型5月销量为X环比下降Y%”这种格式不基于数据的结论不允许输出三是在后置校验环节写规则判断模型生成的数字是否与查询结果一致不一致就重新生成。三个手段叠加幻觉率能压到很低的水平但不敢说完全消除——所以最终报告仍然需要人工复核至少看一眼关键数字对不对。7.4 集群资源规划的经验Spark和Hive跑在同一个集群上资源规划很重要。我早期把Spark Executor内存开得很大每个Executor 8G结果20个并发任务就直接把YARN资源池打满了别的任务全部排队。后来改了策略控制单任务资源上限提高任务并行度牺牲单任务速度换整体吞吐量。一个数据分析系统稳定和整体效率比单任务跑得快更重要。资源池做分组隔离离线批处理任务和即席查询任务分开跑互不影响。关于集群规模我的体会是千万级日增量、TB级数据量的汽车销售分析场景一个中型集群8台16核64G的服务器就够了堆硬件解决不了数据倾斜和代码低效的问题反而掩盖了真正的瓶颈。先优化代码再考虑加机器顺序不能反。8. 后续演进方向从“看懂过去”到“预测未来”项目走到这个阶段基本完成了从数据采集到分析展示的闭环。接下来的演进方向我自己的想法是分两条线。一条线往实时化走。目前销售数据是日级更新对于经营决策已经够了但线索数据、试驾数据其实可以做实时监控——线索进来后两小时没跟进系统就应该触发预警。这块要用Flink做实时流处理架构上把Kafka的流数据直接接入实时计算引擎而不是经过离线数仓链路。架构改动会比较大但业务价值非常明显。另一条线往预测性分析走。用历史销量数据做时间序列预测结合价格、促销、季节等因素预测未来两周各车型的销量走势。预测结果可以指导库存准备和营销资源分配。这块最理想的方案是训练一个专门的销量预测模型而不是用通用大模型来糊弄——大模型做预测需要的数据量、特征工程、评估体系和做文本生成完全是两回事。我给自己的规划是先把预测模型这条线做成一个独立模块基于Spark的MLlib做基础回归预测跑通后再引入更复杂的时序模型。预测结果的准确性评估要跑够三个月再做是否上线的判断不能急着给业务用。数据分析系统的功能可以求快但结论的可靠性必须求稳。最后说一句我做完这个项目最深的感受这类系统的落地难点从来不在某个单独的技术环节而在整条链路的通力配合——爬虫要稳定数仓要规范计算要高效大模型要可控可视化要好用任何一个环节掉链子整个系统的可信度就崩了。做之前先想清楚每个环节的边界和职责比闷头敲代码有用得多。