好,前面九篇文章,我们已经把 Python 里最常用的“小工具”都摸了一遍:变量、print、列表、字典、函数、import、点号、for 循环、yield、装饰器、类、异步、模块…… 听起来好多,对吧?但你回头看,每一个都像一个乐高积木块,单独看都很简单。

现在我们要做一件特别有成就感的事:把这些积木搭成一个真正的、能跑起来的 AI 应用 —— 一个根据你的口味偏好,推荐一周七天、每天三餐的迷你助手。我们管它叫 “我的第一本 AI 食谱”

这个项目会把你学过的几乎所有知识点串在一起。我不会一次扔给你一大段代码,而是一步一步带着你写,每一段代码你都能看懂。到最后,你会惊讶:“原来我也能写出这样的程序!”

别怕,我们慢慢走。

第一步:用变量和 print() 和用户打招呼

每个程序都有一个友好的开头。我们先问用户的名字和口味偏好,把信息存到变量里,然后用 print() 显示出来——就像你第一次写 name = "小明"print(name) 一样简单。

# 欢迎语
print("🍽️ 欢迎使用「我的第一本 AI 食谱」!")

# 用变量存用户信息
user_name = input("先告诉我你的名字吧:")
print(f"你好,{user_name}!")

# 收集口味偏好(存到字典里,为下一步做准备)
preferences = {}
preferences["不吃辣"] = input("你不吃什么?比如:不吃辣、不吃香菜… 直接回车跳过:")
preferences["喜欢菜系"] = input("你偏爱什么菜系?比如:川菜、粤菜、家常… 直接回车跳过:")

print("\n收到啦!我根据你的偏好来推荐一周菜单 🌟")

这里我们用到了:

  • 变量user_namepreferences 存数据。
  • input():让用户在键盘上打字,得到的内容存到变量里。
  • print():把信息显示到屏幕上。
  • f-stringf"你好,{user_name}" 里面用 {变量名} 把变量的值填进去。

运行一下看看,是不是已经像一个小聊天的开头了?

第二步:用列表和字典存一周菜单和用户偏好

一周有七天,我们可以用一个 列表 来按顺序存放每一天。每一天的菜单,又包含早餐、午餐、晚餐,很适合用 字典 来表示:键是 "breakfast""lunch""dinner",值就是菜名(字符串)。

我们先用假数据模拟一下,让你感受结构:

# 用列表存一周的菜单,里面每个元素是一个字典
week_menu = [
    {"breakfast": "牛奶+麦片", "lunch": "番茄炒蛋", "dinner": "清炒西兰花"},  # 周一
    {"breakfast": "小米粥", "lunch": "红烧排骨", "dinner": "蒜蓉空心菜"},      # 周二
    # ... 后面几天类似
]

# 取出周一的午餐
print(week_menu[0]["lunch"])  # 输出:番茄炒蛋

当然,我们不可能手动写一周的真实菜单,那要写到什么时候?我们要让 AI 来生成。所以后面我们会在真正调用 LangChain 时,把每一天的菜单用 字典 的形式返回。

用户偏好的存储:我们前面已经用了一个 preferences 字典。你可以往里面继续加键值对,比如:

preferences["做饭时间"] = "30分钟以内"
preferences["热量要求"] = "低卡"

这些限制会在稍后传给 AI 提示词。

第三步:用函数封装“生成一天菜单”的逻辑

写一大坨代码不如把它拆成小函数。我们用一个函数 generate_day_menu(preferences, day),它接收用户偏好和星期几,然后返回那一天的三餐推荐(一个字典)。这样主程序就会非常干净。

def generate_day_menu(preferences, day):
    """根据偏好生成单日菜单 (这里先用模拟数据,后面换成真正的 AI)"""
    # 临时模拟: 所有日子都返回同一个固定菜单
    menu = {
        "breakfast": "燕麦粥",
        "lunch": "鸡胸肉沙拉",
        "dinner": "蒸鱼+糙米饭"
    }
    return menu

调用它:

monday_menu = generate_day_menu(preferences, "Monday")
print(monday_menu["lunch"])

当然,这还不是 AI,只是写着占位。稍后我们会用 LangChain 的模型来真正生成个性化的菜单。

第四步:用 import 和点号引入 LangChain,调用 AI 模型

这是最激动人心的一步。我们会在代码开头写 from langchain_openai import ChatOpenAIfrom langchain_core.prompts import ChatPromptTemplate,然后用点号去调用模型。

先确保你安装了 langchainlangchain_openai(如果有 OpenAI API key)。如果没有,也可以用国内兼容的接口。安装命令:

pip install langchain langchain_openai

然后写一个 generate_meal_with_ai 函数:

from langchain_openai import ChatOpenAI
from langchain_core.prompts import ChatPromptTemplate

def generate_day_menu_with_ai(preferences, day):
    # 创建模型对象
    llm = ChatOpenAI(model="gpt-3.5-turbo", temperature=0.7)
    
    # 定义提示模板,里面用 {day} 和 {preferences} 占位
    prompt = ChatPromptTemplate.from_messages([
        ("system", "你是一个专业的营养师和厨师,根据用户偏好推荐每日三餐,只输出 JSON 格式,不要多余文字。"),
        ("user", "今天是{day}。用户偏好:{preferences}。请推荐早餐、午餐、晚餐,格式:{{'breakfast':'...', 'lunch':'...', 'dinner':'...'}}")
    ])
    
    # 格式化提示词,并用模型生成
    formatted_prompt = prompt.format_messages(day=day, preferences=preferences)
    response = llm.invoke(formatted_prompt)
    
    # 这里简单把返回的内容转成字典(实际需要解析,先不增加复杂度)
    # 你可以用 eval() 或 json.loads,但注意安全,我们假设 AI 返回正确格式
    menu_dict = eval(response.content)
    return menu_dict

