iflow-bot QQ 渠道图片分析功能优化分享

续上一篇帖子在调试 iflow-bot 时,想看看给qq机器人发图片,她能不能看懂,结果没有无响应,好像没有这个功能(不知道作者做了这个功能没有 我不知道 不知者无罪好嘛),然后我用iflow帮我调试了一下午直到发布这篇帖子之前搞定了,添加了图片分析功能并进行了优化。

环境信息

  • 系统:Termux on Android (Linux 5.10.43)
  • Python:3.13.12
  • iFlow CLI:0.5.17
  • iflow-bot:0.3.8
  • Bot 模型:kimi-k2.5 (thinking mode enabled)
  • QQ SDK:qq-botpy

背景

iflow-bot 的 QQ 渠道原本不支持图片分析,用户发送图片后 AI 无法识别内容。

关于 image_read

image_read 是 iFlow CLI 内置的视觉语言模型工具,可以读取图片文件并生成详细描述。本次优化让 iflow-bot 的 QQ 渠道能够利用这个工具:

  • AI 收到图片路径后,会自动调用 image_read 工具分析图片
  • 无需额外配置,只要是 iFlow CLI 支持的模型都可以使用

实现思路

图片处理流程:
用户发图 → QQ SDK 回调 → 检测 attachments → 下载图片到本地 → 注入路径到消息 → AI 用 image_read 分析 → 返回自然语言描述

两阶段优化:

  1. 第一阶段:添加图片下载 + 预分析

    • 新增 _download_image() 函数下载图片到 ~/.iflow-bot/workspace/images/
    • 新增 _analyze_image_with_tool() 函数预先分析图片
    • 问题:两次分析导致响应时间长

    第二阶段(最终优化):简化流程

    • 删除预分析函数,让 AI 直接调用 image_read 工具
    • 优化提示词:请用简洁自然的语言描述图片内容,1-2句话概括即可,输出更自然的聊天风格

效果对比

  • 分析步骤:从 2 步(预分析+AI分析)优化到 1 步(AI直接分析)
  • 响应时间:减少约 30-50%
  • 描述风格:从技术化详细改为自然聊天风格

修改的源码

修改文件:
/data/data/com.termux/files/usr/lib/python3.13/site-packages/iflow_bot/channels/qq.py

修改后的代码片段:

“”"QQ channel implementation using qq-botpy SDK.

使用 qq-botpy SDK 通过 WebSocket 连接 QQ 频道机器人。
支持 C2C 私聊消息和 QQ 群消息。
“”"

import asyncio
import logging
import aiohttp
from collections import deque
from pathlib import Path
from typing import Any, Optional, TYPE_CHECKING

from iflow_bot.bus.events import OutboundMessage
from iflow_bot.bus.queue import MessageBus
from iflow_bot.channels.base import BaseChannel
from iflow_bot.channels.manager import register_channel
from iflow_bot.config.schema import QQConfig

try:
import botpy
from botpy.message import C2CMessage, GroupMessage
QQ_AVAILABLE = True
except ImportError:
QQ_AVAILABLE = False
botpy = None # type: ignore
C2CMessage = None # type: ignore
GroupMessage = None # type: ignore

if TYPE_CHECKING:
from botpy.message import C2CMessage, GroupMessage

logger = logging.getLogger(name)

图片下载和分析函数

async def _download_image(url: str, save_dir: Path) → Optional[str]:
“”"下载图片到本地

   Args:
       url: 图片 URL
       save_dir: 保存目录

   Returns:
       本地文件路径,失败返回 None
   """
   try:
       save_dir.mkdir(parents=True, exist_ok=True)

       # 生成文件名(使用时间戳避免冲突)
       import time
       filename = f"image_{int(time.time())}.png"
       filepath = save_dir / filename

       # 下载图片
       async with aiohttp.ClientSession() as session:
           async with session.get(url, timeout=aiohttp.ClientTimeout(total=30)) as response:
               if response.status == 200:
                   with open(filepath, 'wb') as f:
                       async for chunk in response.content.iter_chunked(8192):
                           f.write(chunk)
                   logger.info(f"[QQ] Image downloaded: {filepath}")
                   return str(filepath)
               else:
                   logger.warning(f"[QQ] Failed to download image: HTTP {response.status}")
                   return None
   except Exception as e:
       logger.error(f"[QQ] Error downloading image: {e}")
       return None

… 后续 QQChannel 类中的 _on_c2c_message 和 _on_group_message 方法添加了图片处理逻辑 …

   async def _on_c2c_message(self, data: "C2CMessage") -> None:
       """处理来自 QQ 的 C2C 私聊消息。"""
       try:
           # ... 消息去重、用户信息提取 ...

           # 提取消息内容
           content = (data.content or "").strip()

           # 提取图片信息
           media = []
           if hasattr(data, 'attachments') and data.attachments:
               for attachment in data.attachments:
                   ct = getattr(attachment, 'content_type', '')
                   if ct and ct.startswith('image/'):
                       url = getattr(attachment, 'url', '')
                       if url:
                           media.append(url)

           # 下载图片到本地并添加分析信息
           if media:
               image_path = await _download_image(
                   media[0],
                   Path.home() / ".iflow-bot" / "workspace" / "images"
               )
               if image_path:
                   # 直接添加图片路径到消息,AI 会自动用 image_read 分析
                   content += f"\n\n[用户发送了图片,路径: {image_path}。请用简洁自然的语言描述图片内容,1-2句话概括即可,就像朋友聊天一样。]"

           if not content:
               content = "[发送了图片]"

           # ... 后续处理 ...

核心改动点:

  1. 新增 _download_image() 函数(约 30 行)
  2. 在 _on_c2c_message 和 _on_group_message 中添加图片检测和下载逻辑
  3. 优化提示词,引导 AI 用自然语言描述图片

图片保存路径

下载的图片保存在:
~/.iflow-bot/workspace/images/

备份文件

修改时保留了备份:


欢迎交流改进~

你可以在原贴更新的, 或者加下原贴链接.

还没体验你这个项目 :+1:

:+1: :+1: :+1: 。。QQ渠道确实没做图片。。最近很忙,没咋迭代。。。复用你的了。。。直接更新到 0.3.9 即可支持。。。

2 个赞

实战分享很有价值,排坑过程太赞了!

这样啊知道了 我倒是在GitHub这个项目发了issue,里面有贴源码文件,这里还不支持文件

good

古德古德嘻嘻

强啊