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

基于LangChain自查詢檢索器的RAG系統開發實戰 原創

發布于 2024-5-22 09:23
瀏覽
0收藏

本文介紹RAG(檢索增強生成)技術并基于LangChain框架的自查詢檢索器來開發一個實戰型電影推薦系統。

引言

最近,我在瀏覽Max.com網站時想找一部電影看。通常,這個過程包括瀏覽系統呈現給我的各種列表,閱讀一些相關描述,然后挑選一些看起來有趣的電影。如果我知道我想看的電影的片名或我喜歡的演員的名字,我通常只會點擊搜索功能。否則,搜索就沒有多大用處了。

現在,我突然想到了一個新的想法:為什么我不能用自然語言來查找一部電影,更多地基于電影的氛圍或實質,而不僅僅是標題或演員呢?例如,為什么我不能啟動Max、Netflix或Hulu等流媒體播放平臺,并在搜索欄中鍵入類似于以下查詢之一呢:

  • 給我找一部長度不到2小時、以寵物為主角的英語戲劇電影。
  • 推薦僵尸電影,但要確保它們很有趣。
  • 我喜歡《瞬息全宇宙》。給我一部類似的電影,但場景、氛圍或者人物性格更加陰暗、沉重一些。

這種方法的美妙之處超出了更自然的電影搜索方式,還保護了用戶的隱私。該系統根本不會使用用戶數據,不是挖掘用戶的行為、喜歡和不喜歡來提供給推薦系統。唯一需要的就是一個查詢。

為此,我開發了本文中要展示給大家的一個電影搜索程序。這是一個基于RAG(檢索增強生成)的系統,它可以接受用戶的查詢,嵌入查詢,并進行相似性搜索,以找到相似的電影。不過,這個程序超越了普通的RAG系統。這個系統使用了所謂的自查詢檢索器。該技術允許在進行相似性搜索之前,根據電影的元數據對其進行過濾。因此,如果用戶有一個類似“推薦1980年后拍攝的以大量爆炸為特征的恐怖電影”的查詢,搜索算法將首先過濾掉所有不是“1980年后制作的恐怖片”的電影,然后再對“以大量爆炸為主”的電影進行相似性搜索。

在本文中,我將提供一個關于我如何創建此系統的總體概述。如果您想深入了解這個程序,完整的源代碼將在文后的鏈接參考處提供。

接下來,讓我們繼續作深入介紹。

檢索數據

首先,該項目的數據來自電影數據庫(TMDB:https://developer.themoviedb.org/docs/getting-started),并得到了所有者的許可。他們的API使用簡單,維護良好,并且沒有嚴格的費率限制。我從他們的API中提取了以下電影屬性:

  • 標題
  • 運行時間(分鐘)
  • 語言
  • 概述
  • 發布年份
  • 體裁
  • 描述電影的關鍵詞
  • 演員
  • 董事
  • 流式傳輸的位置
  • 購買地點
  • 出租場所
  • 生產公司名單

以下是如何使用TMDB API和Python的響應庫提取數據的片段:

def get_data(API_key, Movie_ID, max_retries=5):
    """
函數以JSON格式提取感興趣的電影的詳細信息。

    parameters:
    API_key (str): Your API key for TMBD
    Movie_ID (str): TMDB id for film of interest

    returns:
    dict: JSON格式的字典,包含您的電影的所有細節
興趣
    """

    query = 'https://api.themoviedb.org/3/movie/' + Movie_ID + \
        '?api_key='+API_key + '&append_to_response=keywords,' + \
            'watch/providers,credits'
    for i in range(max_retries):
        response = requests.get(query)
        if response.status_code == 429:
            # If the response was a 429, wait and then try again
            print(
                f"Request limit reached. Waiting and retrying ({i+1}/{
                    max_retries})")
            time.sleep(2 ** i)  # Exponential backoff
        else:
            dict = response.json()
            return dict

請注意,該查詢需要電影ID(也是使用TMDB獲得的)以及append_to_response,這允許我提取幾種類型的數據,例如關鍵字、影片提供商、演員(導演和演員)以及有關電影的一些基本信息。還有一些基本的框架類代碼,以防我達到速率限制,盡管我注意到從未發生這種情況。

