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

Spring?AI:如何采用Java編寫生成式人工智能應(yīng)用程序

譯文
人工智能
本文將介紹如何使用Spring AI框架采用Java編寫生成式人工智能應(yīng)用程序,并利用檢索增強(qiáng)生成(RAG)改進(jìn)答案。

譯者 | 李睿

審校 | 重樓

生成式人工智能(GenAI)是當(dāng)今科技界的一個熱門話題。它是人工智能的一個子集,專注于創(chuàng)造新的內(nèi)容,例如文本、圖像或音樂。GenAI組件的一種流行類型是大型語言模型(LLM),它可以根據(jù)提示生成類似人類的文本。檢索增強(qiáng)生成(RAG)是一種基于外部知識來源來提高生成式人工智能模型準(zhǔn)確性和可靠性的技術(shù)。雖然大多數(shù)GenAI應(yīng)用程序和相關(guān)內(nèi)容都以Python及其生態(tài)系統(tǒng)為中心,但如果采用Java編寫GenAI應(yīng)用程序應(yīng)該怎么辦?

本文將介紹如何使用Spring AI框架采用Java編寫GenAI應(yīng)用程序,并利用RAG改進(jìn)答案。

什么是Spring AI?

Spring AI是一個用于在Java中構(gòu)建GenAI應(yīng)用程序的框架。它提供了一組工具和實(shí)用程序,用于處理GenAI模型和架構(gòu),例如LLM和RAG。Spring AI構(gòu)建在Spring框架之上,Spring框架是一個用于構(gòu)建企業(yè)應(yīng)用程序的流行Java框架,允許那些已經(jīng)熟悉或參與Spring生態(tài)系統(tǒng)的用戶將GenAI策略合并到他們已經(jīng)存在的應(yīng)用程序和工作流中。

在Java中也有其他GenAI的選擇,例如Langchain4j,但是在這篇文章中將關(guān)注Spring AI。

創(chuàng)建項(xiàng)目

在開始使用Spring AI時,需要創(chuàng)建一個新項(xiàng)目或向現(xiàn)有項(xiàng)目添加適當(dāng)?shù)囊蕾図?xiàng)。可以使用Spring Initializr創(chuàng)建一個新項(xiàng)目,這是一個用于生成Spring Boot項(xiàng)目的基于Web的工具。

當(dāng)創(chuàng)建一個新項(xiàng)目時,需要添加以下依賴項(xiàng):

  • Spring Web
  • OpenAI或其他LLM模型(例如Mistral、Ollama等)
  • Neo4j Vector Database (其他矢量數(shù)據(jù)庫選項(xiàng)也可用)
  • Spring Data Neo4j

如果人工將這些依賴項(xiàng)添加到現(xiàn)有項(xiàng)目中,可以在相關(guān)的GitHub存儲庫中看到依賴項(xiàng)的詳細(xì)信息。

Spring Web依賴項(xiàng)允許開發(fā)人員為GenAI應(yīng)用程序創(chuàng)建REST API。需要OpenAI依賴來訪問OpenAI模型,這是一個流行的LLM。Neo4j Vector Database依賴項(xiàng)允許存儲和查詢用于相似性搜索的向量。最后,添加Spring Data Neo4j依賴項(xiàng)為在Spring應(yīng)用程序中使用Neo4j數(shù)據(jù)庫提供了支持,允許在Neo4j中運(yùn)行Cypher查詢并將實(shí)體映射到Java對象。

繼續(xù)生成項(xiàng)目,然后在喜歡的IDE中打開它。查看pom.xml文件,應(yīng)該會看到里程碑存儲庫已包含在內(nèi)。由于Spring AI還不是一個通用版本,需要包含里程碑存儲庫來獲得依賴項(xiàng)的預(yù)發(fā)布版本。

一個樣板文件

構(gòu)建Neo4j數(shù)據(jù)庫可以使用Neo4j Aura免費(fèi)層,因?yàn)樗芾砹藢?shí)例,當(dāng)然還有Docker鏡像和其他方法。

根據(jù)選擇的LLM模型,還需要API密鑰。對于OpenAI,可以通過在OpenAI注冊獲得API密鑰。

