精品欧美一区二区三区在线观看 _久久久久国色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| 欧美孕妇孕交| 久久99精品久久久久久动态图| 欧美日韩成人精品| 真实乱视频国产免费观看| 欧美日韩成人影院| 一区二区成人在线视频| 国产日韩欧美亚洲一区| 国产精品高清无码| 激情自拍一区| 在线观看91久久久久久| 苍井空张开腿实干12次| 怡红院成人在线| 亚洲丶国产丶欧美一区二区三区| 日本福利一区二区三区| 欧美天堂在线视频| 国产一区二区三区久久悠悠色av| 日本精品视频网站| 国产一级视频在线| 98精品视频| 亚洲男女性事视频| 日本一区二区在线观看视频| 日韩成人综合网站| 色爱区综合激月婷婷| 久操手机在线视频| 国产黄网站在线观看| 久久精品水蜜桃av综合天堂| 国产麻豆日韩| 精品国产亚洲av麻豆| 青青青伊人色综合久久| 日韩暖暖在线视频| 在线观看亚洲欧美| 亚洲九九精品| 欧美裸体xxxx极品少妇| 性生交大片免费全黄| 国际精品欧美精品| 精品香蕉一区二区三区| 亚洲男人在线天堂| 久久久伦理片| 亚洲а∨天堂久久精品喷水| 五月天视频在线观看| 成人免费在线观看视频| 在线精品视频一区二区| 可以在线看的黄色网址| 韩日精品一区二区| 欧美性猛交xxxx黑人| 国产精品网站免费| 成人黄色动漫| 精品久久久久久| 欧美 日韩 国产 高清| ****av在线网毛片| 无码av中文一区二区三区桃花岛| 精品少妇人欧美激情在线观看| 色呦呦呦在线观看| 亚洲综合色在线| 五月天激情图片| 午夜伦理大片视频在线观看| 夜色激情一区二区| 久久精品xxx| 麻豆mv在线看| 日韩欧美aaa| 污污视频网站免费观看| 午夜激情成人网| 欧美日韩另类一区| 国产一级片中文字幕| 亚洲亚洲一区二区三区| 亚洲精品在线观| 国产麻豆天美果冻无码视频 | 欧美色视频在线| 一区二区xxx| 国产精品一区二区美女视频免费看| 欧美精品丝袜久久久中文字幕| 国内自拍第二页| 涩爱av色老久久精品偷偷鲁 | 黄色av电影网站| 久久久久久毛片免费看| 亚洲色图av在线| 91制片厂在线| 亚洲承认在线| 国产成人亚洲综合| 夜夜骚av一区二区三区| 国产a级毛片一区| 久久久国产精品一区二区三区| 理论视频在线| 亚洲欧美在线高清| 性欧美大战久久久久久久| 欧美日韩美女| 欧美一区日韩一区| 无套内谢大学处破女www小说| 国产探花在线精品一区二区| 久久精品久久久久| 国产又大又黑又粗免费视频| 久久综合导航| 亚洲aⅴ男人的天堂在线观看| 欧洲精品久久一区二区| 久久久另类综合| 日韩video| 性欧美18xxxhd| 69堂亚洲精品首页| 爱爱免费小视频| 国产精品大片免费观看| 国产ts人妖一区二区三区 | 国精产品一区一区三区mba视频 | 国产精品一区二区三区四区色| 国产精品超碰97尤物18| 亚洲不卡中文字幕无码| 一区二区三区日本视频| 日韩精品在线观看网站| 69av.com| 美女国产一区二区三区| 精品一区久久久| 成人在线观看亚洲| 欧美在线免费播放| 久久人妻一区二区| 欧美日韩18| 成人国产精品一区| 男操女在线观看| 亚洲成av人在线观看| 国产5g成人5g天天爽| 欧美精品一区二区久久| 97色伦亚洲国产| 精品人妻久久久久一区二区三区 | 亚洲第一中文字幕在线观看| 久草福利资源在线| 日本网站在线观看一区二区三区 | 少妇极品熟妇人妻无码| 欧美韩国日本在线观看| 国产va免费精品高清在线观看| 欧美一级视频免费| 一区二区三区美女| 国产探花在线观看视频| 久久一区91| 国产成人拍精品视频午夜网站| 天堂成人在线视频| 亚洲最新视频在线播放| 四虎成人在线播放| 天天操综合网| 国产又爽又黄的激情精品视频| 国产youjizz在线| 日本道在线观看一区二区| 男男做爰猛烈叫床爽爽小说| 欧美日韩一区二区国产| 91免费看蜜桃| 牛牛精品在线| 亚洲第一中文字幕在线观看| 不卡的免费av| 99视频精品全部免费在线| 激情小视频网站| 久久99国产精品久久99大师| 欧美精品激情blacked18| 亚洲精品国产一区二| 亚洲最新在线观看| 亚洲 欧美 日韩在线| 国产欧美一区二区三区国产幕精品| 福利视频一区二区三区| 2021天堂中文幕一二区在线观| 欧美精品一区二区精品网| 国产精品2020| 99精品偷自拍| 国产成人精品无码播放| 欧美美女一区| 成人写真视频福利网| 中文字幕有码在线视频| 精品国精品国产| 少妇一级淫片免费放中国 | 国产一级做a爱免费视频| 成人午夜视频福利| 精品一区二区中文字幕| heyzo久久| 91在线中文字幕| 成人av影院在线观看| 日韩精品在线视频美女| 成人免费一区二区三区| 亚洲人亚洲人成电影网站色| 免费啪视频在线观看| 西西人体一区二区| 中文字幕不卡每日更新1区2区| 亚洲精品福利| 日本精品一区二区三区在线| 午夜激情视频在线| 精品国精品国产尤物美女| 久久久久久久久黄色| 中文字幕视频一区二区三区久| 日本天堂在线播放| 日韩av在线免费观看不卡| 91九色国产ts另类人妖| 日韩av中文字幕一区| 国产精品一香蕉国产线看观看 | 亚洲精品久久久蜜桃| 在线精品一区二区三区| 麻豆精品国产91久久久久久| 国产黄色激情视频| 国产一区不卡| www.久久爱.cn| 色8久久影院午夜场| 欧美理论片在线观看| 青青青草原在线| 日韩视频123| 最近中文在线观看| 婷婷综合在线观看| 欧美三级小视频| 国产日韩欧美高清| 国产伦精品一区三区精东| 老鸭窝一区二区久久精品| www..com日韩| 久久久久久久久99精品大| 免费久久一级欧美特大黄| 久久三级中文| 国产欧美日韩中文| 欧美特大特白屁股xxxx| 性欧美在线看片a免费观看 | 91精品国产高清| 宅男在线观看免费高清网站| 中文精品99久久国产香蕉| 天堂中文资源在线观看| 日韩一区二区精品在线观看| 亚洲免费视频二区| 欧美性高潮床叫视频| 精品无码人妻一区二区三| 国产精品久久久久久户外露出| 成人免费无码大片a毛片| 国产91精品一区二区麻豆亚洲| 成人亚洲精品777777大片| 久久精品网址| 国产黄页在线观看| 亚洲日本国产| 久久精品xxx| 欧美日韩调教| 久久福利一区二区| 欧美激情1区2区| 午夜探花在线观看| 国产精品黑丝在线播放| 亚洲福利av| 欧美亚洲国产精品久久| 欧美一区二区福利| 国产精品片aa在线观看| 久久免费视频1| 亚洲国产欧美日韩在线观看第一区| 国产精品国产亚洲精品看不卡15 | 视频一区在线免费观看| 国产99精品| 日韩一区二区三区资源| 国产aⅴ精品一区二区三区久久| 精品国产一区二区三区日日嗨 | 日韩av在线资源| 天天干天天摸天天操| 亚洲福利视频网| 亚洲欧美丝袜中文综合| 亚洲精品少妇网址| 黄色片视频在线观看| 一区二区三区国产视频| 国产在线视频网| 综合久久五月天| 国产激情在线| 97国产一区二区精品久久呦| 欧美私密网站| 国产精品免费一区二区三区都可以| yw.尤物在线精品视频| 国产欧美亚洲视频| 国产亚洲高清一区| julia一区二区中文久久94| 国产精品自在| 欧美连裤袜在线视频| 成人一二三区| 日韩一二区视频| 日韩一级大片| 精品久久久久久无码国产| 麻豆精品新av中文字幕| 肉丝美足丝袜一区二区三区四| 成人性生交大片免费看中文| 丝袜美腿中文字幕| 国产精品亲子伦对白| 欧美色图一区二区| 欧美午夜www高清视频| 中文字幕有码视频| 日韩欧美二区三区| 日本aaa在线观看| 久久深夜福利免费观看| а√天堂资源官网在线资源| 国产精品av在线播放| 日本少妇精品亚洲第一区| 久久99精品久久久久久三级 | 国产精品午夜一区二区| 欧美一区日韩一区| 久草视频在线看| 欧美噜噜久久久xxx| 日韩大尺度黄色| 999国产在线| 神马电影久久| 日韩欧美猛交xxxxx无码| 丝袜a∨在线一区二区三区不卡| 国产九九九视频| 久久精品人人爽人人爽| 男女羞羞免费视频| 欧美亚洲动漫另类| 免费观看毛片网站| 视频在线观看一区二区| 亚洲小少妇裸体bbw| 亚洲在线观看视频| 狠狠色丁香婷婷综合影院| youjizz.com在线观看| 免费不卡在线观看| 丰满少妇一区二区三区| 亚洲日本va午夜在线影院| 手机av免费观看| 亚洲第一免费网站| 污网站在线免费看| 国产免费成人av| 国内黄色精品| 日韩中文字幕在线视频观看| 国产综合色视频| 国产精品久久免费观看| 精品露脸国产偷人在视频| av免费在线不卡| 日韩中文字幕网| 91久久久久久白丝白浆欲热蜜臀| 国产精品一区在线播放| 91精品国偷自产在线电影 | 女人帮男人橹视频播放| 久久国产综合精品| 日韩在线视频免费看| 欧美亚洲自拍偷拍| 蝌蚪视频在线播放| 国产91色在线| 久久综合亚洲| 十八禁视频网站在线观看| 91美女片黄在线观看| 日本熟妇毛耸耸xxxxxx| 欧美电影免费观看完整版| av片哪里在线观看| 91免费精品视频| 久久久9色精品国产一区二区三区| 在线免费av播放| 中文无字幕一区二区三区| 无码人妻久久一区二区三区| 日韩精品极品视频免费观看| 成年女人在线看片| 精品乱码一区| 午夜在线视频观看日韩17c| 黑丝av在线播放| 日韩欧美国产视频| 国产在线视频网| 国产美女直播视频一区| 外国成人激情视频| 超碰在线免费av| 一区二区三区在线影院| 亚洲精品福利网站| 69视频在线免费观看| 网友自拍一区| 国产v亚洲v天堂无码久久久| 国产日韩精品视频一区| 伊人免费在线观看高清版| 久久精品电影网站| 色妞ww精品视频7777| 久久国产精品视频在线观看| 94色蜜桃网一区二区三区| 无码日韩精品一区二区| 中文字幕日韩精品在线| japansex久久高清精品| 男人的天堂avav| 91影院在线观看| 中文字幕人妻一区二区三区视频| 日韩中文字幕在线视频| 日韩欧美中文在线观看| 日本网站免费在线观看| 国产欧美日韩视频一区二区| 亚洲视频一区二区三区四区| 久久夜色精品国产| 九九热hot精品视频在线播放| www.日日操| 亚洲三级电影网站| 天堂网在线中文| 国产欧美va欧美va香蕉在| 欧美激情综合| 草草影院第一页| 在线不卡中文字幕| 欧美日韩国产观看视频| 亚洲精品一区二区三区四区五区| 国产精品一卡二卡| www.国产高清| 另类视频在线观看| 亚洲精品亚洲人成在线| 日韩av在线中文| 天天综合日日夜夜精品| 香港伦理在线| 国产一区免费在线| 麻豆精品在线播放| 色婷婷av国产精品| 美女少妇精品视频| 综合伊思人在钱三区| 国产永久免费网站| 日韩欧美a级成人黄色| 好了av在线| 日本高清不卡一区二区三| 福利一区二区在线| 中文无码精品一区二区三区| 欧美激情区在线播放|