1. 项目概述:当冰箱空空如也时,我的AI厨房助手诞生记

又是一个周五晚上,拖着疲惫的身体回到家,打开冰箱,里面是昨晚的剩菜、几个鸡蛋、半颗蔫了的西兰花,还有一包快过期的鸡胸肉。站在冰箱前发呆的十分钟里,我意识到一个问题:我们拥有的食材远比我们想象的要多,但“今晚吃什么”这个世纪难题,往往源于我们想象力的匮乏和食谱搜索的繁琐。那一刻,我决定不再依赖那些需要精确食材匹配的食谱App,而是自己动手,打造一个能理解我“冰箱现状”、并能天马行空给出创意建议的私人AI厨房助手。

这个项目的核心,是利用大型语言模型(LLM),特别是OpenAI的GPT-3.5-turbo,构建一个能进行自然对话的食谱生成器。它不是一个简单的数据库查询工具,而是一个真正的“厨房参谋”。你告诉它“我有鸡蛋、西红柿和一点芝士”,它不仅能告诉你“可以做西红柿炒蛋”,还能建议你“试试做个简易的意式烘蛋(Frittata),把芝士撒在上面烤一下,风味更佳”。这种基于现有条件的创造性建议,才是AI在厨房里真正的价值。

整个项目流程可以概括为:用Python编写核心逻辑,通过Agenta这个开源平台来管理、测试和部署我们的AI应用。Agenta的作用就像一个高效的AI应用开发车间,它帮我们处理了从提示词工程、多版本测试到一键部署的繁琐过程,让我们能专注于让AI变得更“懂”吃这件事本身。无论你是想解决自己的吃饭问题,还是对如何将LLM落地到一个具体、有趣的场景感兴趣,这个项目都将是一次绝佳的实践。

2. 核心思路与工具选型解析

2.1 为什么选择LLM而非传统食谱数据库?

传统食谱应用或网站大多基于标签匹配和搜索。你输入“鸡肉”,它返回所有含鸡肉的菜谱。这存在几个痛点:第一,它无法处理“残缺”的食材列表(比如你只有鸡胸肉,但菜谱要求鸡腿);第二,它缺乏灵活性和创造性,无法根据“鸡蛋、剩米饭、午餐肉”这三个毫不相干的食材,联想到可以做一顿丰盛的蛋炒饭;第三,交互生硬,无法进行多轮对话,比如你问“这个菜小孩能吃吗?”或者“能少放点油吗?”。

大型语言模型(LLM)恰好能弥补这些缺陷。GPT系列模型在训练时“阅读”了海量的互联网文本,其中包含无数的食谱、美食博客、烹饪讨论。它学会的不仅仅是菜名和食材的对应关系,更是烹饪的逻辑、风味的搭配和创作的灵感。当我们用系统提示词(System Prompt)将它设定为“厨房助手”时,它就能调用这些内化的知识,进行创造性的推理。例如,它能理解“清淡”意味着少油少盐,能根据“快速”的诉求推荐15分钟快手菜,甚至能基于“庆祝”的场景建议一道有仪式感的甜品。这种基于语义理解而非关键字匹配的能力,是革命性的。

2.2 技术栈深度剖析:GPT-3.5-turbo与Agenta的组合优势

GPT-3.5-turbo的选择考量: 在项目启动时,我选择了 gpt-3.5-turbo 作为主力模型,而非更强大的GPT-4。这主要基于几点务实考虑:

  1. 成本与性能平衡 :对于食谱生成这类创造性文本任务, gpt-3.5-turbo 已经能提供极高品质的回复,其成本却远低于GPT-4。在需要频繁实验和调优的开发阶段,控制成本至关重要。
  2. 速度 gpt-3.5-turbo 的响应速度更快,这对于未来集成到移动端、追求流畅对话体验的场景来说是个优势。
  3. 足够的“智慧” :在烹饪这个领域,模型的“知识”广度和创造性比极致的复杂推理能力更重要。 gpt-3.5-turbo 在常识和创意方面已经绰绰有余。

当然,我在代码中预留了模型选择的灵活性,将 gpt-4 及其他多个 gpt-3.5-turbo 的变体(如 gpt-3.5-turbo-16k )都列入了可选列表。这样,在Agenta的测试平台上,我可以轻松进行A/B测试,对比不同模型在相同食材输入下的回答质量、创意度和成本,从而为最终生产环境选择最佳模型。

