Agno开发教程系列(八):使用多模态大模型

87 阅读34分钟

本教程是Agno开发教程系列的第八篇,深入讲解如何在Agno框架中使用多模态大语言模型,重点介绍qwen-vl-plus等先进模型的应用实践。

目录


第一部分:概念讲解

1.1 什么是多模态大模型

多模态大语言模型(Multimodal Large Language Models,简称MLLMs) 是能够同时处理和理解多种数据类型的AI模型。与传统的单模态模型(仅处理文本或图像)不同,多模态模型可以:

核心能力特点

  • 跨模态理解:同时处理文本、图像、音频、视频等多种输入
  • 模态融合:将不同模态的信息进行整合推理
  • 多模态生成:输出不仅限于文本,还可以生成图像、音频等
  • 统一表征:在统一的语义空间中理解不同模态的信息

技术优势

  1. 更接近人类感知:人类是通过视觉、听觉、触觉等多种感官理解世界的,多模态模型更贴近这种认知方式
  2. 处理复杂场景:能够处理现实世界中包含多种信息类型的复杂任务
  3. 丰富交互体验:提供更自然、更智能的人机交互方式
  4. 知识增强:不同模态的信息相互补充,提高理解准确度

Qwen-VL-Plus模型介绍

Qwen-VL-Plus 是阿里云通义千问推出的强大视觉语言模型,具有以下特点:

  • 卓越的图像理解能力:支持图像描述、OCR、物体识别等多种视觉任务
  • 多语言支持:原生支持中文和英文,OCR能力覆盖32种语言
  • 高分辨率处理:支持最高448分辨率输入,细节识别更精准
  • 开放域定位:可以识别和标注图像中的特定物体及其边界框
  • 文档理解:强大的文档解析能力,支持表格、公式、图表等复杂内容

1.2 多模态大模型的应用场景

多模态大模型在各行各业都有广泛的应用,以下是一些典型场景:

1. 图像理解与分析

应用示例:

  • 图像描述生成:为图片自动生成详细的文字描述
  • OCR文字识别:从图片、文档、票据中提取文字信息
  • 物体识别与检测:识别图像中的物体、人物、场景
  • 图像分类与标注:自动为图片打标签、分类

实际应用:

  • 电商平台的商品图片分析
  • 智能相册的自动整理和搜索
  • 身份证、票据的自动识别
  • 医疗影像的辅助诊断

2. 视频内容分析

应用示例:

  • 视频摘要生成:自动提取视频的核心内容
  • 视频问答:基于视频内容回答问题
  • 场景分析:识别视频中的场景变化和关键帧
  • 字幕生成:自动生成视频字幕

实际应用:

  • 视频监控系统的智能分析
  • 在线教育平台的视频内容索引
  • 短视频平台的内容审核
  • 影视制作的智能剪辑

3. 文档智能处理

应用示例:

  • 文档解析:提取PDF、扫描件中的文字和结构
  • 表格识别:识别并提取表格数据
  • 公式识别:识别数学公式和特殊符号
  • 多语言识别:支持多种语言混排文档

实际应用:

  • 企业文档管理系统
  • 财务票据自动化处理
  • 学术论文的信息提取
  • 合同审核和比对

4. 智能客服与助手

应用示例:

  • 图片问题诊断:通过用户上传的错误截图诊断问题
  • 产品咨询:基于产品图片回答用户问题
  • 教育辅导:识别题目图片并提供解答
  • 医疗咨询:分析症状图片提供初步建议

实际应用:

  • 电商平台的智能客服
  • 在线教育的AI辅导老师
  • 医疗健康咨询平台
  • 技术支持系统

5. 内容创作与营销

应用示例:

  • 图文生成:基于图片生成营销文案
  • 社交媒体内容:自动创作社交平台帖子
  • 产品描述:为商品图片生成吸引人的描述
  • 创意故事:根据图片创作故事

实际应用:

  • 自媒体内容创作
  • 电商产品上架
  • 广告创意设计
  • 品牌营销活动

1.3 Agno中的多模态支持

Agno框架为多模态AI应用提供了完善的支持,让开发者能够轻松构建强大的多模态Agent。

支持的模态类型

Agno原生支持以下多模态输入和输出:

模态类型输入支持输出支持主要应用
文本对话、问答、内容生成
图像图像理解、图像生成
音频语音识别、语音合成
视频视频理解、场景分析
文件文档解析、数据提取

支持的模型提供商

Agno与多个主流模型提供商集成,提供灵活的选择:

1. DashScope(阿里云通义千问)

  • ✅ 图像输入支持
  • 推荐模型:qwen-vl-plus, qwen-vl-ocr
  • 特点:中文场景优化,OCR能力强

2. Google Gemini

  • ✅ 图像、音频、视频、文件上传全支持
  • 推荐模型:gemini-2.0-flash-exp
  • 特点:多模态支持最全面,视频理解能力强

3. OpenAI

  • ✅ 图像、音频、视频输入支持
  • ✅ 图像生成(DALL-E)
  • 推荐模型:gpt-4o, gpt-4o-mini
  • 特点:综合能力强,生态完善

核心Media类

Agno提供了专门的Media类来处理多模态输入:

1. Image类 - 处理图像输入

from agno.media import Image

# 方式1:URL
Image(url="https://example.com/image.jpg")

# 方式2:本地文件
Image(filepath="/path/to/image.jpg")

# 方式3:字节数据
Image(content=image_bytes)

2. Video类 - 处理视频输入

from agno.media import Video

# 方式1:本地文件
Video(filepath="/path/to/video.mp4")

# 方式2:URL
Video(url="https://example.com/video.mp4")

3. Audio类 - 处理音频输入

from agno.media import Audio

# 音频内容和格式
Audio(content=audio_bytes, format="wav")

多模态Agent的特点

Agno的多模态Agent具有以下优势:

  1. 统一的API接口:无论处理什么模态,都使用一致的Agent接口
  2. 模型无关:轻松切换不同的模型提供商
  3. 流式支持:支持流式输出,提升用户体验
  4. 工具集成:可以与各种工具结合,扩展能力
  5. 内存管理:支持对话历史和上下文管理
  6. 高性能:Agent实例化速度快,内存占用小

第二部分:代码示例

2.1 多模态模型配置

基础配置 - 使用qwen-vl-plus

from agno.agent import Agent
from agno.models.dashscope import DashScope
from agno.media import Image

# 配置qwen-vl-plus多模态模型
agent = Agent(
    name="多模态助手",
    model=DashScope(
        id="qwen-vl-plus",  # 推荐使用qwen-vl-plus模型
        # qwen-vl-plus在图像理解、OCR、物体识别方面表现优异
    ),
    description="一个能够处理图像、视频和文本的多模态AI助手",
    markdown=True,  # 启用Markdown格式输出
)

# 测试基础配置
agent.print_response(
    "你好,请介绍一下你的能力",
    stream=True
)

