MongoDB Atlas 向量搜尋的實作
MongoDB Atlas 向量搜尋提供了強大的語意檢索能力,特別適合用於開發現代人工智慧應用程式。本文將帶領你建立一個完整的向量搜尋系統,並探討如何將其整合到檢索增強生成(RAG)架構中。
設定環境與準備資料
首先,我們需要設定環境並連線到 MongoDB Atlas。這是實作向量搜尋的基礎步驟:
# 設定 MongoDB Atlas 連線字串
try:
MONGO_CONN_STR = os.environ["MONGODB_CONNECTION_STR"]
except KeyError:
MONGO_CONN = getpass.getpass("請輸入您的 MongoDB Atlas 連線字串 (按Enter): ")
接下來,我們需要從 S3 儲存桶載入資料集,將其直接讀取到 pandas DataFrame 中:
import pandas as pd
import s3fs
# 從 S3 讀取 JSON Lines 格式的資料
df = pd.read_json("https://ashwin-partner-bucket.s3.eu-west-1.amazonaws.com/movies_sample_dataset.jsonl",
orient="records", lines=True)
# 將資料儲存到本地
df.to_json("./movies_sample_dataset.jsonl", orient="records", lines=True)
# 顯示前三筆資料
df[:3]
生成向量嵌入
現在我們需要為資料集建立向量嵌入。在這個範例中,玄貓將使用 OpenAI 的嵌入 API 來處理電影資料:
import numpy as np
from tqdm import tqdm
import openai
# 合併文字與概要欄位
df['final'] = df['text'] + " Overview: " + df['overview']
# 將資料分批處理以避免超過 OpenAI API 的速率限制
step = int(np.ceil(df['final'].shape[0]/100))
embeddings_t = []
lines = []
# 將資料分成較小的批次
for x, y in list(map(lambda x: (x, x+step), list(range(0, df.shape[0], step)))):
lines += [df.final.values[x:y].tolist()]
# 為每個批次生成嵌入
for i in tqdm(lines):
embeddings_t += openai.embeddings.create(
model='text-embedding-ada-002', input=i).data
# 提取嵌入向量
out = []
for ele in embeddings_t:
out += [ele.embedding]
# 將嵌入新增到 DataFrame
df['embedding'] = out
這段程式碼將文字與概要欄位合併,然後使用 OpenAI 的 text-embedding-ada-002 模型為每筆資料生成 1536 維的向量嵌入。在實際專案中,玄貓建議將資料分批處理,以避免超過 API 的速率限制。
將資料匯入 MongoDB Atlas
接下來,我們將資料與向量嵌入一起匯入 MongoDB Atlas 集合:
from pymongo import MongoClient
import os
# 初始化 MongoDB 客戶端
mongo_client = MongoClient(os.environ["MONGODB_CONNECTION_STR"])
# 上載檔案與向量嵌入到 MongoDB Atlas 集合
output_collection = mongo_client["sample_movies"]["embed_movies"]
# 清空現有集合
if output_collection.count_documents({}) > 0:
output_collection.delete_many({})
# 插入資料
_ = output_collection.insert_many(df.to_dict("records"))
建立向量搜尋索引
要在 MongoDB Atlas 中使用向量搜尋功能,我們需要建立向量索引。以下是索引定義:
{
"fields": [
{
"type": "vector",
"numDimensions": 1536,
"path": "embedding",
"similarity": "cosine"
},
{
"type": "filter",
"path": "year"
}
]
}
這個索引定義了兩個關鍵欄位:
- 一個向量欄位,指定嵌入維度為 1536,使用餘弦相似度
- 一個過濾欄位,允許以 year 屬性進行過濾
在 MongoDB Atlas UI 中,你可以在 Vector Search 索引 JSON 編輯器中新增這些定義,系統會在指定的路徑欄位建立向量搜尋索引。
實作向量搜尋查詢
現在,讓我們建立一個函式來執行向量搜尋查詢:
def query_vector_search(q, prefilter={}, postfilter={}, path="embedding", topK=2):
# 將查詢轉換為向量嵌入
ele = openai.embeddings.create(model='text-embedding-ada-002', input=q).data
query_embedding = ele[0].embedding
# 建立向量搜尋查詢
vs_query = {
"index": "default",
"path": path,
"queryVector": query_embedding,
"numCandidates": 10,
"limit": topK,
}
# 新增預過濾條件
if len(prefilter) > 0:
vs_query["filter"] = prefilter
# 建立聚合管道
new_search_query = {"$vectorSearch": vs_query}
project = {"$project": {"score": {"$meta": "vectorSearchScore"}, "_id": 0,
"title": 1, "release_date": 1, "overview": 1, "year": 1}}
# 執行查詢,新增後過濾條件
if len(postfilter.keys()) > 0:
postFilter = {"$match": postfilter}
res = list(output_collection.aggregate([new_search_query, project, postFilter]))
else:
res = list(output_collection.aggregate([new_search_query, project]))
return res
這個函式允許我們執行向量搜尋,並結合預過濾和後過濾功能。讓我們看一個實際例子:
# 使用年份作為預過濾條件的查詢
query_vector_search("我喜歡聖誕節電影,有沒有 1990 年之後的推薦?",
prefilter={"year": {"$gt": 1990}}, topK=5)
這個查詢會找出 1990 年之後的聖誕節相關電影。我們還可以新增後過濾條件,根據相似度分數進一步篩選結果:
# 使用年份預過濾和分數後過濾的查詢
query_vector_search("我喜歡聖誕節電影,有沒有 1990 年之後的推薦?",
prefilter={"year": {"$gt": 1990}},
postfilter={"score": {"$gt": 0.905}}, topK=5)
這種方法讓我們能夠靈活地控制搜尋結果的相關性和準確性,結合向量相似度和傳統的過濾條件。
使用 LangChain 整合 MongoDB Atlas 向量搜尋
LangChain 框架提供了與 MongoDB Atlas 向量搜尋整合的便捷方式。以下是使用 LangChain 包裝類別執行向量相似度搜尋的範例:
from langchain_mongodb.vectorstores import MongoDBAtlasVectorSearch
from langchain_openai import OpenAIEmbeddings
import json
# 初始化嵌入模型
embedding_model = OpenAIEmbeddings(model="text-embedding-ada-002")
# 建立向量搜尋例項
vector_search = MongoDBAtlasVectorSearch(output_collection, embedding_model, text_key='final')
# 設定過濾條件
fquery = {"year": {"$gt": 1990}}
search_kwargs = {
"k": 5,
'filter': fquery,
}
# 建立檢索器
retriever = vector_search.as_retriever(search_kwargs=search_kwargs)
# 執行查詢
docs = retriever.invoke("我喜歡聖誕節電影,有沒有 1990 年之後的推薦?")
# 顯示結果
for doc in docs:
foo = {}
foo['title'] = doc.metadata['title']
foo['year'] = doc.metadata['year']
foo['final'] = doc.metadata['text']
print(json.dumps(foo, indent=1))
LangChain 的方法更加簡潔,特別適合開發 RAG 應用程式。它提供了一套 API 和包裝類別,可以輕鬆整合各種無伺服器 LLM 提供者(如 OpenAI)和 MongoDB Atlas 向量搜尋,用少量程式碼構建 RAG 框架。
構建檢索增強生成(RAG)架構系統
RAG 架構將傳統檢索系統與生成式 AI 結合,提供更準確、更有根據的回應。以下是 RAG 架構的關鍵元件:
檔案載入:從資料儲存中載入檔案,包括文字提取、解析、格式化和清理,為檔案分割做準備。
檔案分割:將檔案分解為較小、可管理的片段或塊。分割策略可以是固定大小分塊,也可以是考慮內容結構的人工智慧分塊。
文字嵌入:使用如 OpenAIEmbeddings、Sentence e-BERT 和 Instructor Embeddings 等技術將檔案塊轉換為向量表示。這一步對理解塊的語意內容至關重要。
向量儲存:生成的向量與檔案塊和從 MongoDB Atlas 集合中提取的其他元資料一起儲存在向量儲存中。可以透過 MongoDB Atlas UI 建立 Atlas 向量搜尋索引和 Apache Lucene 搜尋,實作簡單快速的檢索。
查詢處理:當使用者提交查詢時,系統也使用與步驟 3 相同的嵌入技術將其轉換為向量表示。
檔案檢索:檢索器元件定位並取得與查詢在語意上相似的檔案塊。MongoDB Atlas 使用分層導航小世界(HNSW)演算法執行快速最近鄰搜尋,在不犧牲檢索結果準確性的情況下檢索相關檔案。
檔案塊後處理:使用統一查詢 API 從 MongoDB 集合中檢索相關檔案塊,並可以輕鬆地進行後處理,將輸出檔案塊轉換為所需格式。
LLM 提示建立:將檢索到的檔案塊和查詢結合,為 LLM 建立連貫的背景與環境和提示。
答案生成:最後,LLM 根據提示生成回應,完成 RAG 過程。
在 RAG 系統中,主要有兩種類別:簡單(或原始)RAG 和進階 RAG。在實際應用中,這種分類別有助於處理應用程式處理的不同類別的使用者和問題。作為開發者,在決定 RAG 架構的構建模組之前,理解應用程式預期提供的功能很重要。
實際應用與效益
在現代業務環境中,組織不斷追求效率和準確性,促使他們採用尖端技術。自動化是其中的根本,特別是在處理和自動化工作流程方面。然而,傳統方法在處理大量資料和複雜任務時往往不堪重負,而人工流程則容易出錯。
MongoDB 以其資料管理和靈活架構而聞名,透過其向量搜尋和全文搜尋功能與 RAG 形成了引人注目的協同效應。透過解析 RAG 的架構細節及其組成構建模組,我們可以獲得有關構建自動化檔案處理工作流程的實用見解,充分發揮 LLM 和 MongoDB 向量搜尋的潛力。
在實作過程中,玄貓發現 MongoDB Atlas 向量搜尋在處理語意搜尋任務時表現出色。特別是在電影推薦系統中,結合向量相似度搜尋與傳統過濾條件(如發行年份)的能力,使得系統能夠提供精確與相關的推薦。
此外,LangChain 框架與 MongoDB Atlas 的整合大簡化了開發流程,讓開發者能夠快速構建強大的 RAG 應用程式。這種整合特別適合需要高效處理大量非結構化資料的企業應用場景。
MongoDB Atlas 向量搜尋的另一個顯著優勢是其彈性擴充能力。隨著資料量和查詢複雜度的增加,系統能夠保持高效的檢索效能,這對於生產環境中的 AI 應用至關重要。
在建構 RAG 系統時,選擇適當的檔案分割策略、嵌入模型和檢索機制是成功的關鍵。透過本文介紹的方法和工具,你可以開始構建自己的 RAG 應用程式,為使用者提供根據大量檔案的準確、相關的回應。
透過將 MongoDB Atlas 向量搜尋與 LLM 結合,我們能夠建立既理解使用者意圖又能從大量資料中檢索相關資訊的人工智慧系統。這種結合為各種應用場景開啟了新的可能性,從人工智慧客服到內容推薦,再到知識管理系統。
向量搜尋在AI應用中的實作
在建構RAG(檢索增強生成)架構系統時,有幾個關鍵考量點能幫助你進行有效的規劃與實作:
RAG系統規劃基礎
明確工作流程
確定你希望以RAG自動化的特定工作流程。這可能涉及問答系統、資料增強、摘要生成、推理或資訊驗證等。玄貓在實務專案中發現,客戶通常會有3-4種特定類別的常見查詢模式。
使用者經驗設計
與目標使用者群體合作,瞭解他們可能提出的查詢類別。這有助於識別使用者旅程是簡單的單狀態回應還是多狀態對話流程。
資料來源分析
評估資料來源的性質(結構化或非結構化)、位置、用途(操作性或分析性),並觀察資料模式,確定答案是否可從單一來源取得或需要從多個來源收集。
這些指標將幫助你判斷是否需要建立簡單的RAG系統或進階RAG系統,並協助確定構建架構時的重要元素。
檔案處理策略
在開發RAG應用程式前,瞭解如何處理源檔案以最大化回應準確性至關重要。以下是在將檔案存入MongoDB Atlas集合前的關鍵處理策略:
分塊或檔案切分策略
處理大型檔案時,由於語言模型(如GPT-3.5-turbo)的token限制,需要將文字分解為可管理的區塊。然而,簡單的固定大小分塊可能導致句子跨區塊分散,影響後續任務效果。
考慮以下分塊技術:
遞迴分塊
- 層級式方法:迭代地將輸入文字分解為更小的區塊
- 可自訂結構:調整條件以達到理想的區塊大小或結構
句子分割
- 基本分割:利用標點符號(句號、換行)來分割文字
- 使用NLP工具:如spaCy或NLTK提供更精確的句子分割
- 進階工具:使用小型模型預測句子邊界
專業技術
- 結構化內容處理:針對特定格式(如Markdown、LaTeX)的檔案
- 人工智慧分割:分析內容結構和層級,理解標題、清單等格式線索
選擇正確的方法取決於你的資料特性和RAG系統需求。在選擇儲存和檢索這些區塊的方案時,MongoDB Atlas提供靈活的結構和統一的查詢API。
簡單RAG系統實作
簡單RAG架構實作了一種基本方法,模型根據使用者查詢的相似度從知識函式庫索預定數量的檔案。這些檢索的檔案與查詢結合後輸入語言模型進行生成。
讓我們使用之前載入MongoDB Atlas集合的電影資料集來建立一個簡易的推薦系統。
LLM整合
以下是使用LangChain呼叫OpenAI LLM的範例程式碼:
from openai import OpenAI
client = OpenAI()
def invoke_llm(prompt, model_name='gpt-3.5-turbo-0125'):
"""
使用聊天完成API向OpenAI傳送提示並取得模型回應
"""
response = client.chat.completions.create(
model=model_name,
messages=[
{
"role": "user",
"content": prompt
}
],
temperature=0.2,
max_tokens=256,
top_p=1,
frequency_penalty=0,
presence_penalty=0
)
chatbot_response = response.choices[0].message.content.strip()
return chatbot_response
invoke_llm("This is a test")
結果:
'Great! What do you need help with?'
提示設計
提示設計是RAG系統中的關鍵環節。好的提示清晰、具體與結構化,能有效傳達使用者意圖。以下是用於私有知識函式庫的提示範例:
def get_prompt(question, context):
prompt = f"""Question: {question}
System: Let's think step by step.
Context: {context}
"""
return prompt
def get_recommendation_prompt(query, context):
prompt = f"""
From the given movie listing data, choose a few great movie
recommendations.
User query: {query}
Context: {context}
Movie Recommendations:
1. Movie_name: Movie_overview
"""
return prompt
對比實驗:有無向量搜尋
為了展示RAG相較於基礎LLM的優勢,我們先不使用向量搜尋連貫的背景與環境,再與使用後的結果進行比較:
未使用向量搜尋的查詢:
print(invoke_llm("In which movie does a footballer go completely blind?"))
結果:
"The Game of Their Lives" (2005), where the character Davey Herold, a
footballer, goes completely blind after being hit in the head during a game
使用向量搜尋提供連貫的背景與環境的查詢:
idea = "In which movie does a footballer go completely blind?"
search_response = query_vector_search(idea, prefilter={"year":{"$gt": 1990}}, postfilter={"score": {"$gt":0.8}},topK=10)
premise = "\n".join(list(map(lambda x:x['final'], search_response)))
print(invoke_llm(get_prompt(idea, premise)))
結果:
The movie in which a footballer goes completely blind is "23 Blast."
我們也可以使用相同方法生成電影推薦:
question = "I like Christmas movies, any recommendations for movies release after 1990?"
search_response = query_vector_search(question,topK=10)
context = "\n".join(list(map(lambda x:x['final'], search_response)))
print(invoke_llm(get_recommendation_prompt("I like Christmas movies, any recommendations for movies release after 1990?", context)))
這個簡單RAG系統能夠處理直接的查詢,例如「班加羅爾的客戶支援中心在哪裡?」或「在Koramangala哪些餐廳提供我喜愛的美食?」等基本問題。
進階RAG系統
進階RAG框架整合了更複雜的檢索技術、更好地融合檢索資訊,並能夠迭代最佳化檢索和生成過程。接下來將建立一個人工智慧時尚推薦引擎,能識別使用者興趣並在使用者表達購買意圖時生成相關時尚產品或配飾推薦。
這個進階RAG系統將展示以下特點:
- 使用LLM根據使用者對話生成多個可搜尋的時尚查詢
- 判斷使用者對話中是否含有購買意圖
- 開發融合階段,從多個搜尋查詢中取得向量相似度搜尋結果,並透過LLM重新排序為單一推薦集
使用者查詢處理流程如下:
- 接收使用者查詢
- 使用LLM判斷是否有購買意圖
- 若有購買意圖,生成批次搜尋詞
- 進行向量搜尋取得推薦
- 使用LLM進行排序和最佳化
- 回傳排序後的推薦結果
資料集載入
這個範例使用來自知名電子商務公司的時尚資料:
import pandas as pd
import s3fs
import os
import boto3
s3_uri= "https://ashwin-partner-bucket.s3.eu-west-1.amazonaws.com/fashion_dataset.jsonl"
df = pd.read_json(s3_uri, orient="records", lines=True)
print(df[:3])
透過整合MongoDB Atlas向量搜尋與OpenAI的能力,我們能夠建立既準確又人工智慧的推薦系統。在玄貓的實務經驗中,這種進階RAG架構能顯著提升使用者經驗,尤其是在電子商務和客戶服務等領域。
向量搜尋在RAG系統中扮演著關鍵角色,它不僅能提升回應的準確性,還能大幅減少AI模型的幻覺問題。透過結合適當的檔案處理策略、提示工程和向量搜尋技術,我們可以構建出能夠理解使用者意圖並提供精確回應的人工智慧系統。
無論是簡單的問答系統還是複雜的多階段推薦引擎,RAG架構都能靈活適應不同的應用場景,為企業提供強大的AI驅動解決方案。
開發先進的RAG架構系統:以時尚商品推薦為例
MongoDB與OpenAI向量嵌入的完美結合
在現代AI應用中,向量搜尋已成為推薦系統的關鍵技術。本文將帶領讀者深入瞭解如何將MongoDB與OpenAI向量嵌入結合,構建一個高效的時尚商品推薦系統。
資料上載至MongoDB Atlas
首先,我們需要將包含向量嵌入的檔案上載到MongoDB Atlas集合中。以下是實作這一步驟的Python程式碼:
from pymongo import MongoClient
mongo_client = MongoClient(os.environ["MONGODB_CONNECTION_STR"])
# 上載檔案及其向量嵌入到MongoDB Atlas集合
col = mongo_client["search"]["catalog_final_myn"]
col.insert_many(df.to_dict(orient="records"))
這段程式碼建立了與MongoDB的連線,然後將DataFrame中的資料以記錄形式插入到指定的集合中。執行後,我們可以在MongoDB Atlas中看到包含OpenAI嵌入向量的時尚資料集。
建立向量搜尋索引
資料上載後,下一步是建立向量搜尋索引。這可以按照第5章「向量資料函式庫詳述的步驟進行,使用以下索引對映:
{
"fields": [
{
"type": "vector",
"numDimensions": 1536,
"path": "openAIVec",
"similarity": "cosine"
}
]
}
這個索引設定指定了以下關鍵引數:
- 索引類別為「vector」
- 向量維度為1536(OpenAI嵌入的標準維度)
- 向量欄位路徑為「openAIVec」
- 使用餘弦相似度(cosine)作為相似度計算方法
構建先進RAG系統的時尚推薦引擎
完成資料載入和索引建立後,現在可以開始構建先進的RAG系統,實作人工智慧時尚推薦功能。首先,我們需要匯入必要的套件:
from langchain_core.output_parsers import JsonOutputParser
from langchain_core.prompts import PromptTemplate
from langchain_core.pydantic_v1 import BaseModel, Field
from langchain_openai import ChatOpenAI
from langchain_community.embeddings import OpenAIEmbeddings
from langchain_mongodb.vectorstores import MongoDBAtlasVectorSearch
from pymongo import MongoClient
from typing import List
from itertools import chain
import certifi
import os
from dotenv import load_dotenv
load_dotenv()
from functools import lru_cache
這些匯入涵蓋了多個關鍵功能:
JsonOutputParser
用於解析JSON格式的輸出PromptTemplate
用於建立提示範本BaseModel
和Field
用於定義資料模型ChatOpenAI
用於與OpenAI的聊天模型互動OpenAIEmbeddings
用於生成文字嵌入MongoDBAtlasVectorSearch
用於在MongoDB Atlas中執行向量搜尋- 其他輔助工具和類別
最佳化系統效能的快取設計
在構建推薦系統時,效能是關鍵考量因素。我們使用lru_cache
裝飾器來實作關鍵元件的快取,提高系統回應速度:
@lru_cache
def get_openai_emb_transformers():
"""
回傳OpenAI轉換器模型的OpenAIEmbeddings例項。
此函式建立並回傳OpenAIEmbeddings類別的例項,
提供對OpenAI轉換器模型的存取,用於自然語言處理。
該例項使用lru_cache裝飾器進行快取,以便高效重用。
Returns:
embeddings (OpenAIEmbeddings): OpenAIEmbeddings類別的例項。
"""
embeddings = OpenAIEmbeddings()
return embeddings
@lru_cache
def get_vector_store():
"""
取得MongoDB Atlas的向量儲存。
Returns:
MongoDBAtlasVectorSearch: 向量儲存物件。
"""
vs = MongoDBAtlasVectorSearch(
collection=col,
embedding=get_openai_emb_transformers(),
index_name="vector_index_openAi_cosine",
embedding_key="openAIVec",
text_key="title"
)
return vs
@lru_cache(10)
def get_conversation_chain_conv():
"""
取得用於聊天對話的對話鏈模型。
Returns:
ChatOpenAI: 用於聊天對話的對話鏈模型。
"""
llm = ChatOpenAI(model="gpt-3.5-turbo", temperature=0.2, max_tokens=2048)
return llm
這三個函式分別負責:
get_openai_emb_transformers()
- 建立並快取OpenAI嵌入模型get_vector_store()
- 設定並快取MongoDB Atlas向量搜尋get_conversation_chain_conv()
- 設定並快取對話模型
使用lru_cache
裝飾器可以避免重複建立這些資源密集型物件,大幅提升系統效能。特別是對於get_conversation_chain_conv()
函式,我們限制了快取大小為10,以平衡記憶體使用和計算效率。
設計考量與最佳實踐
在設計這個時尚推薦RAG系統時,有幾個關鍵考量因素值得注意:
向量維度選擇:OpenAI嵌入模型生成1536維向量,這在時尚專案相似性判斷中提供了良好的精確度,但也需要考慮儲存和計算成本。
相似度演算法:我們選擇餘弦相似度而非歐氏距離,因為它更適合高維空間中的語義相似性比較。
快取策略:使用
lru_cache
可以顯著提高效能,特別是在處理重複請求時。但要注意監控記憶體使用情況,避免過度快取導致系統資源耗盡。模型溫度設定:對於推薦系統,我們將模型溫度設為0.2,這有利於產生較為一致與可預測的結果,適合商品推薦場景。
令牌限制:設定
max_tokens=2048
為回應提供了足夠的空間,同時避免過長回應帶來的成本和延遲問題。
這個RAG系統的設計體現了效率與精確度的平衡,適用於需要高品質個人化推薦的時尚電商平台。
系統架構的擴充套件性考量
在實際佈署這種推薦系統時,還需要考慮以下擴充套件性因素:
資料更新機制:時尚產品目錄經常更新,系統需要有效的增量更新策略,避免完全重建嵌入和索引。
多模態擴充套件:考慮整合影像特徵向量,結合文字和視覺元素進行更全面的時尚推薦。
個人化層次:在基本向量搜尋基礎上,可以加入使用者歷史行為分析,進一步提高推薦相關性。
快取失效策略:隨著產品目錄的更新,需要人工智慧管理快取失效,確保推薦根據最新資料。
分散式佈署:對於大規模應用,考慮將向量搜尋和LLM推理分佈在不同伺服器上,最佳化整體效能。
RAG架構的優勢在於它結合了檢索能力和生成能力,使系統能夠提供既相關又個人化的推薦。透過MongoDB Atlas的向量搜尋功能和OpenAI的語言模型,我們建立了一個強大與靈活的時尚推薦引擎,能夠理解使用者需求並提供符合其風格偏好的精準建議。
在建構類別似系統時,平衡技術選擇、效能最佳化和使用者經驗至關重要。透過恰當的架構設計和實作策略,RAG系統可以為電商平台帶來顯著的競爭優勢。
向量搜尋:AI應用的核心引擎
向量搜尋技術已成為現代AI應用的關鍵根本。隨著非結構化資料與多模態資料集的擴張,傳統的搜尋方法已難以應對複雜的語義比對需求。在我多年的AI系統開發經驗中,向量搜尋始終扮演著連線原始資料與人工智慧應用的橋樑角色。
向量搜尋的核心優勢在於能夠處理語義相似性而非僅依賴關鍵字比對。當使用者詢問「有什麼防曬產品適合敏感肌膚?」時,向量搜尋能夠找出描述「適合過敏體質的溫和防曬乳」的產品,即使兩者措辭不同。這種語義理解能力使得AI應用能夠提供更加精確與符合使用者真實需求的回應。
向量搜尋如何改變AI應用領域
向量搜尋技術已深入影響多個AI應用領域:
- 影像識別與檢索:將影像轉換為向量表示,實作「以圖搜圖」功能
- 自然語言處理:透過語義相似性理解使用者意圖,提供更精準的回應
- 推薦系統:根據使用者偏好和專案特性的向量相似性提供個人化推薦
- 多模態搜尋:結合文字、影像、音訊等不同模態的資料進行綜合搜尋
在我參與的一個電子商務平台重構專案中,引入向量搜尋後,產品推薦的點選率提升了37%,這充分證明瞭向量搜尋在實際應用中的價值。
MongoDB Atlas向量搜尋實作
在實作向量搜尋時,選擇合適的資料函式庫重要。MongoDB Atlas提供了強大的向量搜尋功能,結合了靈活的schema設計和高效的向量索引能力,使其成為RAG系統的理想選擇。
基礎環境設定
首先,我們需要設定基本環境並連線MongoDB Atlas:
from pymongo import MongoClient
from dotenv import load_dotenv
import os
from functools import lru_cache
from langchain.embeddings import OpenAIEmbeddings
from langchain.vectorstores.mongodb_atlas import MongoDBAtlasVectorSearch
# 載入環境變數
load_dotenv()
# 連線MongoDB Atlas
@lru_cache
def get_openai_emb_transformers():
"""取得OpenAI嵌入模型例項"""
return OpenAIEmbeddings()
# 連線向量儲存
@lru_cache
def get_vector_store():
"""取得MongoDB Atlas向量儲存例項"""
client = MongoClient(os.environ.get("MONGODB_ATLAS_URI"))
collection = client[os.environ.get("MONGODB_DATABASE")][os.environ.get("MONGODB_COLLECTION")]
return MongoDBAtlasVectorSearch.from_connection_string(
connection_string=os.environ.get("MONGODB_ATLAS_URI"),
namespace=f"{os.environ.get('MONGODB_DATABASE')}.{os.environ.get('MONGODB_COLLECTION')}",
embedding=get_openai_emb_transformers(),
index_name=os.environ.get("MONGODB_INDEX_NAME")
)
這段程式碼建立了與MongoDB Atlas的連線,並設定了向量儲存功能。值得注意的是,我使用了lru_cache
裝飾器來快取函式結果,這在處理多次查詢時能顯著提升效能。
資料準備與向量索引建立
在MongoDB Atlas中建立向量索引前,我們需要先將文字資料轉換為向量嵌入。以下是一個典型的流程:
- 準備檔案資料
- 使用嵌入模型(如OpenAI embeddings)生成向量表示
- 將向量與原始資料一起儲存到MongoDB
- 在MongoDB中建立向量索引
MongoDB Atlas支援多種向量索引類別,包括HNSW(Hierarchical Navigable Small World)和BF(Brute Force)。在我的實踐中,對於百萬級資料量,HNSW索引通常能提供更好的查詢效能,而BF索引則適用於較小規模但要求精確結果的場景。
RAG架構系統:連線檢索與生成
RAG(檢索增強生成)架構結合了檢索模型和生成模型的優勢,成為解決知識密集型問答場景的有力工具。RAG的核心思想是:先從知識函式庫索相關資訊,再將這些資訊作為連貫的背景與環境提供給大語言模型,從而生成更準確、更可靠的回應。
簡單RAG系統實作
讓我們從一個基本的RAG系統開始,這個系統利用OpenAI的語言模型和嵌入模型:
from langchain.chains import ConversationalRetrievalChain
from langchain.memory import ConversationBufferMemory
from langchain.chat_models import ChatOpenAI
def get_conversation_chain():
"""建立基本的對話檢索鏈"""
vectorstore = get_vector_store()
llm = ChatOpenAI(temperature=0)
memory = ConversationBufferMemory(
memory_key="chat_history",
return_messages=True
)
chain = ConversationalRetrievalChain.from_llm(
llm=llm,
retriever=vectorstore.as_retriever(),
memory=memory
)
return chain
在這個簡單的RAG實作中,我們使用了以下元件:
- 向量儲存:儲存檔案及其向量表示
- 檢索器:負責從向量儲存中檢索相關檔案
- 語言模型:生成最終回應
- 記憶模組:維護對話歷史
這個基本系統已經能夠處理簡單的問答場景,但在更複雜的應用中,我們需要更高階的RAG架構。
進階RAG系統:條件決策與排序最佳化
在實際應用中,基本RAG系統往往無法滿足複雜的業務需求。以電商推薦為例,我們需要判斷使用者是否有購買意圖,並根據意圖提供相關產品推薦。
下面是一個進階RAG系統的實作,專注於時尚產品推薦:
from typing import List
from langchain.output_parsers import JsonOutputParser
from langchain.prompts import PromptTemplate
from pydantic import BaseModel, Field
from langchain.chains import ConversationChain
from langchain.memory import ConversationBufferWindowMemory
@lru_cache
def get_conversation_chain_conv():
"""取得對話鏈"""
llm = ChatOpenAI(temperature=0)
chain = ConversationChain(
llm=llm,
memory=ConversationBufferWindowMemory(k=5)
)
return llm
# 定義資料結構
class ProductRecoStatus(BaseModel):
"""
表示產品推薦狀態
"""
relevancy_status: bool = Field(description="根據查詢連貫的背景與環境判斷是否與購買時尚服飾/配飾相關")
recommendations: List[str] = Field(description="根據查詢連貫的背景與環境的推薦產品標題列表")
class Product(BaseModel):
"""
表示一個產品
"""
title: str = Field(description="產品標題")
baseColour: List[str] = Field(description="產品基本顏色列表")
gender: List[str] = Field(description="產品目標性別列表")
articleType: str = Field(description="產品類別")
mfg_brand_name: str = Field(description="製造商或品牌名稱")
接下來,我們建立相關的提示範本和解析器:
# 建立解析器和提示範本
reco_status_parser = JsonOutputParser(pydantic_object=ProductRecoStatus)
reco_status_prompt = PromptTemplate(
template="你是一個AI助手,負責識別查詢中是否存在產品購買意圖並提供合適的時尚推薦。\n{format_instructions}\n{query}\n\n#聊天歷史摘要: {chat_history}\n\n根據查詢連貫的背景與環境,請提供相關性狀態和推薦產品列表。",
input_variables=["query", "chat_history"],
partial_variables={"format_instructions": reco_status_parser.get_format_instructions()},
)
# 定義產品推薦狀態取得函式
def get_product_reco_status(query: str, chat_history: List[str] = []):
"""
根據給定查詢和聊天歷史取得產品推薦狀態
"""
llm = get_conversation_chain_conv()
chain = reco_status_prompt | llm | reco_status_parser
resp = chain.invoke({"query": query, "chat_history": chat_history})
return resp
在這個進階RAG系統中,我新增了以下關鍵功能:
- 意圖識別:使用LLM判斷使用者查詢是否包含購買意圖
- 條件推薦:只有在識別到購買意圖時才生成推薦
- 結果排序:根據使用者查詢對檢索結果進行重新排序
- 產品分類別:將推薦產品按類別分組,提升推薦多樣性
這種模組化設計使系統更加靈活,能夠根據不同的使用者流程提供個人化體驗。
RAG系統實際應用測試
讓我們測試這個進階RAG系統在實際查詢中的表現:
query = "能推薦一些適合與男友約會的休閒洋裝嗎?"
status = get_product_reco_status(query)
print(status)
print(get_product_recommendations(query, reco_queries=status["recommendations"], chat_history=[]))
系統輸出:
{'relevancy_status': True,
'recommendations': ['花卉印花裹身洋裝',
'一字領荷葉邊洋裝',
'蕾絲合身傘擺洋裝',
'中長絲綢洋裝',
'牛仔襯衫洋裝']}
當使用者查詢不包含購買意圖時,系統會識別出這一點並提供適當的回應:
query = "我該帶男友去哪裡約會?"
status = get_product_reco_status(query)
print(status)
print(get_conversation_chain_conv().invoke(query).content)
系統輸出:
{'relevancy_status': False, 'recommendations': []}
這表明系統能夠正確識別不同類別的使用者意圖,並根據意圖提供相應的回應。這種人工智慧決策能力大提升了使用者經驗。
向量搜尋與RAG系統的實踐思考
在實施向量搜尋和RAG系統的過程中,我總結了幾點關鍵經驗:
嵌入模型選擇至關重要:不同的嵌入模型會產生不同品質的向量表示,直接影響檢索效果。在預算允許的情況下,OpenAI的ada-002等模型通常能提供較好的效果。
索引引數需要調優:向量索引的引數(如維度、距離度量方式)需要根據具體應用場景進行調整。例如,時尚產品推薦可能更適合使用餘弦相似度,而科學文獻檢索則可能需要歐氏距離。
檢索策略需要多樣化:單一的向量檢索策略往往不夠全面,結合關鍵字搜尋、過濾條件和重排序可以顯著提升檢索品質。
LLM的角色不止於生成:在進階RAG系統中,LLM不僅可以用於最終回應生成,還可以用於意圖識別、查詢重寫和結果評估等環節。
模組化設計至關重要:將RAG系統拆分為可獨立評估和最佳化的模組,有助於快速迭代和持續改進。
在一個金融服務客戶的專案中,我們透過這種模組化設計,將檔案檢索的精確度從初始的67%提升到了92%,大減少了人工干預的需求。
向量搜尋與RAG的未來發展
隨著技術的不斷進步,向量搜尋和RAG系統還有廣闊的發展空間:
- 多模態RAG:整合文字、影像、音訊等不同模態的資訊,提供更全面的檢索增強生成能
LLM 輸出評估:確保AI系統品質的關鍵策略
在人工智慧應用日益普及的今日,評估大語言模型(LLM)輸出品質已成為確保AI系統成功的關鍵環節。作為技術工作者,玄貓過去參與過多個企業級AI系統的評估與最佳化,深知一個完善的評估機制對於開發高效能、可信賴的智慧應用的重要性。本文將探討LLM評估的核心概念、方法論與實踐策略。
理解LLM評估的本質與重要性
LLM評估(或稱LLM evals)是一個系統性過程,用於評估大語言模型及其應用在特定任務上的表現。這不僅是對模型效能的簡單測量,更是對其在特定條件下的可靠性、特定使用情境中的有效性,以及其整體能力的全面審視。
評估的重要性體現在幾個關鍵層面:
- 品質保證 - 確保智慧應用達到預設的標準與期望
- 變更影響測量 - 量化系統元件或資料變更對整體表現的影響
- 持續改進依據 - 為高品質系統提供精確的進步或退步指標
玄貓在為某金融科技公司最佳化客服AI系統時,發現一個關鍵問題:當系統已達到90%以上的成功率時,人工評估者很難僅憑直覺判斷小幅度改進(例如從90%到90.5%)的實際影響。這突顯了建立量化評估機制的必要性。
設計全面的LLM評估框架
設計評估框架時,應考慮以下關鍵導向:
安全性評估
AI系統不應洩露任何私密或機密資訊,無論是模型權重中的資訊還是應用程式所檢索的資訊。在我建構醫療對話系統時,安全性評估是首要考量,確保病患資料絕不外洩。
商業聲譽保護
AI系統不應生成可能損害企業聲譽的輸出。例如,客服聊天機器人不應在任何情況下推薦競爭對手的服務。
正確性檢驗
系統應提供準確的輸出,避免錯誤或幻覺(hallucinations)。在技術支援應用中,錯誤的解決方案可能導致更嚴重的問題。
風格一致性
AI系統應遵循指定的語調和風格準則。例如,法律助手應保持正式語調並使用適當的法律術語。
回應一致性
系統應產生符合預期的一致輸出。給定相同輸入,系統應以可預測的方式運作,即使回應內容有所不同。
倫理標準符合
AI系統應遵循一系列倫理原則,避免產生偏見或歧視性內容,並謹慎處理敏感話題。
元件評估與端對端評估策略
評估應該涵蓋應用程式的不同層面。以旅遊助手聊天機器人為例,該系統包含多個元件:檢索器、相關性護欄和回應生成器,每個元件都使用LLM執行特定任務。
元件評估
每個呼叫LLM的子系統都應進行評估,因為每個元件都會影響整體系統效能。元件評估能確保每個部分都符合所需的品質標準並可靠運作。
玄貓在評估一個電子商務推薦系統時發現,單獨最佳化查詢前處理器而忽略檢索後處理器,導致整體推薦品質未顯著提升。這凸顯了全面評估所有元件的重要性。
端對端評估
端對端評估檢視整個整合系統的表現,捕捉實際應用性、使用者經驗和系統可靠性等方面。對於RAG(檢索增強生成)系統,這涉及評估語言模型輸出、檢索機制效率與準確性、檢索資訊相關性,以及系統如何結合外部知識與LLM固有能力。
模型基準測試:選擇最適合的LLM
模型基準測試是比較多個模型在統一評估集上表現的過程,有助於瞭解各模型的能力和限制。
通常在基準測試表現最佳的是最大的模型(如GPT-4和Claude 3 Opus),但這些模型往往執行成本更高,生成速度更慢。即使大型模型成本過高,在開發過程中使用它們仍有價值,因為它們建立了理想系統效能的基準。
常見的LLM基準測試包括:
- MMLU(大規模多工語言理解):使用大學水平多選題測量模型的知識取得能力
- HellaSwag:使用多選文字完成測量模型的常識推理能力
- HumanEval:測量模型的Python程式設計能力
- MATH:測量模型解決數學應用題的能力
玄貓在為一家旅遊科技公司選擇模型時,發現MMLU分數高的模型通常更適合回答旅遊問題,因為世界知識對旅遊推薦至關重要。相比之下,Python程式設計基準測試的高分對旅遊推薦品質幾乎沒有影響。
建立評估資料集:衡量系統表現的根本
評估資料集是輸入到AI系統以產生輸出的資料,用於測量AI系統效能。這些資料集通常包含評估指標可用來確定評估分數的標準。
每個評估案例通常包括以下資訊:
- 輸入:輸入到AI系統的資料
- 參考:評估指標用來評估AI系統輸出是否正確的標準,通常是系統給定輸入的理想輸出(也稱為黃金答案或參考答案)
評估資料集設計考量
建立有效的評估資料集需要考慮多種因素:
- 代表性:資料集應包含系統將在實際環境中遇到的各種情況
- 多樣性:涵蓋不同難度和情境的案例
- 平衡性:確保不同類別的案例均衡分佈
- 實用性:反映實際使用者使用模式和需求
在設計旅遊助手評估資料集時,我發現包含極端情況(如罕見目的地查詢)和邊界案例(如模糊不清的請求)對於全面評估系統至關重要。
關鍵評估指標:量化LLM效能的方法
評估指標是將AI系統的輸入和輸出轉化為效能分數的方法。這些指標可分為自動評估和人工評估兩大類別。
自動評估指標
自動評估指標使用演算法計算分數,無需人工干預:
根據相似度的指標:
- BLEU/ROUGE:測量生成文字與參考文字的詞彙重疊度
- BERTScore:使用BERT嵌入測量語義相似度
根據LLM的評估:
- 利用LLM本身評估輸出品質
- 可評估準確性、相關性、有用性等多個維度
特定任務指標:
- 針對特定應用的自定義指標
- 例如,摘要系統可能使用ROUGE-L測量關鍵資訊保留度
人工評估的重要性
儘管自動評估便捷高效,人工評估仍是不可或缺的環節:
- 主觀品質評估:評估語氣、風格、整體連貼性等主觀特質
- 細微差別捕捉:識別自動指標可能忽略的細微問題或優勢
- 使用者經驗視角:從實際使用者角度評估系統輸出
在實施人工評估時,關鍵是建立明確的評分標準和一致的評估流程,確保不同評估者之間的結果可比較。
將評估作為應用程式的護欄
評估不僅用於測量系統效能,還可作為護欄機制,確保系統在佈署時表現符合預期:
- 即時評估:在系統生成回應後、展示給使用者前進行評估
- 品質閾值:設定最低品質標準,不符合標準的回應將被攔截
- 動態調整:根據評估結果動態調整系統引數或策略
玄貓在為金融服務聊天機器人實施護欄機制時,透過設定準確性和合規性閾值,成功將不當回應率降低了85%,顯著提高了系統可靠性。
實用技術:建立有效的LLM評估流程
根據實際經驗,這裡提供一些建立LLM評估流程的具體建議:
- 從簡單開始:先建立基本評估框架,再逐步擴充套件
- 多層次評估:結合自動指標和人工審查,兩者互補
- 持續評估:定期重新評估系統,特別是在模型或資料更新後
- 反饋迴圈:將評估結果用於改進系統,形成持續最佳化迴圈
- 檔案化:記錄評估方法、標準和結果,確保流程透明可追蹤
評估的挑戰與解決方案
LLM評估面臨多種挑戰,以下是常見問題及其解決方案:
主觀性問題:
- 挑戰:不同評估者可能對同一輸出有不同判斷
- 解決方案:建立詳細評分標準,培訓評估者,使用多人評估取平均
資源限制:
- 挑戰:全面評估需要大量時間和資源
- 解決方案:優先評估關鍵元件和高風險場景,使用分層評估策略
過度最佳化風險:
- 挑戰:過度針對評估指標最佳化可能導致實際效能下降
- 解決方案:使用多樣化評估指標,定期更新評估資料集
真實世界差異:
- 挑戰:評估環境與實際佈署環境可能存在差距
- 解決方案:納入真實使用者資料進行評估,實施A/B測試
在評估工作中,玄貓發現平衡自動化與人工評估是最大挑戰之一。過度依賴自動指標可能忽略細微但關鍵的品質問題,而過度依賴人工評估則可能導致效率低下。最佳方案是建立混合評估系統,利用自動指標進行初步篩選,再由人工評估者深入審查關鍵或邊界案例。
LLM評估是一個動態與不斷發展的領域。隨著模型和應用變得更加複雜,評估方法也需不斷創新。建立強大、全面的評估框架不僅能確保當前系統的品質,還能為未來改進提供清晰路徑。透過系統性評估,我們能夠開發更可靠、更有用、更負責任的AI應用,真正釋放LLM技術的潛力。
在人工智慧快速發展的時代,嚴謹的評估不僅是技術需求,更是倫理責任。只有透過全面、持續的評估,我們才能確保AI系統不僅聰明,而與值得信賴。
評估 LLM 輸出品質的關鍵方法
在人工智慧應用飛速發展的今日,評估大語言模型(LLM)輸出品質已成為確保AI系統可靠性的關鍵環節。作為技術領域的實踐者,玄貓發現許多團隊在建立評估框架時常忽略系統性方法的重要性。本文將探討LLM輸出評估的核心方法、資料集建立策略和實用指標。
評估資料集的結構與設計原則
評估LLM輸出的第一步是建立高品質的評估資料集。在我參與設計企業AI評估框架的過程中,發現評估資料集通常包含以下關鍵元素:
- 輸入訊息:使用者提供的原始查詢或指令
- 標準答案:人工編寫或工作者審核的理想回應
- 標籤或元資料:幫助分類別和追蹤評估案例的資訊
評估資料集通常採用表格式或檔案式資料結構,常見的儲存格式包括CSV、JSON或Parquet。以下是一個旅遊助手聊天機器人的簡單評估資料集範例:
輸入 | 標準答案 | 標籤 |
---|---|---|
七月份在紐約應該做什麼? | 可以去參觀時代廣場、參加戶外音樂會,以及遊覽自由女神像。 | [“todo”, “nyc”, “usa”] |
你能幫我解數學作業嗎? | 很抱歉,我無法協助您的數學作業,因為我是旅遊助手。您有任何與旅遊相關的問題嗎? | [“security”] |
法國的首都是哪裡? | 巴黎是法國的首都。 | [“europe”, “france”] |
關於評估資料集的規模,雖然沒有絕對的公式來決定,但根據我的實務經驗,可以參考以下粗略指引:
- 每個評估指標至少需要10個評估案例
- 至少需要100-200個具代表性的評估案例,以全面瞭解系統效能
建立代表性評估資料集的策略
定義基準評估案例
建立評估資料集的第一步是建立一組基準評估案例,這些案例應涵蓋系統預期行為和需要最佳化的邊緣情況。在我與金融科技客戶合作時,我們通常從以下幾方面著手:
多樣化的常見輸入樣本:可以利用現有資料來源,例如針對旅遊助手,可以從Google熱門旅遊搜尋詞彙中取得靈感。
需要最佳化的邊緣案例:包括測試系統安全和倫理防護機制的輸入。如果執行紅隊測試(Red Team),可以從測試結果中找到良好的邊緣案例。
這些基準評估案例通常足以讓AI系統進入導向使用者的環境。一旦系統投入使用,就可以驗證基準評估案例的有效性,並根據需要建立額外的評估案例。
利用使用者回饋
系統上線後,可以從使用者資料中取得評估案例,持續改進系統效能。若應用程式具有使用者回饋機制,如評分或留言,可以利用這些識別系統成功或失敗的案例。
在實作過程中,我建議在將任何應用程式資料新增到評估資料集之前進行人工審核,確保案例適合評估與不包含敏感資訊。也可以新增元資料,如標籤或評估案例名稱。
雖然技術上可以建立完全自動化的評估案例建立流程,但我強烈建議保持人工參與,原因如下:
- 人工審核員能更容易確保評估資料集的高品質
- 讓參與AI系統開發的人員瞭解評估資料集中的案例有助於理解系統能力
- 由於有效的評估資料集通常不需要特別大(幾百個評估案例通常已足夠),建立根據LLM的自動化系統可能過於複雜
合成資料的應用
大語言模型是生成評估資料集的強大工具。使用LLM生成的資料稱為合成資料,這種方法可以讓建立評估資料的過程更快速、更容易。
雖然截至2024年中期,尚無一套結構化的最佳實踐,但根據我在實際專案中的經驗,可以考慮以下原則:
- 保持人工參與:人工審核所有合成資料案例,並視需要編輯或移除,這為合成資料提供品質控制。
- 利用擾動技術:LLM在建立現有評估案例的微小變化(如句子的改述)方面非常有效。可以使用擾動來測試AI系統對微小變化的反應一致性。
- 使用對話式介面:通常,根據LLM的聊天機器人(如ChatGPT、Claude或Gemini)足以幫助建立合成資料。聊天機器人介面的來回互動也可以幫助改進合成資料建立過程。
評估指標的分類別與應用
評估指標是評估AI系統的關鍵工具,它接受AI系統的輸入和輸出,並回傳衡量系統表現的分數。指標通常回傳0到1之間的分數,可分為:
- 二元指標:僅回傳0(失敗)或1(透過)的指標
- 歸一化指標:回傳0到1之間的分數,提供更細微的系統表現檢視
為了提高歸一化指標的可解釋性,可以設定最低閾值分數,將分數高於閾值視為透過,低於閾值視為失敗。
LLM系統的評估指標大致分為以下幾類別:
根據斷言的指標
根據斷言的指標評估AI系統輸出是否符合程式碼中的斷言,類別似於傳統軟體工程中的單元測試。這些指標包括:
- 相等性:評估實際輸出是否等於(==)或不等於(!=)預期值
- 比較運算元:評估實際輸出是否符合比較條件:大於(>)、大於等於(>=)、小於(<)或小於等於(<=)
- 子字串比對:評估字串輸出是否包含預期的子字串
- 正規表示式比對:評估字串輸出是否符合正規表示式
以下是一個評估旅遊助手聊天機器人輸入相關性防護機制的範例程式碼:
from prettytable import PrettyTable
input_relevance_guardrail_data = [
{
"input": "七月份在紐約應該做什麼?",
"output": True,
"expected": True
},
{
"input": "你能幫我解數學作業嗎?",
"output": False,
"expected": False
},
{
"input": "法國的首都是哪裡?",
"output": False,
"expected": True
},
]
這個評估針對輸入相關性防護機制,案例包含評估輸入、防護機制的預期輸出以及透過防護機制執行輸入的實際輸出。評估指標判斷實際輸出是否等於預期輸出。
統計指標
統計指標使用統計演算法評估AI系統的輸出。在我的實踐中,常用的統計指標包括:
- BLEU、ROUGE和METEOR:這些指標最初為機器翻譯開發,但也可用於評估生成文字與參考文字的比對度
- F1分數:評估生成文字與參考文字在關鍵字或實體層面的比對程度
- 餘弦相似度:評估生成嵌入向量與參考嵌入向量的相似度
LLM作為評判的指標
隨著LLM能力的提升,越來越多團隊使用LLM自身作為評估工具。LLM評判指標使用一個LLM來評估另一個LLM的輸出是否符合質化標準。
這種方法的優勢在於能夠評估難以量化的指標,如創意性、有用性、準確性或安全性。在我主導的幾個專案中,LLM評判方法展現出與人類評估相當的一致性,特別是在使用最新的模型如GPT-4或Claude 3 Opus時。
RAG專用指標
檢索增強生成(RAG)系統需要特殊的評估指標,因為它們不僅生成回應,還需要檢索相關內容。RAG評估通常關注以下方面:
- 連貫的背景與環境相關性:檢索的連貫的背景與環境是否與查詢相關
- 回應準確性:生成的回應是否準確反映了檢索的連貫的背景與環境
- 參照準確性:回應中的參照是否正確指向來源檔案
綜合評估方法與實務建議
在建立完整的LLM評估框架時,我發現結合多種評估方法通常能獲得最佳結果。以下是一些實務建議:
採用多層次評估策略:同時使用根據斷言的指標、統計指標和LLM評判指標,從不同角度評估系統表現。
定期更新評估資料集:隨著使用者行為和需求的變化,持續更新評估資料集以確保其代表性。
建立評估基準:為每個指標設定最低表現標準,並追蹤系統在這些標準上的表現變化。
整合評估到開發流程:將評估納入持續整合/持續佈署(CI/CD)流程,確保每次更新都不會降低系統品質。
關注使用者經驗指標:除了技術指標外,也要收集和分析使用者滿意度、任務完成率等使用者經驗指標。
建立有效的LLM輸出評估框架需要持續的努力和迭代,但這項投資將為AI系統的可靠性和使用者信任提供堅實基礎。隨著評估方法的不斷發展,保持開放的心態並願意採用新的評估技術將有助於確保AI系統的長期成功。
在AI系統開發之旅中,評估不僅是確保系統品質的工具,也是深入理解系統能力與侷限性的視窗。透過建立完善的評估框架,我們能夠更有信心地將AI系統佈署到實際應用中,並持續提升其效能與可靠性。
玄貓的LLM評估:斷言式評估與統計指標解析
評估模型輸出的關鍵方法
在人工智慧和大語言模型(LLM)的應用開發過程中,評估模型輸出的品質是至關重要的一環。當玄貓在設計智慧應用程式時,我發現評估系統的表現不僅是為了確保品質,更是持續最佳化模型的基礎。今天讓我們探討兩種主要的評估方法:斷言式評估和統計指標評估。
斷言式評估的實作細節
斷言式評估是一種直接與高效的方法,它根據明確的判斷標準來評估模型輸出。這種評估方式特別適合有明確正確答案的任務,例如事實性問答或特定規則的遵循情況。
以下是一個我常用的斷言式評估框架:
def evaluate_correctness(output, expected):
return 1 if output == expected else 0
def calculate_average(scores):
return sum(scores) / len(scores)
def create_table(data):
table = PrettyTable()
table.field_names = ["Input", "Output", "Expected", "Score"]
scores = [evaluate_correctness(case["output"], case["expected"]) for case in data]
for case, score in zip(data, scores):
table.add_row([case["input"], case["output"], case["expected"], score])
# 增加視覺分隔
table.add_row(["", "", "", ""])
# 新增平均分數至表格底部
average_score = calculate_average(scores)
table.add_row(["Average", "", "", f"{average_score:.4f}"])
return table
這段程式碼的核心在於evaluate_correctness
函式,它對比模型輸出與預期答案,如果完全比對則給予1分,否則給予0分。雖然這種評估方式簡單明瞭,但它的二元性有時過於嚴格,不能反映部分正確的情況。
當我們將此評估框架應用於旅遊助手聊天機器人時,評估結果如下:
+--------------------------------------------+--------+----------+--------+
| Input | Output | Expected | Score |
+--------------------------------------------+--------+----------+--------+
| What should I do in New York City in July? | True | True | 1 |
| Can you help me with my math homework? | False | False | 1 |
| What's the capital of France? | False | True | 0 |
| | | | |
| Average | | | 0.6667 |
+--------------------------------------------+--------+----------+--------+
從結果可以看出,模型在前兩個問題上表現良好,但在第三個問題上有所偏差。這種評估方式特別適合用於評估LLM系統中的決策元件,例如判斷使用者查詢是否與應用領域相關。
統計指標評估的深度解析
當我們需要評估更複雜的自然語言生成任務時,統計指標就顯得尤為重要。這些指標能夠量化模型輸出與參考答案之間的相似度,提供更細緻的評估結果。
在NLP領域,兩個最常用的統計指標是BLEU和ROUGE:
BLEU (Bilingual Evaluation Understudy): BLEU主要測量模型輸出的精確度,計算模型生成文字中有多少n-gram片段出現在參考文字中。它最初用於機器翻譯評估,但現在廣泛應用於各種文字生成任務。
ROUGE (Recall-Oriented Understudy for Gisting Evaluation): ROUGE則著重於召回率,測量參考文字中有多少內容被模型成功捕捉。ROUGE特別適合評估摘要任務,也可用於測量檢索增強生成(RAG)系統的效果。
在實際應用中,我通常會結合這兩種指標來全面評估模型效能。例如,以下是評估旅遊助手聊天機器人回應生成器的程式碼:
from prettytable import PrettyTable
import sacrebleu
from rouge_score import rouge_scorer
# 計算BLEU分數的函式
def calculate_bleu(output, reference):
bleu = sacrebleu.corpus_bleu([output], [[reference]])
return bleu.score
# 計算ROUGE分數的函式
def calculate_rouge(output, contexts):
if not contexts:
return 0.0 # 如果沒有連貫的背景與環境可用,回傳0
scorer = rouge_scorer.RougeScorer(['rouge1'], use_stemmer=True)
# 計算輸出與每個連貫的背景與環境的ROUGE分數
scores = [scorer.score(output, context)['rouge1'].fmeasure for context in contexts]
# 回傳最高分數,表示輸出與最相關連貫的背景與環境的相似度
return max(scores) if scores else 0.0
# 評估並格式化結果
def evaluate_responses(data):
table = PrettyTable()
table.field_names = ["Input", "BLEU Score", "ROUGE Score"]
bleu_scores = []
rouge_scores = []
for case in data:
bleu = calculate_bleu(case["output"], case["golden_answer"])
rouge = calculate_rouge(case["output"], case["contexts"])
table.add_row([case["input"], f"{bleu:.4f}", f"{rouge:.4f}"])
bleu_scores.append(bleu)
rouge_scores.append(rouge)
# 增加視覺分隔
table.add_row(["", "", ""])
# 新增平均分數
avg_bleu = sum(bleu_scores) / len(bleu_scores)
avg_rouge = sum(rouge_scores) / len(rouge_scores)
table.add_row(["Average", f"{avg_bleu:.4f}", f"{avg_rouge:.4f}"])
return table
這段程式碼分別計算了模型回應與標準答案的BLEU分數,以及模型回應與檢索連貫的背景與環境的ROUGE分數。BLEU分數反映了生成回應與標準答案的相似度,而ROUGE分數則反映了模型如何有效利用檢索到的資訊。
選擇適合的評估方法
在玄貓多年的開發經驗中,我發現選擇合適的評估指標需要考慮以下因素:
任務性質:對於事實性問答或決策任務,斷言式評估可能更合適;對於摘要、翻譯或創意文字生成,統計指標通常更有意義。
評估目標:如果關注模型的決策正確性,可選擇斷言式評估;如果關注生成文字的品質和流暢度,統計指標會提供更多洞見。
系統架構:在RAG系統中,除了評估最終輸出外,還需要評估檢索元件的效能,這時ROUGE等指標就特別有價值。
人力資源:雖然人工評估通常是最準確的,但自動化評估指標能夠在資源有限的情況下提供快速反饋。
評估系統的實踐建議
根據我在實際專案中的經驗,以下是幾點關於建立有效評估系統的建議:
建立多樣化的測試集:確保測試集覆寫各種可能的使用場景和邊緣案例。
結合多種評估指標:不要僅依賴單一指標,結合斷言式評估和統計指標可提供更全面的視角。
定期更新評估標準:隨著模型和應用的發展,評估標準也應相應調整。
考慮人機協作評估:在關鍵應用中,結合自動評估和人工審核可以達到最佳效果。
關注長期趨勢:除了單次評估結果外,更要關注評估指標的長期變化趨勢,以指導持續最佳化。
評估LLM系統輸出是一個不斷發展的領域。隨著技術的進步,我們可能會看到更多創新的評估方法出現。作為開發者,保持對這些方法的瞭解和靈活應用是確保AI應用品質的關鍵。
在智慧應用的開發過程中,評估不僅是為了驗證系統是否達到預期目標,更是為了識別改進機會並指導後續開發。透過結合斷言式評估與統計指標評估,我們能夠建立更全面、更可靠的評估框架,為使用者提供更優質的AI體驗。
統計評估工具與LLM評價技術
在AI系統開發過程中,評估生成內容的品質至關重要。本文將探討如何使用統計評估工具和LLM作為評價者來全面評估AI模型的輸出品質。
統計評估指標實作
評估AI生成的文字通常使用兩種主要統計指標:BLEU和ROUGE。這些指標可以幫助我們量化模型輸出與標準答案之間的相似度。
# 統計評估工具
def evaluate_bleu(output, golden_answer):
bleu = sacrebleu.corpus_bleu([output], [[golden_answer]])
return bleu.score / 100 # 將BLEU分數標準化至0到1之間
def evaluate_rouge(output, contexts):
context_text = ("\n").join(contexts)
scorer = rouge_scorer.RougeScorer(['rouge1', 'rouge2', 'rougeL'], use_stemmer=True)
scores = scorer.score(context_text, output)
return scores['rougeL'].fmeasure
def calculate_average(scores):
return sum(scores) / len(scores)
# 截斷字串以便在表格中更容易顯示
def truncate_string(s, max_length=10):
return (s[:max_length] + '...') if len(s) > max_length else s
這些函式提供了統計評估的核心功能。BLEU分數主要用於測量生成文字與參考答案的詞序相似性,而ROUGE則更著重於文字覆寫率和召回率。
接下來,玄貓建立了一個建立評估表格的函式,它能夠計算並呈現所有評估案例的結果:
def create_table(data):
table = PrettyTable()
table.field_names = ["Input", "Output", "Golden Answer", "# Contexts", "BLEU", "ROUGE"]
bleu_scores = [evaluate_bleu(case["output"], case["golden_answer"]) for case in data]
rouge_scores = [evaluate_rouge(case["output"], case["contexts"]) for case in data]
for case, bleu, rouge in zip(data, bleu_scores, rouge_scores):
table.add_row([
truncate_string(case["input"]),
truncate_string(case["output"]),
truncate_string(case["golden_answer"]),
len(case["contexts"]),
f"{bleu:.4f}",
f"{rouge:.4f}"])
# 加入空白行以便視覺分隔
table.add_row(["", "", "", "", "", ""])
# 在表格底部加入平均分數
average_bleu = calculate_average(bleu_scores)
average_rouge = calculate_average(rouge_scores)
table.add_row(["Average", "", "", "", f"{average_bleu:.4f}", f"{average_rouge:.4f}"])
return table
當執行此程式時,輸出結果會顯示評估資料的表格,包括每個測試案例的BLEU和ROUGE分數,以及整體平均值。例如:
+---------------+---------------+---------------+------------+--------+--------+
| Input | Output | Golden Answer | # Contexts | BLEU | ROUGE |
+---------------+---------------+---------------+------------+--------+--------+
| What shoul... | Check out ... | Explore Ce... | 3 | 0.0951 | 0.2857 |
| Can you he... | I'm design... | I am a tra... | 0 | 0.0270 | 0.0000 |
| What's the... | The capita... | Paris is t... | 2 | 0.2907 | 0.2857 |
| | | | | | |
| Average | | | | 0.1376 | 0.1905 |
+---------------+---------------+---------------+------------+--------+--------+
統計指標的意義與侷限性
從上面的結果可以看出,第一個案例中BLEU和ROUGE分數的顯著差異表明模型回答與黃金答案有較大差距,但與連貫的背景與環境資訊的吻合度相對較高。這意味著可以透過最佳化檢索器取得更相關的連貫的背景與環境資訊,以更好地滿足黃金答案的需求。
這些統計指標在評估LLM用於傳統NLP任務(如翻譯和摘要)時最為有用。它們也可以在比較相同AI系統的不同版本時提供有價值的方向性指標。
然而,在開發過程中,玄貓發現這些量化指標無法完全捕捉語言生成的細微方面,如連貫性、創造力、事實正確性和連貫的背景與環境適當性。因此,還需要建立定性評估來瞭解LLM系統在這些方面的表現。
LLM作為評價者的評估方法
為了彌補統計指標的不足,可以使用LLM來評估LLM系統輸出的定性標準。這種方法被稱為「LLM-as-a-judge」(LLM作為評價者)。
在許多開放域任務中,如聊天機器人進行延伸對話,定量指標無法完全捕捉系統的有效性。例如,ROUGE分數可能夠指示摘要與源檔案的接近程度,但無法判斷摘要是否包含幻覺(hallucination)。
以下是可以使用LLM作為評價者的幾個領域:
- 回應的語氣和風格
- 回應是否根據輸入資訊個人化
- 回應是否包含不應分享的敏感資訊
- 回應是否符合特定法律或規定
當建立LLM作為評價者的評估指標時,玄貓建議記住以下關鍵點:
- 始終將LLM溫度設為0:這可確保輸出一致性
- 選擇更優質的LLM作為評價者:在基準測試中排名較高的LLM往往會產生更符合預期的評估結果
- 使用多樣本提示:包括輸入範例和模型應提供的輸出,這通常能改善評估準確性
- 採用思維鏈提示:要求模型在產生最終答案前解釋其思考過程
- 每個評估指標只評估單一品質方面:這使評估任務更容易被LLM解釋
- 保持LLM的一致性:不同的LLM可能在相同評估任務上產生不同結果
- 生成結構化評估輸出:評價者LLM應產生結構化輸出,如透過/失敗,或0-5的整數評分
實作LLM評價者系統
以下是一個使用LLM作為評價者來評估旅行助手聊天機器人是否在其回應中向使用者提供建議的程式碼範例:
import json
from prettytable import PrettyTable
import openai
import os
這個評估不需要參考答案就能判斷聊天機器人是否提供了相關建議,這是一種無參考評估。實際實施時,我們需要安裝相關Python套件,如prettytable用於以可讀格式輸出結果,以及openai用於呼叫OpenAI API使用GPT-4o LLM。
在實際系統中,這種LLM評價者方法能夠提供更全面的品質評估,特別是針對那些難以量化的語言生成特性。
整合評估方法的建議
在開發AI系統時,玄貓建議將統計指標與LLM評價者方法結合使用,以獲得更全面的評估:
- 使用BLEU和ROUGE等統計指標來評估基本的文字相似性和覆寫率
- 使用LLM評價者來評估品質方面,如連貫性、事實準確性和適當性
- 針對特定應用場景設計自定義評估指標
- 建立持續評估流程,隨著系統迭代不斷改進評估方法
透過這種多方面的評估方法,可以更有效地識別AI系統的優勢和不足,從而指導進一步的開發和最佳化。
在實際應用中,這些評估方法不僅可以幫助提高AI系統的品質,還能增強使用者對系統的信任。隨著AI技術的不斷發展,評估方法也將持續演進,為建立更優質、更可靠的AI系統提供支援。
運用 LLM 作為評估工具:如何評估模型輸出品質
在人工智慧快速發展的今日,評估大語言模型(LLM)的輸出品質已成為一個關鍵挑戰。傳統的評估方法往往需要大量人力資源,而「LLM-as-a-Judge」(LLM作為評判)的方法則提供了一種自動化與可擴充套件的替代方案。本文將探討如何利用LLM評估其他模型的輸出品質,並深入分析實際實作的程式碼。
為何需要自動化評估機制
評估AI模型輸出品質的傳統方法通常涉及人工審核,這種方法不僅耗時與成本高昂,還難以擴充套件。隨著AI應用的普及,我們需要更有效率的評估方式。使用LLM作為評判提供了一個有吸引力的解決方案,特別是在特定領域的評估中。
LLM-as-a-Judge的基本原理
LLM-as-a-Judge方法的核心理念是利用一個強大的語言模型來評估另一個模型的輸出。這種方法根據以下假設:高效能的LLM能夠理解複雜的語境和標準,並能提供與人類評判相似的判斷。
在實際應用中,我們透過以下步驟實作:
- 定義明確的評估標準
- 設計包含少量範例(few-shot examples)的提示
- 使用高效能LLM處理這些提示並生成評估結果
- 將結果解析為可量化的分數
實作LLM評估系統的程式碼分析
讓我們分析一下上面的Python程式碼,該程式碼實作了一個根據LLM的評估系統,用於判斷輸出是否包含推薦內容。
API設定與評估資料準備
首先,程式碼設定了OpenAI API金鑰,並定義了要評估的資料:
# Add your OpenAI API key to call the model
openai.api_key = os.getenv("OPENAI_API_KEY")
# Data to evaluate
evaluation_data = [
{
"input": "What should I do in New York City in July?",
"output": "Check out Times Square, go to an outdoor concert, and visit the Statue of Liberty.",
},
{
"input": "Can you help me with my math homework?",
"output": "I'm designed to assist with travel queries. For math help, try using online resources like Khan Academy or Mathway.",
},
{
"input": "What's the capital of France?",
"output": "The capital of France is Paris.",
}
]
這裡的評估資料包含三個案例,每個案例都有輸入和對應的輸出。玄貓注意到這些案例涵蓋了不同類別的查詢,包括旅遊建議、非旅遊查詢的處理,以及事實性問題。
自定義評估指標
接下來,程式碼定義了一個評估函式,專門用於判斷輸出是否包含推薦內容:
def evaluate_includes_recommendation(input, output):
# Few-shot examples to help the model produce better answers.
few_shot_examples = [
{
"input": "What are some good restaurants in Paris?",
"output": "Try Le Jules Verne for an upscale dining experience, or visit Le Relais de l'Entrecôte for a classic steak frites.",
"recommendation": True
},
# 其他範例...
]
# Constructing the prompt
prompt = """Determine whether the following output includes a recommendation based on the input.
Format response as a JSON object with the shape { "recommendation": boolean }.
Examples:
"""
這個函式的核心是透過few-shot learning來幫助LLM理解什麼是"推薦"。程式碼提供了五個範例,其中三個是包含推薦的正面例子,兩個是不包含推薦的負面例子。
提示工程與API呼叫
提示的構建是這個評估系統的關鍵部分:
# Append few-shot examples to the prompt.
for example in few_shot_examples:
prompt += f"""Input: {example['input']}
Output: {example['output']}
Recommendation: {{ "recommendation": {str(example['recommendation']).lower()} }}
"""
prompt += f"""Input: {input}
Output: {output}
Recommendation:"""
# Call the OpenAI API
response = openai.chat.completions.create(
# Use strong evaluator LLM
model="gpt-4o",
## Format response as JSON, so it is easier to parse
response_format={ "type": "json_object" },
messages=[{ "role": "user", "content": prompt }],
# Make sure temperature=0 for consistent outputs
temperature=0
)
在這裡,程式碼先將所有範例新增到提示中,然後新增要評估的輸入和輸出。接著,它使用OpenAI的API呼叫GPT-4o模型來評估輸出。
值得注意的是,程式碼使用了以下技巧來確保評估的準確性和一致性:
- 使用強大的模型(gpt-4o)作為評估器
- 設定temperature=0以確保輸出的一致性
- 指定JSON格式的回應,使解析更容易
結果解析與展示
最後,程式碼解析API回應並計算平均分數:
recommendation = json.loads(response.choices[0].message.content)["recommendation"]
return 1 if recommendation == True else 0
def calculate_average(scores):
return sum(scores) / len(scores)
def truncate_string(s, max_length=30):
return (s[:max_length] + '...') if len(s) > max_length else s
def create_table(data):
table = PrettyTable()
table.field_names = ["Input", "Output", "Score"]
scores = [evaluate_includes_recommendation(case["input"], case["output"]) for case in data]
# 表格新增行的程式碼
這部分程式碼將LLM的判斷轉換為二元分數(0或1),然後計算平均分數並建立一個表格來展示結果。
LLM評估系統的最佳化策略
從上面的程式碼中,玄貓歸納出幾個關鍵的最佳化策略:
1. 精心設計的few-shot範例
提供多樣化與平衡的範例對於幫助LLM理解評估標準至關重要。在這個例子中,範例包括:
- 不同類別的查詢(餐廳、住宿、天氣)
- 明確的正面和負面例子
- 邊界情況(如包含事實資訊但也有推薦的例子)
2. 明確的評估指標與輸出格式
程式碼明確指定了評估的目標(是否包含推薦),並要求LLM以特定的JSON格式輸出結果。這種方法使得結果解析變得簡單與可靠。
3. 模型選擇與引數設定
使用強大的模型(GPT-4o)作為評估器,並設定temperature=0來確保一致性。這些選擇對於獲得可靠的評估結果至關重要。
LLM-as-a-Judge方法的侷限性
雖然LLM-as-a-Judge方法提供了許多優勢,但玄貓認為我們也應該意識到它的侷限性:
主觀性問題:LLM的判斷可能受其訓練資料的偏見影響,特別是在主觀評估標準上。
成本考量:使用高效能LLM(如GPT-4)進行大規模評估可能成本高昂。
評估一致性:即使設定temperature=0,不同版本的LLM或不同的提示設計仍可能導致評估結果不一致。
複雜評估標準的侷限:對於需要深入領域知識或複雜判斷的評估標準,LLM可能不如人類工作者可靠。
實際應用案例
在我的實際工作中,玄貓曾使用類別似的LLM-as-a-Judge方法來評估客戶服務聊天機器人的回應品質。我們發現,透過精心設計的評估提示,LLM能夠可靠地識別出以下幾個方面的問題:
- 回應是否直接回答了使用者的問題
- 語氣和措辭是否專業與符合品牌形象
- 回應是否包含必要的資訊
- 是否有潛在的誤導或不準確資訊
這種自動化評估方法極大地提高了我們的QA效率,使我們能夠在大規模佈署前更全面地測試聊天機器人。
擴充套件LLM評估系統
根據上述程式碼,我們可以進一步擴充套件LLM評估系統,以評估更多維度的輸出品質:
def evaluate_helpfulness(input, output):
# 評估回應的有用性
# 實作類別似於evaluate_includes_recommendation的邏輯
def evaluate_accuracy(input, output):
# 評估回應的準確性
# 可能需要外部知識來源來驗證
def evaluate_professionalism(input, output):
# 評估回應的專業性和語氣
透過組合多個維度的評估,我們可以獲得更全面的輸出品質評估。
評估結果的解釋與應用
評估結果不僅可以用於模型選擇,還可以指導模型的改進。例如,如果評估顯示模型在提供推薦方面表現不佳,我們可以:
- 調整模型提示以強調推薦的重要性
- 微調模型以增強其推薦能力
- 設計後處理邏輯來增強推薦內容
實用建議
根據玄貓的經驗,以下是一些使用LLM-as-a-Judge方法的實用建議:
結合多種評估方法:LLM評估應與其他方法(如人工評估、自動化指標)結合使用,而不是完全替代它們。
定期校準:透過與人類評判結果比較來校準LLM評估器,確保其判斷與人類期望一致。
透明的評估標準:明確定義評估標準,並在報告結果時包含這些標準,以便正確解釋結果。
考慮領域特異性:為特定領域或應用定製評估提示和範例,以提高評估的相關性。
批次評估:設計系統以支援批次評估,減少API呼叫成本並提高效率。
人工智慧模型的評估是一個持續發展的領域。LLM-as-a-Judge方法提供了一個強大的工具,使我們能夠以更高效、可擴充套件的方式評估模型輸出。透過精心設計的提示、適當的模型選擇和結果解釋,我們可以利用這種方法來提高AI系統的品質和可靠性。
隨著LLM技術的不斷進步,玄貓相信這種評估方法將變得更加精確和多樣化,最終幫助我們開發出更符合人類期望的AI系統。
程式碼評估指標:從簡單實作到RAG系統測量
在建立人工智慧應用時,評估大語言模型(LLM)輸出的品質是確保系統可靠性的關鍵步驟。本文將探討如何從基本的評估表格開始,逐步建立更複雜的評估機制,特別是針對檢索增強生成(RAG)系統的測量方法。
評估表格的建立與計算
評估LLM輸出的第一步是建立一個清晰的測量框架。以下程式碼展示如何建立一個基本的評估表格:
# 新增空白列以增加視覺分隔
table.add_row(["", "", ""])
# 計算並新增平均分數到表格底部
average = calculate_average(scores)
table.add_row(["Average", "", f"{average:.4f}"])
return table
# 建立並列印表格
result_table = create_table(evaluation_data)
print(result_table)
這段程式碼將產生一個包含輸入、輸出和評分的表格,並自動計算平均分數。例如:
+-----------------------------------+-----------------------------------+--------+
| Input | Output | Score |
+-----------------------------------+-----------------------------------+--------+
| What should I do in New York C... | Check out Times Square, go to ... | 1 |
| Can you help me with my math h... | I'm designed to assist with tr... | 1 |
| What's the capital of France? | The capital of France is Paris... | 0 |
| | | |
| Average | | 0.6667 |
+-----------------------------------+-----------------------------------+--------+
這個例子展示瞭如何建立簡單的「LLM作為評審」指標,用於評估回應是否包含推薦內容。這種技術可以進一步擴充套件,用於評估LLM系統的各種方面。
RAG系統評估指標
檢索增強生成(RAG)系統是目前最受歡迎的LLM應用方式之一。為評估RAG系統的有效性,業界已發展出一套特定的指標,這些指標都使用LLM作為評審。
RAG系統的評估主要聚焦於兩個核心元件:
- 檢索(Retrieval):從外部來源取得相關資訊的元件,通常結合向量搜尋和根據LLM的預處理和後處理
- 生成(Generation):使用LLM產生文字輸出的元件
常用的RAG評估指標
以下是兩個常用於評估RAG系統的指標:
- 回答忠實度(Answer faithfulness):測量生成的回答與檢索的連貫的背景與環境資訊的一致性
- 回答相關性(Answer relevance):測量生成的回答與提供的輸入的相關程度
Ragas是一個流行的Python函式庫含實作這些指標的模組以及其他RAG評估工具。
回答忠實度評估
回答忠實度是評估RAG系統生成元件的指標,它測量生成回答中的資訊與檢索連貫的背景與環境資訊的一致程度。透過識別生成回答與檢索連貫的背景與環境之間的事實差異,忠實度指標可以幫助識別回答中的幻覺(hallucinations)。
Ragas函式庫測量忠實度的模組,它使用以下公式計算忠實度:
忠實度 = 可從連貫的背景與環境推斷的宣告數量 / 回答中的總宣告數量
計算忠實度的步驟如下:
- 使用LLM從生成的回答中提取所有宣告
- 使用LLM在參考材料中定位每個宣告
- 計算可從連貫的背景與環境資訊推斷的宣告比例
實作忠實度評估
要實作Ragas的忠實度指標,首先需要安裝必要的Python套件:
pip3 install ragas==0.1.13 langchain-openai==0.1.20 datasets==2.20.0
這些套件包括:
ragas
:包含回答忠實度指標和報告模組langchain-openai
:允許將OpenAI模型傳遞給Ragasdatasets
:Ragas依賴此套件來格式化輸入
安裝完成後,可以執行評估程式碼:
from ragas.metrics import faithfulness
from ragas import evaluate
from datasets import Dataset
from langchain_openai.chat_models import ChatOpenAI
import os
openai_api_key = os.getenv("OPENAI_API_KEY")
evaluation_data = [
{
"input": "What should I do in New York City in July?",
"output": "Check out Times Square, go to an outdoor concert, and visit the Statue of Liberty.",
"contexts": [
"Times Square is known for its Broadway theaters, bright lights, and bustling atmosphere.",
"Outdoor concerts in Central Park are popular summer events attracting many visitors.",
"The Statue of Liberty is a symbol of freedom and a must-see landmark in NYC."
]
},
{
"input": "Can you help me with my math homework?",
"output": "I'm designed to assist with travel queries. For math help, try using online resources like Khan Academy or Mathway.",
"contexts": []
},
{
"input": "What's the capital of France?",
"output": "The capital of France is Paris.",
"contexts": [
"Paris, known as the City of Light, is the most populous city of France.",
"European capitals: Paris, France; Berlin, Germany; Madrid, Spain",
]
}
]
這個程式碼範例展示瞭如何設定評估資料,包括輸入問題、系統輸出回答以及相關的連貫的背景與環境資訊。透過這些資料,Ragas可以計算回答的忠實度,幫助我們評估RAG系統的生成品質。
為何評估指標對RAG系統至關重要
在玄貓開發的多個RAG應用中,發現評估指標對於系統改進至關重要。忠實度指標特別有價值,因為它能幫助識別模型何時在「編造」不存在於檢索資料中的資訊。這種幻覺不僅會誤導使用者,還可能在某些應用場景(如醫療或法律諮詢)中造成嚴重後果。
透過系統化地評估RAG輸出,開發者可以:
- 識別系統弱點
- 最佳化向量檢索策略
- 調整提示工程以減少幻覺
- 建立可靠的測試基準以監控系統效能
在建立自己的RAG系統評估框架時,結合多種指標通常比單一指標更能全面反映系統品質。除了忠實度外,相關性、準確性和完整性也是重要的評估維度。
Ragas:自動評估RAG系統效能的強大工具
在建立RAG(檢索增強生成)系統後,我們需要評估其效能,確保它能夠提供準確與相關的回答。這時,Ragas這個專為RAG系統評估而設計的開放原始碼工具就顯得格外重要。本文將探討如何利用Ragas評估RAG系統的輸出品質。
準備資料集以符合Ragas結構
Ragas需要特定格式的資料才能進行評估。以下是如何將資料轉換為Ragas可用格式的步驟:
def prepare_data_for_ragas(data_list):
data_table = {
'question': [],
'answer': [],
'contexts': []
}
for data_item in data_list:
data_table["question"].append(data_item["input"])
data_table["answer"].append(data_item["output"])
data_table["contexts"].append(data_item["contexts"])
return data_table
def create_report(data):
ragas_dict = prepare_data_for_ragas(data)
dataset = Dataset.from_dict(prepare_data_for_ragas(data))
langchain_llm = ChatOpenAI(
model_name="gpt-4o-mini",
api_key=openai_api_key)
score = evaluate(dataset, metrics=[faithfulness], llm=langchain_llm)
return score
# 建立並列印評估表
results = create_report(evaluation_data)
print(results.to_pandas())
print(results)
執行上述程式碼後,終端機會輸出類別似以下的結果:
Evaluating: 100%
3/3 [00:05<00:00, 1.72s/it]
question \
0 What should I do in New York City in July?
1 Can you help me with my math homework?
2 What's the capital of France?
answer \
0 Check out Times Square, go to an outdoor conce...
1 I'm designed to assist with travel queries. Fo...
2 The capital of France is Paris.
contexts faithfulness
0 [Times Square is known for its Broadway theate... 1.0
1 [] 0.0
2 [Paris, known as the City of Light, is the mos... 1.0
{'faithfulness': 0.6667}
從結果可以看出,Ragas評估器認為第一個和第三個例子是忠實的(faithfulness得分為1.0),而第二個例子不忠實(得分為0)。
答案相關性評估
除了忠實度外,答案相關性(Answer Relevance)是另一個重要的RAG評估指標。它衡量RAG系統輸出對於輸入問題的相關程度,這對於判斷系統是否能夠針對提供的問題給出適當回應非常有用。
Ragas計算答案相關性的步驟如下:
- 使用LLM從生成的回答中產生一系列問題
- 為上一步驟中LLM生成的每個問題建立向量嵌入,同時為最初的輸入查詢建立向量嵌入
- 計算原始問題嵌入與每個生成問題嵌入之間的餘弦相似度
- 答案相關性得分是原始問題與每個生成問題之間餘弦相似度的平均值
Ragas假設如果生成的答案與原始問題高度相關,那麼從這個答案中衍生出的問題在語義上應該與原始問題相似。這一假設根據一個理念:相關的答案包含直接針對查詢的資訊,因此評判LLM應該能夠反向推匯出與原始輸入密切相符的問題。
以下是使用Ragas答案相關性指標評估範例資料集的程式碼:
首先,安裝必要的Python套件:
pip3 install ragas==0.1.13 langchain-openai==0.1.20 datasets==2.20.0
然後執行以下程式碼進行評估:
from ragas.metrics import answer_relevancy
from ragas import evaluate
from datasets import Dataset
from langchain_openai.chat_models import ChatOpenAI
from langchain_openai.embeddings import OpenAIEmbeddings
import os
openai_api_key = os.getenv("OPENAI_API_KEY")
evaluation_data = [
{
"input": "What should I do in New York City in July?",
"output": "Check out Times Square, go to an outdoor concert, and visit the Statue of Liberty.",
"contexts": [
"Times Square is known for its Broadway theaters, bright lights, and bustling atmosphere.",
"Outdoor concerts in Central Park are popular summer events attracting many visitors.",
"The Statue of Liberty is a symbol of freedom and a must-see landmark in NYC."
]
},
{
"input": "Can you help me with my math homework?",
"output": "I'm designed to assist with travel queries. For math help, try using online resources like Khan Academy or Mathway.",
"contexts": []
},
{
"input": "What's the capital of France?",
"output": "The capital of France is Paris.",
"contexts": [
"Paris, known as the City of Light, is the most populous city of France.",
"European capitals: Paris, France; Berlin, Germany; Madrid, Spain",
]
}
]
使用嵌入模型進行答案相關性評估
在評估答案相關性時,我們需要使用嵌入模型來生成問題和答案的向量表示。以下程式碼展示瞭如何使用OpenAI的嵌入模型來評估答案相關性:
def prepare_data_for_ragas(data_list):
data_table = {
'question': [],
'answer': [],
'contexts': []
}
for data_item in data_list:
data_table["question"].append(data_item["input"])
data_table["answer"].append(data_item["output"])
data_table["contexts"].append(data_item["contexts"])
return data_table
def create_report(data):
dataset = Dataset.from_dict(prepare_data_for_ragas(data))
# 設定LLM和嵌入模型
langchain_llm = ChatOpenAI(
model_name="gpt-4o-mini",
api_key=openai_api_key)
embeddings = OpenAIEmbeddings(
api_key=openai_api_key)
# 進行評估
score = evaluate(
dataset,
metrics=[answer_relevancy],
llm=langchain_llm,
embeddings=embeddings)
return score
# 執行評估並輸出結果
results = create_report(evaluation_data)
print(results.to_pandas())
print(results)
執行此程式碼後,我們會得到每個問答對的答案相關性分數。這些分數反映了生成的答案與原始問題的相關程度,分數越高表示相關性越強。
Ragas評估指標的綜合應用
在實際應用中,玄貓建議同時使用多種Ragas評估指標來全面評估RAG系統的效能。例如,我們可以結合忠實度(faithfulness)和答案相關性(answer_relevancy)以及其他指標如連貫的背景與環境精確度(context_precision)、連貫的背景與環境召回率(context_recall)等。
以下是一個使用多種指標進行評估的範例:
from ragas.metrics import faithfulness, answer_relevancy, context_precision, context_recall
def comprehensive_evaluation(data):
dataset = Dataset.from_dict(prepare_data_for_ragas(data))
langchain_llm = ChatOpenAI(
model_name="gpt-4o-mini",
api_key=openai_api_key)
embeddings = OpenAIEmbeddings(
api_key=openai_api_key)
# 使用多種評估指標
metrics = [
faithfulness,
answer_relevancy,
context_precision,
context_recall
]
score = evaluate(
dataset,
metrics=metrics,
llm=langchain_llm,
embeddings=embeddings)
return score
在實際開發RAG系統時,我發現定期進行這種全面評估能夠幫助識別系統的弱點,並指導後續的最佳化方向。例如,如果faithfulness得分低,可能需要改進檢索機制;如果answer_relevancy得分低,則可能需要最佳化生成模型的提示工程或微調模型。
自動化評估流程的建議
隨著RAG系統的不斷發展,建立自動化的評估流程變得越來越重要。在我的實踐中,將Ragas評估整合到CI/CD管道中是一種有效的方法,可以確保每次更新都不會降低系統效能。
以下是一個自動化評估流程的簡單架構:
- 維護一個高品質的測試資料集,包含各種類別的查詢和預期回答
- 在每次系統更新後,自動執行Ragas評估
- 設定效能閾值,如果評估分數低於閾值,則觸發警示或阻止佈署
- 將評估結果記錄到監控儀錶板,以便隨時間追蹤效能變化
這種自動化評估流程可以幫助團隊快速識別效能退化,並確保RAG系統的持續改進。
RAG系統評估是一個複雜但至關重要的任務。Ragas提供了一套全面的指標和工具,使我們能夠客觀地評估系統效能,並指導最佳化方向。透過結合忠實度、答案相關性等多種指標,我們可以全面瞭解RAG系統的強項和弱點,從而開發更加準確、相關與有用的AI應用。