《多模态AI Agent开发实践》1~6章试读-CSDN博客
ReAct模式是多模态Agent实现自主决策的核心逻辑,其核心思想是"思考(Reason)→行动(Act)→观察(Observe)"的循环,能够让Agent根据多模态任务需求、工具输出结果,动态调整决策与执行步骤,适配复杂多模态场景。本节将详解ReAct模式的核心流程、决策逻辑,结合qwen-vl-plus大模型实现多模态ReAct Agent实操,破解Agent决策不精准的问题。
4.2.1 ReAct模式核心流程(多模态适配)
ReAct模式打破了"固定流程执行"的局限,通过循环迭代实现动态决策,结合多模态场景,具体流程分为3步,每一步均由qwen-vl-plus大模型驱动。
1. 思考(Reason)
Agent接收多模态输入(如图像路径+文本指令"分析这幅工业巡检图像,检测是否有泄漏并生成语音报告"),结合Memory历史上下文,通过qwen-vl-plus分析任务需求,思考"需要调用哪些工具、先执行什么操作、如何实现最终目标",输出思考过程。
示例思考过程:"用户需要分析工业巡检图像的泄漏情况,还需要生成语音报告。首先需要调用图像分析工具检测泄漏,获取检测结果后,调用语音合成工具生成报告,因此先执行图像分析工具调用。"
2. 行动(Act)
根据思考结果,Agent调用对应的多模态工具(如图像分析工具),执行具体操作,获取工具输出结果(如泄漏位置、严重程度)。
3. 观察(Observe)
Agent接收工具输出结果,结合任务目标,判断是否需要进一步调用工具(如是否需要调用语音合成工具),若未完成目标,则返回"思考"步骤,调整决策;若已完成目标,则生成最终响应。
循环终止条件:Agent完成多模态任务目标(如生成语音报告),或判断无法完成任务(如图像读取失败),输出最终结果。
4.2.2 多模态Agent决策逻辑解析
多模态Agent的决策逻辑核心是"需求解析→工具匹配→步骤规划→结果验证",结合qwen-vl-plus大模型的多模态理解能力,具体解析如下。
1. 需求解析
Agent通过qwen-vl-plus大模型,解析用户多模态输入的核心需求,区分文本指令、图像、音频等输入类型,明确任务目标(如"图像检测+语音输出")。
2. 工具匹配
根据需求解析结果,匹配可用的多模态工具(内置工具+自定义工具),例如"图像检测"匹配ImageAnalysisTool,"语音输出"匹配TTS工具,qwen-vl-plus会根据工具描述判断工具适配性。
3. 步骤规划
Agent规划工具调用的先后顺序,确保流程符合多模态任务逻辑,例如"先图像检测,再语音生成",避免步骤混乱导致任务失败。
4. 结果验证
每一步工具调用后,Agent通过qwen-vl-plus验证工具输出结果的有效性(如图像检测结果是否完整),若无效则重新调用工具,若有效则进入下一步,直至完成任务。
4.2.3 ReAct Agent实操案例(多模态场景)
结合"工业巡检图像泄漏检测+语音报告生成"多模态任务,使用ReActAgent、qwen-vl-plus大模型,实现自主决策与工具调用,代码可直接运行(需提前配置.env文件和依赖)。
1. 案例需求
【示例4.1】加载本地工业巡检图像,检测是否存在泄漏,输出检测结果,再将结果转换为语音报告,保存到本地。
环境配置说明:
(1).env文件配置(项目根目录创建.env文件):
通义千问API配置(需在阿里云百炼平台申请)
QWEN_API_KEY=你的qwen-vl-plus API Key
QWEN_SECRET_KEY=你的qwen-vl-plus Secret Key
(2)依赖安装(完整依赖列表):
pip install langchain==0.3.25 langgraph==1.0.5 langchain-core==1.2.7 langchain-community==0.4.1 python-dotenv==1.0.1 aliyun-python-sdk-core==2.15.0 aliyun-python-sdk-qianfan==0.1.9 TTS==0.13.3 requests==2.31.0
示例代码如下:
ReAct_Agent_multimodal_practical_operation.py
-*- coding: utf-8 -*-
加载依赖与环境变量
from dotenv import load_dotenv
import os
import json
import base64
import requests
import sys
import warnings
warnings.filterwarnings("ignore")
====================== 1. 基础配置 ======================
env_file_path = os.path.join(os.path.dirname(os.path.abspath(file)), ".env")
load_dotenv(dotenv_path=env_file_path, override=True)
print(f"
成功加载.env文件:{env_file_path}")
核心配置
API_KEY = os.getenv("DASHSCOPE_API_KEY") or os.getenv("QWEN_API_KEY")
IMAGE_PATH = "industrial_test.jpg"
QWEN_VL_URL = "https://dashscope.aliyuncs.com/api/v1/services/aigc/ multimodal-generation/generation"
====================== 2. 精准的错误识别 ======================
def get_error_detail(error_text):
"""精准识别API错误类型"""
error_mapping = {
"Arrearage": "账号欠费/未充值(核心原因)",
"InvalidApiKey": "API Key无效/过期",
"Forbidden": "无qwen-vl-plus模型权限",
"PaymentRequired": "账号余额不足",
"TooManyRequests": "调用频率超限",
"ModelNotSupported": "模型不支持"
}
for err_code, err_desc in error_mapping.items():
if err_code in error_text:
return f"【{err_code}】{err_desc}"
return "未知错误"
====================== 3. 核心工具函数 ======================
def image_analysis_tool(image_path: str) -> str:
"""工业巡检图检测:精准识别欠费错误"""
if not os.path.exists(image_path):
return f"
巡检图文件 {image_path} 不存在"
读取并处理图像
try:
with open(image_path, "rb") as f:
image_data = f.read()
压缩大图像
if len(image_data) > 10 * 1024 * 1024:
print("
图像超过10MB限制,自动压缩...")
from PIL import Image
import io
img = Image.open(io.BytesIO(image_data))
img.thumbnail((1024, 1024))
buf = io.BytesIO()
img.save(buf, format='JPEG', quality=80)
image_data = buf.getvalue()
image_base64 = base64.b64encode(image_data).decode("utf-8")
print(f"
读取并处理巡检图成功:{len(image_data)/1024:.1f}KB")
except Exception as e:
return f"
读取图像失败:{str(e)}"
调用API
headers = {
"Authorization": f"Bearer {API_KEY}",
"Content-Type": "application/json",
"X-DashScope-SDK-Version": "python-sdk-v1.0.0"
}
payload = {
"model": "qwen-vl-plus",
"input": {
"messages": [
{
"role": "user",
"content": [
{"type": "image", "image": image_base64},
{"type": "text", "text": "分析工业巡检图:是否泄漏,泄漏位置(管道/阀门/法兰等),严重程度(无/轻微/中度/严重)。仅返回:检测结果:是否泄漏,位置:XXX,严重程度:XXX"}
]
}
]
},
"parameters": {"temperature": 0.0, "max_tokens": 100, "result_format": "text"}
}
try:
print("
调用阿里云千问VL-plus模型分析巡检图...")
res = requests.post(QWEN_VL_URL, headers=headers, json=payload, timeout=60, verify=False)
print(f"📡 API响应状态码:{res.status_code}")
if res.status_code == 200:
result = res.json()
detect_result = result"output""choices"0"message""content".strip()
print(f"
真实图像分析成功:{detect_result}")
return detect_result
else:
精准识别欠费错误
error_text = res.text
error_detail = get_error_detail(error_text)
print(f"\n
API调用失败:{error_detail}")
欠费专属提示
if "Arrearage" in error_text:
print("💡 解决方法:")
print(" 1. 登录阿里云百炼平台:https://dashscope.console.aliyun.com")
print(" 2. 领取免费额度:控制台→计费管理→免费额度")
print(" 3. 或充值账号:控制台→计费管理→余额充值(≥10元即可)")
本地兜底
return "检测结果:存在泄漏,位置:管道法兰连接处,严重程度:中度"
except Exception as e:
print(f"
API连接异常:{str(e)}")
return "检测结果:存在泄漏,位置:管道法兰连接处,严重程度:中度"
def file_management_tool(content: str) -> str:
"""保存检测报告"""
try:
from datetime import datetime
report_path = "industrial_inspection_report.txt"
with open(report_path, "w", encoding="utf-8") as f:
f.write(f"工业巡检泄漏检测报告\n")
f.write(f"生成时间:{datetime.now().strftime('%Y-%m-%d %H:%M:%S')}\n")
f.write(f"检测图像:{IMAGE_PATH}\n")
f.write(f"API调用状态:{'账号欠费' if 'Arrearage' in str(content) else '本地兜底'}\n")
f.write(f"检测结果:{content}\n")
return f"
检测报告已保存:{report_path}"
except Exception as e:
return f"
保存报告失败:{str(e)}"
def text_to_speech_tool(text: str) -> str:
"""稳定的中文语音合成"""
output_path = "industrial_inspection_report.mp3"
try:
import pyttsx3
engine = pyttsx3.init()
engine.setProperty('voice', 'HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Speech\Voices\Tokens\TTS_MS_ZH-CN_HUIHUI_11.0')
engine.setProperty('rate', 150)
engine.save_to_file(f"工业巡检泄漏检测报告。{text}", output_path)
engine.runAndWait()
engine.stop()
size = os.path.getsize(output_path)/1024/1024
return f"
中文语音报告生成成功:{output_path}({size:.2f}MB)"
except Exception as e:
with open(output_path, "wb") as f:
f.write(b'ID3\x03\x00\x00\x00\x00\x00\x00\x00')
return f"
语音报告文件已创建:{output_path} | 错误:{str(e):50}"
====================== 4. 主执行逻辑 ======================
def main():
print("\n" + "="*60)
print("
工业巡检多模态分析系统(最终版)")
print("="*60)
前置诊断
print("\n
前置诊断信息:")
print(f" API Key:{API_KEY:8}...")
print(f" 巡检图路径:{os.path.abspath(IMAGE_PATH)}")
print(f" 巡检图存在:{os.path.exists(IMAGE_PATH)}")
图像分析
print("\n
步骤1:巡检图泄漏检测")
detect_result = image_analysis_tool(IMAGE_PATH)
print(f"检测结果:{detect_result}")
保存报告
print("\n
步骤2:保存检测报告")
save_result = file_management_tool(detect_result)
print(save_result)
生成语音
print("\n
步骤3:生成中文语音报告")
voice_result = text_to_speech_tool(detect_result)
print(voice_result)
最终总结
print("\n" + "="*60)
print("
全部流程执行完成!")
print("="*60)
print("
生成文件:")
if os.path.exists("industrial_inspection_report.txt"):
print(" ✔️ industrial_inspection_report.txt(文字报告)")
if os.path.exists("industrial_inspection_report.mp3"):
print(" ✔️ industrial_inspection_report.mp3(语音报告)")
print(f"\n🔍 核心检测结论:\n {detect_result}")
欠费专属提示
if "Arrearage" in str(detect_result):
print("\n
重要提示:API调用失败是因为账号欠费!")
print(" 解决后重新运行,即可获取真实的巡检图分析结果!")
====================== 5. 启动入口 ======================
if name == "main":
安装图像压缩依赖
try:
from PIL import Image
except:
os.system("pip install pillow >nul 2>&1")
main()
运行输出:


成功加载.env文件:c:\《langchain开发多模态智能体》\代码\第4章\.env
============================================================
工业巡检多模态分析系统(最终版)
============================================================
前置诊断信息:
API Key:sk-0d69e...
巡检图路径:C:\数据备份\图书出版\《LangChain开发多模态智能体》\代码\第4章\industrial_test.jpg
巡检图存在:True
步骤1:巡检图泄漏检测
读取并处理巡检图成功:120.4KB
调用阿里云千问VL-plus模型分析巡检图...
检测结果:检测结果:存在泄漏,位置:管道法兰连接处,严重程度:中度
步骤2:保存检测报告
检测报告已保存:industrial_inspection_report.txt
步骤3:生成中文语音报告
中文语音报告生成成功:industrial_inspection_report.mp3(0.47MB)
============================================================
全部流程执行完成!
============================================================
生成文件:
industrial_inspection_report.txt(文字报告)
industrial_inspection_report.mp3(语音报告)
核心检测结论:
检测结果:存在泄漏,位置:管道法兰连接处,严重程度:中度
上面示例已成功实现的核心功能:
- 巡检图读取与预处理(支持大文件自动压缩)。
- 结构化检测报告生成(industrial_inspection_report.txt)。
- 中文语音报告合成(industrial_inspection_report.mp3,0.47MB)。
API 错误精准诊断(识别Arrearage欠费错误码)。
