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

RAG系列:切分優化 - 基于句子余弦距離的語義切分

人工智能
本文介紹了一種更智能的切分方法 - 基于句子余弦距離的語義切分,并通過 langchain-experimental 中的 SemanticChunker 的源碼來帶大家了解了語義切分的實現原理。

引言

傳統的文檔切分方法通常采用基于特定字符和固定長度的切分策略,這種方法雖然實現簡單,但在實際應用中容易割裂完整的語義單元,導致后續的信息檢索與理解受到影響。

相比之下,一種更智能的切分方法是基于句子余弦距離的語義切分。它不再依據特定字符和固定長度進行機械切分,而是對每個句子進行 embedding,以此來計算相鄰句子的余弦距離,再通過算法算出一個相對合理的切分點(某個距離值),最后將不大于該閾值的相鄰句子聚合在一起作為一個文檔塊,從而實現文檔語義切分。

例如 句子_1、句子_2、句子_3 之間的余弦距離都小于該閾值,而 句子_3 與 句子_4 的余弦距離大于該閾值,則在 句子_3 和 句子_4 之間增加切分點,最終的切分結果就是把 句子_1、句子_2、句子_3 聚合在一個文檔塊中,句子_4 在其它的文檔塊中。

實現原理

基于余弦距離的語義切分大致分為以下5個步驟:

圖片

langchain-experimental中的 SemanticChunker[1] 實現了基于余弦距離的語義切分,因此本文我將通過 SemanticChunker 的源碼來帶大家了解語義切分的實現原理。

以下是 SemanticChunker 的初始化參數,后面根據不同步驟所需要的參數來了解這些參數的具體作用。

class SemanticChunker(
    # 向量模型
    embeddings: Embeddings,
    # 向前向后取 buffer_size 個句子一起 embedding
    buffer_size: int = 1, 
    # 是否在元數據添加開始切分的位置(以文檔字符長度計算)
    add_start_index: bool = False,
    # 切分點計算方法
    breakpoint_threshold_type: BreakpointThresholdType = "percentile",
    # 切分點計算閾值
    breakpoint_threshold_amount: float | None = None,
    # 切分后的文檔塊數量
    number_of_chunks: int | None = None,
    # 句子切分規則
    sentence_split_regex: str = r"(?<=[.?!])\s+",
    # 最小文檔塊大小
    min_chunk_size: int | None = None
)

句子切分

這一步是通過特定規則將文檔切分為一個個句子,在 SemanticChunker 中通過參數 sentence_split_regex 來設置規則進行切分,默認值為 r"(?<=[.?!])\s+",這是以英文的句號、問號、感嘆號來進行切分的,而且是對比較規范的英文行文,也就是這三種標點后還跟空白字符的。如果要對中文文檔切分,那就需要將這個正則表達式替換成能切分中文的,例如:r"(?<=[。?!\n])",也就是以中文的句號、問號、感嘆號以及換行符來進行切分。

SemanticChunker的實現源碼如下:

import re

def _get_single_sentences_list(self, text: str) -> List[str]:
    return re.split(self.sentence_split_regex, text)

句子 embedding

這一步是將每個句子進行 embedding,理論上接著就以每個句子 embedding 結果來計算相鄰句子的距離就可以了。但通過實際操作發現對單個句子處理噪音比較大,后續切分的效果并不理想,因此 SemanticChunker 通過 buffer_size 來控制當前句子前、后各取幾個句子組成一組來計算 embedding 并計算余弦距離。例如buffer_size設置為為1(默認值),表示取當前句子前、后各取1個句子組成一組來計算 embedding。

SemanticChunker的實現源碼如下:

首先根據buffer_size得到當前句子的組合。

def combine_sentences(sentences: List[dict], buffer_size: int = 1) -> List[dict]:
    for i inrange(len(sentences)):
        # 創建一個字符串變量來保存連接的句子
        combined_sentence = ""

        # 添加當前句子之前 buffer_size 個句子
        for j inrange(i - buffer_size, i):
            if j >= 0:
                combined_sentence += sentences[j]["sentence"] + " "

        # 添加當前句子
        combined_sentence += sentences[i]["sentence"]

        # 添加當前句子之后 buffer_size 個句子
        for j inrange(i + 1, i + 1 + buffer_size):
            if j < len(sentences):
                combined_sentence += " " + sentences[j]["sentence"]

        # 將合并好的句子存儲在當前的句子 combined_sentence 中
        sentences[i]["combined_sentence"] = combined_sentence

    return sentences

