精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

開發(fā)arXiv論文引擎機(jī)器人程序:基于RAG+LangChain+Chainlit+ChromaDB 原創(chuàng)

發(fā)布于 2024-6-3 09:26
瀏覽
0收藏

本文將完整細(xì)致地介紹如何使用RAG技術(shù)與LangChain、Chainlit Copilot組件以及Literal AI可觀測性特征聯(lián)合開發(fā)一款語義論文搜索引擎程序。

簡介

在本文中,我將演示如何使用檢索增強(qiáng)生成(RAG)技術(shù)構(gòu)建語義研究論文引擎。具體地說,我將使用LangChain(https://www.langchain.com/)作為構(gòu)建語義引擎的主要框架,以及OpenAI公司的大語言模型和ChromaDB開源向量數(shù)據(jù)庫(https://www.trychroma.com/)。為了構(gòu)建名稱為Copilot的嵌入式Web應(yīng)用程序,我將使用Chainlit中的Copilot插件功能,并結(jié)合Literal AI公司(https://literalai.com/)的可觀察性特征。借助于該應(yīng)用程序,用戶可以更容易地查找相關(guān)論文,從而促進(jìn)學(xué)術(shù)研究。用戶還可以通過詢問有關(guān)推薦論文的問題直接與內(nèi)容互動(dòng)。最后,我們將在應(yīng)用程序中集成可觀察性特征,以便跟蹤和調(diào)試對(duì)LLM的調(diào)用。整個(gè)應(yīng)用程序的架構(gòu)如下圖所示。

開發(fā)arXiv論文引擎機(jī)器人程序:基于RAG+LangChain+Chainlit+ChromaDB-AI.x社區(qū)

Copilot嵌入式語義研究論文應(yīng)用程序整體架構(gòu)

以下先來看一下我們將在本教程中介紹的所有內(nèi)容的概覽:

  • 使用OpenAI、LangChain和ChromaDB開發(fā)RAG管道,以處理和檢索arXiv API中最相關(guān)的PDF文檔。
  • 使用Copilot插件開發(fā)Chainlit應(yīng)用程序,用于在線論文檢索。
  • 使用Literal AI公司的LLM可觀察性特征進(jìn)一步增強(qiáng)本應(yīng)用程序功能。

開發(fā)arXiv論文引擎機(jī)器人程序:基于RAG+LangChain+Chainlit+ChromaDB-AI.x社區(qū)

Copilot嵌入式語義研究論文引擎的運(yùn)行時(shí)快照

注意,本教程中的完整示例工程代碼可以在GitHub地址https://github.com/tahreemrasul/semantic_research_engine處找到:

開發(fā)arXiv論文引擎機(jī)器人程序:基于RAG+LangChain+Chainlit+ChromaDB-AI.x社區(qū)

環(huán)境設(shè)置

首先,我們要?jiǎng)?chuàng)建一個(gè)新的conda環(huán)境:

conda create -n semantic_research_engine python=3.10

然后,使用如下命令激活環(huán)境:

conda activate semantic_research_engine

最后,通過運(yùn)行以下命令,在激活的環(huán)境中安裝所有必需的依賴項(xiàng):

pip install -r requirements.txt

RAG管道創(chuàng)建

檢索增強(qiáng)生成(RAG)是一種流行的技術(shù),允許你使用自己的數(shù)據(jù)構(gòu)建自定義的對(duì)話式人工智能應(yīng)用程序。RAG的原理相當(dāng)簡單:我們將文本數(shù)據(jù)轉(zhuǎn)換為向量嵌入,并將其插入向量數(shù)據(jù)庫;然后將該數(shù)據(jù)庫鏈接到大型語言模型(LLM)。需要說明的是,我們將限制LLM從自己的數(shù)據(jù)庫中獲取信息,而不是依賴先驗(yàn)知識(shí)來回答用戶查詢。在接下來的幾個(gè)步驟中,我將詳細(xì)介紹如何為我們的語義研究論文引擎做到這一點(diǎn)。我們將創(chuàng)建一個(gè)名為rag_test.py的測試腳本來理解和構(gòu)建RAG管道的組件。之后,這些組件將在構(gòu)建我們的集成Copilot插件的Chainlit應(yīng)用程序時(shí)重復(fù)使用。

步驟1:注冊(cè)賬戶

需要注冊(cè)一個(gè)賬戶,以便保護(hù)OpenAI API密鑰。完成后,在項(xiàng)目目錄中創(chuàng)建一個(gè).env文件,并添加該OpenAI API密鑰,如下所示:

OPENAI_API_KEY="your_openai_api_key"

在本文應(yīng)用程序中,我們將使用這個(gè).env文件來存儲(chǔ)我們項(xiàng)目的所有API密鑰。

步驟2:輸入數(shù)據(jù)

在這一步中,我們將創(chuàng)建一個(gè)數(shù)據(jù)庫來存儲(chǔ)針對(duì)用戶查詢的研究論文。為此,我們首先需要從arXiv API中檢索相關(guān)論文的列表以進(jìn)行查詢。我們將使用LangChain的ArxivLoader包,因?yàn)榇税橄罅伺cAPI的交互,然后檢索論文以供進(jìn)一步處理。我們可以將這些論文分割成更小的塊,以確保以后的高效處理和相關(guān)信息檢索。

為此,我們將使用LangChain中的RecursiveTextSplitter()函數(shù),因?yàn)樗梢源_保在分割文檔時(shí)信息的語義保留。接下來,我們將使用HuggingFace(https://python.langchain.com/docs/integrations/platforms/huggingface/#embedding-models)中的sentence-transformers嵌入為這些塊創(chuàng)建嵌入。最后,我們將把這些分割文檔嵌入到ChromaDB數(shù)據(jù)庫中進(jìn)行進(jìn)一步查詢。

# rag_test.py 
from langchain_community.document_loaders import ArxivLoader
from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain_community.vectorstores import Chroma
from langchain_community.embeddings import HuggingFaceEmbeddings

query = "lightweight transformer for language tasks"
arxiv_docs = ArxivLoader(query=query, load_max_docs=3).load()
pdf_data = []
for doc in arxiv_docs:
    text_splitter = RecursiveCharacterTextSplitter(
                    chunk_size=1000,
                    chunk_overlap=100)
    texts = text_splitter.create_documents([doc.page_content])
    pdf_data.append(texts)

embeddings = HuggingFaceEmbeddings(model_name="sentence-transformers/all-MiniLM-l6-v2")
db = Chroma.from_documents(pdf_data[0], embeddings)

步驟3:檢索和生成

一旦創(chuàng)建了特定主題的數(shù)據(jù)庫,我們就可以使用該數(shù)據(jù)庫作為檢索器,并根據(jù)提供的上下文回答用戶問題。LangChain提供了一些不同的檢索鏈,我們將在本教程中使用最簡單的RetrievalQA鏈。我們將使用from_chain_type()方法設(shè)置此鏈,指定模型和檢索器。對(duì)于LLM中的文檔集成,我們將使用stuff鏈類型,因?yàn)樗軌驅(qū)⑺形臋n填充到一個(gè)提示中。

