Spaces:
Sleeping
Sleeping
升級 Google GenerativeAI 到最新版本 (google-genai v1.36.0)
Browse files- 更新 requirements.txt: google-generativeai -> google-genai
- 重構 app.py 以使用新的 Google Gen AI Python SDK
- 改用 genai.Client() 和 types.GenerateContentConfig()
- 優化圖片處理和內容生成流程
- 新增專案說明文件 CLAUDE.md
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
- CLAUDE.md +91 -0
- app.py +49 -10
- requirements.txt +1 -1
CLAUDE.md
ADDED
|
@@ -0,0 +1,91 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# CLAUDE.md
|
| 2 |
+
|
| 3 |
+
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
| 4 |
+
|
| 5 |
+
## 專案概述
|
| 6 |
+
|
| 7 |
+
這是一個基於 Gradio 和 Google AI Gemini 1.5 Flash 的智慧食物卡路里檢測應用程式。使用者可以上傳食物照片,AI 會自動識別食物種類並估算卡路里含量。
|
| 8 |
+
|
| 9 |
+
## 核心架構
|
| 10 |
+
|
| 11 |
+
### 單檔案應用程式結構
|
| 12 |
+
- **app.py**: 主要應用程式檔案,包含所有功能:
|
| 13 |
+
- Google AI 模型配置和初始化
|
| 14 |
+
- 圖片處理和 base64 編碼
|
| 15 |
+
- AI 食物識別和卡路里估算
|
| 16 |
+
- Gradio 使用者介面建立
|
| 17 |
+
- 事件處理(圖片上傳和分析)
|
| 18 |
+
|
| 19 |
+
### 關鍵依賴
|
| 20 |
+
- **Gradio**: 前端 web 介面框架
|
| 21 |
+
- **Google AI Generative Language**: 與 Gemini 1.5 Flash 模型的整合
|
| 22 |
+
- **Pillow (PIL)**: 圖片處理
|
| 23 |
+
- **python-dotenv**: 本機環境變數載入(可選)
|
| 24 |
+
|
| 25 |
+
### 環境配置
|
| 26 |
+
- **本機開發**: 使用 `.env` 檔案存儲 `GOOGLE_API_KEY`
|
| 27 |
+
- **HuggingFace Spaces 部署**: 透過平台環境變數設定 `GOOGLE_API_KEY`
|
| 28 |
+
- 支援自動檢測環境(本機 vs HuggingFace Spaces)
|
| 29 |
+
|
| 30 |
+
## 常用指令
|
| 31 |
+
|
| 32 |
+
### 環境設定
|
| 33 |
+
```bash
|
| 34 |
+
# 建立虛擬環境
|
| 35 |
+
uv venv .venv
|
| 36 |
+
|
| 37 |
+
# 啟動虛擬環境
|
| 38 |
+
source .venv/bin/activate
|
| 39 |
+
|
| 40 |
+
# 安裝依賴
|
| 41 |
+
uv pip install -r requirements.txt
|
| 42 |
+
|
| 43 |
+
# 設定環境變數
|
| 44 |
+
cp .env.example .env
|
| 45 |
+
# 編輯 .env 檔案並填入 GOOGLE_API_KEY
|
| 46 |
+
```
|
| 47 |
+
|
| 48 |
+
### 執行應用程式
|
| 49 |
+
```bash
|
| 50 |
+
# 方法一:直接執行
|
| 51 |
+
python app.py
|
| 52 |
+
|
| 53 |
+
# 方法二:使用執行腳本
|
| 54 |
+
./run.sh
|
| 55 |
+
```
|
| 56 |
+
|
| 57 |
+
### 開發工具
|
| 58 |
+
- 沒有特定的測試框架或 linting 工具設定
|
| 59 |
+
- 使用 Dockerfile 進行容器化部署
|
| 60 |
+
- 支援 HuggingFace Spaces 自動部署
|
| 61 |
+
|
| 62 |
+
## 重要的技術細節
|
| 63 |
+
|
| 64 |
+
### AI 模型整合
|
| 65 |
+
- 使用 Google AI GenerativeServiceClient
|
| 66 |
+
- 模型:`models/gemini-1.5-flash`
|
| 67 |
+
- 圖片透過 base64 編碼傳送給 AI
|
| 68 |
+
- 溫度設定為 0.4,確保一致性回應
|
| 69 |
+
|
| 70 |
+
### 錯誤處理
|
| 71 |
+
- API 金鑰驗證和錯誤訊息
|
| 72 |
+
- 圖片處理異常捕捉
|
| 73 |
+
- 非食物檢測和適當回應
|
| 74 |
+
|
| 75 |
+
### 使用者介面
|
| 76 |
+
- 繁體中文介面
|
| 77 |
+
- 自動分析(圖片上傳時觸發)
|
| 78 |
+
- 手動分析按鈕
|
| 79 |
+
- 自訂 CSS 樣式
|
| 80 |
+
|
| 81 |
+
## 部署資訊
|
| 82 |
+
|
| 83 |
+
### HuggingFace Spaces
|
| 84 |
+
- SDK: gradio
|
| 85 |
+
- SDK 版本: 5.42.0
|
| 86 |
+
- 需要設定 GOOGLE_API_KEY 環境變數
|
| 87 |
+
- 支援自動建置和部署
|
| 88 |
+
|
| 89 |
+
### Docker
|
| 90 |
+
- 基於 Python 3.11
|
| 91 |
+
- 簡單的多階段建置流程
|
app.py
CHANGED
|
@@ -1,12 +1,17 @@
|
|
| 1 |
import os
|
| 2 |
import gradio as gr
|
| 3 |
-
|
|
|
|
| 4 |
from PIL import Image
|
| 5 |
import io
|
| 6 |
import base64
|
| 7 |
|
| 8 |
-
#
|
| 9 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 10 |
|
| 11 |
# 配置Google AI
|
| 12 |
def configure_google_ai():
|
|
@@ -14,15 +19,18 @@ def configure_google_ai():
|
|
| 14 |
api_key = os.getenv("GOOGLE_API_KEY")
|
| 15 |
if not api_key:
|
| 16 |
raise ValueError("請設定GOOGLE_API_KEY環境變數")
|
| 17 |
-
|
| 18 |
-
|
|
|
|
|
|
|
| 19 |
|
| 20 |
# 初始化模型
|
| 21 |
try:
|
| 22 |
-
|
|
|
|
| 23 |
except Exception as e:
|
| 24 |
print(f"警告:無法初始化Google AI模型 - {e}")
|
| 25 |
-
|
| 26 |
|
| 27 |
def analyze_food_calories(image):
|
| 28 |
"""
|
|
@@ -34,10 +42,16 @@ def analyze_food_calories(image):
|
|
| 34 |
Returns:
|
| 35 |
str: 分析結果
|
| 36 |
"""
|
| 37 |
-
if
|
| 38 |
return "錯誤:Google AI模型未正確初始化,請檢查API KEY設定"
|
| 39 |
|
| 40 |
try:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 41 |
# 準備提示詞
|
| 42 |
prompt = """
|
| 43 |
請分析這張圖片中的內容:
|
|
@@ -59,9 +73,34 @@ def analyze_food_calories(image):
|
|
| 59 |
如果不是食物,就直接回答「這個不是食物」。
|
| 60 |
"""
|
| 61 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 62 |
# 生成回應
|
| 63 |
-
response =
|
| 64 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 65 |
|
| 66 |
except Exception as e:
|
| 67 |
return f"分析時發生錯誤:{str(e)}"
|
|
|
|
| 1 |
import os
|
| 2 |
import gradio as gr
|
| 3 |
+
from google import genai
|
| 4 |
+
from google.genai import types
|
| 5 |
from PIL import Image
|
| 6 |
import io
|
| 7 |
import base64
|
| 8 |
|
| 9 |
+
# 載入環境變數(本機開發時需要)
|
| 10 |
+
try:
|
| 11 |
+
from dotenv import load_dotenv
|
| 12 |
+
load_dotenv()
|
| 13 |
+
except ImportError:
|
| 14 |
+
pass
|
| 15 |
|
| 16 |
# 配置Google AI
|
| 17 |
def configure_google_ai():
|
|
|
|
| 19 |
api_key = os.getenv("GOOGLE_API_KEY")
|
| 20 |
if not api_key:
|
| 21 |
raise ValueError("請設定GOOGLE_API_KEY環境變數")
|
| 22 |
+
|
| 23 |
+
# 使用新的 Gen AI 客戶端
|
| 24 |
+
client = genai.Client(api_key=api_key)
|
| 25 |
+
return client
|
| 26 |
|
| 27 |
# 初始化模型
|
| 28 |
try:
|
| 29 |
+
client = configure_google_ai()
|
| 30 |
+
model_name = "gemini-1.5-flash"
|
| 31 |
except Exception as e:
|
| 32 |
print(f"警告:無法初始化Google AI模型 - {e}")
|
| 33 |
+
client = None
|
| 34 |
|
| 35 |
def analyze_food_calories(image):
|
| 36 |
"""
|
|
|
|
| 42 |
Returns:
|
| 43 |
str: 分析結果
|
| 44 |
"""
|
| 45 |
+
if client is None:
|
| 46 |
return "錯誤:Google AI模型未正確初始化,請檢查API KEY設定"
|
| 47 |
|
| 48 |
try:
|
| 49 |
+
# 將圖片轉換為 base64
|
| 50 |
+
img_byte_arr = io.BytesIO()
|
| 51 |
+
image.save(img_byte_arr, format='PNG')
|
| 52 |
+
img_byte_arr = img_byte_arr.getvalue()
|
| 53 |
+
img_base64 = base64.b64encode(img_byte_arr).decode('utf-8')
|
| 54 |
+
|
| 55 |
# 準備提示詞
|
| 56 |
prompt = """
|
| 57 |
請分析這張圖片中的內容:
|
|
|
|
| 73 |
如果不是食物,就直接回答「這個不是食物」。
|
| 74 |
"""
|
| 75 |
|
| 76 |
+
# 建立內容,包含文字和圖片
|
| 77 |
+
contents = [
|
| 78 |
+
types.Content(
|
| 79 |
+
role="user",
|
| 80 |
+
parts=[
|
| 81 |
+
types.Part.from_text(prompt),
|
| 82 |
+
types.Part.from_bytes(
|
| 83 |
+
data=img_byte_arr,
|
| 84 |
+
mime_type="image/png"
|
| 85 |
+
)
|
| 86 |
+
]
|
| 87 |
+
)
|
| 88 |
+
]
|
| 89 |
+
|
| 90 |
# 生成回應
|
| 91 |
+
response = client.models.generate_content(
|
| 92 |
+
model=model_name,
|
| 93 |
+
contents=contents,
|
| 94 |
+
config=types.GenerateContentConfig(
|
| 95 |
+
temperature=0.4,
|
| 96 |
+
max_output_tokens=1024,
|
| 97 |
+
)
|
| 98 |
+
)
|
| 99 |
+
|
| 100 |
+
if response.text:
|
| 101 |
+
return response.text
|
| 102 |
+
else:
|
| 103 |
+
return "無法生成回應"
|
| 104 |
|
| 105 |
except Exception as e:
|
| 106 |
return f"分析時發生錯誤:{str(e)}"
|
requirements.txt
CHANGED
|
@@ -1,3 +1,3 @@
|
|
| 1 |
gradio==5.42.0
|
| 2 |
-
google-
|
| 3 |
pillow==11.3.0
|
|
|
|
| 1 |
gradio==5.42.0
|
| 2 |
+
google-genai
|
| 3 |
pillow==11.3.0
|