Сучасні великі мовні моделі мають доступ до постійно зростаючої кількості інформації. Однак залишається величезна кількість приватних даних, які ці моделі не використовують. Ось чому одним із найпопулярніших застосувань LLM у корпоративних налаштуваннях є пошуково-доповнена генерація (скорочено RAG). на , нашої платформи аналізу даних на базі ШІ, ми отримали цінну інформацію про створення ефективних систем RAG. У цьому підручнику ми поділимося деякими з наших знань і покажемо вам, як створити власну систему RAG. Візли Ви дізнаєтеся, як використовувати LangChain, дуже популярну структуру для побудови систем RAG, щоб створити просту систему RAG. Наприкінці навчального посібника ми матимемо чат-бота (з інтерфейсом Streamlit і всім іншим), який пробиратиметься через деякі особисті дані, щоб дати відповіді на запитання. Що таке RAG? Щоб зрозуміти, що таке RAG, розглянемо простий приклад. Студент першого курсу коледжу, Чендлер, розглядає можливість пропустити кілька уроків, але хоче переконатися, що він не порушує правила відвідування університету. Як і будь-що в наші дні, він задає питання . ChatGPT Звичайно, ChatGPT не може на нього відповісти. Чат-бот не тупий — він просто не має доступу до університетських документів Чендлера. Тож Чендлер сам знаходить документ про політику та виявляє, що це довге технічне читання, яке він не хоче пробиратися. Замість цього він передає весь документ ChatGPT і знову ставить запитання. Цього разу він отримує відповідь. Це окремий випадок генерації з доповненим пошуком. Відповідь (генерація) мовної моделі доповнюється (збагачується) контекстом, отриманим із джерела, яке не є частиною її початкового навчання. Масштабована версія системи RAG зможе відповісти на будь-яке запитання студента, самостійно шукаючи університетські документи, знаходячи відповідні та витягуючи фрагменти тексту, які, швидше за все, містять відповідь. Загалом кажучи, у системі RAG ви отримуєте інформацію з приватного джерела даних і передаєте її в мовну модель, дозволяючи моделі давати релевантну контексту відповідь. Компоненти програми RAG Така система, незважаючи на те, що звучить просто, мала б багато рухомих компонентів. Перш ніж створити його самостійно, нам потрібно переглянути, що це таке та як вони грають разом. Документи Перша складова — документ або сукупність документів. Залежно від типу RAG-системи, яку ми створюємо, документами можуть бути текстові файли, PDF-файли, веб-сторінки (RAG поверх неструктурованих даних) або бази даних графіків, SQL або NoSQL (RAG поверх структурованих даних). Вони використовуються для введення різних типів даних у систему. Завантажувачі документів реалізує сотні класів, які називаються , для читання даних із різних джерел документів, таких як PDF-файли, Slack, Notion, Google Drive тощо. LangChain завантажувачами документів Кожен клас завантажувача документів є унікальним, але всі вони мають однаковий метод . Наприклад, ось як можна завантажити PDF-документ і веб-сторінку в LangChain: .load() from langchain_community.document_loaders import PyPDFLoader, WebBaseLoader # pip install langchain-community pdf_loader = PyPDFLoader("framework_docs.pdf") web_loader = WebBaseLoader( "https://python.langchain.com/v0.2/docs/concepts/#document-loaders" ) pdf_docs = pdf_loader.load() web_docs = web_loader.load() Клас PyPDFLoader обробляє PDF-файли за допомогою пакета PyPDF2 під капотом, тоді як WebBaseLoader сканує вміст заданої веб-сторінки. містить чотири об’єкти документа, по одному для кожної сторінки: pdf_docs >>> len(pdf_docs) 4 Хоча містять лише один: web_docs >>> print(web_docs[0].page_content[125:300].strip()) You can view the v0.1 docs here.IntegrationsAPI referenceLatestLegacyMorePeopleContributingCookbooks3rd party tutorialsYouTubearXivv0.2v0.2v0.1🦜️🔗LangSmithLangSmith DocsLangCh Пізніше ці об’єкти документа передаються моделям вбудовування, щоб зрозуміти семантичне значення їхнього тексту. Щоб дізнатися більше про інші типи завантажувачів документів, LangChain пропонує a . присвячена сторінка з інструкціями Розділювачі тексту Після того, як ви завантажили свої документи, дуже важливо розбити їх на менші та зручніші фрагменти тексту. Ось основні причини: Багато моделей вбудовування (більше про них пізніше) мають максимальний ліміт маркерів. Отримання точніше, якщо у вас є менші фрагменти. Мовна модель подається в точний контекст. LangChain пропонує багато типів текстових роздільників у своєму пакеті langchain_text_splitters, і вони відрізняються залежно від типу документа. Ось як використовувати для розділення звичайного тексту на основі списку роздільників і розміру блоку: RecursiveCharacterTextSplitter !pip install langchain_text_splitters from langchain_text_splitters import RecursiveCharacterTextSplitter # Example text text = """ RAG systems combine the power of large language models with external knowledge sources. This allows them to provide up-to-date and context-specific information. The process involves several steps including document loading, text splitting, and embedding. """ # Create a text splitter text_splitter = RecursiveCharacterTextSplitter( chunk_size=50, chunk_overlap=10, length_function=len, separators=["\n\n", "\n", " ", ""], ) # Split the text chunks = text_splitter.split_text(text) # Print the chunks for i, chunk in enumerate(chunks): print(f"Chunk {i + 1}: {chunk}") Вихід: Chunk 1: RAG systems combine the power of large language Chunk 2: language models with external knowledge sources. Chunk 3: This allows them to provide up-to-date and Chunk 4: and context-specific information. Chunk 5: The process involves several steps including Chunk 6: including document loading, text splitting, and Chunk 7: and embedding. Цей розгалужувач є універсальним і добре працює в багатьох випадках використання. Він створює кожен блок із кількістю символів, максимально наближеною до . Він може рекурсивно перемикатися між роздільниками, на які потрібно розділити, щоб зберегти кількість символів. chunk_size У наведеному вище прикладі наш роздільник намагається спочатку розділити на символи нового рядка, потім на пробіли, а нарешті між будь-якими символами, щоб досягти бажаного розміру фрагмента. У пакеті є багато інших роздільників. Ось деякі з них: langchain_text_splitters HTMLSectionSplitter PythonCodeTexSplitter RecursiveJsonSplitter і так далі. Деякі з розгалужувачів створюють семантично значущі фрагменти за допомогою моделі трансформатора під капотом. Правильний роздільник тексту значно впливає на продуктивність системи RAG. Докладніше про те, як використовувати роздільники тексту, див . інструкції тут Вбудовування моделей Коли документи розділені на текст, їх потрібно закодувати в числове представлення, що є вимогою для всіх моделей обчислень, що працюють з текстовими даними. У контексті RAG таке кодування називається і виконується . Вони створюють векторне представлення фрагмента тексту, яке фіксує їх семантичне значення. Представляючи текст таким чином, ви можете виконувати з ним математичні операції, наприклад шукати в нашій базі даних документів текст, найбільш схожий за значенням, або знаходити відповідь на запит користувача. вбудовуванням моделями вбудовування LangChain підтримує всіх основних постачальників моделей вбудовування, таких як OpenAI, Cohere, HuggingFace тощо. Вони реалізовані як класи та надають два методи: один для вбудовування документів і один для вбудовування запитів (підказок). Embedding Ось приклад коду, який вбудовує фрагменти тексту, які ми створили в попередньому розділі за допомогою OpenAI: from langchain_openai import OpenAIEmbeddings # Initialize the OpenAI embeddings embeddings = OpenAIEmbeddings() # Embed the chunks embedded_chunks = embeddings.embed_documents(chunks) # Print the first embedded chunk to see its structure print(f"Shape of the first embedded chunk: {len(embedded_chunks[0])}") print(f"First few values of the first embedded chunk: {embedded_chunks[0][:5]}") Вихід: Shape of the first embedded chunk: 1536 First few values of the first embedded chunk: [-0.020282309502363205, -0.0015041005099192262, 0.004193042870610952, 0.00229285703971982, 0.007068077567964792] Вихідні дані вище показують, що модель вбудовування створює 1536-вимірний вектор для всіх блоків у наших документах. Щоб вставити один запит, ви можете використати метод : embed_query() query = "What is RAG?" query_embedding = embeddings.embed_query(query) print(f"Shape of the query embedding: {len(query_embedding)}") print(f"First few values of the query embedding: {query_embedding[:5]}") Вихід: Shape of the query embedding: 1536 First few values of the query embedding: [-0.012426204979419708, -0.016619959846138954, 0.007880032062530518, -0.0170428603887558, 0.011404196731746197] Векторні магазини У великомасштабних додатках RAG, де у вас можуть бути гігабайти документів, ви отримаєте величезну кількість текстових блоків і, отже, векторів. Від них немає користі, якщо ви не можете їх надійно зберігати. Ось чому зараз у моді. Окрім зберігання ваших вставок, векторні бази даних піклуються про виконання векторного пошуку за вас. Ці бази даних оптимізовано для швидкого пошуку найбільш схожих векторів, якщо їм надано вектор запиту, що важливо для отримання відповідної інформації в системах RAG. векторні сховища чи бази даних Ось фрагмент коду, який вбудовує вміст веб-сторінки та зберігає вектори в векторній базі даних Chroma ( , яке повністю працює на вашому комп’ютері): Chroma — це рішення векторної бази даних із відкритим кодом !pip install chromadb langchain_chroma from langchain_community.document_loaders import WebBaseLoader from langchain_text_splitters import RecursiveCharacterTextSplitter # Load the web page loader = WebBaseLoader("https://python.langchain.com/v0.2/docs/tutorials/rag/") docs = loader.load() # Split the documents into chunks text_splitter = RecursiveCharacterTextSplitter(chunk_size=1000, chunk_overlap=200) chunks = text_splitter.split_documents(docs) Спочатку ми завантажуємо сторінку за допомогою і створюємо фрагменти. Потім ми можемо безпосередньо передати фрагменти в метод разом із обраною моделлю вбудовування: WebBaseLoader from_documents Chroma from langchain_openai import OpenAIEmbeddings from langchain_chroma import Chroma db = Chroma.from_documents(chunks, OpenAIEmbeddings()) Усі об’єкти векторної бази даних у LangChain надають метод , який приймає рядок запиту: similarity_search query = "What is indexing in the context of RAG?" docs = db.similarity_search(query) print(docs[1].page_content) Вихід: If you are interested for RAG over structured data, check out our tutorial on doing question/answering over SQL data.ConceptsA typical RAG application has two main components:Indexing: a pipeline for ingesting data from a source and indexing it. This usually happens offline.Retrieval and generation: the actual RAG chain, which takes the user query at run time and retrieves the relevant data from the index, then passes that to the model.The most common full sequence from raw data to answer looks like:IndexingLoad: First we need to load our data. This is done with Document Loaders.Split: Text splitters break large Documents into smaller chunks. This is useful both for indexing data and for passing it in to a model, since large chunks are harder to search over and won't fit in a model's finite context window.Store: We need somewhere to store and index our splits, so that they can later be searched over. This is often done using a VectorStore and Embeddings model.Retrieval and Результатом є список документів, які, швидше за все, містять інформацію, яку ми запитуємо в запиті. similarity_search Докладніше про використання векторних сховищ див . інструкції тут Ретривери Хоча всі векторні сховища підтримують пошук у формі пошуку подібності, LangChain реалізує спеціальний інтерфейс , який повертає документи за неструктурованим запитом. Ретриверу потрібно лише повертати або витягувати документи, а не зберігати їх. Retriever Ось як ви можете перетворити будь-який векторний магазин на ретривер у LangChain: # Convert the vector store to a retriever chroma_retriever = db.as_retriever() docs = chroma_retriever.invoke("What is indexing in the context of RAG?") >>> len(docs) 4 Можна обмежити кількість релевантних документів до top за допомогою : k search_kwargs chroma_retriever = db.as_retriever(search_kwargs={"k": 1}) docs = chroma_retriever.invoke("What is indexing in the context of RAG?") >>> len(docs) 1 Ви можете передати інші параметри, пов’язані з пошуком, у search_kwargs. Дізнайтеся більше про використання ретриверів з . конкретні інструкції Покроковий робочий процес для створення програми RAG у LangChain Тепер, коли ми розглянули ключові компоненти системи RAG, ми створимо її самостійно. Я проведу вас через крок за кроком впровадження чат-бота RAG, розробленого спеціально для документації коду та навчальних посібників. Ви знайдете це особливо корисним, коли вам потрібна допомога в кодуванні ШІ для нових фреймворків або нових функцій існуючих фреймворків, які ще не є частиною бази знань сучасних LLM. 0. Створення структури проекту Спочатку заповніть свій робочий каталог такою структурою проекту: rag-chatbot/ ├── .gitignore ├── requirements.txt ├── README.md ├── app.py ├── src/ │ ├── __init__.py │ ├── document_processor.py │ └── rag_chain.py └── .streamlit/ └── config.toml Ось команди: $ touch .gitignore requirements.txt README.md app.py $ mkdir src .streamlit $ touch src/{.env,__init__.py,document_processor.py,rag_chain.py} $ touch .streamlit/{.env,config.toml} 1. Налаштування середовища На цьому кроці ви спочатку створюєте нове середовище Conda та активуєте його: $ conda create -n rag_tutorial python=3.9 -y $ conda activate rag_tutorial Далі відкрийте файл і вставте такі залежності: requirements.txt langchain==0.2.14 langchain_community==0.2.12 langchain_core==0.2.35 langchain_openai==0.1.22 python-dotenv==1.0.1 streamlit==1.37.1 faiss-cpu pypdf і встановити їх: $ pip install -r requirements.txt Також створіть файл , щоб приховати файли від індексування git: .gitignore # .gitignore venv/ __pycache__/ .env *.pdf *.png *.jpg *.jpeg *.gif *.svg 2. Налаштування завантажувачів документів Далі відкрийте файл і вставте наступні фрагменти коду. src/document_processor.py Необхідний імпорт: import logging from langchain.text_splitter import RecursiveCharacterTextSplitter from langchain.text_splitter import Language from langchain_community.document_loaders import PyPDFLoader from langchain_community.document_loaders.parsers.pdf import ( extract_from_images_with_rapidocr, ) from langchain.schema import Document Пояснення щодо імпорту: : рекурсивно розділяє текст на менші фрагменти. RecursiveCharacterTextSplitter : Enum для визначення мов програмування в розділенні тексту. Language : завантажує та витягує текст із файлів PDF. PyPDFLoader : функція OCR для вилучення тексту із зображень. extract_from_images_with_rapidocr : представляє документ із вмістом і метаданими. Document : надає функцію журналювання для налагодження та інформації. logging Потім функція для обробки PDF-файлів: def process_pdf(source): loader = PyPDFLoader(source) documents = loader.load() # Filter out scanned pages unscanned_documents = [doc for doc in documents if doc.page_content.strip() != ""] scanned_pages = len(documents) - len(unscanned_documents) if scanned_pages > 0: logging.info(f"Omitted {scanned_pages} scanned page(s) from the PDF.") if not unscanned_documents: raise ValueError( "All pages in the PDF appear to be scanned. Please use a PDF with text content." ) return split_documents(unscanned_documents) Ось як це працює: Він завантажує PDF за допомогою . PyPDFLoader Він фільтрує відскановані сторінки, видаляючи документи з порожнім вмістом. Він реєструє кількість пропущених відсканованих сторінок, якщо такі є. Якщо скануються всі сторінки (тобто немає текстового вмісту), виникає помилка ValueError. Нарешті, він розбиває решту несканованих документів на менші частини за допомогою функції split_documents. Ця функція обробляє випадки, коли PDF-файл може містити суміш тексту та відсканованих сторінок, забезпечуючи подальшу обробку лише текстових сторінок. Це має вирішальне значення для завдань аналізу тексту, коли відскановані сторінки без OCR були б непридатними. Ми визначимо функцію пізніше. split_documents Далі ми пишемо функцію для отримання інформації із зображень (скріншотів фрагментів коду та/або веб-сторінок): def process_image(source): # Extract text from image using OCR with open(source, "rb") as image_file: image_bytes = image_file.read() extracted_text = extract_from_images_with_rapidocr([image_bytes]) documents = [Document(page_content=extracted_text, metadata={"source": source})] return split_documents(documents) Ця функція обробляє файл зображення шляхом вилучення тексту за допомогою OCR (оптичне розпізнавання символів). Він зчитує файл зображення, перетворює його на байти, а потім використовує бібліотеку RapidOCR для вилучення тексту із зображення. Потім витягнутий текст загортається в об’єкт Document із метаданими, що містять шлях до вихідного файлу. Нарешті, функція розбиває документ на менші фрагменти за допомогою функції , яку ми визначаємо далі: split_documents def split_documents(documents): # Split documents into smaller chunks for processing text_splitter = RecursiveCharacterTextSplitter.from_language( language=Language.PYTHON, chunk_size=1000, chunk_overlap=200 ) return text_splitter.split_documents(documents) Функція використовує клас RecursiveCharacterTextSplitter із синтаксисом Python, щоб розділити текст на фрагменти по 1000 символів із перекриттям 200 символів. Наша остання функція об’єднує функції аналізатора PDF і зображень в одну: def process_document(source): # Determine file type and process accordingly if source.lower().endswith(".pdf"): return process_pdf(source) elif source.lower().endswith((".png", ".jpg", ".jpeg")): return process_image(source) else: raise ValueError(f"Unsupported file type: {source}") Ця остання функція використовуватиметься інтерфейсом користувача Streamlit для створення, вбудовування та зберігання фрагментів із наданих документів і передачі їх у компонент RAG нашої системи. 3. Налаштування RAG Тепер відкрийте файл і вставте наступні фрагменти коду. src/rag_chain.py Спочатку імпортуйте необхідні модулі: import os from dotenv import load_dotenv from langchain.prompts import PromptTemplate from langchain_community.vectorstores import FAISS from langchain_core.output_parsers import StrOutputParser from langchain_core.runnables import RunnablePassthrough from langchain_openai import ChatOpenAI, OpenAIEmbeddings # Load the API key from env variables load_dotenv() api_key = os.getenv("OPENAI_API_KEY") Ось пояснення щодо імпорту: • : взаємодія операційної системи • : завантаження змінних середовища • компоненти : os dotenv langchain : створення спеціального підказки PromptTemplate : легке векторне сховище документів FAISS : Перетворення об’єктів повідомлень LLM у вихідні рядки StrOutputParser : створюйте складні ланцюжки RunnablePassthrough , : взаємодія моделі OpenAI ChatOpenAI OpenAIEmbeddings Далі ми створюємо наш запит для системи RAG: RAG_PROMPT_TEMPLATE = """ You are a helpful coding assistant that can answer questions about the provided context. The context is usually a PDF document or an image (screenshot) of a code file. Augment your answers with code snippets from the context if necessary. If you don't know the answer, say you don't know. Context: {context} Question: {question} """ PROMPT = PromptTemplate.from_template(RAG_PROMPT_TEMPLATE) Підказка системи RAG є одним з найважливіших факторів її успіху. Наша версія проста, але більшу частину часу виконає роботу. На практиці ви витратите багато часу на ітерацію та вдосконалення підказки. Якщо ви помітили, ми використовуємо клас для створення підказки. Ця конструкція дозволяє нам динамічно вводити контекст, отриманий із документів і запиту користувача, у кінцеву підказку. PromptTemplate Говорячи про документи, нам потрібна функція для їх форматування перед тим, як вони будуть передані як контекст у системну підказку: def format_docs(docs): return "\n\n".join(doc.page_content for doc in docs) Це проста функція, яка об’єднує вміст сторінки отриманих документів. Нарешті, ми створюємо функцію, яка розвиватиме наш ланцюжок RAG: def create_rag_chain(chunks): embeddings = OpenAIEmbeddings(api_key=api_key) doc_search = FAISS.from_documents(chunks, embeddings) retriever = doc_search.as_retriever( search_type="similarity", search_kwargs={"k": 5} ) llm = ChatOpenAI(model_name="gpt-4o-mini", temperature=0) rag_chain = ( {"context": retriever | format_docs, "question": RunnablePassthrough()} | PROMPT | llm | StrOutputParser() ) return rag_chain Функція приймає фрагменти документів, які надає функція у сценарії . process_document document_processor.py Функція починається з визначення моделі вбудовування та збереження документів у векторному сховищі FAISS. Потім він перетворюється на інтерфейс пошуку за схожістю, який повертає перші п’ять документів, які відповідають запиту користувача. Для мовної моделі ми будемо використовувати але ви можете використовувати інші моделі, наприклад GPT-4o, залежно від вашого бюджету та потреб. gpt-4o-mini Потім ми об’єднаємо всі ці компоненти за допомогою мови виразів LangChain (LCEL). Першим компонентом ланцюжка є словник із і як ключі. Значення цих ключів надаються ретрівером, відформатованим нашою функцією форматування та відповідно. Останній клас діє як заповнювач для запиту користувача. context question RunnablePassthrough() Потім словник передається в підказку нашої системи; підказка передається в LLM, який генерує вихідний клас повідомлення. Клас повідомлення надається синтаксичному аналізатору виведення рядка, який повертає відповідь у вигляді звичайного тексту. 4. Створення інтерфейсу Streamlit У цьому розділі ми створимо наведений нижче інтерфейс користувача для нашої програми: Це чистий, мінімальний інтерфейс із двома полями введення: одне для документа, інше для постановки запитань щодо документа. На лівій бічній панелі користувачеві пропонується ввести свій ключ API. Щоб створити інтерфейс, відкрийте сценарій на найвищому рівні вашого робочого каталогу та вставте наступний код: app.py import streamlit as st import os from dotenv import load_dotenv from src.document_processor import process_document from src.rag_chain import create_rag_chain # Load environment variables load_dotenv() st.set_page_config(page_title="RAG Chatbot", page_icon="🤖") st.title("RAG Chatbot") # Initialize session state if "rag_chain" not in st.session_state: st.session_state.rag_chain = None # Sidebar for API key input with st.sidebar: api_key = st.text_input("Enter your OpenAI API Key", type="password") if api_key: os.environ["OPENAI_API_KEY"] = api_key # File uploader uploaded_file = st.file_uploader("Choose a file", type=["pdf", "png", "jpg", "jpeg"]) if uploaded_file is not None: if st.button("Process File"): if api_key: with st.spinner("Processing file..."): # Save the uploaded file temporarily with open(uploaded_file.name, "wb") as f: f.write(uploaded_file.getbuffer()) try: # Process the document chunks = process_document(uploaded_file.name) # Create RAG chain st.session_state.rag_chain = create_rag_chain(chunks) st.success("File processed successfully!") except ValueError as e: st.error(str(e)) finally: # Remove the temporary file os.remove(uploaded_file.name) else: st.error("Please provide your OpenAI API key.") # Query input query = st.text_input("Ask a question about the uploaded document") if st.button("Ask"): if st.session_state.rag_chain and query: with st.spinner("Generating answer..."): result = st.session_state.rag_chain.invoke(query) st.subheader("Answer:") st.write(result) elif not st.session_state.rag_chain: st.error("Please upload and process a file first.") else: st.error("Please enter a question.") Незважаючи на те, що він містить лише 65 рядків, він реалізує такі функції: Введення ключа API: дозволяє користувачам безпечно вводити ключ OpenAI API. Завантаження файлів: підтримує завантаження файлів PDF, PNG, JPG і JPEG. Обробка документів: обробляє завантажений файл і створює фрагменти тексту. Створення ланцюжка RAG: будує ланцюжок генерації з доповненим пошуком, використовуючи фрагменти обробленого документа. Обробка запитів: приймає запитання користувачів щодо завантаженого документа. Генерація відповідей: використовує ланцюжок RAG для створення відповідей на основі завантаженого документа та запиту користувача. Обробка помилок: надає відповідні повідомлення про помилки для відсутніх ключів API, необроблених файлів або порожніх запитів. Відгуки користувачів: відображаються лічильники під час обробки та повідомлення про успіх/помилку, щоб тримати користувача в курсі. Керування станом: використовує стан сеансу Streamlit для підтримки ланцюга RAG між взаємодіями. 5. Розгортання як чат-бота Streamlit Залишився лише один крок — розгорнути наш додаток Streamlit. Тут є багато варіантів, але найпростішим є використання Streamlit Cloud, яке є безкоштовним і простим у налаштуванні. Спочатку відкрийте сценарій і вставте такі конфігурації: .streamlit/config.toml [theme] primaryColor = "#F63366" backgroundColor = "#FFFFFF" secondaryBackgroundColor = "#F0F2F6" textColor = "#262730" font = "sans serif" Це деякі коригування теми, які випливають з особистих уподобань. Потім запишіть файл README.md (ви можете скопіювати його вміст із ). цього розміщеного файлу на GitHub Нарешті, перейдіть на і створіть нове сховище. Скопіюйте його посилання та поверніться до робочого каталогу: GitHub.com $ git init $ git add . $ git commit -m "Initial commit" $ git remote add origin https://github.com/YourUsername/YourRepo.git $ git push --set-upstream origin master Наведені вище команди ініціалізують Git, створюють початковий комміт і надсилають усе до репозиторію (не забудьте замінити посилання репо своїм власним). Тепер вам потрібно зареєструвати безкоштовний обліковий запис у . Підключіть свій обліковий запис GitHub і виберіть репозиторій, що містить вашу програму. Streamlit Cloud Потім налаштуйте параметри програми: Встановіть версію Python (наприклад, 3.9) Встановіть основний шлях до файлу app.py Додайте будь-які необхідні секрети (наприклад ) у налаштуваннях програми OPENAI_API_KEY Нарешті натисніть «Розгорнути»! Додаток має запрацювати протягом кількох хвилин. Програму, яку я створив для цього підручника, можна знайти за . Спробуйте! цим посиланням Висновок У цьому підручнику розглядається потужне поєднання Retrieval-Augmented Generation (RAG) і Streamlit, яке формує інтерактивну систему відповідей на запитання на основі документів. Він проводить читача через увесь процес, від налаштування середовища й обробки документів до побудови ланцюжка RAG і розгортання зручної веб-програми. Важливі моменти: RAG для розумнішої (у сенсі зовнішніх знань) мовної моделі Ланцюги RAG можна створювати за допомогою моделей LangChain, OpenAI та сторонніх інтеграцій спільноти. Додаток можна зробити інтерактивним за допомогою Streamlit і розгорнути для загального використання. Цей проект є основою для більш просунутих програм. Його можна розширити значною мірою, наприклад, об’єднати декілька типів документів, покращити точність пошуку та такі функції, як резюмування документів. І все-таки він насправді служить для демонстрації потенційної потужності цих технологій, як окремо, так і разом.