# rag_test.py
from langchain.chains import RetrievalQA
from langchain_openai import OpenAI
from dotenv import load_dotenv

load_dotenv()
llm = OpenAI(model='gpt-3.5-turbo-instruct', temperature=0)
qa = RetrievalQA.from_chain_type(llm=llm, 
                                 chain_type="stuff", 
                                 retriever=db.as_retriever())

question = "how many and which benchmark datasets and tasks were 
            compared for light weight transformer?"
result = qa({"query": question})

現(xiàn)在,我們已經(jīng)介紹了arXiv API的在線檢索以及RAG管道的數(shù)據(jù)輸入和檢索步驟。接下來,我們將著手開發(fā)語義研究引擎Web應(yīng)用程序。

理解Literal AI可觀察性特征

Literal AI(https://literalai.com/)是一個(gè)提供可觀察性特征并能夠進(jìn)行評(píng)估和分析的平臺(tái),用于構(gòu)建生產(chǎn)級(jí)LLM應(yīng)用程序。歸納起來看,Literal AI提供的一些關(guān)鍵功能包括:

  • 可觀察性:能夠監(jiān)控LLM應(yīng)用程序,包括對(duì)話、中間步驟、提示等。
  • 數(shù)據(jù)集:允許創(chuàng)建混合生產(chǎn)數(shù)據(jù)和手寫示例的數(shù)據(jù)集。
  • 在線評(píng)估:允許使用不同的評(píng)估器評(píng)估線程和生產(chǎn)中的執(zhí)行。
  • 提示詞管理:允許對(duì)提示詞進(jìn)行迭代、版本控制和部署。

我們將使用可觀察性和提示迭代功能來評(píng)估和調(diào)試我們的語義研究論文應(yīng)用程序進(jìn)行的諸多調(diào)用。

使用Literal AI提示詞管理

在創(chuàng)建對(duì)話式人工智能應(yīng)用程序時(shí),開發(fā)人員需要迭代多個(gè)版本的提示,以獲得產(chǎn)生最佳結(jié)果的提示詞。提示工程在大多數(shù)LLM任務(wù)中起著至關(guān)重要的作用,因?yàn)槲⑿〉男薷木涂梢燥@著改變語言模型的響應(yīng)。Literal AI提示詞管理可以用來簡化這個(gè)過程。一旦選擇了模型提供程序,就可以輸入初始提示模板,添加任何其他信息,并反復(fù)完善提示以找到最合適的提示。在接下來的幾個(gè)步驟中,我們將使用這個(gè)功能為我們的應(yīng)用程序找到最佳提示信息。

步驟1