一旦有了Neo4j數(shù)據(jù)庫和API密鑰,就可以在應(yīng)用程序中設(shè)置application.properties文件。以下是一個可能的示例:

Properties files 
 spring.ai.openai.api-key=<YOUR API KEY HERE>
 spring.neo4j.uri=<NEO4J URI HERE>
 spring.neo4j.authentication.username=<NEO4J USERNAME HERE>
 spring.neo4j.authentication.password=<NEO4J PASSWORD HERE>
 spring.data.neo4j.database=<NEO4J DATABASE NAME HERE>

注意:將API密鑰和密碼等敏感信息保存在環(huán)境變量或應(yīng)用程序外部的其他位置是一個很好的想法。要創(chuàng)建環(huán)境變量,可以在終端中使用export命令或在IDE中設(shè)置它們。

可以為OpenAI客戶端和Neo4j矢量存儲設(shè)置Spring Beans,這將允許在應(yīng)用程序中需要的任何地方訪問必要的組件。

可以在SpringAiApplication類中添加以下代碼:

Java 
 @Bean
 public EmbeddingClient embeddingClient() {
 return new OpenAiEmbeddingClient(new OpenAiApi(System.getenv("SPRING_AI_OPENAI_API_KEY")));
 }

 @Bean
 public Neo4jVectorStore vectorStore(Driver driver, EmbeddingClient embeddingClient) {
 return new Neo4jVectorStore(driver, embeddingClient,
 Neo4jVectorStore.Neo4jVectorStoreConfig.builder()
 .withLabel("Review")
 .withIndexName("review-embedding-index")
 .build());
 }

EmbeddingClient bean為OpenAI API創(chuàng)建一個客戶端,并傳入API密鑰環(huán)境變量。最后,Neo4jVectorStore bean將Neo4j配置為嵌入(向量)的存儲。通過為存儲嵌入的節(jié)點(diǎn)指定標(biāo)簽來定制配置,因?yàn)镾pring的默認(rèn)設(shè)置是查找Document實(shí)體。還為嵌入指定索引名(默認(rèn)是spring-ai-document-index)。

數(shù)據(jù)集

對于這個例子,將使用來自Goodreads的書籍和評論數(shù)據(jù)集。可以從這里獲取數(shù)據(jù)集的精選版本。該數(shù)據(jù)集包含有關(guān)書籍的信息以及相關(guān)評論。

已經(jīng)使用OpenAI的API生成了嵌入,所以用戶如果想生成自己的嵌入,需要在腳本中注釋掉最后的Cypher語句,而不是運(yùn)行g(shù)enerate-embeddings.py腳本(或自定義版本)來生成和加載Neo4j的審查嵌入。

應(yīng)用程序模型

接下來,需要在應(yīng)用程序中創(chuàng)建一個域模型,以映射到數(shù)據(jù)庫模型。本例將創(chuàng)建一個表示圖書節(jié)點(diǎn)的Book實(shí)體。還將創(chuàng)建一個Review實(shí)體,它表示對某本書的評論。Review實(shí)體將有一個與之關(guān)聯(lián)的嵌入(向量),將使用它進(jìn)行相似性搜索。

這些實(shí)體是標(biāo)準(zhǔn)的Spring Data Neo4j代碼,所以不會在這里展示代碼。但是,每個類的完整代碼都可以在GitHub存儲庫中獲得(Book類、Review類)。

此外,還需要定義一個存儲庫接口,以便與數(shù)據(jù)庫進(jìn)行交互。雖然需要定義一個自定義查詢,但稍后將返回并添加它。

Java 
 public interface BookRepository extends Neo4jRepository<Book, String> {
 }

接下來,這個應(yīng)用程序的核心是控制器類。這個類將包含獲取用戶提供的搜索短語并調(diào)用Neo4jVectorStore來計(jì)算和返回最相似短語的邏輯。然后,可以將這些類似的評論傳遞到Neo4j查詢中,以檢索連接的實(shí)體,在LLM的提示中提供額外的場景。它將使用提供的所有信息,為原始搜索短語提供一些類似的書籍推薦。

控制器

首先,控制器類包含兩個常見的注解。還將注入之前定義的Neo4jVectorStore和BookRepository bean,以及用于嵌入客戶端的OpenAiChatClient。

