多模态LLM执行函数调用的技巧
一、这是什么?(概念解释)
多模态LLM(Multimodal LLM) 是能够理解和处理多种类型输入(文本、图片、音频、视频等)的大语言模型。
结合函数调用:让多模态LLM不仅能"看"图片,还能根据图片内容执行相应的工具操作。
核心能力:
- 视觉理解:识别图片中的内容(人物、场景、文字等)
- 工具调用:根据识别结果自动调用合适的工具
- 跨模态推理:将视觉信息转化为工具调用参数
二、有什么用?(应用场景)
| 场景 | 说明 |
|---|---|
| 图像识别 + 天气查询 | 识别城市地标图片,自动查询该城市天气 |
| 文字识别 + 数据录入 | OCR 识别图片中的文字,自动填入表单 |
| 物品识别 + 电商平台 | 识别商品图片,自动查询价格和库存 |
| 场景理解 + 智能客服 | 识别用户上传的故障图片,调用维修工具 |
| 图表识别 + 数据分析 | 识别图表数据,自动生成分析报告 |
| 文生图应用 | 根据文字描述调用AI绘画工具生成图片 |
| 图片编辑 + PS工具 | 识别图片需要修改的部分,调用PS API |
三、应用一:图像识别 + 工具调用
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import base64
import json
import os
from typing import Type, Any
import requests
from langchain_core.output_parsers import StrOutputParser
from langchain_core.prompts import ChatPromptTemplate
from pydantic import Field, BaseModel
from langchain_core.runnables import RunnablePassthrough
from langchain_core.tools import BaseTool
from langchain_openai import ChatOpenAI
import dotenv
dotenv.load_dotenv()
# ============ 第一步:定义天气查询工具 ============
class WeatherArgsSchema(BaseModel):
city: str = Field(description="需要查询天气预报的目标城市")
class WeatherTool(BaseTool):
"""根据传入的城市名查询天气"""
name: str = "weather_query"
description: str = "当你想询问天气或与天气相关的问题时的工具"
args_schema: Type[BaseModel] = WeatherArgsSchema
def _run(self, city: str) -> str:
# 调用天气 API
return f"{city}今天晴天,温度 25°C"
# ============ 第二步:创建多模态 Prompt ============
# 关键:支持图片输入的 Prompt 格式
prompt = ChatPromptTemplate.from_messages([
("human", [
{"type": "text", "text": "请获取下上传图片所在城市的天气预报"},
{"type": "image_url", "image_url": {"url": "{image_url}"}}
])
])
# 用于整理天气信息的 Prompt
weather_prompt = ChatPromptTemplate.from_template(
"""请整理下传递的城市的天气预报信息,并以用户友好的方式输出。
<weather>
{weather}
</weather>"""
)
# ============ 第三步:创建多模态 LLM 并绑定工具 ============
# 使用支持视觉的模型
llm = ChatOpenAI(model="gpt-4-vision-preview")
llm_with_tools = llm.bind_tools(
tools=[WeatherTool()],
tool_choice="weather_query" # 强制使用天气工具
)
# ============ 第四步:构建链 ============
chain = (
{
"weather": (
{"image_url": RunnablePassthrough()}
| prompt
| llm_with_tools
| (lambda msg: msg.tool_calls[0]["args"])
| WeatherTool()
)
}
| weather_prompt
| llm
| StrOutputParser()
)
# ============ 第五步:准备图片并调用 ============
# 方式一:使用网络图片 URL
image_url = "https://example.com/guangzhou.jpg"
# 方式二:将本地图片转换为 base64
# with open("city.jpg", "rb") as f:
# image_data = f.read()
# image_url = f"data:image/jpeg;base64,{base64.b64encode(image_data).decode('utf-8')}"
result = chain.invoke(image_url)
print(result)
# 输出:根据图片识别,这是广州。广州今天晴天,温度 25°C
四、应用二:文生图工具调用
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import dotenv
from langchain_core.tools import tool
from langchain_openai import ChatOpenAI
import requests
from datetime import datetime
dotenv.load_dotenv()
# ============ 第一步:定义图片生成工具 ============
@tool
def generate_image(prompt: str) -> str:
"""
使用AI绘画工具生成图片
Args:
prompt: 图片描述提示词
Returns:
生成图片保存路径
"""
try:
# 调用图片生成 API(以通义万相为例)
# 实际使用时替换为真实的 API 调用
image_url = "https://example.com/generated_image.jpg"
# 下载图片
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
filename = f"generated_image_{timestamp}.png"
img_response = requests.get(image_url)
if img_response.status_code == 200:
with open(filename, 'wb') as f:
f.write(img_response.content)
return f"图片生成成功!已保存到: {filename}"
else:
return f"图片生成失败"
except Exception as e:
return f"图片生成异常: {str(e)}"
# ============ 第二步:创建 LLM 并绑定工具 ============
llm = ChatOpenAI(model="gpt-4o-mini")
llm_with_tools = llm.bind_tools([generate_image])
# ============ 第三步:构建链 ============
def extract_tool_args(msg):
"""提取工具调用参数"""
if msg.tool_calls:
return msg.tool_calls[0]["args"]
else:
# 如果 LLM 没有调用工具,使用原始消息作为提示词
return {"prompt": msg.content}
chain = llm_with_tools | extract_tool_args | generate_image
# ============ 第四步:调用 ============
result = chain.invoke("请生成一张图片:一只可爱的猫咪在花园里")
print(result)
# 输出:图片生成成功!已保存到: generated_image_20240713_123456.png
五、流程图
┌─────────────────────────────────────────────────────────────────────────┐
│ 多模态 LLM 函数调用流程 │
└─────────────────────────────────────────────────────────────────────────┘
================== 应用一:图像识别 + 工具调用 ==================
用户上传图片 视觉LLM 工具执行
│ │ │
▼ ▼ │
广州塔.jpg ───────────────▶│ 分析图片 │
│ │ │
│ │ 识别出:这是广州 │
│◀──────────────────────│ │
│ │ │
│ ▼ │
│ 决定调用工具 │
│ tool_calls: [ │
│ {name: "weather_query", │
│ args: {city: "广州"}} │
│ ] │
│ │ │
▼ │ │
提取参数 │ │
city = "广州" │ │
│ │ │
▼ ▼ ▼
调用天气工具 ────────────────────────────────────────▶│
│ 查询广州天气
│◀───────────────────────────────────────│
│ │ │
▼ ▼ ▼
返回天气结果 "晴天,25°C"
│ │ │
│ ▼ │
│ 整理最终回答 │
│◀──────────────────────│ │
"根据图片识别,这是 │ │
广州。广州今天晴天, │ │
温度25°C。" │ │
================== 应用二:文生图工具调用 ==================
用户输入 LLM 绘画工具
│ │ │
▼ ▼ │
"生成一只可爱的猫咪 ───────▶│ 分析需求 │
在花园里的图片" │ │
│ │ │
│ │ 决定调用图片生成工具 │
│ │ tool_calls: [ │
│ │ {name: "generate_image",│
│ │ args: {prompt: "..."}}│
│ │ ] │
│◀──────────────────────│ │
│ │ │
▼ │ │
提取参数 │ │
prompt = "一只可爱的... │ │
│ │ ▼
▼ ▼ 调用绘画API
调用图片生成工具 ──────────────────────────────────────▶│
│ 生成图片
│◀───────────────────────────────────────│
│ │ │
▼ ▼ ▼
返回图片路径 保存图片
"图片生成成功! │
已保存到: xxx.png" │
┌─────────────────────────────────────────────────────────────────────────┐
│ 核心要点 │
└─────────────────────────────────────────────────────────────────────────┘
1. 多模态输入 - Prompt 支持 image_url 类型
2. 视觉理解 - LLM 识别图片内容
3. 参数提取 - 将识别结果转换为工具参数
4. 工具执行 - 调用外部 API 完成任务