{"id":477233,"date":"2026-04-24T09:15:51","date_gmt":"2026-04-24T09:15:51","guid":{"rendered":"https:\/\/savepearlharbor.com\/?p=477233"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=477233","title":{"rendered":"\u0420\u0430\u0437\u0432\u043e\u0440\u0430\u0447\u0438\u0432\u0430\u0435\u043c RAG \u043d\u0430 Java \u0431\u0435\u0437 \u0431\u043e\u043b\u0438: \u043f\u0440\u0430\u043a\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u0439 \u0433\u0430\u0439\u0434"},"content":{"rendered":"<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<p>\u0412\u0441\u0435\u043c \u043f\u0440\u0438\u0432\u0435\u0442! \u041d\u0435\u0434\u0430\u0432\u043d\u043e \u0441\u0442\u043e\u043b\u043a\u043d\u0443\u043b\u0441\u044f \u0441 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u043e\u0439, \u0447\u0442\u043e \u0432\u00a0\u043d\u0430\u0441\u0442\u043e\u044f\u0449\u0435\u0435 \u0432\u0440\u0435\u043c\u044f \u0431\u043e\u043b\u044c\u0448\u0430\u044f \u0447\u0430\u0441\u0442\u044c \u043e\u0431\u0443\u0447\u0430\u044e\u0449\u0438\u0445 \u043c\u0430\u0442\u0435\u0440\u0438\u0430\u043b\u043e\u0432 \u043f\u043e\u00a0<strong>Retrieval\u2011Augmented Generation (RAG)<\/strong> \u0441\u043e\u0441\u0440\u0435\u0434\u043e\u0442\u043e\u0447\u0435\u043d\u0430 \u043d\u0430\u00a0<strong>Python\u2011\u044d\u043a\u043e\u0441\u0438\u0441\u0442\u0435\u043c\u0435<\/strong> (LangChain, LlamaIndex \u0438 \u0442\u043e\u043c\u0443 \u043f\u043e\u0434\u043e\u0431\u043d\u043e\u0435), \u0430\u00a0\u043f\u043e\u0448\u0430\u0433\u043e\u0432\u044b\u0435 \u0440\u0443\u043a\u043e\u0432\u043e\u0434\u0441\u0442\u0432\u0430, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043f\u043e\u043a\u0430\u0437\u044b\u0432\u0430\u044e\u0442, \u043a\u0430\u043a\u00a0\u0431\u044b\u0441\u0442\u0440\u043e \u0441\u043e\u0431\u0440\u0430\u0442\u044c \u0440\u0430\u0431\u043e\u0447\u0435\u0435 RAG\u2011\u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u043d\u0430\u00a0\u0447\u0438\u0441\u0442\u043e\u043c <strong>Java\u2011\u0441\u0442\u0435\u043a\u0435<\/strong>, \u0432\u0441\u0442\u0440\u0435\u0447\u0430\u044e\u0442\u0441\u044f \u043a\u0440\u0430\u0439\u043d\u0435 \u0440\u0435\u0434\u043a\u043e. \u042d\u0442\u0430 \u0441\u0442\u0430\u0442\u044c\u044f \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0441\u043e\u0431\u043e\u0439 \u043f\u0440\u043e\u0441\u0442\u043e\u0435 \u043f\u0440\u0430\u043a\u0442\u0438\u0447\u0435\u0441\u043a\u043e\u0435 \u0440\u0443\u043a\u043e\u0432\u043e\u0434\u0441\u0442\u0432\u043e, \u0433\u0434\u0435 \u043c\u044b \u0440\u0430\u0437\u0431\u0435\u0440\u0451\u043c \u0432\u0435\u0441\u044c \u043f\u0440\u043e\u0446\u0435\u0441\u0441 \u043e\u0442\u00a0\u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u043e\u043a\u0440\u0443\u0436\u0435\u043d\u0438\u044f \u0434\u043e\u00a0\u043f\u043e\u043b\u043d\u043e\u0433\u043e \u043f\u0440\u0438\u043c\u0435\u0440\u0430 \u043a\u043e\u0434\u0430, \u0447\u0442\u043e\u0431\u044b \u0434\u0430\u0436\u0435 \u043d\u0430\u0447\u0438\u043d\u0430\u044e\u0449\u0438\u0439 Java\u2011\u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a \u043c\u043e\u0433 \u0440\u0430\u0437\u0432\u0435\u0440\u043d\u0443\u0442\u044c RAG.<\/p>\n<figure class=\"full-width \"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/1a9\/646\/c8b\/1a9646c8bbd6b5351729dd1f594947ff.png\" width=\"1376\" height=\"768\" sizes=\"auto, (max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/getpro\/habr\/upload_files\/1a9\/646\/c8b\/1a9646c8bbd6b5351729dd1f594947ff.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/1a9\/646\/c8b\/1a9646c8bbd6b5351729dd1f594947ff.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/figure>\n<h2>\u0410\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u0430 RAG<\/h2>\n<div class=\"floating-image\">\n<figure class=\"float full-width \"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/cdc\/903\/d09\/cdc903d09cbed5ad7e0791dde24fe159.png\" alt=\"\u041f\u0443\u0442\u044c \u0437\u0430\u043f\u0440\u043e\u0441\u0430 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f\" title=\"\u041f\u0443\u0442\u044c \u0437\u0430\u043f\u0440\u043e\u0441\u0430 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f\" width=\"872\" height=\"646\" sizes=\"auto, (max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/getpro\/habr\/upload_files\/cdc\/903\/d09\/cdc903d09cbed5ad7e0791dde24fe159.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/cdc\/903\/d09\/cdc903d09cbed5ad7e0791dde24fe159.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/p>\n<div><figcaption>\u041f\u0443\u0442\u044c \u0437\u0430\u043f\u0440\u043e\u0441\u0430 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f<\/figcaption><\/div>\n<\/figure>\n<p>\u0410\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u0443 \u0442\u0443\u0442 \u043c\u043e\u0436\u043d\u043e \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u0438\u0442\u044c \u043a\u0430\u043a \u043f\u0440\u043e\u0441\u0442\u0443\u044e \u0446\u0435\u043f\u043e\u0447\u043a\u0443: \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u0441\u0442\u0443\u0447\u0438\u0442\u0441\u044f \u0432 REST\u2011endpoint \u043d\u0430 Spring Boot, \u0437\u0430\u043f\u0440\u043e\u0441 \u043f\u043e\u043f\u0430\u0434\u0430\u0435\u0442 \u0432 Spring<strong> <\/strong>AI, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0432\u0435\u043a\u0442\u043e\u0440\u0438\u0437\u0443\u0435\u0442 \u0435\u0433\u043e (Embedding<strong> <\/strong>model) \u0438 \u0438\u0434\u0451\u0442 \u0432 Qdrant (Vector DB) \u0437\u0430 \u0440\u0435\u043b\u0435\u0432\u0430\u043d\u0442\u043d\u044b\u043c\u0438 \u043a\u0443\u0441\u043a\u0430\u043c\u0438 \u0442\u0435\u043a\u0441\u0442\u0430, \u0430 \u0443\u0436\u0435 \u043f\u043e\u0442\u043e\u043c \u043f\u043e\u0434\u043c\u0435\u0448\u0438\u0432\u0430\u0435\u0442 \u0438\u0445 \u0432 \u043f\u0440\u043e\u043c\u043f\u0442 \u043a \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u043e\u0439 \u043c\u043e\u0434\u0435\u043b\u0438 \u0447\u0435\u0440\u0435\u0437 Ollama.<\/p>\n<\/div>\n<h2>\u041f\u043e\u0434\u0433\u043e\u0442\u043e\u0432\u043a\u0430 \u043e\u043a\u0440\u0443\u0436\u0435\u043d\u0438\u044f<\/h2>\n<p>\u0412\u00a0\u044d\u0442\u043e\u043c \u0433\u0430\u0439\u0434\u0435 \u0443\u00a0\u043d\u0430\u0441 \u0442\u0440\u0438 \u0433\u043b\u0430\u0432\u043d\u044b\u0445 \u0433\u0435\u0440\u043e\u044f \u043d\u0430\u00a0\u0441\u0442\u043e\u0440\u043e\u043d\u0435 \u0431\u044d\u043a\u0435\u043d\u0434\u0430: <strong>Spring Boot (Spring AI),<\/strong> \u0432\u0435\u043a\u0442\u043e\u0440\u043d\u043e\u0435 \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0435 <strong>Qdrant<\/strong> \u0438 LLM \u0447\u0435\u0440\u0435\u0437 <strong>Ollama<\/strong>. \u0427\u0442\u043e\u0431\u044b \u0432\u0441\u0451 \u044d\u0442\u043e \u0437\u0430\u0440\u0430\u0431\u043e\u0442\u0430\u043b\u043e \u043a\u0430\u043a\u00a0\u0435\u0434\u0438\u043d\u0430\u044f RAG\u2011\u043c\u0430\u0448\u0438\u043d\u0430, \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u043e\u00a0\u043b\u0438\u0448\u044c \u0430\u043a\u043a\u0443\u0440\u0430\u0442\u043d\u043e \u043f\u043e\u0434\u0442\u044f\u043d\u0443\u0442\u044c \u043d\u0443\u0436\u043d\u044b\u0435 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u044c, \u043f\u043e\u0434\u043d\u044f\u0442\u044c \u0432\u00a0docker \u0432\u0435\u043a\u0442\u043e\u0440\u043d\u0443\u044e \u0431\u0430\u0437\u0443 \u0438 \u043d\u0430\u0441\u0442\u0440\u043e\u0438\u0442\u044c \u043f\u0430\u0440\u0443 YAML \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0439. \u041f\u0440\u0438\u0441\u0442\u0443\u043f\u0438\u043c \u043a \u043f\u043e\u0448\u0430\u0433\u043e\u0432\u043e\u043c\u0443 \u0440\u0443\u043a\u043e\u0432\u043e\u0434\u0441\u0442\u0432\u0443:<\/p>\n<h3>\u0428\u0430\u0433 1. \u041f\u043e\u0434\u043d\u0438\u043c\u0430\u0435\u043c Qdrant \u0432 Docker<\/h3>\n<p>\u0414\u043b\u044f RAG \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e\u0435 \u0432\u0435\u043a\u0442\u043e\u0440\u043d\u043e\u0435 \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0435, \u043a\u0443\u0434\u0430 \u0431\u0443\u0434\u0443\u0442 \u0441\u043a\u043b\u0430\u0434\u044b\u0432\u0430\u0442\u044c\u0441\u044f \u044d\u043c\u0431\u0435\u0434\u0434\u0438\u043d\u0433\u0438 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u043e\u0432. \u0412 \u044d\u0442\u043e\u0439 \u0440\u043e\u043b\u0438 \u043e\u0442\u043b\u0438\u0447\u043d\u043e \u0432\u044b\u0441\u0442\u0443\u043f\u0430\u0435\u0442 <strong>Qdrant<\/strong>: \u043e\u043d \u0443\u043c\u0435\u0435\u0442 \u0431\u044b\u0441\u0442\u0440\u044b\u0439 ANN\u2011\u043f\u043e\u0438\u0441\u043a, \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442 gRPC \u0438 HTTP \u0438 \u0445\u043e\u0440\u043e\u0448\u043e \u0438\u043d\u0442\u0435\u0433\u0440\u0438\u0440\u0443\u0435\u0442\u0441\u044f \u0441\u043e Spring AI. \u0427\u0442\u043e\u0431\u044b \u043d\u0435 \u0432\u043e\u0437\u0438\u0442\u044c\u0441\u044f \u0441 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u043e\u0439 \u0432\u0440\u0443\u0447\u043d\u0443\u044e, \u043f\u043e\u0434\u043d\u0438\u043c\u0435\u043c Qdrant \u0432 Docker\u2011\u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u0435.<\/p>\n<pre><code class=\"yaml\">services:  qdrant:    image: qdrant\/qdrant:latest    container_name: qdrant    ports:      - \"6333:6333\"      - \"6334:6334\"    environment:      QDRANT__SERVICE__API_KEY: \"your_secret_api_key_here\"    configs:      - source: qdrant_config        target: \/qdrant\/config\/production.yaml    volumes:      - .\/qdrant_storage:\/qdrant\/storage:z<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:87px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0427\u0442\u043e \u0437\u0434\u0435\u0441\u044c \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442:<\/p>\n<ul>\n<li>\n<p>\u041f\u0440\u043e\u0431\u0440\u0430\u0441\u044b\u0432\u0430\u0435\u043c \u043f\u043e\u0440\u0442\u044b 6333 (HTTP) \u0438 6334 (gRPC) \u043d\u0430 \u0445\u043e\u0441\u0442 \u2014 Spring AI \u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e \u043e\u0431\u0449\u0430\u0435\u0442\u0441\u044f \u0441 Qdrant \u043f\u043e gRPC.<\/p>\n<\/li>\n<li>\n<p>\u0412\u043a\u043b\u044e\u0447\u0430\u0435\u043c API\u2011\u043a\u043b\u044e\u0447 \u0447\u0435\u0440\u0435\u0437\u00a0<code>QDRANT__SERVICE__API_KEY<\/code>, \u0447\u0442\u043e\u0431\u044b \u043a \u0432\u0435\u043a\u0442\u043e\u0440\u043d\u043e\u043c\u0443 \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0443 \u043d\u0435\u043b\u044c\u0437\u044f \u0431\u044b\u043b\u043e \u043f\u0440\u043e\u0441\u0442\u043e \u0442\u0430\u043a \u0434\u043e\u0441\u0442\u0443\u0447\u0430\u0442\u044c\u0441\u044f \u0438\u0437\u0432\u043d\u0435.<\/p>\n<\/li>\n<li>\n<p>\u041c\u043e\u043d\u0442\u0438\u0440\u0443\u0435\u043c\u00a0<code>.\/qdrant_storage<\/code>\u00a0\u0432\u043e \u0432\u043d\u0443\u0442\u0440\u0435\u043d\u043d\u044e\u044e \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u044e \u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f Qdrant, \u0447\u0442\u043e\u0431\u044b \u043a\u043e\u043b\u043b\u0435\u043a\u0446\u0438\u0438 \u0438 \u044d\u043c\u0431\u0435\u0434\u0434\u0438\u043d\u0433\u0438 \u043d\u0435 \u043f\u0440\u043e\u043f\u0430\u0434\u0430\u043b\u0438 \u043f\u043e\u0441\u043b\u0435 \u043f\u0435\u0440\u0435\u0437\u0430\u043f\u0443\u0441\u043a\u0430 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u0430.<\/p>\n<\/li>\n<\/ul>\n<h3>\u0428\u0430\u0433 2. \u0414\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u0432 Spring Boot<\/h3>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u044b\u0435 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u0434\u043b\u044f\u00a0Java Spring Boot \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f. \u041f\u043e\u0434\u043a\u043b\u044e\u0447\u0438\u043c \u043a \u043f\u0440\u043e\u0435\u043a\u0442\u0443 Spring AI \u0438 \u0441\u0442\u0430\u0440\u0442\u0435\u0440\u044b \u0434\u043b\u044f Ollama \u0438 Qdrant. \u0414\u043b\u044f Gradle (build.gradle.kts) \u044d\u0442\u043e \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u043f\u0440\u0438\u043c\u0435\u0440\u043d\u043e \u0442\u0430\u043a:<\/p>\n<pre><code class=\"kotlin\">dependencies {    \/\/ spring boot    implementation(\"org.springframework.boot:spring-boot-starter\")    implementation(\"org.springframework.boot:spring-boot-starter-web\")    \/\/ qdrant    implementation(\"org.springframework.ai:spring-ai-starter-vector-store-qdrant\")    \/\/ ollama    implementation(\"org.springframework.ai:spring-ai-starter-model-ollama\")}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0417\u0434\u0435\u0441\u044c:<\/p>\n<ul>\n<li>\n<p><code>spring-boot-starter-web<\/code>\u00a0\u0434\u0430\u0451\u0442 \u043d\u0430\u043c \u043a\u043b\u0430\u0441\u0441\u0438\u0447\u0435\u0441\u043a\u0438\u0439 REST\u2011\u043a\u0430\u0440\u043a\u0430\u0441 \u043d\u0430 Spring Boot.<\/p>\n<\/li>\n<li>\n<p><code>spring-ai-ollama-spring-boot-starter<\/code>\u00a0\u2014 \u0438\u043d\u0442\u0435\u0433\u0440\u0430\u0446\u0438\u044f \u0441 \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u043e\u0439 LLM \u0447\u0435\u0440\u0435\u0437 Ollama.<\/p>\n<\/li>\n<li>\n<p><code>spring-ai-qdrant-spring-boot-starter<\/code>\u00a0\u2014 \u0433\u043e\u0442\u043e\u0432\u044b\u0439 VectorStore \u043f\u043e\u0432\u0435\u0440\u0445 Qdrant \u0438 \u0430\u0432\u0442\u043e\u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u044f \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f.<\/p>\n<\/li>\n<\/ul>\n<h3>\u0428\u0430\u0433 3. \u041d\u0430\u0441\u0442\u0440\u0430\u0438\u0432\u0430\u0435\u043c application.yml<\/h3>\n<p>\u0418 \u043d\u0430\u043a\u043e\u043d\u0435\u0446 \u043c\u043e\u0436\u0435\u043c \u043f\u0435\u0440\u0435\u0439\u0442\u0438 \u043a\u00a0application.yaml \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0438, \u0434\u043e\u0431\u0430\u0432\u044c\u0442\u0435 \u0431\u043b\u043e\u043a <strong>ai<\/strong> \u043a\u00a0\u0432\u0430\u0448\u0435\u043c\u0443 \u043a\u043e\u043d\u0444\u0438\u0433\u0443:<\/p>\n<pre><code class=\"yaml\">spring:  application:    name: springboot-rag-demo  ai:    ollama:      base-url: http:\/\/localhost:11434      chat:        options:          model: llama3:8b          temperature: 0.0          num-ctx: 4096      embedding:        options:          model: bge-m3      request-timeout: 120s    vectorstore:      qdrant:        url: http:\/\/localhost:6333        collection-name: collection        embedding-model: ollama        api-key: \"your_secret_api_key_here\"        use-tls: false        initialize-schema: true<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u041a\u043b\u044e\u0447\u0435\u0432\u044b\u0435 \u043c\u043e\u043c\u0435\u043d\u0442\u044b:<\/p>\n<ul>\n<li>\n<p><code>ollama.base-url<\/code>\u00a0\u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u0442 \u043d\u0430 \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u044b\u0439 Ollama, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e \u0441\u043b\u0443\u0448\u0430\u0435\u0442 \u043f\u043e\u0440\u0442 11434.<\/p>\n<\/li>\n<li>\n<p>\u0412\u00a0<code>chat.model<\/code>\u00a0\u0432\u044b\u0431\u0438\u0440\u0430\u0435\u043c \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u044b\u0439 \u0442\u0435\u0433 Llama, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440\u00a0<code>llama3:8b<\/code>\u00a0&#8212; \u044d\u0442\u043e \u0445\u043e\u0440\u043e\u0448\u0438\u0439 \u043a\u043e\u043c\u043f\u0440\u043e\u043c\u0438\u0441\u0441 \u043c\u0435\u0436\u0434\u0443 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u043e\u043c \u0438 \u0442\u0440\u0435\u0431\u043e\u0432\u0430\u043d\u0438\u044f\u043c\u0438 \u043a \u0436\u0435\u043b\u0435\u0437\u0443.<\/p>\n<\/li>\n<li>\n<p>\u0412\u00a0<code>embedding.model<\/code>\u00a0\u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u043c \u043c\u043e\u0434\u0435\u043b\u044c \u0434\u043b\u044f \u043f\u043e\u0441\u0442\u0440\u043e\u0435\u043d\u0438\u044f \u044d\u043c\u0431\u0435\u0434\u0434\u0438\u043d\u0433\u043e\u0432 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u043e\u0432 &#8212; \u0432 \u043f\u0440\u0438\u043c\u0435\u0440\u0435 \u044d\u0442\u043e\u00a0<code>bge-m3<\/code>, \u043e\u0434\u0438\u043d \u0438\u0437 \u043f\u043e\u043f\u0443\u043b\u044f\u0440\u043d\u044b\u0445 \u0432\u0430\u0440\u0438\u0430\u043d\u0442\u043e\u0432 \u0434\u043b\u044f RAG\u2011\u0441\u0446\u0435\u043d\u0430\u0440\u0438\u0435\u0432.<\/p>\n<\/li>\n<li>\n<p>\u0412 \u0431\u043b\u043e\u043a\u0435\u00a0<code>vectorstore.qdrant<\/code>\u00a0\u043f\u0440\u043e\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u043c URL HTTP\u2011API (\u043f\u043e\u0440\u0442 6333), \u0438\u043c\u044f \u043a\u043e\u043b\u043b\u0435\u043a\u0446\u0438\u0438 \u0438 \u0442\u043e\u0442 \u0436\u0435 API\u2011\u043a\u043b\u044e\u0447, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0437\u0430\u0434\u0430\u0432\u0430\u043b\u0438 \u0432\u00a0<code>docker-compose<\/code><\/p>\n<\/li>\n<\/ul>\n<p>\u0421 \u0442\u0430\u043a\u0438\u043c YAML Spring Boot \u043f\u0440\u0438 \u0441\u0442\u0430\u0440\u0442\u0435 \u043f\u043e\u0434\u043d\u0438\u043c\u0435\u0442 \u0430\u0432\u0442\u043e\u0441\u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0439 \u043a\u043b\u0438\u0435\u043d\u0442 \u0434\u043b\u044f Ollama \u0438 VectorStore \u0434\u043b\u044f Qdrant, \u0438 \u0434\u0430\u043b\u044c\u0448\u0435 \u0432 \u043a\u043e\u0434\u0435 \u043c\u043e\u0436\u043d\u043e \u0431\u0443\u0434\u0435\u0442 \u043f\u0440\u043e\u0441\u0442\u043e \u0438\u043d\u0436\u0435\u043a\u0442\u0438\u0442\u044c \u0433\u043e\u0442\u043e\u0432\u044b\u0435 \u0431\u0438\u043d\u044b.<\/p>\n<h2>\u041f\u0440\u0438\u043c\u0435\u0440 \u043f\u0440\u043e\u0441\u0442\u043e\u0439 \u043f\u043e\u043b\u043d\u043e\u0446\u0435\u043d\u043d\u043e\u0439 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u043d\u0430 Java<\/h2>\n<p>\u0414\u043b\u044f \u043f\u0440\u0438\u043c\u0435\u0440\u0430 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u043d\u0430\u043f\u0438\u0448\u0435\u043c \u043f\u0440\u043e\u0441\u0442\u0435\u0439\u0448\u0438\u0439 \u0443\u043d\u0438\u0432\u0435\u0440\u0441\u0430\u043b\u044c\u043d\u044b\u0439 \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u0442\u044c \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u044b \u0438 \u0437\u0430\u0434\u0430\u0432\u0430\u0442\u044c \u0432\u043e\u043f\u0440\u043e\u0441\u044b, \u043f\u043e\u043b\u0443\u0447\u0430\u044f \u043e\u0442\u0432\u0435\u0442\u044b, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043e\u043f\u0438\u0440\u0430\u044e\u0442\u0441\u044f \u043d\u0430 \u0437\u0430\u0433\u0440\u0443\u0436\u0435\u043d\u043d\u044b\u0435 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u044b.<\/p>\n<pre><code class=\"java\">@RestController@RequestMapping(\"\/api\/rag\")public class RagController {    private final RagService ragService;    private final DocumentIndexingService documentService;    public RagController(RagService ragService,                          DocumentIndexingService documentService) {        this.ragService = ragService;        this.documentService = documentService;    }    @GetMapping(\"\/ask\")    public String ask(@RequestParam String question) {        return ragService.ask(question);    }    @PostMapping(\"\/documents\")    public String saveDocument(@RequestBody String content) {        documentIndexingService.saveDocument(content);        return \"\u0414\u043e\u043a\u0443\u043c\u0435\u043d\u0442 \u0443\u0441\u043f\u0435\u0448\u043d\u043e \u0441\u043e\u0445\u0440\u0430\u043d\u0451\u043d \u0432 Qdrant\";    }}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0421\u0434\u0435\u043b\u0430\u0435\u043c RAG \u0441\u0435\u0440\u0432\u0438\u0441 \u043f\u043e\u0434 \u043d\u0435\u0433\u043e, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f \u0433\u043e\u0442\u043e\u0432\u044b\u0435 \u043a\u043b\u0438\u0435\u043d\u0442\u044b \u0434\u043b\u044f Qdrant \u0438 Ollama, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0434\u043e\u043b\u0436\u0435\u043d \u043e\u0442\u0432\u0435\u0447\u0430\u0442\u044c \u043d\u0430 \u0432\u043e\u043f\u0440\u043e\u0441\u044b, \u043e\u043f\u0438\u0440\u0430\u044f\u0441\u044c \u043d\u0430 \u0434\u0430\u043d\u043d\u044b\u0435 \u0438\u0437 \u0432\u0435\u043a\u0442\u043e\u0440\u043d\u043e\u0439 \u0431\u0430\u0437\u044b Qdrant.<\/p>\n<pre><code class=\"java\">package com.example.rag.service;import java.util.List;import org.springframework.ai.chat.client.ChatClient;import org.springframework.ai.document.Document;import org.springframework.ai.vectorstore.SearchRequest;import org.springframework.ai.vectorstore.VectorStore;import org.springframework.stereotype.Service;@Servicepublic class RagService {    private final VectorStore vectorStore;    private final ChatClient chatClient;    public RagService(VectorStore vectorStore, ChatClient.Builder chatClientBuilder) {        this.vectorStore = vectorStore;        this.chatClient = chatClientBuilder.build();    }    public String ask(String question) {        List&lt;Document&gt; documents = vectorStore.similaritySearch(                SearchRequest.builder()                        .query(question)                        .topK(4)                        .build()        );        String context = documents.stream()                .map(Document::getText)                .reduce(\"\", (a, b) -&gt; a + \"\\n\\n\" + b);        return chatClient.prompt()                .system(\"\"\"                        \u0422\u044b \u043f\u043e\u043c\u043e\u0449\u043d\u0438\u043a, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043e\u0442\u0432\u0435\u0447\u0430\u0435\u0442 \u0442\u043e\u043b\u044c\u043a\u043e \u043d\u0430 \u043e\u0441\u043d\u043e\u0432\u0435 \u043f\u0435\u0440\u0435\u0434\u0430\u043d\u043d\u043e\u0433\u043e \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u0430.                        \u0415\u0441\u043b\u0438 \u0432 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u0435 \u043d\u0435\u0442 \u043e\u0442\u0432\u0435\u0442\u0430, \u0447\u0435\u0441\u0442\u043d\u043e \u0441\u043a\u0430\u0436\u0438 \u043e\u0431 \u044d\u0442\u043e\u043c.                        \"\"\")                .user(\"\"\"                        \u041a\u043e\u043d\u0442\u0435\u043a\u0441\u0442:                        %s                        \u0412\u043e\u043f\u0440\u043e\u0441:                        %s                        \"\"\".formatted(context, question))                .call()                .content();    }}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0422\u0430\u043a \u043a\u0430\u043a \u0434\u0430\u043d\u043d\u044b\u0445 \u0432 Qdrant \u043f\u043e\u043a\u0430 \u043d\u0435\u0442, \u043d\u0443\u0436\u043d\u043e \u0434\u043e\u043f\u0438\u0441\u0430\u0442\u044c \u0441\u0435\u0440\u0432\u0438\u0441 \u0438\u043d\u0434\u0435\u043a\u0441\u0430\u0446\u0438\u0438 \u0438 \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u043e\u0432, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0442\u0430\u043a\u0436\u0435 \u043e\u0447\u0435\u043d\u044c \u043f\u0440\u043e\u0441\u0442\u043e \u0438\u043d\u0442\u0435\u0433\u0440\u0438\u0440\u0443\u0435\u0442\u0441\u044f \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e Spring AI.<\/p>\n<pre><code class=\"java\">package com.example.rag.service;import java.util.List;import java.util.Map;import org.springframework.ai.document.Document;import org.springframework.ai.vectorstore.VectorStore;import org.springframework.stereotype.Service;@Servicepublic class DocumentIndexingService {    private final VectorStore vectorStore;    public DocumentIndexingService(VectorStore vectorStore) {        this.vectorStore = vectorStore;    }    public void saveDocument(String content) {        Document document = new Document(content);        vectorStore.add(List.of(document));    }    public void saveDocument(String content, Map&lt;String, Object&gt; metadata) {        Document document = new Document(content, metadata);        vectorStore.add(List.of(document));    }    public void saveDocuments(List&lt;String&gt; contents) {        List&lt;Document&gt; documents = contents.stream()                .map(Document::new)                .toList();        vectorStore.add(documents);    }}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<h2>\u0417\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u0438\u0435<\/h2>\n<p>\u041c\u044b \u0441\u043e\u0431\u0440\u0430\u043b\u0438 \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u044b\u0439 RAG\u2011\u0441\u0435\u0440\u0432\u0438\u0441 \u043d\u0430 Java: Spring Boot \u0434\u0430\u0451\u0442 REST\u2011API, Spring AI \u0443\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u0442 \u043c\u043e\u0434\u0435\u043b\u044f\u043c\u0438, Qdrant \u0445\u0440\u0430\u043d\u0438\u0442 \u044d\u043c\u0431\u0435\u0434\u0434\u0438\u043d\u0433\u0438, \u0430 Ollama \u043a\u0440\u0443\u0442\u0438\u0442 Llama \u043f\u0440\u044f\u043c\u043e \u043d\u0430 \u043c\u0430\u0448\u0438\u043d\u0435. \u041f\u043e \u043f\u0443\u0442\u0438 \u043c\u044b \u043d\u0430\u0441\u0442\u0440\u043e\u0438\u043b\u0438 \u043e\u043a\u0440\u0443\u0436\u0435\u043d\u0438\u0435 \u0438\u00a0<code>docker-compose<\/code>, \u043f\u0440\u043e\u043f\u0438\u0441\u0430\u043b\u0438 \u043a\u043e\u043d\u0444\u0438\u0433 \u0432\u00a0<code>application.yml<\/code>, \u0434\u043e\u0431\u0430\u0432\u0438\u043b\u0438 \u0441\u0435\u0440\u0432\u0438\u0441\u044b \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u043e\u0432 \u0438 \u043f\u043e\u0438\u0441\u043a\u0430, \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440\u00a0<code>\/api\/rag\/ask<\/code>. \u042d\u0442\u043e\u0442 \u0441\u043a\u0435\u043b\u0435\u0442 \u0443\u0436\u0435 \u043c\u043e\u0436\u043d\u043e \u043f\u0440\u0435\u0432\u0440\u0430\u0449\u0430\u0442\u044c \u0432\u043e \u0432\u043d\u0443\u0442\u0440\u0435\u043d\u043d\u0435\u0433\u043e \u0430\u0441\u0441\u0438\u0441\u0442\u0435\u043d\u0442\u0430: \u043c\u0435\u043d\u044f\u0442\u044c \u043c\u043e\u0434\u0435\u043b\u0438, \u0432\u044b\u043d\u043e\u0441\u0438\u0442\u044c Qdrant \u0432 \u043f\u0440\u043e\u0434 \u0438 \u043d\u0430\u0432\u0435\u0448\u0438\u0432\u0430\u0442\u044c UI. \u0415\u0441\u043b\u0438 \u0431\u0443\u0434\u0435\u0442\u0435 \u0441\u043e\u0431\u0438\u0440\u0430\u0442\u044c \u0441\u0432\u043e\u044e \u0432\u0435\u0440\u0441\u0438\u044e, \u0442\u043e \u044d\u0442\u0443 \u043f\u0440\u043e\u0441\u0442\u0443\u044e \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044e \u043c\u043e\u0436\u043d\u043e \u0432\u0437\u044f\u0442\u044c \u0437\u0430 \u043e\u0441\u043d\u043e\u0432\u0443 \u0438 \u0434\u043e\u043f\u0438\u043b\u0438\u0442\u044c \u043f\u043e\u0434 \u0441\u0432\u043e\u0438 \u043d\u0443\u0436\u0434\u044b.<\/p>\n<\/div>\n<p>\u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u0438 <a href=\"https:\/\/habr.com\/ru\/articles\/1027426\/\">https:\/\/habr.com\/ru\/articles\/1027426\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>\u0412\u0441\u0435\u043c \u043f\u0440\u0438\u0432\u0435\u0442! \u041d\u0435\u0434\u0430\u0432\u043d\u043e \u0441\u0442\u043e\u043b\u043a\u043d\u0443\u043b\u0441\u044f \u0441 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u043e\u0439, \u0447\u0442\u043e \u0432\u00a0\u043d\u0430\u0441\u0442\u043e\u044f\u0449\u0435\u0435 \u0432\u0440\u0435\u043c\u044f \u0431\u043e\u043b\u044c\u0448\u0430\u044f \u0447\u0430\u0441\u0442\u044c \u043e\u0431\u0443\u0447\u0430\u044e\u0449\u0438\u0445 \u043c\u0430\u0442\u0435\u0440\u0438\u0430\u043b\u043e\u0432 \u043f\u043e\u00a0Retrieval\u2011Augmented Generation (RAG) \u0441\u043e\u0441\u0440\u0435\u0434\u043e\u0442\u043e\u0447\u0435\u043d\u0430 \u043d\u0430\u00a0Python\u2011\u044d\u043a\u043e\u0441\u0438\u0441\u0442\u0435\u043c\u0435 (LangChain, LlamaIndex \u0438 \u0442\u043e\u043c\u0443 \u043f\u043e\u0434\u043e\u0431\u043d\u043e\u0435), \u0430\u00a0\u043f\u043e\u0448\u0430\u0433\u043e\u0432\u044b\u0435 \u0440\u0443\u043a\u043e\u0432\u043e\u0434\u0441\u0442\u0432\u0430, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043f\u043e\u043a\u0430\u0437\u044b\u0432\u0430\u044e\u0442, \u043a\u0430\u043a\u00a0\u0431\u044b\u0441\u0442\u0440\u043e \u0441\u043e\u0431\u0440\u0430\u0442\u044c \u0440\u0430\u0431\u043e\u0447\u0435\u0435 RAG\u2011\u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u043d\u0430\u00a0\u0447\u0438\u0441\u0442\u043e\u043c Java\u2011\u0441\u0442\u0435\u043a\u0435, \u0432\u0441\u0442\u0440\u0435\u0447\u0430\u044e\u0442\u0441\u044f \u043a\u0440\u0430\u0439\u043d\u0435 \u0440\u0435\u0434\u043a\u043e. \u042d\u0442\u0430 \u0441\u0442\u0430\u0442\u044c\u044f \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0441\u043e\u0431\u043e\u0439 \u043f\u0440\u043e\u0441\u0442\u043e\u0435 \u043f\u0440\u0430\u043a\u0442\u0438\u0447\u0435\u0441\u043a\u043e\u0435 \u0440\u0443\u043a\u043e\u0432\u043e\u0434\u0441\u0442\u0432\u043e, \u0433\u0434\u0435 \u043c\u044b \u0440\u0430\u0437\u0431\u0435\u0440\u0451\u043c \u0432\u0435\u0441\u044c \u043f\u0440\u043e\u0446\u0435\u0441\u0441 \u043e\u0442\u00a0\u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u043e\u043a\u0440\u0443\u0436\u0435\u043d\u0438\u044f \u0434\u043e\u00a0\u043f\u043e\u043b\u043d\u043e\u0433\u043e \u043f\u0440\u0438\u043c\u0435\u0440\u0430 \u043a\u043e\u0434\u0430, \u0447\u0442\u043e\u0431\u044b \u0434\u0430\u0436\u0435 \u043d\u0430\u0447\u0438\u043d\u0430\u044e\u0449\u0438\u0439 Java\u2011\u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a \u043c\u043e\u0433 \u0440\u0430\u0437\u0432\u0435\u0440\u043d\u0443\u0442\u044c RAG.\u0410\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u0430 RAG\u041f\u0443\u0442\u044c \u0437\u0430\u043f\u0440\u043e\u0441\u0430 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f\u0410\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u0443 \u0442\u0443\u0442 \u043c\u043e\u0436\u043d\u043e \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u0438\u0442\u044c \u043a\u0430\u043a \u043f\u0440\u043e\u0441\u0442\u0443\u044e \u0446\u0435\u043f\u043e\u0447\u043a\u0443: \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u0441\u0442\u0443\u0447\u0438\u0442\u0441\u044f \u0432 REST\u2011endpoint \u043d\u0430 Spring Boot, \u0437\u0430\u043f\u0440\u043e\u0441 \u043f\u043e\u043f\u0430\u0434\u0430\u0435\u0442 \u0432 Spring AI, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0432\u0435\u043a\u0442\u043e\u0440\u0438\u0437\u0443\u0435\u0442 \u0435\u0433\u043e (Embedding model) \u0438 \u0438\u0434\u0451\u0442 \u0432 Qdrant (Vector DB) \u0437\u0430 \u0440\u0435\u043b\u0435\u0432\u0430\u043d\u0442\u043d\u044b\u043c\u0438 \u043a\u0443\u0441\u043a\u0430\u043c\u0438 \u0442\u0435\u043a\u0441\u0442\u0430, \u0430 \u0443\u0436\u0435 \u043f\u043e\u0442\u043e\u043c \u043f\u043e\u0434\u043c\u0435\u0448\u0438\u0432\u0430\u0435\u0442 \u0438\u0445 \u0432 \u043f\u0440\u043e\u043c\u043f\u0442 \u043a \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u043e\u0439 \u043c\u043e\u0434\u0435\u043b\u0438 \u0447\u0435\u0440\u0435\u0437 Ollama.\u041f\u043e\u0434\u0433\u043e\u0442\u043e\u0432\u043a\u0430 \u043e\u043a\u0440\u0443\u0436\u0435\u043d\u0438\u044f\u0412\u00a0\u044d\u0442\u043e\u043c \u0433\u0430\u0439\u0434\u0435 \u0443\u00a0\u043d\u0430\u0441 \u0442\u0440\u0438 \u0433\u043b\u0430\u0432\u043d\u044b\u0445 \u0433\u0435\u0440\u043e\u044f \u043d\u0430\u00a0\u0441\u0442\u043e\u0440\u043e\u043d\u0435 \u0431\u044d\u043a\u0435\u043d\u0434\u0430: Spring Boot (Spring AI), \u0432\u0435\u043a\u0442\u043e\u0440\u043d\u043e\u0435 \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0435 Qdrant \u0438 LLM \u0447\u0435\u0440\u0435\u0437 Ollama. \u0427\u0442\u043e\u0431\u044b \u0432\u0441\u0451 \u044d\u0442\u043e \u0437\u0430\u0440\u0430\u0431\u043e\u0442\u0430\u043b\u043e \u043a\u0430\u043a\u00a0\u0435\u0434\u0438\u043d\u0430\u044f RAG\u2011\u043c\u0430\u0448\u0438\u043d\u0430, \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u043e\u00a0\u043b\u0438\u0448\u044c \u0430\u043a\u043a\u0443\u0440\u0430\u0442\u043d\u043e \u043f\u043e\u0434\u0442\u044f\u043d\u0443\u0442\u044c \u043d\u0443\u0436\u043d\u044b\u0435 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u044c, \u043f\u043e\u0434\u043d\u044f\u0442\u044c \u0432\u00a0docker \u0432\u0435\u043a\u0442\u043e\u0440\u043d\u0443\u044e \u0431\u0430\u0437\u0443 \u0438 \u043d\u0430\u0441\u0442\u0440\u043e\u0438\u0442\u044c \u043f\u0430\u0440\u0443 YAML \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0439. \u041f\u0440\u0438\u0441\u0442\u0443\u043f\u0438\u043c \u043a \u043f\u043e\u0448\u0430\u0433\u043e\u0432\u043e\u043c\u0443 \u0440\u0443\u043a\u043e\u0432\u043e\u0434\u0441\u0442\u0432\u0443:\u0428\u0430\u0433 1. \u041f\u043e\u0434\u043d\u0438\u043c\u0430\u0435\u043c Qdrant \u0432 Docker\u0414\u043b\u044f RAG \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e\u0435 \u0432\u0435\u043a\u0442\u043e\u0440\u043d\u043e\u0435 \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0435, \u043a\u0443\u0434\u0430 \u0431\u0443\u0434\u0443\u0442 \u0441\u043a\u043b\u0430\u0434\u044b\u0432\u0430\u0442\u044c\u0441\u044f \u044d\u043c\u0431\u0435\u0434\u0434\u0438\u043d\u0433\u0438 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u043e\u0432. \u0412 \u044d\u0442\u043e\u0439 \u0440\u043e\u043b\u0438 \u043e\u0442\u043b\u0438\u0447\u043d\u043e \u0432\u044b\u0441\u0442\u0443\u043f\u0430\u0435\u0442 Qdrant: \u043e\u043d \u0443\u043c\u0435\u0435\u0442 \u0431\u044b\u0441\u0442\u0440\u044b\u0439 ANN\u2011\u043f\u043e\u0438\u0441\u043a, \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442 gRPC \u0438 HTTP \u0438 \u0445\u043e\u0440\u043e\u0448\u043e \u0438\u043d\u0442\u0435\u0433\u0440\u0438\u0440\u0443\u0435\u0442\u0441\u044f \u0441\u043e Spring AI. \u0427\u0442\u043e\u0431\u044b \u043d\u0435 \u0432\u043e\u0437\u0438\u0442\u044c\u0441\u044f \u0441 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u043e\u0439 \u0432\u0440\u0443\u0447\u043d\u0443\u044e, \u043f\u043e\u0434\u043d\u0438\u043c\u0435\u043c Qdrant \u0432 Docker\u2011\u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u0435.services:  qdrant:    image: qdrant\/qdrant:latest    container_name: qdrant    ports:      &#8212; &#171;6333:6333&#187;      &#8212; &#171;6334:6334&#187;    environment:      QDRANT__SERVICE__API_KEY: &#171;your_secret_api_key_here&#187;    configs:      &#8212; source: qdrant_config        target: \/qdrant\/config\/production.yaml    volumes:      &#8212; .\/qdrant_storage:\/qdrant\/storage:z\u0427\u0442\u043e \u0437\u0434\u0435\u0441\u044c \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442:\u041f\u0440\u043e\u0431\u0440\u0430\u0441\u044b\u0432\u0430\u0435\u043c \u043f\u043e\u0440\u0442\u044b 6333 (HTTP) \u0438 6334 (gRPC) \u043d\u0430 \u0445\u043e\u0441\u0442 \u2014 Spring AI \u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e \u043e\u0431\u0449\u0430\u0435\u0442\u0441\u044f \u0441 Qdrant \u043f\u043e gRPC.\u0412\u043a\u043b\u044e\u0447\u0430\u0435\u043c API\u2011\u043a\u043b\u044e\u0447 \u0447\u0435\u0440\u0435\u0437\u00a0QDRANT__SERVICE__API_KEY, \u0447\u0442\u043e\u0431\u044b \u043a \u0432\u0435\u043a\u0442\u043e\u0440\u043d\u043e\u043c\u0443 \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0443 \u043d\u0435\u043b\u044c\u0437\u044f \u0431\u044b\u043b\u043e \u043f\u0440\u043e\u0441\u0442\u043e \u0442\u0430\u043a \u0434\u043e\u0441\u0442\u0443\u0447\u0430\u0442\u044c\u0441\u044f \u0438\u0437\u0432\u043d\u0435.\u041c\u043e\u043d\u0442\u0438\u0440\u0443\u0435\u043c\u00a0.\/qdrant_storage\u00a0\u0432\u043e \u0432\u043d\u0443\u0442\u0440\u0435\u043d\u043d\u044e\u044e \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u044e \u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f Qdrant, \u0447\u0442\u043e\u0431\u044b \u043a\u043e\u043b\u043b\u0435\u043a\u0446\u0438\u0438 \u0438 \u044d\u043c\u0431\u0435\u0434\u0434\u0438\u043d\u0433\u0438 \u043d\u0435 \u043f\u0440\u043e\u043f\u0430\u0434\u0430\u043b\u0438 \u043f\u043e\u0441\u043b\u0435 \u043f\u0435\u0440\u0435\u0437\u0430\u043f\u0443\u0441\u043a\u0430 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u0430.\u0428\u0430\u0433 2. \u0414\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u0432 Spring Boot\u0422\u0435\u043f\u0435\u0440\u044c \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u044b\u0435 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u0434\u043b\u044f\u00a0Java Spring Boot \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f. \u041f\u043e\u0434\u043a\u043b\u044e\u0447\u0438\u043c \u043a \u043f\u0440\u043e\u0435\u043a\u0442\u0443 Spring AI \u0438 \u0441\u0442\u0430\u0440\u0442\u0435\u0440\u044b \u0434\u043b\u044f Ollama \u0438 Qdrant. \u0414\u043b\u044f Gradle (build.gradle.kts) \u044d\u0442\u043e \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u043f\u0440\u0438\u043c\u0435\u0440\u043d\u043e \u0442\u0430\u043a:dependencies {    \/\/ spring boot    implementation(&#171;org.springframework.boot:spring-boot-starter&#187;)    implementation(&#171;org.springframework.boot:spring-boot-starter-web&#187;)    \/\/ qdrant    implementation(&#171;org.springframework.ai:spring-ai-starter-vector-store-qdrant&#187;)    \/\/ ollama    implementation(&#171;org.springframework.ai:spring-ai-starter-model-ollama&#187;)}\u0417\u0434\u0435\u0441\u044c:spring-boot-starter-web\u00a0\u0434\u0430\u0451\u0442 \u043d\u0430\u043c \u043a\u043b\u0430\u0441\u0441\u0438\u0447\u0435\u0441\u043a\u0438\u0439 REST\u2011\u043a\u0430\u0440\u043a\u0430\u0441 \u043d\u0430 Spring Boot.spring-ai-ollama-spring-boot-starter\u00a0\u2014 \u0438\u043d\u0442\u0435\u0433\u0440\u0430\u0446\u0438\u044f \u0441 \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u043e\u0439 LLM \u0447\u0435\u0440\u0435\u0437 Ollama.spring-ai-qdrant-spring-boot-starter\u00a0\u2014 \u0433\u043e\u0442\u043e\u0432\u044b\u0439 VectorStore \u043f\u043e\u0432\u0435\u0440\u0445 Qdrant \u0438 \u0430\u0432\u0442\u043e\u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u044f \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f.\u0428\u0430\u0433 3. \u041d\u0430\u0441\u0442\u0440\u0430\u0438\u0432\u0430\u0435\u043c application.yml\u0418 \u043d\u0430\u043a\u043e\u043d\u0435\u0446 \u043c\u043e\u0436\u0435\u043c \u043f\u0435\u0440\u0435\u0439\u0442\u0438 \u043a\u00a0application.yaml \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0438, \u0434\u043e\u0431\u0430\u0432\u044c\u0442\u0435 \u0431\u043b\u043e\u043a ai \u043a\u00a0\u0432\u0430\u0448\u0435\u043c\u0443 \u043a\u043e\u043d\u0444\u0438\u0433\u0443:spring:  application:    name: springboot-rag-demo  ai:    ollama:      base-url: http:\/\/localhost:11434      chat:        options:          model: llama3:8b          temperature: 0.0          num-ctx: 4096      embedding:        options:          model: bge-m3      request-timeout: 120s    vectorstore:      qdrant:        url: http:\/\/localhost:6333        collection-name: collection        embedding-model: ollama        api-key: &#171;your_secret_api_key_here&#187;        use-tls: false        initialize-schema: true\u041a\u043b\u044e\u0447\u0435\u0432\u044b\u0435 \u043c\u043e\u043c\u0435\u043d\u0442\u044b:ollama.base-url\u00a0\u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u0442 \u043d\u0430 \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u044b\u0439 Ollama, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e \u0441\u043b\u0443\u0448\u0430\u0435\u0442 \u043f\u043e\u0440\u0442 11434.\u0412\u00a0chat.model\u00a0\u0432\u044b\u0431\u0438\u0440\u0430\u0435\u043c \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u044b\u0439 \u0442\u0435\u0433 Llama, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440\u00a0llama3:8b\u00a0&#8212; \u044d\u0442\u043e \u0445\u043e\u0440\u043e\u0448\u0438\u0439 \u043a\u043e\u043c\u043f\u0440\u043e\u043c\u0438\u0441\u0441 \u043c\u0435\u0436\u0434\u0443 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u043e\u043c \u0438 \u0442\u0440\u0435\u0431\u043e\u0432\u0430\u043d\u0438\u044f\u043c\u0438 \u043a \u0436\u0435\u043b\u0435\u0437\u0443.\u0412\u00a0embedding.model\u00a0\u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u043c \u043c\u043e\u0434\u0435\u043b\u044c \u0434\u043b\u044f \u043f\u043e\u0441\u0442\u0440\u043e\u0435\u043d\u0438\u044f \u044d\u043c\u0431\u0435\u0434\u0434\u0438\u043d\u0433\u043e\u0432 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u043e\u0432 &#8212; \u0432 \u043f\u0440\u0438\u043c\u0435\u0440\u0435 \u044d\u0442\u043e\u00a0bge-m3, \u043e\u0434\u0438\u043d \u0438\u0437 \u043f\u043e\u043f\u0443\u043b\u044f\u0440\u043d\u044b\u0445 \u0432\u0430\u0440\u0438\u0430\u043d\u0442\u043e\u0432 \u0434\u043b\u044f RAG\u2011\u0441\u0446\u0435\u043d\u0430\u0440\u0438\u0435\u0432.\u0412 \u0431\u043b\u043e\u043a\u0435\u00a0vectorstore.qdrant\u00a0\u043f\u0440\u043e\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u043c URL HTTP\u2011API (\u043f\u043e\u0440\u0442 6333), \u0438\u043c\u044f \u043a\u043e\u043b\u043b\u0435\u043a\u0446\u0438\u0438 \u0438 \u0442\u043e\u0442 \u0436\u0435 API\u2011\u043a\u043b\u044e\u0447, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0437\u0430\u0434\u0430\u0432\u0430\u043b\u0438 \u0432\u00a0docker-compose\u0421 \u0442\u0430\u043a\u0438\u043c YAML Spring Boot \u043f\u0440\u0438 \u0441\u0442\u0430\u0440\u0442\u0435 \u043f\u043e\u0434\u043d\u0438\u043c\u0435\u0442 \u0430\u0432\u0442\u043e\u0441\u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0439 \u043a\u043b\u0438\u0435\u043d\u0442 \u0434\u043b\u044f Ollama \u0438 VectorStore \u0434\u043b\u044f Qdrant, \u0438 \u0434\u0430\u043b\u044c\u0448\u0435 \u0432 \u043a\u043e\u0434\u0435 \u043c\u043e\u0436\u043d\u043e \u0431\u0443\u0434\u0435\u0442 \u043f\u0440\u043e\u0441\u0442\u043e \u0438\u043d\u0436\u0435\u043a\u0442\u0438\u0442\u044c \u0433\u043e\u0442\u043e\u0432\u044b\u0435 \u0431\u0438\u043d\u044b.\u041f\u0440\u0438\u043c\u0435\u0440 \u043f\u0440\u043e\u0441\u0442\u043e\u0439 \u043f\u043e\u043b\u043d\u043e\u0446\u0435\u043d\u043d\u043e\u0439 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u043d\u0430 Java\u0414\u043b\u044f \u043f\u0440\u0438\u043c\u0435\u0440\u0430 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u043d\u0430\u043f\u0438\u0448\u0435\u043c \u043f\u0440\u043e\u0441\u0442\u0435\u0439\u0448\u0438\u0439 \u0443\u043d\u0438\u0432\u0435\u0440\u0441\u0430\u043b\u044c\u043d\u044b\u0439 \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u0442\u044c \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u044b \u0438 \u0437\u0430\u0434\u0430\u0432\u0430\u0442\u044c \u0432\u043e\u043f\u0440\u043e\u0441\u044b, \u043f\u043e\u043b\u0443\u0447\u0430\u044f \u043e\u0442\u0432\u0435\u0442\u044b, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043e\u043f\u0438\u0440\u0430\u044e\u0442\u0441\u044f \u043d\u0430 \u0437\u0430\u0433\u0440\u0443\u0436\u0435\u043d\u043d\u044b\u0435 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u044b.@RestController@RequestMapping(&#171;\/api\/rag&#187;)public class RagController {    private final RagService ragService;    private final DocumentIndexingService documentService;    public RagController(RagService ragService,                          DocumentIndexingService documentService) {        this.ragService = ragService;        this.documentService = documentService;    }    @GetMapping(&#171;\/ask&#187;)    public String ask(@RequestParam String question) {        return ragService.ask(question);    }    @PostMapping(&#171;\/documents&#187;)    public String saveDocument(@RequestBody String content) {        documentIndexingService.saveDocument(content);        return &#171;\u0414\u043e\u043a\u0443\u043c\u0435\u043d\u0442 \u0443\u0441\u043f\u0435\u0448\u043d\u043e \u0441\u043e\u0445\u0440\u0430\u043d\u0451\u043d \u0432 Qdrant&#187;;    }}\u0421\u0434\u0435\u043b\u0430\u0435\u043c RAG \u0441\u0435\u0440\u0432\u0438\u0441 \u043f\u043e\u0434 \u043d\u0435\u0433\u043e, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f \u0433\u043e\u0442\u043e\u0432\u044b\u0435 \u043a\u043b\u0438\u0435\u043d\u0442\u044b \u0434\u043b\u044f Qdrant \u0438 Ollama, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0434\u043e\u043b\u0436\u0435\u043d \u043e\u0442\u0432\u0435\u0447\u0430\u0442\u044c \u043d\u0430 \u0432\u043e\u043f\u0440\u043e\u0441\u044b, \u043e\u043f\u0438\u0440\u0430\u044f\u0441\u044c \u043d\u0430 \u0434\u0430\u043d\u043d\u044b\u0435 \u0438\u0437 \u0432\u0435\u043a\u0442\u043e\u0440\u043d\u043e\u0439 \u0431\u0430\u0437\u044b Qdrant.package com.example.rag.service;import java.util.List;import org.springframework.ai.chat.client.ChatClient;import org.springframework.ai.document.Document;import org.springframework.ai.vectorstore.SearchRequest;import org.springframework.ai.vectorstore.VectorStore;import org.springframework.stereotype.Service;@Servicepublic class RagService {    private final VectorStore vectorStore;    private final ChatClient chatClient;    public RagService(VectorStore vectorStore, ChatClient.Builder chatClientBuilder) {        this.vectorStore = vectorStore;        this.chatClient = chatClientBuilder.build();    }    public String ask(String question) {        List&lt;Document&gt; documents = vectorStore.similaritySearch(                SearchRequest.builder()                        .query(question)                        .topK(4)                        .build()        );        String context = documents.stream()                .map(Document::getText)                .reduce(&#171;&#187;, (a, b) -&gt; a + &#171;\\n\\n&#187; + b);        return chatClient.prompt()                .system(&#171;&#187;&#187;                        \u0422\u044b \u043f\u043e\u043c\u043e\u0449\u043d\u0438\u043a, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043e\u0442\u0432\u0435\u0447\u0430\u0435\u0442 \u0442\u043e\u043b\u044c\u043a\u043e \u043d\u0430 \u043e\u0441\u043d\u043e\u0432\u0435 \u043f\u0435\u0440\u0435\u0434\u0430\u043d\u043d\u043e\u0433\u043e \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u0430.                        \u0415\u0441\u043b\u0438 \u0432 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u0435 \u043d\u0435\u0442 \u043e\u0442\u0432\u0435\u0442\u0430, \u0447\u0435\u0441\u0442\u043d\u043e \u0441\u043a\u0430\u0436\u0438 \u043e\u0431 \u044d\u0442\u043e\u043c.                        &#171;&#187;&#187;)                .user(&#171;&#187;&#187;                        \u041a\u043e\u043d\u0442\u0435\u043a\u0441\u0442:                        %s                        \u0412\u043e\u043f\u0440\u043e\u0441:                        %s                        &#171;&#187;&#187;.formatted(context, question))                .call()                .content();    }}\u0422\u0430\u043a \u043a\u0430\u043a \u0434\u0430\u043d\u043d\u044b\u0445 \u0432 Qdrant \u043f\u043e\u043a\u0430 \u043d\u0435\u0442, \u043d\u0443\u0436\u043d\u043e \u0434\u043e\u043f\u0438\u0441\u0430\u0442\u044c \u0441\u0435\u0440\u0432\u0438\u0441 \u0438\u043d\u0434\u0435\u043a\u0441\u0430\u0446\u0438\u0438 \u0438 \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u043e\u0432, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0442\u0430\u043a\u0436\u0435 \u043e\u0447\u0435\u043d\u044c \u043f\u0440\u043e\u0441\u0442\u043e \u0438\u043d\u0442\u0435\u0433\u0440\u0438\u0440\u0443\u0435\u0442\u0441\u044f \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e Spring AI.package com.example.rag.service;import java.util.List;import java.util.Map;import org.springframework.ai.document.Document;import org.springframework.ai.vectorstore.VectorStore;import org.springframework.stereotype.Service;@Servicepublic class DocumentIndexingService {    private final VectorStore vectorStore;    public DocumentIndexingService(VectorStore vectorStore) {        this.vectorStore = vectorStore;    }    public void saveDocument(String content) {        Document document = new Document(content);        vectorStore.add(List.of(document));    }    public void saveDocument(String content, Map&lt;String, Object&gt; metadata) {        Document document = new Document(content, metadata);        vectorStore.add(List.of(document));    }    public void saveDocuments(List&lt;String&gt; contents) {        List&lt;Document&gt; documents = contents.stream()                .map(Document::new)                .toList();        vectorStore.add(documents);    }}\u0417\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u0438\u0435\u041c\u044b \u0441\u043e\u0431\u0440\u0430\u043b\u0438 \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u044b\u0439 RAG\u2011\u0441\u0435\u0440\u0432\u0438\u0441 \u043d\u0430 Java: Spring Boot \u0434\u0430\u0451\u0442 REST\u2011API, Spring AI \u0443\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u0442 \u043c\u043e\u0434\u0435\u043b\u044f\u043c\u0438, Qdrant \u0445\u0440\u0430\u043d\u0438\u0442 \u044d\u043c\u0431\u0435\u0434\u0434\u0438\u043d\u0433\u0438, \u0430 Ollama \u043a\u0440\u0443\u0442\u0438\u0442 Llama \u043f\u0440\u044f\u043c\u043e \u043d\u0430 \u043c\u0430\u0448\u0438\u043d\u0435. \u041f\u043e \u043f\u0443\u0442\u0438 \u043c\u044b \u043d\u0430\u0441\u0442\u0440\u043e\u0438\u043b\u0438 \u043e\u043a\u0440\u0443\u0436\u0435\u043d\u0438\u0435 \u0438\u00a0docker-compose, \u043f\u0440\u043e\u043f\u0438\u0441\u0430\u043b\u0438 \u043a\u043e\u043d\u0444\u0438\u0433 \u0432\u00a0application.yml, \u0434\u043e\u0431\u0430\u0432\u0438\u043b\u0438 \u0441\u0435\u0440\u0432\u0438\u0441\u044b \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u043e\u0432 \u0438 \u043f\u043e\u0438\u0441\u043a\u0430, \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440\u00a0\/api\/rag\/ask. \u042d\u0442\u043e\u0442 \u0441\u043a\u0435\u043b\u0435\u0442 \u0443\u0436\u0435 \u043c\u043e\u0436\u043d\u043e \u043f\u0440\u0435\u0432\u0440\u0430\u0449\u0430\u0442\u044c \u0432\u043e \u0432\u043d\u0443\u0442\u0440\u0435\u043d\u043d\u0435\u0433\u043e \u0430\u0441\u0441\u0438\u0441\u0442\u0435\u043d\u0442\u0430: \u043c\u0435\u043d\u044f\u0442\u044c \u043c\u043e\u0434\u0435\u043b\u0438, \u0432\u044b\u043d\u043e\u0441\u0438\u0442\u044c Qdrant \u0432 \u043f\u0440\u043e\u0434 \u0438 \u043d\u0430\u0432\u0435\u0448\u0438\u0432\u0430\u0442\u044c UI. \u0415\u0441\u043b\u0438 \u0431\u0443\u0434\u0435\u0442\u0435 \u0441\u043e\u0431\u0438\u0440\u0430\u0442\u044c \u0441\u0432\u043e\u044e \u0432\u0435\u0440\u0441\u0438\u044e, \u0442\u043e \u044d\u0442\u0443 \u043f\u0440\u043e\u0441\u0442\u0443\u044e \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044e \u043c\u043e\u0436\u043d\u043e \u0432\u0437\u044f\u0442\u044c \u0437\u0430 \u043e\u0441\u043d\u043e\u0432\u0443 \u0438 \u0434\u043e\u043f\u0438\u043b\u0438\u0442\u044c \u043f\u043e\u0434 \u0441\u0432\u043e\u0438 \u043d\u0443\u0436\u0434\u044b.\u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u0438 https:\/\/habr.com\/ru\/articles\/1027426\/<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[],"tags":[],"class_list":["post-477233","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/477233","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=477233"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/477233\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=477233"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=477233"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=477233"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}