Skip to content

Latest commit

 

History

History
558 lines (418 loc) · 15 KB

File metadata and controls

558 lines (418 loc) · 15 KB

批量图片处理功能说明

功能概述

饮食分析机器人现在支持批量处理多张图片,可以一次性发送多张照片,每张照片会被当作独立的一餐进行分析,并支持批量导入到多维表格。

功能特性

1. 智能批量识别

  • 检测到多张图片时自动进入批量处理模式
  • 每张图片独立分析,互不干扰
  • 所有文字内容会附加到每张图片的分析中

2. 独立消息显示

  • 每张图片发送独立的分析消息(不会被覆盖)
  • 每条消息包含完整的 AI 分析和营养建议
  • 每条消息都有独立的"导入到多维表格"按钮
  • 可以单独导入某一条记录,也可以批量导入全部

3. 独立分析每张图片

  • 每张图片作为独立的一餐记录
  • 提取每张图片的时间水印(如果有)
  • 分别识别日期、时间、餐次、营养成分等

4. 批量汇总展示

  • 所有图片分析完成后,发送最终汇总消息
  • 显示所有记录的明细
  • 计算总热量、总蛋白质、总碳水、总脂肪
  • 显示平均饮食评分

5. 灵活的导入方式

  • 单独导入:每条分析消息都可以单独点击导入
  • 批量导入:汇总消息提供一键批量导入所有记录
  • 每条记录保存各自的图片
  • 显示导入进度和结果统计

使用方法

批量上传多张照片

步骤

  1. 在飞书聊天中,一次性选择多张食物照片
  2. (可选)添加文字说明,会附加到每张图片
  3. 发送消息
  4. 机器人会逐个分析每张图片,每张图片发送一条独立的分析消息
  5. 每条分析消息都包含完整的营养分析和单独导入按钮
  6. 所有图片分析完成后,发送最终汇总消息
  7. 可以选择:
    • 单独导入某条记录(点击该分析消息的按钮)
    • 批量导入所有记录(点击汇总消息的批量导入按钮)

示例场景

场景 1:补录一天的饮食

用户操作

[上传3张照片]
- 早餐:豆浆油条(图片水印:2026-01-20 07:30)
- 午餐:麻辣香锅(图片水印:2026-01-20 12:30)
- 晚餐:烤鱼(图片水印:2026-01-20 19:00)

附加文字:"1月20日的饮食"

机器人响应 - 消息1(第1张图片的完整分析)

**营养分析** 🥛

从图片左下角的时间水印可以看到,这是 **2026年1月20日 07:30** 拍摄的照片!

豆浆油条是经典的中式早餐组合,让我帮你分析一下营养成分:

• 豆浆(1杯):约 120 kcal
• 油条(2根):约 230 kcal

总热量约:350 kcal

**营养建议** 💡

这是一顿比较传统的早餐,蛋白质和碳水都有...

---

📊 数据摘要

• 餐次:早餐
• 主餐:豆浆油条
• 热量:350 kcal
• 蛋白质:15 g
• 碳水:45 g
• 脂肪:12 g
• 评分:7/10

[按钮: 📥 导入到多维表格]

机器人响应 - 消息2(第2张图片的完整分析)

**营养分析** 🍜

从图片左下角的时间水印可以看到,这是 **2026年1月20日 12:30** 拍摄的照片!

哇!麻辣香锅看起来超级诱人呀!让我帮你分析一下这顿午餐:

• 麻辣香锅(肉类+蔬菜):约 1200 kcal

**营养建议** 💡

这是一顿热量较高的餐食,但营养比较均衡...

---

📊 数据摘要

• 餐次:午餐
• 主餐:麻辣香锅
• 热量:1200 kcal
• 蛋白质:45 g
• 碳水:60 g
• 脂肪:55 g
• 评分:7/10

[按钮: 📥 导入到多维表格]

机器人响应 - 消息3(第3张图片的完整分析)

**营养分析** 🐟

从图片左下角的时间水印可以看到,这是 **2026年1月20日 19:00** 拍摄的照片!