高级配置 - 多模型支持

from agno.agent import Agent
from agno.models.dashscope import DashScope
from agno.models.google import Gemini
from agno.models.openai import OpenAIChat

# 方案1: 使用DashScope qwen-vl-plus (推荐用于中文场景)
agent_qwen = Agent(
    name="通义多模态助手",
    model=DashScope(id="qwen-vl-plus"),
    description="基于阿里云通义千问的多模态助手,擅长中文场景",
    markdown=True,
)

# 方案2: 使用Gemini (支持视频、音频、文件上传)
agent_gemini = Agent(
    name="Gemini多模态助手",
    model=Gemini(id="gemini-2.0-flash-exp"),
    description="基于Google Gemini的多模态助手,支持多种输入格式",
    markdown=True,
)

# 方案3: 使用OpenAI GPT-4o (支持图像、音频、视频)
agent_gpt = Agent(
    name="GPT多模态助手",
    model=OpenAIChat(id="gpt-4o"),
    description="基于OpenAI GPT-4o的多模态助手",
    markdown=True,
)

完整配置参数详解

import os

from agno.agent import Agent
from agno.media import Image
from agno.models.openai import OpenAILike
from dotenv import load_dotenv

load_dotenv()
agent = Agent(
    # 基础配置
    name="智能图像分析助手",
    model=OpenAILike(
        id="qwen3-vl-plus",
        base_url="https://dashscope.aliyuncs.com/compatible-mode/v1",
        api_key=os.getenv("QWEN_API_KEY"),
    ),

    # 角色定义
    description="专业的图像分析AI助手,能够理解和分析各种图像内容",

    # 指令设置
    instructions=[
        "你是一个专业的图像分析专家",
        "当用户提供图像时,请仔细观察图像的所有细节",
        "提供准确、详细的分析结果",
        "对于OCR任务,请确保文字识别的准确性",
        "用清晰的语言描述图像内容"
    ],

    # 输出格式
    markdown=True,  # 启用Markdown格式化输出

    # 显示配置
    debug_mode=False,  # 调试模式
)

agent.print_response("请分析一张图片,并给出其内容", images=[Image(filepath="YOU_IMG_PATH")])

2.2 图像理解示例

图像描述 - 多种输入方式

import os

from agno.agent import Agent
from agno.media import Image
from pathlib import Path

from agno.models.openai import OpenAILike
from dotenv import load_dotenv

load_dotenv()
# 创建图像描述Agent
image_agent = Agent(
    name="图像描述助手",
    model=OpenAILike(
        id="qwen3-vl-plus",
        base_url="https://dashscope.aliyuncs.com/compatible-mode/v1",
        api_key=os.getenv("QWEN_API_KEY"),
    ),
    description="专注于图像内容描述和分析",
    instructions=[
        "详细描述图像中的主要元素",
        "注意颜色、构图、场景等细节",
        "用生动的语言表达视觉内容"
    ],
    markdown=True,
)

# 方式1:使用图像URL
image_url = "https://example.com/sample.jpg"
print("图像描述结果:")
image_agent.print_response(
    input="请详细描述这张图片的内容",
    images=[Image(url=image_url)],
)

# 方式2:使用本地图像文件
image_path = Path("./images/sample.jpg")
if image_path.exists():
    image_agent.print_response(
        input="分析这张图片,包括主题、风格、色彩和情感",
        images=[Image(filepath=str(image_path))],
    )

# 方式3:使用图像bytes数据
import requests
image_url = "https://example.com/image.jpg"
response_http = requests.get(image_url)
if response_http.status_code == 200:
    image_bytes = response_http.content
    image_agent.print_response(
        input="这张图片中有什么?",
        images=[Image(content=image_bytes)],
    )

OCR文字识别

import os

from agno.agent import Agent
from agno.media import Image
from agno.models.openai import OpenAILike
from dotenv import load_dotenv

load_dotenv()
# 创建OCR专用Agent
ocr_agent = Agent(
    name="OCR文字识别助手",
    model=OpenAILike(
        id="qwen3-vl-plus",
        base_url="https://dashscope.aliyuncs.com/compatible-mode/v1",
        api_key=os.getenv("QWEN_API_KEY"),
    ),
    description="专业的文字识别和提取工具",
    instructions=[
        "准确识别图像中的所有文字内容",
        "保持原文的格式和结构",
        "对于表格,保持表格结构",
        "对于公式,尽可能还原公式形式",
        "标注不清晰或不确定的文字"
    ],
    markdown=True,
)

# OCR示例 - 识别文档图像
document_url = "https://example.com/document.png"

response = ocr_agent.run(
    input="请识别并提取这张图片中的所有文字内容,保持原有格式",
    images=[Image(url=document_url)],
)

print("OCR识别结果:")
print(response.content)

# 保存识别结果
with open("ocr_result.txt", "w", encoding="utf-8") as f:
    f.write(response.content)

多语言OCR识别

from agno.agent import Agent
from agno.models.openai import OpenAILike
from agno.media import Image

# 多语言OCR Agent
multilingual_ocr_agent = Agent(
    name="多语言OCR助手",
    model=OpenAILike(
        id="qwen3-vl-plus",
        base_url="https://dashscope.aliyuncs.com/compatible-mode/v1",
        api_key=os.getenv("QWEN_API_KEY"),
    ),
    description="支持多语言的文字识别系统",
    instructions=[
        "识别图像中的所有语言文字",
        "区分不同语言的内容",
        "保持多语言混排的原有格式",
        "对特殊符号和公式进行准确识别"
    ],
    markdown=True,
)

# 识别包含中英文的文档
bilingual_doc_url = "https://example.com/bilingual_document.jpg"

response = multilingual_ocr_agent.run(
    input="""请识别这张图片中的文字内容,要求:
    1. 识别所有语言的文字
    2. 保持原有段落结构
    3. 标注不同语言的部分
    4. 提取关键信息""",
    images=[Image(url=bilingual_doc_url)],
)

print(response.content)

物体识别和定位

from agno.agent import Agent
from agno.models.dashscope import DashScope
from agno.media import Image
from dotenv import load_dotenv

load_dotenv()
# 创建物体识别Agent
object_detection_agent = Agent(
    name="物体识别专家",
    model=DashScope(id="qwen3-vl-plus",
                    base_url="https://dashscope.aliyuncs.com/compatible-mode/v1"),
    description="专业的物体检测和识别系统",
    instructions=[
        "识别图像中的所有主要物体",
        "描述物体的位置、大小和关系",
        "统计物体数量",
        "分析物体的特征和属性",
        "描述场景的整体布局"
    ],
    markdown=True,
)

# 物体识别示例

print("物体识别结果:")
object_detection_agent.print_response(
    input="""请分析这张图片:
    1. 列出所有可识别的物体
    2. 描述每个物体的位置和特征
    3. 统计主要物体的数量
    4. 分析物体之间的空间关系""",
    images=[Image(filepath="example.jpeg")],
)

