LangChain應用開發指南-TruLens用量化對抗幻覺 精華
在AI的發展中,大規模語言模型已經取得了令人矚目的成果,然而,隨之而來的是模型質量和不確定性的問題。如何衡量和改進模型的質量,一直是我們面臨的一個挑戰。
為了解決這些問題,我們將在這篇文章中,介紹LangChain框架和TruLens工具,它們將幫助我們評估模型的質量,提高模型質量,并能夠用量化的方法對抗不確定。
什么是TruLens
TruLens是面向神經網絡應用的質量評估工具,它可以幫助你使用反饋函數來客觀地評估你的基于LLM(語言模型)的應用的質量和效果。反饋函數可以幫助你以編程的方式評估輸入、輸出和中間結果的質量,從而加快和擴大實驗評估的范圍。你可以將它用于各種各樣的用例,包括問答、檢索增強生成和基于代理的應用。
TruLens的核心思想是,你可以為你的應用定義一些反饋函數,這些函數可以根據你的應用的目標和期望,對你的應用的表現進行打分或分類。例如:
- 定義一個反饋函數來評估你的問答應用的輸出是否與問題相關,是否有依據,是否有用。
- 定義一個反饋函數來評估你的檢索增強生成應用的輸出是否符合語法規則,是否有創造性,是否有邏輯性。
- 定義一個反饋函數來評估你的基于代理的應用的輸出是否符合道德標準,是否有友好性,是否有誠實性。
TruLens可以讓你在開發和測試你的應用的過程中,實時地收集和分析你的應用的反饋數據,從而幫助你發現和解決你的應用的問題,提高你的應用的質量和效果。你可以使用TruLens提供的易用的用戶界面,來查看和比較你的應用的不同版本的反饋數據,從而找出你的應用的優勢和劣勢,以及改進的方向。
如何在LangChain中使用TruLens來評估模型輸出和檢索質量
LangChain作為一種新的語言模型框架,它提供了一種有效的部署和管理大規模語言模型的框架。使用LangChain管理模型,不僅可以輕松部署和執行模型,還可以方便地觀察模型的內部狀態。再結合TruLens的評估工具,我們就可以對模型的質量進行深入理解和改進。
要在LangChain中使用TruLens來評估你的應用,你只需要做兩件事:
- 在你的LangChain代碼中,導入TruLens,并使用TruChain類來包裝你的LangChain對象。TruChain類是一個裝飾器,它可以讓你的LangChain對象在運行時,自動地調用TruLens的反饋函數,并記錄反饋數據。
- 在你的TruLens代碼中,指定你想要使用的反饋函數,以及你想要給你的應用的ID。你可以使用TruLens提供的內置的反饋函數,也可以自定義你自己的反饋函數。你可以為你的應用指定一個唯一的ID,這樣你就可以在TruLens的用戶界面中,根據ID來查找和比較你的應用的反饋數據。
下面是一個簡單的示例,展示了如何在LangChain中使用TruLens來評估一個問答應用:
pip install trulens_eval
# 導入LangChain和TruLens
from langchain.chains import LLMChain
from langchain.llms import OpenAI
from langchain.prompts import PromptTemplate
from langchain.prompts.chat import ChatPromptTemplate,HumanMessagePromptTemplate
from trulens_eval import TruChain,Feedback, Huggingface, Tru, OpenAI as TruOpenAI
from trulens_eval.feedback.provider.langchain import Langchain
tru = Tru()
# 定義一個問答應用的提示模板
full_prompt = HumanMessagePromptTemplate(
prompt=PromptTemplate(
template=
"Provide a helpful response with relevant background information for the following: {prompt}",
input_variables=["prompt"],
)
)
chat_prompt_template = ChatPromptTemplate.from_messages([full_prompt])
# 創建一個LLMChain對象,使用llm和chat_prompt_template作為參數
llm = OpenAI()
chain = LLMChain(llm=llm, prompt=chat_prompt_template, verbose=True)
# Initialize Huggingface-based feedback function collection class:
# Define a language match feedback function using HuggingFace.
hugs = Huggingface()
f_lang_match = Feedback(hugs.language_match).on_input_output()
# Question/answer relevance between overall question and answer.
provider = TruOpenAI()
f_qa_relevance = Feedback(provider.relevance).on_input_output()
# 使用TruChain類來包裝chain對象,指定反饋函數和應用ID
tru_recorder = TruChain(
chain,
app_id='Chain1_QAApplication',
feedbacks=[f_lang_match,f_qa_relevance])
# 使用with語句來運行chain對象,并記錄反饋數據
with tru_recorder as recording:
# 輸入一個問題,得到一個回答
chain("What is langchain?")
# 查看反饋數據
tru_record = recording.records[0]
# 打印反饋數據
print("tru_record:",tru_record)
# 啟動tru展示控制臺
tru.run_dashboard()
以RAG為例看看TruLens的評估結果
RAG(Retrieval-Augmented Generation)是一種基于LLM的應用,它可以利用檢索系統來增強LLM的生成能力。RAG的工作原理是,當給定一個輸入時,它會先從一個大規模的知識庫中檢索出一些相關的文檔,然后將這些文檔作為LLM的上下文,再使用LLM來生成一個輸出。RAG可以用于各種生成任務,例如問答、摘要、對話等。
RAG的優點是,它可以利用檢索系統來提供LLM所缺乏的知識和信息,從而提高LLM的生成質量和多樣性。RAG的缺點是,它也可能引入一些錯誤和幻覺,例如檢索出不相關或不準確的文檔,或者生成與輸入或文檔不一致的輸出。
為了評估RAG的質量和效果,我們可以使用TruLens提供的RAG三角形(RAG Triad)的評估方法。RAG三角形是由三個評估指標組成的,分別是:
- 上下文相關性(Context Relevance):評估輸入和檢索出的文檔之間的相關性,以及文檔之間的一致性。上下文相關性越高,說明檢索系統越能找到與輸入匹配的知識和信息,從而為LLM提供更好的上下文。
- 有根據性(Groundedness):評估輸出和檢索出的文檔之間的一致性,以及輸出的可信度。有根據性越高,說明LLM越能利用檢索出的文檔來生成有依據的輸出,從而避免產生幻覺或錯誤。
- 答案相關性(Answer Relevance):評估輸出和輸入之間的相關性,以及輸出的有用性。答案相關性越高,說明LLM越能理解輸入的意圖和需求,從而生成有用的輸出,滿足用戶的目的。
RAG三角形的評估方法可以讓我們從不同的角度來檢驗RAG的質量和效果,從而發現和改進RAG的問題。我們可以使用TruLens來實現RAG三角形的評估方法,具體步驟如下:
- 在LangChain中,創建一個RAG對象,使用RAGPromptTemplate作為提示模板,指定檢索系統和知識庫的參數。
- 在TruLens中,創建一個TruChain對象,包裝RAG對象,指定反饋函數和應用ID。反饋函數可以使用TruLens提供的f_context_relevance, f_groundness, f_answer_relevance,也可以自定義。
- 使用with語句來運行RAG對象,并記錄反饋數據。輸入一個問題,得到一個回答,以及檢索出的文檔。
- 查看和分析反饋數據,根據RAG三角形的評估指標,評價RAG的表現。
下面是一個簡單的示例,展示了如何在LangChain中使用TruLens來評估一個RAG問答應用:
# 導入LangChain和TruLens
from IPython.display import JSON
# Imports main tools:
from trulens_eval import TruChain, Feedback, Huggingface, Tru
from trulens_eval.schema import FeedbackResult
tru = Tru()
tru.reset_database()
# Imports from langchain to build app
import bs4
from langchain import hub
from langchain.chat_models import ChatOpenAI
from langchain.document_loaders import WebBaseLoader
from langchain.embeddings import OpenAIEmbeddings
from langchain.schema import StrOutputParser
from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain.vectorstores import Chroma
from langchain_core.runnables import RunnablePassthrough
from trulens_eval.feedback.provider import OpenAI
import numpy as np
from trulens_eval.app import App
from trulens_eval.feedback import Groundedness
# 加載文件
loader = WebBaseLoader(
web_paths=("https://lilianweng.github.io/posts/2023-06-23-agent/",),
bs_kwargs=dict(
parse_notallow=bs4.SoupStrainer(
class_=("post-content", "post-title", "post-header")
)
),
)
docs = loader.load()
# 分詞
text_splitter = RecursiveCharacterTextSplitter(chunk_size=1000, chunk_overlap=200)
splits = text_splitter.split_documents(docs)
# 存入到向量數據庫
vectorstore = Chroma.from_documents(documents=splits, embedding=OpenAIEmbeddings(
))
# 定義一個RAG Chain
retriever = vectorstore.as_retriever()
prompt = hub.pull("rlm/rag-prompt")
llm = ChatOpenAI(model_name="gpt-3.5-turbo", temperature=0)
def format_docs(docs):
return "\n\n".join(doc.page_content for doc in docs)
rag_chain = (
{"context": retriever | format_docs, "question": RunnablePassthrough()}
| prompt
| llm
| StrOutputParser()
)
# 使用TruChain類來包裝rag對象,指定反饋函數和應用ID
# Initialize provider class
provider = OpenAI()
# select context to be used in feedback. the location of context is app specific.
context = App.select_context(rag_chain)
grounded = Groundedness(groundedness_provider=provider)
# f_context_relevance, f_groundness, f_answer_relevance 定義反饋函數
# Define a groundedness feedback function
f_groundedness = (
Feedback(grounded.groundedness_measure_with_cot_reasons)
.on(context.collect()) # collect context chunks into a list
.on_output()
.aggregate(grounded.grounded_statements_aggregator)
)
# Question/answer relevance between overall question and answer.
f_qa_relevance = Feedback(provider.relevance).on_input_output()
# Question/statement relevance between question and each context chunk.
f_context_relevance = (
Feedback(provider.qs_relevance)
.on_input()
.on(context)
.aggregate(np.mean)
)
# 使用with語句來運行rag對象,并記錄反饋數據
tru_recorder = TruChain(rag_chain,
app_id='Chain1_ChatApplication',
feedbacks=[f_qa_relevance, f_context_relevance, f_groundedness])
with tru_recorder as recording:
# 輸入一個問題,得到一個回答,以及檢索出的文檔
llm_response = rag_chain.invoke("What is Task Decomposition?")
# 查看反饋數據
rec = recording.get() # use .get if only one record
# 打印反饋數據
print(rec)
# 啟動tru展示控制臺
tru.run_dashboard()
結論
在本文中,我們介紹了如何在LangChain中使用TruLens來對LLM進行評估和優化,以及如何利用TruLens的結果來量化和對抗模型的不確定性。我們通過一個文本生成的任務為例,演示了如何使用TruLens來對模型的輸出進行測量和量化,以及對模型的行為進行分析和解釋。我們還分享了一個RAG案例代碼,用實際指標說明了TruLens的評估結果。
我們也期待,未來有更多的工具和方法,可以對LLM進行更有效的評估和優化,以及更好地量化和對抗模型的不確定性。我們相信,這將有助于推動LLM的發展和應用,以及提升AI語言的水平和價值。
本文轉載自 ??AI小智??,作者: AI小智
