用 Trae Solo+豆包1.6+Seedream4.0 做了个能识菜点餐的 AI 工具

3 阅读

为什么要做“AI识菜通”

出国吃饭最头疼什么?不是口味,是看不懂菜单。哪怕会一点外语,面对手写体、排版混乱或专业术语堆砌的菜单,也常常两眼一抹黑。更别说有些地方连英文都没有。

文章配图

能不能有个工具,拍张照就告诉我这是什么菜、大概什么味道,还能直接生成一句我能拿给服务员看的话?这个想法催生了“AI识菜通”——一个纯前端、不依赖后端的智能点餐助手。

文章配图

它的核心逻辑很简单:

文章配图

  1. 用户上传一张菜单图片;
  2. AI 自动识别所有菜品,翻译成中文,并附上描述;
  3. 为每道菜生成一张看起来靠谱的图片;
  4. 用户点选想吃的菜,最后生成一句包含中英文菜名的点餐清单。

文章配图

听起来不难,但要把这几个步骤串起来、跑得稳、结果准,光靠调几个 API 是不够的。关键在于如何管理整个过程中的上下文信息。

文章配图

上下文工程:让多个 AI 模型协同干活

文章配图

过去我们总说“提示词工程”,好像只要 prompt 写得好,模型就能听话。但在多步骤任务里,这远远不够。比如在这个项目里,第一步要让视觉模型读懂菜单,第二步要让文生图模型画出对应的菜,第三步还要把用户的选择汇总成一句话。每一步都依赖前一步的结果,而且中间可能出错、用户可能修改选择。

文章配图

这时候就需要“上下文工程”——不是简单地传一段文字给模型,而是构建一个动态更新的信息空间,让每个模块都知道当前状态、历史操作和下一步目标。

文章配图

作者选用了 Trae Solo 来承担这个角色。它不是一个大模型,而是一个上下文编排平台,相当于整个 AI 应用的“操作系统”。它的作用包括:

文章配图

  • 结构化建模:定义清楚哪些是用户输入(图片)、哪些是系统状态(已识别的菜品列表)、哪些是模型能力(豆包能做什么、Seedream 能做什么);
  • 动态注入上下文:调用豆包时,只传图片和明确指令;调用 Seedream 时,只传菜名和生成要求,避免无关信息干扰;
  • 管理用户意图:如果用户删掉一道菜,系统能立刻更新购物车,并停止为那道菜生成图片;
  • 错误降级:万一某个模型返回格式不对,可以切换备用方案,而不是直接崩溃。

文章配图

这种设计让整个流程变得鲁棒。即使某一步慢了或错了,系统也能继续运行,而不是让用户从头再来。

文章配图

用到的两个核心模型

文章配图

项目主要依赖字节跳动在火山引擎 Mass 平台上提供的两个模型:

文章配图

豆包 Vision 1.6(doubao-seed-1-6-vision)

文章配图

这是一个多模态理解模型,擅长从图像中提取结构化信息。作者给它的指令很明确:

文章配图

“请识别这张菜单图片中的所有菜品,并翻译为中文。请按照以下 JSON 格式返回:

{"dishes": [{"originalName": "原文名称", "chineseName": "中文名称", "description": "菜品描述", "estimatedPrice": "预估价格"}]}
```”

文章配图

这个模型支持 256k 上下文窗口,能处理复杂排版的菜单,甚至能区分主菜、配菜和价格。关键是它能稳定输出 JSON,省去了后续解析的麻烦。

文章配图

Seedream 4.0(doubao-seedream-4-0)

文章配图

这是字节最新的文生图模型,原生支持文本+图像混合输入。不过在这个项目里,只用了纯文本生成模式。对每道菜,系统会构造这样的 prompt:

文章配图

“高质量的{菜品名称}美食摄影,专业餐厅级别,自然光线,精美摆盘”

文章配图

然后生成一张 1024x1024 的图片。虽然不能保证 100% 还原真实菜品,但至少能让用户对“这道菜长什么样”有个直观印象,比干巴巴的文字强多了。

文章配图

两个模型通过 API 调用,密钥由用户自己在设置页填入,存在浏览器 LocalStorage 里,不会上传到任何服务器,保障了隐私和成本控制。

文章配图

前端实现:React + shadcn/ui

文章配图

整个应用是纯前端的,技术栈很现代:

文章配图

  • 框架:React 18 + TypeScript + Vite
  • UI 组件库:shadcn/ui(基于 Radix UI),自带暗色模式、响应式和无障碍支持
  • 状态管理:React Context + useReducer,管理菜品列表、购物车、处理进度等全局状态
  • 路由:简单的页面路由(首页、菜单页、设置页)
  • 部署:Vercel,每次 push 到 GitHub 自动构建预览

文章配图

页面流程也很清晰:

文章配图

  1. 首页:一个大大的拖拽上传区,用户放菜单图片进来;
  2. 处理中:显示“正在分析菜单”“正在生成图片”等状态;
  3. 菜单页:每道菜以卡片形式展示,包含中文名、原文名、描述、AI 生成图,以及一个“+”按钮加入购物车;
  4. 购物车:右下角浮动图标,点击展开已选菜品,可调整数量;
  5. 生成订单:点击后弹出一个文本框,内容类似:“我要点:宫保鸡丁 (Kung Pao Chicken)、麻婆豆腐 (Mapo Tofu)”——用户可以直接复制或展示给服务员。

文章配图

文章配图

文章配图

文章配图

文章配图

文章配图

所有数据都存在本地。如果你重新打开页面,最近一次识别的菜单还会缓存着,不用重复上传。

实际效果与局限

作者用国外餐厅的真实菜单做了测试。比如一张意大利语菜单,上传后几秒内就识别出“Pasta al Pomodoro”(番茄意面)、“Osso Buco”(米兰炖牛膝)等菜品,翻译准确,描述也合理(比如注明 Osso Buco 是“慢炖小牛膝配藏红花烩饭”)。

图片生成质量不错,至少能看出是意面、牛排或沙拉,不会把甜点生成成主菜。当然,细节上会有偏差——比如“提拉米苏”可能生成得偏湿,但整体可接受。

目前的局限也很明显:

  • 依赖用户 API 密钥:普通用户得自己去火山引擎申请,有一定门槛;
  • 模型调用有成本:每识别一次菜单、每生成一张图都要花钱,不适合高频使用;
  • 无法处理极端模糊或手写菜单:如果图片质量太差,识别率会下降;
  • 图片仅为示意:不能替代真实菜品照片,更多是辅助理解。

但作为个人工具或旅行应急方案,已经足够实用。

为什么这个组合值得关注

这个项目的价值,不在于做出了多么惊艳的功能,而在于展示了如何用现有开源/商用模型,通过合理的上下文设计,快速搭建一个端到端的 AI 应用

Trae Solo 解决了多模型协作中最头疼的状态同步问题;豆包提供了可靠的多语言视觉理解;Seedream 补上了视觉呈现的一环。三者结合,让开发者不用从零训练模型,也不用写复杂的后端逻辑,就能做出一个体验流畅的产品。

更重要的是,整个过程完全在浏览器完成,数据不出本地。这在当前强调隐私和成本控制的环境下,是一种值得借鉴的轻量化 AI 应用范式。

如果你经常出国吃饭,或者对多模态 AI 应用开发感兴趣,不妨试试这个思路。代码和部署链接都已经公开,改改 prompt 或换换模型,说不定就能做出属于你自己的“AI识XX通”。