然后你在主程序里循环一周的每一天,调用这个函数,就把所有菜单生成了。这里面用到了:

  • import:从 langchain 工具箱里拿工具。
  • 点号llm.invoke()ChatPromptTemplate.from_messages()
  • 字典:传 preferences 进去。
  • 函数generate_day_menu_with_ai

第五步:用 for 循环和 yield 让菜单“流”出来

你不想一次性等七天的结果全出来,而是想一天一天地出现(或者一个字一个字出现)。这里可以用 yield 做一个生成器,每天生成完后马上交给主程序。

def menu_generator(preferences):
    days = ["周一", "周二", "周三", "周四", "周五", "周六", "周日"]
    for day in days:
        menu = generate_day_menu_with_ai(preferences, day)   # 调用上面的 AI 函数
        yield {day: menu}   # 产出一个字典,比如 {"周一": {"早餐":...}}
        # 产出后主程序就能立刻拿到这一天,不需要等全部完成

主程序里用 for 循环接收:

for one_day_menu in menu_generator(preferences):
    print(one_day_menu)
    print("------- 继续生成下一天 -------")

这样你就能看到菜单一天一天地出现,而不是卡住等 7 秒钟才一次性显示。

第六步:用装饰器给生成菜单的函数加日志(可选)

你想记录一下每次调用 AI 生成了什么菜单,方便调试。可以用装饰器,不修改原函数,额外加个打印。

def log_menu(func):
    def wrapper(preferences, day):
        print(f"[日志] 正在为 {day} 生成菜单...")
        result = func(preferences, day)
        print(f"[日志] {day} 菜单生成完毕")
        return result
    return wrapper

@log_menu
def generate_day_menu_with_ai(preferences, day):
    # ... 原来函数内容不变

这里用到了我们学过的 装饰器 知识。你不需要写很复杂,但看到 @log_menu 就知道它给函数加了日志功能。

第七步:把整个项目封装成一个类(可选整洁版)

如果你想把所有相关函数和数据打包在一起,可以定义一个 MealPlanner 类,里面包含 __init__(初始化偏好、模型)、generate_week 等方法。

class MealPlanner:
    def __init__(self, preferences, model_name="gpt-3.5-turbo"):
        self.preferences = preferences
        self.llm = ChatOpenAI(model=model_name)
    
    def generate_day(self, day):
        # 使用 self.llm 和 self.preferences 生成一天菜单
        pass
    
    def generate_week(self):
        days = ["周一", "周二", "周三", "周四", "周五", "周六", "周日"]
        week_menu = []
        for day in days:
            week_menu.append(self.generate_day(day))
        return week_menu

# 使用
planner = MealPlanner(preferences)
week = planner.generate_week()

这个类把数据和操作放在了一起,调用起来很清爽。你不需要每次都传 preferencesllm 参数。

第八步:用 asyncawait 让多天的生成同时进行(进阶)

如果你想把七天的生成请求同时发给 AI(异步并行),总耗时就会从“7倍单次时间”变成“约等于最慢那次”。这要用到 async defawait。我们写一个简单的异步版本:

import asyncio

async def generate_day_async(planner, day):
    return await planner.generate_day_async(day)   # 假设你实现了异步方法

async def generate_week_async(planner):
    days = ["周一", "周二", "周三", "周四", "周五", "周六", "周日"]
    tasks = [generate_day_async(planner, day) for day in days]
    results = await asyncio.gather(*tasks)
    return dict(zip(days, results))

# 运行
planner = MealPlanner(preferences)
week_menu = asyncio.run(generate_week_async(planner))

虽然异步代码稍微多几行,但效果很酷:所有天的请求几乎同时发出,谁先回来就先处理谁。你可以先跑通同步版本,再尝试改成异步。

第九步:把代码拆分到不同文件(模块和包)

当你的项目越来越大,一个文件会很乱。你可以这样整理:

my_recipe_assistant/
  __init__.py
  preferences.py   (收集用户偏好)
  ai_generator.py   (调用 LangChain 生成菜单的函数)
  menu_formatter.py (把菜单打印成漂亮表格)
  main.py           (主程序,组装所有)

main.py 里,你就可以写:

from preferences import get_preferences
from ai_generator import generate_week_menu
from menu_formatter import print_menu

prefs = get_preferences()
week = generate_week_menu(prefs)
print_menu(week)

干净的目录结构让你以后扩展功能(比如保存到文件、加 web 界面)都非常轻松。

完结小结与你的下一站

小结:我们用九个小步骤,把前面学过的所有 Python 知识点——变量、print、列表、字典、函数、import、点号、foryield、装饰器、类、async、模块/包——全部用进了一个真实的 LangChain 项目中。你不再只是“学过这些概念”,而是亲手搭建了一个能根据用户口味推荐一周菜单的 AI 助手。这个程序虽然小,但它包含了真实软件开发的几乎所有基本要素:输入、处理、调用外部 AI、输出、组织代码。

你的下一站:从这里出发,你可以试着改动它:比如加上“每餐热量计算”、用 LangGraph 做多轮对话调整菜单、把菜单存成 PDF、或者做一个简单的网页界面。你已经有能力去读 LangChain 和 LangGraph 的官方文档了——它们不再是一堆看不懂的咒语,而是一个个你认识的朋友。

恭喜你走完了这条小路。你不再是那个被 defclass 劝退的新手,而是一个能动手写出 AI 应用的创造者。去折腾吧,代码就是你的乐高。我们路上见!

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