下一步是為提示符定義一個字符串。這是將傳遞給LLM以生成響應(yīng)的文本,將使用用戶提供的搜索短語和在數(shù)據(jù)庫中找到的類似評論,在幾分鐘內(nèi)填充提示參數(shù)。接下來,定義控制器類的構(gòu)造函數(shù),它將注入必要的bean。

Java 
 @RestController
 @RequestMapping("/")
 public class BookController {
 private final OpenAiChatClient client;
 private final Neo4jVectorStore vectorStore;
 private final BookRepository repo;

 String prompt = """
 You are a book expert with high-quality book information in the CONTEXT section.
 Answer with every book title provided in the CONTEXT.
 Do not add extra information from any outside sources.
 If you are unsure about a book, list the book and add that you are unsure.

 CONTEXT:
 {context}

 PHRASE:
 {searchPhrase}
 """;

 public BookController(OpenAiChatClient client, Neo4jVectorStore vectorStore, BookRepository repo) {
 this.client = client;
 this.vectorStore = vectorStore;
 this.repo = repo;
 }

 //Retrieval Augmented Generation with Neo4j - vector search + retrieval query for related context
 @GetMapping("/rag")
 public String generateResponseWithContext(@RequestParam String searchPhrase) {
 List<Document> results = vectorStore.similaritySearch(SearchRequest.query(searchPhrase).withTopK(5).withSimilarityThreshold(0.8));
 //more code shortly!
 }
 }

最后,定義了一個方法,當(dāng)用戶向/rag端點(diǎn)發(fā)出GET請求時將調(diào)用該方法。該方法首先將搜索短語作為查詢參數(shù),并將其傳遞給向量存儲的similaritySearch()方法,以查找相似的評論。還通過限制前5個結(jié)果(. withtopk(5))并只提取最相似的結(jié)果(withSimilarityThreshold(0.8))向查詢添加了兩個自定義過濾器。

Spring AI的similaritySearch()方法的實(shí)際實(shí)現(xiàn)如下所示。

Java 
 @Override
 public List<Document> similaritySearch(SearchRequest request) {
 Assert.isTrue(request.getTopK() > 0, "The number of documents to returned must be greater than zero");
 Assert.isTrue(request.getSimilarityThreshold() >= 0 && request.getSimilarityThreshold() <= 1,
 "The similarity score is bounded between 0 and 1; least to most similar respectively.");

 var embedding = Values.value(toFloatArray(this.embeddingClient.embed(request.getQuery())));

 try (var session = this.driver.session(this.config.sessionConfig)) {
 StringBuilder condition = new StringBuilder("score >= $threshold");
 
 if (request.hasFilterExpression()) {
 condition.append(" AND ")
 .append(this.filterExpressionConverter.convertExpression(request.getFilterExpression()));
 }

 String query = """
 CALL db.index.vector.queryNodes($indexName, $numberOfNearestNeighbours, $embeddingValue)
 YIELD node, score
 WHERE %s
 RETURN node, score""".formatted(condition);
 
 return session
 .run(query,
 Map.of("indexName", this.config.indexName, "numberOfNearestNeighbours", request.getTopK(),
 "embeddingValue", embedding, "threshold", request.getSimilarityThreshold()))
 .list(Neo4jVectorStore::recordToDocument);
 }
 }

然后,將類似的Review節(jié)點(diǎn)映射回Document實(shí)體,因?yàn)镾pring AI需要通用的文檔類型。Neo4jVectorStore類包含將Document轉(zhuǎn)換為自定義記錄的方法,以及將記錄反向轉(zhuǎn)換為Document的方法。以下將顯示這些方法的實(shí)際實(shí)現(xiàn)。

Java 
 private Map<String, Object> documentToRecord(Document document) {
 var embedding = this.embeddingClient.embed(document);
 document.setEmbedding(embedding);

 var row = new HashMap<String, Object>();
 row.put("id", document.getId());

 var properties = new HashMap<String, Object>();
 properties.put("text", document.getContent());

 document.getMetadata().forEach((k, v) -> properties.put("metadata." + k, Values.value(v)));
 row.put("properties", properties);
 row.put(this.config.embeddingProperty, Values.value(toFloatArray(embedding)));

 return row;
 }

 private static Document recordToDocument(org.neo4j.driver.Record neoRecord) {
 var node = neoRecord.get("node").asNode();
 var score = neoRecord.get("score").asFloat();
 var metaData = new HashMap<String, Object>();

 metaData.put("distance", 1 - score);

 node.keys().forEach(key -> {
 if (key.startsWith("metadata.")) {
 metaData.put(key.substring(key.indexOf(".") + 1), node.get(key).asObject());
 }
 });

 return new Document(node.get("id").asString(), node.get("text").asString(), Map.copyOf(metaData));
 }

