当前位置: 首页 > news >正文

【带你 langchain 双排系列教程】6.LangChain多模态输入与自定义输出实战指南

一、为什么需要多模态交互?

在真实业务场景中,数据从来都不是单一形式的。想象一个智能客服系统需要同时分析用户的文字描述、上传的产品图片和语音留言,或者一个内容审核系统需要检查文本、图像和视频的组合内容。传统单一模态的处理方式已经无法满足这些需求。

二、环境准备

pip install langchain-openai Pillow python-multipart librosa

三、多模态输入处理实战

1. 基础文本处理

from langchain_core.prompts import ChatPromptTemplate
from langchain_openai import ChatOpenAI

prompt = ChatPromptTemplate.from_template("分析这段话的情感倾向:{text}")
model = ChatOpenAI(model="gpt-4")

chain = prompt | model
response = chain.invoke({"text": "虽然产品功能不错,但客服响应太慢了"})
print(response.content)

2. 图像处理进阶

from PIL import Image
import base64

def image_to_base64(image_path):
    with open(image_path, "rb") as image_file:
        return base64.b64encode(image_file.read()).decode('utf-8')

image_analysis_prompt = """
请分析这张图片:
<img src="data:image/png;base64,{image}" width=300/>
重点说明:
1. 主要视觉元素
2. 颜色搭配特点
3. 可能的商业应用场景
"""

prompt = ChatPromptTemplate.from_template(image_analysis_prompt)
chain = prompt | model

response = chain.invoke({
    "image": image_to_base64("product_design.png")
})
print(response.content)

图片url方式多模态,模型可用视觉相关的模型,有些对话模型或不支持多模态。
在这里插入图片描述

import base64
import httpx
from langchain_core.messages import HumanMessage
from langchain_openai import ChatOpenAI
import os

image_url = "https://scpic.chinaz.net/files/pic/pic9/201602/apic19010.jpg"
image_data = base64.b64encode(httpx.get(image_url).content).decode("utf-8")
model = ChatOpenAI(
    model="deepseek-ai/deepseek-vl2",
    temperature=0.8,
    max_tokens=None,
    timeout=None,
    max_retries=2,
    api_key=os.getenv("silicon-key"),
    base_url="https://api.siliconflow.cn/v1"
    # organization="...",
    # other params...
)
message = HumanMessage(
    content=[
        {"type": "text", "text": "用中文描述这张图片中的天气"},
        {"type": "image_url", "image_url": {"url": image_url}},
    ], )
response = model.invoke([message])
print(response.content)

在这里插入图片描述
多张图片的情况:

import base64
import httpx
from langchain_core.messages import HumanMessage
from langchain_openai import ChatOpenAI
import os

image_url = "https://scpic.chinaz.net/files/pic/pic9/201602/apic19010.jpg"
image_url2 = "https://pic.nximg.cn/file/20140920/18021896_181234816000_2.jpg"
image_data = base64.b64encode(httpx.get(image_url).content).decode("utf-8")
model = ChatOpenAI(
    model="deepseek-ai/deepseek-vl2",
    temperature=0.8,
    max_tokens=None,
    timeout=None,
    max_retries=2,
    api_key=os.getenv("silicon-key"),
    base_url="https://api.siliconflow.cn/v1"
    # organization="...",
    # other params...
)
message = HumanMessage(
    content=[
        {"type": "text", "text": "用中文描述这张2图片中的天气是不是一样的"},
        {"type": "image_url", "image_url": {"url": image_url}},
        {"type": "image_url", "image_url": {"url": image_url2}},
    ], )
response = model.invoke([message])
print(response.content)

在这里插入图片描述
工具调用方式多模态处理:

import base64
import httpx
from langchain_core.messages import HumanMessage
from langchain_openai import ChatOpenAI
import os
from langchain_core.tools import tool
from typing import Literal


@tool
def weather_tool(weather: Literal["晴朗的", "多云的", "多雨的", "下雪的"]) -> None:
    """ Description the weather"""
    pass


image_url = "https://scpic.chinaz.net/files/pic/pic9/201602/apic19010.jpg"
image_url2 = "https://pic.nximg.cn/file/20140920/18021896_181234816000_2.jpg"
image_data = base64.b64encode(httpx.get(image_url).content).decode("utf-8")
model = ChatOpenAI(
    model="deepseek-ai/deepseek-vl2",
    temperature=0.8,
    max_tokens=None,
    timeout=None,
    max_retries=2,
    api_key=os.getenv("silicon-key"),
    base_url="https://api.siliconflow.cn/v1"
    # organization="...",
    # other params...
)

model.bind_tools([weather_tool])

message = HumanMessage(
    content=[
        {"type": "text", "text": "用中文描述这张2图片中的天气是不是一样的"},
        {"type": "image_url", "image_url": {"url": image_url}},
        {"type": "image_url", "image_url": {"url": image_url2}},
    ], )
response = model.invoke([message])
print(response.content)

在这里插入图片描述

3. 音频处理技巧

import librosa
import numpy as np

def audio_feature_extraction(file_path):
    y, sr = librosa.load(file_path)
    return {
        "duration": len(y)/sr,
        "tempo": librosa.beat.tempo(y=y, sr=sr)[0],
        "spectral_centroid": np.mean(librosa.feature.spectral_centroid(y=y, sr=sr))
    }