首先,我們需要使用瀏覽器打開Literal AI管理控制臺(tái)(https://cloud.getliteral.ai/)來創(chuàng)建API密鑰。為此,需要注冊(cè)一個(gè)帳戶,導(dǎo)航到項(xiàng)目(“projects”)頁面,然后創(chuàng)建新項(xiàng)目。每個(gè)項(xiàng)目都有其唯一的API密鑰。在設(shè)置(“Settings”)選項(xiàng)卡上,你將在API密鑰部分找到你自己的API密鑰。最后,將其添加到.env文件中:

LITERAL_API_KEY="your_literal_api_key"

步驟2

在左側(cè)邊欄中,單擊“提示(Prompts)”,然后導(dǎo)航到“新建提示(New Prompt)”。這將打開一個(gè)新的提示創(chuàng)建會(huì)話。

開發(fā)arXiv論文引擎機(jī)器人程序:基于RAG+LangChain+Chainlit+ChromaDB-AI.x社區(qū)

Literal AI平臺(tái)的提示面板

進(jìn)入相應(yīng)界面后,在左側(cè)邊欄的模板(Template)部分添加一條新的系統(tǒng)(System)消息。括號(hào)中的任何內(nèi)容都將被添加到變量(Variables)中,并被視為提示中的輸入:

You are a helpful assistant. Use provided {{context}} to answer user 
{{question}}. Do not use prior knowledge. 
Answer:

接下來,在右側(cè)欄中,你可以提供你的OpenAI API密鑰。選擇參數(shù),如“模型(Model)”、“溫度(Temperature)”和“最大完成長度(Maximum Length)”等,以便配合提示詞使用。

開發(fā)arXiv論文引擎機(jī)器人程序:基于RAG+LangChain+Chainlit+ChromaDB-AI.x社區(qū)

Literal AI提示詞管理界面

對(duì)提示版本感到滿意后,單擊“保存(Save)”。系統(tǒng)將提示你輸入提示的名稱和可選說明。我們可以將此版本添加到我們的代碼中。在名為search_engine.py的新腳本中,添加以下代碼:

#search_engine.py
from literalai import LiteralClient
from dotenv import load_dotenv

load_dotenv()

client = LiteralClient()

# 下面的代碼將會(huì)使用最新版本,你也可以選擇使用特定版本
prompt = client.api.get_prompt(name="test_prompt")
prompt = prompt.to_langchain_chat_prompt_template()
prompt.input_variables = ["context", "question"]

Literal AI允許你保存提示詞對(duì)應(yīng)的不同的運(yùn)行結(jié)果,并具有版本管理功能。你還可以查看每個(gè)版本與上一個(gè)版本的不同之處。默認(rèn)情況下,最新版本會(huì)被取消。如果你想將某個(gè)版本更改為最新版本,你可以在管理面板上選擇它,然后單擊“升級(jí)(Promote)”。

開發(fā)arXiv論文引擎機(jī)器人程序:基于RAG+LangChain+Chainlit+ChromaDB-AI.x社區(qū)

Literal AI面板提示詞版本管理

添加上述代碼后,我們將能夠在Literal AI 控制面板中查看特定提示的生成結(jié)果(稍后將對(duì)此進(jìn)行詳細(xì)介紹)。

理解Chainlit的Copilot組件功能

Chainlit(https://github.com/Chainlit/chainlit)是一個(gè)開源Python包,旨在構(gòu)建可用于生產(chǎn)級(jí)別的對(duì)話式人工智能應(yīng)用程序。這個(gè)包能夠?yàn)閹讉€(gè)事件(聊天開始、用戶消息、會(huì)話恢復(fù)、會(huì)話停止等)提供裝飾器支持。你可以查看鏈接處https://medium.com/@tahreemrasul/building-a-chatbot-application-with-chainlit-and-langchain-3e86da0099a6?source=post_page-----9c345fcd1cd8--------------------------------我撰寫的文章,了解更全面的解釋。

在本教程中,我們將重點(diǎn)關(guān)注使用Chainlit為我們的RAG應(yīng)用程序構(gòu)建軟件Copilot。Chainlit Copilot能夠在我們的應(yīng)用程序中提供上下文指導(dǎo)和自動(dòng)化用戶操作功能。

開發(fā)arXiv論文引擎機(jī)器人程序:基于RAG+LangChain+Chainlit+ChromaDB-AI.x社區(qū)

使用相關(guān)工具構(gòu)建的研究論文應(yīng)用程序架構(gòu)

開發(fā)Copilot應(yīng)用程序

在你的應(yīng)用程序網(wǎng)站中嵌入一個(gè)Copilot組件可能很有用。原因有幾個(gè):我們將為我們的語義研究論文引擎構(gòu)建一個(gè)簡單的Web界面,并在其中集成一個(gè)Copilot組件。這個(gè)Copilot組件將提供幾項(xiàng)不同的功能,但以下是最突出的幾個(gè)功能:

  • 它將嵌入到我們網(wǎng)站的HTML文件中。
  • Copilot組件將能夠代表用戶采取相應(yīng)的動(dòng)作。假設(shè)用戶要求提供關(guān)于某個(gè)特定主題的在線研究論文。這些要求可以在一個(gè)模態(tài)對(duì)話框中顯示,我們可以配置Copilot組件自動(dòng)完成,而無需用戶輸入。

在接下來的幾個(gè)步驟中,我將詳細(xì)介紹如何使用Chainlit為我們的語義研究引擎創(chuàng)建軟件中的Copilot組件。

步驟1

第一步涉及為我們的chailit應(yīng)用程序編寫邏輯。我們將在本項(xiàng)目中使用兩個(gè)chailit裝飾器函數(shù):@cl.on_chat_start和@cl.on_message。我們將把來自在線搜索和RAG管道的邏輯添加到這些功能中。需要記住的幾件事:

  • @cl.on_chat_start中將包含在新用戶會(huì)話開始時(shí)需要執(zhí)行的所有代碼。
  • @cl.on_message中將包含用戶發(fā)送新消息時(shí)需要執(zhí)行的所有代碼。

我們將封裝從接收研究主題到創(chuàng)建數(shù)據(jù)庫以及在@cl.on_chat_start裝飾器函數(shù)中接收文檔的整個(gè)過程。

首先,需要在search_engine.py腳本中,導(dǎo)入所有必要的模塊和庫:

# search_engine.py
import chainlit as cl
from langchain_community.document_loaders import ArxivLoader
from langchain_community.vectorstores import Chroma
from langchain_community.embeddings import HuggingFaceEmbeddings
from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain.chains import RetrievalQA
from langchain_openai import ChatOpenAI
from dotenv import load_dotenv

load_dotenv()

現(xiàn)在,讓我們添加@cl.on_chat_start裝飾器的代碼。我們將使此函數(shù)以異步方式執(zhí)行,以確保多個(gè)任務(wù)可以同時(shí)運(yùn)行。

# search_engine.py
# contd.

@cl.on_chat_start
async def retrieve_docs():
    # QUERY PORTION
    arxiv_query = None
    # 等待用戶輸入一個(gè)標(biāo)題
    while arxiv_query is None:
        arxiv_query = await cl.AskUserMessage(
            content="Please enter a topic to begin!", timeout=15).send()
    query = arxiv_query['output']

    # ARXIV文檔部分
    arxiv_docs = ArxivLoader(query=arxiv_query, load_max_docs=3).load()
    # 準(zhǔn)備arXiv結(jié)果,用于顯示
    arxiv_papers = [f"Published: {doc.metadata['Published']} \n "
                    f"Title: {doc.metadata['Title']} \n "
                    f"Authors: {doc.metadata['Authors']} \n "
                    f"Summary: {doc.metadata['Summary'][:50]}... \n---\n"
                    for doc in arxiv_docs]

    await cl.Message(content=f"{arxiv_papers}").send()

    await cl.Message(content=f"Downloading and chunking articles for {query} "
                             f"This operation can take a while!").send()

    #數(shù)據(jù)庫部分
    pdf_data = []
    for doc in arxiv_docs:
        text_splitter = RecursiveCharacterTextSplitter(
                        chunk_size=1000, chunk_overlap=100)
        texts = text_splitter.create_documents([doc.page_content])
        pdf_data.append(texts)
  
    llm = ChatOpenAI(model='gpt-3.5-turbo',
                         temperature=0)
    embeddings = HuggingFaceEmbeddings(
                 model_name="sentence-transformers/all-MiniLM-l6-v2")
    db = Chroma.from_documents(pdf_data[0], embeddings)

    # 鏈部分
    chain = RetrievalQA.from_chain_type(llm=llm,
                                            chain_type="stuff",
                                            retriever=db.as_retriever(),
                                            chain_type_kwargs={
                                                "verbose": True,
                                                "prompt": prompt
                                            }
                                            )

    # 讓用戶知道管道已經(jīng)準(zhǔn)備到位
    await cl.Message(content=f"Database creation for `{query}` complete. "
                             f"You can now ask questions!").send()

    cl.user_session.set("chain", chain)
    cl.user_session.set("db", db)

讓我們來看看這個(gè)函數(shù)中包含的代碼:

提示用戶查詢:我們首先讓用戶發(fā)送一個(gè)研究主題。在用戶提交主題之前,此函數(shù)不會(huì)繼續(xù)往下執(zhí)行。

  • 在線搜索:我們使用LangChain的arXiv搜索包裝器檢索相關(guān)論文,并以可讀的格式顯示每個(gè)條目中的相關(guān)字段。
  • 輸入數(shù)據(jù):接下來,我們對(duì)文章進(jìn)行分組,并創(chuàng)建嵌入以供進(jìn)一步處理。大塊可以確保有效地處理長論文。然后,從處理過的文檔塊和嵌入中創(chuàng)建Chroma數(shù)據(jù)庫。
  • 檢索:最后,我們建立了RetrievalQA鏈,將LLM和新創(chuàng)建的數(shù)據(jù)庫集成為檢索器。我們還提供了之前在Literal AI管理界面中創(chuàng)建的提示。
  • 存儲(chǔ)變量:我們使用cl.user_session.set功能將鏈和數(shù)據(jù)庫存儲(chǔ)在變量中,以便以后重用。
  • 用戶消息:我們?cè)谡麄€(gè)函數(shù)中使用Chainlit的cl.Message功能來與用戶交互。

現(xiàn)在,讓我們定義@cl.on_message函數(shù),并添加RAG管道的生成部分。用戶應(yīng)該能夠從獲取的論文中提出問題,應(yīng)用程序應(yīng)該提供相關(guān)答案。

@cl.on_message
async def retrieve_docs(message: cl.Message):
    question = message.content
    chain = cl.user_session.get("chain")
    db = cl.user_session.get("db")
    # 為每次調(diào)用創(chuàng)建一個(gè)新的回調(diào)處理程序?qū)嵗?    cb = client.langchain_callback()
    variables = {"context": db.as_retriever(search_kwargs={"k": 1}), 
                 "query": question}
    database_results = await chain.acall(variables,
                                         callbacks=[cb])
    results = [f"Question: {question} "
               f"\n Answer: {database_results['result']}"]
    await cl.Message(results).send()

以下是上面函數(shù)中代碼的各功能說明:

  • 鏈和數(shù)據(jù)庫檢索:我們首先從用戶會(huì)話中檢索以前存儲(chǔ)的鏈和數(shù)據(jù)庫。
  • LangChain回調(diào)集成:為了確保我們能夠跟蹤我們的提示和使用特定提示版本的所有生成結(jié)果,我們需要在調(diào)用我們的鏈時(shí)添加來自Literal AI的LangChain回調(diào)處理程序。我們使用的是LiteralClient實(shí)例中的langchain_callback()方法創(chuàng)建回調(diào)處理程序。此回調(diào)會(huì)自動(dòng)將所有LangChain交互結(jié)果記錄到Literal AI中。
  • 生成:我們定義有關(guān)變量,使用數(shù)據(jù)庫作為檢索的上下文,用戶的問題作為查詢,還指定檢索頂部結(jié)果(k:1)。最后,我們使用所提供的變量和回調(diào)來調(diào)用鏈。

步驟2

第二步是將Copilot組件嵌入到我們的應(yīng)用程序網(wǎng)站中。我們將創(chuàng)建一個(gè)簡單的網(wǎng)站進(jìn)行演示。創(chuàng)建一個(gè)index.html文件,并向其中添加以下代碼:

<!DOCTYPE html>
<html>
  <head>
    <title>Semantic Search Engine</title>
  </head>
 <body>
   <!-- ... -->
   <script src="http://localhost:8000/copilot/index.js"></script>
   <script>
     window.mountChainlitWidget({
       chainlitServer: "http://localhost:8000",
     });
   </script>
 </body>

在上面的代碼中,我們通過指向托管我們應(yīng)用程序的Chainlit服務(wù)器的位置,將Copilot組件嵌入了我們的網(wǎng)站中。上述代碼中,window.mountChainlitWidget能夠在當(dāng)前網(wǎng)站的右下角添加一個(gè)浮動(dòng)按鈕。點(diǎn)擊它將打開Copilot功能。為了確保我們的Copilot正常工作,我們需要首先運(yùn)行Chainlit應(yīng)用程序。在項(xiàng)目目錄中導(dǎo)航到合適的位置并運(yùn)行如下命令:

chainlit run search_engine.py -w

這段代碼將在地址https://localhost:8000處運(yùn)行應(yīng)用程序。接下來,我們需要托管我們的應(yīng)用程序網(wǎng)站。在瀏覽器中打開index.html腳本是不起作用的。相反,我們需要?jiǎng)?chuàng)建一個(gè)HTTPS測試服務(wù)器。你可以用不同的方法來實(shí)現(xiàn)這一點(diǎn),但一種簡單的方法是使用npx工具。npx包含在Node.js附帶的npm(節(jié)點(diǎn)包管理器)中;因此,要獲得npx,只需在系統(tǒng)上安裝Node.js即可。在項(xiàng)目目錄中導(dǎo)航到合適的位置并運(yùn)行如下命令:

npx http-server

這段代碼將在地址https://localhost:8080處啟動(dòng)服務(wù)器程序。導(dǎo)航到該地址,你將能夠看到一個(gè)嵌入Copilot組件的簡單Web界面。

開發(fā)arXiv論文引擎機(jī)器人程序:基于RAG+LangChain+Chainlit+ChromaDB-AI.x社區(qū)

嵌入Copilot組件的Web界面

由于我們將使用@cl.on_chat_start包裝器函數(shù)來歡迎用戶,因此我們可以在Chainlit配置中將show_readme_as_default設(shè)置為false,以避免界面閃爍。你可以在項(xiàng)目目錄中的.Chainlit/config.toml中找到你的配置文件。

開發(fā)arXiv論文引擎機(jī)器人程序:基于RAG+LangChain+Chainlit+ChromaDB-AI.x社區(qū)

Copilot組件小窗預(yù)覽

步驟3

要僅在Copilot組件內(nèi)部執(zhí)行代碼,我們可以添加以下內(nèi)容:

@cl.on_message
async def retrieve_docs(message: cl.Message):
    if cl.context.session.client_type == "copilot":
        # code to be executed only inside the Copilot

只有當(dāng)你在Copilot組件中與應(yīng)用程序交互時(shí),才會(huì)執(zhí)行此塊中的任何代碼。例如,如果在位于https://localhost:8000地址的Chainlit應(yīng)用程序接口上運(yùn)行查詢,上面if塊中的代碼將不會(huì)執(zhí)行,因?yàn)樗谕蛻舳祟愋蜑镃opilot。這是一個(gè)有用的功能,可以用來區(qū)分直接在Chainlit應(yīng)用程序中執(zhí)行的操作和通過Copilot界面啟動(dòng)的操作。通過這樣做,你可以根據(jù)請(qǐng)求的上下文定制應(yīng)用程序的行為,從而獲得更動(dòng)態(tài)、更響應(yīng)的用戶體驗(yàn)。

步驟4

Copilot組件可以調(diào)用你網(wǎng)站上的函數(shù)。這對(duì)于代表用戶執(zhí)行操作非常有用,例如打開模態(tài)、創(chuàng)建新文檔等。我們將進(jìn)一步修改Chainlit裝飾器函數(shù),使其包含兩個(gè)新的Copilot函數(shù)。為此,我們需要在index.html文件中指定當(dāng)Chainlit后端應(yīng)用程序中的Copilot函數(shù)被激活時(shí),前端應(yīng)該如何響應(yīng)。具體響應(yīng)情況將根據(jù)應(yīng)用程序的不同而作相應(yīng)處理。對(duì)于我們的語義研究論文引擎程序來說,每當(dāng)需要顯示相關(guān)論文或數(shù)據(jù)庫答案以響應(yīng)用戶查詢時(shí),我們都會(huì)在前端生成彈出通知。

開發(fā)arXiv論文引擎機(jī)器人程序:基于RAG+LangChain+Chainlit+ChromaDB-AI.x社區(qū)

響應(yīng)Copilot組件中的用戶查詢而彈出

我們將在應(yīng)用程序中創(chuàng)建兩個(gè)Copilot函數(shù):

  • showArxivResults:此函數(shù)將負(fù)責(zé)顯示arXiv API針對(duì)用戶查詢提取的在線結(jié)果。
  • showDatabaseResults:此函數(shù)將負(fù)責(zé)顯示針對(duì)用戶問題從我們獲取的數(shù)據(jù)庫中提取的結(jié)果。

首先,讓我們?cè)趕earch_engine.py腳本中設(shè)置后端邏輯,并修改@cl.on_chat_start函數(shù):