为什么是Agenta? 你可以把Agenta想象成LLM应用开发的“瑞士军刀”或“集成开发环境(IDE)”。自己从零搭建一个具备以下所有功能的管理平台是极其复杂的:

  • 提示词版本管理 :今天我想让助手语气像法国大厨,明天想让它像家常妈妈,手动改代码和配置非常低效。Agenta允许你为同一个应用创建多个“变体”(Variant),每个变体可以有不同的系统提示词、温度参数等,并并行对比效果。
  • 系统化评估 :AI应用的好坏不能光靠“感觉”。Agenta内置了多种评估器(Evaluator),比如可以检查生成的食谱是否包含所有输入食材(事实一致性),或者比较两个变体生成的食谱哪个更受人类评分员喜欢(A/B测试)。这为迭代优化提供了数据依据。
  • 一键部署与API管理 :开发完成后,我需要一个稳定的API端点(Endpoint)供前端(比如一个手机App)调用。Agenta可以直接将测试好的应用变体部署到生产环境,并自动生成API文档和访问密钥,省去了自己配置服务器、Docker容器和API网关的麻烦。

实操心得 :在项目初期,我曾尝试直接用Flask/FastAPI搭建后端,然后手动管理不同的提示词文件和环境配置,很快就变得混乱不堪。引入Agenta后,开发流程变得清晰且可追溯。它的“Playground”功能尤其好用,我可以实时调整参数、切换模型并立刻看到输出变化,极大提升了实验效率。

3. 从零开始:构建AI厨房助手核心逻辑

3.1 项目初始化与环境搭建

首先,我们需要一个干净的工作空间。我强烈建议使用虚拟环境(如 venv conda )来隔离项目依赖,避免与系统或其他项目的Python包发生冲突。

# 创建项目目录并进入
mkdir kitchen_assistant && cd kitchen_assistant

# 创建并激活虚拟环境(以venv为例)
python -m venv .venv
# Windows
.venv\Scripts\activate
# macOS/Linux
source .venv/bin/activate

# 创建依赖文件
touch requirements.txt

接下来,编辑 requirements.txt 文件,填入我们需要的核心库:

agenta==0.9.0  # Agenta SDK,用于应用管理和部署
openai>=1.0.0   # OpenAI官方Python SDK,用于调用GPT模型
pydantic>=2.0   # 数据验证(通常会被agenta或openai依赖)

安装依赖:

pip install -r requirements.txt

安全是重中之重。OpenAI API调用需要密钥。我们不应将密钥硬编码在代码中,而是使用环境变量。

# 创建.env文件来存储敏感信息
touch .env

.env 文件中填入你的OpenAI API密钥:

OPENAI_API_KEY=sk-your-actual-secret-key-here

重要警告 :务必确保 .env 文件被添加到 .gitignore 中, 绝对不要 将其提交到版本控制系统(如GitHub)。这是保护账户安全的基本操作。

3.2 核心代码逐行解读

现在,创建主程序文件 app.py ,这是我们AI助手的大脑。

# Stdlib Imports
from typing import Dict, Any

# Third Party Imports
import agenta as ag
from openai import AsyncOpenAI

# 1. 定义系统提示词 - 设定AI的“人设”
SYSTEM_PROMPT = """你是一位专业、富有创意且贴心的AI厨房助手。你的核心任务是:
1.  根据用户提供的现有食材,推荐一道或多道可行的、美味的菜肴。
2.  为推荐的菜肴提供清晰、详细的步骤说明。
3.  在适当时机,提供食物安全处理建议(例如,鸡肉要彻底煮熟)。
4.  回答用户关于食材替换、烹饪技巧等相关问题。
请保持回答热情、鼓励,并专注于帮助用户解决“吃什么”的难题。"""

系统提示词是驾驭LLM行为的关键缰绳。上面这个提示词明确了角色、任务范围和回答风格。你可以把它想象成给AI演员的剧本大纲。一个模糊的提示词(如“帮我做菜”)会导致回答不稳定。一个具体、带有约束的提示词能引导AI输出更可靠、有用的结果。

# 2. 定义可选的模型列表
CHAT_LLM_GPT = [
    "gpt-3.5-turbo",        # 默认平衡选择
    "gpt-3.5-turbo-16k",    # 需要处理更长对话或复杂提示时使用
    "gpt-4",                # 当需要最高质量、复杂推理时使用(成本较高)
]