批量图像处理

from agno.agent import Agent
from agno.models.dashscope import DashScope
from agno.media import Image
from typing import List
import json

from dotenv import load_dotenv

load_dotenv()
# 创建批量处理Agent
batch_agent = Agent(
    name="批量图像处理器",
    model=DashScope(id="qwen3-vl-plus", base_url="https://dashscope.aliyuncs.com/compatible-mode/v1"),
    markdown=True,
)


def process_images_batch(image_urls: List[str], task: str) -> List[dict]:
    """批量处理多张图像"""
    results = []

    for idx, url in enumerate(image_urls):
        print(f"处理第 {idx + 1}/{len(image_urls)} 张图像...")

        try:
            response = batch_agent.run(
                message=task,
                images=[Image(url=url)],
            )

            results.append({
                "index": idx + 1,
                "url": url,
                "result": response.content,
                "status": "success"
            })
        except Exception as e:
            results.append({
                "index": idx + 1,
                "url": url,
                "error": str(e),
                "status": "failed"
            })

    return results


# 使用示例
image_list = [
    "https://example.com/image1.jpg",
    "https://example.com/image2.jpg",
    "https://example.com/image3.jpg",
]

# 批量执行图像描述任务
results = process_images_batch(
    image_urls=image_list,
    task="简要描述这张图片的主要内容(50字以内)"
)

# 保存结果
with open("batch_results.json", "w", encoding="utf-8") as f:
    json.dump(results, f, ensure_ascii=False, indent=2)

print(f"批量处理完成,共处理 {len(results)} 张图像")

2.3 视频分析示例

基础视频理解

from agno.agent import Agent
from agno.models.google import Gemini
from agno.media import Video
from pathlib import Path

# 创建视频分析Agent(使用Gemini,因为它对视频支持更好)
video_agent = Agent(
    name="视频分析专家",
    model=Gemini(id="gemini-2.0-flash-exp"),
    description="专业的视频内容分析系统",
    instructions=[
        "仔细观看整个视频内容",
        "分析视频的主题和关键信息",
        "描述重要的场景和事件",
        "总结视频的核心内容",
        "提取视频中的文字信息(如有)"
    ],
    markdown=True,
)

# 使用本地视频文件
video_path = Path("./videos/sample.mp4")

if video_path.exists():
    response = video_agent.run(
        input="请分析这个视频的内容,包括主题、关键场景和主要信息",
        videos=[Video(filepath=video_path)],
    )
    print("视频分析结果:")
    print(response.content)
else:
    print(f"视频文件不存在:{video_path}")

视频内容摘要

from agno.agent import Agent
from agno.models.google import Gemini
from agno.media import Video

# 创建视频摘要Agent
video_summary_agent = Agent(
    name="视频摘要助手",
    model=Gemini(id="gemini-2.0-flash-exp"),
    description="生成视频内容的简洁摘要",
    instructions=[
        "观看完整视频",
        "提取核心信息",
        "生成结构化摘要",
        "突出重点内容",
        "用简洁的语言表达"
    ],
    markdown=True,
)

# 视频URL方式
video_url = "https://example.com/video.mp4"

response = video_summary_agent.run(
    input="""请生成这个视频的摘要,包括:
    1. 视频主题(一句话概括)
    2. 主要内容(3-5个要点)
    3. 关键信息提取
    4. 视频时长估计
    5. 适合的观众群体""",
    videos=[Video(url=video_url)],
)

print(response.content)

视频问答系统

from agno.agent import Agent
from agno.models.google import Gemini
from agno.media import Video
from pathlib import Path

# 创建视频问答Agent
video_qa_agent = Agent(
    name="视频问答助手",
    model=Gemini(id="gemini-2.0-flash-exp"),
    description="基于视频内容回答问题",
    instructions=[
        "仔细理解视频内容",
        "准确回答用户问题",
        "引用视频中的具体场景",
        "如果信息不足,明确说明"
    ],
    markdown=True,
)

# 加载视频
video_path = Path("./videos/tutorial.mp4")

# 多轮问答示例
questions = [
    "这个视频的主要内容是什么?",
    "视频中出现了哪些人物?",
    "有哪些重要的步骤或流程?",
    "视频中提到了什么关键数据或信息?"
]

print("=" * 50)
print("视频问答系统")
print("=" * 50)

for i, question in enumerate(questions, 1):
    print(f"\n问题 {i}: {question}")
    
    response = video_qa_agent.run(
        input=question,
        videos=[Video(filepath=video_path)],
    )
    
    print(f"回答: {response.content}")
    print("-" * 50)

视频字幕生成

from agno.agent import Agent
from agno.models.google import Gemini
from agno.tools.moviepy_video import MoviePyVideoTools
from agno.media import Video
from pathlib import Path

# 创建视频字幕生成Agent
subtitle_agent = Agent(
    name="视频字幕生成器",
    model=Gemini(id="gemini-2.0-flash-exp"),
    tools=[MoviePyVideoTools()],  # 包含视频处理工具需要先安装pip install moviepy ffmpeg
    description="自动生成视频字幕的完整工具",
    instructions=[
        "提取视频中的音频",
        "进行语音识别和转录",
        "生成时间轴准确的字幕",
        "将字幕嵌入到视频中",
        "输出带字幕的新视频文件"
    ],
    markdown=True,
    read_tool_call_history=True,
)

# 指定输入视频路径
input_video = Path("./videos/source.mp4")
output_video = Path("./videos/with_subtitles.mp4")

# 生成字幕并嵌入视频
response = subtitle_agent.run(
    input=f"""请为视频生成字幕:
    1. 提取音频内容
    2. 转录为文字
    3. 生成SRT字幕文件
    4. 将字幕嵌入视频

    输入视频: {input_video}
    输出视频: {output_video}
    """,
    videos=[Video(filepath=input_video)],
)

print("字幕生成结果:")
print(response.content)

if output_video.exists():
    print(f"✅ 带字幕的视频已生成:{output_video}")
else:
    print("❌ 字幕生成失败")

第三部分:实战案例

3.1 智能图片故事生成器

这个案例展示如何基于图片内容,自动创作有趣的故事。

from agno.agent import Agent
from agno.models.dashscope import DashScope
from agno.media import Image
from dotenv import load_dotenv

load_dotenv()
# 创建图片故事生成Agent
story_agent = Agent(
    name="图片故事创作家",
    model=DashScope(id="qwen3-vl-plus", base_url="https://dashscope.aliyuncs.com/compatible-mode/v1"),
    description="基于图片创作有趣的故事",
    instructions=[
        "仔细观察图片的所有细节",
        "发挥想象力创作故事",
        "故事要有开头、发展和结尾",
        "融入图片中的元素",
        "语言生动有趣"
    ],
    markdown=True,
)


