RAG(Retrieval-Augmented Generation)介绍
Retrieval-Augmented Generation for Large Language Models: A Survey:arxiv.org/abs/231 2.10997
github项目:GitHub - Tongji-KGLLM/RAG-Survey
RAGFlow项目
环境配置
wsl安装
安装 WSL文档: 安装 WSL | Microsoft Learn
WSL基本命令:WSL 的基本命令 | Microsoft Learn 1、管理员权限打开powershell命令
也可以手动选择:
编辑
docker环境安装
下载安装路径:docs.docker.com/engine/inst…
设置镜像本地路径
默认镜像拉取到本地后会保存在c:盘,我们设置到其它路径
编辑
设置镜像源
国外镜像源拉取比较慢,更新成国内镜像源
编辑
测试docker是否正常
编辑
安装运行RAGFlow
ragflow项目地址:GitHub - infiniflow/ragflow: RAGFlow is an open-source RAG (Retrieval-Augmented Generation) engine based on deep document understanding. git把代码拉取下来
拉取代码后:
请注意,运行上述命令会自动下载 RAGFlow 的开发版本 docker 镜像。如果你想下载并运行特定版本的 docker 镜像,请在 docker/.env 文件中找到 RAGFLOW_VERSION 变量,将其改为对应版本。例如 RAGFLOW_VERSION=v0.10.0,这个版本就是github的代码版本,然后运行上述命令。
核心镜像文件大约 9 GB,可能需要一定时间拉取。请耐心等待这个过程会要一段时间,请耐心等待
编辑
启动
服务器启动成功后再次确认服务器状态:
出现以下界面提示说明服务器启动成功:
如果您跳过这一步系统确认步骤就登录 RAGFlow,你的浏览器有可能会提示或 网络异常 ,因为 RAGFlow 可能并未完全启动成功。
登录
下面网站和端口即可打开系统
按照提示注册登录即可
建立知识库与聊天
模型配置
正常我们选择本地ollama部署的大语言模型
界面演示如下
编辑
编辑
建立知识库
上传一个本地文件,一定要把文件解析好
编辑
新建助理时,选择好对应的知识库
编辑
选择模型配置时的大模型
编辑
Naive RAG
使用langchain构建简单RAG
Introduction | 🦜️🔗 LangChain Chroma
环境准备
安装chroma
编辑
使用openai的模型
如果使用openai的模型来生成,你需要在项目的根目录下的 .env 文件中设置相关的环境变量。要获取 OpenAI 的 API 密钥,你需要注册 OpenAI 账户,并在platform.openai.com/account/api…页面中选择“创建新的密钥”。
完成这些设置后,运行下面的命令来加载你所设置的环境变量。
通义千问
注册地址:help.aliyun.com/zh/dashscop… on-of-api-key
兼容openai文档地址:help.aliyun.com/zh/dashscop… openai-with-dashscope
完成这些设置后,运行下面的命令来加载你所设置的环境变量。
使用ollama
则需要安装前面模型微调训练中的ollama服务搭建方式,把ollama服务跑起来,并下载好推理用的模型
准备数据完整代码
from langchain_chroma import Chroma
from langchain_community.embeddings import HuggingFaceBgeEmbeddings
#准备知识库数据,建索引 def prepare_data():
loader = WebBaseLoader("baike.baidu.com/item/AIGC? fromModule=lemma_search-box")
documents = loader.load()
text_splitter = RecursiveCharacterTextSplitter(chunk_size=500, chunk_overlap=50)
chunks = text_splitter.split_documents(documents)
print(chunks[0].page_content)
return chunks
#embedding 知识库,保存到向量数据库
def embedding_data(chunks):
#openai embedding #rag_embeddings=OpenAIEmbeddings()
#创建BAAI的embedding
rag_embeddings = HuggingFaceBgeEmbeddings(model_name="BAAI/bge-small-zh- v1.5")
#embed保存知识到向量数据库
vector_store = Chroma.from_documents(documents=chunks, embedding=rag_embeddings,persist_directory="./chroma_langchain_db")
retriever = vector_store.as_retriever() return vector_store,retriever
#使用ollama服务
llm = OllamaLLM(model="qwen2:7b-instruct-q4_0") template = """您是问答任务的助理。
使用以下检索到的上下文来回答问题。
如果你不知道答案,就说你不知道。
最多使用三句话,不超过100字,保持答案简洁。
Question: {question} Context: {context} Answer:
"""
prompt = ChatPromptTemplate.from_template(template)
chunks = prepare_data()
vector_store,retriever = embedding_data(chunks)
#生成答案
def generate_answer(question):
Advanced RAG
数据提取
提取方式
llamaindex reader文档:Index - LlamaIndex
添加元数据
llamaindex metadata提取文档:Index - LlamaIndex
例子:docs.llamaindex.ai/en/stable/e… e/
知识图谱
使用KG来组织多个文档,可以参考这篇研究论文KGP:Knowledge Graph Prompting for Multi-
Document Question Answering :[2308.11730] Knowledge Graph Prompting for Multi-Document Question Answering
llamaindex 知识图谱文档:docs.llamaindex.ai/en/stable/a… graph/
层次化索引结构
总分层级索引(总→细,提高搜索的效率)
利用元数据进行多层次过滤:docs.llamaindex.ai/en/stable/e… c_auto_retrieval/multi_doc_auto_retrieval/
FilterOperator, MetadataFilter, MetadataFilters,
)
async def aprocess_doc(doc, include_summary: bool = True): """Process doc."""
metadata = doc.metadata
date_tokens = metadata["created_at"].split("T")[0].split("-") year = int(date_tokens[0])
month = int(date_tokens[1]) day = int(date_tokens[2])
assignee = (
"" if "assignee" not in doc.metadata else doc.metadata["assignee"]
)
size = ""
if len(doc.metadata["labels"]) > 0:
size_arr = [l for l in doc.metadata["labels"] if "size:" in l] size = size_arr[0].split(":")[1] if len(size_arr) > 0 else ""
new_metadata = {
"state": metadata["state"], "year": year,
"month": month, "day": day, "assignee": assignee, "size": size,
}
提取文档总结摘要
summary_index = SummaryIndex.from_documents([doc])
query_str = "Give a one-sentence concise summary of this issue." query_engine = summary_index.as_query_engine(
llm=OpenAI(model="gpt-3.5-turbo")
)
summary_txt = await query_engine.aquery(query_str) summary_txt = str(summary_txt)
index_id = doc.metadata["index_id"] # 通过 doc id过滤出对应的文档
filters = MetadataFilters( filters=[
MetadataFilter(
key="index_id", operator=FilterOperator.EQ, value=int(index_id)
),
]
)
#创建的一个索引节点,包括有元数据和摘要总结文本 index_node = IndexNode(
text=summary_txt,#总结 metadata=new_metadata,#包括年月日,状态等
obj=doc_index.as_retriever(filters=filters), index_id=doc.id_,#文档id
)
父子层级索引(细→总,提高搜索精确问题的准确性)
TreeIndex
句子窗口索引
多种切分方式并行查询
并行优化例子:
Parallelizing Ingestion Pipeline - LlamaIndex
多chunks大小索引和查询:
Ensemble Retrieval Guide - LlamaIndex
预检索过程(Pre-Retrieval Process)
提示词优化
Advanced Prompt Techniques (Variable Mappings, Functions) - LlamaIndex
提示词改写
这有一篇论文:Query Rewriting for Retrieval-Augmented Large Language Models arxiv.or g/pdf/2305.14283
子查询
llamaindex 查询引擎例子:docs.llamaindex.ai/en/stable/e…
_auto_retrieval/multi_doc_auto_retrieval/
HyDE(假设答案)
有篇论文 Precise Zero-Shot Dense Retrieval without Relevance Labels :arxiv.org/pdf/221 2.10496
Reverse HyDE(假设问题) CoVe
使用Meta AI 提出的Chain-of-Verification:[2309.11495] Chain-of-Verification Reduces Hallucination in Large Language Models,
检索过程(Retrieval)
在条件成本允许的情况下,可以适当地进行微调,从而提升其在垂直领域检索效果。以下是部分文档中介绍的微调方式,我们后面课程会详细讲
编辑
LlamaIndex Embedding 微调方式:github.com/run-llama/f… ain/evaluate.ipynb
编辑
Retrieval Augmentation 微调:docs.llamaindex.ai/en/stable/e… edge/finetune_retrieval_aug.html#fine-tuning-with-retrieval-augmentation
编辑
cross-encoder 交叉编码微调:docs.llamaindex.ai/en/latest/e…
_encoder_finetuning/cross_encoder_finetuning.html#
后检索过程(Post-Retrieval Process)
提示词压缩(Prompt Compression)
llamaindex关于提示词的文档:docs.llamaindex.ai/en/stable/e… prompts/
LLMLingua
论文:aclanthology.org/2023.emnlp-…
LongLLMLingua
论文:aclanthology.org/2024.acl-lo…
LongLLMLingua2
论文:aclanthology.org/2024.findin…
使用llamaindex实例
环境配置
我们继续使用前面langchain例子的python虚环境,不用新建,激活就行
不同LLM环境配置
api_key设置
api_key环境变量和langchain项目方法一样
安装chroma
安装chroma轻量级向量数据库,因为它轻量并且支持windows,不需要wsl,不需要docker
准备数据
在这个例子以及后面的例子中,语料库我们都将使用百度百科关于aigc的知识:baike.baidu.co m/item/AIGC?fromModule=lemma_search-box
完整代码
from llama_index.readers.web import TrafilaturaWebReader from llama_index.core.node_parser import SimpleNodeParser from llama_index.core.schema import IndexNode
from llama_index.embeddings.huggingface import HuggingFaceEmbedding from llama_index.core import VectorStoreIndex, StorageContext
#from llama_index.llms.openai import OpenAI
#from llama_index.embeddings.openai import OpenAIEmbedding from llama_index.llms.ollama import Ollama
from llama_index.core.node_parser import SentenceSplitter from llama_index.core import Settings
import chromadb
from llama_index.vector_stores.chroma import ChromaVectorStore
def prepare_data(): url="baike.baidu.com/item/AIGC?f…" docs = TrafilaturaWebReader().load_data([url])
return docs
#embed保存知识到向量数据库
def embedding_data(docs): #向量数据库客户端
chroma_client = chromadb.EphemeralClient()
chroma_collection = chroma_client.create_collection("quickstart")
#向量数据库,指定了存储位置 vector_store =
ChromaVectorStore(chroma_collection=chroma_collection,persist_dir="./chroma_langc hain_db")
storage_context = StorageContext.from_defaults(vector_store=vector_store)
#创建文档切割器
node_parser = SimpleNodeParser.from_defaults(chunk_size=500,chunk_overlap=50)
#创建BAAI的embedding
embed_model = HuggingFaceEmbedding(model_name="BAAI/bge-small-zh-v1.5") #创建index
base_index = VectorStoreIndex.from_documents(documents=docs,transformations= [node_parser],storage_context=storage_context, embed_model=embed_model)
return base_index,embed_model
#龙哥抖音号:龙哥紫貂智能
def get_llm():
#创建OpenAI的llm
#llm = OpenAI(model="gpt-3.5-turbo")
#通义千问 '''
from llama_index.llms.dashscope import DashScope, DashScopeGenerationModels llm = DashScope(model_name=DashScopeGenerationModels.QWEN_MAX)
'''
#ollama本地模型
llm = Ollama(model="qwen2:7b-instruct-q4_0", request_timeout=120.0)
#创建谷歌gemini的llm # llm = Gemini()
return llm
def retrieve_data(question): #创建检索器
base_retriever = base_index.as_retriever(similarity_top_k=2)
#检索相关文档
retrievals = base_retriever.retrieve( question
)
#print(retrievals)
#docs.llamaindex.ai/en/stable/e…
from llama_index.core.response.notebook_utils import display_source_node
for n in retrievals:
display_source_node(n, source_length=1500)
return retrievals
def generate_answer(question):
query_engine = base_index.as_query_engine()
#大语言模型的回答
response = query_engine.query( question
)
Modular RAG
论文Modular RAG: Transforming RAG Systems into LEGO-like Reconfigurable Frameworks:http s://arxiv.org/pdf/2407.21059
推理阶段
网易开源的QAnything
比如网易开源的QAnything:GitHub - netease-youdao/QAnything: Question and Answer based on Anything.
QAnything使用的检索组件BCEmbedding:GitHub - netease-youdao/BCEmbedding: Netease Youdao's open-source embedding and reranker models for RAG products.有非常强悍的双语和跨语种能力
bce-embedding-base_v1和bce-reranker-base_v1的组合是SOTA
重写-检索-阅读(RRR)
重写-检索-阅读(RRR)也是典型的顺序结构(arxiv.org/pdf/2305.14…)。
条件模式
条件 RAG 的经典实现是semantic-router这个项目:GitHub - aurelio-labs/semantic-router: Superfast AI decision making and intelligent processing of multi-modal data.
llamaindex实现例子代码
迭代检索
迭代检索的一个典型案例是ITER-RETGEN :[2305.15294] Enhancing Retrieval-Augmented Large Language Models with Iterative Retrieval-Generation Synergy,它迭代检索增强和生成增强。
递归检索
1、澄清树(TOC)
论文Tree of Clarifications: Answering Ambiguous Questions with Retrieval-Augmented Large Language Models:arxiv.org/pdf/2310.14…
llamaindex文档:docs.llamaindex.ai/en/stable/e… e_retriever/
自适应(主动)检索
1、基于提示词方法:
一个典型的实现示例是 前瞻式主动检索增强生成 FLARE(Forward-Looking Active Retrieval Augmented Generation):
blog.lancedb.com/better-rag-… 9f/
论文Active Retrieval Augmented Generation:arxiv.org/pdf/2305.06…
llamaindex实现了FLARE instruct
langchain中实现了 FlareChain
下面是FLARE Direct 例子代码
from langchain import PromptTemplate, LLMChain
from langchain.text_splitter import RecursiveCharacterTextSplitter from langchain.chains import RetrievalQA
from langchain.embeddings import HuggingFaceBgeEmbeddings from langchain.document_loaders import PyPDFLoader
from langchain.vectorstores import LanceDB
from langchain.document_loaders import ArxivLoader from langchain.chains import FlareChain
from langchain.prompts import PromptTemplate from langchain.chains import LLMChain import os
import gradio as gr import lancedb
from io import BytesIO
from langchain.llms import OpenAI import getpass
pass your api key
os.environ["OPENAI_API_KEY"] = "sk-yourapikeyforopenai"
llm = OpenAI()
os.environ["OPENAI_API_KEY"] = "sk-yourapikeyforopenai" llm = OpenAI()
model_name = "BAAI/bge-large-en"
model_kwargs = {'device': 'cpu'}
encode_kwargs = {'normalize_embeddings': False} embeddings = HuggingFaceBgeEmbeddings(
model_name=model_name, model_kwargs=model_kwargs, encode_kwargs=encode_kwargs
)
here is example arxiv.org/pdf/2305.06… # you need to pass this number to query 2305.06983
fetch docs from arxiv, in this case it's the FLARE paper
docs = ArxivLoader(query="2305.06983", load_max_docs=2).load() # instantiate text splitter
text_splitter = RecursiveCharacterTextSplitter(chunk_size=1500,
chunk_overlap=150)
split the document into chunks
doc_chunks = text_splitter.split_documents(docs) # lancedb vectordb
db = lancedb.connect('/tmp/lancedb')
table = db.create_table("documentsai", data=[
{"vector": embeddings.embed_query("Hello World"), "text": "Hello World", "id": "1"}
], mode="overwrite")
vector_store = LanceDB.from_documents(doc_chunks, embeddings, connection=table) vector_store_retriever = vector_store.as_retriever()
flare = FlareChain.from_llm( llm=llm, retriever=vector_store_retriever, max_generation_len=300,
min_prob=0.45#任何以低于此概率生成的token都将被视为不确定
)
Define a function to generate FLARE output based on user input def generate_flare_output(input_text):
output = flare.run(input_text) return output
input = gr.Text(
label="Prompt", show_label=False, max_lines=1,
placeholder="Enter your prompt", container=False,
)
iface = gr.Interface(fn=generate_flare_output, inputs=input,
outputs="text", title="My AI bot",
description="FLARE implementation with lancedb & bge embedding.", allow_screenshot=False,
allow_flagging=False
)
iface.launch(debug=True)
2、Tuning-base:
一个典型案例是 Self-RAG(SELF-RAG: LEARNING TO RETRIEVE, GENERATE, AND CRITIQUE THROUGH SELF-REFLECTION)
论文:arxiv.org/pdf/2310.11… github:Self-RAG: Learning to Retrieve, Generate and Critique through Self-Reflection
微调后的模型
llamaindex self_rag 例子代码:首次执行时需要下载 SelfRAGPack
langchain例子深入
让LLM在用户的查询语句的基础上再生成多个查询语句,这些LLM生成的查询语句是从不同角度,不同视角对用户查询语句的补充:
LLM在此基础上又生成了5个问题:
多重查询完整代码
#准备知识库数据,建索引 def prepare_data():
loader = WebBaseLoader("baike.baidu.com/item/AIGC? fromModule=lemma_search-box")
documents = loader.load()
text_splitter = RecursiveCharacterTextSplitter(chunk_size=500, chunk_overlap=50)
chunks = text_splitter.split_documents(documents)
print(chunks[0].page_content)
return chunks
#embedding 知识库,保存到向量数据库
def embedding_data(chunks):
#openai embedding #rag_embeddings=OpenAIEmbeddings()
#创建BAAI的embedding
rag_embeddings = HuggingFaceBgeEmbeddings(model_name="BAAI/bge-small-zh- v1.5")
#embed保存知识到向量数据库
vector_store = Chroma.from_documents(documents=chunks, embedding=rag_embeddings,persist_directory="./chroma_langchain_db")
retriever = vector_store.as_retriever() return vector_store,retriever
#龙 哥抖音号:龙 哥紫 貂智能
#获取多查询,检索出知识,然后RRF排序融合 def get_multiple_queries(question):
Multi Query: Different Perspectives
template = """You are an AI language model assistant. Your task is to generate five
different versions of the given user question to retrieve relevant documents from a vector
database. By generating multiple perspectives on the user question, your goal is to help
the user overcome some of the limitations of the distance-based similarity search.
Provide these alternative questions separated by newlines. Original question:
{question}"""
prompt_perspectives = ChatPromptTemplate.from_template(template) generate_queries = (
prompt_perspectives
| llm
| StrOutputParser()
| (lambda x: x.split("\n"))
)
#生成多个查询
response = generate_queries.invoke({"question":question}) print(response)
#检索出知识
all_results = retrieval_and_rank(response)
#RRF融合
reranked_results = reciprocal_rank_fusion(all_results)
return generate_queries,reranked_results
def get_unique_union(documents: list[list]): """ Unique union of retrieved docs """
Flatten list of lists, and convert each Document to string
flattened_docs = [dumps(doc) for sublist in documents for doc in sublist] # Get unique documents
unique_docs = list(set(flattened_docs))
Return
return [loads(doc) for doc in unique_docs]
#生成答案
def generate_answer(question): '''
#使用通义千问
llm = ChatOpenAI(
api_key=os.getenv("DASHSCOPE_API_KEY"), # 如果您没有配置环境变量,请在此处用您的API Key进行替换
base_url="dashscope.aliyuncs.com/compatible-…", # 填写
DashScope base_url
model="qwen-plus"
)
'''
#使用openai
#llm = ChatOpenAI(model_name="gpt-3.5-turbo", temperature=0)
rag_chain = (
{"context": retriever, "question": RunnablePassthrough()}
| prompt
| llm
| StrOutputParser()
)
resp=rag_chain.invoke(question) print(resp)
#生成答案
def multi_query_generate_answer(question): # RAG
template = """Answer the following question based on this context:
{context}
Question: {question} """
prompt = ChatPromptTemplate.from_template(template)
retrieval_chain = generate_queries | retriever.map() | get_unique_union
final_rag_chain = (
{"context": retrieval_chain,
"question": operator.itemgetter("question")}
| prompt
| llm
| StrOutputParser()
)
response = final_rag_chain.invoke({"question":question}) print(response)
#检索出每一个查询的相关知识,每一个查询对应的相关知识又相似得分,对每一个查询内部进行排名 def retrieval_and_rank(queries):
all_results = {}
for query in queries: if query:
search_results = vector_store.similarity_search_with_score(query) results = []
for res in search_results:
content = res[0].page_content score = res[1] results.append((content, score))
all_results[query] = results
document_ranks = []
for query, doc_score_list in all_results.items(): #每一个查询内部的list排名
ranking_list = [doc for doc, _ in sorted(doc_score_list, key=lambda x: x[1], reverse=True)]
document_ranks.append(ranking_list)
return document_ranks
##对所有查询结果 按照rrf倒排融合
def reciprocal_rank_fusion(document_ranks, k=60): fused_scores = {}
for docs in document_ranks:
for rank, doc in enumerate(docs): doc_str = dumps(doc)
if doc_str not in fused_scores: fused_scores[doc_str] = 0
fused_scores[doc_str] += 1 / (rank + k)
reranked_results = [ (loads(doc), score)
for doc, score in sorted(fused_scores.items(), key=lambda x: x[1], reverse=True)
]
return reranked_results
#使用ollama服务
llm = OllamaLLM(model="qwen2:7b-instruct-q4_0") template = """您是问答任务的助理。
使用以下检索到的上下文来回答问题。
如果你不知道答案,就说你不知道。
最多使用三句话,不超过100字,保持答案简洁。
Question: {question} Context: {context} Answer:
"""
prompt = ChatPromptTemplate.from_template(template)
chunks = prepare_data()
vector_store,retriever = embedding_data(chunks)
query = "艾伦•图灵的论文叫什么"
generate_queries,querys= get_multiple_queries(query)
multi_query_generate_answer(query)
#generate_answer(query)
#生成提示词模版 '''
template = """你是一名智能助手,根据上下文回答用户的问题,不需要回答额外的信息或捏造事实。
已知内容:
{context}
问题:
{question} """
RAG效果评估
RAG评价指标
langchain 的 Criteria Evaluation python.langchain.com/v0.1/docs/g… hain/
Ragas 中的 Aspect Critique
常用评估工具
Ragas
也可以通过 langsmith(LangSmith)来监控每次评估的过程,帮助分析每次评估的原因和观察 API key 的消耗。
TruLens
Llama-Index
phoenix
github开源项目:GitHub - Arize-ai/phoenix: AI Observability & Evaluation
deepeval
GitHub - confident-ai/deepeval: The LLM Evaluation Framework
OpenAI Evals
LangSmith 和 Langfuse:
Evaluation Overview | 🦜️🛠️ LangSmith
使用 RAGAs 评估
github项目地址:GitHub - explodinggradients/ragas: Supercharge Your LLM Application Evaluations 🚀
文档地址:Ragas
环境准备
准备评估数据
在这个例子以及后面的例子中,语料库我们都将使用百度百科关于aigc的知识:baike.baidu.co m/item/AIGC?fromModule=lemma_search-box
操作如下:
评估 RAG
评估指标,可以参考文档:docs.ragas.io/en/stable/c… ics
完整代码
print(chunks[0].page_content)
return chunks
#embedding 知识库,保存到向量数据库
def embedding_data(chunks):
#openai embedding #rag_embeddings=OpenAIEmbeddings()
#创建BAAI的embedding
rag_embeddings = HuggingFaceBgeEmbeddings(model_name="BAAI/bge-small-zh- v1.5")
#embed保存知识到向量数据库
vector_store = Chroma.from_documents(documents=chunks, embedding=rag_embeddings,persist_directory="./chroma_langchain_db")
retriever = vector_store.as_retriever()
return vector_store,retriever,rag_embeddings
#使用ollama服务
llm = OllamaLLM(model="qwen2:7b-instruct-q4_0") template = """您是问答任务的助理。
使用以下检索到的上下文来回答问题。
如果你不知道答案,就说你不知道。
最多使用三句话,不超过100字,保持答案简洁。
Question: {question} Context: {context} Answer:
"""
prompt = ChatPromptTemplate.from_template(template)
chunks = prepare_data()
vector_store,retriever,embedding= embedding_data(chunks)
#生成答案
def ragas_eval(): '''
#使用通义千问
llm = ChatOpenAI(
api_key=os.getenv("DASHSCOPE_API_KEY"), # 如果您没有配置环境变量,请在此处用您的API Key进行替换
base_url="dashscope.aliyuncs.com/compatible-…", # 填写
DashScope base_url
model="qwen-plus"
)
'''
#使用openai
#llm = ChatOpenAI(model_name="gpt-3.5-turbo", temperature=0)
rag_chain = (
{"context": retriever, "question": RunnablePassthrough()}
| prompt
| llm
| StrOutputParser()
)
questions = ["艾伦•图灵的论文叫什么?",
"人工智能生成的画作在佳士得拍卖行卖了什么价格?",
"目前企业在使用相关的AIGC能力时,主要有哪五种方式?",
]
ground_truths = ["计算机器与智能(Computing Machinery and Intelligence )", "2018年,人工智能生成的一幅画作在佳士得拍卖行以43.25万美元的价格成交", "企业在使用AIGC能力时的五种主要方式包括:直接使用、Prompt、LoRA、
Finetune、Train"]
answers = [] contexts = []
Inference
for query in questions: answers.append(rag_chain.invoke(query)) contexts.append([docs.page_content for docs in
retriever.get_relevant_documents(query)])
To dict data = {
"question": questions, "answer": answers, "contexts": contexts, "ground_truth": ground_truths
}
Convert dict to dataset
dataset = Dataset.from_dict(data) return dataset
from ragas import evaluate from ragas.metrics import (
faithfulness, answer_relevancy, context_recall, context_precision,
)
run_config = RunConfig(
使用TruLens 评估
项目官网:www.trulens.org
github地址:GitHub - truera/trulens: Evaluation and Tracking for LLM Experiments
环境准备
ollama本地模型支持
trulens支持的provider:www.trulens.org/reference/t… r/
对ollama的本地模型支持方法 github.com/truera/trul… ls/ollama_quickstart.ipynb
使用litellm支持ollama本地部署的大模型
开始
在这个例子以及后面的例子中,语料库我们都将使用百度百科关于aigc的知识:baike.baidu.co m/item/AIGC?fromModule=lemma_search-box
完整代码
vector_store = ChromaVectorStore(chroma_collection=chroma_collection,persist_dir="./chroma_langc hain_db")
storage_context = StorageContext.from_defaults(vector_store=vector_store)
#创建文档切割器
node_parser = SimpleNodeParser.from_defaults(chunk_size=500,chunk_overlap=50)
#创建BAAI的embedding
embed_model = HuggingFaceEmbedding(model_name="BAAI/bge-small-zh-v1.5") #创建index
base_index = VectorStoreIndex.from_documents(documents=docs,transformations= [node_parser],storage_context=storage_context, embed_model=embed_model)
return base_index,embed_model
def get_llm():
#创建OpenAI的llm
#llm = OpenAI(model="gpt-3.5-turbo")
#通义千问 '''
from llama_index.llms.dashscope import DashScope, DashScopeGenerationModels llm = DashScope(model_name=DashScopeGenerationModels.QWEN_MAX)
'''
#ollama本地模型
llm = Ollama(model="qwen2:7b-instruct-q4_0", request_timeout=120.0)
#创建谷歌gemini的llm # llm = Gemini()
return llm
def retrieve_data(question): #创建检索器
base_retriever = base_index.as_retriever(similarity_top_k=2)
#检索相关文档
retrievals = base_retriever.retrieve( question
)
#print(retrievals)
#docs.llamaindex.ai/en/stable/e…
from llama_index.core.response.notebook_utils import display_source_node
for n in retrievals:
display_source_node(n, source_length=1500)
return retrievals
def generate_answer(question):
query_engine = base_index.as_query_engine()
#大语言模型的回答
response = query_engine.query( question
)
print(str(response))
return query_engine,response
question="艾伦•图灵的论文叫什么" docs=prepare_data() llm=get_llm()
base_index,embed_model=embedding_data(docs)
#通过设置来配置 llm,embedding等等 Settings.llm = llm
Settings.embed_model = embed_model
#Settings.node_parser = SentenceSplitter(chunk_size=512, chunk_overlap=20) Settings.num_output = 512
Settings.context_window = 3000
query_engine = base_index.as_query_engine()
from trulens.core import TruSession
#from trulens_eval import OpenAI as fOpenAI import nest_asyncio
import numpy as np
from trulens.apps.llamaindex import TruLlama from trulens.core import Feedback
import litellm
from trulens.providers.litellm import LiteLLM
from trulens.dashboard import run_dashboard
def prepare_tru(): #设置线程的并发执行
nest_asyncio.apply()
#初始化数据库,它用来存储prompt、reponse、中间结果等信息。
session = TruSession() session.reset_database()
return session
#定义一个provider用来执行反馈 #provider = fOpenAI()
def prepare_feedback():
litellm.set_verbose = False
provider = LiteLLM( model_engine="ollama/qwen2:7b-instruct-q4_0",
api_base="http://localhost:11434"
)
f_answer_relevance = Feedback(
provider.relevance_with_cot_reasons,#反馈函数 name="Answer Relevance"#面板标识
).on_input_output()
context_selection = TruLlama.select_context(query_engine)
f_context_relevance = ( Feedback(provider.context_relevance_with_cot_reasons, name="Context
Relevance")
.on_input()#用户查询
.on(context_selection)#检索结果
.aggregate(np.mean)#合计所有检索结果
)
f_groundedness = ( Feedback(
provider.groundedness_measure_with_cot_reasons, name="Groundedness"
)
.on(context_selection.collect()) # collect context chunks into a list
.on_output()
)
tru_recorder = TruLlama( app=query_engine, app_id="App_longe", feedbacks=[
f_context_relevance, f_answer_relevance, f_groundedness
]
)
面板查看评估结果
运行完整代码后默认下面地址:
可以本地打开dashboard页面查看评估结果:
编辑
Llama-Index评估
文档地址:Redirecting...