当前位置: 首页 > news >正文

从语义到推荐:大语言模型(LLM)如何驱动智能选车系统?

近年来,随着大语言模型(LLM, Large Language Model)在自然语言理解上的突破,传统推荐系统也迎来了一次全新的“语言驱动”升级。本文将以我开发的“AI 智能选车助手”为例,介绍 LLM 在智能决策系统中的角色,以及我们是如何将“自然语言需求”转化为“结构化推荐逻辑”的。

🎯 用户痛点:选车不想填表格,只想说人话

传统的购车推荐系统往往依赖用户去填写各种选项:

  • 用途?

  • 座位数?

  • 动力类型?

  • 预算区间?

这种方式虽然精确,但用户体验不够自然,也缺乏智能性。

然而现在,用户只需要说一句:

“我想买辆适合家庭出行的中型 SUV,预算二十万以内,续航最好超过 800 公里。”

我们就能把这句话转化为精准的推荐结果——这背后,靠的正是大语言模型。

🧠 模型能力:让 LLM 来理解你的购车需求

大语言模型的强大之处在于:

  • 能理解非结构化语义

  • 能输出结构化数据

  • 能补全用户未明确提及的信息

  • 能学会领域专业术语(如车辆类型、动力形式等)。


🔢 实现方式:从语义结构到精准评分

我们为每辆车打分的方式如下:

属性维度评分方式
预算范围区间匹配 + 容差惩罚
用途/类型精准匹配打满分
动力匹配完全匹配双倍得分,插混与油混兼容打1.5倍
能耗/电耗按动力类型区分单位(L/100km vs kWh/100km)
续航/座位数模糊评分(越接近用户需求得分越高)

评分函数样例:

def range_score(value, target, tolerance, weight):delta = abs(value - target)return weight * (1 - delta / tolerance) if delta <= tolerance else 0

最终的推荐结果是将得分排序,返回匹配度最高的 N 辆车。


💡 创新点:LLM + 评分引擎的组合价值

这个系统的亮点并不在于推荐算法本身,而在于LLM 所赋予的前端语义接口能力

传统方法LLM 驱动的智能推荐
用户需逐项填写参数用户只需描述一句话
推荐逻辑死板可调整权重灵活打分
无法理解模糊语言可理解“长续航”、“适合家用”等词
不会补全默认值LLM 会自动填默认意图

这使得推荐系统从“选项列表”升级为“自然语言交互”系统,用户体验显著提升。


🏗️ 系统架构与技术栈

模块技术
前端界面Streamlit
模型接口Moonshot / OpenAI GPT-4 LLM
数据处理Pandas, JSON 数据库
可视化输出DataFrame + CSV 导出
能耗识别逻辑动态单位判别(L vs kWh)
编程语言Python 3.10+

🔄 核心功能实现

1. 自然语言解析模块(query_kimi)

  • 接收用户输入的购车意图(自然语言)

  • 调用 Moonshot/GPT 接口,输入自定义 System Prompt

  • 模型输出标准化 JSON 结构,包含:

    • 需求 字段:包含用途、预算、动力、续航等

    • 权重 字段:各指标重要性,用于个性化评分

示例输出:

{"需求": {"用途": "家庭出行","预算区间": {"min": 0, "max": 200000},"动力类型": "油电混合","能耗上限": 7.0,"续航需求_km": 800},"权重": {"用途": 1,"预算区间": 3,"动力类型": 2,"能耗上限": 2,"续航需求_km": 2}
}

✨ 亮点:即使用户没有明确提及某个参数(如驱动方式),模型也会补全合理的默认值。


2. 车辆数据库与结构化评分模块(score_car)

系统加载一份包含 1000 款汽车的 JSON 数据集,字段包括:

  • 名称、价格区间、动力类型、用途、续航、电耗/油耗、驱动方式、座位数等

评分逻辑包含:

维度匹配方式说明
用途/类型精准匹配得满分
动力类型完全匹配加倍得分,油电与插混视为兼容加权
价格/预算区间匹配 + 容差评分
能耗评分根据动力类型判断单位:L/100km 或 kWh/100km
续航评分容差 ±200km 内逐步减分

