
简介这是一份面向企业营销、个性化推荐与客户洞察场景的智能用户画像分析系统完整源码包以大语言模型LLM为核心集成了用户行为分析、情感识别、消费习惯挖掘、价值观推断、动态标签生成、多源数据融合、自然语言处理与深度学习方法可同时处理结构化与非结构化数据适合算法工程师、数据产品经理及研究者学习参考。压缩包共28个文件以16个Python脚本为主另有Markdown说明文档、依赖配置文件及使用说明等整体仅144KB结构清晰便于快速定位与复现。目前已有282人在CSDN学习下载。资源内含核心模块与API接口目录并配有用户画像生成流程详解和核心功能说明能够帮助读者理解系统架构、掌握大模型接口调用方式并据此落地动态标签与多维画像构建。1. 从统计标签到活画像智能用户画像分析系统为什么绕不开LLM传统用户画像系统大多是统计标签机从订单表算RFM从日志算活跃频次然后打成固定标签。这套东西在电商、金融、内容平台跑了十几年但面对评论、工单、客服会话、社交媒体文本时就变成了黑匣子。基于大语言模型LLM的智能用户画像分析系统本质上是做一次多源数据融合把结构化行为数据和非结构化文本同时喂给模型输出情感倾向、消费习惯、价值观推断再结合深度学习排序模型生成动态标签。它不是替换传统标签体系而是给画像补上感知层和推断层。适合正在做用户增长、CRM、精细化运营手头有大量用户文本却不知道怎么下料的人。我按数据治理、Prompt设计、标签演进再到踩坑的顺序把整套工程方案拆给你。2. 多源数据融合与结构化治理先把用户画像的底料洗干净2.1 三类数据源分管道结构化字段、行为日志、非结构化文本真实项目里最普遍的状态是数据不缺缺的是能直接喂给LLM的数据。多源数据融合听起来高大上落地时第一步永远是盘点。我一般会把数据源分成三类。第一类是结构化数据用户注册表、订单表、商品表、会员等级表字段可靠但散落在不同库口径还经常不一致比如A库性别用1/2B库用男/女。第二类是半结构化行为日志埋点JSON、点击事件、浏览记录、客服会话记录量大、噪声大一张事件表动辄几亿行。第三类是非结构化文本商品评价、投诉工单、调研开放题、社交媒体评论这些是最有价值也最难处理的部分。在动手建任何模型之前先做三件事统一user_id把各端的会员IDopenID设备ID都映射到一个全局ID统一时区事件日志全部转成UTC8的本地时间否则跨天窗口和流失判断全是错的统一字段口径性别、城市、渠道码都转成同一套枚举。这三件事不做完后面LLM输出十个标签里有八个会串号。常见做法是把融合结果落到一张用户宽表。LLM推断时最怕现场joinToken成本和延迟都不可控。宽表里除了结构化字段还要预留text_summary、behavior_summary、vector_feature、updated_ts这几个位置它们是给LLM和深度学习模型用的摘要层。下面是基本的表结构你也可以在此基础上加is_active、data_source_weight等字段CREATE TABLE user_unified_profile ( user_id VARCHAR(64) PRIMARY KEY, gender STRING, age_group STRING, city_level INT, rfm_score DOUBLE, total_order_cnt INT, avg_order_value DOUBLE, last_active_ts BIGINT, -- 非结构化摘要 text_summary STRING, behavior_summary STRING, vector_feature ARRAYFLOAT, updated_ts BIGINT );为什么要用宽表而不是星型模型因为画像服务的调用方是实时推荐、营销触达、客服弹窗它们要的是一条记录里能看懂的画像不是几张表层层join。text_summary存清洗压缩后的文本摘要behavior_summary存近30天的行为事件序列摘要vector_feature存文本Embedding这三个字段是后面情感识别和消费习惯挖掘的直接输入。2.2 非结构化文本清洗与实体抽取规则快路径LLM慢路径很多方案直接把原始评论拼接后丢给LLM这是最快的翻车方式。原始评论文本里满是HTML片段、表情符号、手机号、订单号、口语重复LLM会把噪声当成特征还会把脱敏要求当成对话内容。文本清洗至少有四步去标签去控制字符手机号和证件号脱敏统一繁体简体和全角半角对超长文本做截断。截断长度建议控制在LLM上下文的一半以内比如模型支持8K就截到3K字符留一半空间给Prompt和输出。实体抽取这里我建议走混合策略。高频、格式化的实体用正则和词表快路径比如手机号、订单号、金额、日期正则一秒钟扫完几万条低频或需要语义判断的实体比如空调外机声音大里的噪音问题、物流到门口不给送里的配送服务才交给LLM。这样能省下很大一块Token成本。下面这段是常用的清洗与快路径截取逻辑慢路径只留一个接口import re def clean_text(raw: str, max_len: int 3000) - str: # 去掉HTML标签、控制字符 t re.sub(r[^], , raw) t re.sub(r[\x00-\x08\x0b\x0c\x0e-\x1f], , t) # 表情符换占位符避免打乱相邻语义 t re.sub(r[\U00010000-\U0010ffff], [emoji], t) # 业务脱敏 t re.sub(r1[3-9]\d{9}, [phone], t) t re.sub(r\d{17}[\dXx], [idcard], t) # 压缩空白 t re.sub(r\s, , t) return t[:max_len]清洗后的文本再做实体抽取。快路径用正则找金额、时间、地址找情绪触发词比如失望太贵再也不这些用词表就够了。真正需要LLM的是对象问题的抽取比如吹了一晚上还是不凉快要抽成目标空调制冷、问题制冷效果差。这一步的产出会直接进text_summary所以宁可少抽不要错抽错抽的标签比没有标签更难纠正。2.3 向量化与多源特征融合Embedding不是越贵越好对齐才关键多源数据融合的最后一步是把三种形态的特征放到同一个向量空间里。文本通过Embedding模型转成向量行为序列通过聚合统计转成数值特征比如近7天浏览次数、平均决策时长、价格带偏好结构化字段直接做标准化和One-Hot。但这里有一个非常容易踩的坑三种特征维度差距太大直接concat会把文本向量淹没在高维稀疏里。常见做法是给三种特征分别降维再拼接。如果文本Embedding是768维先用PCA压到128维行为统计这组通常有几十个字段保留最终有效的16个结构化字段做成32维的编码。我一般不追求端到端的深度网络做融合生产环境里特征拼接可解释性强的模型比如XGBoost或LR更容易上线和维护。融合后的向量存到user_unified_profile.vector_feature同时把原始特征名和归一化参数存一份配置表不然模型迭代后根本不知道向量是什么含义。下面是融合的示意代码import numpy as np def fuse_features(text_emb, behavior_stats, structured_vec, keep_dim128): # 文本向量先降维行为与结构字段只保留有效位 if len(text_emb) keep_dim: # 生产上建议用PCA拟合后transformed这里做切分示例 text_emb np.array(text_emb[:keep_dim]) fused np.concatenate([ np.array(text_emb), np.array(behavior_stats[:keep_dim // 8]), np.array(structured_vec[:keep_dim // 4]) ]) return fused这里的参数不是拍脑袋定的文本占128行为统计占16结构化字段占32是因为实际业务里文本对情感、价值观的贡献最大行为统计次之结构化字段往往只有性别、城市、等级这几个强特征。如果你的业务是金融风控结构化字段的权重可能就要反过来所以这个维度分配应该由一次离线实验的SHAP值来定而不是抄网上的配置。多源数据融合的核心是对齐不只是维度对齐还有时间对齐——行为日志和文本必须落在同一个统计窗口内否则拿过去三个月的评论和过去一周的行为去推断消费习惯必然互相打架。提示Embedding模型的选择有玄学成分但不要迷信榜单。同一个用户的价格敏感和品质偏好文字向量在欧氏空间里可能很近真正区分度要靠下游标签模型去学。所以别在Embedding上花太多钱够用、版本可控就好。3. 用LLM做情感识别和消费习惯挖掘Prompt、Schema与行为序列怎么配3.1 情感识别不直接问高兴还是生气加维度、加强度、加证据用户画像里的情感识别和通用情感分析完全是两码事。通用模型输出正向/负向/中性就完事画像系统需要的是用户对什么不满、不满到什么程度、原文哪句话触发的这样运营才能知道是补发货还是改话术。所以我建议把情感识别任务拆成四元组情感类别、强度、目标对象、触发句。情感类别不只是正负中性还要有混合情绪比如物流慢但客服态度好。Prompt里最关键的不是提示词文采而是输出约束和样例。下面是我在生产里用过的模板temperature必须设为0否则同一句评文每次识别的结果都可能不同标签一不稳定下游就没人信SENTIMENT_PROMPT 你是用户洞察助手。请对下面的用户文本做细粒度情感识别。 输出JSON不允许输出其他内容 { emotion: positive|negative|neutral|mixed, strength: 1, target: 商品|物流|价格|服务|渠道|其他, trigger: 原文触发句 } 强度用1到5的整数5表示情绪极强。 如果文本中没有明确对象target填整体。 用户文本 {text} 这里有个细节strength用1-5而不是0-1因为业务方对5分制更习惯而且打散到5档比连续值好做质检。每类情感至少给一个few-shot示例尤其是mixed类型不然模型默认输出正负二分类。情感识别的结果要回写到宽表的text_summary比如价格敏感度4/5物流不满触发句‘一周才到’这样后续做消费习惯挖掘时才不会丢失上下文。3.2 消费习惯挖掘让LLM读事件流而不是读统计表用户行为分析里最容易犯的错是把统计表直接塞给大模型近30天客单价120元复购3次品类偏好家电/美妆这种输入LLM只能复述挖不出什么习惯。真正的消费习惯藏在事件流里比如满减券生效前加购生效后才下单深夜反复比较两个品牌最后选了便宜那个这些模式只有把事件按时间排开才能看出来。因此我构建行为序列时坚持事件流摘要双路输入。事件流是最近N次关键动作的排序压缩摘要是对应窗口内的统计值。N不宜太大30条以内足够太多会稀释注意力太长Token成本也会失控。行为序列的每条事件需要包含时间、动作、品类、金额、渠道这五个要素下面是构造代码def build_behavior_sequence(events, max_events30): # events: [{ts:2025-04-01 12:00,action:view,category:空调,price:2999,channel:app}] events.sort(keylambda x: x[ts]) lines [] for e in events[-max_events:]: lines.append( f{e[ts][:10]} {e[action]} {e[category]} f金额{e.get(price, 0)} 渠道{e.get(channel, )} ) return \n.join(lines)把这段序列和一段摘要例如近30天浏览15次、加购6次、下单3次客单价均值2500一起放进Prompt再问LLM推断这个用户的消费习惯、决策周期、价格敏感度和促销偏好。输出用JSON字段固定。你会发现模型能说出价格敏感但愿意为空调这类高卷入商品承受较高单价这才是消费习惯挖掘的价值。要注意光读事件流远远不够还要把场景告诉LLM比如这是电商还是本地生活否则模型会把外卖的消费频次和买家电的频次混在一起。3.3 结构化输出不被大模型幻觉带偏JSON Schema、重试与置信度大模型做信息抽取时幻觉集中在两处一是格式幻觉输出里夹解释、多括号、字段名拼错二是内容幻觉用户没提到的特征模型根据刻板印象脑补比如看到女生就推断美妆偏好。格式问题靠约束生成和解析兜底能解决内容问题必须靠证据。对于JSON输出我建议做三层防线。第一层Prompt里给JSON Schema的明确样例并重复只输出JSON。第二层代码里用json.loads尝试解析失败后做一次修复重试——把上一次原始输出拼接进Prompt要求模型纠正错误。第三层如果重试还失败丢弃该条不返回半成品。修复重试的参数设为2次就好超过2次就该怀疑文本质量了。同时给每个标签附带着conf字段模型自己的置信度虽然不完美但可以用来做下游加权。数值型、风险型标签尤其要抑制幻觉对用户画像来说一个错误的价值观推断可能直接影响推荐策略。所以价值观推断这种任务我倾向让模型输出支持该推断的用户原话片段后续校验时只要对不上原文就打回。情感识别和消费习惯挖掘也一样所有触发句必须能从原始文本里找到否则宁可放弃这条标签。把证据和标签一起存储也是将来人工审核和模型迭代少吵架的基础。4. 动态标签生成与画像更新从算一次到自动演进4.1 标签体系分层事实、规则、模型、LLM推断谁也不能越权很多团队接入LLM后第一反应是让模型把所有标签都改成智能标签这是最伤的做法。画像标签必须有层级否则一旦LLM抽风整个用户群都会被带偏。我习惯把标签分成四层事实标签、规则标签、模型标签、LLM推断标签。事实标签来自用户自己填写或系统行为比如性别、注册渠道、实名状态这类标签不可由模型覆盖规则标签由业务规则产生例如近30天无购买流失预警、订单金额Top10%高价值这类标签稳定、可解释模型标签来自深度学习模型或机器学习模型比如购买概率、流失概率对时效有要求LLM推断标签则负责语义推断比如情感倾向、消费价值观、品牌偏好是这层体系里唯一能读出非结构化数据信息的层。为什么要分层而不是让LLM接管所有因为召回、营销、风控的下游系统对标签的可解释性和稳定性要求不同。规则标签的稳定性最适合人群圈选模型标签的分数适合做排序LLM标签适合做内容理解和时机判断。四层之间必须有优先级当两处标签冲突时事实层 规则层 模型层 LLM推断层。比如用户填写的职业是教师LLM从评论推断可能是个体户那以事实为准LLM推断只能作为补充标签。下面这张表可以贴在项目文档里避免业务方反复来问标签层示例更新方式冲突优先级事实标签性别、城市、注册来源实时同步最高规则标签近30天未购买、高价值离线定时次高模型标签购买概率、流失概率模型推理中LLM推断标签价格敏感、注重品质、情感倾向任务触发/定时批跑低4.2 动态画像更新时间窗口、衰减和版本控制动态标签生成不是一条SQL跑完就完它需要一套自动演进机制。用户画像随时间会变三个月前的消费习惯可能已经不适合现在的推荐。常见做法是给不同标签配置不同生命周期基础属性如年龄、性别变化慢可以30天复核一次消费偏好、情感状态变化快7到14天就要重算即时意图类标签应该实时更新比如用户正浏览某个品类时打上当前兴趣。我一般会为每个标签配一个时间衰减权重越久远的信号权重越低。比如计算价格敏感度时近7天的消费行为权重是0.78到30天权重0.230天以上0.1。这个衰减系数不是死值要根据业务节奏调整大促期间衰减要调慢否则把促销季的狂热购买算成常态大促一结束画像就失真。给一段处理代码def decaying_weights(event_days_ago, half_life14): # half_life越大越看重历史行为越小越聚焦近期 return 0.5 ** (event_days_ago / half_life) # 示例近7天、14天、30天权重 for days in [7, 14, 30]: print(days, round(decaying_weights(days), 3))输出权重大概是7天0.70814天0.530天0.225。这样算出来的画像比简单事件计数要平滑。版本控制也很重要LLM本身就是易变的。模型版本升级、Prompt调整甚至换Embedding模型都会让同一用户的标签发生变化。所以在user_unified_profile里要记录profile_version、prompt_version、build_time下游应用只能读取最新有效版本的画像做分析的人如果要看趋势应该对比同一版本号内的历史快照跨版本不能直接比。4.3 冷启动与多源冲突没有历史文本时怎么推断价值观一个真实的用户画像是从零开始的。新注册用户没有评价没有行为日志只有手机号和注册渠道。这时候LLM并不能无中生有。我的做法是把冷启动分成两段基础画像先由规则标签和注册信息填比如城市、渠道、首单品类价值观推断类标签不做而是挂起等积累到至少3条有效文本或者5次关键行为后才尝试否则模型只能靠着性别年龄做刻板猜测这样的标签放出去不如不放。多源冲突也是动态标签生成的常客。用户文本里说最讨厌贵的东西但订单记录显示他刚下单了一个奢侈品包。这不是标签错误是数据源信息冲突。处理冲突不能简单取平均而要加置信度。通常结构化订单的置信度高文本推断置信度低但文本里如果带有明确情绪词且多条一致置信度就要上调。冲突发生后给标签打上conflict_flag进人工审核队列。动态标签生成一定要有兜底靠规则、模型和LLM推断三层互相校验系统才不会崩在个别嘴硬但手很诚实的用户身上。5. 落地避坑LLM用户画像最容易翻车的5个细节5.1 标签漂移同一用户昨天高消费今天变低消费原因多半是温度没归零现象同一批用户画像每天跑批标签在价格敏感/价格不敏感之间反复横跳下游营销策略不敢自动执行整个人群包完全失效。现象背后不是模型坏了而是推理参数没固定。很多调用的默认temperature是非0的输出带有随机性导致同样的输入跑两次结果不同。原因LLM推断标签没有设置temperature0也没有固定seed同时Prompt里缺少约束模型在自己脑补标签自然不稳定。解决在服务封装里强制temperature0对所有画像生成类任务关闭采样随机性必要时设置seed并固定模型版本同时把标签证据置信度写入结果表对于strength相对低的标签做状态位标记不进自动决策链路。这一条是LLM画像系统的地基不处理后面全是无底洞。判断漂移还有一种更快的办法把用户最近三天的标签历史拉出来如果同一个标签在版本间变更幅度超过阈值自动进观察名单。5.2 Token成本爆炸直接把全量日志喂给LLM一个月账单能吓到预算负责人现象开始几天效果惊艳月底成本报表出来发现模型的token消耗占了预算的一大半业务方直接叫停。原因伪多源融合把所有行为数据和评论文本全部拼接进Prompt每条用户序列达到成千上万token。尤其在大促和月底日志量翻倍成本线性上涨。解决重新设计输入裁剪策略。规则和正则能处理的事不要交给LLM格式化、脱敏、高频实体抽取都由规则处理LLM只消费摘要证据片段。对行为序列先聚合事件限制在30条以内对长文本先做摘要再让模型基于摘要推断。给每个标签制定token预算上限。比如单用户单次画像生成控制在800token以内超出后削减事件数和文本长度。如果预算还是超就降低非核心标签的重算频率把最贵的情感识别和价值观推断从日更改成周更核心规则标签继续日更。宁可让推断层慢一点也要保住主链路的稳定。5.3 价值观推断引发用户投诉问题出在越权判断现象某用户收到一封你的生活品味偏低的营销文案火很大投诉到客服。原因是价值观推断覆盖到了不该碰的领域或者模型基于数据做了过度推断。价值观本身是主观判断我们做画像只应该碰消费价值观追求性价比还是追求品牌不要上升到人格评价。一位用户下单便宜商品不代表他可以被打上低价值标签。原因标签体系里缺少价值观推断的禁区。性别、年龄、地域、民族这些人口属性不能作为推断依据模型容易从这些词里脑补出歧视性结论这是做智能画像最危险的地方。解决在Prompt里明确禁止依据人口属性推断对价值观标签设只给建议不下定义的规范所有标签必须附原文证据做上线前小范围人工评估抽取样本看标签是否会造成冒犯。遇到敏感标签直接弃用不做风险评估的价值观推断就是在高级场合搞低级冒犯这种坑踩一次就够。5.4 多源标签冲突导致自动化投放翻车没有仲裁机制现象规则标签认为高价值用户LLM标签认为消费力萎缩两者同时触发自动化投放结果该发优惠券的收到涨价通知。原因这两类标签来源不同业务上没有定义优先级下游系统拿到冲突结果后随机选了一个这属于典型的标签打架。解决在画像服务层建立标签冲突仲裁。事实、规则、模型、LLM推断的优先级固定冲突时默认取高优先级同时把LLM推断的字段保存为推断层供人工分析不直接覆盖决策用字段。自动化投放只允许读取某几个层级敏感策略还要加人工兜底。更细一步给每个标签加来源字段和更新时间下游取数时按高优先级最近更新排序。如果还有冲突就触发一个简单的规则取置信度高的那条。仲裁逻辑做成配置表别写死在代码里业务策略经常变配置化才能快速调。5.5 模型升级后历史画像全部不可比换Embedding模型不是换个库那么轻松现象为了效果把Embedding模型从A换到B结果全量用户的相似度分数和画像分布大变运营怀疑系统出bug了。原因不同Embedding模型的向量空间不是对齐的直接把新旧向量混合用肯定不可比。你升级模型后所有基于向量相似度的业务——相似人群、聚类分析、推荐召回——都会面目全非。解决模型升级不直接替换要在旁边起一个shadow service新旧模型并行跑一段时间对比标签分布的变化。对比指标包括同一批用户的标签命中率、标签幅度均值、Top类目排序的KR距离。正式切换前用历史数据重算一遍关键标签并把旧向量保存在历史表里。对画像分析来说连续性比最新的精度更重要。升级完成后要发布一个版本变更说明告诉下游哪些标签是重算过的哪些是旧的避免业务方拿旧画像做决策。这件事做好了升级才叫升级否则就是给自己挖坑。6. 画像素描与验证把画像系统从能跑做到可信画像系统上线后最重要的一步是验证不是dashboard。我每次都会做一套小样本质检随机抽200个用户覆盖不同渠道、注册时长、消费区间把系统输出的情感、消费习惯、价值观标签和有经验的运营人员标注结果对比计算一致率。一致率低于70%先回去修Prompt不要急着全量开放。这个质检要定期跑因为LLM行为不是一成不变的换模型、换Prompt、换数据窗口都可能改变分布。第二步是用LLM as Judge做自动化粗筛。选一个综合能力更强的模型当裁判让它对照原文证据标签判断标签是否吻合。虽然LLM as Judge也有自己的偏差但用来筛掉明显离谱的标签很高效。粗筛后人工只需要复核那些存疑样本而不是看全量数据。需要看结果一致性也可以参考公开的基准测试或榜单来做模型选择但最终一定要在自己业务数据上跑一轮质检通用能力好和业务适配好是两回事。最后给每个标签穿三层验证外衣证据原文、置信度、有效期。没有证据的标签不上线置信度低于阈值的标签只做展示不做决策过了有效期没有重新计算标签自动过期失效。环境里把prompt版本、模型版本、日期都记录下来这些是一个画像系统可信的地基比任何模型换血都重要。我刚做这个方向时也被智能画像四个字带偏过想着一个模型解决所有问题。后来我发现可靠比聪明值钱得多。给模型让出一点想象力把证据和版本管好这钱才花得值。希望帮到你。本文还有配套的精品资源点击获取