# 交互式故事生成
def create_story_from_image(image_path: str):
    """基于图片创作故事"""

    print("🎨 图片故事生成器启动!")
    print("=" * 50)

    # 第一步:分析图片
    print("\n📷 正在分析图片...")
    analysis = story_agent.run(
        input="请详细描述这张图片中的场景、人物、物品和氛围",
        images=[Image(filepath=image_path)],
    )
    print(f"分析结果:\n{analysis.content}\n")

    # 第二步:创作故事
    print("📝 正在创作故事...")
    story = story_agent.run(
        input="""基于这张图片,创作一个有趣的短故事(300字左右):
        1. 要有完整的情节
        2. 包含图片中的主要元素
        3. 要有情感和氛围
        4. 结尾要有亮点""",
        images=[Image(filepath=image_path)],
    )
    print(f"故事内容:\n{story.content}\n")

    # 第三步:生成故事标题
    print("📌 正在生成标题...")
    title = story_agent.run(
        input="为刚才的故事起一个吸引人的标题(10字以内)",
        images=[Image(filepath=image_path)],
    )
    print(f"故事标题: {title.content}\n")

    print("=" * 50)
    print("✅ 故事创作完成!")

    return {
        "title": title.content,
        "analysis": analysis.content,
        "story": story.content
    }


# 使用示例
result = create_story_from_image("./images/scene.jpg")


# 保存故事
with open("story_output.md", "w", encoding="utf-8") as f:
    f.write(f"# {result['title']}\n\n")
    f.write(f"## 图片分析\n\n{result['analysis']}\n\n")
    f.write(f"## 故事内容\n\n{result['story']}\n")

3.2 多模态智能客服系统

构建一个能够处理文本和图像的智能客服系统。

from agno.agent import Agent
from agno.models.dashscope import DashScope
from agno.media import Image
from agno.tools.duckduckgo import DuckDuckGoTools

# 创建智能客服Agent
customer_service_agent = Agent(
    name="多模态智能客服",
    model=DashScope(id="qwen3-vl-plus", base_url="https://dashscope.aliyuncs.com/compatible-mode/v1"),
    tools=[DuckDuckGoTools()],  # 添加搜索能力
    description="提供全方位客户服务支持",
    instructions=[
        "友好、专业地回答用户问题",
        "如果用户发送图片,仔细分析图片内容",
        "针对产品问题,提供详细解决方案",
        "对于截图中的错误信息,进行诊断",
        "必要时搜索最新信息",
        "保持耐心和同理心"
    ],
    markdown=True,
    read_tool_call_history=True,
)

class MultimodalCustomerService:
    """多模态客服系统"""
    
    def __init__(self):
        self.agent = customer_service_agent
        self.conversation_history = []
    
    def handle_text_query(self, question: str) -> str:
        """处理纯文本问题"""
        response = self.agent.run(message=question)
        self.conversation_history.append({
            "type": "text",
            "question": question,
            "answer": response.content
        })
        return response.content
    
    def handle_image_query(self, question: str, image_path: str) -> str:
        """处理包含图片的问题"""
        response = self.agent.run(
            message=question,
            images=[Image(filepath=image_path)]
        )
        self.conversation_history.append({
            "type": "image",
            "question": question,
            "image": image_path,
            "answer": response.content
        })
        return response.content
    
    def diagnose_error(self, error_screenshot: str) -> str:
        """诊断错误截图"""
        response = self.agent.run(
            input="""请分析这个错误截图:
            1. 识别错误类型和错误信息
            2. 分析可能的原因
            3. 提供详细的解决步骤
            4. 给出预防建议""",
            images=[Image(filepath=error_screenshot)]
        )
        return response.content
    
    def product_inquiry(self, product_image: str, question: str) -> str:
        """产品咨询"""
        response = self.agent.run(
            input=f"关于图片中的产品,用户想了解:{question}",
            images=[Image(filepath=product_image)]
        )
        return response.content

# 使用示例
service = MultimodalCustomerService()

print("🤖 多模态智能客服系统")
print("=" * 50)

# 场景1:文本咨询
print("\n场景1:产品功能咨询")
answer1 = service.handle_text_query("你们的产品支持哪些支付方式?")
print(f"客服:{answer1}\n")

# 场景2:产品图片咨询
print("场景2:产品图片咨询")
answer2 = service.product_inquiry(
    product_image="./images/product.jpg",
    question="这个产品有什么颜色可选?价格是多少?"
)
print(f"客服:{answer2}\n")

# 场景3:错误诊断
print("场景3:错误截图诊断")
answer3 = service.diagnose_error("./images/error_screenshot.png")
print(f"客服:{answer3}\n")

print("=" * 50)
print(f"✅ 本次会话共处理 {len(service.conversation_history)} 个问题")

3.3 智能文档分析助手

实现一个强大的文档分析系统,支持OCR、信息提取、文档对比等功能。

from agno.agent import Agent
from agno.models.dashscope import DashScope
from agno.media import Image
import json

# 创建文档分析Agent
doc_analyzer = Agent(
    name="智能文档分析师",
    model=DashScope(id="qwen3-vl-plus", base_url="https://dashscope.aliyuncs.com/compatible-mode/v1"),
    description="专业的文档内容分析和信息提取工具",
    instructions=[
        "准确识别文档类型",
        "提取所有文字内容",
        "识别文档结构(标题、段落、表格等)",
        "提取关键信息",
        "生成结构化摘要",
        "保持原文的逻辑关系"
    ],
    markdown=True,
)


class DocumentAnalyzer:
    """文档分析系统"""

    def __init__(self):
        self.agent = doc_analyzer

    def analyze_document(self, doc_image_path: str) -> dict:
        """分析文档图片"""

        # 1. 识别文档类型
        doc_type = self.agent.run(
            input="请识别这是什么类型的文档(如:合同、发票、报告、表格等)",
            images=[Image(filepath=doc_image_path)]
        )

        # 2. 提取文字内容
        ocr_result = self.agent.run(
            input="请提取文档中的所有文字内容,保持原有格式和结构",
            images=[Image(filepath=doc_image_path)]
        )

        # 3. 提取关键信息
        key_info = self.agent.run(
            input="""请提取文档的关键信息,包括:
            - 标题/主题
            - 日期
            - 重要数字和金额
            - 人名、公司名
            - 关键条款或要点
            用JSON格式返回""",
            images=[Image(filepath=doc_image_path)]
        )

        # 4. 生成摘要
        summary = self.agent.run(
            input="请用3-5句话总结这个文档的核心内容",
            images=[Image(filepath=doc_image_path)]
        )

        return {
            "document_type": doc_type.content,
            "ocr_text": ocr_result.content,
            "key_information": key_info.content,
            "summary": summary.content
        }

    def compare_documents(self, doc1_path: str, doc2_path: str) -> str:
        """对比两个文档"""

        response = self.agent.run(
            input="""请对比这两个文档:
            1. 它们的相同点
            2. 它们的不同点
            3. 主要差异在哪些方面
            4. 是否有冲突或矛盾的内容""",
            images=[
                Image(filepath=doc1_path),
                Image(filepath=doc2_path)
            ]
        )

        return response.content

    def extract_table_data(self, table_image_path: str) -> str:
        """提取表格数据"""

        response = self.agent.run(
            input="""请提取表格中的所有数据,并:
            1. 保持表格结构
            2. 用Markdown表格格式输出
            3. 确保数据准确
            4. 标注表头""",
            images=[Image(filepath=table_image_path)]
        )

        return response.content


