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