然后根據通過參數 embeddings傳入的向量模型對句子組合進行 embedding。

def _calculate_sentence_distances(self, single_sentences_list: List[str]) -> Tuple[List[float], List[dict]]:
    _sentences = [
        {"sentence": x, "index": i} for i, x in enumerate(single_sentences_list)
    ]
    sentences = combine_sentences(_sentences, self.buffer_size)
    embeddings = self.embeddings.embed_documents(
        [x["combined_sentence"] for x in sentences]
    )
    for i, sentence in enumerate(sentences):
        sentence["combined_sentence_embedding"] = embeddings[i]

    return calculate_cosine_distances(sentences)

計算相鄰句子(組)余弦距離

這一步就是通過計算相鄰句子(組) 的余弦相似度來得到相鄰句子(組) 的余弦距離。

將橫軸記為句子(組)的序號,縱軸為相鄰句子(組) 的余弦距離,就可得到下面類似的圖:

圖片

SemanticChunker的實現源碼如下:

from langchain_community.utils.math import cosine_similarity

defcalculate_cosine_distances(sentences: List[dict]) -> Tuple[List[float], List[dict]]:
    distances = []
    for i inrange(len(sentences) - 1):
        embedding_current = sentences[i]["combined_sentence_embedding"]
        embedding_next = sentences[i + 1]["combined_sentence_embedding"]

        # 計算余弦相似度
        similarity = cosine_similarity([embedding_current], [embedding_next])[0][0]

        # 轉換成余弦距離
        distance = 1 - similarity
        distances.append(distance)

        # 保存余弦距離
        sentences[i]["distance_to_next"] = distance

    # 【可選】最后一個句子的處理
    # sentences[-1]['distance_to_next'] = None  # 或其它默認值

    return distances, sentences

計算切分點

如何計算切分點,SemanticChunker給出了4種方法:

  • percentile: 分位法,默認方法。將所有余弦距離在第 X 分位數的值作為閾值,并在那些余弦距離超過該閾值的位置進行切分。第 X 分位數可通過breakpoint_threshold_amount 設置,默認為 95。還可以通過 number_of_chunks 指定切分后的文檔塊總數量,采用線性插值的方式反向推導出該分位數;

SemanticChunker的實現源碼如下:

import numpy as np

def_calculate_breakpoint_threshold(self, distances: List[float]) -> Tuple[float, List[float]]:
# 第一種方式:指定分位數
return cast(
      float,
      np.percentile(distances, self.breakpoint_threshold_amount),
  ), distances

# 第二種方式:通過 number_of_chunks 反向推導分位數
  x1, y1 = len(distances), 0.0
  x2, y2 = 1.0, 100.0
  x = max(min(self.number_of_chunks, x1), x2)
if x2 == x1:
      y = y2
else:
      y = y1 + ((y2 - y1) / (x2 - x1)) * (x - x1) # 線性插值
  y = min(max(y, 0), 100)
    return cast(
      float,
      np.percentile(distances, y),), 
      distances
  • standard_deviation: 標準差偏離法,是統計學中表示偏離的常規方法,這種方法比較適合正態分布。將所有余弦距離的平均值加上 X 倍的所有余弦距離標準差的值作為閾值,并在那些余弦距離超過該閾值的位置進行切分。X 倍可通過breakpoint_threshold_amount 設置,默認為 3,這是最常用的值;

SemanticChunker的實現源碼如下:

import numpy as np

def _calculate_breakpoint_threshold(self, distances: List[float]) -> Tuple[float, List[float]]:
  return cast(
    float,
    np.mean(distances) + 
      self.breakpoint_threshold_amount * np.std(distances),), 
    distances
  • interquartile: 四分位距法,是統計學中表示偏離的另一種常規方法,這種方法計算分位數,所以數據分布不那么正態問題也不大。將所有余弦距離的平均值加上 X 倍的所有余弦距離四分位距的值作為閾值,并在那些余弦距離超過該閾值的位置進行切分。X 倍可通過breakpoint_threshold_amount 設置,默認為 1.5,也是最常用的值;

