# food-vision-agent **Repository Path**: hwxus/food-vision-agent ## Basic Information - **Project Name**: food-vision-agent - **Description**: 上传一张食物照片,自动识别菜品、把每道菜拆到原材料级别成分,并给出营养估算与膳食建议。 - **Primary Language**: Unknown - **License**: MIT - **Default Branch**: master - **Homepage**: https://gitee.com/hwxus/food-vision-agent - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-09-10 - **Last Updated**: 2026-09-10 ## Categories & Tags **Categories**: Uncategorized **Tags**: WorkBuddy, langchain, FastAPI ## README # 食物识别智能体 (Food Vision Agent) 上传一张食物照片,自动识别菜品、把每道菜拆到**原材料级别成分**,并给出营养估算与膳食建议。 - 第一阶段:浏览器上传图片使用 - 第二阶段:Android App 复用同一套 REST 接口(后端无需改动) 完整技术方案与接口设计见 [`docs/设计文档.html`](docs/设计文档.html)。 > ⚠️ 本项目调用第三方大模型 API(阿里云百炼 / 腾讯云 TokenHub / OpenRouter)。**你必须自备 API Key 并自行承担调用费用与合规责任**,详见文末「数据安全与合规」。 ## 特性 - 多供应商故障转移:一家欠费/限流自动切换另一家,不中断服务 - 零成本兜底:OpenRouter 免费视觉/文本模型可用,开发演示不花钱 - 原材料级成分拆解:番茄炒蛋 → 鸡蛋、番茄、食用油、食盐、白糖 - 营养分析:热量/蛋白/脂肪/碳水/纤维/钠 + 健康评分与可执行建议 - 前置校验:启动即探测各家 Key/额度/模型权限,页面可一键重查 - 图片预处理:EXIF 纠偏 + 等比缩放 + JPEG 重编码,token 降本一个数量级 - 历史记录:SQLite 持久化,分页查询 ## 快速开始 ```bash # 1. 安装依赖(Python 3.14 全局环境;见下方「运行依赖」) pip install -r requirements.txt # 2. 准备配置:复制模板,填入你自己的 Key cp .env.example .env # 编辑 .env,至少填一个供应商的 API_KEY # 3. 启动 python main.py # 4. 浏览器打开 # 页面 http://127.0.0.1:8000/ # 接口文档 http://127.0.0.1:8000/docs ``` 手机真机调试:`python main.py --host 0.0.0.0`,把地址里的 `127.0.0.1` 换成电脑局域网 IP。 ## 运行依赖 本机 Python 3.14.4 已验证全部可用。`requirements.txt` 用于换机器复现: | 组件 | 用途 | |---|---| | fastapi / uvicorn | Web 服务 | | langchain / langchain-openai | 模型编排(走 OpenAI 兼容协议) | | dashscope | 通义千问 SDK(DashScope 原生兜底路径) | | pillow / numpy | 图片处理 | | json_repair / httpx | JSON 容错解析 / 供应商校验请求 | | python-dotenv / python-multipart / pydantic | 配置 / 文件上传 / 数据契约 | **不要安装 torch / tensorflow / opencv-python** —— Python 3.14 无对应 wheel,且本项目不使用本地推理。 ## 配置说明 所有密钥由服务端 `.env` 持有。**三家供应商可同时配置**,按 `FOOD_VISION_CHAIN` / `FOOD_TEXT_CHAIN` 顺序自动故障转移。 | 配置 | 默认 | 说明 | |---|---|---| | `DASHSCOPE_API_KEY` | 空 | 阿里云百炼,视觉 `qwen-vl-max`、文本 `qwen-plus`(需充值) | | `TOKENHUB_API_KEY` | 空 | 腾讯云 TokenHub,视觉 `hy-vision-2.0-instruct`(需充值/后付费) | | `OPENROUTER_API_KEY` | 空 | OpenRouter 聚合网关,**免费模型可用,零成本兜底** | | `OPENROUTER_VISION_MODELS` | 见 .env.example | 免费视觉模型兜底链,逗号分隔,逐个尝试 | | `OPENROUTER_TEXT_MODELS` | 见 .env.example | 免费文本模型兜底链 | | `FOOD_VISION_CHAIN` | `openrouter,tokenhub,dashscope` | 视觉故障转移顺序 | | `FOOD_TEXT_CHAIN` | `openrouter,tokenhub,dashscope` | 文本故障转移顺序 | | `FOOD_CHECK_ON_STARTUP` | 1 | 启动后台异步校验,不阻塞服务 | | `FOOD_CHECK_TTL` | 600 | 校验结果缓存秒数 | | `FOOD_MOCK` | 0 | 置 1 强制 mock,不发任何网络请求、不计费 | | `FOOD_MAX_IMAGE_SIDE` | 1024 | 图片缩放到最长边上限 | | `FOOD_PORT` | 8000 | 服务端口 | > **实测坑**:DashScope 视觉模型必须用 `qwen-vl-max`,带 `-latest` 后缀(如 `qwen-vl-max-latest`)会 403 无权限——同一个 Key,只差一个后缀。 ## 免费模型(零成本开发/演示) 不想充值时,填 `OPENROUTER_API_KEY` 并把视觉/文本链首位设为 `openrouter` 即可: - 可用:`nvidia/nemotron-3-nano-omni-30b-a3b-reasoning:free`(多模态 + 文本,当前主力) - 限流恢复后自动顶上:`google/gemma-4-31b-it:free`、`google/gemma-4-26b-a4b-it:free` - **不要用** `openrouter/free`:它会路由到内容安全分类器,只回 "User Safety: safe",不是视觉模型 **限速提醒**:免费模型速率上限极低(上游 `ResourceExhausted`),表现为「偶尔能调、连调就被限」,适合低频开发演示,不适合生产高并发。生产请给 DashScope 或 TokenHub 充值,代码无需改动即自动切换。 ## 接口一览 | 方法 | 路径 | 用途 | |---|---|---| | POST | `/api/analyze` | 上传图片并识别(核心) | | GET | `/api/health` | 健康检查与配置自检 | | GET | `/api/version` | 依赖版本自检 | | POST | `/api/config/check` | 校验各供应商 Key/模型/额度,`reload=true` 热加载 .env | | GET | `/api/history` | 历史列表(分页) | | GET | `/api/history/{id}` | 单条记录详情 | | GET | `/api/image/{id}` | 获取记录图片 | 错误统一返回 `{"ok": false, "error": {"code": 400, "message": "..."}}`。 ## 多供应商与前置校验 三家供应商都走 OpenAI 兼容协议,共用同一套调用代码,差异只在 `base_url`、Key 和模型名。 - **故障转移**:识别时按链顺序逐个尝试,第一个成功的返回;DashScope 额外有一条原生 SDK 兜底。全部失败才报错。 - **前置校验**(必须,非可选):实测中抓出过文档里没有的问题——`qwen-vl-max-latest` 403、TokenHub 免费额度耗尽 402、OpenRouter 余额 0 需充值。 - 校验在三个时机触发:**启动后台异步**(不阻塞服务)、**页面按钮手动**、**识别前查缓存排序**。 ## 数据安全与合规 1. **密钥安全**:所有 API Key 仅在服务端 `.env` 中,前端不持有、不下发。`.env` 已被 `.gitignore` 忽略,**切勿提交到版本库**。若 Key 曾泄露,立即到对应控制台重置。 2. **数据出境**:上传的图片与食物信息会发送给你所配置的第三方大模型供应商,按其服务条款与隐私政策处理。请确认你使用的供应商在你所在地区合规。 3. **本地存储**:识别记录存于本地 `data/`(SQLite + 图片),已被 `.gitignore` 忽略;上线前请迁移到受控存储并定期清理。 4. **合规使用**:本项目仅供学习/个人使用,商业部署需自行评估大模型供应商的许可与资费。 ## 目录结构 ``` food-vision-agent/ ├── main.py 启动入口 ├── .env.example 配置模板(复制为 .env 后填 Key) ├── .env 密钥与配置(已被 .gitignore 忽略,勿提交) ├── requirements.txt 依赖清单 ├── app/ │ ├── config.py 唯一读取环境变量的地方 │ ├── providers.py 供应商注册表 + 前置校验器 │ ├── schemas.py 接口契约 │ ├── vision.py 图片预处理 + 多模型识别 │ ├── nutrition.py 营养分析与建议 │ ├── storage.py SQLite 持久化 │ └── api.py FastAPI 路由 ├── static/index.html 上传页面 ├── docs/ 设计文档 └── data/ SQLite + 图片仓库(运行时生成,被忽略) ``` ## 上线前必做 - [ ] 收窄 CORS 的 `allow_origins`,现在放开的是 `*` - [ ] 加接口鉴权(Token 或签名) - [ ] 给 `/api/analyze` 加频率限制,防止刷爆额度 - [ ] 图片目录迁对象存储,避免本地磁盘占满 - [ ] 定期清理历史图片(保留 N 天) - [ ] 确认所选大模型供应商的合规与数据出境要求 ## License [MIT License](LICENSE) —— 可自由使用、修改、分发,包括但不限于商业用途,但需保留版权声明,且不提供任何担保。 --- 免责声明:本项目与任一大模型供应商无隶属关系;识别结果由第三方模型生成,仅供参考,不构成营养或医疗建议。