函数示例:

def range_score(value, target, tolerance, weight):delta = abs(value - target)return weight * (1 - delta / tolerance) if delta <= tolerance else 0

3. 推荐函数(recommend_car)

  • 批量对所有车辆打分

  • 按得分降序排列

  • 保留预算内且座位数符合的车型

  • 返回前 N 个最优推荐


4. Streamlit 图形界面(your_script.py)

  • 用户输入自然语言

  • 可手动设置权重(8个评分维度)

  • 实时展示推荐结果

  • 支持 CSV 文件导出

  • 自动识别电车/油车并切换能耗单位显示(kWh or L)

🌟 亮点:权重调整后即时影响推荐排序,用户控制力强。


📁 项目结构

project/
├── ai_car_selector_kimi.py   # 主推荐逻辑 + LLM接口
├── your_script.py            # Streamlit界面逻辑
├── vehicle_db_1000_named.json # 汽车数据库

📥 依赖安装

使用 pip 安装依赖:

pip install -r requirements.txt

requirements.txt 示例内容:

openai
streamlit
pandas
numpy

🚀 运行系统

Step 1:准备 API Key

你需要一个 Moonshot 或 OpenAI 的 API 密钥。如果你使用 Moonshot,可以在界面输入:

sk-xxxxxxxxxxxxxxxxxxxx

也可以设置为环境变量:

export MOONSHOT_API_KEY=sk-xxxxxxx

Step 2:启动界面(Streamlit)

streamlit run your_script.py

然后浏览器会自动打开界面,或访问:

http://localhost:8501

📌 使用方式

  1. 输入自然语言购车需求,如:

    我想买一辆适合城市代步的纯电车,预算15万以内,续航不要低于400公里
  2. 选择展示推荐的数量(Top-N)

  3. (可选)展开“高级设置”自定义评分权重(如:更注重动力类型、续航等)

  4. 点击“开始智能选车”按钮

  5. 查看推荐表格,并可导出 CSV 文件

📁 代码说明 

 ai_car_selector_kimi.py 