SemanticChunker的實現源碼如下:

import numpy as np

def _calculate_breakpoint_threshold(self, distances: List[float]) -> Tuple[float, List[float]]:
  # 取出25分位(下四分位)和75分位(上四分位)的數值
  q1, q3 = np.percentile(distances, [25, 75])

  # 計算兩個分位的差值(四分位距)
  iqr = q3 - q1

  return np.mean(distances) + 
            self.breakpoint_threshold_amount * iqr, distances
  • gradient: 梯度法。首先計算所有余弦距離的變化梯度,變化梯度計算出來后,就可以知道哪個地方余弦距離變化得快,然后將所有變化梯度在第 X 分位數的值作為閾值,并在那些余弦距離超過該閾值的位置進行切分。第 X 分位數可通過breakpoint_threshold_amount 設置,默認為 95。

SemanticChunker的實現源碼如下:

import numpy as np

def _calculate_breakpoint_threshold(self, distances: List[float]) -> Tuple[float, List[float]]:
  # 計算所有余弦距離的變化梯度
  distance_gradient = np.gradient(distances, range(0, len(distances)))
  return cast(
      float,
      np.percentile(distance_gradient,
                    self.breakpoint_threshold_amount)),
      distance_gradient

按切分點切分

通過第4步各方法得到切分點后,就可以按切分點對文檔進行切分(通過設置min_chunk_size控制合并較小的塊),就可得到下面類似的圖(包括切分位置以及切片):

圖片

SemanticChunker的實現源碼如下:

def split_text(self, text: str,) -> List[str]:
      # 計算相鄰句子的余弦距離
      distances, sentences = self._calculate_sentence_distances(single_sentences_list)

      # 計算切分點
      breakpoint_distance_threshold, breakpoint_array = self._calculate_breakpoint_threshold(distances)

      indices_above_thresh = [
          i
          for i, x inenumerate(breakpoint_array)
          if x > breakpoint_distance_threshold
      ]

      chunks = []
      start_index = 0

      # 遍歷切分點來分割句子
      for index in indices_above_thresh:
          end_index = index
          group = sentences[start_index : end_index + 1]
          combined_text = " ".join([d["sentence"] for d in group])
        
          # 通過設置 min_chunk_size 來合并較小的文檔塊
          if (
              self.min_chunk_size isnotNone
              andlen(combined_text) < self.min_chunk_size
          ):
              continue
          chunks.append(combined_text)

          start_index = index + 1

      if start_index < len(sentences):
          combined_text = " ".join([d["sentence"] for d in sentences[start_index:]])
          chunks.append(combined_text)
      return chunks

代碼實踐

原 TypeScript 項目已使用 Python 進行了重構,后續將優先使用 Python 進行代碼實踐和講解。

其中:RAG.libs 中是封裝好的各種不同作用的模塊,如 RAG/libs/text_splitter.py 是封裝好的文檔切分器,RAG/libs/evaluator.py 是封裝好的評估器,因此文中不再貼具體的代碼,如需查看具體代碼實現,請移步到 github 代碼倉庫中查看。

本文完整代碼地址[2]:https://github.com/laixiangran/ai-learn-python/blob/main/RAG/examples/06_semantic_splitting.py

先看下基于句子余弦距離的語義切分的評估結果:

圖片

從評估結果來看,相較于 RecursiveCharacterTextSplitter 的切分方法,在上下文召回率、上下文相關性以及答案準確性都有不同程度的提升。

加載文件

from RAG.libs.file_loader import FileLoader

file_loader = FileLoader(
    file_path="RAG/datas/2024少兒編程教育行業發展趨勢報告.md",
    provider="customMarkdownLoader",
)
documents = file_loader.load()

語義切分

因為我們的文檔只要是中文,因此需要將 sentence_split_regex修改成可對中文切分的規則,如:r"(?<=[。?!\n])"