@cl.on_chat_start
async def retrieve_docs():
    if cl.context.session.client_type == "copilot":
        # 代碼同上

        #觸發(fā)顯示arXiv論文結(jié)果的彈出窗口
        fn_arxiv = cl.CopilotFunction(name="showArxivResults", 
                   args={"results": "\n".join(arxiv_papers)})
        await fn_arxiv.acall()
        
        # same code as before

在上面的代碼中,定義并異步調(diào)用了一個(gè)名為showArxivResults的Copilot函數(shù)。此函數(shù)作用是直接在Copilot界面中顯示arXiv論文的格式化列表。函數(shù)簽名非常簡單:我們指定函數(shù)的名稱及其將發(fā)送回的參數(shù)。我們將在index.html文件中使用這些信息來創(chuàng)建一個(gè)彈出窗口。

接下來,我們需要用第二個(gè)Copilot函數(shù)修改我們的@cl.on_message函數(shù),當(dāng)用戶根據(jù)獲取的論文提出問題時(shí),將執(zhí)行該函數(shù):

@cl.on_message
async def retrieve_docs(message: cl.Message):
    if cl.context.session.client_type == "copilot":
        #代碼同上
        
        # 激活相應(yīng)于數(shù)據(jù)庫查詢結(jié)果的彈出小窗口
        fn_db = cl.CopilotFunction(name="showDatabaseResults", 
                args={"results": "\n".join(results)})
        await fn_db.acall()
        
        #代碼同前