这里定义了一个模型列表。在Agenta平台中,我们可以通过下拉菜单轻松切换这些模型,对比它们的效果和成本,而无需修改代码。

# 3. 初始化Agenta并配置参数
ag.init()

ag.config.default(
    temperature=ag.FloatParam(0.2),
    max_tokens=ag.IntParam(-1, -1, 4000),
    prompt_system=ag.TextParam(SYSTEM_PROMPT),
    model=ag.MultipleChoiceParam("gpt-3.5-turbo", CHAT_LLM_GPT),
)

这是Agenta SDK的魔力所在:

  • ag.init() : 初始化Agenta,为后续操作做准备。
  • ag.config.default() : 定义应用的 可调参数 。这些参数会在Agenta的Web界面上显示为可调节的控件。
    • temperature ( FloatParam ): 创造性参数。我设为 0.2 ,偏向保守和稳定。如果设为 0.8 ,AI可能会给出更天马行空(也可能离谱)的食谱。 0.2 能确保食谱基本可靠。
    • max_tokens ( IntParam ): 生成内容的最大长度。 -1 表示使用模型默认最大值。后面的 (-1, 4000) 定义了在UI中可调节的范围(从-1到4000)。
    • prompt_system ( TextParam ): 将我们定义的系统提示词暴露为可调参数。这意味着我可以在Agenta界面上直接修改提示词,比如改成“你是一个严格的素食主义厨师”,并立即测试效果,无需改代码。
    • model ( MultipleChoiceParam ): 将模型选择暴露为下拉菜单。
# 4. 初始化OpenAI异步客户端
client = AsyncOpenAI()
# 注意:AsyncOpenAI会自动从环境变量 OPENAI_API_KEY 中读取密钥

使用异步客户端 AsyncOpenAI 是为了更好的性能。当我们的应用未来需要同时处理多个用户请求时,异步IO可以避免阻塞,提高吞吐量。

# 5. 定义应用的核心入口点
@ag.entrypoint
async def suggest(inputs: ag.MessagesInput = ag.MessagesInput()) -> Dict[str, Any]:
    """
    根据输入的食材,推荐定制化的美味菜肴。

    Args:
        inputs (ag.MessagesInput): 用户输入的聊天消息列表。

    Returns:
        dict: 包含LLM回复、token使用情况和估算成本。
    """
    # 5.1 构建发送给GPT的消息列表
    messages = [{"role": "system", "content": ag.config.prompt_system}] + inputs

    # 5.2 处理max_tokens参数(-1转为None)
    max_tokens = ag.config.max_tokens if ag.config.max_tokens != -1 else None

    # 5.3 调用OpenAI API
    chat_completion = await client.chat.completions.create(
        model=ag.config.model,
        messages=messages,
        temperature=ag.config.temperature,
        max_tokens=max_tokens,
    )

    # 5.4 提取使用量和成本
    token_usage = chat_completion.usage.dict()  # 获取本次请求消耗的token数
    return {
        "message": chat_completion.choices[0].message.content,  # AI的回复文本
        **{"usage": token_usage},  # token使用详情
        "cost": ag.calculate_token_usage(ag.config.model, token_usage),  # Agenta估算的成本
    }

@ag.entrypoint 装饰器是Agenta的核心。它告诉Agenta:“这个函数是我的应用的起点,请把它变成一个API。” Agenta底层会基于FastAPI自动将这个函数包装成POST端点。 ag.MessagesInput() 是一个特殊的类型,它允许Agenta的UI以聊天格式接收用户输入(类似于ChatGPT的界面)。函数内部逻辑清晰:组合系统提示词和用户输入,调用GPT API,然后返回一个结构化的字典,包含回答、资源使用情况和成本。成本估算功能对于监控应用开销非常实用。

4. 在Agenta平台上进行实验、评估与部署

4.1 发布应用到Agenta Cloud并初次测试

代码写好了,现在要让它在Agenta上跑起来。首先需要安装Agenta命令行工具(CLI),并在Agenta Cloud(或本地部署)上创建账户和项目。

# 在项目目录下,确保虚拟环境已激活,然后安装agenta-cli
pip install agenta-cli

# 登录到Agenta Cloud (会打开浏览器进行认证)
agenta login

# 初始化项目,这会引导你创建新项目或连接到已有项目
agenta init

