RAG 開發(fā)四大痛點(diǎn)及解決方案 原創(chuàng)
1、痛點(diǎn)1:知識(shí)缺失
知識(shí)庫(kù)缺乏必要的上下文信息,導(dǎo)致 RAG 系統(tǒng)在無(wú)法找到確切答案時(shí),可能會(huì)提供模棱兩可的錯(cuò)誤信息,而不是直接表明其無(wú)知。這種情況下,用戶可能會(huì)接收到誤導(dǎo)性的信息,從而感到沮喪。針對(duì)這一問(wèn)題,有以下兩種解決方案:
解決方案一:優(yōu)化數(shù)據(jù)質(zhì)量
“垃圾輸入,垃圾輸出?!?若源數(shù)據(jù)質(zhì)量不佳,比如:存在相互矛盾的信息,即便是再完美的 RAG 流程也無(wú)法從劣質(zhì)數(shù)據(jù)中提煉出有價(jià)值的知識(shí)。以下提出的解決方案不僅能解決這一難題,還能應(yīng)對(duì)本文中提到的其他問(wèn)題。高質(zhì)量的數(shù)據(jù)是確保 RAG 流程順暢運(yùn)行的關(guān)鍵。
以下是一些常見的數(shù)據(jù)優(yōu)化策略:
1. 清除噪音和無(wú)關(guān)信息:包括移除特殊字符、停用詞(比如:“the”和“a”等常見詞匯)以及 HTML 標(biāo)簽。
2. 識(shí)別并修正錯(cuò)誤:涉及拼寫錯(cuò)誤、打字錯(cuò)誤和語(yǔ)法錯(cuò)誤。拼寫檢查工具和語(yǔ)言模型等資源對(duì)此很有幫助。
3. 去除重復(fù)數(shù)據(jù):消除可能干擾檢索過(guò)程的重復(fù)或相似記錄。
解決方案二:優(yōu)化提示詞設(shè)計(jì)
由于知識(shí)庫(kù)信息不足,系統(tǒng)可能會(huì)提供看似合理卻錯(cuò)誤的答案。在這種情況下,優(yōu)化提示詞可以顯著提升系統(tǒng)表現(xiàn)。通過(guò)使用“若你不確定答案,請(qǐng)表明你不知道”等提示詞,可以引導(dǎo)大模型承認(rèn)其局限,并更清晰地表達(dá)不確定性。雖然這不能確保答案的絕對(duì)正確性,但在數(shù)據(jù)優(yōu)化之后,設(shè)計(jì)恰當(dāng)?shù)奶崾驹~是提高系統(tǒng)透明度的有效手段之一。
2、痛點(diǎn)2:更相關(guān)的知識(shí)沒(méi)有檢索出來(lái)
在初步檢索階段知識(shí)未能被檢索出來(lái)。關(guān)鍵的文檔可能沒(méi)有在檢索組件給出的初步結(jié)果中,導(dǎo)致正確答案被遺漏,大模型因此無(wú)法提供精確的響應(yīng)。研究指出:“問(wèn)題的答案其實(shí)就藏在文檔里,只是因?yàn)樗琶粔蚋?,所以沒(méi)有被呈現(xiàn)給用戶。”針對(duì)這一問(wèn)題,有以下兩種解決方案:
解決方案一:調(diào)整 chunk_size 和 similarity_top_k 超參數(shù)
在 RAG 模型中,chunk_size 和 similarity_top_k 是控制數(shù)據(jù)檢索效率和準(zhǔn)確性的兩個(gè)關(guān)鍵參數(shù)。對(duì)這些參數(shù)的調(diào)整會(huì)影響到計(jì)算效率和信息檢索質(zhì)量之間的平衡。
解決方案二:Rerank 重排序
在將檢索結(jié)果傳遞給大語(yǔ)言模型(LLM)之前對(duì)其進(jìn)行重新排序,可以顯著增強(qiáng) RAG 系統(tǒng)的性能。LlamaIndex 的筆記揭示了有無(wú)重新排序的差別:
- 未經(jīng)重新排序直接獲取前兩個(gè)節(jié)點(diǎn)的檢索結(jié)果,導(dǎo)致結(jié)果不夠精確。
- 相比之下,檢索前 10 個(gè)節(jié)點(diǎn)并利用 CohereRerank 進(jìn)行重排序,然后僅返回前兩個(gè)節(jié)點(diǎn),可以實(shí)現(xiàn)更精確的檢索。
import os
from llama _ index.postprocessor.cohere _ rerank import CohereRerank
api _ key = os.environ [ "COHERE _ API _ KEY" ]
cohere _ rerank = CohereRerank ( api _ key=api _ key , top _ n=2 ) # return top 2 nodes from reranker
query _ engine = index.as _ query _ engine (
similarity _ top _ k=10 , # we can set a high top _ k here to ensure maximum relevant retrieval
node _ postprocessors= [ cohere _ rerank ], # pass the reranker to node _ postprocessors
)
response = query _ engine.query (
"What did Sam Altman do in this essay?" ,
)
3、痛點(diǎn)3:格式錯(cuò)誤
輸出格式不正確。當(dāng)大語(yǔ)言模型(LLM)未能遵循以特定格式(比如:表格或列表)提取信息的指令時(shí),我們提出了以下四種解決方案:
解決方案一:優(yōu)化提示詞設(shè)計(jì)
為了改善提示詞并解決這一問(wèn)題,可以采取以下幾種策略:
- 明確指出格式要求。
- 簡(jiǎn)化指令并突出關(guān)鍵術(shù)語(yǔ)。
- 提供具體示例。
- 對(duì)提示詞進(jìn)行迭代并追加相關(guān)問(wèn)題。??
解決方案二:輸出解析方法
輸出解析可以用于以下目的,以確保獲得期望的輸出格式:
- 為每個(gè)提示/查詢提供格式化指南。
- 對(duì)LLM的輸出進(jìn)行“解析”處理。??
以下是一個(gè)使用 LangChain 輸出解析模塊的示例代碼片段,該模塊可在LlamaIndex 中應(yīng)用。
from llama _ index.core import VectorStoreIndex , SimpleDirectoryReader
from llama _ index.core.output _ parsers import LangchainOutputParser
from llama _ index.llms.openai import OpenAI
from langchain.output _ parsers import StructuredOutputParser , ResponseSchema
# load documents , build index
documents = SimpleDirectoryReader ( " .. /paul _ graham _ essay/data" ).load _ data ( )
index = VectorStoreIndex.from _ documents ( documents )
# define output schema
response _ schemas = [
ResponseSchema (
name= "Education" ,
description= "Describes the author's educational experience/background." ,
) ,
ResponseSchema (
name= "Work" ,
description= "Describes the author's work experience/background." ,
) ,
]
# define output parser
lc _ output _ parser = StructuredOutputParser.from _ response _ schemas (
response _ schemas
)
output _ parser = LangchainOutputParser ( lc _ output _ parser )
# Attach output parser to LLM
llm = OpenAI ( output _ parser=output _ parser )
# obtain a structured response
query _ engine = index.as _ query _ engine ( llm=llm )
response = query _ engine.query (
"What are a few things the author did growing up?" ,
)
print ( str ( response ))
解決方案三:Pydantic 程序
Pydantic 程序是一個(gè)多功能的框架,它能夠?qū)⑤斎氲淖址D(zhuǎn)換成結(jié)構(gòu)化的 Pydantic 對(duì)象。LlamaIndex 提供了幾種不同類型的 Pydantic 程序:
LLM 文本補(bǔ)全 Pydantic 程序:這類程序負(fù)責(zé)處理輸入的文本,并將其轉(zhuǎn)換成用戶自定義的結(jié)構(gòu)化對(duì)象,這個(gè)過(guò)程結(jié)合了文本補(bǔ)全 API 和輸出解析。
LLM 函數(shù)調(diào)用 Pydantic 程序:這些程序通過(guò)使用 LLM 函數(shù)調(diào)用 API 來(lái)處理輸入文本,并將其轉(zhuǎn)換成用戶指定的結(jié)構(gòu)化對(duì)象。
預(yù)制 Pydantic 程序:這些程序設(shè)計(jì)用于將輸入文本轉(zhuǎn)換成預(yù)定義的結(jié)構(gòu)化對(duì)象。
以下是一個(gè)使用 OpenAI 的 Pydantic 程序的示例代碼片段:
from pydantic import BaseModel
from typing import List
from llama _ index.program.openai import OpenAIPydanticProgram
# Define output schema ( without docstring )
class Song ( BaseModel ) :
title : str
length _ seconds : int
class Album ( BaseModel ) :
name : str
artist : str
songs : List [ Song ]
# Define openai pydantic program
prompt _ template _ str = """\
Generate an example album , with an artist and a list of songs.\
Using the movie { movie _ name } as inspiration.\
"""
program = OpenAIPydanticProgram.from _ defaults (
output _ cls=Album , prompt _ template _ str=prompt _ template _ str , verbose= True
)
# Run program to get structured output
output = program (
movie _ name= "The Shining" , description= "Data model for an album."
)
解決方案四:OpenAI JSON 模式
通過(guò)OpenAI的 JSON 模式,我們可以將`response_format`設(shè)置為`{ "type": "json_object" }`,從而激活響應(yīng)的 JSON 模式。當(dāng)啟用 JSON 模式后,大模型將被限制僅生成可以解析為有效 JSON 對(duì)象的字符串。JSON 模式確保了輸出格式的強(qiáng)制性,但它并不支持根據(jù)特定模式進(jìn)行驗(yàn)證。
4、痛點(diǎn)4:輸出不完整
回答缺失完整性。雖然部分答復(fù)沒(méi)有錯(cuò)誤,但它們并未包含所有必要的細(xì)節(jié),即便這些信息在上下文中是可獲取的。比如:當(dāng)有人提問(wèn):“文檔A、B和C中討論的主要議題是什么?”為了確?;卮鸬耐暾?,單獨(dú)對(duì)每份文檔進(jìn)行查詢可能更為有效。
解決方案一:查詢變換
在最初的 RAG 方法中,比較類型的問(wèn)題表現(xiàn)尤為不佳。提升 RAG 推理能力的一個(gè)有效方法是引入查詢理解層——在實(shí)際將查詢向量存入存儲(chǔ)之前進(jìn)行查詢變換。以下是四種不同的查詢變換方法:
1. 路由:保留原始查詢,并識(shí)別出與之相關(guān)的合適工具子集。隨后,將這些工具指定為合適的選項(xiàng)。
2. 查詢重寫:保留選定的工具,但以不同方式重新構(gòu)建查詢,以便在同一工具集中應(yīng)用。
3. 子問(wèn)題分解:將查詢拆分為幾個(gè)更小的問(wèn)題,每個(gè)問(wèn)題針對(duì)不同的工具,由其元數(shù)據(jù)來(lái)決定。
4. ReAct Agent 工具選擇:基于原始查詢,確定使用的工具,并制定在該工具上運(yùn)行的特定查詢。
請(qǐng)參考以下示例代碼片段,了解如何應(yīng)用 HyDE(假設(shè)文檔嵌入)這一查詢重寫技術(shù)。給定一個(gè)自然語(yǔ)言查詢,首先生成一個(gè)假設(shè)文檔/答案。接著,使用這個(gè)假設(shè)文檔進(jìn)行嵌入搜索,而不是使用原始查詢。
# load documents , build index
documents = SimpleDirectoryReader ( " .. /paul _ graham _ essay/data" ).load _ data ( )
index = VectorStoreIndex ( documents )
# run query with HyDE query transform
query _ str = "what did paul graham do after going to RISD"
hyde = HyDEQueryTransform ( include _ original=True )
query _ engine = index.as _ query _ engine ( )
query _ engine = TransformQueryEngine ( query _ engine , query _ transform=hyde )
response = query _ engine.query ( query _ str )
print ( response )
本文轉(zhuǎn)載自公眾號(hào)玄姐聊AGI 作者:玄姐
原文鏈接:??https://mp.weixin.qq.com/s/YQJ4CXKPNDM9XW1OpFrN8g??