audio_features = audio_feature_extraction("customer_feedback.wav")

analysis_prompt = """
根据以下音频特征生成报告:
- 时长:{duration:.2f}秒
- 节奏:{tempo:.1f}BPM
- 频谱重心:{spectral_centroid:.1f}Hz

结合语音内容:"{transcript}"
分析客户情绪状态"""

四、自定义输出深度解析

1. 结构化输出实践

from pydantic import BaseModel
from langchain_core.output_parsers import PydanticOutputParser

class MarketAnalysis(BaseModel):
    target_audience: str
    competitive_advantages: list[str]
    risk_factors: list[str]
    market_score: float 

parser = PydanticOutputParser(pydantic_object=MarketAnalysis)

prompt_template = """
执行深度市场分析:
{instruction}
{format_instructions}
"""
prompt = ChatPromptTemplate.from_template(prompt_template).partial(
    format_instructions=parser.get_format_instructions()
)

chain = prompt | model | parser
result = chain.invoke({
    "instruction": "分析智能手表市场现状"
})

print(f"目标人群:{result.target_audience}")
print(f"风险因素:{result.risk_factors[:2]}")

2. 动态格式转换

from langchain_core.output_parsers import JsonOutputParser

dynamic_prompt = """
根据用户查询生成响应:
查询内容:{query}
要求格式:{format}
"""

chain = ChatPromptTemplate.from_template(dynamic_prompt) | model | JsonOutputParser()

response = chain.invoke({
    "query": "对比Python和JavaScript的优缺点",
    "format": """{
        "comparison_points": ["语法", "生态系统", "性能"],
        "summary": "综合建议"
    }"""
})

print(response["summary"])

五、综合实战案例:智能内容审核系统

class ContentAuditResult(BaseModel):
    violation_type: Optional[str]
    confidence: float
    problematic_elements: list[str]
    recommendation: str

def multimodal_audit(text: str, image: Image, audio: bytes):
    # 图像处理
    image_analysis = chain_image.invoke(...)
    
    # 音频转录
    audio_text = transcribe_audio(audio)
    
    # 综合审核
    combined_prompt = """
    执行内容审核:
    文本内容:{text}
    图片分析:{image_analysis}
    语音转录:{audio_text}
    
    输出要求:
    {format_instructions}
    """
    
    chain = (
        ChatPromptTemplate.from_template(combined_prompt)
        .partial(format_instructions=parser.get_format_instructions())
        | model
        | parser
    )
    
    return chain.invoke(...)

# 使用示例
result = multimodal_audit(
    text="敏感文本内容",
    image=Image.open("user_image.jpg"),
    audio=audio_bytes
)

六、性能优化技巧

  1. 并行处理:使用async/await实现多模态并行处理
  2. 缓存策略:对静态内容(如产品图片)实施特征缓存
  3. 分级处理:先快速筛查再深度分析的分级处理机制
async def parallel_processing(text, image, audio):
    image_task = chain_image.ainvoke(...)
    audio_task = chain_audio.ainvoke(...)
    results = await asyncio.gather(image_task, audio_task)
    return combine_results(text, *results)

七、扩展思考

  1. 视频处理:结合OpenCV进行关键帧提取
  2. 3D模型处理:使用PointNet进行三维数据分析
  3. 传感器数据集成:融合IoT设备数据流

通过本文的实践案例,我们已经掌握了构建多模态智能系统的核心方法。随着多模态大模型的快速发展,建议持续关注以下方向:

  • 跨模态注意力机制
  • 端到端的多模态训练
  • 实时流式处理优化

相关文章:

  • 机器学习数学通关指南——链式法则
  • Three.js轮廓线、边框线、选中效果实现的几种实现方法以及性能评估
  • Lock-Free环形队列C++实现
  • C进阶 自定义类型
  • 计算机性能指标
  • list结构刨析与模拟实现
  • 【p-camera-h5】 一款开箱即用的H5相机插件,支持拍照、录像、动态水印与样式高度定制化。
  • STM32——HAL库开发笔记22(定时器3—呼吸灯实验)(参考来源:b站铁头山羊)
  • muduo源码阅读:socket常见操作及一些补充
  • PAT甲级 1103 Integer Factorization
  • Docker安装Mysql
  • C语言图结构学习笔记
  • JavaScript函数-函数的返回值
  • 计算机网络之路由协议(自治系统)
  • AI学习之-阿里天池
  • jmeter后端监视器的妙用和实现方法
  • Progress bar (进度条)
  • 谷歌浏览器安装Vue3插件
  • 亲测Win11电脑可以安装LabVIEW的版本,及2015、2018、2020版本直接的区别
  • Google第三方库详解------ProtoBuf详解 + 样例(5万字详解!)
  • 中青报:“猿辅导员工猝死”事件上热搜,是对健康职场环境的共同关切
  • 鞍钢矿业党委书记、董事长刘炳宇调任中铝集团副总经理
  • 美联储报告披露关税战冲击波:消费信心下降,经济担忧加深
  • 云南舞蹈大家跳暨2025年牟定“三月会”昨天开幕
  • 一季度公募管理规模出炉:44家实现增长,4家规模环比翻倍
  • 税务部门曝光3起通过拆分经营骗享小规模纳税人税费优惠偷税案件