如何科學評估RAG應用?RAG應用中的四個常見問題及方案探討【下】

2024年2月6日 20点热度 0人点赞

專註LLM深度應用,關註我不迷路

在前面的兩篇關於RAG優化的文章中,我們直接聚焦在應用本身的輸出:如何提升語意檢索精度、處理多模態知識等。本篇我們將關註一個重要工程問題:當我們了構建了一個完整的RAG應用以後,在交付生產之前,如何對應用作一個科學的評估(Evaluation),以發現問題並確保我們有信心將其投入生產?

為什麼需要評估RAG應用

當前,借助於開源框架,比如LangChain或者LlamaIndex;或者一些RAG應用SaaS平臺,可以在較短的時間內快速構建一個RAG應用;如果您的企業一直都有較完善的知識管理與維護平臺及機制,這個時間或許還可以進一步縮短。但是正如我們之前提到的大模型在真實的企業應用場景中的一些挑戰:

  • 大模型的輸出不確定性會帶來一定的不可預知性,一個RAG應用在投入生產之前需要科學的測試以衡量這種不可預知性
  • RAG應用上線後的持續維護增強中,需要科學、快速、可復用的手段來衡量其改進,比如回答的置信度是上升了10%還是下降了5%?
  • RAG應用中的“外掛”知識庫是動態的,在不斷的維護過程中,可能會產生新的相互幹擾,因此,定期的檢測與評估是必要的
  • 如何在遍地的商業與開源大模型選擇最適合企業的模型?或者如何知道大模型一次版本升級對我的RAG應用產生了多大影響?

傳統的軟件開發在交付之前必然會經過完整的測試,借助科學的用例、腳本與工具來評估軟件的輸入輸出是否符合預期。基於大模型的RAG應用同樣也需要這樣的過程,但是不同的是,傳統應用軟件的輸出大多是確定且易於衡量的,而RAG應用中的輸入輸出都是自然語言,評估其相關性與準確性等都無法通過簡單的觀察判斷,需要借助工具與評估模型來完成。

本文介紹如何借助開源的RAGAS評估框架,來科學地評估RAG應用的一些關鍵指標,以實現指標驅動開發(MDD,Metrics-Driven Development)的願景,確保RAG應用的持續監控與增強。

了解RAGAS框架及指標體系

RAGAs (Retrieval-Augmented Generation Assessment)是一個針對大模型RAG應用的評估框架。借助它你可以快速對構建的RAG應用做性能評估,以建立用於持續改進的量化指標體系。

RAGAS需要的輸入信息

RAGAS評估需要的輸入信息包括以下四項:

  • question:作為 RAG 應用的輸入,通常是用戶問題。
  • answer:RAG應用的輸出結果,比如問題的答案。
  • contexts:從“外掛”知識庫語義檢索出的相關知識。
  • ground_truths:人類需要標註/提供的事實即正確答案。

因此,基於這些信息的評估流程大致如下:

組件級評估

組件評估是對構成RAG的兩個重要組件進行獨立評估,並生成相關指標,用於更細致地觀察與分析問題所在,從而進行優化與增強。任何RAG應用都必然包含的兩個組件:

檢索器組件(Retriever):代表RAG中的“R”。用於從外部向量數據庫中通過語意檢索生成與Question最相關的知識上下文,提供給大模型用於生成回答。

生成器組件(Generator):代表RAG中的“G”。也就是大模型根據檢索到的相關上下文、輸入問題及指令,生成輸出回答。

RAGAS提供了對RAG應用的這兩個組件評估的一系列標準指標(Metrics):

主要包括如下幾個關鍵的評估指標,在後續的例子中會進一步闡述如何觀察與解釋指標:

名稱

相關輸入

解釋

忠實度

faithfulness

answer

contexts

答案與檢索出的上下文的一致性。即答案內容是否能從檢索出的context中推理出來。

答案相關性

Answer

relevancy

answer

question

答案與用戶問題的相關性。即答案是否完整且不冗餘地回答了輸入問題,此次不考慮答案的正確性。

上下文精度

Context

precision

contexts

ground-truths

檢索出的相關上下文中與正確答案相關的條目是否排名較高。