然后,我們必須解析JSON響應。以下的代碼片段展示了如何解析電影中的演員和導演:

credits = dict['credits']
    actor_list, director_list = [], []

# 分析演員表
cast = credits['cast']
NUM_ACTORS = 5
for member in cast[:NUM_ACTORS]:
    actor_list.append(member["name"])

# 分析劇組
crew = credits['crew']
for member in crew:
    if member['job'] == 'Director':
        director_list.append(member["name"])

actor_str = ', '.join(list(set(actor_list)))
director_str = ', '.join(list(set(director_list)))

請注意,我將演員數量限制在一部電影的前五名。我還必須說明,我只對導演感興趣,因為系統的響應還包括其他類型的劇組成員,如編輯、服裝設計師等。

所有這些數據隨后被編譯成CSV文件。上面列出的每個屬性都被轉換成了一列,現在每一行都代表一部特定的電影。以下是通過程序創建的2008_movie_collection_data.csv文件中的短片。在這個項目中,我獲得了大約100部1920年至2023年的頂級電影。

基于LangChain自查詢檢索器的RAG系統開發實戰-AI.x社區

用于演示目的的電影數據片段(作者本人提供)

信不信由你,我還沒看過《功夫熊貓》。也許我必須完成這個項目。

將文檔上載到pinecone網站

接下來,我必須將csv數據上傳到https://www.pinecone.io/網站([譯者注]。Pinecone是一個非開源型的向量數據庫。Pinecone支持在大規模向量集上進行快速且實時的搜索,具有亞秒級的查詢響應時間,適用于需要高性能和實時性的大型應用,特別適合于構建實時推薦系統、電商搜索引擎和社交媒體內容過濾等)。通常,分塊在RAG系統中很重要,但這里每個“文檔”(CSV文件的行)都很短,所以分塊不是一個問題。我首先必須將每個CSV文件轉換為LangChain文檔,然后指定哪些字段應該是主要內容,哪些字段應該作為元數據。

以下是用于構建這些文檔的代碼片段:

# 從所有csv文件加載數據
loader = DirectoryLoader(
    path="./data",
    glob="*.csv",
    loader_cls=CSVLoader,
    show_progress=True)

docs = loader.load()

metadata_field_info = [
    AttributeInfo(
        name="Title", description="The title of the movie", type="string"),
    AttributeInfo(name="Runtime (minutes)",
                  description="The runtime of the movie in minutes", type="integer"),
    AttributeInfo(name="Language",
                  description="The language of the movie", type="string"),
    ...
]

for doc in docs:
    #將page_content字符串解析到字典中
    page_content_dict = dict(line.split(": ", 1)
                             for line in doc.page_content.split("\n") if ": " in line)
    
    doc.page_content = 'Overview: ' + page_content_dict.get(
        'Overview') + '. Keywords: ' + page_content_dict.get('Keywords')
    doc.metadata = {field.name: page_content_dict.get(
        field.name) for field in metadata_field_info}

    #將字段從字符串轉換為字符串列表
    for field in fields_to_convert_list:
        convert_to_list(doc, field)      

    # 將字段從字符串轉換為整數
    for field in fields_to_convert_int:
        convert_to_int(doc, field)

LangChain的DirectoryLoader負責將所有csv文件加載到文檔中。然后,我需要指定什么應該是page_content,什么應該是metadata;這是一個重要的決定。page_content將在檢索階段嵌入并用于相似性搜索。在進行相似性搜索之前,metadata將僅用于過濾目的。我決定采用overview和keywords屬性并嵌入它們,其余的屬性將是元數據。應該做進一步的調整,看看title是否也應該包括在page_content中,但我發現這種配置對大多數用戶查詢都很有效。

接下來,文件必須上傳到pinecone網站。這是一個相當簡單的過程:

# 如果尚未創建索引,則取消注釋
pc.create_index(
    name=PINECONE_INDEX_NAME,
    dimension=1536,
    metric="cosine",
    spec=PodSpec(
        environment="gcp-starter"
    )
)

# 目標索引和檢查狀態
pc_index = pc.Index(PINECONE_INDEX_NAME)
print(pc_index.describe_index_stats())

embeddings = OpenAIEmbeddings(model='text-embedding-ada-002')