烤鱼是一道营养丰富的菜肴...

---

📊 数据摘要

• 餐次:晚餐
• 主餐:烤鱼
• 热量:800 kcal
• 蛋白质:50 g
• 碳水:35 g
• 脂肪:28 g
• 评分:8/10

[按钮: 📥 导入到多维表格]

机器人响应 - 消息4(最终汇总)

📊 批量分析完成

成功分析 3 条饮食记录!

📝 记录明细

1. 2026-01-20 07:30 - 早餐:豆浆油条 (350 kcal)
2. 2026-01-20 12:30 - 午餐:麻辣香锅 (1200 kcal)
3. 2026-01-20 19:00 - 晚餐:烤鱼 (800 kcal)

🔢 营养总计

• 总热量:2350 kcal
• 总蛋白质:110 g
• 总碳水:140 g
• 总脂肪:95 g
• 平均评分:7.3/10

[按钮: 📥 批量导入 3 条记录到多维表格]

操作选择

  • 选项1:点击消息1、2、3各自的按钮,单独导入每条记录
  • 选项2:点击消息4(汇总)的批量导入按钮,一次性导入全部3条记录

场景 2:快速记录多餐

用户操作

[上传5张照片]
- 周一早餐
- 周一午餐
- 周一晚餐
- 周二早餐
- 周二午餐

机器人响应

📊 批量分析完成

成功分析 5 条饮食记录!

📝 记录明细

1. 2026-01-20 07:45 - 早餐:鸡蛋三明治 (420 kcal)
2. 2026-01-20 12:15 - 午餐:宫保鸡丁 (950 kcal)
3. 2026-01-20 19:30 - 晚餐:水煮鱼 (1100 kcal)
4. 2026-01-21 08:00 - 早餐:牛奶麦片 (380 kcal)
5. 2026-01-21 12:45 - 午餐:烧鹅饭 (880 kcal)

🔢 营养总计

• 总热量:3730 kcal
• 总蛋白质:165 g
• 总碳水:380 g
• 总脂肪:145 g
• 平均评分:7.0/10

[按钮: 📥 批量导入 5 条记录到多维表格]

技术实现

1. 消息路由逻辑

bots/food_analyzer/bot.pyprocess_messages() 方法中:

def process_messages(self, chat_id: str, parts: List[MessagePart], status_msg_id: Optional[str]) -> str:
    # 分离图片和文字
    images = [part for part in parts if part.kind == "image" and part.image_key]
    texts = [part for part in parts if part.kind == "text" and part.text]
    combined_text = " ".join([t.text for t in texts]) if texts else ""

    # 根据图片数量路由到不同处理器
    if not images or len(images) == 1:
        return self._process_single_meal(chat_id, parts, status_msg_id, combined_text)
    else:
        return self._process_multiple_meals(chat_id, images, combined_text, status_msg_id)

2. 批量处理流程

def _process_multiple_meals(self, chat_id, images, combined_text, status_msg_id) -> str:
    all_meal_data = []

    # 逐个处理每张图片
    for idx, image_part in enumerate(images, start=1):
        # 构建单张图片的消息(图片 + 文字)
        single_parts = [image_part]
        if combined_text:
            single_parts.append(MessagePart(kind="text", text=combined_text))

        # 调用 AI 分析
        messages = self._build_ai_messages(single_parts)
        result = self._call_ai_streaming(chat_id, messages, status_msg_id)

        # 提取并保存数据
        meal_data = self._extract_json_data(result)
        if meal_data:
            meal_data["user_comment"] = combined_text
            meal_data["image_key"] = image_part.image_key
            meal_data["image_message_id"] = image_part.message_id
            all_meal_data.append(meal_data)

    # 生成汇总和交互式卡片
    summary_text = self._build_batch_summary(all_meal_data)
    card_content = self._build_batch_interactive_card(summary_text, all_meal_data)
    return summary_text

3. 批量保存逻辑

main.pyhandle_card_action() 方法中:

def async_save():
    # 检查是否为批量导入
    is_batch = isinstance(meal_data, dict) and meal_data.get("batch") == True

    if is_batch:
        # 批量导入模式
        meals = meal_data.get("meals", [])
        success_count = 0
        fail_count = 0

        for idx, single_meal in enumerate(meals, start=1):
            if self.bot._save_to_bitable(single_meal):
                success_count += 1
            else:
                fail_count += 1

        # 发送批量结果通知
        result_msg = f"✅ **批量导入成功!**\n\n已成功保存 {success_count} 条饮食记录到多维表格"

4. 数据结构

单条记录卡片按钮

{
  "value": {
    "date": "2026-01-20",
    "time": "12:30",
    "meal_type": "午餐",
    ...
  }
}

批量记录卡片按钮

{
  "value": {
    "batch": true,
    "meals": [
      {"date": "2026-01-20", "time": "07:30", ...},
      {"date": "2026-01-20", "time": "12:30", ...},
      {"date": "2026-01-20", "time": "19:00", ...}
    ]
  }
}

批量模式 vs 单图模式

特性 单图模式 批量模式
触发条件 0或1张图片 2张及以上图片
分析方式 一次性分析 逐个独立分析
结果展示 详细分析+数据摘要 批量汇总+营养总计
导入按钮 "📥 导入到多维表格" "📥 批量导入 N 条记录到多维表格"
保存方式 单条记录保存 循环保存多条记录
图片保存 保存该图片 每条记录保存各自的图片

性能和限制

性能考虑

  • 每张图片需要独立调用 AI 进行分析
  • AI 调用为串行处理(逐个分析,不是并行)
  • 处理时间 = 单张图片处理时间 × 图片数量
  • 建议一次不超过 10 张图片

限制说明

  • 飞书消息中可能对图片数量有限制
  • 过多图片可能导致处理时间较长
  • 批量保存失败时会显示部分成功的结果

状态更新

批量处理时,状态消息会实时更新:

🔍 批量分析模式

检测到 3 张图片,正在逐个分析...

↓

🔍 正在分析第 1/3 张图片...

识别食物中...

↓

📝 正在分析中...

[第1张的分析内容]
正在生成中...

↓

🔍 正在分析第 2/3 张图片...

↓

...

↓

📊 批量分析完成

[汇总结果]

与其他功能的集成

日期时间识别

  • 批量模式下,每张图片的日期和时间独立提取
  • 优先使用各自图片的时间水印
  • 如果用户添加了文字说明(如"1月20日的饮食"),会应用到所有图片

文字附言

  • 批量模式下,用户发送的文字会附加到每条记录的"附言"字段
  • 所有记录共享相同的附言内容

图片保存

  • 每条记录保存各自对应的图片
  • 图片上传到飞书云存储后获得 file_token
  • 多维表格的"图片"字段保存对应的 file_token

错误处理

部分分析失败

  • 如果某张图片分析失败,不影响其他图片
  • 汇总中只包含成功分析的记录
  • 日志中会记录失败原因

部分导入失败

  • 批量导入时,每条记录独立保存
  • 显示成功和失败的数量
  • 例如:"成功:2 条,失败:1 条"

全部失败

  • 如果所有图片都无法分析:显示"批量分析失败"
  • 如果批量导入全部失败:显示具体错误信息

常见问题

Q1:批量模式和单图模式有什么区别?

A

  • 单图模式(0或1张图片):显示详细的营养分析和建议
  • 批量模式(2张及以上):显示汇总数据和记录明细,更注重整体统计

Q2:批量上传时,文字说明如何处理?

A

  • 用户发送的所有文字内容会合并
  • 合并后的文字会附加到每一条记录的"附言"字段
  • 例如:文字"今天吃得不错"会保存到所有3条记录中

Q3:如果图片有时间水印,批量模式下如何识别?

A

  • 每张图片的时间水印独立提取
  • 第1张图片:使用第1张的水印时间
  • 第2张图片:使用第2张的水印时间
  • 各自保存到对应的日期和时间

