从0到1构建食谱推荐智能体:让AI自主分析食材、推荐菜谱、规划饮食
在快节奏的现代生活中,很多人经常会遇到“冰箱里有食材但不知道做什么菜”“想吃的菜谱步骤太复杂”“不知道怎么搭配饮食才健康”这类问题。针对这些痛点,我们可以基于大语言模型的工具调用能力,从0到1构建一个食谱推荐智能体,让AI能够自主完成食材分析、菜谱推荐、饮食规划的全流程工作。本文将详细介绍整个实现过程,包含完整的代码逻辑和核心功能说明。
核心功能设计
食谱推荐智能体需要具备以下核心能力:
- 食材识别与分析:能够识别用户提供的食材列表,判断食材的新鲜度、适用场景、营养属性
- 个性化菜谱推荐:结合用户口味偏好、饮食限制(如素食、低卡、过敏忌口)、烹饪时长要求推荐合适菜谱
- 饮食规划:根据用户每日热量需求、饮食目标(增肌、减脂、维持体重)生成一日三餐的合理搭配方案
- 烹饪指导:提供菜谱的详细步骤、注意事项,以及常见问题的解决方案
环境准备与依赖安装
我们使用Python作为开发语言,基于OpenAI的兼容接口调用大模型,同时需要安装必要的工具库。首先需要安装依赖:
# 安装所需依赖
# pip install openai python-dotenv
import os
import json
from openai import OpenAI
from dotenv import load_dotenv
# 加载环境变量,需要提前在.env文件中配置API_KEY和BASE_URL
load_dotenv()
client = OpenAI(
api_key=os.getenv("API_KEY"),
base_url=os.getenv("BASE_URL")
)这里我们使用dotenv管理环境变量,避免敏感信息硬编码到代码中,实际使用时只需要创建.env文件,填入对应的大模型API密钥和接口地址即可。
工具函数定义
为了让智能体能够调用外部能力,我们需要定义几个核心的工具函数,大模型会根据用户需求自主选择调用对应的工具。
食材分析工具
该工具用于分析用户提供的食材列表,返回食材的营养属性、适用菜谱类型等信息:
def analyze_ingredients(ingredients: list) -> dict:
"""
分析食材列表,返回食材的营养属性、适用场景等信息
:param ingredients: 食材列表,例如["鸡蛋", "西红柿", "面条"]
:return: 食材分析结果字典
"""
# 这里可以对接真实的食材数据库,此处为示例逻辑
ingredient_db = {
"鸡蛋": {"类型": "蛋白质", "热量": "144kcal/100g", "适用场景": ["早餐", "快手菜", "烘焙"]},
"西红柿": {"类型": "蔬菜", "热量": "18kcal/100g", "适用场景": ["凉拌", "热炒", "汤品"]},
"面条": {"类型": "主食", "热量": "286kcal/100g", "适用场景": ["午餐", "晚餐", "快手主食"]}
}
result = {}
for item in ingredients:
if item in ingredient_db:
result[item] = ingredient_db[item]
else:
result[item] = {"类型": "未知", "热量": "暂无数据", "适用场景": []}
return result菜谱推荐工具
该工具结合用户偏好和食材信息,返回匹配的菜谱列表:
def recommend_recipes(ingredients: list, preferences: dict = None) -> list:
"""
根据食材和用户偏好推荐菜谱
:param ingredients: 可用食材列表
:param preferences: 用户偏好,例如{"口味": "咸鲜", "限制": "无辣", "时长": "30分钟以内"}
:return: 推荐菜谱列表
"""
# 示例菜谱库,实际可对接更完整的菜谱数据库
recipe_db = [
{
"名称": "西红柿鸡蛋面",
"所需食材": ["西红柿", "鸡蛋", "面条"],
"口味": "咸鲜",
"烹饪时长": "20分钟",
"热量": "约450kcal/份",
"步骤": ["西红柿切块,鸡蛋打散炒熟备用", "锅中倒油炒西红柿出汁,加入鸡蛋翻炒", "加水煮开下面条,煮熟即可"]
},
{
"名称": "清炒时蔬",
"所需食材": ["任意绿叶蔬菜", "蒜"],
"口味": "清淡",
"烹饪时长": "10分钟",
"热量": "约80kcal/份",
"步骤": ["蔬菜洗净切段,蒜切末", "热油爆香蒜末,下蔬菜翻炒至断生", "加盐调味出锅"]
}
]
preferences = preferences or {}
result = []
for recipe in recipe_db:
# 判断是否包含所需食材
if all(ing in ingredients for ing in recipe["所需食材"]):
# 匹配口味偏好
if "口味" in preferences and preferences["口味"] not in recipe["口味"]:
continue
# 匹配时长偏好
if "时长" in preferences:
recipe_min = int(recipe["烹饪时长"].replace("分钟", ""))
prefer_min = int(preferences["时长"].replace("分钟以内", ""))
if recipe_min > prefer_min:
continue
result.append(recipe)
return result饮食规划工具
该工具根据用户的热量需求和饮食目标,生成一日三餐的搭配方案:
def plan_diet(daily_calorie: int, goal: str = "维持体重") -> dict:
"""
生成一日三餐饮食规划
:param daily_calorie: 每日所需总热量,单位kcal
:param goal: 饮食目标,可选"增肌"、"减脂"、"维持体重"
:return: 一日三餐规划字典
"""
# 不同目标的热量分配比例
goal_ratio = {
"增肌": {"早餐": 0.3, "午餐": 0.4, "晚餐": 0.3},
"减脂": {"早餐": 0.35, "午餐": 0.35, "晚餐": 0.3},
"维持体重": {"早餐": 0.3, "午餐": 0.4, "晚餐": 0.3}
}
ratio = goal_ratio.get(goal, goal_ratio["维持体重"])
plan = {}
for meal, rate in ratio.items():
meal_calorie = int(daily_calorie * rate)
plan[meal] = {
"建议热量": f"{meal_calorie}kcal",
"推荐搭配": f"包含蛋白质、碳水、蔬菜,例如早餐可选择鸡蛋+牛奶+全麦面包,约{meal_calorie}kcal"
}
return plan智能体核心逻辑实现
接下来我们定义智能体的核心调度逻辑,让大模型能够理解用户需求,并选择调用对应的工具函数,最终返回用户需要的结果。
def recipe_agent(user_query: str) -> str:
"""
食谱推荐智能体核心调度函数
:param user_query: 用户输入的查询内容
:return: 智能体的回复结果
"""
# 定义工具列表,告诉大模型可以调用的工具
tools = [
{
"type": "function",
"function": {
"name": "analyze_ingredients",
"description": "分析食材列表,返回食材的营养属性、适用场景等信息",
"parameters": {
"type": "object",
"properties": {
"ingredients": {
"type": "array",
"items": {"type": "string"},
"description": "食材列表,例如['鸡蛋', '西红柿', '面条']"
}
},
"required": ["ingredients"]
}
}
},
{
"type": "function",
"function": {
"name": "recommend_recipes",
"description": "根据食材和用户偏好推荐菜谱",
"parameters": {
"type": "object",
"properties": {
"ingredients": {
"type": "array",
"items": {"type": "string"},
"description": "可用食材列表"
},
"preferences": {
"type": "object",
"description": "用户偏好,例如{'口味': '咸鲜', '限制': '无辣', '时长': '30分钟以内'}",
"properties": {
"口味": {"type": "string"},
"限制": {"type": "string"},
"时长": {"type": "string"}
}
}
},
"required": ["ingredients"]
}
}
},
{
"type": "function",
"function": {
"name": "plan_diet",
"description": "根据用户的热量需求和饮食目标,生成一日三餐的搭配方案",
"parameters": {
"type": "object",
"properties": {
"daily_calorie": {
"type": "integer",
"description": "每日所需总热量,单位kcal"
},
"goal": {
"type": "string",
"description": "饮食目标,可选增肌、减脂、维持体重,默认维持体重"
}
},
"required": ["daily_calorie"]
}
}
}
]
# 初始化对话上下文
messages = [
{"role": "system", "content": "你是一个专业的食谱推荐智能体,负责帮助用户分析食材、推荐菜谱、规划饮食。当用户提供食材时,先调用食材分析工具,再推荐菜谱;当用户需要饮食规划时,调用饮食规划工具。回复要友好清晰,结合工具返回的结果给出实用建议。"},
{"role": "user", "content": user_query}
]
# 第一次调用大模型,获取工具调用指令
response = client.chat.completions.create(
model="gpt-3.5-turbo-0125",
messages=messages,
tools=tools,
tool_choice="auto"
)
response_message = response.choices[0].message
messages.append(response_message)
# 处理工具调用
if response_message.tool_calls:
for tool_call in response_message.tool_calls:
function_name = tool_call.function.name
function_args = json.loads(tool_call.function.arguments)
# 调用对应的本地函数
if function_name == "analyze_ingredients":
function_result = analyze_ingredients(**function_args)
elif function_name == "recommend_recipes":
function_result = recommend_recipes(**function_args)
elif function_name == "plan_diet":
function_result = plan_diet(**function_args)
else:
function_result = {"error": "未找到对应工具"}
# 将工具调用结果加入对话上下文
messages.append(
{
"tool_call_id": tool_call.id,
"role": "tool",
"name": function_name,
"content": json.dumps(function_result, ensure_ascii=False)
}
)
# 第二次调用大模型,生成最终回复
second_response = client.chat.completions.create(
model="gpt-3.5-turbo-0125",
messages=messages
)
return second_response.choices[0].message.content
else:
# 如果不需要调用工具,直接返回大模型的回复
return response_message.content功能测试与效果验证
完成核心逻辑开发后,我们可以测试智能体的不同功能场景,验证是否符合预期。
测试场景1:食材分析+菜谱推荐
# 测试用户查询:我冰箱里有鸡蛋、西红柿、面条,想做30分钟以内的咸鲜口味菜,有什么推荐?
user_query1 = "我冰箱里有鸡蛋、西红柿、面条,想做30分钟以内的咸鲜口味菜,有什么推荐?"
result1 = recipe_agent(user_query1)
print("测试1结果:")
print(result1)智能体会先调用analyze_ingredients分析三种食材的属性,再调用recommend_recipes匹配符合条件的菜谱,最终返回西红柿鸡蛋面的详细信息和烹饪步骤,同时给出食材搭配的建议。
测试场景2:饮食规划
# 测试用户查询:我每天需要1800kcal热量,目标是减脂,帮我规划一日三餐
user_query2 = "我每天需要1800kcal热量,目标是减脂,帮我规划一日三餐"
result2 = recipe_agent(user_query2)
print("测试2结果:")
print(result2)智能体会调用plan_diet工具,按照减脂的热量分配比例,生成早餐、午餐、晚餐的建议热量和搭配方案,同时给出每餐的具体食物选择建议。
后续优化方向
当前版本的智能体已经实现了核心功能,后续可以从以下几个方向优化:
- 接入更完整的食材数据库和菜谱数据库,支持更多食材和菜谱的识别推荐
- 增加用户历史偏好记忆功能,不需要每次都重复说明口味、饮食限制等信息
- 添加图片识别能力,支持用户直接上传食材照片,自动识别食材列表
- 增加营养计算功能,自动计算推荐菜谱的总热量、蛋白质、碳水、脂肪含量,方便用户控制饮食
通过以上步骤,我们就完成了一个基础版的食谱推荐智能体的从0到1构建,你可以根据自己的需求调整工具函数的逻辑和数据库内容,让智能体更贴合实际使用场景。