# 使用示例
analyzer = DocumentAnalyzer()

print("📄 智能文档分析助手")
print("=" * 50)

# 示例1:分析单个文档
print("\n任务1:分析合同文档")
contract_result = analyzer.analyze_document("./documents/contract.jpg")

print(f"\n文档类型:{contract_result['document_type']}")
print(f"\n文档摘要:\n{contract_result['summary']}")
print(f"\n关键信息:\n{contract_result['key_information']}")

# 保存分析结果
with open("contract_analysis.json", "w", encoding="utf-8") as f:
    json.dump(contract_result, f, ensure_ascii=False, indent=2)

# 示例2:对比文档
print("\n\n任务2:对比两个版本的文档")
comparison = analyzer.compare_documents(
    doc1_path="./documents/version1.jpg",
    doc2_path="./documents/version2.jpg"
)
print(f"对比结果:\n{comparison}")

# 示例3:提取表格
print("\n\n任务3:提取财务报表数据")
table_data = analyzer.extract_table_data("./documents/financial_table.jpg")
print(f"表格数据:\n{table_data}")

print("\n" + "=" * 50)
print("✅ 文档分析完成!")

3.4 多模态教育辅导系统

构建一个AI辅导老师,能够识别题目图片并提供解答。

from agno.agent import Agent
from agno.models.dashscope import DashScope
from agno.media import Image
from agno.tools.duckduckgo import DuckDuckGoTools

# 创建教育辅导Agent
tutor_agent = Agent(
    name="AI辅导老师",
    model=DashScope(id="qwen3-vl-plus", base_url="https://dashscope.aliyuncs.com/compatible-mode/v1"),
    tools=[DuckDuckGoTools()],
    description="专业的多模态教育辅导助手",
    instructions=[
        "耐心解答学生问题",
        "识别题目图片中的内容",
        "提供详细的解题思路",
        "用通俗易懂的语言讲解",
        "举例说明概念",
        "鼓励学生独立思考",
        "必要时搜索相关知识点"
    ],
    markdown=True,
    read_tool_call_history=True,
)


class EducationTutor:
    """教育辅导系统"""

    def __init__(self):
        self.agent = tutor_agent

    def solve_problem(self, problem_image: str, student_question: str = "") -> str:
        """解答题目"""

        question = f"""这是一道题目的图片。

        学生的疑问:{student_question if student_question else '请帮我解答这道题'}

        请提供:
        1. 题目内容识别
        2. 知识点分析
        3. 详细解题步骤
        4. 答案
        5. 解题技巧和注意事项"""

        response = self.agent.run(
            input=question,
            images=[Image(filepath=problem_image)]
        )

        return response.content

    def explain_diagram(self, diagram_image: str, topic: str) -> str:
        """解释图表/示意图"""

        response = self.agent.run(
            input=f"""这是关于'{topic}'的图表/示意图,请:
            1. 描述图中的内容和结构
            2. 解释其中的原理或关系
            3. 说明这个图表的用途
            4. 提供相关的知识点
            5. 举一个实际应用的例子""",
            images=[Image(filepath=diagram_image)]
        )

        return response.content

    def check_homework(self, homework_image: str) -> str:
        """批改作业"""

        response = self.agent.run(
            input="""请批改这份作业:
            1. 识别题目和学生的答案
            2. 指出错误之处
            3. 解释正确答案
            4. 给出改进建议
            5. 评估答题质量(优秀/良好/需改进)""",
            images=[Image(filepath=homework_image)]
        )

        return response.content


# 使用示例
tutor = EducationTutor()

print("👨‍🏫 AI辅导老师上线!")
print("=" * 50)

# 场景1:解答数学题
print("\n📐 场景1:解答数学题")
math_solution = tutor.solve_problem(
    problem_image="./homework/math_problem.jpg",
    student_question="这道题的第二步我不太理解"
)
print(math_solution)
print("-" * 50)

# 场景2:解释物理图表
print("\n🔬 场景2:解释物理图表")
physics_explanation = tutor.explain_diagram(
    diagram_image="./homework/circuit_diagram.jpg",
    topic="串联电路"
)
print(physics_explanation)
print("-" * 50)

# 场景3:批改作业
print("\n✏️ 场景3:批改英语作文")
homework_feedback = tutor.check_homework(
    homework_image="./homework/essay.jpg"
)
print(homework_feedback)

print("\n" + "=" * 50)
print("✅ 辅导完成!继续努力学习!")

3.5 多模态内容创作助手

实现一个全能的内容创作系统,从图片分析到文案撰写,再到配图生成。

from agno.agent import Agent
from agno.models.dashscope import DashScope
from agno.models.openai import OpenAIChat
from agno.media import Image
from agno.tools.dalle import DalleTools
from agno.tools.duckduckgo import DuckDuckGoTools

model = DashScope(id="qwen3-vl-plus", base_url="https://dashscope.aliyuncs.com/compatible-mode/v1")

# 创建图像理解Agent
image_analyst = Agent(
    name="图像分析师",
    model=model,
    description="分析图像内容,提取创作灵感",
    markdown=True,
)

# 创建文案撰写Agent
copywriter = Agent(
    name="文案创作家",
    model=model,
    tools=[DuckDuckGoTools()],
    description="撰写吸引人的文案",
    instructions=[
        "文案要简洁有力",
        "突出重点和亮点",
        "语言生动有趣",
        "适合目标受众"
    ],
    markdown=True,
)

# 创建图像生成Agent
image_creator = Agent(
    name="图像生成师",
    model=OpenAIChat(id="gpt-4o"),
    tools=[DalleTools()],
    description="根据描述生成配图",
    instructions=[
        "理解文案需求",
        "生成匹配的图像",
        "注重视觉效果",
        "保持风格统一"
    ],
    markdown=True,
)