from langchain_experimental.text_splitter import SemanticChunker
from RAG.libs.embedding import Embedding

# 向量模型
embeddings = Embedding(model="nomic-embed-text", provider="ollama")

# 使用 SemanticChunker 切分
text_splitter = SemanticChunker(
    embeddings=embeddings,
    breakpoint_threshold_type="percentile",
    sentence_split_regex=r"(?<=[。?!\n])",
)
documents = text_splitter.split_documents(documents=documents)

切分后處理

使用SemanticChunker進行切分,會出現較短或者較長的切片。比如通過percentile進行切分后的結果可以看到,最小的文檔塊大小只有 1,最大的文檔塊大小有 3346。因此,為了更好的檢索效果,我們一般需要=對較長的文檔做二次切分、對較短的文檔進行合并和添加標題等其它切分后處理。

count 75 // 總數
mean 731 // 平均值
std 685 // 標準差
min 1 // 最小值
25% 218 // 25分位值
50% 568 // 50分位值
75% 990 // 75分位值
90% 1535 // 90分位值
97% 2577 // 97分位值
99% 2876 // 99分位值
max 3346 // 最大值

將較大的文檔塊進行二次切分、合并較小的塊和添加標題:

from RAG.libs.text_splitter import (
    TextSplitter,
    merge_small_documents,
    add_headers_to_documents,
)

# 將較大的文檔塊進行二次切分
text_splitter = TextSplitter(
    provider="recursiveCharacter",
    chunk_size=500,
    chunk_overlap=0,
)
documents = text_splitter.split_documents(documents)

# 合并較小的塊和添加標題
documents = merge_small_documents(documents, merge_max_length=100)
documents = add_headers_to_documents(documents)

效果評估

from RAG.libs.evaluator import BatchEvaluator

eval_result = BatchEvaluator(
    chat_model=chat_model,
    vector_store=vector_store,
    qa_data=qa_data,
    top_k=3,
    filter=filter,
    output_path=output_path,
)

結語

本文介紹了一種更智能的切分方法 - 基于句子余弦距離的語義切分,并通過 langchain-experimental 中的 SemanticChunker 的源碼來帶大家了解了語義切分的實現原理。

從最后評估結果來看,相較于 RecursiveCharacterTextSplitter 的切分方法,在上下文召回率、上下文相關性以及答案準確性都有不同程度的提升,這說明通過基于句子余弦距離的語義切分方法對文檔切分優化具有一定的可行性,大家可以根據自己的實際情況進一步驗證,歡迎大家留言交流。

引用鏈接

[1] SemanticChunker: https://github.com/langchain-ai/langchain-experimental/blob/main/libs/experimental/langchain_experimental/text_splitter.py#L99

[2] 本文完整代碼地址: https://github.com/laixiangran/ai-learn-python/blob/main/RAG/examples/06_semantic_splitting.py

責任編輯:龐桂玉 來源: 燃哥講AI
相關推薦

2025-06-10 04:30:00

2024-09-04 09:11:42

2025-08-01 01:55:00

2022-01-07 14:00:35

分庫分表業務量

2019-11-25 10:12:59

Python技巧工具

2011-08-18 16:03:48

數據切分MySQL

2025-04-02 04:00:00

RAG分塊優化

2025-05-22 06:48:50

RAGAI應用開發框架DeepSeek

2017-07-17 14:45:43

數據庫DB分庫切分策略

2024-09-29 00:00:02

2017-12-08 10:42:49

HBase切分細節

2017-08-28 16:40:07

Region切分觸發策略

2021-03-17 16:15:55

數據MySQL 架構

2024-06-24 14:32:33

2025-10-30 02:11:00

2017-06-19 16:45:41

數據庫水平切分用戶中心

2025-05-26 09:57:46

2024-02-05 14:12:37

大模型RAG架構

2023-10-10 14:03:47

swap排序解法

2025-05-07 08:35:11

點贊
收藏

51CTO技術棧公眾號

