多彩编程 多彩编程MZPH · CODE BLOG
ARTICLE DETAIL

文章详情

深耕前端与后端开发技术的一线实战笔记与踩坑复盘。

基于EdgeOne Makers Agents与Next.js构建智能菜谱AI助手实践

基于EdgeOne Makers Agents与Next.js构建智能菜谱AI助手实践 1. 项目缘起当烹饪APP遇到AI Agent最近在迭代一个自己维护的烹饪类Side Project功能挺常规的就是菜谱浏览、收藏和购物清单。但做着做着总觉得少了点“灵魂”。用户跟着菜谱做成功了固然好可要是家里缺了某样调料或者想根据口味调整咸淡甚至想把中式红烧肉改成适合健身的版本现有的静态菜谱就无能为力了。用户只能去别的平台搜索或者凭经验摸索体验是割裂的。我一直关注着AI Agent的发展觉得它不该只是个高级聊天机器人。真正的智能应该能理解上下文主动规划步骤并执行具体任务。直到我深入体验了EdgeOne的Makers Agents平台一个想法冒了出来为什么不给我的APP“雇佣”一位24小时在线的AI主厨呢这位主厨不止能回答“料酒是什么”这种问题更能理解“我家没有蚝油用什么代替”、“这份糖醋排骨的糖量能减半吗会影响口感吗”这类动态需求并直接给出修改后的、可执行的菜谱方案。这个项目就是基于Next.js前端框架利用EdgeOne Makers Agents构建的后端AI能力打造的一个能深度理解用户意图、并动态“改写”菜谱的智能烹饪助手。它让菜谱从冰冷的文本变成了一个可以对话、可以协商、可以个性化定制的智能体。2. 技术选型与架构设计为什么是它们2.1 核心平台EdgeOne Makers Agents选择EdgeOne Makers Agents作为AI能力的基座是经过一番对比的。市面上提供AI Agent开发能力的平台不少但Makers Agents有几个点直接命中我的需求第一开箱即用的Agent编排能力。我不需要从零开始用LangChain或AutoGen去搭框架处理复杂的工具调用、记忆流和规划逻辑。Makers Agents提供了可视化的编排界面我可以像搭积木一样把“理解用户查询”、“检索知识库菜谱”、“调用大模型分析”、“生成修改建议”这几个模块连接起来。这极大降低了开发门槛让我能聚焦在烹饪领域的业务逻辑本身。第二原生集成与低延迟。我的APP主体部署在Vercel与Next.js绝配而EdgeOne本身与Vercel同属一个生态且在边缘网络上有深度优化。这意味着AI Agent的服务可以部署在离用户更近的边缘节点当用户提出“修改菜谱”的请求时Agent的思考与响应速度会非常快避免了因网络延迟带来的对话卡顿感这对交互体验至关重要。第三可控的成本与权限管理。作为一个个人项目成本必须可控。Makers Agents的按需调用计费模式很清晰并且它允许我精细地控制Agent能访问哪些数据比如只访问我的菜谱数据库、能调用哪些工具比如只能进行菜谱文本修改不能访问外部API安全性更有保障。2.2 前端框架Next.js 14 (App Router)Next.js几乎是现代React应用的首选尤其是其App Router模式为这个项目带来了巨大便利。服务端组件Server Components的天然优势。菜谱详情页、用户历史记录这些静态或个性化内容我可以用服务端组件直接渲染速度快且利于SEO。而需要与AI主厨交互的聊天界面则使用客户端组件实现动态交互。这种混合渲染模式让架构非常清晰高效。API Routes的便捷性。在app/api/目录下创建路由来处理与EdgeOne Agents后端的通信变得极其简单。我只需要一个/api/chat的POST接口前端将用户消息和上下文传过来我在这里调用EdgeOne的Agent API再将流式或非流式的响应返回给前端。Next.js帮我处理了路由、解析等琐事。对流式响应Streaming的出色支持。AI主厨的“思考”过程如果一下子全返回用户需要等待较长时间。更好的体验是让回答一个字一个字“流”出来。Next.js 14的App Router可以很方便地使用Response对象和TextStream来实现服务端到客户端的流式传输这正是实时对话体验所需要的。2.3 AI Agent设计思路从聊天到“执行”这是本项目的核心。我的目标不是做一个“菜谱问答机”而是一个能执行“修改菜谱”指令的Agent。它的工作流我设计如下意图识别与槽位填充用户说“我想做红烧肉但不吃肥肉”。Agent需要识别出核心意图是“修改菜谱”并提取关键槽位目标菜谱红烧肉约束条件去除肥肉。知识检索与上下文构建根据目标菜谱从我的数据库里检索出标准的红烧肉菜谱包括食材、步骤、技巧。将原始菜谱和用户约束一起作为新的上下文。任务规划与工具调用Agent内部规划要满足“去肥肉”需要调整“选材”步骤改用瘦肉部位和“烹饪”步骤调整炖煮时间以防柴。它需要调用我预设的“菜谱修改工具”这个工具本质上是一套提示词Prompt指导大模型进行专业修改。执行与呈现大模型基于工具调用输出修改后的完整菜谱。Agent将此结果结构化如分成“调整要点”、“新食材清单”、“新步骤”返回给前端。这个流程的关键在于Agent的“大脑”被植入了专业的烹饪知识通过高质量的提示词和示例使其修改建议不是天马行空而是合乎烹饪逻辑的。注意Agent的能力边界必须在一开始就定义清楚。例如我明确禁止它生成全新的、未经验证的菜谱有食品安全风险它的核心权限仅限于在现有权威菜谱基础上进行符合常识的替换、增减量、合并步骤等操作。3. 核心实现细节拆解3.1 EdgeOne Makers Agents 的编排实战在Makers Agents的控制台我创建了一个名为“AI主厨”的Agent。其编排逻辑如下图所示用文字描述节点1输入解析器。接收来自Next.js后端的用户查询。这里我配置了一个预处理提示词让模型先判断用户意图是否是“修改菜谱”或“烹饪建议”。如果是简单问答如“牛排几分熟好吃”会走一个快速问答分支如果是复杂修改则进入主流程。节点2菜谱检索器。这是一个自定义工具节点。我编写了一个函数根据解析出的菜谱名称去查询我的PostgreSQL数据库。这里有个技巧除了精确匹配我还使用了向量搜索。在录入菜谱时我用OpenAI的嵌入模型text-embedding-3-small为每道菜的标题、主要食材和风味特点生成了向量存储在Supabase的pgvector扩展中。当用户说“我想做那个甜甜的、用鸡肉和花生做的菜”这种模糊描述时Agent能通过语义相似度找到“宫保鸡丁”检索准确率大幅提升。节点3菜谱修改引擎核心工具。这是我花费精力最多的部分。这不是一个简单的代码函数而是一个精心设计的、具有链式思考Chain-of-Thought能力的提示词模板。它被定义为一个“工具”接收两个参数original_recipe原始菜谱JSON和user_request用户修改请求。提示词会要求模型按以下步骤工作1. 分析用户请求对菜谱的哪一部分食材、调料、步骤、技巧、设备造成了影响。 2. 评估修改的可行性及对最终风味、口感可能产生的影响。 3. 分点列出具体的修改建议并解释原因。 4. 输出修改后的完整菜谱并特别标注出改动处。例如对于“去除肥肉”的请求模型可能会输出“调整要点1. 主料改用猪梅花肉或去皮五花肉瘦肉部分以平衡口感与油脂。2. 煸炒阶段减少出油时间避免瘦肉变干。3. 炖煮时增加约15分钟并使用更小的火力使瘦肉更酥烂。新食材清单猪梅花肉500克……后续略”节点4结果格式化与安全过滤。修改引擎输出的内容还需要经过一层处理。这里我设置了一个“安全与格式检查”节点它会检查输出中是否包含不安全的烹饪建议如“生吃豆角”并将模型输出的文本格式化为前端易于解析的JSON结构比如{“summary”: “调整要点”, “ingredients”: […], “steps”: […], “tips”: “…”}。3.2 Next.js 前端与Agent的通信桥梁前端界面是一个典型的聊天界面但重点在于与后端的高效、流畅通信。API路由设计 (app/api/chat/route.ts)import { NextRequest, NextResponse } from next/server; import { EdgeOneAgentClient } from /lib/edgeone; // 封装的EdgeOne SDK客户端 export async function POST(request: NextRequest) { try { const { messages, recipeContext } await request.json(); // 获取消息历史和当前菜谱上下文 const userMessage messages[messages.length - 1].content; // 构建Agent执行所需的输入包含对话历史和关键的菜谱上下文 const agentInput { query: userMessage, context: 当前用户正在查看的菜谱信息${JSON.stringify(recipeContext)}。历史对话${JSON.stringify(messages.slice(-5))} // 限制历史长度 }; // 调用EdgeOne Makers Agents的API启用流式响应 const stream await EdgeOneAgentClient.executeStreaming(your-agent-id, agentInput); // 将EdgeOne返回的流转换为Next.js可用的ReadableStream const encoder new TextEncoder(); const readableStream new ReadableStream({ async start(controller) { for await (const chunk of stream) { const content chunk.choices[0]?.delta?.content; if (content) { controller.enqueue(encoder.encode(content)); } } controller.close(); }, }); // 返回流式响应 return new Response(readableStream, { headers: { Content-Type: text/plain; charsetutf-8, Cache-Control: no-cache, }, }); } catch (error) { console.error(Chat API error:, error); return NextResponse.json({ error: AI主厨暂时离线请稍后再试 }, { status: 500 }); } }前端流式渲染 (app/components/chat-ui.tsx) 前端使用useState管理消息列表在用户发送消息时调用上述API并通过fetch处理流式响应。const [input, setInput] useState(); const [messages, setMessages] useStateChatMessage[]([]); const [isLoading, setIsLoading] useState(false); const handleSubmit async () { if (!input.trim()) return; const userMessage: ChatMessage { role: user, content: input }; setMessages(prev [...prev, userMessage]); setInput(); setIsLoading(true); // 添加一个空的助手消息用于接收流式内容 setMessages(prev [...prev, { role: assistant, content: }]); try { const response await fetch(/api/chat, { method: POST, headers: { Content-Type: application/json }, body: JSON.stringify({ messages: [...messages, userMessage], recipeContext: currentRecipe // 当前页面菜谱数据 }), }); const reader response.body?.getReader(); const decoder new TextDecoder(); if (!reader) return; while (true) { const { done, value } await reader.read(); if (done) break; const chunk decoder.decode(value); // 将流式内容逐步追加到最后一条助手消息中 setMessages(prev { const lastMsg prev[prev.length - 1]; const otherMsgs prev.slice(0, -1); return [...otherMsgs, { ...lastMsg, content: lastMsg.content chunk }]; }); } } catch (error) { console.error(Streaming error:, error); setMessages(prev [...prev, { role: assistant, content: 抱歉我好像出了点小状况。 }]); } finally { setIsLoading(false); } };3.3 提示词工程让AI成为“专业主厨”Agent的智能程度90%取决于提示词的质量。我的“菜谱修改引擎”提示词是一个多轮对话的模板你是一位经验丰富、精通中西餐的顶级主厨。你的任务是帮助用户根据他们的个性化需求调整一份既有的经典菜谱。 ## 背景信息 这是原始菜谱 {original_recipe} 这是用户的需求 {user_request} ## 你的任务 1. **分析影响**用户的请求主要希望改变菜谱的哪个方面食材、调味、步骤复杂度、烹饪时间、适用人群等 2. **评估可行性**这个改变在烹饪原理上是否可行可能会带来哪些正面或负面的风味/口感变化 3. **制定修改方案**给出具体的、可操作的修改点。对于食材替换请给出1-2种常见替代品。对于增减量请给出建议比例。 4. **输出新菜谱**生成一份完整的、修改后的菜谱。请用以下JSON格式回复不要有任何额外的markdown标记 { analysis: 简要的分析与可行性评估, modification_points: [要点1: ..., 要点2: ...], modified_recipe: { name: 新菜谱名称可稍作调整, ingredients: [用量 食材1, 用量 食材2...], steps: [步骤1..., 步骤2...], chef_tips: 给你的额外烹饪建议 } } ## 重要原则 - **安全第一**绝对不要建议生食易中毒的食材如豆角、木薯、某些蘑菇。 - **忠于原味**修改应尽量保持菜系的原始风味精髓。 - **清晰具体**用量使用“克”、“毫升”、“茶匙”等标准单位避免“适量”、“少许”。这个提示词明确了角色、任务、输出格式和边界原则让大模型的输出稳定、可靠、有用。4. 踩坑实录与性能优化4.1 遇到的典型问题与解决方案问题一Agent“幻觉”导致离谱建议。早期测试中用户问“做蛋糕没有烤箱怎么办”Agent有时会建议“用微波炉高火加热10分钟”这显然会导致灾难。或者建议用“酸奶”代替“鸡蛋”完全无视食材功能性的不同。解决方案强化提示词中的约束在提示词中明确加入“安全第一”和“烹饪原理可行性”章节并列举负面例子。引入知识库校验在Agent流程中增加一个“常识校验”节点。当修改引擎输出建议后这个节点会调用一个更轻量级的模型如GPT-3.5-Turbo基于一个烹饪常识库我整理的QA对进行快速校验如果发现高风险或明显错误建议则触发重新生成或直接返回“此修改存在风险建议您...”。设置用户确认环节对于涉及重大改变如主要蛋白质替换或非主流烹饪方法的建议前端会在展示时高亮提示“此为AI建议请谨慎尝试并确保食材熟透”。问题二流式响应在复杂思考时卡顿。当用户请求复杂时Agent内部思考Chain-of-Thought时间变长导致前端等待十几秒才看到第一个字体验很差。解决方案分阶段流式输出我修改了Agent的编排让“分析影响”和“评估可行性”这两个初步思考结论先流式输出。比如先快速打出“好的您希望减少糖分。这会影响菜品的色泽和焦糖化风味但用代糖或水果天然甜味可以部分弥补。” 让用户立刻感知到AI已理解。然后再慢慢输出具体的修改方案和完整菜谱。前端优化等待体验在等待时前端不仅显示加载动画还会随机显示一些烹饪小贴士如“热锅冷油不易粘锅”转移用户注意力降低等待焦虑感。问题三上下文长度与成本控制。每次对话都携带完整的菜谱文本和长对话历史导致Token消耗很快成本上升。解决方案智能上下文窗口不是所有历史都有用。我实现了一个简单的历史摘要机制。当对话轮次超过5轮我会调用大模型将之前的对话总结成一段简短的摘要如“用户希望将川菜口味调淡并已讨论了减少辣椒和花椒的方案”然后用摘要替代原始长历史作为新的上下文输入。菜谱向量化检索如前所述只传递菜谱的关键特征向量和ID而不是全文在Agent需要细节时再通过ID实时查询数据库大幅减少了无效Token。4.2 性能与体验优化点1. 预加载Agent在用户进入某个菜谱详情页时前端就在后台静默初始化一个与该菜谱关联的Agent会话。这样当用户点击“咨询AI主厨”按钮时几乎可以立刻开始对话消除了冷启动延迟。2. 结构化结果渲染前端解析Agent返回的JSON不是简单以文本形式展示。modification_points会渲染成高亮的要点列表modified_recipe的食材和步骤会重新渲染成漂亮的UI组件并且“修改处”有视觉对比如划掉原内容新增内容标绿让用户一目了然。3. 操作快捷入口在AI主厨给出的新菜谱下方提供“使用此菜谱创建新菜单”、“将修改加入购物车”等按钮将AI的建议无缝转化为用户的下一步操作形成体验闭环。5. 效果评估与未来展望上线测试一段时间后我从用户反馈和数据中观察到一些有趣的现象用户活跃度提升集成AI主厨的菜谱页面平均停留时长提升了近3倍。用户不仅看更开始“问”和“改”。高频修改场景排名前三的修改需求是1.食材替代家里没有/不喜欢某样东西2.口味调整减盐、减糖、加辣3.工具简化没有烤箱/空气炸锅怎么办。这验证了“动态菜谱”需求的真实性。信任建立需要过程初期用户对AI建议将信将疑但随着多次提供合理建议例如建议用菠萝汁代替糖来增加酸甜味用户信任度逐渐建立。在界面明确标注“AI建议仅供参考”反而增加了可信度。我个人最大的体会是AI Agent的价值不在于替代人而在于放大人的能力。它把用户从一个被动的菜谱“跟随者”变成了一个主动的“共创者”。技术实现上EdgeOne Makers Agents提供的编排能力让复杂AI逻辑的开发变得像搭乐高而Next.js的现代前端架构则让交互体验流畅自然。两者的结合让我这个小型独立开发者也能在有限资源下做出具有“智能感”的产品。这个项目还有很多可以深挖的方向比如让AI主厨根据用户冰箱里的现有食材自动推荐菜谱并生成采购清单或者根据用户的历史健康数据如需要低钠饮食自动过滤和调整菜谱。AI与垂直场景的结合永远有新的故事可讲。
返回列表