class ContentCreationAssistant:
    """内容创作助手"""

    def __init__(self):
        self.analyst = image_analyst
        self.copywriter = copywriter
        self.image_creator = image_creator

    def create_social_media_post(self, source_image: str, platform: str, topic: str) -> dict:
        """创作社交媒体内容"""

        print(f"\n🎨 正在为{platform}创作内容...")
        print(f"主题:{topic}")
        print("-" * 50)

        # 步骤1:分析源图片
        print("\n步骤1:分析图片内容...")
        analysis = self.analyst.run(
            input=f"分析这张图片,提取适合{topic}主题的创作元素和灵感",
            images=[Image(filepath=source_image)]
        )
        print(f"分析结果:{analysis.content}...")

        # 步骤2:撰写文案
        print("\n步骤2:撰写文案...")
        copy_prompt = f"""基于图片分析结果,为{platform}平台撰写一条关于'{topic}'的帖子文案。

        要求:
        - 字数:{'50字以内' if platform == '微博' else '200字以内'}
        - 风格:{'轻松活泼' if platform in ['微博', '小红书'] else '专业有深度'}
        - 包含:吸引人的标题、核心内容、相关话题标签
        - 互动:引导用户点赞、评论、分享

        图片内容:{analysis.content}
        """

        copy_text = self.copywriter.run(input=copy_prompt)
        print(f"文案:{copy_text.content}")

        # 步骤3:生成配图(可选)
        print("\n步骤3:生成配图...")
        image_prompt = f"为{topic}主题创作一张配图"

        new_image = self.image_creator.run(input=image_prompt)
        generated_images = new_image.images
        image_url = None
        if generated_images and isinstance(generated_images, list):
            image_url = generated_images[0].url
            print(f"配图已生成:{image_url}")

        return {
            "platform": platform,
            "topic": topic,
            "analysis": analysis.content,
            "copy": copy_text.content,
            "generated_image": image_url
        }


# 使用示例
creator = ContentCreationAssistant()

print("🎭 多模态内容创作助手")
print("=" * 50)

# 案例:创作社交媒体内容
social_post = creator.create_social_media_post(
    source_image="./images/travel_photo.jpg",
    platform="小红书",
    topic="周末旅行推荐"
)

# 保存结果
with open("social_media_post.md", "w", encoding="utf-8") as f:
    f.write(f"# {social_post['topic']}\n\n")
    f.write(f"**平台**:{social_post['platform']}\n\n")
    f.write(f"## 文案\n\n{social_post['copy']}\n\n")
    if social_post['generated_image']:
        f.write(f"## 配图\n\n![配图]({social_post['generated_image']})\n")

print("\n✅ 内容创作完成!")

第四部分:最佳实践和注意事项

4.1 模型选择建议

根据任务选择合适的模型

任务类型推荐模型理由
中文图像理解qwen-vl-plus中文优化好,OCR准确
多语言OCRqwen-vl-plus支持32种语言
视频分析gemini-2.0-flash-exp视频支持最全面
图像生成gpt-4o + DALL-E图文理解+生成能力强
复杂推理gpt-4o综合能力强
高性价比qwen-vl-plus性能好且成本低

模型切换示例

from agno.agent import Agent
from agno.models.dashscope import DashScope
from agno.models.google import Gemini

# 根据任务动态选择模型
def get_agent_for_task(task_type: str) -> Agent:
    """根据任务类型返回最合适的Agent"""
    
    if task_type in ["ocr", "chinese_image"]:
        return Agent(
            name="中文图像专家",
            model=DashScope(id="qwen3-vl-plus"),
            markdown=True,
        )
    elif task_type == "video":
        return Agent(
            name="视频分析专家",
            model=Gemini(id="gemini-2.0-flash-exp"),
            markdown=True,
        )
    else:
        return Agent(
            name="通用多模态助手",
            model=DashScope(id="qwen3-vl-plus"),
            markdown=True,
        )

# 使用
ocr_agent = get_agent_for_task("ocr")
video_agent = get_agent_for_task("video")

4.2 图像处理最佳实践

图像质量优化

from PIL import Image as PILImage
import io


def optimize_image_for_analysis(image_path: str, max_size: int = 2048) -> bytes:
    """优化图像用于分析

    Args:
        image_path: 图像文件路径
        max_size: 最大尺寸(宽或高)

    Returns:
        优化后的图像字节数据
    """
    # 打开图像
    img = PILImage.open(image_path)

    # 转换为RGB(如果需要)
    if img.mode != 'RGB':
        img = img.convert('RGB')

    # 调整大小(保持宽高比)
    if max(img.size) > max_size:
        img.thumbnail((max_size, max_size), PILImage.Resampling.LANCZOS)

    # 保存为bytes
    buffer = io.BytesIO()
    img.save(buffer, format='JPEG', quality=85, optimize=True)

    return buffer.getvalue()


# 使用优化后的图像
from agno.agent import Agent
from agno.models.dashscope import DashScope
from agno.media import Image

agent = Agent(
    name="图像分析器",
    model=DashScope(id="qwen3-vl-plus"),
    markdown=True,
)

# 优化图像
optimized_image = optimize_image_for_analysis("./large_image.jpg")

# 使用优化后的图像
response = agent.run(
    input="分析这张图片",
    images=[Image(content=optimized_image)]
)

批量处理性能优化

from agno.agent import Agent
from agno.models.dashscope import DashScope
from agno.media import Image
from concurrent.futures import ThreadPoolExecutor, as_completed
from typing import List, Dict
import time

class OptimizedBatchProcessor:
    """优化的批量处理器"""
    
    def __init__(self, max_workers: int = 5, batch_size: int = 10):
        self.agent = Agent(
            name="批量处理器",
            model=DashScope(id="qwen3-vl-plus"),
            markdown=True,
        )
        self.max_workers = max_workers
        self.batch_size = batch_size
    
    def process_batch_with_progress(
        self, 
        image_paths: List[str], 
        task: str
    ) -> List[Dict]:
        """带进度显示的批量处理"""
        
        results = []
        total = len(image_paths)
        completed = 0
        
        with ThreadPoolExecutor(max_workers=self.max_workers) as executor:
            # 分批处理
            for i in range(0, total, self.batch_size):
                batch = image_paths[i:i + self.batch_size]
                
                # 提交批次任务
                futures = {
                    executor.submit(self._process_single, img, task): img 
                    for img in batch
                }
                
                # 收集批次结果
                for future in as_completed(futures):
                    result = future.result()
                    results.append(result)
                    completed += 1
                    
                    # 显示进度
                    progress = (completed / total) * 100
                    print(f"进度:{completed}/{total} ({progress:.1f}%)")
                
                # 批次间短暂延迟,避免请求过快
                if i + self.batch_size < total:
                    time.sleep(1)
        
        return results
    
    def _process_single(self, image_path: str, task: str) -> Dict:
        """处理单张图像"""
        try:
            response = self.agent.run(
                input=task,
                images=[Image(filepath=image_path)]
            )
            return {
                "image": image_path,
                "result": response.content,
                "status": "success"
            }
        except Exception as e:
            return {
                "image": image_path,
                "error": str(e),
                "status": "failed"
            }

# 使用示例
processor = OptimizedBatchProcessor(max_workers=5, batch_size=10)
results = processor.process_batch_with_progress(
    image_paths=[f"./images/img_{i}.jpg" for i in range(100)],
    task="描述图片主要内容"
)

4.3 错误处理和重试策略

健壮的错误处理