执行 agenta init 后,CLI会交互式地询问项目名称、选择Agenta主机(Cloud或本地)、输入API密钥等。完成后,会在当前目录生成一个 config.toml 文件,记录项目配置。

接下来,将我们的应用“发布”为一个可测试的变体:

agenta variant serve app.py

这个命令做了几件重要的事:

  1. 它读取 app.py ag.config.default 中的参数定义。
  2. 在Agenta Cloud上创建一个名为 app.default 的应用变体( app 是代码库名, default 是配置名)。
  3. 在后台为这个变体构建一个Docker容器,并启动一个承载着REST API的服务。
  4. 在终端输出一个Playground的URL。

打开这个URL,你就进入了Agenta的Playground界面。这里你可以:

  • 在聊天框输入你的食材,例如:“我冰箱里有鸡蛋、西红柿、洋葱、一点芝士。”
  • 实时调整右侧面板的参数:把 temperature 调到 0.7 看看AI会不会推荐更疯狂的菜式;把 model 换成 gpt-4 对比一下回答的细致程度;甚至直接修改 prompt_system 文本框里的文字。
  • 每次点击“Run”,你都能看到AI的回复、消耗的Token、估算成本以及响应时间。

实操心得 :在Playground里,我做了第一个重要实验:对比 temperature=0.2 temperature=0.8 。输入“鸡蛋、牛奶、糖”,前者稳定地推荐了“牛奶炒蛋”或“甜味蒸蛋”,而后者则兴奋地建议我尝试“法式奶油布丁(Crème Brûlée)的简易平底锅版本”。这让我意识到,对于想寻求灵感的用户,或许应该提供一个“创意模式”的开关,实际上就是动态调整 temperature 参数。

4.2 构建测试集与自动化评估

当应用变体多起来后,靠人工一个个测试效率太低。Agenta的“Test Sets”和“Evaluations”功能就是为了解决这个问题。

创建黄金测试集(Golden Test Set): 在Agenta的“Test Sets”标签页,我可以创建一个数据集。例如,我添加了多条测试用例:

输入(用户消息) 期望输出(包含的关键词)
“只有鸡蛋和米饭” “蛋炒饭”、“葱花”、“酱油”
“鸡胸肉、西兰花、大蒜” “清炒”、“蒜香”、“腌制”
“我想吃甜的,有香蕉和牛奶” “香蕉奶昔”、“甜品”、“搅拌”

这个测试集定义了在给定输入下,一个“好”的回答应该具备哪些要素。它成为了我们评估AI表现的基准。

配置自动化评估: 在“Evaluations”标签页,我可以创建一个新的评估任务:

  1. 选择评估器 :例如,我选择“相似度匹配(Similarity Match)”评估器,它可以计算AI生成回答与我的“期望输出”在语义上的相似度得分。
  2. 选择测试集 :关联上面创建的黄金测试集。
  3. 选择要对比的变体 :比如,我可以同时对比 app.default (使用 gpt-3.5-turbo )和另一个我新创建的 app.chef_mode (使用 gpt-4 和更华丽的提示词)两个变体。

运行评估后,Agenta会生成一份报告,清晰地展示哪个变体在测试集上的平均得分更高。这种数据驱动的决策方式,远比“我觉得这个回答更好”要可靠。

4.3 部署到生产环境与API集成

经过Playground的调试和评估环节的验证,我们找到了一个表现最佳的变体配置(比如 model=gpt-3.5-turbo-16k , temperature=0.3 , 提示词为专业厨师风格)。现在可以将其部署到生产环境了。

在Agenta的Playground或“Variants”页面,找到你满意的变体,点击“Publish”。在弹出的窗口中,选择“Production”环境,然后确认。Agenta会自动将这个变体的容器部署到更稳定、可扩展的生产服务器集群上,并提供一个专有的、带认证的API端点。

部署完成后,进入“Endpoints”页面,选择“Production”环境,Agenta会为你展示如何调用这个API。它支持Python、cURL和TypeScript三种代码示例。

例如,使用cURL调用:

curl -X POST https://your-agenta-cloud-endpoint/your-app-id/variants/your-variant-id \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "inputs": [
      {"role": "user", "content": "我有土豆、胡萝卜、牛肉,能做什么?"}
    ]
  }'

