支持多种抽取技术的多模态 Agent


文档摘要

源文件:chapter3/multimodal-agent/README.md 支持多种抽取技术的多模态 Agent 一个用于教学的 Agent 框架,在多个 AI 提供商(Gemini、OpenAI、豆包)之间对比不同的多模态内容抽取技术。 特性 三种抽取模式 原生多模态:直接使用模型自带的多模态能力进行处理 Gemini 2.5 Pro:文档(PDF)、图像、音频 GPT-5/GPT-4o:图像(OpenAI 多模态格式) 豆包 1.6:图像(OpenAI 多模态格式) 先抽取为文本:先把多模态内容转为文本,再处理 PDF:使用 Gemini 或 GPT-5 做 OCR 图像:使用 GPT-5 或豆包 1.

源文件:chapter3/multimodal-agent/README.md

支持多种抽取技术的多模态 Agent

一个用于教学的 Agent 框架,在多个 AI 提供商(Gemini、OpenAI、豆包)之间对比不同的多模态内容抽取技术。

特性

三种抽取模式

  1. 原生多模态:直接使用模型自带的多模态能力进行处理

    • Gemini 2.5 Pro:文档(PDF)、图像、音频
    • GPT-5/GPT-4o:图像(OpenAI 多模态格式)
    • 豆包 1.6:图像(OpenAI 多模态格式)
  2. 先抽取为文本:先把多模态内容转为文本,再处理

    • PDF:使用 Gemini 或 GPT-5 做 OCR
    • 图像:使用 GPT-5 或豆包 1.6 生成描述
    • 音频:使用 Whisper API 或 Gemini 转写
  3. 多模态分析工具:用于追问的附加功能

    • 图像分析工具(GPT-5 / 豆包 1.6)
    • 音频分析工具(Gemini 2.5 Pro)
    • PDF 分析工具(Gemini 2.5 Pro)

架构

Agent 采用模块化架构,职责清晰分离:

MultimodalAgent ├── 配置 (config.py) │ ├── 模型配置 │ ├── API 密钥管理 │ └── 抽取模式设置 ├── Agent 核心 (agent.py) │ ├── 消息处理(OpenAI 格式) │ ├── 对话历史 │ ├── 按模式处理 │ └── 流式响应 └── 多模态工具 ├── 图像分析 ├── 音频分析 └── PDF 分析

安装

  1. 克隆仓库并进入项目目录:
cd chapter3/multimodal-agent
  1. 安装依赖:
pip install -r requirements.txt
  1. 配置 API 密钥:
cp env.example .env # 编辑 .env,填入你的 API 密钥
  1. 加载环境变量:
export $(cat .env | xargs)

离线快速上手(无需 API 密钥)

生成一份打包好的多模态样本——一份带图表的报告——让你能端到端跑通
实验 3-7。精确的季度数字只出现在图表的柱子里,正文文本中没有,
这正是让三种范式取舍变得可度量的关键。

# 离线:生成 test_files/sample_chart.png 和 test_files/sample_report.pdf python create_sample.py # 或:python demo.py --generate-sample

然后针对同一份文件和同一问题对比三种抽取范式
(需要视觉 API 密钥,如 OpenAI 或 Gemini):

python demo.py \ --file test_files/sample_chart.png \ --query "Which quarter had the highest revenue, and what was the exact value?" \ --model gpt-5.6-luna

所有 CLI 都提供中文 --helppython demo.py --help
python main.py --helppython create_sample.py --help)。

用法

交互式对话模式

启动一个与 Agent 的交互式会话:

python main.py --interactive

交互模式下的可用命令:

  • /file <path> - 加载一个多模态文件
  • /mode <native|extract_to_text> - 切换抽取模式
  • /model <model_name> - 切换模型
  • /tools <on|off> - 启用 / 禁用多模态工具
  • /history - 显示对话历史
  • /clear - 清空对话历史
  • /quit - 退出

处理单个文件

用指定查询处理一个文件:

# 原生模式(默认) python main.py --file document.pdf --query "What is the main topic?" # 先抽取为文本模式 python main.py --mode extract_to_text --file image.jpg --query "Describe this image" # 启用多模态工具 python main.py --tools --mode extract_to_text --file audio.mp3 --query "What's the content?"

