get_similarity.py 5.88 KB
Newer Older
1
from src.pgdb.knowledge.similarity import VectorStore_FAISS
tinywell committed
2
from .rerank import BgeRerank
3

4 5 6 7 8

from langchain_core.prompts import PromptTemplate
from langchain_core.output_parsers.list import ListOutputParser


9 10 11 12
class GetSimilarity:
    def __init__(self, _question, _faiss_db: VectorStore_FAISS):
        self.question = _question
        self.faiss_db = _faiss_db
13 14
        self.similarity_docs = self.faiss_db.get_text_similarity(self.question)
        self.similarity_doc_txt = self.faiss_db.join_document(self.similarity_docs)
15
        self.rerank_docs = ""
16

tinywell committed
17
    def get_rerank(self,reranker:BgeRerank ,top_k = 5):
18
        rerank_docs = reranker.compress_documents(self.similarity_docs,self.question)
19 20 21 22 23
        d_list = []
        for d in rerank_docs[:top_k]:
            d_list.append(d)
        self.rerank_docs = rerank_docs[:top_k]
        return self.faiss_db.join_document(d_list)
tinywell committed
24

25
    def get_similarity_doc(self):
26 27 28 29
        return self.similarity_doc_txt
    
    def get_similarity_docs(self):
        return self.similarity_docs
tinywell committed
30 31 32
    
    def get_rerank_docs(self):
        return self.rerank_docs
33

文靖昊 committed
34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66

class GetSimilarityWithExt:
    def __init__(self, _question, _faiss_db: VectorStore_FAISS):
        self.question = _question
        self.faiss_db = _faiss_db
        self.similarity_docs = self.get_text_similarity_with_ext()
        self.similarity_doc_txt = self.faiss_db.join_document(self.similarity_docs)
        self.rerank_docs = ""

    def get_rerank(self, reranker: BgeRerank, top_k=5):
        question = '\n'.join(self.question)
        print(question)
        rerank_docs = reranker.compress_documents(self.similarity_docs, question)
        d_list = []
        for d in rerank_docs[:top_k]:
            d_list.append(d)
        self.rerank_docs = rerank_docs[:top_k]
        return self.faiss_db.join_document(d_list)

    def get_similarity_doc(self):
        return self.similarity_doc_txt

    def get_similarity_docs(self):
        return self.similarity_docs

    def get_rerank_docs(self):
        return self.rerank_docs

    def get_text_similarity_with_ext(self):
        similarity_docs = []
        for q in self.question:
            similarity_doc = self.faiss_db.get_text_similarity(q)
            similarity_docs.extend(similarity_doc)
文靖昊 committed
67 68 69 70 71 72 73 74
        content_set = set()
        unique_documents = []
        for doc in similarity_docs:
            content = hash(doc.page_content)
            if content not in content_set:
                unique_documents.append(doc)
                content_set.add(content)
        return unique_documents
文靖昊 committed
75 76


77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158
DEFAULT_PROMPT = """作为一个向量检索助手,你的任务是结合历史记录,从不同角度,为“原问题”生成个不同版本的“检索词”,从而提高向量检索的语义丰富度,提高向量检索的精度。生成的问题要求指向对象清晰明确,并与“原问题语言相同”。例如:
历史记录: 
'''
'''
原问题: 介绍下剧情。
检索词: ["介绍下故事的背景。","故事的主题是什么?","介绍下故事的主要人物。"]
----------------
历史记录: 
'''
Q: 对话背景。
A: 当前对话是关于 Nginx 的介绍和使用等。
'''
原问题: 怎么下载
检索词: ["Nginx 如何下载?","下载 Nginx 需要什么条件?","有哪些渠道可以下载 Nginx?"]
----------------
历史记录: 
'''
Q: 对话背景。
A: 当前对话是关于 Nginx 的介绍和使用等。
Q: 报错 "no connection"
A: 报错"no connection"可能是因为……
'''
原问题: 怎么解决
检索词: ["Nginx报错"no connection"如何解决?","造成'no connection'报错的原因。","Nginx提示'no connection',要怎么办?"]
----------------
历史记录: 
'''
Q: 护产假多少天?
A: 护产假的天数根据员工所在的城市而定。请提供您所在的城市,以便我回答您的问题。
'''
原问题: 沈阳
检索词: ["沈阳的护产假多少天?","沈阳的护产假政策。","沈阳的护产假标准。"]
----------------
历史记录: 
'''
Q: 作者是谁?
A: FastGPT 的作者是 labring。
'''
原问题: Tell me about him
检索词: ["Introduce labring, the author of FastGPT." ," Background information on author labring." "," Why does labring do FastGPT?"]
----------------
历史记录:
'''
Q: 对话背景。
A: 关于 FatGPT 的介绍和使用等问题。
'''
原问题: 你好。
检索词: ["你好"]
----------------
历史记录:
'''
Q: FastGPT 如何收费?
A: FastGPT 收费可以参考……
'''
原问题: 你知道 laf 么?
检索词: ["laf 的官网地址是多少?","laf 的使用教程。","laf 有什么特点和优势。"]
----------------
历史记录:
'''
Q: FastGPT 的优势
A: 1. 开源
   2. 简便
   3. 扩展性强
'''
原问题: 介绍下第2点。
检索词: ["介绍下 FastGPT 简便的优势", "从哪些方面,可以体现出 FastGPT 的简便"]。
----------------
历史记录:
'''
Q: 什么是 FastGPT?
A: FastGPT 是一个 RAG 平台。
Q: 什么是 Laf?
A: Laf 是一个云函数开发平台。
'''
原问题: 它们有什么关系?
检索词: ["FastGPT和Laf有什么关系?","介绍下FastGPT","介绍下Laf"]
----------------
历史记录:
'''
{histories}
'''
原问题: {query}
tinywell committed
159
检索词: """
160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189


class QAExt:
    llm = None

    def __init__(self, llm) -> None:
        self.llm = llm
        prompt = PromptTemplate.from_template(DEFAULT_PROMPT)
        # parser = ListOutputParser()
        self.query_extend = prompt | llm 

    def extend_query(self, question, messages=None):
        """
            question: str
            messages: list of tuple (str,str)
                eg:
                [
                    ("Q1","A1"),
                    ("Q2","A2"),
                    ...
                ]
            
        """
        if not messages:
            messages = []
        history = ""
        for msg in messages:
            history += f"Q: {msg[0]}\nA: {msg[1]}\n"
        return self.query_extend.invoke(input={"histories":messages, "query":question})