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

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

發(fā)布于 2024-7-8 20:58
瀏覽
0收藏

譯者 | 李睿

審校 | 重樓

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

Spring?AI:如何采用Java編寫生成式人工智能應(yīng)用程序-AI.x社區(qū)

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

什么是Spring AI?

Spring AI是一個用于在Java中構(gòu)建GenAI應(yīng)用程序的框架。它提供了一組工具和實用程序,用于處理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)建項目

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

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

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

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

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

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

一個樣板文件

構(gòu)建Neo4j數(shù)據(jù)庫可以使用Neo4j Aura免費層,因為它管理了實例,當(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é)點指定標簽來定制配置,因為Spring的默認設(shè)置是查找Document實體。還為嵌入指定索引名(默認是spring-ai-document-index)。

數(shù)據(jù)集

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

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

應(yīng)用程序模型

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

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

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

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

接下來,這個應(yīng)用程序的核心是控制器類。這個類將包含獲取用戶提供的搜索短語并調(diào)用Neo4jVectorStore來計算和返回最相似短語的邏輯。然后,可以將這些類似的評論傳遞到Neo4j查詢中,以檢索連接的實體,在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端點發(fā)出GET請求時將調(diào)用該方法。該方法首先將搜索短語作為查詢參數(shù),并將其傳遞給向量存儲的similaritySearch()方法,以查找相似的評論。還通過限制前5個結(jié)果(. withtopk(5))并只提取最相似的結(jié)果(withSimilarityThreshold(0.8))向查詢添加了兩個自定義過濾器。

