问题背景:

在企业arg项目中,针对文档内容存在图片,让LLM去完整返回是一个令人头痛的问题。

例如当一个文档中有这样一块知识:

Q:在XX系统下单功能流程是怎样的?

A: 步骤一:下单流程:![图1](https://oss.xxx.com/pay_1.png)

       步骤二:支付接口交互:![图2](https://oss.xxx.com/pay_2.png)

       步骤三:回调更新: ![图3](https://oss.xxx.com/pay_3.png)

针对这种知识文档,当向量检索到后即使完整的内容全部返回给大模型,大模型针对知识的输出结果也是五花八门。结果大概会是这样的:

1、三个步骤的文字内容都有,但是只有其中一个步骤的图片;

2、步骤一的图片放在了步骤三,而步骤一内容直接没有图片。 =>  图片和对应内容错乱了;

3、只有步骤一和步骤二的内容和图片,缺失步骤三;

看到上面三个例子,我们大概知道了,大模型返回的知识结果极不稳定。究其原因就是文本大模型本身不具备多模态的能力,无法针对图片链接去进行正确的判断;同时还有一个重要的原因就是LLM 生成阶段是“基于注意力和概率分布”的,不是精确模板式输出。

解决方案:

下面我们通过以下几个方式去进行优化,降低LLM生成结果不完整和“货不对板”的问题

1、针对内容和图片,为图片赋予一个根据内容相关的名称,降低大模型输出时无法判断图片内容导致的图片和内容错乱问题。例如:![下单流程图](https://oss.xxx.com/pay_1.png)

2、调整提示词,如:如果上下文中包含 image_url,请将它以 Markdown 图片语法形式输出。

3、检索和生成阶段双重约束,在检索层将多图分块拆分存储,不要让一个chunk中包含多张图片。每张图独立成块,这样模型检索到时更容易逐个引用。例如将文档知识的每个步骤分为一个chunk块,这样的分段上下文每段图片与对应文本的语义是强绑定的,attention 不会混乱。
而在生成层:通过提示词显式要求模型输出所有图片。如:1.回答问题时必须引用所有与该内容相关的图片。2.每个图片都以 Markdown 语法形式输出。3. 若有多张图片,请在描述中逐一解释。 通过这个方式可以提高检索粒度和准确性,让模型生成时更精确地关联到对应图片。

针对第三点优化,引入了一个新的问题,如果在检索过程中,几个步骤的块不是连续的,中间容易穿插其他知识分块,或者步骤分块缺失。 这也是rag落地中最容易踩坑的地方,引入解决方案后也出现了新的问题。这一块我们企业是这样处理的:

在存储知识内容到向量库时为每个 chunk 加入元数据,记录文档知识chunk索引文档来源id,检索命中某个 chunk 时,自动向前后扩展相邻块,同时在召回到多个文档知识块时,对文档知识块根据文档来源chunk索引顺序重排序,保证获取到的知识具有连续性。

4、对每个分块增加元数据标签,在知识落库阶段为每个知识分块利用LLM进行打标签,生成的标签存储数据库中,让LLM每次基于现有的标签库进行打标签,只有在标签库都不满足的情况下才生成新的标签。

因为将一个知识文档进行切分为多个分块,可能会导致问题只在第一个分块中,而后几个步骤的分块并没有携带问题信息。例如:

问题:如何更换打印机墨盒?
步骤:
1. 打开前盖。步骤 1 操作图
2. 拔出旧墨盒。步骤2操作图
3. 插入新墨盒。步骤3操作图
4. 关闭盖子。

针对这类问题我们采用这个方案解决。

5、采用上下文策略,为每个分块内容增加一个简短摘要或关键问句引用,这样可以保证用户提问时模型只召回了部分块也不会丢失原问题上下文。如:

chunk_1:[解释如何更换打印机墨盒操作] + 步骤1 + 图片1

chunk_2:[解释如何更换打印机墨盒操作] + 步骤2 + 图片2

chunk_3:[解释如何更换打印机墨盒操作] + 步骤3 + 图片3 + 步骤4

6、根据企业场景,可以通过OCR、视觉理解模型对图片内容提取其视觉特征,为图片进行描述从而提升模型生成效果。例:

我们要如何了解系统架构设计:

![系统架构设计图](https://oss.xxx.com/pay_1.png)

>  描述:一个清晰的系统架构图,显示了前端、后端、数据库和缓存层之间的交互关系,采用微服务架构设计。

到这里针对rag图文输出效果问题,在采用上述方案后基本可以满足预期了。

Logo

中国智能体开发者社区,聚焦智能体与大模型开发,提供前沿资讯、实用工具链、开源项目及行业案例。通过技术沙龙、开发者大赛等活动,促进经验交流与协作,助力开发者快速构建创新智能应用。

更多推荐