上下文召回率

Context

recall

contexts

ground-truths

檢索出的相關上下文與正確答案之間的一致程度。即正確答案的內容是否能夠歸因到上下文。

上下文相關性

Context

relevancy

contexts

question

檢索出的上下文與用戶問題之間的相關性。即上下文中有多少內容是和輸入question相關。

端到端評估

所謂端到端評估是對RAG應用的端到端性能進行評估,即從用戶體驗的角度感知到的RAG的整體性能指標。主要包括兩個指標:

回答的語意相似度:簡單地說,就是輸出的答案與你提供的“標準答案”之間的語意相似度,在0到1之間,分數越高表示生成的答案與正確答案越一致。

回答的正確性:回答的正確性是一個更籠統的指標,涵蓋了回答的語意相似度與事實相似度,並可對這兩方面設定權重,計算出一個在0到1之間的正確性。

RAGAS評估實測

本部分我們使用RAGAS來評估一個最小粒度構建的RAG應用,以直觀的展示與了解RAGAS的應用與其指標,此處以組件級評估做例子,端到端評估方法類似。

準備工作

RAGAS需要應用到的python包有langchain,openai,ragas,其他則根據自身應用情況而定。請使用pip自行安裝。另外,由於需要使用OpenAI模型作為評估使用,請確保擁有OpenAI賬戶及API-key。

應用構建

此處我快速構建一個簡單的RAG應用作為測試,借助Langchain可以輕易實現:首先,準備用於構建的私有知識數據(此處用一個包含若幹問答的test.csv),加載後通過embedding模型生成向量,並進入向量數據庫(Chroma):

#加載測試知識test.csv
loader = CSVLoader(
file_path='test.csv',
encoding="utf-8",
csv_args={'delimiter':',','quotechar':'"','fieldnames':['q','a']})
data = loader.load()
#embedding進入向量數據庫(chroma)
embeddings = OpenAIEmbeddings()
chroma_client =chromadb.PersistentClient(path='./chroma_db')
vs = Chroma.from_documents(
documents = data,
embedding = embeddings,
client = chroma_client,
collection_name = 'test_collection')

接下來,構建一個RAG簡單應用,借助Langchain的Chain組件實現:

#檢索器
retriever = vs.as_retriever()
#大模型
llm = ChatOpenAI(model_name="gpt-3.5-turbo-1106",temperature=0)
#prompt模板
template = """您是一個用於問答任務的助手,請使用下面提供的上下文來回答問題,並保持簡潔的答案。
Question: {question}
Context: {context}
Answer:
"""
prompt = ChatPromptTemplate.from_template(template)
#RAG生成器
rag_chain = (
{"context": retriever, "question": RunnablePassthrough()}
| prompt
| llm
| StrOutputParser()
)
#簡單測試下結果
rag_chain.invoke('如何進入國稅電子稅務局報送匯算清繳?')

應用評估

現在,我們需要準備一個評估數據集。RAGAS框架需要的唯一人類工作就是準備question與ground_truths數據對,即問題與正確答案,然後讓已經構建的RAG應用來生成另外兩個必需的信息:answer,contexts,即推理的答案與檢索出的上下文。

在真實應用評估時,測試數據集的準備最好是從真實的生產應用場景中獲得,比如從現有的在線咨詢或者搜索歷史中獲得用戶的真實問題和正確答案,且需要人工來檢查確認,這在首次準備時會有一定工作量。

questions = [
"小規模轉一般納稅人之後,企業的稅務登記信息會變更嗎(比如企業的納稅人識別號,公司的納稅人名稱)?",
"生產企業外購貨物直接出口可以享受出口退稅嗎?",
"總公司與重點人群簽訂勞動合同,員工實際在分公司工作,並由分公司為其繳納社保,應當由總公司還是分公司享受稅收政策?",
"中國首都在哪裡,有哪些名勝古跡可以參觀呢?"
]
ground_truths = [["小規模轉一般納稅人以後,不會變更公司的稅務登記信息的,隻是企業的資格認定信息中會有一般納稅人資格認定。"],
["生產企業外購貨物直接出口是否享受出口退稅首先看企業是否屬於列名生產企業出口非自產貨物適用免抵退政策,具體情況詳見相關政策。"],
["對於與總公司簽訂勞動合同,分公司繳納社保的情形,應當由總公司享受稅收政策。"],
["中國的首都是北京。北京有頤和園、長城、故宮等著名的風景名勝區。"]]

