基于GPT-3.5与Agenta的AI厨房助手:从LLM应用到生产部署全流程实践
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。这主要基于几点务实考虑:
- 成本与性能平衡 :对于食谱生成这类创造性文本任务,
gpt-3.5-turbo已经能提供极高品质的回复,其成本却远低于GPT-4。在需要频繁实验和调优的开发阶段,控制成本至关重要。 - 速度 :
gpt-3.5-turbo的响应速度更快,这对于未来集成到移动端、追求流畅对话体验的场景来说是个优势。 - 足够的“智慧” :在烹饪这个领域,模型的“知识”广度和创造性比极致的复杂推理能力更重要。
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
这个命令做了几件重要的事:
- 它读取
app.py和ag.config.default中的参数定义。 - 在Agenta Cloud上创建一个名为
app.default的应用变体(app是代码库名,default是配置名)。 - 在后台为这个变体构建一个Docker容器,并启动一个承载着REST API的服务。
- 在终端输出一个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”标签页,我可以创建一个新的评估任务:
- 选择评估器 :例如,我选择“相似度匹配(Similarity Match)”评估器,它可以计算AI生成回答与我的“期望输出”在语义上的相似度得分。
- 选择测试集 :关联上面创建的黄金测试集。
- 选择要对比的变体 :比如,我可以同时对比
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 常见问题排查实录
- 问题 :运行
agenta variant serve时失败,提示Docker相关错误。- 排查 :首先确认Docker服务是否在本地运行(
docker ps)。如果使用Agenta Cloud,通常不需要本地Docker。确保网络通畅,并且config.toml中配置的Agenta主机地址正确。
- 排查 :首先确认Docker服务是否在本地运行(
- 问题 :在Playground调用成功,但通过生产环境Endpoint调用返回
401 Unauthorized。- 排查 :检查Endpoint页面提供的API Key是否正确复制,并在请求头中正确添加了
Authorization: Bearer <API_KEY>。生产环境的Key与Playground的测试Key不同。
- 排查 :检查Endpoint页面提供的API Key是否正确复制,并在请求头中正确添加了
- 问题 :AI回复看起来“很蠢”,总是重复类似的菜谱,缺乏创意。
- 排查 :首先检查
temperature是否设置过低(如接近0)。尝试将其提高到0.5-0.7。其次,审查系统提示词,是否限制过多(如“只推荐家常菜”),尝试加入“请发挥创意”、“推荐一些不常见的融合菜式”等指令。
- 排查 :首先检查
- 问题 :响应速度很慢。
- 排查 :a) 检查使用的模型,
gpt-4比gpt-3.5-turbo慢。b) 检查max_tokens是否设置过大。c) 考虑使用异步客户端(如我们代码中的AsyncOpenAI)并在前端实现加载状态,提升用户体验感知。
- 排查 :a) 检查使用的模型,
这个项目从厨房里的一个烦恼开始,最终变成了一个功能完整、可部署的AI应用。它最让我满意的部分,不是技术本身,而是它切实解决了一个日常问题。通过Agenta,整个开发、测试、优化到部署的流程变得异常顺畅。你可以在此基础上无限扩展:增加图片识别食材功能,连接智能冰箱的库存API,甚至整合外卖平台,在AI建议你“做番茄炒蛋”的同时,一键下单缺少的葱花。技术的乐趣,莫过于此。
更多推荐



所有评论(0)