精品国产91久久久久久老师| 国产高清不卡一区| 中文字幕精品一区二区精品| 久久久久xxxx| av在线资源| 欧美国产日韩精品免费观看| 51国产成人精品午夜福中文下载 | 欧美日韩午夜剧场| 亚洲精品影院| 日本精品一二区| 麻豆国产精品777777在线| 韩国欧美亚洲国产| www.99re7| 成人91在线| 日韩三级高清在线| 中文字幕在线观看第三页| 大桥未久在线播放| 亚洲欧洲精品一区二区三区不卡| 麻豆av一区二区| 国产婷婷在线视频| 久久久青草婷婷精品综合日韩| 久久久精品视频在线观看| 在线精品一区二区三区| 99精品美女视频在线观看热舞 | 国产欧美精品aaaaaa片| 国产黄在线观看免费观看不卡| 国产91精品一区二区麻豆网站| 国产精品视频一区国模私拍| 日本三级理论片| 五月天综合网站| 国产一区二区三区在线播放免费观看| 国产在线不卡av| 精品视频国内| 欧美精品日韩一本| 美女一区二区三区视频| 日韩大片免费观看| 亚洲成在线观看| 免费观看亚洲视频| www红色一片_亚洲成a人片在线观看_| 国产无一区二区| 国产在线精品一区二区三区| 国产强伦人妻毛片| 久久精品国产免费| 国产精品精品视频| 国产精品午夜一区二区| 9色国产精品| 午夜精品一区二区三区视频免费看 | 国产手机视频在线观看| www日韩tube| 91麻豆视频网站| wwwxx欧美| 在线观看毛片视频| 日韩主播视频在线| 91国内免费在线视频| 久久99久久98精品免观看软件 | 日韩极品视频在线观看| 午夜伦理在线视频| 亚洲午夜在线观看视频在线| 国内少妇毛片视频| 成人性生交大片免费看网站| 亚洲国产一区在线观看| 国产原创popny丨九色| free性护士videos欧美| 欧美午夜激情在线| 91蝌蚪视频在线观看| 欧美xnxx| 欧美剧情片在线观看| 深爱五月综合网| 99re6热只有精品免费观看| 亚洲成人精品av| 人妻熟女aⅴ一区二区三区汇编| 亚洲欧美tv| 中文字幕日韩视频| 黄色一级片在线| 日韩午夜av| 国产精品久久激情| 国产三级自拍视频| 成人av在线资源| 欧美一二三区| av在线导航| 午夜日韩在线观看| 欧美日韩在线成人| 国产精品igao视频网网址不卡日韩| 欧美一区在线视频| 亚洲欧美色图视频| 欧美电影免费播放| 中文字幕久热精品在线视频| 久久久久无码精品国产sm果冻| 98精品久久久久久久| 午夜精品一区二区三区在线播放| 日本免费在线观看视频| 国产在线乱码一区二区三区| 国产精品日韩欧美一区二区| av成人手机在线| 亚洲综合色区另类av| 国产麻花豆剧传媒精品mv在线| 国产成人福利夜色影视| 欧美一二三区精品| 一区二区三区免费在线观看视频| 日韩中字在线| 97国产成人精品视频| 亚洲天堂手机在线| aaa亚洲精品一二三区| 色香蕉在线观看| 极品在线视频| 日韩一区二区三区在线视频| 亚洲国产av一区| 欧美日本不卡高清| 国产精品久久久久久久久久久久久久 | 亚洲精品乱码| 91精品国产自产在线| 亚洲欧洲精品视频| 亚洲精选视频免费看| 欧美黑人又粗又大又爽免费| 粉嫩av一区二区| 久久精品国产亚洲| 波多野结衣高清在线| 成人av电影在线| 经典三级在线视频| 粉嫩91精品久久久久久久99蜜桃| 亚洲国产一区自拍| 久久久精品视频免费观看| 奇米影视一区二区三区| 六十路精品视频| 国模雨婷捆绑高清在线| 欧美日韩高清一区| 少妇无套高潮一二三区| 国产精品视频| 国产成人精品免费视频大全最热| 黄色片免费在线观看| 在线免费观看日本一区| 玖草视频在线观看| 亚洲黄色影院| 91九色在线观看| aa在线视频| 777亚洲妇女| 中文字幕无码日韩专区免费| 麻豆精品久久精品色综合| 日本亚洲自拍| 偷拍精品精品一区二区三区| 亚洲精品一区二区在线| 天天操天天摸天天干| 不卡视频一二三| 国产精品www在线观看| 超碰97成人| 欧美激情一区二区三区高清视频| 亚洲精品无遮挡| 亚洲一区中文日韩| 中文字幕天堂网| 亚洲日本国产| 久久99欧美| 欧美18av| 一区二区三区黄色| 伊人色综合久久久| 亚洲欧美日韩在线不卡| 美女被艹视频网站| 亚洲视屏一区| 久久草.com| 桃色一区二区| 日韩一级黄色av| av中文字幕在线免费观看| 亚洲午夜久久久久久久久久久| 中文字幕永久免费| 亚洲乱码久久| 欧美一区二区三区在线播放| 日韩精品免费观看视频| 综合久久五月天| 99久久亚洲精品日本无码| 亚洲一区二区三区免费视频| 一级特级黄色片| 日韩黄色免费电影| 99热一区二区三区| 国偷自产av一区二区三区| 欧美一区二区.| 自拍视频在线| 日韩精品一区二区在线观看| 国产三级av片| 国产精品久久久久久福利一牛影视| 日本网站在线看| 日韩视频一区| 亚洲一区影院| 国内自拍欧美| 国产美女直播视频一区| 狂野欧美性猛交xxxxx视频| 精品一区二区三区四区在线| 在线不卡免费视频| 亚洲在线观看免费视频| 三级网站在线免费观看| 国产精品123区| 欧美成人免费高清视频| 91国语精品自产拍| 噜噜噜噜噜久久久久久91| 亚洲精品aa| 97久久精品人人澡人人爽缅北| av在线电影免费观看| 精品精品欲导航| 国产精品高清无码| 亚洲一区二区欧美日韩| 337人体粉嫩噜噜噜| 国产91精品一区二区| 日日噜噜夜夜狠狠| 国产欧美一级| 日本中文字幕一级片| 国产探花在线精品一区二区| 99精品99久久久久久宅男| 日本在线中文字幕一区二区三区| 欧美成年人网站| 成人精品一区二区三区免费 | 五十路六十路七十路熟婆| 久久99精品网久久| 四虎永久在线精品无码视频| 欧美精品一卡| 日本一区免费看| 成人自拍在线| 92看片淫黄大片欧美看国产片| 日韩影片中文字幕| 久久久久久亚洲精品| 快射视频在线观看| 在线观看国产精品日韩av| 亚洲欧美日韩免费| 亚洲精品一区在线观看| 国产深喉视频一区二区| 欧美人妖巨大在线| 国产免费a视频| 精品久久久视频| 久青草免费视频| 亚洲欧美日韩一区| 少妇被躁爽到高潮无码文| 国产精品国产三级国产aⅴ无密码 国产精品国产三级国产aⅴ原创 | 国产一区二区91| 天天综合网日韩| 日韩精品1区2区3区| 成人在线免费在线观看| 亚洲美女毛片| 免费拍拍拍网站| 国自产拍偷拍福利精品免费一 | 动漫一区在线| 日韩中文字幕欧美| 最新国产在线观看| 在线观看国产成人av片| 成全电影播放在线观看国语| 亚洲欧美日韩精品| 黄色软件在线观看| 亚洲香蕉成视频在线观看| 免费看男男www网站入口在线| 日韩精品一区二区三区第95| 日本亚洲一区| 亚洲欧洲成视频免费观看| 黄色软件在线| 最新国产成人av网站网址麻豆| 91官网在线| 久久精品精品电影网| 国产在线观看av| 久久91精品国产| www在线观看黄色| 18久久久久久| 日韩制服一区| 国产日产亚洲精品| 国产视频一区二区在线播放| 91九色蝌蚪成人| 久久精品66| 欧美一级爽aaaaa大片| 成人毛片免费看| 亚洲国产精品女人| 国产综合网站| 精品一区二区中文字幕| 日本v片在线高清不卡在线观看| 特级丰满少妇一级| 国产精品一区二区久久精品爱涩| 国产精品一区二区在线免费观看| 不卡视频一二三| 欧美丰满老妇熟乱xxxxyyy| 日韩美女精品在线| 黄色小视频在线免费看| 日本久久一区二区| 国产伦精品一区二区三区视频痴汉 | 久草青青在线观看| 蜜桃av一区二区在线观看| 亚洲视频在线不卡| 91在线视频网址| 男人天堂资源网| 亚洲一区在线电影| 欧美高清69hd| 欧美v日韩v国产v| 日本a一级在线免费播放| 中文字幕在线看视频国产欧美| 啦啦啦中文在线观看日本| 国产成人啪精品视频免费网| а天堂中文最新一区二区三区| 国产午夜精品一区| 欧美激情电影| 2022亚洲天堂| 国产一区二区三区久久悠悠色av| 老熟妇精品一区二区三区| 国产精品久久久久影院| 日韩久久久久久久久| 精品视频免费看| 三级在线电影| 色与欲影视天天看综合网| 久久亚洲精品国产亚洲老地址| 日本高清免费在线视频| 成人aaaa免费全部观看| 中文字幕伦理片| 亚洲一区电影777| 亚洲一区二区视频在线播放| 欧美精品一区二区三| 永久免费在线观看视频| 91精品国产电影| 精品国产亚洲一区二区三区| 欧美午夜精品理论片a级大开眼界| 亚洲精品网址| 精品久久久久久久无码| 99久久久国产精品免费蜜臀| 国产精品视频一区二区在线观看| 好吊成人免视频| 亚洲h视频在线观看| 精品国产一区久久久| 三级成人黄色影院| 国精产品一区二区| 欧美精品入口| 天天av天天操| 国产精品久久看| 成人公开免费视频| 亚洲精品二三区| 免费污视频在线观看| 亚洲最大福利网站| 久久久久午夜电影| 国产精品自拍视频在线| 国产亚洲精品超碰| 69视频免费在线观看| 日韩欧美亚洲国产精品字幕久久久| 狠狠色伊人亚洲综合网站l| 2019中文字幕在线免费观看| 国产精品18hdxxxⅹ在线| 久久综合亚洲精品| 国产一区二区不卡在线| 一区二区三区四区五区| 欧美日韩国产成人在线91| porn视频在线观看| 国产精品久久久久久久久久| 免费视频亚洲| 男人的天堂日韩| 国产情人综合久久777777| 免费黄色一级大片| 在线成人中文字幕| 黄色日韩网站| 91香蕉视频网址| 国内成+人亚洲+欧美+综合在线| 精品国产大片大片大片| 在线观看91av| 哥也色在线视频| 国产成人看片| 99在线热播精品免费99热| 偷拍女澡堂一区二区三区| 一本一本大道香蕉久在线精品 | 99精品视频网站| 激情五月播播久久久精品| 丝袜美腿小色网| 精品日韩一区二区三区| 都市激情国产精品| 欧美日韩高清在线一区| 日韩高清不卡一区| 小向美奈子av| 欧美电影免费观看完整版 | 国产精品免费看久久久香蕉| 日韩一区二区在线免费| 亚洲色图偷拍视频| 亚洲永久免费av| 天堂成人在线| 2018中文字幕一区二区三区| 九九热精品视频在线观看| 欧美精品aaaa| 亚洲色图欧美激情| 色一情一乱一乱一区91av| 国产成人av在线| 国产精品麻豆久久| 日本泡妞xxxx免费视频软件| 激情懂色av一区av二区av| 国产最新视频在线| 91嫩草在线视频| 亚洲国产精品第一区二区三区| 公侵犯人妻一区二区三区| 欧美日韩一二三区| 欧美日韩在线视频免费观看| 欧美精品亚洲精品| 国产原创一区二区三区| 国产成人在线播放视频| 中文字幕亚洲欧美在线| 9l视频自拍九色9l视频成人| 五月丁香综合缴情六月小说| 欧美国产成人在线| 国产 日韩 欧美 精品| 秋霞av国产精品一区| 亚洲国产精品91| 在哪里可以看毛片| 日韩精品在线网站| 国产成人精品一区二区三区免费| 日韩精品在线观看av| 国产精品丝袜久久久久久app| 免费观看a视频|