Q4:批量导入时,如果部分记录失败怎么办?

A

  • 系统会继续保存其他记录
  • 最后显示成功和失败的统计
  • 可以查看日志了解失败原因
  • 可以手动重新导入失败的记录

Q5:最多可以一次上传多少张图片?

A

  • 技术上没有硬性限制
  • 但考虑到处理时间,建议一次不超过 10 张
  • 每张图片需要调用 AI 分析,处理时间会随图片数量增加

Q6:批量模式下能看到详细的营养建议吗?

A

  • 批量模式更注重汇总统计,不会显示每条记录的详细分析
  • 如果需要详细分析,可以单独发送每张图片
  • 或者在批量导入后,在多维表格中查看各条记录的详细数据

Q7:批量导入会保存图片吗?

A

  • 会的!每条记录都会保存各自对应的图片
  • 图片会上传到飞书云存储
  • 多维表格的"图片"字段会显示对应的食物照片

技术细节

批量处理流程

用户发送多张图片
    ↓
process_messages() 检测到多张图片
    ↓
调用 _process_multiple_meals()
    ↓
循环处理每张图片:
  - 更新状态:"正在分析第 N/M 张图片..."
  - 构建消息:图片 + 文字
  - 调用 AI 分析
  - 提取 JSON 数据
  - 添加图片信息和附言
  - 保存到 all_meal_data 数组
    ↓
调用 _build_batch_summary() 生成汇总
    ↓
调用 _build_batch_interactive_card() 生成交互卡片
    ↓
更新消息显示汇总和按钮
    ↓
用户点击批量导入按钮
    ↓
handle_card_action() 检测到 batch=true
    ↓
循环保存每条记录:
  - 调用 _save_to_bitable(single_meal)
  - 统计成功和失败数量
    ↓
发送批量导入结果通知

关键代码位置

  • 消息路由bots/food_analyzer/bot.py:42-72 (process_messages)
  • 批量处理bots/food_analyzer/bot.py:129-236 (_process_multiple_meals)
  • 批量汇总bots/food_analyzer/bot.py:238-281 (_build_batch_summary)
  • 批量卡片bots/food_analyzer/bot.py:283-324 (_build_batch_interactive_card)
  • 批量保存main.py:165-231 (handle_card_actionasync_save 内部逻辑)

日志输出

批量处理时的日志示例:

[饮食分析助手] 开始分析饮食,消息片段数: 5
[饮食分析助手] 检测到 3 张图片,2 条文字
[饮食分析助手] 批量处理模式:3 张图片
[饮食分析助手] 处理第 1/3 张图片
[饮食分析助手] 处理第 2/3 张图片
[饮食分析助手] 处理第 3/张图片
[饮食分析助手] 批量分析完成,成功: 3/3
[饮食分析助手] 批量导入模式,共 3 条记录
[饮食分析助手] 保存第 1/3 条记录...
[饮食分析助手] 保存第 2/3 条记录...
[饮食分析助手] 保存第 3/3 条记录...
[饮食分析助手] 批量导入完成: 成功 3/3

配置要求

批量处理功能不需要额外配置,使用现有的配置即可:

# config/food_analyzer/config.yaml

bitable:
  enabled: true
  app_token: "你的多维表格 app_token"
  table_id: "你的数据表 table_id"
  fields:
    date: "日期"          # 必须配置
    time: "时间"          # 必须配置
    image: "图片"         # 必须配置(附件字段)
    # ... 其他字段

总结

批量图片处理功能让你可以:

  • ✅ 一次性发送多张食物照片
  • ✅ 每张照片独立分析为一餐记录
  • ✅ 自动提取各自的日期和时间
  • ✅ 查看所有记录的汇总统计
  • ✅ 一键批量导入到多维表格
  • ✅ 每条记录保存各自的图片
  • ✅ 高效补录多天的饮食数据

特别适合:

  • 补录过去几天的饮食
  • 快速记录一整天的饮食
  • 整理相册中的食物照片