在上面的代碼中,我們定義了要異步調(diào)用的第二個(gè)Copilot函數(shù)showDatabaseResults。此函數(shù)的任務(wù)是在Copilot界面中顯示從數(shù)據(jù)庫檢索到的結(jié)果。函數(shù)簽名指定函數(shù)的名稱及其將發(fā)送回的參數(shù)。

步驟5

接下來,我們將進(jìn)一步編輯我們的index.html文件,這包括以下幾個(gè)方面的更改:

  • 添加兩個(gè)Copilot函數(shù)。
  • 指定當(dāng)兩個(gè)Copilot函數(shù)中的任何一個(gè)被觸發(fā)時(shí),我們的網(wǎng)站上會(huì)發(fā)生什么。我們將創(chuàng)建一個(gè)彈出窗口來顯示應(yīng)用程序后端的結(jié)果。
  • 為彈出窗口添加簡單的樣式。

首先,我們需要為Copilot函數(shù)添加事件偵聽器。在index.html文件的<script>標(biāo)記中,添加以下代碼:

<script>
 // 前面的代碼
 window.addEventListener("chainlit-call-fn", (e) => {
 const { name, args, callback } = e.detail;
 if (name === "showArxivResults") {
   document.getElementById("arxiv-result-text").innerHTML =
     args.results.replace(/\n/g, "<br>");
   document.getElementById("popup").style.display = "flex";
   if (callback) callback();
 } else if (name === "showDatabaseResults") {
   document.getElementById("database-results-text").innerHTML =
     args.results.replace(/\n/g, "<br>");
   document.getElementById("popup").style.display = "flex";
   if (callback) callback();
 }
 });
</script>

以下是上述代碼的解釋:

  • 包括顯示(showPopup())和隱藏(hidePopup())彈出窗口的函數(shù)。
  • 為chainlit-call-fn事件注冊(cè)一個(gè)事件偵聽器,該事件在調(diào)用Copilot函數(shù)(showArxivResults或showDatabaseResults)時(shí)觸發(fā)。
  • 檢測到事件后,偵聽器將檢查調(diào)用的Copilot函數(shù)的名稱。根據(jù)函數(shù)名稱,它會(huì)使用函數(shù)提供的結(jié)果更新彈出窗口中相關(guān)部分的內(nèi)容。它將換行符(\\n)替換為HTML換行符(<br>),以便為HTML顯示正確格式化的文本。
  • 更新內(nèi)容后,將顯示彈出模式(顯示:“flex”),允許用戶查看結(jié)果。可以使用關(guān)閉按鈕隱藏窗口,該按鈕調(diào)用hidePopup()函數(shù)。

接下來,我們需要定義上面指定的彈出窗口。我們可以通過將以下代碼添加到index.html腳本的<body>標(biāo)記中來實(shí)現(xiàn)這一點(diǎn):

<div id="popup" class="popup">
 <span class="close-btn" onclick="hidePopup()">×</span>
 <div class="arxiv-results-wrapper">
   <h1>Arxiv Results</h1>
   <p id="arxiv-result-text">Online results will be displayed here.</p>
 </div>
 <div class="database-results-wrapper">
   <h1>Database Results</h1>
   <p id="database-results-text">Database results will be displayed here.</p>
 </div>
</div>

讓我們也為彈出窗口添加一些樣式。編輯index.html文件的<head>標(biāo)記:

<style>
 * {
   box-sizing: border-box;
 }
 
 body {
   font-family: sans-serif;
 }
 
 .close-btn {
   position: absolute;
   top: 10px;
   right: 20px;
   font-size: 24px;
   cursor: pointer;
 }
 
 .popup {
   display: none;
   position: fixed;
   top: 50%;
   left: 50%;
   transform: translate(-50%, -50%);
   background-color: white;
   padding: 20px;
   box-shadow: rgba(99, 99, 99, 0.2) 0px 2px 8px 0px;
   width: 40%;
   flex-direction: column;
   gap: 50px;
 }
 
 p {
   color: #00000099;
 }
