
文心一言寫代碼:代碼生成力的探索
在設計Doubao知識問答系統(tǒng)時,首先需要明確任務的核心:使用本地文件作為知識庫,通過文本分割和向量數(shù)據(jù)庫的構建,快速搭建一個可以自動回答用戶問題的系統(tǒng)。項目的第一步是對文本數(shù)據(jù)進行處理,將其分割為若干小塊,以便于后續(xù)的向量轉換和數(shù)據(jù)庫嵌入。
為了使項目順利進行,需要創(chuàng)建一個虛擬環(huán)境,并安裝必要的庫。常見的庫包括pypdf
用于PDF文件操作,docx2txt
用于處理Word文檔,以及flask
用于創(chuàng)建前端應用。
conda install conda-forge::pypdf
conda install conda-forge::docx2txt
conda install conda-forge::flask
在代碼分析部分,我們需要導入必要的庫和函數(shù),并確保獲取到所有需要的環(huán)境變量。這些環(huán)境變量包括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
文件加載與文本分割是本地知識庫問答系統(tǒng)構建的基礎步驟。通過加載本地文檔,并使用文本分割器將其分割成適當大小的文本塊,以確保數(shù)據(jù)的可管理性和模型的理解能力。
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)
在數(shù)據(jù)轉換步驟中,通過定義一個繼承自Embeddings
和BaseModel
的自定義類DoubaoEmbeddings
,我們可以將文本數(shù)據(jù)轉換為嵌入向量。
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
創(chuàng)建檢索問答鏈是系統(tǒng)的核心部分,通過實例化大模型對象,并結合多查詢檢測工具,構建一個強大的問答鏈。
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)
問答交互是用戶體驗的直接體現(xiàn),通過Flask框架的使用,我們可以輕松實現(xiàn)一個簡單的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)
通過上述步驟,我們成功地構建了一個可以本地運行的智能問答系統(tǒng)。然而,在實際運行中,可能會遇到一些問題,如答案不準確或系統(tǒng)不穩(wěn)定。這些問題可能與知識庫的構建方式或文本處理的細節(jié)相關。