vectorstore = PineconeVectorStore(
    pc_index, embeddings
)

# 創建記錄管理器
namespace = f"pinecone/{PINECONE_INDEX_NAME}"
record_manager = SQLRecordManager(
    namespace, db_url="sqlite:///record_manager_cache.sql"
)

record_manager.create_schema()

# 將文檔上載到松果網站
index(docs, record_manager, vectorstore,
      cleanup="full", source_id_key="Website")

我只想在這里強調幾個事情:

  • 如果多次運行此代碼,那么使用SQLRecordManager可確保不會將重復的文檔上載到Pinecone。如果修改了文檔,則在矢量存儲中僅修改該文檔。
  • 我們使用OpenAI的經典text-embedding-ada-002作為我們的嵌入模型。

創建自查詢檢索器

自查詢檢索器將允許我們通過我們之前定義的元數據來過濾RAG期間檢索到的電影。這將大大提高我們電影推薦人的實用性。

在選擇矢量存儲時,一個重要的考慮因素是確保它支持按元數據過濾,因為并非所有數據庫都支持這種技術。鏈接https://python.langchain.com/docs/integrations/retrievers/self_query處提供了LangChain支持自查詢檢索的數據庫列表。另一個重要的考慮因素是對于每個矢量存儲允許什么類型的比較器。比較器是我們通過元數據進行過濾的方法。例如,我們可以使用eq比較器來確保我們的電影屬于科幻類型:eq('Genre', 'Science Fiction')。并非所有矢量存儲都允許所有比較器。舉個例子,有興趣的讀者可以觀察一下開源的嵌入式數據庫Chroma中支持的比較器(https://docs.trychroma.com/usage-guide#using-where-filters),以及它們與Pinecone網站中支持的比較器(https://docs.pinecone.io/guides/data/filtering-with-metadata#metadata-query-language)有何不同。我們需要告訴模型允許使用哪些比較器,以防止它意外地寫入禁止的查詢。

除了告訴模型存在哪些比較器之外,我們還可以提供用戶查詢和相應過濾器的模型示例。這被稱為小樣本學習(Few-shot Learning),這對指導您的模型是非常寶貴的。

要具體地了解這一技巧有何幫助,您可以嘗試查看以下兩個用戶查詢:

  • “推薦一些約戈斯·蘭蒂莫斯的電影。”
  • “類似于約戈斯·蘭圖米奧斯電影的電影?!?/li>

我的元數據過濾模型很容易為這些示例中的每一個編寫相同的過濾查詢,盡管我希望對它們進行不同的處理。第一部應該只推薦蘭蒂莫斯執導的電影,而第二部應該推薦與蘭蒂莫斯電影有相似氛圍的電影。為了確保這種行為,我一點點細致地提供了我想要的行為的模型示例。語言模型的美妙之處在于,它們可以利用自己的“推理”能力和世界知識,將這些小樣本學習示例推廣到其他用戶查詢中。

document_content_description = "Brief overview of a movie, along with keywords"

        # 定義允許的比較器列表
        allowed_comparators = [
            "$eq",  # Equal to (number, string, boolean)
            "$ne",  # Not equal to (number, string, boolean)
            "$gt",  # Greater than (number)
            "$gte",  # Greater than or equal to (number)
            "$lt",  # Less than (number)
            "$lte",  # Less than or equal to (number)
            "$in",  # In array (string or number)
            "$nin",  # Not in array (string or number)
            "$exists", # Has the specified metadata field (boolean)
        ]

        examples = [
            (
                "Recommend some films by Yorgos Lanthimos.",
                {
                    "query": "Yorgos Lanthimos",
                    "filter": 'in("Directors", ["Yorgos Lanthimos]")',
                },
            ),
            (
                "Films similar to Yorgos Lanthmios movies.",
                {
                    "query": "Dark comedy, absurd, Greek Weird Wave",
                    "filter": 'NO_FILTER',
                },
            ),
            ...
        ]

        metadata_field_info = [
            AttributeInfo(
                name="Title", description="The title of the movie", type="string"),
            AttributeInfo(name="Runtime (minutes)",
                          description="The runtime of the movie in minutes", type="integer"),
            AttributeInfo(name="Language",
                          description="The language of the movie", type="string"),
            ...
        ]

        constructor_prompt = get_query_constructor_prompt(
            document_content_description,
            metadata_field_info,
            allowed_comparators=allowed_comparators,
            examples=examples,
        )

        output_parser = StructuredQueryOutputParser.from_components()
        query_constructor = constructor_prompt | query_model | output_parser

        retriever = SelfQueryRetriever(
            query_constructor=query_constructor,
            vectorstore=vectorstore,
            structured_query_translator=PineconeTranslator(),
            search_kwargs={'k': 10}
        )

