接着上次faithfulness下讲另一个指标-relevance回答相关性,这是测回答的内容和提问的问题是否强相关的一项指标,使用的基本原理是将被测系统提问问题所回答出来的内容,通过大模型倒推出问题,再用向量模型比对倒推出的问题和原问题的语义相关性,因此,需要引入一个向量模型,引入前仍先在models文件里接着封装一个类,用来做向量适配器;
Class Embedding(Embeddings): def __init__(self, url:str): self.url = url def _embed(self, texts): res = _requests.post(self.url, json={"texts": texts}, timeout=30) res.raise_for_status() return res.json()["data"]["vectors"] def embed_documents(self, texts): return self._embed(texts) def embed_query(self, text): return self._embed([text])[0]通过这个类,将转发的requests到引用的向量接口中,接下来新建一个Answer_relevance.py文件
import os sys import pandas as pd from ragas import EvaluationDataset, evaluate, RunConfig from ragas.metrics import AnswerRelevancy from ragas.llms import LangchainLLMWrapper #路径锚定: 不管从哪个目录跑, data 都指向 目录\data\ BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) DATA_DIR = os.path.join(BASE_DIR, "data") sys.path.insert(0, BASE_DIR) #锚定绝对路径 from models import Chat, Embeddings #==========配置参数 ========== EMBED_URL="填写向量大模型url" DETAIL_CSV = DATA_DIR + "/eval_detail_relevancy.csv" # 单独保存回答相关性的成绩 # ============================上面写好文件里的配置项,包括引用的各种库,配置好向量模型,以及把存放的明细文件地址写好,接下来写好正式的"打分"代码,因为回答相关性不看检索文档也不看标准答案(源文档),所以需要准备的东西会比faithfulness这里少很多;
def build_samples(df_res, rows=None): #准备材料 if rows is None: rows = range(len(df_res)) samples = [] for i in rows: row = df_res.iloc[i] samples.append({ "user_input": row["question"],#原题 "response": row["response"], # 考生的回答 }) return samples def judge_relevancy(df_res): dataset = EvaluationDataset.from_list(build_samples(df_res)) #把Python列表弄成ragas认可的格式 print(f"已加载 {len(dataset)} 条,开始打分...") judge_llm = LangchainLLMWrapper(Chat())#给模型包一层lanterchain外壳 embeddings = Embeddings(url=EMBED_URL) #使用向量大模型 run_config = RunConfig(timeout=600, max_retries=0, max_workers=2) # 与faithfulness相同配置,超时设置10分钟,不重试不重跑,开双路 result = evaluate(dataset=dataset, metrics=[AnswerRelevancy()], llm=judge_llm, embeddings=embeddings, run_config=run_config) print(f"\n AnswerRelevancy: {result}") detail = result.to_pandas() #结果转成表detail.to_csv(DETAIL_CSV, index=False, encoding="utf-8-sig") n_nan = detail["answer_relevancy"].isna().sum() if n_nan: print(f"缺考 {n_nan} 题(NaN不计分不计题)") print(f"明细已存 {DETAIL_CSV}") return result if __name__ == "__main__": df_res = pd.read_csv(DATA_DIR + "/dataset_result.csv").dropna(subset=["question"] judge_relevancy(df_res)