所有文章 > 日积月累 > Doubao 本地知识库:构建高效知识问答系统的指南
Doubao 本地知识库:构建高效知识问答系统的指南

Doubao 本地知识库:构建高效知识问答系统的指南

调用火山引擎大语言模型 & Embedding向量模型

在构建一个高效的本地知识库问答系统时,使用火山引擎大语言模型和Embedding向量模型是一个非常有效的方法。这种方法通过将文本数据转化为大模型可以理解的向量数据,从而实现快速、准确的问答系统构建。

火山引擎大语言模型

项目分析

在设计Doubao知识问答系统时,首先需要明确任务的核心:使用本地文件作为知识库,通过文本分割和向量数据库的构建,快速搭建一个可以自动回答用户问题的系统。项目的第一步是对文本数据进行处理,将其分割为若干小块,以便于后续的向量转换和数据库嵌入。

环境相关

为了使项目顺利进行,需要创建一个虚拟环境,并安装必要的库。常见的库包括pypdf用于PDF文件操作,docx2txt用于处理Word文档,以及flask用于创建前端应用。

conda install conda-forge::pypdf
conda install conda-forge::docx2txt
conda install conda-forge::flask

环境设置

代码分析

导入相关库/函数,获取环境变量

在代码分析部分,我们需要导入必要的库和函数,并确保获取到所有需要的环境变量。这些环境变量包括API密钥、模型端点等。

import os
import logging
from volcenginesdkarkruntime import Ark
from langchain_openai import ChatOpenAI
from langchain.embeddings.base import Embeddings
from pydantic import BaseModel
from typing import Dict, List, Any

文件加载与文本分割

文件加载与文本分割是本地知识库问答系统构建的基础步骤。通过加载本地文档,并使用文本分割器将其分割成适当大小的文本块,以确保数据的可管理性和模型的理解能力。

base_dir = os.path.dirname(os.path.abspath(__file__))
folder_path = os.path.join(base_dir, 'docums')
documents = []
for file in os.listdir(folder_path):
    file_path = os.path.join(folder_path, file)
    if file.endswith('.pdf'):
        loader = PyPDFLoader(file_path)
        documents.extend(loader.load())
    elif file.endswith('.docx'):
        loader = Docx2txtLoader(file_path)
        documents.extend(loader.load())
    elif file.endswith('.txt'):
        loader = TextLoader(file_path)
        documents.extend(loader.load())

text_splitter = RecursiveCharacterTextSplitter(chunk_size=200, chunk_overlap=30)
chunk_docs = text_splitter.split_documents(documents)

文本分割示例

数据转换

在数据转换步骤中,通过定义一个继承自EmbeddingsBaseModel的自定义类DoubaoEmbeddings,我们可以将文本数据转换为嵌入向量。

class DoubaoEmbeddings(BaseModel, Embeddings):
    client: Ark = None
    api_key: str = ""
    model: str

    def __init__(self, **data: Any,):
        super().__init__(**data)
        self.client = Ark(
            base_url=url,
            api_key=self.api_key,
        )

    def embed_query(self, text: str) -> List[float]:
        embeddings = self.client.embeddings.create(model=self.model, input=text)
        return embeddings.data[0].embedding

    def embed_documents(self, texts: List[str]) -> List[List[float]]:
        return [self.embed_query(text) for text in texts]

    class Config:
        arbitrary_types_allowed = True

创建检索问答链

创建检索问答链是系统的核心部分,通过实例化大模型对象,并结合多查询检测工具,构建一个强大的问答链。

logging.basicConfig()
logging.getLogger("langchain.retrievers.multi_query").setLevel(logging.INFO)

llm = ChatOpenAI(
    openai_api_key=api_key,
    openai_api_base=url,
    model=model,
    temperature=0,
)

retriever_llm = MultiQueryRetriever.from_llm(retriever=vectorstore.as_retriever(), llm=llm)
retrieval_chain = RetrievalQA.from_chain_type(llm, retriever=retriever_llm)

问答链示例

问答交互

问答交互是用户体验的直接体现,通过Flask框架的使用,我们可以轻松实现一个简单的Web界面,供用户输入问题并获得实时答案。

template_path = os.path.join(base_dir, 'templates')
app = Flask(__name__, template_folder=template_path)

@app.route('/', methods=['GET', 'POST'])
def homepage():
    if request.method == 'POST':
        question = request.form.get('question')
        result = retrieval_chain({'query': question})
        return render_template('index.html', result=result)
    return render_template('index.html')

if __name__ == "__main__":
    app.run(host='127.0.0.1', debug=True, port=5000)

问答交互界面

运行结果与总结

通过上述步骤,我们成功地构建了一个可以本地运行的智能问答系统。然而,在实际运行中,可能会遇到一些问题,如答案不准确或系统不稳定。这些问题可能与知识库的构建方式或文本处理的细节相关。

FAQ

1. 问:如何确保知识库中的信息是最新的?

  • 答:通过定期更新知识库的数据源,并使用动态知识更新技术,确保知识库中的信息始终是最新的。

2. 问:可以在系统中添加多种数据格式吗?

  • 答:是的,系统支持多种数据格式,包括PDF、Word文档和纯文本文件。

3. 问:如何优化问答系统的性能?

  • 答:可以通过优化向量数据库的检索算法、调整文本分割参数以及增加硬件资源来提升系统的性能。

4. 问:为何系统有时会回答“不知道”?

  • 答:这可能是由于知识库中缺乏相关信息或检索算法未能准确匹配到相关内容。

5. 问:如何确保系统的可扩展性?

  • 答:通过模块化设计和使用可扩展的技术栈,如Flask和Qdrant,可以有效地提升系统的可扩展性。
#你可能也喜欢这些API文章!