除了示例之外,模型還必須知道每個元數據字段的描述。這有助于它了解什么是元數據過濾。

最后,我們來構建我們的鏈。這里的query_model是使用OpenAI API的GPT-4 Turbo的一個實例。我建議使用GPT-4而不是3.5來編寫這些元數據過濾器查詢,因為這是一個關鍵步驟,理由是3.5會更頻繁地出錯。search_kwargs={'k':10}告訴檢索器根據用戶查詢找出十部最相似的電影。

創建聊天模型

最后,在構建了自查詢檢索器之后,我們可以在此基礎上構建標準的RAG模型。我們首先定義我們的聊天模型。這就是我所說的摘要模型,因為它采用上下文(檢索到的電影+系統消息),并以每個推薦的摘要作為響應。如果你想降低成本,這個模型可以是GPT-3.5 Turbo;當然,如果你想獲得絕對最佳的結果,這個模型也可以是GPT-4 Turbo。

在系統消息中,我告訴機器人它的目標是什么,并提供了一系列建議和限制,其中最重要的是不要推薦自我查詢檢索器沒有提供給它的電影。在測試中,當用戶查詢沒有從數據庫中得到電影時,我遇到了問題。例如,查詢“推薦一些由韋斯·安德森執導的馬特·達蒙主演的1980年之前拍攝的恐怖電影”會導致自我查詢檢索器無法檢索到任何電影(因為盡管聽起來很棒,但這部電影并不存在)。在沒有電影數據的情況下,該模型會使用自己的(錯誤的)內存來嘗試推薦一些電影。這是不好的行為。我不希望Netflix的推薦人討論數據庫中沒有的電影。下面的系統消息成功阻止了此行為。我確實注意到GPT-4比GPT-3.5更善于遵循指令,這是在意料之中的事情。

chat_model = ChatOpenAI(
    model=SUMMARY_MODEL_NAME,
    temperature=0,
    streaming=True,
)

prompt = ChatPromptTemplate.from_messages(
    [
        (
            'system',
            """
            Your goal is to recommend films to users based on their 
            query and the retrieved context. If a retrieved film doesn't seem 
            relevant, omit it from your response. If your context is empty
            or none of the retrieved films are relevant, do not recommend films
            , but instead tell the user you couldn't find any films 
            that match their query. Aim for three to five film recommendations,
            as long as the films are relevant. You cannot recommend more than 
            five films. Your recommendation should be relevant, original, and 
            at least two to three sentences long.
            
            YOU CANNOT RECOMMEND A FILM IF IT DOES NOT APPEAR IN YOUR 
            CONTEXT.

            # TEMPLATE FOR OUTPUT
            - **Title of Film**:
                - Runtime:
                - Release Year:
                - Streaming:
                - (Your reasoning for recommending this film)
            
            Question: {question} 
            Context: {context} 
            """
        ),
    ]
)

def format_docs(docs):
    return "\n\n".join(f"{doc.page_content}\n\nMetadata: {doc.metadata}" for doc in docs)

# Create a chatbot Question & Answer chain from the retriever
rag_chain_from_docs = (
    RunnablePassthrough.assign(
        context=(lambda x: format_docs(x["context"])))
    | prompt
    | chat_model
    | StrOutputParser()
)

rag_chain_with_source = RunnableParallel(
    {"context": retriever, "question": RunnablePassthrough()}
).assign(answer=rag_chain_from_docs)

上述代碼中,formatdocs用于格式化提供給模型的信息,使其易于理解和解析。我們向模型提供page_content(概述和關鍵字)以及元數據(所有其他電影屬性);任何它可能需要用來更好地向用戶推薦電影的信息。

