为什么很少有聊天机器人在回复中返回源文档的数据?
”

检索增强生成(RAG) 是生成式人工智能最早且最成功的应用之一。然而,很少有聊天机器人会同时返回源文档中的图片、表格和图表,同时提供文本回答。
在本文中,我将探讨为何构建一个可靠、真正多模态的RAG系统如此困难,尤其是对于研究论文和企业报告等复杂文档——这些文档通常包含密集的文本、公式、表格和图表。
此外,我在此提出了一种改进的多模态RAG流水线方法,能够在这些文档类型中提供一致且高质量的多模态结果。
数据集与设置
举例来说,我基于以下文档构建了一个小型多模态知识库:
完全微调的CLIP模型是高效的少点学习者 矢量画师:使用笔画风格先验的高级风格化矢量图形合成 金融服务营销策略:为科特迪瓦的木薯、玉米和大蕉价值链提供融资与加工
使用的语言模型是GPT-4o,嵌入时我用了text-embedding-3-small。
标准多模态RAG架构
理论上,多模态RAG机器人应当:
接受文本和图片查询。 回复文字和图片。 从文本和图片来源中获取上下文。
典型的管道如下:
摄入
解析与分块:将文档拆分成文本段并提取图片。 图片摘要:使用大型语言模型为每张图片生成说明或摘要。 多向量嵌入:为文本块、图像摘要以及可选的原始图像特征(例如使用CLIP)创建嵌入。
索引
将嵌入和元数据存储在矢量数据库中。
检索
对于用户查询,对以下内容进行相似性搜索: 文本嵌入(用于文本匹配) 图像摘要嵌入(用于图像相关性)
生成
使用多模态大型语言模型(LLM)综合最终响应,结合检索的文本和图像。
固有假设
这种方法假设由内容生成的图片标题或摘要,始终包含文档中出现的文本或主题的足够上下文,因此该图片是合适的回应。
在现实文件中,这种情况往往不成立。
示例:企业报告中的上下文丢失
以数据集中的“金融服务营销策略(#3)”报告为例。在其执行摘要中,有两张看起来相似的表格显示营运资金需求——一张是初级生产者(农民),一张是加工商。它们如下:


GPT-4o为第一个表格生成如下内容:
“表格概述了农业企业的各种营运资金融资选项,包括其用途和在不同情况下的可用性”
第二张表如下:
“表格概述了营运资金融资选项,详细说明了其目的以及在不同场景下对企业,特别是出口商和股票购买者的潜在适用性。”
单独看两者似乎都不错——但都未能体现生产者与加工者的区别。
这意味着对于专门询问生产者或加工者的查询,这些数据会被错误检索。还有其他表格,如资本支出(CAPEX)、融资机会(Funding opportunities),也会出现同样的问题。
对于VectorPainter论文,论文图3展示了VectorPainter的流程,GPT-4o生成了标题为“基于笔画风格提取和带有笔画级约束的风格化SVG合成框架概述”,但忽略了这实际上代表了论文的核心主题,作者称之为“VectorPainter”。
对于CLIP微调论文第3.3节定义的视觉语言相似性蒸馏损失公式,生成的说明为“表示变分Logit分布(VLD)损失的方程,定义为预测与目标Logit分布在一批输入上的Kullback–Leibler(KL)散度之和”,其中缺少视觉与语言相关性的上下文。
还需注意的是,在研究论文中,图表和图表配有作者提供的说明,但在提取过程中,这些说明并非作为图像的一部分被提取,而是作为文本的一部分。而且说明文字有时在图形上方,有时在下方。至于营销策略报告,嵌入的表格和其他图片甚至没有附带说明图。
上述情况表明,现实文档不遵循任何标准的文本、图片、表格和说明格式,这使得将上下文与图表联系起来变得困难。
新改进的多模态RAG流水线
为了解决这个问题,我做了两个关键调整。
上下文感知图像摘要
我没有让大语言模型总结图像,而是在图形前后紧接着提取文本——每个方向最多200个字符。 这样,图片说明包括:
作者提供的说明文字(如有) 赋予它意义的周围叙事
即使文档缺乏正式说明,也能提供上下文准确的摘要。
文本响应引导图像在生成时的选择
检索时,我不会直接将用户查询与图片说明匹配。这是因为用户查询通常过短,无法提供足够的上下文以便图像检索(例如;这是什么......?) 相反:
首先,利用检索的顶部文本块生成文本回复。 然后,选择两张与图片说明相匹配的文本最佳图片
这确保最终图片是根据实际回答而非仅仅是查询来选择。
以下是提取到嵌入流水线的示意图:

检索与响应生成的流程如下:

实现细节
步骤1:提取文本和图片
使用 Adobe PDF Extract API 将 PDF 解析成:
图表/表格/文件夹,包含.png文件 一个包含位置、文本和文件路径的structuredData.json文件
我发现这个API比像PyMuPDF这样的库更可靠,尤其是在提取公式和图表方面。
步骤2:创建文本文件
将 JSON 中的所有文本元素串接起来,生成原始文本语料库:
# Extract text, sorted by Page and vertical order (Bounds[1])
elements = data.get("elements", [])
# Concatenate text
all_text = []
for el in elements:
if "Text" in el:
all_text.append(el["Text"].strip())
final_text = "\n".join(all_text)
步骤3:构建图片说明:逐一浏览“structuredData.json”中的每个元素,检查该元素文件路径是否以“.png”结尾。从文档的图表文件夹加载文件,然后用LLM对图片进行质量检查。这是必要的,因为提取过程中会发现一些难以辨认、小巧的图片、页眉和页脚、公司标志等,这些都必须排除在用户回复中。
注意,我们并不是要求LLM去解释这些图像;只要评论内容是否清晰且相关,值得被纳入数据库。LLM的题目大致是:
Analyse the given image for quality, clarity, size etc. Is it a good quality image that can be used for further processing ? The images that we consider good quality are tables of facts and figures, scientific images, formulae, everyday ob jects and scenes etc. Images of poor quality would be any company logo or any image that is illegible, small, faint and in general would not look good in a response to a user query. Answer with a simple Good or Poor. Do not be verbose
接下来我们创建图片摘要。为此,在“structuredData.json”中,我们观察“.png”元素的前方和后方元素,并从每个方向收集最多200个字符,总共400个字符。这构成了图片说明或摘要。代码摘要如下:
# Collect before
j = i - 1
while j >= 0 and len(text_before) < 200:
if "Text" in elements[j] and not ("Table" in elements[j]["Path"] or "Figure" in elements[j]["Path"]):
text_before = elements[j]["Text"].strip() + " " + text_before
j -= 1
text_before = text_before[-200:]
# Collect after
k = i + 1
while k < len(elements) and len(text_after) < 200:
if "Text" in elements[k]:
text_after += " " + elements[k]["Text"].strip()
k += 1
text_after = text_after[:200]
我们对数据库中的每个文档的每个图形和表格都执行此作,并将图片说明作为元数据存储。我自己是作为“image_captions.json”文件存储的。
这一简单的改动带来了巨大变化——最终生成的说明包含了有意义的背景信息。例如,我从市场策略报告中获得的两个营运资金表的说明如下。请注意,现在的语境已经被明确区分,包括农民和加工者。
"caption": "o farmers for their capital expenditure needs as well as for their working capital needs. The table below shows the different products that would be relevant for the small, medium, and large farmers. Working Capital Input Financing For purchase of farm inputs and labour Yes Yes Yes Contracted Crop Loan* For purchase of inputs for farmers contracted by reputable buyers Yes Yes Yes Structured Loan"
"caption": "producers and their buyers b)\t Potential Loan products at the processing level At the processing level, the products that would be relevant to the small scale and the medium_large processors include Working Capital Invoice discounting_ Factoring Financing working capital requirements by use of accounts receivable as collateral for a loan Maybe Yes Warehouse receipt-financing Financing working ca"
步骤4:分块文本并生成嵌入
文档的文本文件被拆分为每块1000个字符的块,使用“langchain”中的“递归字符TextSplitter”并存储。为文本块和图片说明创建嵌入,归一化并存储为“faiss”索引
步骤5:上下文检索与响应生成
用户查询会被匹配,并检索前5段文本作为上下文。然后我们利用这些检索到的区块和用户查询,利用LLM获得文本响应。
下一步,我们根据生成的文本回复,找出与回复最接近的前两个图片(基于说明嵌入)。这与传统将用户查询与图像嵌入匹配的方式不同,能提供更好的结果。
还有最后一步。我们的图片说明基于文档中图片周围的400个字符,可能无法形成逻辑简洁的展示说明。因此,对于最终选中的两张图片,我们要求LLM将图片说明与图片一同制作简短说明,准备在最终回复中展示。
以下是上述逻辑的代码:
# Retrieve context
result = retrieve_context_with_images_from_chunks(
user_input,
content_chunks_json_path,
faiss_index_path,
top_k=5,
text_only_flag= True
)
text_results = result.get("top_chunks", [])
# Construct prompts
payload_1 = construct_prompt_text_only (user_input, text_results)
# Collect responses (synchronously for tool)
assistant_text, caption_text = "", ""
for chunk in call_gpt_stream(payload_1):
assistant_text += chunk
lst_final_images = retrieve_top_images (assistant_text, caption_faiss_index_path, captions_json_path, top_n=2)
if len(lst_final_images) > 0:
payload = construct_img_caption (lst_final_images)
for chunk in call_gpt_stream(payload):
caption_text += chunk
response = {
"answer": assistant_text + ("\n\n" + caption_text if caption_text else ""),
"images": [x['image_name'] for x in lst_final_images],
}
return response
测试结果 让我们运行本博客开头提到的查询,看看检索到的图片是否与用户查询相关。为了简化,我只打印图片及其说明,而不是文字回复。
问题1:初级生产者的贷款和营运资金需求是什么?
图1:小农、中农和大农营运资金融资选项概述。
图2:中大型农户的资本支出融资选项。

问题2:处理商的贷款和营运资金需求是什么?
图1:小规模及中大型加工商营运资金贷款产品的概述。 图2:加工层面用于机械采购和业务扩展的资本支出贷款产品。

问题3:什么是视觉语言蒸馏?
图1:用于将预训练CLIP向微调模型传递模态一致性的视觉-语言相似性蒸馏损失公式。
图2:最终目标函数,结合蒸馏损失、监督对比损失和视觉-语言相似蒸馏损失,并加平衡超参数。

问题4:什么是VectorPainter流水线?
图1:笔画样式提取和SVG合成过程概述,重点介绍笔画向量化、保持样式丢失以及基于文本提示的生成。
图2:跨栅格和矢量格式的样式转移方法比较,展示了所提方法在保持样式一致性方面的有效性。

结论
这一增强的流水线展示了上下文感知图像摘要和基于文本响应的图像选择如何显著提升多模态检索的准确性。
该方法能产生丰富多模态的答案,将文本与视觉以连贯的方式结合——这对研究助理、文档智能系统和人工智能驱动的知识机器人至关重要。
推荐学习书籍 《CDA一级教材》适合CDA一级考生备考,也适合业务及数据分析岗位的从业者提升自我。完整电子版已上线CDA网校,累计已有10万+在读~ !



雷达卡





京公网安备 11010802022788号