import os  # 用于访问环境变量
import json  # 用于解析和生成 JSON 数据
import pandas as pd  # 用于处理结构化数据
from openai import OpenAI  # 导入 OpenAI 接口客户端MOONSHOT_API_KEY = os.getenv("MOONSHOT_API_KEY", "sk-****************")  # 从环境变量获取 API 密钥,或使用默认密钥,这里需要自己修改
client = OpenAI(api_key=MOONSHOT_API_KEY, base_url="https://api.moonshot.cn/v1")  # 初始化 OpenAI 客户端,设置 base_url 为 moonshot 接口
MODEL_NAME = "moonshot-v1-8k"  # 使用的模型名称
VEHICLE_DB = "vehicle_db_1000_named.json"  # 本地车辆数据库文件名SYSTEM_PROMPT = """  # 系统提示词,定义 AI 应该如何将用户意图结构化为标准 JSON
你是一名资深汽车顾问,根据用户的自然语言购车需求,严格生成符合以下格式和要求的 JSON 数据。
【必填字段】以下字段必须提供,若用户未明确指出,请使用指定默认值:
- 用途(可选项:家庭出行、城市代步、商务接待、长途出行、运动旅行、越野探险;默认:"家庭出行")
- 车辆类型(可选项:中型SUV、小型掀背、大型轿车、旅行车、房车、小型两厢、Coupe、MPV、硬派SUV、皮卡;默认:"中型SUV")
- 预算区间(格式:{"min": 数字, "max": 数字},默认:{"min": 0, "max": 200000})
- 座位数(整数,默认:5)
- 动力类型(可选项:油电混合、纯电、3.0T汽油、1.6L汽油、插电混动、2.5L汽油、氢燃料电池;默认:"油电混合")
- 驱动方式(可选项:两驱、前驱、后驱、四驱;默认:"两驱")
- 续航需求_km(单位:公里,默认:800)
- 能耗上限(数字,单位根据动力类型自动判定:燃油车为 L/100km,电动车为 kWh/100km;默认:7.0)
【说明】
- 无需让用户输入单位,系统将自动判断。
- “能耗上限”代表用户希望的最大单位能耗,不论是油耗还是电耗。
【硬性筛选规则】
1. 车辆价格超出预算直接排除。
2. 车辆座位数不足直接排除。
【输出格式】
仅输出以下 JSON 格式,不要添加任何多余内容:
{"需求": {"用途": "...","车辆类型": "...","预算区间": { "min": ..., "max": ... },"座位数": ...,"动力类型": "...","驱动方式": "...","续航需求_km": ...,"能耗上限": ...},"权重": {"用途": 数字,"车辆类型": 数字,"预算区间": 数字,"座位数": 数字,"动力类型": 数字,"驱动方式": 数字,"续航需求_km": 数字,"能耗上限": 数字}
}
请严格遵守字段名、格式和选项要求,确保字段齐全,不可遗漏。
"""def query_kimi(user_text: str) -> dict:  # 向 Moonshot 请求,将用户自然语言转换为结构化需求 JSONcompletion = client.chat.completions.create(model=MODEL_NAME,messages=[{"role": "system", "content": SYSTEM_PROMPT},{"role": "user", "content": user_text}],temperature=0.3,)return json.loads(completion.choices[0].message.content)  # 解析模型返回内容为 dict 格式def normalize_weights(weights):  # 权重归一化,确保总和为 1total = sum(weights.values())return {k: v / total for k, v in weights.items()} if total else weightsdef range_score(value, target, tolerance, weight):  # 根据偏差计算得分,允许在一定容差范围内递减delta = abs(value - target)return weight * (1 - delta / tolerance) if delta <= tolerance else 0def score_car(car, spec, w):  # 对单辆车进行打分,按需求与权重进行匹配度评估score = 0.0w = normalize_weights(w)  # 首先归一化权重try:lo, hi = car["价格区间"].replace("万人民币", "").split("-")  # 提取价格区间car_price = (int(lo) + int(hi)) * 5000  # 取中值并转为元单位bmin, bmax = spec["预算区间"]["min"], spec["预算区间"]["max"]if bmin <= car_price <= bmax:score += w["预算区间"]  # 价格在预算内,加满分else:score += range_score(car_price, (bmin + bmax) / 2, 100000, w["预算区间"])  # 不在预算范围内但允许容差except: pass  # 异常跳过价格评分seat_diff = abs(car["座位数"] - spec["座位数"])  # 计算座位差异score += w["座位数"] * {0:1.0,1:0.75,2:0.5}.get(seat_diff, -0.1)  # 根据差异进行加权打分if car["用途"] == spec["用途"]: score += w["用途"]  # 用途匹配加分if car["车辆类型"] == spec["车辆类型"]: score += w["车辆类型"]  # 类型匹配加分if car["驱动方式"] == spec["驱动方式"]: score += w["驱动方式"]  # 驱动方式匹配加分if car["动力类型"] == spec["动力类型"]:score += w["动力类型"] * 2  # 完全匹配动力类型,权重加倍elif (car["动力类型"], spec["动力类型"]) in [("油电混合", "插电混动"), ("插电混动", "油电混合")]:score += w["动力类型"] * 1.5  # 类似动力匹配,加权较高分try:energy_value = float(car["油耗/电耗"].split()[0])  # 提取能耗数值if car["动力类型"] in ["纯电", "氢燃料电池"]:score += range_score(energy_value, spec["能耗上限"], 5, w["能耗上限"])  # 电车能耗评分score += range_score(int(car["续航/续驶里程"].split()[0]), spec["续航需求_km"], 200, w["续航需求_km"])  # 电车续航评分else:score += range_score(energy_value, spec["能耗上限"], 2, w["能耗上限"])  # 油车能耗评分except: pass  # 解析失败则跳过能耗评分return round(score, 2)  # 最终得分保留两位小数def recommend_car(user_query: str, top_n: int = 3, custom_weights: dict = None, custom_spec: dict = None):  # 推荐车辆主函数if custom_spec is None:ai_resp = query_kimi(user_query)  # 若无自定义需求,调用 Kimi 获取结构化需求spec = ai_resp["需求"]else:spec = custom_spec  # 使用传入的需求规范weights = custom_weights or query_kimi(user_query)["权重"]  # 使用自定义或 AI 提供的权重df = pd.read_json(VEHICLE_DB, orient="records")  # 读取车辆数据库为 DataFramedf["score"] = df.apply(lambda row: score_car(row, spec, weights), axis=1)  # 逐行计算得分return df.sort_values(["score", "价格区间"], ascending=[False, True]).head(top_n)[  # 根据得分和价格排序取前 top_n["id", "名称", "价格区间", "用途", "车辆类型", "动力类型", "驱动方式", "座位数", "续航/续驶里程", "油耗/电耗", "score"]]

 your_script.py 

import os  # 操作系统相关模块,用于设置环境变量等
import streamlit as st  # 引入 Streamlit 库,用于构建 Web 应用界面
from ai_car_selector_kimi import recommend_car, query_kimi  # 从自定义模块导入推荐函数和 Kimi 查询函数st.set_page_config(page_title="🚘 AI 智能选车助手", layout="centered")  # 设置网页标题和布局
st.title("🚗 AI 智能选车助手")  # 页面主标题st.markdown("**请输入你的购车需求**(如:我想买一辆适合家庭出行的中型SUV,预算20万以内,最好油电混合,续航超过800公里):")  # 输入提示
user_query = st.text_area("购车需求", height=120)  # 多行文本输入框用于填写用户需求
top_n = st.slider("展示前 N 个推荐结果", 1, 10, value=3)  # 滑动条选择推荐结果数量# 自动判断默认单位(简化逻辑处理)
default_unit = "L/100km"  # 默认是油耗单位
if any(x in user_query for x in ["纯电", "电动", "电车", "氢", "氢燃料"]):  # 如果用户提到电车/氢能源default_unit = "kWh/100km"  # 更换为电耗单位with st.expander("⚖️ 高级设置:自定义评分权重(可选)"):  # 可展开的区域用于设置评分权重weight_inputs = {"用途": st.slider("用途 权重", 0, 5, 1),  # 各评分项使用滑动条设置权重"车辆类型": st.slider("车辆类型 权重", 0, 5, 1),"预算区间": st.slider("预算区间 权重", 0, 5, 1),"座位数": st.slider("座位数 权重", 0, 5, 1),"动力类型": st.slider("动力类型 权重", 0, 5, 1),"驱动方式": st.slider("驱动方式 权重", 0, 5, 1),"续航需求_km": st.slider("续航需求_km 权重", 0, 5, 1),"能耗上限": st.slider(f"能耗上限(单位:{default_unit}) 权重", 0, 5, 1),}with st.expander("🔐 API Key 设置(当前会话内有效)"):  # 可展开区域用于输入自定义 API Keycustom_key = st.text_input("Moonshot API Key", type="password")  # 输入框(隐藏密码)if custom_key:  # 如果用户提供了 keyos.environ["MOONSHOT_API_KEY"] = custom_key  # 设置为当前环境变量,覆盖默认 keyif st.button("开始智能选车 🚀"):  # 点击按钮开始推荐流程if not user_query.strip():  # 如果输入为空st.error("请输入购车需求")  # 显示错误提示st.stop()  # 停止运行with st.spinner("正在匹配推荐车型…"):  # 显示加载状态提示try:ai_resp = query_kimi(user_query)  # 调用 LLM 接口获取结构化需求与权重spec = ai_resp["需求"]  # 提取需求字段if any(val > 0 for val in weight_inputs.values()):  # 如果用户自定义了权重weights = weight_inputs  # 使用用户定义权重st.info("✅ 使用手动设置的评分权重")else:weights = ai_resp["权重"]  # 否则使用 AI 推荐的权重st.info("⚠️ 使用 AI 自动推荐权重")st.subheader("AI 分析出的购车需求:")  # 显示需求st.json(spec)  # 用 JSON 格式展示需求st.write("**使用的评分权重:**")  # 展示权重标题st.json(weights)  # 展示权重内容result_df = recommend_car(  # 调用推荐函数user_query=user_query,top_n=top_n,custom_weights=weights,custom_spec=spec)except Exception as e:  # 捕获异常st.error(f"调用失败:{e}")  # 显示错误信息st.stop()  # 停止运行if result_df.empty:  # 如果结果为空st.warning("未找到符合条件的车型,请调整条件重试。")  # 提示用户修改条件else:st.success("✅ 推荐完成,以下是匹配度最高的车型:")  # 成功提示st.dataframe(result_df.rename(columns={  # 重命名列标题并显示为表格"id": "车型ID","名称": "名称","价格区间": "价格","用途": "用途","车辆类型": "类型","动力类型": "动力","驱动方式": "驱动","座位数": "座位","续航/续驶里程": "续航","油耗/电耗": "油耗","score": "得分"}), use_container_width=True)st.download_button(  # 提供下载按钮"📥 下载推荐结果 CSV",  # 按钮标题data=result_df.to_csv(index=False, encoding="utf-8-sig"),  # 下载内容为 CSV 格式数据file_name="car_recommendations.csv",  # 下载文件名mime="text/csv"  # 文件类型)

vehicle_db_1000_named.json(部分如下)

  {"id": "car0001","名称": "日产·宝马4系 Pro","用途": "越野探险","车辆类型": "Coupe","价格区间": "56-77万人民币","动力类型": "氢燃料电池","驱动方式": "两驱","座位数": 4,"续航/续驶里程": "651 km","油耗/电耗": "17.1 kWh/100km"},{"id": "car0002","名称": "法拉利·GL8 Max","用途": "商务接待","车辆类型": "MPV","价格区间": "245-257万人民币","动力类型": "油电混合","驱动方式": "前驱","座位数": 7,"续航/续驶里程": "334 km","油耗/电耗": "12.9 L/100km"},{"id": "car0003","名称": "现代·骐达 Max","用途": "商务接待","车辆类型": "小型两厢","价格区间": "28-51万人民币","动力类型": "2.5L汽油","驱动方式": "后驱","座位数": 5,"续航/续驶里程": "311 km","油耗/电耗": "7.8 L/100km"}

相关文章:

  • 蚂蚁百宝箱快速创建智能体AI小程序
  • 【入门级-基础知识与编程环境:计算机的基本构成 (CPU、内存、I/O设备等)】
  • 【算法一周目】分而治之,归并如风:算法中的美学与哲理
  • IEC61850 一致性测试中的 UCA 测试
  • AI大模型学习之基础数学:高斯分布-AI大模型概率统计的基石
  • `toRaw` 与 `markRaw`:Vue3 响应式系统的细粒度控制
  • ad24智能pdf输出的装配图没有四个边角那里的圆孔
  • 学习C++、QT---03(C++的输入输出、C++的基本数据类型介绍)
  • GO语言---数组
  • `teleport` 传送 API 的使用:在 Vue 3 中的最佳实践
  • ffmpeg(七):直播相关命令
  • Python列表常用操作方法
  • 爱高集团引领转型浪潮:AI与区块链驱动香港科技资本新机遇
  • GitHub Copilot快捷键
  • 【AGI】突破感知-决策边界:VLA-具身智能2.0
  • 力扣-72.编辑距离
  • Qt输入数据验证的方法
  • 在 `setup` 函数中使用 Vuex
  • XCVU47P-2FSVH2892E Xilinx Virtex UltraScale+ FPGA AMD
  • 华为OD机试_2025 B卷_判断一组不等式是否满足约束并输出最大差(Python,100分)(附详细解题思路)
  • 扬州网站优化/百度指数专业版价格
  • 郑州高新区做网站开发的公司/如何在互联网推广自己的产品
  • 如何申请域名做网站知乎/万网域名注册查询
  • 销售网站怎么做/软文标题和内容
  • html制作网站的步骤/东莞网站建设推广技巧
  • 中国企业公司/搜索引擎优化的意思