做这个之前需要先安装一下LangSmith,方便查看提示词和检索的知识库document,因为这里我们需要用到rag的优化策略 LangSmith的功能
看每一步 prompt / chain 在干嘛
记录调用日志(trace)
找 bug(为什么模型答错)
做评测(哪个 prompt 更好)安装步骤
1.安装
2.注册 + 拿 API Key 去官网:https://smith.langchain.com
拿到 API key 后,设置环境变量:写在.env就好
1 2 3 4 5 # langsmith 配置 LANGSMITH_TRACING=true LANGSMITH_ENDPOINT=https://api.smith.langchain.com LANGSMITH_API_KEY=lsv2...............................................7c LANGSMITH_PROJECT="nangua"
这样就好了,记得重启环境和load_dotenv()
这边说说什么是 ,RAG融合吧(rag_fusion) ,核心的话就是两点
把单一问题变成多角度的(用LLM在检索前改写)
对得到的chunk进行打分重新排序ps:注意哦,这个在你切分得到chunks,准备初始化Chroma数据库的时候,先给chunks的meta加一个id属性,方便后面辨认chunk是不是同一个
1 2 3 4 5 6 7 chunks=text_splitter.split_documents(doc) for i, doc in enumerate (chunks): doc.metadata["id" ] = f"doc_{i} "
具体而言分以下步骤
1 写一个专门改写生成多个问题的链条 1.1 定义一个prompt 1 2 3 4 5 6 7 8 #定义多问题的prompt prompt_perspectives=ChatPromptTemplate.from_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. Provide these alternative questions separated by newlines. Original question: {question}"""
1.2 定义一个链条 1 2 3 4 5 6 7 8 generate_queries = ( prompt_perspectives | ChatOpenAI(temperature=0) | StrOutputParser() | (lambda x: x.split("\n")) )
肉眼可以直接看出吧?这里得到的肯定是一个list[document]老朋友了。然后我们要用这五个问题去检索。生成结果类似这种。
2 对检索的Chunk排序打分 有五个问题嘛,假设我们一个问题取3个相似最高的chunk嘛,那不就是一个二维数组, 5×3吗~注意哦他 检索给我们返回的顺序也是很重要的,越靠前的语义相似度最高 。那我们现在要做的就是对这个二维列表里的chunk再排序,这次我们排序的依据是 重复次数 ,
这个是打分的函数 其中;
rank :文档在当前列表中的位置(0-based)
k :平滑常数(代码中k=60),防止分母为0,调节排名影响
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 def rec (result: list [list ], k=60 ): fused_scores = {} for docs in result: for rank, doc in enumerate (docs): doc_id = doc.metadata.get('id' ) if doc_id not in fused_scores: fused_scores[doc_id] = [doc, 0 ] fused_scores[doc_id][1 ] += 1 / (rank + k) reranked_result = sorted ( fused_scores.values(), key=lambda x: x[1 ], reverse=True ) return reranked_result