尧图建网站 尧图建网站 YAOTU WEB BUILD 免费咨询
ARTICLE DETAIL

资讯详情

深耕网站建设与建站编程的一线实战洞察。

基于LLM与情境感知的智能餐饮推荐系统架构与实现

基于LLM与情境感知的智能餐饮推荐系统架构与实现 1. 项目概述当AI美食家学会“看天吃饭”与“入乡随俗”最近在捣鼓一个挺有意思的项目我把它叫做“会看天、懂地方的智能美食推荐助手”。这名字听起来有点绕但核心想法很直接我们平时用大众点评或者地图App找吃的推荐逻辑要么是基于你的历史口味要么是基于距离和评分很少会考虑“今天这天气适合吃什么”或者“在这个城市的这个区域大家通常怎么吃”。比如在重庆一个闷热的夏夜给你推荐热腾腾的九宫格火锅可能就不如一碗冰粉或凉虾来得贴心又或者在广州的老城区早餐推荐肠粉和粥远比推荐三明治更接地气。这个项目就是想让人工智能特别是大语言模型LLM学会这种结合实时天气、具体地理位置和本地饮食文化的“情境化推理”能力让它推荐的餐厅或菜品不仅好吃而且“应景”和“地道”。这背后其实是一个典型的智能体Agent应用场景。我们不再把LLM当作一个简单的问答机或者文本生成器而是把它打造成一个拥有“感知-思考-行动”循环的智能体。它的“感知”来自外部API提供的实时天气数据和精确的地理位置信息“思考”则依赖于LLM内部蕴含的庞大世界知识比如不同菜系的特点、食材的性味、各地的饮食习俗最后的“行动”就是生成一份贴合当下情境的个性化餐饮推荐。这个项目的挑战在于如何让LLM将结构化的外部数据温度、湿度、降水概率、经纬度与非结构化的内部知识“雨天适合喝汤”、“川菜麻辣祛湿”有机地结合起来进行连贯、合理的推理。对于餐饮行业的从业者、本地生活服务的产品经理或者对AI应用开发感兴趣的开发者来说这个项目提供了一个绝佳的样板展示了如何将前沿的LLM能力与具体的垂直场景餐饮推荐深度结合创造出超越传统规则引擎或协同过滤算法的智能体验。接下来我就把自己在构建这个“美食智能体”过程中的核心设计、技术实现细节以及踩过的那些坑毫无保留地分享出来。2. 核心架构设计构建一个“感官健全”的推荐智能体要让一个AI系统具备“天气和位置感知”能力我们不能指望LLM凭空变出这些信息。它的核心架构必须是一个能够与外部世界交互的智能体系统。我设计的整体架构主要包括四个层次感知层、推理层、知识层和执行层。2.1 感知层为智能体装上“眼睛”和“皮肤”感知层负责采集所有必要的外部情境信息。这主要包括两大类地理位置上下文这不仅仅是获取用户的经纬度坐标通过设备GPS或IP定位更重要的是将其转化为有意义的“区域语义”。例如坐标39.9042, 116.4074对应“中国北京市东城区”。我们需要通过逆地理编码服务如高德地图、百度地图的API来获取省、市、区、街道乃至商圈信息。更进一步我们还可以为不同区域打上标签如“金融商务区”、“大学城”、“老牌美食街”、“旅游景区”等。这些标签将直接影响推荐策略——商务区可能侧重快速、正式的午餐美食街则适合探索多样化的地方小吃。实时天气上下文这是项目的关键变量之一。我们需要从气象API如和风天气、OpenWeatherMap获取用户所在位置的实时天气数据包括温度直接影响对冷热食物的偏好。天气现象晴、阴、雨、雪、雾等。雨天和热汤面是经典搭配。降水量与湿度高湿度地区可能更需要祛湿食材如辣椒、花椒的推荐。风速与体感温度大风或体感寒冷时推荐高热量的食物会更受欢迎。注意选择气象API时除了精度和稳定性务必关注其调用频率限制和成本。对于推荐系统通常不需要秒级更新的数据每15-30分钟更新一次天气缓存既能保证时效性又能极大降低API调用开销。我在初期曾因过于频繁的调用而触发了限流。2.2 推理层与知识层LLM如何扮演“美食顾问”这是整个系统的“大脑”。我们利用LLM如GPT-4、Claude 3或开源的Llama 3、Qwen系列进行核心推理。但直接问LLM“北京下雨天吃什么好”虽然能得到一些答案但缺乏系统性也无法保证与实时数据如当前温度25度小雨精确结合。因此我采用了“结构化提示工程”配合“思维链”的方法。具体流程如下信息整合与格式化将感知层获取的原始数据格式化成一段LLM易于理解的“情境描述”。例如“用户当前位于北京市海淀区中关村属于高科技企业聚集区时间是工作日傍晚18:30。实时天气为小雨气温18摄氏度湿度85%微风。用户表达了寻找晚餐的意向。”分步推理提示我们不是让LLM直接输出餐厅名单而是引导它进行多步推理。提示词Prompt会这样设计你是一位精通全球饮食文化与营养学的美食顾问。请基于以下情境进行逐步推理 步骤1分析当前天气小雨18°C高湿度对人们饮食需求的普遍影响例如驱寒、祛湿、补充能量等。 步骤2结合地理位置北京中关村科技商圈分析该区域常见的餐饮类型、消费场景如工作餐、同事聚餐、快速简餐及本地特色。 步骤3综合以上两步提出3-5条具体的菜品或 cuisine菜系推荐方向并简要说明推荐理由。 步骤4基于上述推荐方向构想一个理想的餐厅应具备的特征例如提供热汤类菜品、环境舒适适合雨天停留、上菜速度较快等。通过这种分步引导LLM的推理过程变得透明且可控它能够有逻辑地将天气、位置知识结合起来。世界知识的利用LLM的“知识层”是其预训练语料中蕴含的关于食物、文化、地理的庞大数据。我们的提示词需要有效地“唤醒”这部分知识。例如提到“北京小雨”模型应能关联到“老北京炸酱面配热面汤”、“铜锅涮肉”等本土化选择而不是泛泛的“面条”。这需要在Prompt中明确强调“结合本地饮食特色”。2.3 执行层从“想法”到“推荐列表”推理层输出的是推荐方向和餐厅特征描述这还不能直接给用户。执行层负责将这些高质量的特征转化为可执行的筛选条件作用于底层的餐厅数据库。特征向量化将LLM生成的文本描述如“环境温馨”、“适合雨天”、“有招牌热汤”通过一个嵌入模型Embedding Model转化为向量。数据库查询我们的餐厅数据库中的每家店也应有其对应的特征向量来自餐厅描述、标签、用户评论的嵌入。通过计算余弦相似度可以快速从海量餐厅中检索出与LLM生成的特征最匹配的候选集。多目标排序最后将语义匹配度、餐厅的常规评分、距离因素、人均价格等纳入一个排序模型生成最终的、排好序的推荐列表。这样既保证了推荐的“情境贴合度”又兼顾了商业平台固有的质量与距离考量。这个架构的核心思想是“LLM负责创意与推理传统算法负责精准检索与排序”两者各司其职优势互补。3. 关键技术实现细节与实操要点理解了架构我们来看看具体实现时有哪些技术细节和“魔鬼”。3.1 多源异构数据的融合与编码感知层的数据五花八门数值型的温度、类别型的天气现象、文本型的行政区划、时间型的时刻。如何将它们统一“喂”给LLM我的做法是构建一个“情境上下文字符串模板”。这是一个高度结构化的文本片段确保每次请求LLM时信息格式一致且完整。def build_context_string(location_info, weather_info, user_intent): 构建给LLM的情境描述字符串。 location_info: 字典包含‘city’, ‘district’, ‘business_zone’, ‘tags’等 weather_info: 字典包含‘temp’, ‘condition’, ‘humidity’, ‘wind_speed’等 user_intent: 字符串如‘晚餐’, ‘朋友聚餐’, ‘一人食’ context f ## 用户当前情境 - **位置**{location_info[city]}{location_info[district]}{location_info[business_zone]}。区域特征{, .join(location_info[tags])}。 - **时间**{datetime.now().strftime(%Y年%m月%d日 %H:%M)}{‘工作日’ if is_weekday() else ‘周末/节假日’}。 - **实时天气**{weather_info[condition]}气温{weather_info[temp]}摄氏度湿度{weather_info[humidity]}%风速{weather_info[wind_speed]}米/秒。 - **用户意图**{user_intent}。 return context这种结构化的自然语言描述比传递JSON格式更受LLM欢迎因为它本身就是模型训练数据的主要形式易于理解和处理。3.2 提示词工程引导LLM进行区域敏感推理Prompt的设计直接决定了推理的质量。经过大量测试我总结出一个高效的提示词结构它包含以下几个部分角色设定明确赋予LLM一个专业角色如“资深美食生活家”、“本地通美食向导”。任务指令清晰说明需要LLM完成的具体任务分步推理。情境输入插入上面生成的context字符串。推理格式要求明确要求LLM以指定的格式如JSON、Markdown列表输出方便后续程序解析。约束与引导加入一些关键引导例如“请特别考虑本地当季食材”、“避免推荐不适合当前天气的菜品如冰品在寒冷天气”、“思考该区域此时间的典型用餐场景”。一个完整的Prompt示例如下你是一位生活在北京的资深美食家对各地饮食文化与气候、地域的关系了如指掌。请根据下面的用户情境为你朋友提供一份晚餐推荐分析。 【用户情境】 {context} 请按以下步骤思考并输出结果 1. **天气影响分析**针对上述天气分析其对食欲和菜品选择的普遍影响驱寒祛湿开胃。 2. **地域场景分析**结合具体区域{business_zone}和时间分析最常见的用餐类型和需求。 3. **推荐方向生成**综合以上给出3个最契合的菜品或菜系推荐方向。每个方向需包含(1) 方向名称(2) 1-2句核心推荐理由(3) 该方向下理想餐厅应具备的2-3个特征。 4. **输出格式**请将最终结果以JSON格式输出包含analysis、recommendations两个键。recommendations为一个列表列表中的每个元素包含cuisine, reason, features字段。 请确保推荐充分体现“本地化”和“应景”理由阐述具体、有说服力。实操心得在Prompt中要求LLM进行“分步思考”并在最终输出中体现这些步骤即使后续程序只使用最后一部分能显著提高输出的稳定性和逻辑性。这相当于让模型把自己的“思维链”展示出来减少了“跳跃式”错误结论的产生。3.3 本地知识增强与处理“知识幻觉”LLM的世界知识可能过时或存在“幻觉”即编造信息。例如它可能推荐一个已经关闭的“老字号”或者虚构某个地方的所谓“特色菜”。为了缓解这个问题我采用了两种策略本地知识库检索增强建立一个本地的小型知识库存储经过验证的本地信息。例如一个“城市-区域-餐饮特色”的映射表或一个“知名餐厅名录”。在生成Prompt前先根据用户位置从该知识库中检索相关的几条信息如“中关村附近以互联网公司员工为主午餐时段对快餐和轻食需求大”并以“已知本地信息”的形式附加到Prompt中。这样为LLM提供了准确的参考依据。结果校验与后处理对于LLM最终推荐的餐厅名称或具体菜品在执行层进行二次校验。例如将推荐的餐厅名称与我们数据库中的实体进行模糊匹配如果匹配度太低或完全不存在则将该条推荐降权或替换为相似选项。对于菜品可以关联到数据库的菜品标签系统进行验证。3.4 系统流程的完整串联与API设计整个系统的后端是一个微服务架构。我以Python的FastAPI框架为例展示核心推荐接口的流程from fastapi import FastAPI, HTTPException from pydantic import BaseModel import requests import json from your_llm_client import call_llm # 你的LLM调用封装 from your_embedding_model import get_embedding # 你的嵌入模型封装 from your_database import vector_search # 你的向量数据库查询 app FastAPI() class RecommendationRequest(BaseModel): latitude: float longitude: float user_intent: str “晚餐” app.post(“/api/recommend”) async def get_recommendation(request: RecommendationRequest): # 1. 感知层获取情境数据 location_data get_location_info(request.latitude, request.longitude) weather_data get_weather_info(request.latitude, request.longitude) # 2. 构建情境描述 context build_context_string(location_data, weather_data, request.user_intent) # 3. 推理层调用LLM进行情境分析 prompt build_prompt(context, location_data[‘business_zone’]) llm_response call_llm(prompt) # 返回JSON格式的推理结果 try: reasoning_result json.loads(llm_response) recommendation_directions reasoning_result[“recommendations”] except json.JSONDecodeError: # 处理LLM输出格式错误可进行重试或降级到规则推荐 raise HTTPException(status_code500, detail“LLM response format error”) # 4. 执行层将推荐方向转化为查询 all_candidates [] for direction in recommendation_directions: # 将文本特征向量化 query_vector get_embedding(direction[“reason”] “ “ “ “.join(direction[“features”])) # 向量数据库检索 candidates vector_search(query_vector, top_k20, filter_by_locationlocation_data) all_candidates.extend(candidates) # 5. 去重、排序综合向量相似度、评分、距离 final_list rank_and_deduplicate(all_candidates) return { “context”: {“location”: location_data, “weather”: weather_data}, “reasoning”: reasoning_result[“analysis”], # 将LLM的推理过程也返回增加可解释性 “recommendations”: final_list }这个接口清晰地展示了数据流从原始坐标到情境描述再到LLM推理最后通过向量检索落地为具体的餐厅列表。返回结果中包含了推理过程使推荐结果不再是黑盒增强了用户信任。4. 效果评估、调优与常见问题排查项目搭建起来只是第一步更重要的是让它“推荐得准”。我建立了一套评估和迭代优化的方法。4.1 如何评估推荐质量对于这种强情境相关的推荐传统的准确率、召回率指标有时显得力不从心。我主要采用三种评估方式人工情景评测构造一系列覆盖不同天气、位置、时间的典型测试用例Test Cases。例如“上海浦东陆家嘴工作日暴雨午休时间”、“成都宽窄巷子周末晴好下午茶时间”。邀请团队成员或目标用户对推荐结果进行“情境契合度”打分1-5分。这是最直接、最有效的评估方式。A/B测试在产品的真实流量中将用户随机分为两组。对照组接收传统推荐基于热度/距离实验组接收我们的智能体推荐。核心观测指标不是简单的点击率而是“情境满意度”相关的指标例如推荐列表的天气/位置相关标签曝光率系统打上“雨天暖身”、“商圈简餐”等标签的推荐项被用户看到的比例。深度参与度用户在查看推荐后的停留时长、详情页浏览深度、收藏/分享行为。后续行为一致性用户采纳推荐后其评价中是否出现了与情境相关的关键词如“下雨天吃这个太舒服了”、“果然是这个区的老味道”。LLM自我评估这是一个有趣的辅助方法。将原始的“用户情境”、LLM生成的“推理过程”以及“最终推荐列表”再次交给另一个LLM或同一模型的不同会话让它以美食评论家的角度评价这份推荐与情境的契合度并给出理由和分数。虽然可能存在偏差但能快速进行大规模自动化初筛。4.2 模型调优与迭代基于评估反馈系统需要持续调优Prompt迭代如果发现LLM在某些场景下如极端天气、特殊节假日推理偏差较大就需要针对性调整Prompt。例如增加对“节假日家庭聚餐”场景的引导或明确告知模型“在气温高于35度时避免推荐油腻的烧烤类”。知识库更新本地知识库需要定期维护和更新。当发现有新的热门商圈或餐厅开业或者某些饮食潮流兴起应及时补充进知识库。排序模型权重调整在最终排序环节根据A/B测试数据调整“情境向量相似度”、“用户历史偏好”、“实时热度”、“配送距离”等不同特征的权重找到业务收益最大的平衡点。4.3 常见问题与排查实录在实际开发和运营中我遇到了不少典型问题这里分享排查思路和解决方案。问题现象可能原因排查步骤与解决方案推荐结果完全无视天气1. 天气API调用失败或返回默认值。2. Prompt中天气信息未被LLM有效关注。1.检查API查看日志确认天气数据是否成功获取且数值正常如温度不是0或null。2.强化Prompt在Prompt中用更强调的语句如“请务必优先考虑以下实时天气条件对饮食的影响”并将天气信息放在靠前位置。推荐过于泛化缺乏本地特色1. 地理位置信息粒度太粗只到城市级。2. LLM缺乏该区域的细节知识。1.细化位置确保逆地理编码能获取到区、街道甚至商圈信息并将其输入模型。2.知识注入在Prompt中加入从本地知识库检索到的该区域特色描述如“该区域以学生和年轻上班族为主流行快时尚餐饮和网红小吃”。LLM输出格式不稳定解析失败LLM有时不严格遵守指定的JSON输出格式。1.后处理兼容编写更健壮的解析器能处理JSON外的多余文本、格式错误等。2.使用Function Calling如果LLM支持如GPT系列优先使用Function Calling功能让模型以结构化方式调用你定义的“推荐生成函数”格式100%可控。响应延迟过高1. 串行调用多个外部API地理、天气、LLM。2. LLM模型过大或网络延迟高。1.异步并发将地理位置获取和天气获取改为并发请求。2.缓存策略对天气和静态的地理信息进行短期缓存如天气缓存15分钟。3.模型选型对于实时推荐考虑使用响应更快的轻量级模型或专门优化的API。推荐多样性不足向量搜索时过于依赖Top-K相似度导致结果同质化。在向量检索后加入多样性重排策略。例如确保推荐列表中同时包含不同菜系、不同价格档位的餐厅避免全是同一类型的店。踩坑心得最大的一个坑是初期过于依赖LLM的“自由发挥”没有给它足够的“事实锚点”。比如它知道“下雨天适合吃热的”但可能会推荐一个并不存在的“本地特色姜汤面”。后来引入了本地知识库检索增强并将推荐方向约束在数据库已有的菜系分类和标签体系内问题才得到根本解决。记住LLM是强大的推理引擎和创意生成器但它需要准确的事实边界和输出约束。5. 成本控制、扩展性与未来展望对于一个需要频繁调用LLM和外部API的系统成本是不可忽视的因素。5.1 成本控制策略LLM调用优化提示词精简去除Prompt中所有不必要的描述使用更简洁、指令更明确的表达。缓存推理结果对于常见的情境组合如“北京-海淀-中关村-工作日-小雨-晚餐”可以将LLM的推理结果即推荐方向缓存起来。在缓存有效期内相同或高度相似的情境请求可以直接使用缓存无需再次调用LLM。这能节省大量费用。模型分级对于实时性要求不高的场景如生成每周美食攻略可以使用更便宜但能力稍弱的模型对于核心的实时推荐使用性能更强的模型。外部API成本控制天气和地理API通常有免费额度或套餐根据预估的请求量选择合适的套餐。实施请求合并与批量处理避免零散的请求。5.2 系统扩展性思考当前项目聚焦于餐饮推荐但这套“情境感知智能体”的框架具有很强的可扩展性。横向扩展场景旅行规划结合天气、季节、地理位置推荐当日最合适的景点、活动如雨天推荐室内博物馆晴朗的傍晚推荐观景台。穿搭建议基于实时天气、气温趋势、用户所在地的场合通勤、出游、商务生成穿搭推荐。本地活动推荐推荐与当前天气、节日氛围相匹配的线下活动如雨天的书店分享会、雪后的温泉体验。纵向功能深化多轮对话与偏好修正让智能体能够与用户进行多轮对话根据用户的反馈“不想吃辣的”、“今天想奢侈一点”实时调整推荐策略。多模态输入允许用户上传图片如看到的餐厅招牌、想吃的菜品图片结合情境进行推荐。长期记忆与用户画像将用户的历史选择与情境关联起来构建更精细化的“情境-偏好”画像实现越用越懂你的个性化推荐。构建这个系统的过程让我深刻体会到AI应用的未来不在于追求一个“全能”的通用模型而在于如何巧妙地设计智能体架构让大模型的能力与垂直领域的知识、实时数据以及传统的算法工具有效协同。把LLM当作一个拥有常识和推理能力的“大脑”再为它配备上感知环境的“感官”和执行任务的“手脚”它就能在无数像“今天吃什么”这样的具体问题上给出真正有智慧、有温度的答案。这个项目只是一个起点其中关于情境理解、知识融合、提示工程和系统架构的经验对于想要在更多领域打造智能化应用的开发者来说或许能提供一些有价值的参考。
返回列表