from agno.agent import Agent
from agno.models.dashscope import DashScope
from agno.media import Image
import time
from typing import Optional, Callable
import logging

# 配置日志
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)

class RobustMultimodalAgent:
    """带错误处理的健壮多模态Agent"""
    
    def __init__(self, max_retries: int = 3, retry_delay: int = 2):
        self.agent = Agent(
            name="健壮分析器",
            model=DashScope(id="qwen3-vl-plus"),
            markdown=True,
        )
        self.max_retries = max_retries
        self.retry_delay = retry_delay
    
    def analyze_with_retry(
        self,
        image_path: str,
        message: str,
        on_error: Optional[Callable] = None
    ) -> Optional[str]:
        """带重试机制的图像分析"""
        
        for attempt in range(self.max_retries):
            try:
                logger.info(f"尝试 {attempt + 1}/{self.max_retries}...")
                
                response = self.agent.run(
                    input=message,
                    images=[Image(filepath=image_path)]
                )
                
                logger.info("✅ 分析成功!")
                return response.content
                
            except FileNotFoundError:
                logger.error(f"❌ 文件不存在:{image_path}")
                return None
                
            except Exception as e:
                logger.error(f"❌ 错误:{str(e)}")
                
                # 调用错误回调
                if on_error:
                    on_error(attempt, e)
                
                # 重试前等待
                if attempt < self.max_retries - 1:
                    wait_time = self.retry_delay * (attempt + 1)
                    logger.info(f"等待 {wait_time} 秒后重试...")
                    time.sleep(wait_time)
                else:
                    logger.error("❌ 达到最大重试次数")
                    return None
        
        return None

# 使用示例
def error_callback(attempt: int, error: Exception):
    """错误回调函数"""
    print(f"第 {attempt + 1} 次尝试失败:{error}")
    # 可以在这里发送告警、记录日志等

agent = RobustMultimodalAgent(max_retries=3, retry_delay=2)

result = agent.analyze_with_retry(
    image_path="./images/test.jpg",
    message="描述这张图片",
    on_error=error_callback
)

if result:
    print(f"分析结果:\n{result}")
else:
    print("分析失败")

4.4 性能优化建议

缓存策略

from agno.agent import Agent
from agno.models.dashscope import DashScope
from agno.media import Image
import hashlib
import json
from pathlib import Path
from typing import Optional
import time

class CachedMultimodalAgent:
    """带缓存的多模态Agent"""
    
    def __init__(self, cache_dir: str = "./cache", cache_ttl: int = 86400):
        """
        Args:
            cache_dir: 缓存目录
            cache_ttl: 缓存有效期(秒),默认24小时
        """
        self.agent = Agent(
            name="缓存分析器",
            model=DashScope(id="qwen3-vl-plus"),
            markdown=True,
        )
        self.cache_dir = Path(cache_dir)
        self.cache_dir.mkdir(exist_ok=True)
        self.cache_ttl = cache_ttl
        self.cache_hits = 0
        self.cache_misses = 0
    
    def _get_cache_key(self, image_path: str, message: str) -> str:
        """生成缓存键"""
        # 包含文件修改时间,确保文件变化后缓存失效
        file_mtime = Path(image_path).stat().st_mtime
        content = f"{image_path}_{file_mtime}_{message}"
        return hashlib.md5(content.encode()).hexdigest()
    
    def _is_cache_valid(self, cache_file: Path) -> bool:
        """检查缓存是否有效"""
        if not cache_file.exists():
            return False
        
        # 检查是否过期
        cache_age = time.time() - cache_file.stat().st_mtime
        return cache_age < self.cache_ttl
    
    def _load_cache(self, cache_key: str) -> Optional[str]:
        """从缓存加载"""
        cache_file = self.cache_dir / f"{cache_key}.json"
        
        if self._is_cache_valid(cache_file):
            with open(cache_file, "r", encoding="utf-8") as f:
                data = json.load(f)
                self.cache_hits += 1
                return data["result"]
        
        return None
    
    def _save_cache(self, cache_key: str, result: str):
        """保存到缓存"""
        cache_file = self.cache_dir / f"{cache_key}.json"
        with open(cache_file, "w", encoding="utf-8") as f:
            json.dump({
                "result": result,
                "timestamp": time.time()
            }, f, ensure_ascii=False, indent=2)
    
    def analyze(
        self,
        image_path: str,
        message: str,
        use_cache: bool = True
    ) -> str:
        """分析图像(带缓存)"""
        
        cache_key = self._get_cache_key(image_path, message)
        
        # 尝试从缓存加载
        if use_cache:
            cached_result = self._load_cache(cache_key)
            if cached_result:
                print("✓ 从缓存加载")
                return cached_result
        
        # 执行分析
        print("✓ 执行新分析")
        self.cache_misses += 1
        
        response = self.agent.run(
            input=message,
            images=[Image(filepath=image_path)]
        )
        
        result = response.content
        
        # 保存到缓存
        if use_cache:
            self._save_cache(cache_key, result)
        
        return result
    
    def get_cache_stats(self) -> dict:
        """获取缓存统计"""
        total = self.cache_hits + self.cache_misses
        hit_rate = (self.cache_hits / total * 100) if total > 0 else 0
        
        return {
            "hits": self.cache_hits,
            "misses": self.cache_misses,
            "total": total,
            "hit_rate": f"{hit_rate:.1f}%"
        }

# 使用示例
agent = CachedMultimodalAgent(cache_ttl=86400)  # 24小时缓存

# 第一次调用 - 执行分析
result1 = agent.analyze(
    image_path="./images/test.jpg",
    input="描述这张图片"
)

# 第二次调用相同内容 - 从缓存加载
result2 = agent.analyze(
    image_path="./images/test.jpg",
    input="描述这张图片"
)

# 查看缓存统计
stats = agent.get_cache_stats()
print(f"缓存统计:{stats}")

4.5 安全和隐私注意事项

敏感信息处理

from agno.agent import Agent
from agno.models.dashscope import DashScope
from agno.media import Image
import re

class SecureMultimodalAgent:
    """安全的多模态Agent"""
    
    def __init__(self):
        self.agent = Agent(
            name="安全分析器",
            model=DashScope(id="qwen3-vl-plus"),
            markdown=True,
        )
        
        # 敏感信息正则模式
        self.sensitive_patterns = {
            "手机号": r'1[3-9]\d{9}',
            "身份证号": r'\d{17}[\dXx]',
            "银行卡号": r'\d{16,19}',
            "邮箱": r'[\w.-]+@[\w.-]+.\w+',
        }
    
    def mask_sensitive_info(self, text: str) -> str:
        """脱敏处理"""
        masked_text = text
        
        # 手机号脱敏
        masked_text = re.sub(
            self.sensitive_patterns["手机号"],
            lambda m: m.group()[:3] + "****" + m.group()[-4:],
            masked_text
        )
        
        # 身份证号脱敏
        masked_text = re.sub(
            self.sensitive_patterns["身份证号"],
            lambda m: m.group()[:6] + "********" + m.group()[-4:],
            masked_text
        )
        
        # 银行卡号脱敏
        masked_text = re.sub(
            self.sensitive_patterns["银行卡号"],
            lambda m: m.group()[:4] + "****" + m.group()[-4:],
            masked_text
        )
        
        return masked_text
    
    def analyze_safely(self, image_path: str, message: str) -> dict:
        """安全地分析图像"""
        
        # 执行分析
        response = self.agent.run(
            input=message,
            images=[Image(filepath=image_path)]
        )
        
        original_result = response.content
        
        # 脱敏处理
        masked_result = self.mask_sensitive_info(original_result)
        
        return {
            "result": masked_result,
            "has_sensitive_info": original_result != masked_result,
            "warning": "结果包含敏感信息,已自动脱敏" if original_result != masked_result else None
        }