最後,我們借助RAGAS框架評估生成簡單的評估報告。這裡我們導入了四個ragas的指標,然後調用evaluate方法並簡單的傳入指標和數據集即可。

answers = []
contexts = []
# 生成answer和context
for query in questions:
answers.append(rag_chain.invoke(query))
contexts.append([docs.page_content for docs in retriever.get_relevant_documents(query)])
# 構建ragas需要的輸入信息
data = {
"question": questions,
"answer": answers,
"contexts": contexts,
"ground_truths": ground_truths
}
#開始評估
dataset = Dataset.from_dict(data)
result = evaluate(
dataset = dataset,
metrics=[
context_precision,
context_recall,
faithfulness,
answer_relevancy,
],
)
#評估結果輸出到excel
df = result.to_pandas()
df.to_excel('eval_result.xlsx', index=False)

評估完成。可以在輸出結果中看到如下示例的RAGA分數:

借助評估報告,我們可以觀察指標並做簡單解讀:

  • 上下文精度(context_precision)這個指標衡量能夠推導出正確答案的上下文的排名是否較高。此處第4個問題我們故意設定了不相幹的問題,所以檢索出的上下文中無法推導出正確答案,導致得分為0。這通常說明導入知識庫涵蓋范圍不足、或者雖然能夠檢索相關知識,但是卻無法推導出正確答案,可能存在知識錯誤情況。
  • 上下文召回(context_recall):這個指標衡量檢索出的上下文與正確答案的相關性和一致性。這裡最後的不相關問題的召回率也是1,這可能是由於測試中我們把語義相似檢索的閥值設置比較低,導致檢索了一批語義距離較遠、攜帶內容過多的context,誤導了ragas(需進一步確認)。
  • 忠實度(faithfulness)這個指標說明生成的答案(註意不是正確答案)是否能從檢索出上下文推導出。和context_precision一樣,由於第4個問題是個不相幹的問題,上下文無法推導出最後的答案,所以得分0。
  • 如果這裡得分為0或者得分較低,但仍然獲得了答案。就說明獲得的答案全部或者部分由大模型自己“編造”生成(當然也可能是對的),而不是從上下文推理獲得。當然,你可以在提示詞上要求大模型這種情況拒絕回答。
  • 答案相關性(answer_relevancy)這個指標說明生成的答案是否完整且簡潔地回答了問題,但不考慮答案是否正確。這裡的指標較高,說明最後的輸出答案還是涵蓋了問題中需要回答的關鍵點,盡管這些答案不一定是從context得出,也不一定正確。

與LangSmith配合使用

LangSmith是Langchain團隊構建生產級大模型應用的平臺,專註於LLM應用的跟蹤、調試與評估階段。由於RAGAS在底層使用了Langchain,因此可以很方便地與langsmith集成,方便跟蹤evaluator的運行過程。

如果需要設置langsmith,隻要確保設置以下環境,然後正常運行evaluator即可:

export LANGCHAIN_TRACING_V2=true
export LANGCHAIN_ENDPOINT=https://api.smith.langchain.com
export LANGCHAIN_API_KEY=<your-api-key>
export LANGCHAIN_PROJECT=<your-project>

請從smith.langchain.com獲得自己API_KEY。運行RAGAS的evaluate之後,就可以登錄langsmith查看運行軌跡:

結束語

以上我們介紹了如何借助開源的評估框架RAGAS來驗證RAG應用的各項性能指標。大模型RAG應用的概念驗證很容易,但是要為真實的生產準備好,就需要借助這樣完整的指標體系來科學地評估與發現問題,從而能夠采取針對性的優化以增強可用性。

需要指出的是,構建一個高質量的評估數據集也是一個較復雜且工作量較大的任務。因此也有一些項目在研究無參考的指標評估方法,即無需借助人類標註數據集的自動化評估框架,讓我們拭目以待。