</style>

啟動(dòng)應(yīng)用程序

至此,我們已經(jīng)將Copilot邏輯添加到Chainlit應(yīng)用程序中,我們可以運(yùn)行應(yīng)用程序和網(wǎng)站了。要使Copilot工作,我們的應(yīng)用程序必須首先運(yùn)行起來。在項(xiàng)目目錄中打開一個(gè)終端,然后運(yùn)行以下命令啟動(dòng)Chainlit服務(wù)器:

chainlit run search.py -h

在新的終端中,使用以下方式啟動(dòng)網(wǎng)站:

npx http-server

開發(fā)arXiv論文引擎機(jī)器人程序:基于RAG+LangChain+Chainlit+ChromaDB-AI.x社區(qū)

應(yīng)用程序示例界面

Literal AI 的LLM可 觀察性

通常,我們需要將可觀察性特征集成到生產(chǎn)級(jí)應(yīng)用程序中,例如我們現(xiàn)在開發(fā)的集成Copilot組件的語義研究引擎,以確保應(yīng)用程序在生產(chǎn)環(huán)境中的可靠性。我們將在Literal AI框架中使用它。

對(duì)于任何Chainlit應(yīng)用程序,Literal AI都會(huì)自動(dòng)啟動(dòng)監(jiān)控應(yīng)用程序,并將數(shù)據(jù)發(fā)送到Literal人工智能平臺(tái)。在search_engine.py腳本中創(chuàng)建提示時(shí),我們已經(jīng)啟動(dòng)了Literal AI客戶端。現(xiàn)在,每次用戶與我們的應(yīng)用程序交互時(shí),我們都會(huì)在Literal AI面板中看到有關(guān)日志信息。

控制面板