# 使用示例
secure_agent = SecureMultimodalAgent()

result = secure_agent.analyze_safely(
    image_path="./images/id_card.jpg",
    message="提取这张身份证的信息"
)

print(result["result"])
if result["has_sensitive_info"]:
    print(f"\n⚠️ {result['warning']}")

4.6 成本优化建议

智能降采样

from agno.agent import Agent
from agno.models.dashscope import DashScope
from agno.media import Image
from PIL import Image as PILImage

class CostOptimizedAgent:
    """成本优化的Agent"""
    
    def __init__(self):
        self.agent = Agent(
            name="成本优化分析器",
            model=DashScope(id="qwen3-vl-plus"),
            markdown=True,
        )
    
    def analyze_with_auto_resize(
        self,
        image_path: str,
        message: str,
        task_type: str = "general"
    ) -> str:
        """根据任务类型自动调整图像大小"""
        
        # 不同任务的推荐分辨率
        resolution_map = {
            "general": 1024,      # 一般分析
            "ocr": 2048,          # OCR需要高分辨率
            "classification": 512, # 分类任务低分辨率即可
            "detailed": 2048,     # 详细分析
        }
        
        max_size = resolution_map.get(task_type, 1024)
        
        # 调整图像大小
        img = PILImage.open(image_path)
        
        if max(img.size) > max_size:
            img.thumbnail((max_size, max_size), PILImage.Resampling.LANCZOS)
            
            # 保存临时文件
            temp_path = f"./temp_resized_{image_path.split('/')[-1]}"
            img.save(temp_path, quality=85, optimize=True)
            image_to_use = temp_path
        else:
            image_to_use = image_path
        
        # 执行分析
        response = self.agent.run(
            input=message,
            images=[Image(filepath=image_to_use)]
        )
        
        return response.content

# 使用示例
agent = CostOptimizedAgent()

# 分类任务使用低分辨率
result1 = agent.analyze_with_auto_resize(
    image_path="./images/photo.jpg",
    message="这是什么类型的图片?",
    task_type="classification"
)

# OCR任务使用高分辨率
result2 = agent.analyze_with_auto_resize(
    image_path="./images/document.jpg",
    message="提取文档中的文字",
    task_type="ocr"
)

4.7 调试和监控

详细日志记录

from agno.agent import Agent
from agno.models.dashscope import DashScope
from agno.media import Image
import logging
import time
from typing import Dict

# 配置日志
logging.basicConfig(
    level=logging.INFO,
    format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
    handlers=[
        logging.FileHandler('multimodal_agent.log'),
        logging.StreamHandler()
    ]
)

logger = logging.getLogger(__name__)

class MonitoredAgent:
    """带监控的Agent"""
    
    def __init__(self):
        self.agent = Agent(
            name="监控分析器",
            model=DashScope(id="qwen3-vl-plus"),
            markdown=True,
        )
        self.metrics = {
            "total_requests": 0,
            "successful_requests": 0,
            "failed_requests": 0,
            "total_time": 0.0,
        }
    
    def analyze(self, image_path: str, message: str) -> Dict:
        """带监控的分析"""
        
        self.metrics["total_requests"] += 1
        start_time = time.time()
        
        try:
            logger.info(f"开始分析图像:{image_path}")
            logger.info(f"任务:{message}")
            
            response = self.agent.run(
                input=message,
                images=[Image(filepath=image_path)]
            )
            
            elapsed_time = time.time() - start_time
            self.metrics["total_time"] += elapsed_time
            self.metrics["successful_requests"] += 1
            
            logger.info(f"✅ 分析成功,耗时:{elapsed_time:.2f}秒")
            
            return {
                "status": "success",
                "result": response.content,
                "time": elapsed_time
            }
            
        except Exception as e:
            elapsed_time = time.time() - start_time
            self.metrics["failed_requests"] += 1
            
            logger.error(f"❌ 分析失败:{str(e)}")
            logger.error(f"耗时:{elapsed_time:.2f}秒")
            
            return {
                "status": "failed",
                "error": str(e),
                "time": elapsed_time
            }
    
    def get_metrics(self) -> Dict:
        """获取性能指标"""
        avg_time = (
            self.metrics["total_time"] / self.metrics["total_requests"]
            if self.metrics["total_requests"] > 0 else 0
        )
        
        success_rate = (
            self.metrics["successful_requests"] / self.metrics["total_requests"] * 100
            if self.metrics["total_requests"] > 0 else 0
        )
        
        return {
            **self.metrics,
            "average_time": f"{avg_time:.2f}秒",
            "success_rate": f"{success_rate:.1f}%"
        }

# 使用示例
agent = MonitoredAgent()

# 执行多次分析
for i in range(5):
    result = agent.analyze(
        image_path=f"./images/test_{i}.jpg",
        message="描述这张图片"
    )
    print(f"结果 {i+1}{result['status']}")

# 查看性能指标
metrics = agent.get_metrics()
print("\n性能指标:")
for key, value in metrics.items():
    print(f"{key}: {value}")

总结

本教程详细介绍了Agno框架中多模态大模型的使用方法,涵盖了从基础概念到实战应用的完整内容。

核心要点回顾

  1. 多模态模型是AI发展的重要方向,能够处理文本、图像、视频等多种数据类型
  2. Qwen-VL-Plus是优秀的中文多模态模型,特别适合OCR和图像理解任务
  3. Agno框架提供了统一、简洁的API接口,支持多种模型提供商
  4. 实战应用包括智能客服、文档分析、教育辅导、内容创作等多个领域
  5. 最佳实践涉及模型选择、性能优化、错误处理、安全隐私等多个方面

下一步学习建议

  1. 动手实践:运行本教程中的代码示例,理解多模态Agent的工作原理
  2. 探索工具:尝试集成更多工具(如搜索、数据库)扩展Agent能力
  3. 优化性能:根据实际需求调整缓存、批处理等策略
  4. 构建应用:结合业务场景,开发实用的多模态AI应用
  5. 关注更新:持续关注Agno框架和模型的最新发展

相关资源