Spring AI的similaritySearch()方法的實際實現(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é)點映射回Document實體,因為Spring AI需要通用的文檔類型。Neo4jVectorStore類包含將Document轉(zhuǎn)換為自定義記錄的方法,以及將記錄反向轉(zhuǎn)換為Document的方法。以下將顯示這些方法的實際實現(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中運行一個查詢來檢索這些評論的相關(guān)書籍。這是應(yī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é)點、關(guān)系和Review節(jié)點。

現(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ù)(每個項目位于新行上的列表)和用戶的搜索短語。還添加了System.out.println()來將提示打印到控制臺,以便可以看到傳遞給LLM的內(nèi)容。

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

以下測試一下!

運行應(yīng)用程序

要運行Goodreads AI應(yīng)用程序,可以在終端中使用./mvnw spring-boot:run命令。一旦應(yīng)用程序開始運行,就可以使用搜索短語作為查詢參數(shù)向/rag端點發(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

原文標題:Spring AI: How To Write GenAI Applications With Java,作者:Jennifer Reif

鏈接:https://dzone.com/articles/spring-ai-how-to-write-genai-applications-with-jav


?著作權(quán)歸作者所有,如需轉(zhuǎn)載,請注明出處,否則將追究法律責(zé)任
收藏
回復(fù)
舉報
回復(fù)
相關(guān)推薦
精品无人国产偷自产在线| 精品久久中文字幕久久av| 成人www视频在线观看| 久久一级黄色片| 亚洲综合图色| 欧美丰满一区二区免费视频| 日韩国产一级片| 国产h视频在线观看| 国产一区二区三区四区五区入口| 久久久久久久久久国产精品| av电影在线不卡| 视频一区中文字幕精品| 色偷偷成人一区二区三区91 | 日韩av色在线| 中文字幕五月天| 国产成人av| 日韩欧美精品在线视频| 乱子伦视频在线看| 在线heyzo| 国产日韩亚洲欧美综合| 成人综合电影| 国产又黄又粗又猛又爽| 免费日韩精品中文字幕视频在线| 麻豆成人在线看| 强伦人妻一区二区三区| 日韩精品一区国产| 欧美日韩国产小视频在线观看| 野外做受又硬又粗又大视频√| av电影在线观看一区二区三区| 成人h动漫精品一区二区| 成人激情视频网| 波多野结衣电车| 一区二区三区福利| 欧美日韩高清区| 男人在线观看视频| 红桃视频在线观看一区二区| 亚洲国产精品大全| 免费在线观看日韩av| 欧美在线一级| 欧美午夜电影一区| 免费日韩视频在线观看| 99re6在线精品视频免费播放| 中文字幕日韩欧美一区二区三区| 日本在线高清视频一区| 香蕉视频网站在线| 不卡一区中文字幕| 成人av免费在线看| 99草在线视频| 另类小说欧美激情| 国产激情久久久| 伊人中文字幕在线观看| 国产精品毛片在线看| 高清欧美电影在线| 精品少妇久久久| 国产一区二区三区四区三区四 | 快播亚洲色图| 神宫寺奈绪一区二区三区| 国产精品88av| 国产精品av一区| 老熟妇高潮一区二区高清视频| 国产成人综合亚洲91猫咪| 亚洲精品日韩av| 国内精品久久久久久久久久久 | 欧美日韩一区二区三区在线看| 欧美黄色一级片视频| 625成人欧美午夜电影| 欧美日韩综合视频| 麻豆传传媒久久久爱| 影视一区二区三区| 欧美三区在线观看| 91精品999| 亚洲一区二区三区四区电影| 精品国产凹凸成av人导航| 91人妻一区二区| 天天久久夜夜| 亚洲欧美激情精品一区二区| xxxx日本黄色| 手机在线电影一区| 九九九热精品免费视频观看网站| 国产在线视频在线观看| 国产精品婷婷| 国产精品视频自在线| 国产精选久久久| 成人精品视频一区二区三区尤物| 久久成人资源| 国产精品ⅴa有声小说| 中文字幕一区日韩精品欧美| 18视频在线观看娇喘| 国产精品69xx| 91成人免费在线视频| 午夜大片在线观看| 欧美激情影院| 日韩在线激情视频| 久久久久久国产精品免费播放| 在线视频精品| 91精品久久久久久久久久久久久| 亚洲成人中文字幕在线| 91蝌蚪porny| 最新精品视频| 成人短视频app| 欧美一区二区免费| 最新中文字幕视频| 小处雏高清一区二区三区| 97久久久久久| 国产精品毛片久久久久久久av| 99精品国产视频| 亚洲人成人77777线观看| sis001亚洲原创区| 欧洲另类一二三四区| 成人啪啪18免费游戏链接| 国产精品中文字幕亚洲欧美| 欧美日韩成人精品| 亚洲一级视频在线观看| 91偷拍与自偷拍精品| 亚洲五码在线观看视频| 欧美福利在线播放| 亚洲激情第一页| 久久人妻无码aⅴ毛片a片app | 国产成一区二区| 亚洲va天堂va欧美ⅴa在线| 久久久国产综合精品女国产盗摄| 丰满人妻一区二区三区53号| 国产经典一区| 国产婷婷色综合av蜜臀av| 免费一级肉体全黄毛片| 麻豆精品国产91久久久久久| 蜜桃av噜噜一区二区三| 7777kkk亚洲综合欧美网站| 这里只有精品99re| 中文字幕第二区| 久久久久在线| 久久精品国产一区二区三区日韩| 视频在线这里都是精品| 欧美日韩国产经典色站一区二区三区| 制服丝袜第二页| 亚洲每日更新| 国产伦精品一区二区三区免费视频 | 亚洲小说欧美另类激情| 精品176极品一区| 一本一本久久a久久精品牛牛影视| 日本a在线观看| 成人午夜av在线| 亚洲国产一二三精品无码| 久久亚洲精品人成综合网| 亚洲香蕉成人av网站在线观看| 精品欧美一区二区三区免费观看| 成人性生交大片免费看中文| 国产av第一区| 榴莲视频成人app| 久久国产色av| 午夜免费福利视频| 一区二区三区四区在线播放 | 91丨九色丨蝌蚪丨老版| 大伊香蕉精品视频在线| 91精品啪在线观看国产爱臀| 欧美黑人xxx| 亚洲精品国产手机| 亚洲午夜精品在线| a天堂视频在线观看| 99国产精品久久久久久久| 国内精品久久久久久久果冻传媒| av日韩中文| 亚洲精品一区中文字幕乱码| 亚洲视频 欧美视频| 国产欧美一区二区三区鸳鸯浴| 色婷婷综合久久久久中文字幕| 少妇精品久久久| 国产精品入口福利| 国产精品扒开做爽爽爽的视频| 91精品国产高清一区二区三区蜜臀| 国产三级国产精品国产国在线观看| 国产福利91精品一区| 久久精品国产sm调教网站演员| 亚欧日韩另类中文欧美| 国产精品久久av| 久久精品视频观看| 欧美大胆人体bbbb| 亚洲精品男人的天堂| 国产日韩三级在线| 日本高清免费在线视频| 亚洲国产免费看| 欧洲精品久久| 国产亚洲亚洲国产一二区| 欧美激情欧美激情在线五月| 神马亚洲视频| 欧美日本乱大交xxxxx| 青青草偷拍视频| 91亚洲资源网| 国产成人美女视频| 精品99视频| 亚洲a∨一区二区三区| 日韩一区二区三区精品| 91高清视频在线免费观看| av福利在线播放| 精品国产乱码久久久久久久久| 国产精品久免费的黄网站| **性色生活片久久毛片| 色综合久久五月| 蜜臀91精品一区二区三区 | 日韩视频国产视频| 亚洲婷婷综合网| 一区二区三区四区在线| 精品人妻一区二区三区四区| 国产精品996| 少妇网站在线观看| 亚洲精品在线二区| 国产系列第一页| 国产麻豆一区二区三区精品视频| 亚洲xxxx3d| 国产精品麻豆成人av电影艾秋| 97精品久久久| 九七久久人人| 在线成人一区二区| 天天操天天干天天| 欧美一区二区大片| 最新在线中文字幕| 欧美日韩免费网站| 久热精品在线观看| 一区二区中文视频| 性欧美13一14内谢| 99久久国产综合精品麻豆| 一本之道在线视频| 另类中文字幕网| 日韩一级免费在线观看| 亚洲国产一区二区三区高清| 日本免费黄色小视频| 国产精品精品| 亚洲va久久久噜噜噜久久狠狠 | 国产伦精品一区二区三区在线观看| 成人一级片网站| 亚洲人人精品| 国产精品久久久久9999爆乳| 自产国语精品视频| 中文精品一区二区三区| 成人a'v在线播放| 欧美一区少妇| 精品久久久久久久久久久aⅴ| 欧美成人蜜桃| 综合亚洲自拍| 蜜桃网站成人| 亚洲第一二三区| 久久一区二区精品| 西瓜成人精品人成网站| 久99久在线| 自拍自偷一区二区三区| 欧美日韩国产精品一区二区| 伊人久久大香线蕉av不卡| 久久精品美女| 国产成人精品999在线观看| 欧美少妇一区| 欧美一区二区三区激情视频| 日韩免费电影一区二区| 成人在线免费观看网站| 先锋在线资源一区二区三区| 欧美电影《睫毛膏》| 亚洲一区二区三区加勒比| 91麻豆国产自产在线观看亚洲| 亚洲成人动漫在线| 亚洲情侣在线| 国产成人生活片| 亚洲五月婷婷| 久久精品免费一区二区| 久久黄色网页| gai在线观看免费高清| 国产一区二区按摩在线观看| 最新中文字幕日本| 97久久精品人人爽人人爽蜜臀| 成人免费av片| 国产精品情趣视频| avove在线播放| 亚洲国产日韩一区二区| 国产三级av片| 欧美日韩精品欧美日韩精品| av观看在线免费| 亚洲第一视频网站| 福利在线观看| 欧美精品在线免费观看| 一本大道色婷婷在线| 国产精品亚洲网站| 国产精品22p| 欧洲精品码一区二区三区免费看| 97色伦图片97综合影院| 青青草国产免费| 日韩精品每日更新| 欧美日韩理论片| 99re热这里只有精品视频| 欧美精品日韩在线| 亚洲国产精品影院| 亚洲男人天堂网址| 日韩欧美一级二级三级久久久| 爽爽视频在线观看| 久久久www成人免费精品| 秋霞伦理一区| 91久久精品国产91性色| 亚洲欧美tv| 91精品国产吴梦梦| 日日骚欧美日韩| 亚洲色图欧美另类| 国产精品美女www爽爽爽| 日韩免费黄色片| 51精品秘密在线观看| 日本黄在线观看| 欧美第一黄网免费网站| 精品国产欧美日韩一区二区三区| 97在线资源站| 久久在线视频免费观看| 男人靠女人免费视频网站 | 三级黄色片网站| 亚洲欧美日韩中文字幕一区二区三区 | 波多野结衣在线影院| 欧美激情a在线| 在线观看亚洲精品福利片| 麻豆传媒一区二区| 欧美精品99| 91福利免费观看| 国产三级久久久| 特级做a爱片免费69| 精品少妇一区二区三区在线视频| av在线资源站| 日本一区二区三区四区视频| 国产精品xxxav免费视频| 日本精品免费视频| 蜜桃av一区二区三区电影| 右手影院亚洲欧美| 亚洲一二三专区| 国产手机精品视频| 日韩在线播放一区| 色香欲www7777综合网| 免费在线观看一区二区| 激情亚洲网站| 色诱av手机版| 亚洲精品免费视频| 国产免费黄色片| 色av中文字幕一区| 成人国产精品| 先锋影音欧美| 久久精品免费观看| 国产1区2区在线观看| 欧美性感一类影片在线播放| 国产一级在线| 国产精品h在线观看| 国内精品视频在线观看| 国产视频在线视频| 国产视频一区二区在线观看| 日韩综合在线观看| 亚洲色图狂野欧美| 韩国三级一区| 亚洲精品日韩成人| 久久99精品国产麻豆婷婷| 欧美xxxooo| 欧美一级国产精品| 久久亚洲资源| 国产在线精品一区| 国产日本精品| 男女做爰猛烈刺激| 欧美视频一区二| 免费在线看黄色| 97se在线视频| 99精品视频免费全部在线| 人妻无码中文久久久久专区| 精品色蜜蜜精品视频在线观看| 日韩三级电影网| 国产精品久久一| 91精品福利| 国产精品麻豆入口| 色综合久久天天| 日本网站在线免费观看视频| 91视频免费网站| 亚洲三级观看| 免费看裸体网站| 欧美一区二区三区在线视频| 日本乱理伦在线| 欧美精品一区二区三区在线四季 | 99精品视频免费观看视频| 大又大又粗又硬又爽少妇毛片| 在线视频欧美精品| 91三级在线| 久久国产精品-国产精品| 日本va欧美va瓶| 国产亚洲第一页| 亚洲欧美视频在线| 亚洲精品三区| 黄色网页免费在线观看| 国产精品丝袜91| 亚洲美女综合网| 国产精品久久久久久久久免费看| 女人色偷偷aa久久天堂| 中文字幕乱码一区| 欧美日韩视频在线一区二区| 福利写真视频网站在线| 欧美日韩成人一区二区三区| 老司机精品视频在线| 国产一级免费av| 中文字幕在线精品| 久久亚洲黄色| 亚洲欧美日本一区二区| 精品久久久久久久久久久久久久| 69久久精品| 久久久久久久久久码影片| 捆绑紧缚一区二区三区视频|