導(dǎo)航到Literal AI控制界面(https://cloud.getliteral.ai/projects/),從左側(cè)面板中選擇項(xiàng)目,然后單擊“可觀察性(Observability)”。你將看到針對(duì)以下諸功能的日志輸出信息。

線程 ( Threads )

線程表示助理和用戶之間的會(huì)話。你應(yīng)該能夠看到用戶在應(yīng)用程序中進(jìn)行的所有對(duì)話。

開發(fā)arXiv論文引擎機(jī)器人程序:基于RAG+LangChain+Chainlit+ChromaDB-AI.x社區(qū)

Literal AI線程界面

展開特定的對(duì)話將提供關(guān)鍵的細(xì)節(jié)描述,例如每個(gè)步驟所花費(fèi)的時(shí)間、用戶消息的細(xì)節(jié),以及詳細(xì)說明所有步驟的基于樹的視圖。你還可以將對(duì)話添加到數(shù)據(jù)集中。

開發(fā)arXiv論文引擎機(jī)器人程序:基于RAG+LangChain+Chainlit+ChromaDB-AI.x社區(qū)

Literal AI線程界面概覽

運(yùn)行(Runs)

運(yùn)行是代理或鏈所執(zhí)行的一系列步驟。這一部分提供了每次執(zhí)行鏈或代理時(shí)所采取的所有步驟的詳細(xì)信息。通過這個(gè)選項(xiàng)卡,我們可以獲得每個(gè)用戶查詢的輸入和輸出。

開發(fā)arXiv論文引擎機(jī)器人程序:基于RAG+LangChain+Chainlit+ChromaDB-AI.x社區(qū)

Literal AI Runs面板

你可以展開一個(gè)Run,這將提供更多細(xì)節(jié)信息。同樣,你可以將此信息添加到數(shù)據(jù)集中。

開發(fā)arXiv論文引擎機(jī)器人程序:基于RAG+LangChain+Chainlit+ChromaDB-AI.x社區(qū)

Literal AI Runs面板運(yùn)行時(shí)概覽

生成(Generations)

Generations面板包含發(fā)送到LLM的輸入信息及完成信息。這個(gè)面板提供的詳細(xì)信息包括用于完成任務(wù)的模型名稱,符號(hào)計(jì)數(shù),以及請(qǐng)求完成任務(wù)的用戶(如果你配置了多個(gè)用戶會(huì)話)。

開發(fā)arXiv論文引擎機(jī)器人程序:基于RAG+LangChain+Chainlit+ChromaDB-AI.x社區(qū)

Literal AI Generations面板運(yùn)行時(shí)概覽

Literal AI提示評(píng)價(jià)

自從我們添加了LangChain集成以來,我們可以根據(jù)應(yīng)用程序代碼中創(chuàng)建和使用的每個(gè)提示跟蹤生成和線程。因此,每次為用戶查詢調(diào)用鏈時(shí),都會(huì)在Literal AI面板中添加日志信息。這有助于查看特定生成的提示,并比較不同版本的性能。

開發(fā)arXiv論文引擎機(jī)器人程序:基于RAG+LangChain+Chainlit+ChromaDB-AI.x社區(qū)

Copilot集成了具有可觀察性功能的語義研究引擎應(yīng)用程序

結(jié)論

在本教程中,我演示了如何使用LangChain框架、OpenAI大數(shù)據(jù)模型和ChromaDB向量數(shù)據(jù)庫并結(jié)合RAG功能創(chuàng)建一個(gè)語義研究論文引擎。此外,我還展示了如何為該引擎開發(fā)一個(gè)Web應(yīng)用程序,集成了Literal AI的Copilot組件和可觀測性特征。為了確保在現(xiàn)實(shí)世界的語言模型應(yīng)用程序中獲得最佳性能,往往都需要整合評(píng)估和可觀察性功能。此外,Copilot對(duì)于不同的軟件應(yīng)用程序來說也是一個(gè)非常有用的功能;因此,本教程可以成為了解如何為應(yīng)用程序設(shè)置Copilot功能的一個(gè)很好的起點(diǎn)。

最后,你可以在我的GitHub(https://github.com/tahreemrasul/semantic_research_engine)上找到本教程中的所有代碼。

譯者介紹

朱先忠,51CTO社區(qū)編輯,51CTO專家博客、講師,濰坊一所高校計(jì)算機(jī)教師,自由編程界老兵一枚。

原文標(biāo)題:Building an Observable arXiv RAG Chatbot with LangChain, Chainlit, and Literal AI,作者:Tahreem Rasul

鏈接:

https://towardsdatascience.com/building-an-observable-arxiv-rag-chatbot-with-langchain-chainlit-and-literal-ai-9c345fcd1cd8?。

?著作權(quán)歸作者所有,如需轉(zhuǎn)載,請(qǐng)注明出處,否則將追究法律責(zé)任
標(biāo)簽
收藏
回復(fù)
舉報(bào)
回復(fù)
相關(guān)推薦
中文字幕一区二区三区四区不卡 | 伊人久久国产| 久久先锋影音av| 国产欧美亚洲精品| 曰本女人与公拘交酡| 粉嫩av一区二区| 91久久精品一区二区| 美国av在线播放| 天天操天天干天天干| 七七婷婷婷婷精品国产| 大量国产精品视频| 香蕉视频黄色在线观看| 欧美91在线|欧美| 性久久久久久久久久久久| 亚洲高清在线观看一区| 色婷婷av一区二区三区之红樱桃 | 亚洲第一黄色网址| 欧美一级在线| 精品久久久久久久中文字幕 | 91精品久久香蕉国产线看观看| 国产精品第72页| 久久国产成人精品| 国产视频综合在线| 国产女主播在线播放| 福利精品一区| 日韩欧美在线视频| 日本wwwcom| 黄网站视频在线观看| 久久午夜羞羞影院免费观看| 国产福利一区二区三区在线观看| 亚洲一区二区三区高清视频| 鲁大师影院一区二区三区| 欧美激情中文字幕在线| 最新av电影网站| 国产欧美日韩视频在线| 亚洲精品在线看| 又黄又爽的网站| 永久免费精品视频| 91精品国产综合久久福利| 天天视频天天爽| 偷拍中文亚洲欧美动漫| 日韩欧美aⅴ综合网站发布| 日本天堂免费a| 国产成人无吗| 亚洲欧美日韩成人高清在线一区| 亚洲高清资源综合久久精品| 国产三级视频在线| 久久综合狠狠综合| 精品国产一区二区三区四区精华 | 福利一区三区| 欧美日韩视频第一区| 国产理论在线播放| 台湾佬成人网| 欧美系列在线观看| 国产福利影院在线观看| 成人mm视频在线观看| 欧美熟乱第一页| 超碰在线97免费| av在线日韩| 欧美日韩一区三区| 亚洲一区精品视频在线观看| 涩涩涩久久久成人精品| 欧美美女黄视频| 天天做天天干天天操| 99re8精品视频在线观看| 制服.丝袜.亚洲.另类.中文| а 天堂 在线| 日韩精品中文字幕一区二区| 亚洲精品一区二区三区福利| 图片区偷拍区小说区| 国产精品巨作av| 日韩国产激情在线| 亚洲自拍偷拍图| 欧美电影《轻佻寡妇》| 蜜臀久久99精品久久久无需会员| 日本中文字幕免费在线观看| 激情av一区| 欧洲亚洲女同hd| 国产成人自拍偷拍| 精品一区免费av| 国产福利久久| 四虎影院在线播放| 国产成a人亚洲精| 国产一级精品aaaaa看| 秋霞av在线| 国产精品久久久爽爽爽麻豆色哟哟| 伊人精品久久久久7777| 亚洲卡一卡二| 色成人在线视频| 亚洲黄色片免费看| 老司机成人在线| 亚洲一级一级97网| 精品国产精品国产精品| 国产一区二区高清| 国产在线观看精品| 图片区 小说区 区 亚洲五月| 久久久久久久av麻豆果冻| 免费看啪啪网站| 欧美xxxhd| 欧美高清你懂得| 黄色网址在线视频| 日韩国产一区二区三区| 97碰在线观看| 91禁在线观看| 久久综合久久99| japanese在线播放| 成人看片网页| 亚洲精品一区在线观看| 精品无码一区二区三区蜜臀| 国产人成精品一区二区三| 国产一区玩具在线观看| 青春有你2免费观看完整版在线播放高清 | 亚洲激情视频| 91人人爽人人爽人人精88v| 日产精品久久久久久久性色| 亚洲精品免费视频| 欧美一级特黄a| 亚洲国产欧美日韩在线观看第一区| 久久天天躁狠狠躁夜夜躁2014| 国产成人精品网| 国产福利电影一区二区三区| 亚洲7777| 手机看片久久| 精品亚洲一区二区三区四区五区| 欧美毛片在线观看| 久久99国产乱子伦精品免费| 麻豆精品蜜桃一区二区三区| 欧美aaaaaaa| 欧美精品一二三四| 国产美女永久免费无遮挡| 亚洲人www| av一区观看| 欧美极品视频| 欧美日韩亚洲另类| 人妻aⅴ无码一区二区三区| 亚洲国产影院| 国产区一区二区三区| 四季久久免费一区二区三区四区| 欧美女孩性生活视频| 婷婷色一区二区三区| 免费国产自线拍一欧美视频| 国产在线精品一区二区三区》| 永久免费网站在线| 欧美夫妻性生活| 99久久久无码国产精品不卡| 日韩—二三区免费观看av| 欧美一区2区三区4区公司二百| 日韩欧美精品一区二区三区| 亚洲成人久久一区| 国产无码精品在线播放| 99热在这里有精品免费| 国产精品一区二区免费在线观看| 成人香蕉社区| 8050国产精品久久久久久| 天天综合在线视频| 欧美午夜宅男影院在线观看| 可以直接看的无码av| 久久久蜜桃一区二区人| 日韩.欧美.亚洲| 成人午夜亚洲| 日韩在线不卡视频| 成人黄色免费视频| 亚洲一区二区三区三| 亚洲av成人片色在线观看高潮| 一本色道久久| 日本中文不卡| 四虎国产精品免费久久| 久久久国产成人精品| 精品人妻一区二区三区日产乱码| 亚洲一区精品在线| 黄色a一级视频| 视频一区二区不卡| 宅男一区二区三区| 日韩免费高清视频网站| 2019国产精品自在线拍国产不卡| 日本午夜在线| 欧美日韩精品欧美日韩精品 | 91精品视频专区| 羞羞的视频在线看| 日韩精品在线免费播放| 夜夜躁日日躁狠狠久久av| 亚洲欧洲国产专区| 日本一级大毛片a一| 午夜亚洲性色视频| 亚洲精品国产精品久久| 中文一区二区三区四区| 国产精品91在线| 黄色网在线播放| 亚洲国产天堂久久综合网| 色老头一区二区| 亚洲精品网站在线观看| 亚洲av无码国产精品久久| 久久99国产精品成人| 热99这里只有精品| 久久伦理在线| 蜜桃免费一区二区三区| 亚洲午夜国产成人| 午夜精品久久久久久99热| 国产天堂在线| 精品国产成人在线影院 | 欧美变态凌虐bdsm| 亚洲色成人www永久网站| 亚洲日本成人在线观看| 亚洲一区二区乱码| 国产精品亚洲第一区在线暖暖韩国| 波多野结衣之无限发射| 一本一道久久综合狠狠老| 久久精品国产第一区二区三区最新章节 | 欧美性高潮床叫视频| 国产老头老太做爰视频| 久久久久亚洲蜜桃| 国产精品入口麻豆| 国产麻豆精品视频| 久久婷婷国产91天堂综合精品| 极品中文字幕一区| 黄色网络在线观看| 欧美日韩中文字幕一区二区三区| 国产亚洲一区在线播放| 久久久久久亚洲精品美女| 国产精品成人一区| 悠悠资源网亚洲青| 国产最新精品视频| av网站在线看| 菠萝蜜影院一区二区免费| 国内在线精品| 亚洲毛片在线观看.| 欧美 日韩 人妻 高清 中文| 在线播放欧美女士性生活| 嫩草影院一区二区三区| 精品久久香蕉国产线看观看gif| 激情五月婷婷小说| 亚洲欧美激情在线| 天天做夜夜爱爱爱| 亚洲欧洲精品成人久久奇米网| 2019男人天堂| 国产欧美日韩综合| mm131丰满少妇人体欣赏图| jizz一区二区| 亚洲蜜桃精久久久久久久久久久久| 岛国一区二区三区| 国产精品久久久久野外| 国产一区二区三区免费播放| 日韩av.com| 狠狠色丁香久久婷婷综| 中文字幕 91| 看片网站欧美日韩| 国产精品自拍视频在线| 美女国产一区二区三区| 亚欧激情乱码久久久久久久久| 麻豆freexxxx性91精品| 欧美成年人视频在线观看| 狠狠色丁香九九婷婷综合五月| 一区二区免费av| 国内久久精品视频| 亚洲天堂网站在线| 成人午夜免费视频| 欧亚乱熟女一区二区在线| 99久久久国产精品| 熟女俱乐部一区二区视频在线| 久久久久久免费| av黄色免费在线观看| 亚洲免费av在线| 久草视频在线资源站| 亚洲电影在线播放| 国产www在线| 欧美视频中文一区二区三区在线观看| 精品乱码一区内射人妻无码| 欧美日韩免费一区二区三区 | 成人手机电影网| 久久久久麻豆v国产精华液好用吗| 99re亚洲国产精品| 91成人在线免费视频| 亚洲欧洲日韩女同| 亚洲精品在线观看av| 欧美午夜片在线免费观看| 最近中文字幕在线观看| 日韩一区二区三区观看| 五月婷婷六月丁香综合| 中文字幕亚洲综合久久| av网站免费在线观看| 91极品女神在线| 成人在线免费电影网站| 99视频国产精品免费观看| 亚洲成在人线免费观看| 一区二区三区视频在线播放| 红桃视频亚洲| 北条麻妃视频在线| 国产精品一二三区在线| 97人妻天天摸天天爽天天| 国产精品全国免费观看高清| 九九热国产精品视频| 色婷婷久久久综合中文字幕 | 成人毛片在线观看| 懂色av粉嫩av浪潮av| 亚洲一区二区三区在线播放| www.com亚洲| 欧美一级精品大片| 黑人与亚洲人色ⅹvideos| 欧美精品九九久久| 国产激情欧美| 久久精品magnetxturnbtih| 久久久精品久久久久久96| 欧美精品99久久| 国产高清无密码一区二区三区| 国产成人无码精品久久二区三| 草莓视频一区二区三区| 中文字幕一区二区三区不卡在线 | 视频精品导航| 国产精品久久一区二区三区| 国内精品久久久久久99蜜桃| 男人天堂av片| 国产综合色视频| 国产在线观看h| 五月天欧美精品| 亚洲av无码一区二区乱子伦 | 国内视频一区二区| 亚洲国产精品久久久天堂| 一级在线免费视频| 91网站在线播放| 精品一级少妇久久久久久久| 666欧美在线视频| 永久免费av在线| 国产成人一区二区在线| 天堂日韩电影| 欧美深夜福利视频| 国产91富婆露脸刺激对白| 秋霞欧美一区二区三区视频免费 | 欧美一级电影免费在线观看| 精品国产乱码久久久久久樱花| 午夜精品美女久久久久av福利| 亚洲在线视频| 国产中文字幕一区二区| 亚洲国产成人av好男人在线观看| 国产成人麻豆精品午夜在线| 丝袜情趣国产精品| 免费在线观看一区| 任我爽在线视频精品一| 男女av一区三区二区色多| 亚洲制服丝袜在线播放| 亚洲第一搞黄网站| 国产 日韩 欧美 精品| 久久91精品国产91久久跳| 国产一区二区三区亚洲综合| 国产成人精品免费看在线播放 | 亚洲av人人澡人人爽人人夜夜| 一区二区三区中文在线观看| 99国产成人精品| 欧美成人午夜激情| 亚洲成av人片在线观看www| 欧美日韩dvd| 风间由美一区二区三区在线观看| 精品无码久久久久久久| 精品国产乱码久久久久久老虎| 888av在线视频| 久久国产精品高清| 日日摸夜夜添夜夜添精品视频 | 日韩欧美999| 国产视频第一页在线观看| 国产日韩欧美在线看| 综合久久十次| 东京热av一区| 欧美午夜精品久久久久久人妖| 岛国最新视频免费在线观看| 国产精品日日做人人爱| 中文字幕一区二区av| 国产情侣久久久久aⅴ免费| 懂色av影视一区二区三区| 日本中文字幕一区二区有码在线| 国产精品久久久久久久天堂 | 福利在线一区二区| 99久久精品免费| 18国产免费视频| 欧美成人精品一区二区| 久久久免费毛片| 亚洲 欧美 另类人妖| 亚洲精品日韩一| 亚洲 精品 综合 精品 自拍| 国产精品国产自产拍高清av水多| 国产精品毛片久久| 女性生殖扒开酷刑vk| 91久久奴性调教| 最新国产在线拍揄自揄视频| 国内精品久久国产| 久久av资源站| 国产无遮挡又黄又爽在线观看| 影音先锋日韩有码| 91成人午夜| 久久久久久久久久久久91| 艳妇臀荡乳欲伦亚洲一区| 欧美女优在线观看| 成人午夜一级二级三级| 一本色道久久综合亚洲精品高清| 中文字幕有码在线播放| 欧美成人伊人久久综合网| 成人在线爆射| 9191国产视频| 国产女同互慰高潮91漫画| 日本国产在线观看| 成人免费视频在线观看超级碰| 亚洲影视综合|