rag_chain_from_docs是一個鏈,它獲取檢索到的文檔,并使用format_docs對其進行格式化,然后將格式化的文檔饋送到模型用來回答問題的上下文中。最后,我們創建了rag_chain_with_source,這是一個RunnableParallel,顧名思義,它并行運行兩個操作:自查詢檢索器啟動以檢索類似的文檔,而查詢只是通過RunnablePassthrough()函數傳遞給模型。然后將來自這兩個并行組件的結果進行組合,并使用rag_chain_from_docs生成答案。這里的source指的是檢索器,它可以訪問所有的“source”文檔。

因為我希望答案是流式的(例如,像ChatGPT這樣一塊一塊地呈現給用戶),所以我們使用了以下代碼:

for chunk in rag_chain_with_source.stream(query):
    for key in chunk:
        if key == 'answer':
            yield chunk[key]

程序展示

現在進入有趣的部分:與模型一起玩。Streamlit軟件是一個用于創建前端和托管應用程序的優秀工具。當然,我不會在本文中討論所開發軟件的用戶界面相關的代碼;有關此用戶界面實現的詳細信息,請參閱文后所附的原始代碼。當然,這些代碼也相當簡單,Streamlit網站(https://docs.streamlit.io/knowledge-base/tutorials/build-conversational-apps)上還有很多其他的例子可供參考。

基于LangChain自查詢檢索器的RAG系統開發實戰-AI.x社區

電影搜索實例程序的用戶界面(作者本人提供圖片)

您可以使用軟件中提供的好幾個方面的建議,但首先讓我們嘗試使用自己的查詢:

基于LangChain自查詢檢索器的RAG系統開發實戰-AI.x社區

示例查詢和模型響應情況(作者本人提供圖片)

在底層的代碼實現中,這個自我查詢的檢索器確保過濾掉任何不是法語的電影。然后,它對“成長故事”進行了相似性搜索,得出了十部在此背景下的電影。最后,機器人選擇了五部電影進行推薦。請注意建議的電影范圍:有些電影的上映日期最早在1959年,最晚在2012年。為了方便起見,我確保機器人提供的信息中包含電影的運行時間、上映年份、流媒體提供商以及機器人手工制作的簡短推薦。

(旁注:如果你還沒有看過《400拳》( The 400 Blows:https://en.wikipedia.org/wiki/The_400_Blows),請停止你正在做的任何事情,立即去看一看吧。)

值得注意的是,以前在大型語言模型中通常被視為負面的性質,例如其響應的不確定性,現在被系統認為是正面的性質。向模型提出同樣的問題兩次,你可能會得到略微不同的建議。

重要的是,要注意當前實施的一些局限性:

  • 無法保存建議。用戶可能希望重新訪問舊的推薦。
  • 手動更新電影數據庫中的原始數據。將其自動化并每周更新是個好主意。
  • 自查詢檢索過濾的元數據不正確。例如,“本·阿弗萊克電影”的查詢可能會有問題。這可能意味著查詢本·阿弗萊克主演的電影或本·阿弗萊克執導的電影。這是一個對查詢進行澄清會有所幫助的例子。

最后,您可能對本文項目作出的改進之一是,在檢索后對文檔(https://python.langchain.com/docs/integrations/retrievers/cohere-reranker)進行重新排序。另外,提供一個聊天模型也可能很有趣,因為你可以在多回合的對話中與之交談,而不僅僅是一個QA機器人。此外,你還可以創建一個推薦器代理(https://python.langchain.com/docs/integrations/tools/human_tools),以便在查詢不清楚的情況下向用戶提示一個清晰的問題。

最后,祝您的電影搜索玩得開心!

鏈接參考

  • 自己嘗試電影搜索(需要OpenAI API密鑰):https://platform.openai.com/api-keys
  • 本文位于GitHub的示例代碼鏈接:https://github.com/EdIzaguirre/FilmSearchOpen

譯者介紹

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

原文標題:How to Build a RAG System with a Self-Querying Retriever in LangChain,作者:Ed Izaguirre

鏈接:

https://towardsdatascience.com/how-to-build-a-rag-system-with-a-self-querying-retriever-in-langchain-16b4fa23e9ad。

?著作權歸作者所有,如需轉載,請注明出處,否則將追究法律責任
收藏
回復
舉報
回復
相關推薦
秋霞影院一区| 青梅竹马是消防员在线| 综合精品一区| 亚洲精品第一国产综合精品| 欧美 日韩精品| 蜜桃成人在线视频| 精品亚洲国产成人av制服丝袜| 久久综合五月天| 好男人香蕉影院| 欧美日韩亚洲国产| 一区二区三区在线免费播放| 国严精品久久久久久亚洲影视 | 亚洲欧美激情小说另类| 精品国产_亚洲人成在线| 中文字幕视频一区二区| 亚洲图片在线| 上原亚衣av一区二区三区| 久久久久无码国产精品一区李宗瑞| 国产精欧美一区二区三区蓝颜男同| 国产精品每日更新在线播放网址| 国产精品久久久一区二区三区| 日韩欧美国产另类| 亚洲国产一区二区三区高清 | 国产精品二区二区三区| 在线免费观看日韩视频| 校园激情久久| 欧美日韩高清在线观看| 综合 欧美 亚洲日本| 国产精品超碰| 91精品国产一区二区三区| 99免费视频观看| 99在线视频影院| 一区二区三区中文字幕精品精品| 亚洲精品乱码视频| 毛片免费在线| 99久久精品国产精品久久| 91麻豆国产精品| 国产乡下妇女三片| 久久99伊人| 韩国三级电影久久久久久| 日韩精品一区二区亚洲av性色| 国产不卡一二三区| 亚洲免费中文字幕| 亚洲精品视频大全| 国产精品美女在线观看直播| 欧美一区二区三区在线看| 中文字幕第100页| 成人涩涩视频| 欧美影片第一页| 不卡影院一区二区| 美女精品导航| 亚洲成a人片在线观看中文| 久久久成人精品一区二区三区 | 美女国内精品自产拍在线播放| 久久午夜精品视频| 日韩在线观看一区 | 91精品国产欧美一区二区成人| 8x8x最新地址| 69堂精品视频在线播放| 欧美性生活大片视频| 中文字幕第21页| h1515四虎成人| 欧美日韩中文字幕精品| 九九精品久久久| 国产美女视频一区二区| 日韩视频永久免费| 白丝校花扒腿让我c| 成人线上播放| 国产视频在线观看一区二区| 日韩人妻一区二区三区| 精品国产一区二区三区av片| 一区二区成人av| 免费看一级黄色| 亚洲一区二区日韩| 欧美激情国产精品| 中日韩黄色大片| 久久免费高清| 国产伊人精品在线| www日本在线| 99久久国产综合精品女不卡| 免费观看成人高| 第一福利在线| 尤物在线观看一区| 国产伦精品一区二区三区四区视频_| 午夜不卡影院| 欧美这里有精品| 欧美激情第四页| 鲁大师精品99久久久| 国产亚洲精品一区二555| 很污很黄的网站| 亚洲视频免费| 国产精品伦子伦免费视频| 国产又粗又猛又黄又爽| 国产精品亚洲第一区在线暖暖韩国| 国产精品裸体一区二区三区| 激情小说 在线视频| 亚洲女同ⅹxx女同tv| 国产极品粉嫩福利姬萌白酱| 久久亚洲国产精品尤物| 欧美精品一区二区久久婷婷| 影音先锋制服丝袜| 国内一区二区三区| 国产精品日本精品| 日韩在线观看视频一区二区三区| 中文字幕不卡三区| 国产手机免费视频| 九九久久国产| 精品福利一区二区三区| 一级二级黄色片| 99精品热视频只有精品10| 91精品国产综合久久久久久久久| 婷婷综合激情网| 亚洲精品五月天| 青青艹视频在线| 日本精品在线播放 | 国产精品一区二区三区免费观看| av资源网站在线观看| 五月婷婷久久丁香| 久久6免费视频| 九九综合九九| 久久久综合av| 国产激情视频在线播放| 国产精品网站在线观看| 国产欧美在线一区| 加勒比色综合久久久久久久久| 久久人人爽人人爽爽久久| 香蕉污视频在线观看| www.日韩av| 91动漫在线看| 亚洲精品一区在线| 久久久国产在线视频| 中国一级特黄视频| 久久久噜噜噜久久人人看| 欧洲精品在线播放| 韩国三级大全久久网站| 日韩一区二区在线视频| 中文字幕人妻色偷偷久久| 久久久久久久av麻豆果冻| 缅甸午夜性猛交xxxx| 91精品国产自产精品男人的天堂| 最新中文字幕亚洲| 免费黄色一级大片| 国产女人18水真多18精品一级做| 无码人妻丰满熟妇区毛片18| 欧美深夜视频| 欧美一区二区三区……| 亚州男人的天堂| 欧美日韩国产专区| 成人无码www在线看免费| 国产欧美日本| 欧美18视频| 婷婷综合六月| 在线观看国产精品日韩av| 中文字幕永久在线| 中文字幕免费观看一区| 成人亚洲精品777777大片| 精品精品99| 国产精品入口尤物| 生活片a∨在线观看| 欧美欧美欧美欧美| 成人免费精品动漫网站| 国产成人在线视频网站| 波多野结衣av一区二区全免费观看 | 精品国产美女| 国产精品美女免费| 香蕉视频免费在线播放| 欧美精品日韩一区| 欧美日韩人妻精品一区二区三区| 国产91在线看| 日韩免费毛片视频| 日韩欧美电影| 97免费资源站| 日本三级一区| 日韩在线播放av| 99国产精品欲| 黄色一区二区在线观看| b站大片免费直播| 久久国产尿小便嘘嘘| 青青视频免费在线| 同性恋视频一区| 91精品久久久久久久久不口人| 成人区精品一区二区不卡| 亚洲电影免费观看高清完整版在线 | 日韩黄色影片| 欧美日韩视频在线第一区| 欧美成人精品欧美一级| 久久综合久久鬼色中文字| 亚欧美在线观看| 国内精品久久久久久久影视蜜臀| 欧美极品一区| 久久天堂久久| 热久久99这里有精品| 黄色网页在线看| 亚洲国产精品小视频| 中文字幕一区二区三区四区免费看| 亚洲男人的天堂在线aⅴ视频| 精品无码在线视频| 国产一区二区精品久久99| 91av资源网| 91成人影院| 欧美日韩日本网| 香蕉大人久久国产成人av| 国产成人激情小视频| 日韩精品亚洲人成在线观看| 亚洲深夜福利视频| 亚洲成人黄色片| 欧美影院一区二区三区| 好吊妞视频一区二区三区| 亚洲欧洲成人精品av97| 大又大又粗又硬又爽少妇毛片| 国产电影一区二区三区| 欧美日韩中文不卡| 性色一区二区三区| 岛国大片在线播放| 99久久夜色精品国产亚洲96| 极品尤物一区二区三区| 日韩精品免费视频一区二区三区| 国产精品精品久久久| 男人久久天堂| 欧美精品999| а√天堂官网中文在线| 最近2019中文字幕第三页视频| 天天操天天干天天爽| 日韩一区二区视频在线观看| 瑟瑟视频在线免费观看| 色综合av在线| 亚洲男人第一av| 亚洲午夜久久久久久久久电影院| 欧美性x x x| 亚洲欧美一区二区在线观看| 午夜精产品一区二区在线观看的| 不卡视频一二三四| 国产a级片视频| 国产精品一品二品| 精品国产乱码久久久久久1区二区| 老**午夜毛片一区二区三区 | 永久免费看片直接| 中文av字幕一区| 美国美女黄色片| 国产欧美日韩视频在线观看| 魔女鞋交玉足榨精调教| 久久久五月婷婷| 亚洲精品国产一区黑色丝袜| 久久精品视频网| 精品人妻无码一区二区三区| 91美女在线观看| 魔女鞋交玉足榨精调教| 2024国产精品| 亚洲国产日韩一区无码精品久久久| 91免费看视频| 波多野结衣一本| 久久久不卡影院| 一级特黄曰皮片视频| 亚洲国产成人午夜在线一区| 中文字幕求饶的少妇| 日韩一区欧美一区| 欧美极品视频在线观看| 亚洲一区二区三区激情| 国产乱码久久久久久| 五月天国产精品| 欧美特黄aaaaaa| 91久久精品一区二区| 亚洲 欧美 中文字幕| 欧美日韩免费不卡视频一区二区三区 | 欧美性黄网官网| 亚洲成人av网址| 欧美二区在线观看| 东京干手机福利视频| 日韩精品中文字幕在线观看| 可以在线观看的av| 丝袜一区二区三区| 四虎av在线| 欧美一级片一区| 欧美日韩视频免费看| 超碰97在线播放| 亚洲成人一品| 一本色道婷婷久久欧美| 午夜精品电影| 无码精品国产一区二区三区免费| 日本在线不卡视频| www.久久com| 91在线小视频| 日本美女黄色一级片| 午夜欧美大尺度福利影院在线看| 日本韩国欧美中文字幕| 欧美日韩精品免费观看视频| 亚洲va欧美va| 国产午夜精品全部视频在线播放| 国产在线更新| 日本成人在线视频网址| 超碰国产精品一区二页| 精品国产_亚洲人成在线| 99国产精品免费视频观看| 亚洲国产精品成人天堂| 日韩av不卡一区二区| 亚洲一二三四五| 国产精品麻豆视频| 日韩少妇高潮抽搐| 制服丝袜成人动漫| 青青草观看免费视频在线| 久久91精品国产91久久久| 成人做爰视频www网站小优视频| 亚洲精品免费av| 精品国产一区二区三区久久久樱花 | 在线播放av网址| 欧美激情一区二区三区四区| 日韩精品无码一区二区| 91精品国产91久久综合桃花| 国产天堂素人系列在线视频| 久久久久久18| 国产不卡精品| 亚洲精品日韩在线观看| 国产亚洲欧洲| 日本一级大毛片a一| 亚洲色图在线视频| 这里只有久久精品视频| 日韩第一页在线| 欧美寡妇性猛交xxx免费| 国产精品视频免费观看www| 亚洲精品中文字幕99999| 免费毛片网站在线观看| 国产精品自在在线| 亚洲精品一区二区三区在线播放| 色哟哟一区二区| 午夜在线视频观看| 久久青草福利网站| 中文字幕区一区二区三| 影音先锋男人的网站| 日韩精品久久理论片| 波多野结衣福利| 精品久久久久久久久久久| 黄色一级大片在线免费看国产| 久久久精品在线观看| 久久精品嫩草影院| 日韩欧美一区二区视频在线播放 | 亚洲人成伊人成综合网小说| 久久国产香蕉视频| 亚洲午夜色婷婷在线| 热色播在线视频| 久久久com| 亚洲欧美视频| 中文字幕av网址| 欧美视频第一页| 欧美精品少妇| 日产日韩在线亚洲欧美 | 中文字幕中文字幕99| 麻豆精品一区二区| 亚洲欧美日韩第一页| 欧美三级日韩在线| 天天在线视频色| 亚洲自拍av在线| 午夜国产欧美理论在线播放 | 国产视频一区二区在线| 高潮毛片又色又爽免费| 在线播放国产精品| 欧美在线一级| 男人j进女人j| 成人国产免费视频| 久草视频在线观| 亚洲欧美一区二区激情| 成人在线中文| 国产成人精品免费看在线播放 | 91久久久免费一区二区| 午夜免费播放观看在线视频| 亚洲一区二区免费| 伊人成人在线视频| 国产成人精品无码免费看夜聊软件| 欧美午夜www高清视频| 国产精品二线| 成人伊人精品色xxxx视频| 国产精品porn| 熟女俱乐部一区二区视频在线| 欧美网站一区二区| 一区二区三区伦理| 免费成人在线观看av| 久久精品国产一区二区三| 久久精品99久久久久久| 精品亚洲男同gayvideo网站| 69堂免费精品视频在线播放| 超碰在线免费观看97| 99精品欧美一区二区蜜桃免费 | 蜜桃传媒视频麻豆一区| 青青草成人在线观看| 欧美毛片在线观看| 亚洲欧美精品中文字幕在线| 97精品资源在线观看| av日韩一区二区三区| 欧美激情综合在线| 亚洲a视频在线观看| 国产精品久久电影观看| 韩国欧美一区| 国产黄色录像视频| 精品久久久久久久人人人人传媒 | 国产欧美日本在线| 日本在线播放一区二区三区| 久久午夜无码鲁丝片午夜精品| 国产香蕉一区二区三区在线视频 | 精品久久人人做人人爰| 成人美女视频| 黄色a级片免费看|