LangChain —多模态 / 多源上下文管理
在LangChain中,多模态/多源上下文管理指的是整合来自不同来源(如网页、PDF、数据库、API)或不同类型(如文本、图片、音频、表格)的信息,形成统一的上下文供大模型使用。其核心挑战是打破信息格式和来源的壁垒,让模型能综合各类信息生成更全面的回答。以下是具体做法和实现方式:
一、多源上下文管理:整合不同来源的信息
多源信息指来自网页、本地文件(PDF/Word)、数据库(SQL/NoSQL)、API接口等不同渠道的数据。LangChain通过“统一加载→标准化格式→融合检索”三步实现整合。
1. 多源信息统一加载:用Loader适配不同来源
LangChain提供了丰富的Loader
工具,针对不同来源的数据设计专属加载逻辑,确保原始信息能被正确解析。
信息来源 | 对应Loader工具 | 功能说明 |
---|---|---|
网页 | WebBaseLoader | 爬取网页HTML,提取文本内容(支持BeautifulSoup解析) |
PDF文件 | PyPDFLoader /PDFPlumberLoader | 解析PDF的文字和表格(PDFPlumberLoader 支持表格提取) |
数据库(SQL) | SQLDatabaseLoader | 执行SQL查询,获取结构化数据(如MySQL/PostgreSQL) |
API接口 | APILoader (自定义) | 调用第三方API(如天气API、电商商品API)获取数据 |
本地文本/Word | TextLoader /UnstructuredWordLoader | 加载TXT/Word文件,支持格式保留 |
具体操作示例:加载网页、PDF和SQL数据
from langchain.document_loaders import WebBaseLoader, PyPDFLoader, SQLDatabaseLoader
from langchain.sql_database import SQLDatabase# 1. 加载网页信息(如产品官网介绍)
web_loader = WebBaseLoader("https://example.com/product/fridge")
web_docs = web_loader.load() # 返回Document对象列表# 2. 加载PDF手册(如冰箱使用说明书)
pdf_loader = PyPDFLoader("fridge_manual.pdf")
pdf_docs = pdf_loader.load_and_split() # 分块加载PDF# 3. 加载数据库数据(如用户购买记录)
db = SQLDatabase.from_uri("sqlite:///user_orders.db")
sql_loader = SQLDatabaseLoader(db=db,query="SELECT * FROM orders WHERE product='fridge' LIMIT 5" # 查询最近5条冰箱订单
)
sql_docs = sql_loader.load() # 数据库结果转为Document对象
2. 标准化格式:用Document
类统一封装多源信息
不同来源的信息格式各异(如网页是HTML片段,数据库是表格,PDF是文本块),LangChain用Document
类统一封装,确保后续处理逻辑一致。
Document
类的核心结构:
class Document:page_content: str # 信息的文本内容(核心)metadata: dict # 来源元数据(如"source": "web", "url": "...", "page": 5)
示例:多源信息的Document
封装效果
- 网页数据:
Document(page_content="2024款冰箱支持智能控温...", metadata={"source": "web", "url": "..."})
- PDF数据:
Document(page_content="冷藏区温度调节步骤:1.按下设置键...", metadata={"source": "pdf", "page": 12})
- 数据库数据:
Document(page_content="订单10086:用户购买2024款冰箱,反馈制冷慢", metadata={"source": "sql", "order_id": "10086"})
3. 融合检索:跨来源筛选相关信息
加载并标准化后,需将多源Document
存入向量数据库,实现跨来源的相关性检索。当用户提问时,同时从网页、PDF、数据库等来源中找到相关信息。
具体操作示例:多源信息存入向量库并检索
from langchain.embeddings import OpenAIEmbeddings
from langchain.vectorstores import Chroma# 合并多源Document
all_docs = web_docs + pdf_docs + sql_docs# 存入向量数据库(统一嵌入)
embeddings = OpenAIEmbeddings()
vector_db = Chroma.from_documents(documents=all_docs,embedding=embeddings,persist_directory="./multi_source_db"
)# 用户提问:“2024款冰箱制冷慢怎么解决?”
query = "2024款冰箱制冷慢怎么解决?"
# 跨来源检索相关信息(可能来自PDF的故障排除、网页的产品说明、数据库的用户反馈)
relevant_docs = vector_db.similarity_search(query, k=5)# 打印检索结果的来源
for doc in relevant_docs:print(f"来源:{doc.metadata['source']},内容:{doc.page_content[:50]}...")
关键技巧:利用元数据过滤特定来源
# 只检索PDF和数据库中的相关信息(排除网页)
relevant_docs = vector_db.similarity_search(query,k=5,filter={"source": {"$in": ["pdf", "sql"]}} # 元数据过滤
)
二、多模态上下文管理:整合跨类型信息
多模态信息指文本、图片、音频、视频、表格等不同类型的数据。LangChain的核心思路是将非文本信息转换为文本描述(或结构化数据),再与文本信息统一管理。
1. 图片信息处理:从图像到文本描述
图片(如产品图片、图表、截图)需转换为文本描述才能被大模型理解,常用工具包括OCR(提取文字)和图像描述模型(生成内容说明)。
具体操作示例:处理产品图片和图表
from langchain.document_loaders import UnstructuredImageLoader
from langchain.chat_models import ChatOpenAI
from PIL import Image# 1. 用OCR提取图片中的文字(如产品参数标签)
image_loader = UnstructuredImageLoader("fridge_label.jpg", mode="elements") # mode="elements"保留文字位置
image_docs = image_loader.load()
# 结果:Document(page_content="型号:FR-2024 功率:150W 容量:500L", metadata={"source": "image"})# 2. 用GPT-4V生成图片内容描述(如冰箱外观、功能示意图)
def describe_image(image_path: str) -> str:llm = ChatOpenAI(model_name="gpt-4-vision-preview", max_tokens=300)image = Image.open(image_path)response = llm.predict(f"描述这张图片的内容,重点说明冰箱的外观和功能:{image}")return response# 生成图片描述并封装为Document
image_desc = describe_image("fridge_diagram.jpg")
image_desc_doc = Document(page_content=image_desc, # 如:"图片展示2024款冰箱的内部结构,左侧为冷藏区,右侧为冷冻区,顶部有智能控制面板..."metadata={"source": "image", "type": "diagram"}
)
2. 音频/视频信息处理:从语音到文本
音频(如用户语音咨询)或视频(如产品演示视频)需先转换为文本,再进入上下文管理流程。
具体操作示例:音频转文字
import openai
from langchain.document_loaders import AudioLoader# 1. 用OpenAI Whisper将音频转为文字(如用户语音反馈)
def audio_to_text(audio_path: str) -> str:audio_file = open(audio_path, "rb")transcript = openai.Audio.transcribe("whisper-1", audio_file)return transcript["text"]# 2. 封装为Document
audio_text = audio_to_text("user_feedback.wav") # 如:"我的冰箱冷藏区温度调不低,已经按了设置键但没反应"
audio_doc = Document(page_content=audio_text,metadata={"source": "audio", "user_id": "123"}
)# 视频处理:先提取音频或关键帧,再分别转文字(音频用Whisper,帧图片用GPT-4V)
3. 表格信息处理:从结构化表格到文本
表格(如产品参数表、订单统计表)需转换为“文本描述+结构化数据”,既保留数值信息,又便于模型理解语义。
具体操作示例:处理Excel表格
from langchain.document_loaders import UnstructuredExcelLoader
import pandas as pd# 1. 加载Excel表格并提取内容
excel_loader = UnstructuredExcelLoader("fridge_specs.xlsx")
excel_docs = excel_loader.load() # 表格内容转为文本描述# 2. 同时保留结构化数据(便于数值对比)
df = pd.read_excel("fridge_specs.xlsx")
table_structured = df.to_dict(orient="records") # 转为字典列表
# 封装为Document(同时包含文本描述和结构化数据)
table_doc = Document(page_content=f"产品参数表:{str(table_structured)}", # 文本化metadata={"source": "excel", "structured_data": table_structured} # 保留结构化数据
)
4. 多模态信息整合与检索
将转换后的图片描述、音频文字、表格文本等与普通文本信息合并,存入向量数据库,实现跨模态检索。
具体操作示例:多模态信息检索
# 合并多模态Document(文本+图片描述+音频文字+表格)
multi_modal_docs = pdf_docs + [image_desc_doc, audio_doc, table_doc]# 存入向量库
vector_db = Chroma.from_documents(documents=multi_modal_docs,embedding=embeddings
)# 用户提问:“根据图片,2024款冰箱的控制面板在哪里?”
query = "根据图片,2024款冰箱的控制面板在哪里?"
# 检索到图片描述Document(含控制面板位置信息)
relevant_docs = vector_db.similarity_search(query, k=1)
print(relevant_docs[0].page_content) # 输出图片描述中关于控制面板位置的内容
三、核心工具与最佳实践
- 统一格式工具:
Document
类是多源/多模态整合的核心,务必通过metadata
记录来源、类型等信息,便于后续过滤和追溯。 - 转换工具链:
- 图片:
UnstructuredImageLoader
(OCR) +GPT-4V
(内容描述); - 音频:
Whisper
(语音转文字); - 视频:
ffmpeg
(提取音频/帧) + 音频/图片转换工具; - 表格:
UnstructuredExcelLoader
(文本化) +pandas
(结构化保留)。
- 图片:
- 检索优化:
- 多源检索时,用元数据
filter
优先获取高可信度来源(如官方手册>用户评论); - 多模态检索时,对图片/音频描述添加特殊标记(如
[图片描述]
),便于模型区分信息类型。
- 多源检索时,用元数据
总结
LangChain的多模态/多源上下文管理通过“加载→转换→标准化→融合检索”四步实现:
- 多源:用
Loader
加载不同渠道数据,Document
统一封装,向量库跨源检索; - 多模态:将图片、音频等非文本信息转为文本描述,与文本信息一起管理。
这种方式让大模型能综合利用各类信息,尤其适合复杂场景(如结合产品手册、用户语音反馈、实拍图片解答问题),大幅提升回答的全面性和准确性。