回到圖書推薦的控制器方法,現(xiàn)在對用戶搜索的短語有類似的評論。但是評論(以及附帶的文字)并不能真正幫助推薦書籍。所以現(xiàn)在需要在Neo4j中運(yùn)行一個查詢來檢索這些評論的相關(guān)書籍。這是應(yīng)用程序的檢索增強(qiáng)生成(RAG)部分。

可以在BookRepository接口中編寫查詢,以查找與這些評論相關(guān)的圖書。

Java 
 public interface BookRepository extends Neo4jRepository<Book, String> {
 @Query("MATCH (b:Book)<-[rel:WRITTEN_FOR]-(r:Review) " +
 "WHERE r.id IN $reviewIds " +
 "AND r.text <> 'RTC' " +
 "RETURN b, collect(rel), collect(r);")
 List<Book> findBooks(List<String> reviewIds);

}

在查詢中,從相似性搜索($ reviews wids)中傳入評論的ID,并為這些評論提取Review -> Book模式。還過濾掉任何帶有文本“RTC”的評論(這是沒有文本的評論的占位符)。然后返回Book節(jié)點(diǎn)、關(guān)系和Review節(jié)點(diǎn)。

現(xiàn)在需要在控制器中調(diào)用該方法,并將結(jié)果傳遞給提示模板。將把它傳遞給LLM,以根據(jù)用戶的搜索短語生成一個帶有圖書推薦列表的響應(yīng)。

Java 
 //Retrieval Augmented Generation with Neo4j - vector search + retrieval query for related context
 @GetMapping("/rag")
 public String generateResponseWithContext(@RequestParam String searchPhrase) {
 List<Document> results = vectorStore.similaritySearch(SearchRequest.query(searchPhrase).withTopK(5).withSimilarityThreshold(0.8));
 List<Book> bookList = repo.findBooks(results.stream().map(Document::getId).collect(Collectors.toList()));

 var template = new PromptTemplate(prompt, Map.of("context", bookList.stream().map(b -> b.toString()).collect(Collectors.joining("\n")), "searchPhrase", searchPhrase));
 System.out.println("----- PROMPT -----");
 System.out.println(template.render());

 return client.call(template.create().getContents());
 }

從相似性搜索之后開始,調(diào)用新的findBooks()方法,并傳入相似性搜索中的評論ID列表。檢索查詢返回一個名為bookList的圖書列表。接下來,使用提示字符串、圖中的場景數(shù)據(jù)和用戶的搜索短語創(chuàng)建提示模板,并將場景和searchPhrase提示參數(shù)分別映射到圖數(shù)據(jù)(每個項(xiàng)目位于新行上的列表)和用戶的搜索短語。還添加了System.out.println()來將提示打印到控制臺,以便可以看到傳遞給LLM的內(nèi)容。

最后,調(diào)用模板的create()方法從LLM生成響應(yīng)。返回的JSON對象有一個內(nèi)容鍵,其中包含響應(yīng)字符串,基于用戶搜索短語的圖書推薦列表。

以下測試一下!

運(yùn)行應(yīng)用程序

要運(yùn)行Goodreads AI應(yīng)用程序,可以在終端中使用./mvnw spring-boot:run命令。一旦應(yīng)用程序開始運(yùn)行,就可以使用搜索短語作為查詢參數(shù)向/rag端點(diǎn)發(fā)出GET請求。下面包括一些示例。

Shell 
 http ":8080/rag?searchPhrase=happy%20ending"
 http ":8080/rag?searchPhrase=encouragement"
 http ":8080/rag?searchPhrase=high%tech"

示例調(diào)用和輸出+完整提示符

電話和退貨書推薦:

Shell 
 jenniferreif@elf-lord springai-goodreads % http ":8080/rag?searchPhrase=encouragement"

 The Cross and the Switchblade
 The Art of Recklessness: Poetry as Assertive Force and Contradiction
 I am unsure about 90 Minutes in Heaven: A True Story of Death and Life
 The Greatest Gift: The Original Story That Inspired the Christmas Classic It's a Wonderful Life
 I am unsure about Aligned: Volume 1 (Aligned, #1)

應(yīng)用程序日志輸出:

Shell 
 ----- PROMPT -----
 You are a book expert with high-quality book information in the CONTEXT section.
 Answer with every book title provided in the CONTEXT.
 Do not add extra information from any outside sources.
 If you are unsure about a book, list the book and add that you are unsure.

 CONTEXT:
 Book[book_id=772852, title=The Cross and the Switchblade, isbn=0515090255, isbn13=9780515090253, reviewList=[Review[id=f70c68721a0654462bcc6cd68e3259bd, text=encouraging, rating=4]]]
 Book[book_id=89375, title=90 Minutes in Heaven: A True Story of Death and Life, isbn=0800759494, isbn13=9780800759490, reviewList=[Review[id=85ef80e09c64ebd013aeebdb7292eda9, text=inspiring & hope filled, rating=5]]]
 Book[book_id=1488663, title=The Greatest Gift: The Original Story That Inspired the Christmas Classic It's a Wonderful Life, isbn=0670862045, isbn13=9780670862047, reviewList=[Review[id=b74851666f2ec1841ca5876d977da872, text=Inspiring, rating=4]]]
 Book[book_id=7517330, title=The Art of Recklessness: Poetry as Assertive Force and Contradiction, isbn=1555975623, isbn13=9781555975623, reviewList=[Review[id=2df3600d488e182a3ef06bff7fc82eb8, text=Great insight, great encouragement, and great company., rating=4]]]
 Book[book_id=27802572, title=Aligned: Volume 1 (Aligned, #1), isbn=1519114796, isbn13=9781519114792, reviewList=[Review[id=60b9aa083733e751ddd471fa1a77535b, text=healing, rating=3]]]

 PHRASE:
 encouragement

可以看到,LLM生成了一個響應(yīng),其中包含基于數(shù)據(jù)庫中找到的圖書推薦列表(提示的CONTEXT部分)。用戶搜索短語的相似度搜索+圖形檢索查詢的結(jié)果在提示符中,LLM的回答使用該數(shù)據(jù)作為響應(yīng)。

結(jié)語

本文學(xué)習(xí)了如何在Java中使用Spring AI構(gòu)建GenAI應(yīng)用程序。使用OpenAI模型根據(jù)用戶的搜索短語生成圖書推薦。以及使用Neo4j Vector Database來存儲和查詢用于相似性搜索的向量。還將域模型映射到數(shù)據(jù)庫模型,編寫與數(shù)據(jù)庫交互的存儲庫接口,并創(chuàng)建控制器類來處理用戶請求和生成響應(yīng)。

希望這篇文章能幫助人們使用Spring AI。

資源

文檔:Spring AI

網(wǎng)頁:Spring AI project

API:Spring AI - Neo4jVectorStore

原文標(biāo)題:Spring AI: How To Write GenAI Applications With Java,作者:Jennifer Reif


責(zé)任編輯:華軒 來源: 51CTO
相關(guān)推薦

2024-05-10 09:38:01

人工智能

2025-04-09 08:14:03

2024-04-28 08:18:28

SpringAIGen AI

2023-12-05 14:31:17

人工智能

2024-10-08 14:27:16

2023-06-30 10:42:00

2024-04-18 16:12:10

2024-03-05 08:00:00

人工智能Kuberneste

2025-06-27 03:00:00

2023-04-18 10:47:32

2023-12-25 22:27:38

2023-03-23 16:55:32

人工智能Adobe

2023-11-07 10:20:22

人工智能AI

2023-08-02 18:26:31

2023-05-05 14:02:59

人工智能聊天機(jī)器人

2024-06-12 11:03:47

2024-03-01 10:00:09

2023-08-08 18:08:17

2023-09-15 10:01:04

2021-02-20 09:57:02

人工智能移動應(yīng)用
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號

九九在线视频| 男人添女人下面高潮视频| 99久久人妻无码中文字幕系列| 青春草在线免费视频| 韩国成人精品a∨在线观看| 色综合老司机第九色激情| 波多野结衣一二三区| 国产一线二线三线女| 99国产揄拍国产精品| 一区二区动漫| 日韩三级成人av网| 欧美一区二区免费在线观看| 国产精品亲子伦av一区二区三区| 亚洲精品成人少妇| 欧美精品欧美精品| 国产黄色av片| 日本午夜精品一区二区三区电影| 欧美激情在线观看视频| 成人小视频免费看| 欧美成人专区| 日韩欧美国产电影| 欧美亚洲动漫精品| 亚洲精品日韩在线观看| 日韩一区二区三区不卡| 美女脱光内衣内裤视频久久网站| 国产做受69高潮| 免费成人美女女在线观看| 日韩大胆成人| 欧美电视剧在线看免费| 超碰人人草人人| 校园春色亚洲色图| 懂色av一区二区三区| 国产激情在线看| 伊人在线视频| 国产喂奶挤奶一区二区三区| 国产精品一区二| 国产不卡av在线播放| 麻豆免费看一区二区三区| 51精品国产黑色丝袜高跟鞋| 精品一区在线视频| 亚洲综合小说| 日韩一区二区精品视频| 国产毛片久久久久久久| 欧美人妖在线观看| 欧美成人aa大片| 在线播放免费视频| 亚洲欧美一级| 欧美日韩亚洲综合在线| 色悠悠久久综合网| aaaa欧美| 欧美人动与zoxxxx乱| 天堂av在线网站| 精品自拍视频| 欧美日韩亚洲国产综合| 亚洲综合日韩欧美| 久久视频一区二区三区| 77成人影视| 日韩一区二区三区电影| 中文字幕在线视频一区二区| 国产精品久久久久久久久久久久久久久| 欧美午夜精品电影| jizz大全欧美jizzcom| yiren22亚洲综合| 欧美日韩国产综合久久| 久久久久久久久久一区| 99精品美女视频在线观看热舞| 欧美日韩激情一区二区| 五月天视频在线观看| 国产95亚洲| 精品乱人伦小说| 日韩精品人妻中文字幕有码 | 一本久道中文无码字幕av| 中文字幕在线直播| 欧美视频在线不卡| 手机在线观看日韩av| 91成人午夜| 精品性高朝久久久久久久| 性猛交娇小69hd| 天天做综合网| 欧美大片第1页| 国产污污视频在线观看| 日韩在线一区二区三区| 成人午夜一级二级三级| 日本xxxxxwwwww| 国产亚洲综合av| 乱子伦一区二区| caoporn视频在线观看| 色综合久久88色综合天天免费| 日本www.色| 美女日韩一区| 亚洲人在线视频| 久久久久亚洲av片无码| 日韩视频一区| 国产欧美精品在线播放| 韩国av电影在线观看| 国产亚洲欧洲一区高清在线观看| 无码人妻aⅴ一区二区三区日本| 97人澡人人添人人爽欧美| 欧洲视频一区二区| 亚洲欧美日韩色| 日韩av专区| 午夜精品福利电影| 中文字幕av免费观看| 国产成人精品午夜视频免费| 日韩高清在线播放| 黑人精品视频| 欧美久久久久久久久| 国产麻豆天美果冻无码视频| 天天射综合网视频| 日韩美女在线观看一区| 亚洲xxxx天美| 国产精品九色蝌蚪自拍| 欧美一级在线看| 警花av一区二区三区| 精品亚洲精品福利线在观看| 免费网站看av| 国内精品国产三级国产a久久| 久久综合九色欧美狠狠| 亚洲奶水xxxx哺乳期| 欧美色爱综合网| 久久亚洲AV成人无码国产野外| 欧美久久一区| 国产中文欧美精品| 国产1区2区3区在线| 精品国产91久久久久久老师| 中文字幕无码毛片免费看| sdde在线播放一区二区| 日韩av片电影专区| 日韩大片b站免费观看直播| 亚洲综合av网| 国产大片一区二区三区| 欧美电影《睫毛膏》| 国产成人亚洲综合91精品| 无码精品人妻一区二区| 99天天综合性| 欧洲中文字幕精品| 中国xxxx性xxxx产国| 亚洲h色精品| 国产欧亚日韩视频| 国产高清视频在线播放| 日韩欧美在线视频日韩欧美在线视频 | 色综合久久久久久| 亚洲一级二级在线| 麻豆免费在线观看视频| 欧美91福利在线观看| 91夜夜未满十八勿入爽爽影院| 日韩精品成人av| 9191久久久久久久久久久| 精品无码一区二区三区蜜臀| 精品在线播放免费| 潘金莲一级淫片aaaaa免费看| 日本中文字幕视频一区| 精品国产一区二区三区久久狼黑人| 久久久久久av无码免费看大片| 亚洲成人黄色| 久久久久久18| 少妇人妻偷人精品一区二区 | 中文字幕亚洲欧美在线| 国产精品午夜一区二区| 国产精品久久久久久久午夜片| 牛夜精品久久久久久久| 久久久久久影院| 99久久一区三区四区免费| 日本伦理一区二区| 亚洲国产天堂久久综合网| 久久一区二区三区视频| 久久久久久久久99精品| 乌克兰美女av| 欧美精品网站| 久久亚洲免费| 国产成人a视频高清在线观看| 久久网福利资源网站| 精品国产伦一区二区三区| 亚洲成人中文在线| 亚洲乱码国产乱码精品精大量 | 激情久久综合网| 国精品一区二区三区| 久久久综合亚洲91久久98| 精品裸体bbb| 欧美精品情趣视频| 婷婷视频在线观看| 欧美日免费三级在线| 特级片在线观看| 91麻豆国产福利精品| 一本色道久久亚洲综合精品蜜桃 | 在线观看的毛片| 欧美1区2区| 欧美18视频| 久久一级大片| 国产成人91久久精品| 快射av在线播放一区| 日韩极品精品视频免费观看| 一级全黄裸体免费视频| 无吗不卡中文字幕| 日韩精品电影一区二区三区| 国产iv一区二区三区| 91视频免费版污| 韩日视频一区| 国产欧美日韩伦理| 久久久精品人妻一区二区三区四| 本田岬高潮一区二区三区| 亚洲视频在线a| 欧美搞黄网站| 日韩福利一区二区三区| 波多野结衣欧美| 国产精品福利久久久| 韩国中文字幕在线| 精品五月天久久| 精品国产va久久久久久久| 一本到一区二区三区| 欧美成人精品一区二区免费看片 | 色哟哟精品一区| 欧美三级免费看| 亚洲国产精品激情在线观看 | 亚洲国产精品黑人久久久| 精品人妻一区二区免费| 欧美a级理论片| www国产黄色| 怡红院精品视频在线观看极品| 亚洲韩国在线| 偷拍自拍亚洲色图| 国产精华一区| 久久99精品久久久野外观看| 国产精品观看在线亚洲人成网 | 国产成人一区二区三区| 丰满大乳少妇在线观看网站| www.欧美三级电影.com| 波多野结衣在线影院| 日韩精品久久久久| 后进极品白嫩翘臀在线视频| 欧美一区二区三区成人| 97超碰人人草| 欧美在线不卡一区| www.com亚洲| 欧美日韩在线免费观看| 日本三级片在线观看| 亚洲一区精品在线| 欧美日韩精品一区二区三区视频播放| 国产精品久线在线观看| 大吊一区二区三区| 中日韩免费视频中文字幕| 亚洲第一成人网站| 久久久久国产成人精品亚洲午夜| 亚洲激情视频网| 免费又黄又爽又猛大片午夜| 欧美日韩一区二区免费视频| 91探花福利精品国产自产在线| 日批视频在线播放| 精品国产亚洲在线| 国内爆初菊对白视频| 精品福利视频一区二区三区| 丰满熟女一区二区三区| 亚洲高清福利视频| 天堂在线视频网站| 精品一区二区三区三区| 精品99又大又爽又硬少妇毛片| 亚洲欧美精品一区| yourporn在线观看中文站| 中文字幕欧美日韩| 免费在线观看黄| 欧美精品一区在线播放| 黄色在线观看视频网站| 91大神在线播放精品| 国产 日韩 欧美一区| 国产男女猛烈无遮挡91| www久久久| 国产日韩欧美亚洲一区| 久久av超碰| 美国av在线播放| 在线欧美一区| 亚洲成人福利在线观看| 国产精品综合在线视频| 一区二区视频观看| 中文字幕精品一区二区精品绿巨人| 情侣偷拍对白清晰饥渴难耐| 亚洲综合视频在线| www.国产com| 欧美美女黄视频| 欧美 中文字幕| 亚洲欧美国产日韩天堂区| 9色在线观看| 欧美激情在线有限公司| 无人区在线高清完整免费版 一区二| 国产精品视频免费在线观看| 亚洲专区**| 秋霞久久久久久一区二区| 香蕉av一区二区| 黄色动漫网站入口| 国模大尺度一区二区三区| 强迫凌虐淫辱の牝奴在线观看| 中文字幕成人网| 国产精品111| 欧美日韩国产天堂| 天堂а√在线8种子蜜桃视频| 色老头一区二区三区| 国产剧情av在线播放| 国产日韩亚洲欧美| 色先锋久久影院av| 成人在线观看毛片| 青青青爽久久午夜综合久久午夜| 极品白嫩少妇无套内谢| 国产精品久久久久精k8| 特级西西444www大精品视频免费看| 欧美浪妇xxxx高跟鞋交| 你懂的好爽在线观看| 久久久久久久一| 99re8精品视频在线观看| 欧美午夜精品久久久久久蜜| 国产一区亚洲| 91精品视频国产| 国产日韩欧美制服另类| 欧美福利视频一区二区| 欧美va天堂va视频va在线| 日韩成人影视| 国产精品久久中文| 免费日韩一区二区三区| 美女av免费观看| 久草在线在线精品观看| 永久免费av无码网站性色av| 精品久久久久久久久久ntr影视| av小说天堂网| 中文字幕日本欧美| 天堂久久午夜av| 欧美日韩精品久久| 亚洲一区中文| japanese在线观看| 亚洲综合激情小说| 国产suv一区二区| 不卡av在线播放| 91视频成人| 国产成年人在线观看| 日日欢夜夜爽一区| 一色道久久88加勒比一| 色天使色偷偷av一区二区| 日韩a在线观看| 欧美有码在线视频| 青青草原在线亚洲| 99精品人妻少妇一区二区| 成人夜色视频网站在线观看| 国产精品久久久久久久精| 91精品免费观看| 69xxx在线| 97久久天天综合色天天综合色hd| 91麻豆精品国产91久久久平台| 亚洲老女人av| 亚洲三级在线看| 国产婷婷在线视频| 久久6精品影院| 麻豆成人入口| 国产福利视频在线播放| 久久精品亚洲一区二区三区浴池| 4438国产精品一区二区| 亚洲一区二区久久| www.26天天久久天堂| 亚洲国产精品影视| 国产成人在线看| 国产无遮挡aaa片爽爽| 亚洲国产精品人久久电影| 黄色综合网址| 一区二区三区我不卡| 国产一区二区在线看| 精品无码人妻一区二区三| 亚洲二区在线播放视频| 韩日精品一区二区| 亚洲电影免费| 国产精品77777| 久久久久久久久久久久久久av| 亚洲欧美在线第一页| 国产精品黄色片| 国产性生活免费视频| 26uuu国产在线精品一区二区| 波多野结衣一二区| 久热爱精品视频线路一| 精品伊人久久久| 国产成人黄色网址| 一区二区三区四区中文字幕| 性xxxx搡xxxxx搡欧美| 国产精品美女久久久久久免费| 先锋资源久久| 久久亚洲AV成人无码国产野外| 欧美日韩另类一区| 污影院在线观看| 欧美美乳视频网站在线观看| 国内成人精品2018免费看| www成人在线| 日韩在线观看免费| 老司机凹凸av亚洲导航| 亚洲精品高清无码视频| 亚洲精品一卡二卡| 久久精品国产亚洲a∨麻豆| 亚洲伊人久久综合| 羞羞答答国产精品www一本| 人人澡人人澡人人看| 亚洲国产毛片完整版| 亚洲精品大片| 青青草原av在线播放| 亚洲乱码国产乱码精品精的特点| 午夜av免费在线观看| 91香蕉亚洲精品| 久久三级福利|