编程式用法

import asyncio from agent import MultimodalAgent, MultimodalContent from config import ExtractionMode async def example(): # 初始化 Agent agent = MultimodalAgent( model="gemini-3.5-flash", mode=ExtractionMode.NATIVE, enable_tools=True ) # 处理一份 PDF content = MultimodalContent( type="pdf", path="document.pdf" ) result = await agent.process_multimodal_content( content, "Summarize this document" ) print(result) # 流式对话 async for chunk in agent.chat("Tell me more about the key points", stream=True): print(chunk, end="", flush=True) asyncio.run(example())

对比抽取技术

演示脚本

运行完整的对比演示:

# 针对特定文件对比抽取模式(flag 形式) python demo.py --file document.pdf --query "What are the key findings?" --model gpt-5.6-luna # 向后兼容的位置参数形式仍然可用 python demo.py document.pdf "What are the key findings?" # 保存完整对话记录,并跳过跨模型对比 python demo.py --file test_files/sample_chart.png \ --query "Which quarter had the highest revenue?" \ --model gpt-5.6-luna --skip-model-comparison --output result.txt # 这会运行: # 1. 原生多模态模式 # 2. 先抽取为文本模式 # 3. 带工具的先抽取为文本模式 # 4. 跨不同模型对比(除非指定 --skip-model-comparison)

演示 CLI 参数:

参数 说明
--file / 位置参数 file 要处理的多模态文件(图像 / PDF / 音频)
--query / 位置参数 query 针对该文件要提问的问题
--model 用于原生 / 抽取模式的模型(默认:gemini-3.5-flash
--skip-model-comparison 只运行三种范式的对比
--generate-sample 离线:生成打包的图表样本后退出
--output, -o 同时把完整对话记录写入文件

模式对比

模式 优点 缺点 最适用于
原生 - 保留完整上下文
- 视觉理解更好
- 直接处理
- 支持的模型有限
- token 消耗更高
内容混合的复杂文档
先抽取为文本 - 适配所有模型
- token 消耗更低
- 可缓存抽取结果
- 丢失视觉上下文
- 两步流程
文本为主的文档、成本优化
带工具 - 兼具两者优点
- 支持追问
- 选择性深入分析
- 配置更复杂
- 多次 API 调用
交互式会话、详细问答

支持的文件类型

文档

  • PDF 文件(最多 1000 页)
  • 在 Gemini 2.5 Pro 原生模式下效果最佳

图像

  • JPEG、PNG、GIF、BMP、WebP
  • 所有模型均支持

音频

  • MP3、WAV、M4A、FLAC、AAC、OGG
  • 通过 Whisper 或 Gemini 转写

模型能力

模型 原生 PDF 原生图像 原生音频 先抽取为文本 工具支持
Gemini 2.5 Pro 支持 支持 支持 支持 支持
GPT-5/GPT-4o 不支持 支持 不支持 支持 支持
豆包 1.6 不支持 支持 不支持 支持 支持

API 配置

所需 API 密钥

  1. Google Gemini:PDF / 音频原生处理必需

  2. OpenAI:GPT 系列模型和 Whisper 必需

  3. 豆包:豆包模型必需

文件大小限制

  • PDF:20MB
  • 图像:20MB
  • 音频:25MB

测试

运行测试套件:

python test_multimodal.py

示例

示例 1:分析研究论文

# 用原生模式获得最佳理解 agent = MultimodalAgent( model="gemini-3.5-flash", mode=ExtractionMode.NATIVE ) content = MultimodalContent(type="pdf", path="research_paper.pdf") summary = await agent.process_multimodal_content( content, "What are the main contributions and findings?" )

示例 2:处理图像并追问

# 先抽取为文本并启用工具,以便追问 agent = MultimodalAgent( model="gpt-5.6-luna", mode=ExtractionMode.EXTRACT_TO_TEXT, enable_tools=True ) # 初次处理 await agent.chat("images/I have an image at photo.webp", MultimodalContent(type="image", path="photo.jpg")) # 用工具追问 await agent.chat("What objects are in the background?") await agent.chat("What's the color scheme?")

示例 3:音频转写与分析

# 使用 Whisper 进行转写 agent = MultimodalAgent( model="gpt-5.6-luna", mode=ExtractionMode.EXTRACT_TO_TEXT ) content = MultimodalContent(type="audio", path="interview.mp3") transcript = await agent._extract_audio_to_text(content) print(f"Transcript: {transcript}") # 分析转写文本 analysis = await agent._answer_with_context( transcript, "What are the key points discussed?" )

最佳实践

  1. 模式选择

    • 视觉 / 音频理解至关重要时使用原生模式
    • 为优化成本和支持缓存时使用先抽取为文本
    • 带追问的交互式会话启用工具
  2. 模型选择

    • Gemini 2.5 Pro:最适合 PDF 和音频
    • GPT-4o/GPT-5:最适合复杂的图像理解
    • 豆包 1.6:图像处理的备选
  3. 性能优化

    • 对重复查询缓存抽取出的文本
    • 使用流式改善用户体验
    • 处理不超过大小限制的文件
  4. 错误处理

    • 始终校验文件存在性与类型
    • 处理前检查 API 密钥配置
    • 优雅地处理限流和 API 错误

故障排查

常见问题

  1. API 密钥错误

    • 确认 .env 中已设置所有必需的 API 密钥
    • 检查 API 密钥有效性与配额
  2. 文件处理错误

    • 核实文件格式受支持
    • 检查文件大小在限制内
    • 确认文件路径正确
  3. 模型兼容性

    • 并非所有模型都原生支持所有内容类型
    • 对不支持的组合使用先抽取为文本模式

架构细节

消息格式

Agent 使用 OpenAI 兼容的消息格式:

{ "role": "user" | "assistant" | "system" | "tool", "content": "message text" | [{"type": "text", "text": "..."}, ...], "tool_calls": [...], # 可选 "tool_call_id": "...", # 用于工具响应 }

工具调用格式

工具遵循 OpenAI 函数调用规范:

{ "type": "function", "function": { "name": "analyze_image", "description": "...", "parameters": { "type": "object", "properties": {...}, "required": [...] } } }

流式实现

Agent 支持流式响应以改善体验:

  • Gemini:原生流式 API
  • OpenAI/豆包:通过 chat completions API 流式传输
  • 工具结果在完成时即流式返回

贡献

这是一个展示多模态 AI 能力的教学项目。贡献可聚焦于:

  • 增加新的抽取技术
  • 改进模型对比
  • 完善文档
  • 增加更多测试用例

许可证

MIT License - 详情见 LICENSE 文件

OpenRouter 通用回退 / Universal OpenRouter fallback

This experiment now supports a universal OpenRouter fallback for its chat LLM.

  • If the primary provider key (e.g. MOONSHOT_API_KEY / KIMI_API_KEY / OPENAI_API_KEY / DOUBAO_API_KEY …) is present, behavior is unchanged.
  • Else if OPENROUTER_API_KEY is set, the chat LLM is automatically routed through OpenRouter (https://openrouter.ai/api/v1). Model names are mapped automatically: gpt-*/o1-*openai/…, claude-*anthropic/claude-opus-4.8, ids already containing / are kept as-is, and other provider-native ids (e.g. kimi-k3, doubao-*) fall back to openai/gpt-5.6-luna. Set OPENROUTER_MODEL to force a specific OpenRouter model id.
  • Else a clear error lists the accepted keys.

Add OPENROUTER_API_KEY=... to your .env (see env.example) to enable it.

Note: image analysis and text chat route through OpenRouter (vision-capable default openai/gpt-5.6-luna). Audio transcription (Whisper) and native-PDF extraction still require a direct OpenAI/Gemini key.


作者与出处
原作者: bojieli
来源:bojieli
许可证:Apache-2.0
整理: 灏天文库整理
由灏天文库结构化整理,提供目录导航、全文检索与在线阅读,便于系统化学习
发布者: 作者: bojieli 转发
评论区 (0)
U