你会收到一个JSON响应,里面就包含了AI生成的食谱建议。现在,这个端点可以被任何前端应用(如React网页、Flutter移动应用、微信小程序等)调用,你的AI厨房助手就正式上线服务了。

5. 进阶优化与避坑指南

5.1 提示词工程进阶技巧

最初的系统提示词已经能工作,但要让AI助手更“聪明”,还需要精细打磨:

  • 增加约束条件 :在提示词中明确“请列出所需但用户未提及的常见调味料(如盐、油)”,“如果某道菜需要特殊厨具(如烤箱),请明确指出”。
  • 设定输出格式 :让AI的回答结构化,便于前端解析。例如:“请按以下格式回复:1. 推荐菜名;2. 所需食材清单;3. 详细步骤;4. 小贴士。”
  • 注入领域知识 :如果你希望助手更专业,可以在提示词中加入“你精通中餐、意大利菜和日本料理”,或者“你特别擅长为忙碌的上班族设计15分钟快手菜”。
  • 处理多轮对话 :当前的 @ag.entrypoint 函数接收的是 ag.MessagesInput ,这本身就是一个消息列表。你需要在前端维护整个对话历史,并将历史记录作为 inputs 的一部分传入,AI就能基于上下文进行连续对话,例如回答“上一步说的那道菜,能做成辣的吗?”这种问题。

5.2 性能、成本与安全考量

  • 控制生成长度与成本 max_tokens 参数是控制单次响应成本和速度的关键。对于食谱生成,通常设置 max_tokens=800 足以覆盖一道菜的详细说明。过长的生成不仅费钱,用户也懒得看。Agenta返回的 cost 字段要密切关注。
  • 设置超时与重试 :在生产环境调用API时,务必设置合理的超时时间(如10秒),并实现重试逻辑(对于5xx错误),以增强应用鲁棒性。
  • 输入验证与过滤 :永远不要相信用户输入。在前端或API网关层,要对输入的食材列表做基本清洗,过滤掉明显恶意、无关或过长的文本,防止提示词注入攻击或浪费API调用。
  • 内容安全审核 :虽然概率极低,但AI有可能生成不安全的食谱(如建议生食某些肉类)。对于严肃的生产应用,应考虑在输出端接入内容安全API(如OpenAI自己的Moderation API)进行二次检查。

5.3 常见问题排查实录

  1. 问题 :运行 agenta variant serve 时失败,提示Docker相关错误。
    • 排查 :首先确认Docker服务是否在本地运行( docker ps )。如果使用Agenta Cloud,通常不需要本地Docker。确保网络通畅,并且 config.toml 中配置的Agenta主机地址正确。
  2. 问题 :在Playground调用成功,但通过生产环境Endpoint调用返回 401 Unauthorized
    • 排查 :检查Endpoint页面提供的API Key是否正确复制,并在请求头中正确添加了 Authorization: Bearer <API_KEY> 。生产环境的Key与Playground的测试Key不同。
  3. 问题 :AI回复看起来“很蠢”,总是重复类似的菜谱,缺乏创意。
    • 排查 :首先检查 temperature 是否设置过低(如接近0)。尝试将其提高到0.5-0.7。其次,审查系统提示词,是否限制过多(如“只推荐家常菜”),尝试加入“请发挥创意”、“推荐一些不常见的融合菜式”等指令。
  4. 问题 :响应速度很慢。
    • 排查 :a) 检查使用的模型, gpt-4 gpt-3.5-turbo 慢。b) 检查 max_tokens 是否设置过大。c) 考虑使用异步客户端(如我们代码中的 AsyncOpenAI )并在前端实现加载状态,提升用户体验感知。

这个项目从厨房里的一个烦恼开始,最终变成了一个功能完整、可部署的AI应用。它最让我满意的部分,不是技术本身,而是它切实解决了一个日常问题。通过Agenta,整个开发、测试、优化到部署的流程变得异常顺畅。你可以在此基础上无限扩展:增加图片识别食材功能,连接智能冰箱的库存API,甚至整合外卖平台,在AI建议你“做番茄炒蛋”的同时,一键下单缺少的葱花。技术的乐趣,莫过于此。

Logo

中国智能体开发者社区,聚焦智能体与大模型开发,提供前沿资讯、实用工具链、开源项目及行业案例。通过技术沙龙、开发者大赛等活动,促进经验交流与协作,助力开发者快速构建创新智能应用。

更多推荐