Evolusi pesat model AI generatif seperti OpenAI's ChatGPT telah merevolusikan pemprosesan bahasa semula jadi, membolehkan sistem ini menjana tindak balas yang koheren dan berkaitan kontekstual. Walau bagaimanapun, walaupun model terkini menghadapi had apabila menangani pertanyaan khusus domain atau memberikan maklumat yang sangat tepat. Ini selalunya membawa kepada cabaran seperti halusinasi — contoh di mana model menghasilkan butiran yang tidak tepat atau rekaan.
Retrieval-Augmented Generation (RAG), rangka kerja inovatif yang direka untuk merapatkan jurang ini. Dengan menyepadukan sumber data luaran dengan lancar, RAG memperkasakan model generatif untuk mendapatkan maklumat masa nyata, khusus, meningkatkan ketepatan dan kebolehpercayaan dengan ketara.
Dalam artikel ini, kita akan menyelami mekanik RAG, meneroka seni binanya dan membincangkan batasan model generatif tradisional yang memberi inspirasi kepada penciptaannya. Kami juga akan menyerlahkan pelaksanaan praktikal, teknik lanjutan dan kaedah penilaian, mempamerkan cara RAG mengubah cara AI berinteraksi dengan data khusus.
Retrieval-Augmented Generation (RAG) ialah rangka kerja lanjutan yang meningkatkan keupayaan model AI generatif dengan menyepadukan pengambilan semula masa nyata data luaran. Walaupun model generatif cemerlang dalam menghasilkan teks seperti manusia yang koheren, mereka boleh goyah apabila diminta memberikan maklumat yang tepat, terkini atau khusus domain. Di sinilah RAG melangkah masuk, memastikan bahawa respons bukan sahaja kreatif tetapi juga berasaskan sumber yang boleh dipercayai dan berkaitan.
RAG beroperasi dengan menyambungkan model generatif dengan mekanisme perolehan semula, biasanya dikuasakan oleh pangkalan data vektor atau sistem carian. Apabila pertanyaan diterima, komponen perolehan mencari melalui set data luaran yang luas untuk mendapatkan maklumat yang berkaitan. Model generatif kemudiannya mensintesis data ini, menghasilkan output yang tepat dan berwawasan kontekstual.
Dengan menangani cabaran utama seperti halusinasi dan pengetahuan domain terhad, RAG membuka potensi model generatif untuk cemerlang dalam bidang khusus. Aplikasinya merangkumi pelbagai industri, daripada mengautomasikan sokongan pelanggan dengan jawapan yang tepat, membolehkan penyelidik mengakses pengetahuan yang dipilih susun atas permintaan. RAG mewakili satu langkah ke hadapan yang penting dalam menjadikan sistem AI lebih pintar, boleh dipercayai dan berguna dalam senario dunia sebenar.
Pemahaman yang jelas tentang seni bina RAG adalah penting untuk membuka kunci potensi dan faedah penuhnya. Pada terasnya, rangka kerja ini dibina pada dua komponen utama: Retriever dan Generator, bekerja bersama dalam aliran pemprosesan maklumat yang lancar.
Proses keseluruhan ini digambarkan di bawah:
sumber: https://weaviate.io/blog/introduction-to-rag
Semua peringkat dan komponen penting aliran proses RAG, digambarkan dalam rajah di bawah.
sumber: https://www.griddynamics.com/blog/retrieval-augmented-generation-llm
Membahagikan dokumen kepada bahagian yang lebih kecil mungkin kelihatan mudah, tetapi ia memerlukan pertimbangan semantik yang teliti untuk mengelakkan pembahagian ayat secara tidak wajar, yang boleh menjejaskan langkah seterusnya seperti menjawab soalan. Pendekatan chunking bersaiz tetap yang naif boleh mengakibatkan maklumat tidak lengkap dalam setiap bongkah. Kebanyakan algoritma pembahagian dokumen menggunakan saiz bongkah dan bertindih, dengan saiz bongkah ditentukan oleh aksara, perkataan atau kiraan token, dan bertindih memastikan kesinambungan dengan berkongsi teks antara bongkah bersebelahan. Strategi ini mengekalkan konteks semantik merentas bahagian.
sumber: https://www.griddynamics.com/blog/retrieval-augmented-generation-llm
Beberapa pangkalan data vektor yang penting ialah:
sumber: https://www.griddynamics.com/blog/retrieval-augmented-generation-llm
RAG (Retrieval-Augmented Generation) dan penalaan halus ialah dua kaedah utama untuk melanjutkan keupayaan LLM, setiap satunya sesuai dengan senario yang berbeza. Penalaan halus melibatkan latihan semula LLM pada data khusus domain untuk melaksanakan tugas khusus, sesuai untuk kes penggunaan statik dan sempit seperti penjenamaan atau penulisan kreatif yang memerlukan nada atau gaya tertentu. Walau bagaimanapun, ia mahal, memakan masa dan tidak sesuai untuk data dinamik yang kerap dikemas kini.
Sebaliknya, RAG meningkatkan LLM dengan mendapatkan semula data luaran secara dinamik tanpa mengubah suai berat model, menjadikannya kos efektif dan sesuai untuk persekitaran terdorong data masa nyata seperti undang-undang, kewangan atau aplikasi perkhidmatan pelanggan. RAG membolehkan LLM mengendalikan korpora dokumen dalaman yang besar dan tidak berstruktur, menawarkan kelebihan ketara berbanding kaedah tradisional untuk menavigasi repositori data yang tidak kemas.
Penalaan halus cemerlang dalam menghasilkan keluaran yang bernuansa dan konsisten manakala RAG menyediakan maklumat yang terkini dan tepat dengan memanfaatkan pangkalan pengetahuan luaran. Dalam amalan, RAG selalunya menjadi pilihan pilihan untuk aplikasi yang memerlukan respons masa nyata yang boleh disesuaikan, terutamanya dalam perusahaan yang menguruskan data yang luas dan tidak berstruktur.
Terdapat beberapa jenis pendekatan Retrieval-Augmented Generation (RAG), setiap satu disesuaikan dengan kes penggunaan dan objektif tertentu. Jenis utama termasuk:
sumber: https://x.com/weaviate_io/status/1866528335884325070
Rangka kerja Retrieval-Augmented Generation (RAG) mempunyai pelbagai aplikasi merentas pelbagai industri kerana keupayaannya untuk menyepadukan pengetahuan luaran secara dinamik ke dalam model bahasa generatif. Berikut ialah beberapa aplikasi yang menonjol:
Dalam bahagian ini, kami akan membangunkan aplikasi strim yang mampu memahami kandungan PDF dan menjawab pertanyaan pengguna berdasarkan kandungan tersebut menggunakan Retrieval-Augmented Generation (RAG). Pelaksanaan itu memanfaatkan platform LangChain untuk memudahkan interaksi dengan LLM dan kedai vektor. Kami akan menggunakan LLM OpenAI dan model benamnya untuk membina stor vektor FAISS untuk mendapatkan maklumat yang cekap.
python -m venv venv source venv/bin/activate #for ubuntu venv/Scripts/activate #for windows
pip install langchain langchain_community openai faiss-cpu PyPDF2 streamlit python-dotenv tiktoken
OPENAI_API_KEY=sk-proj-xcQxBf5LslO62At... OPENAI_MODEL_NAME=gpt-3.5-turbo OPENAI_EMBEDDING_MODEL_NAME=text-embedding-3-small
from dotenv import load_dotenv import os load_dotenv() OPENAI_API_KEY = os.getenv("OPENAI_API_KEY") OPENAI_MODEL_NAME = os.getenv("OPENAI_MODEL_NAME") OPENAI_EMBEDDING_MODEL_NAME = os.getenv("OPENAI_EMBEDDING_MODEL_NAME")
Import perpustakaan penting untuk membina apl, mengendalikan PDF seperti langchain, streamlit, pyPDF.
import streamlit as st from PyPDF2 import PdfReader from langchain.text_splitter import CharacterTextSplitter from langchain.prompts import PromptTemplate from langchain_community.embeddings import OpenAIEmbeddings from langchain_community.vectorstores import FAISS from langchain.memory import ConversationBufferMemory from langchain.chains import ConversationalRetrievalChain from langchain_community.chat_models import ChatOpenAI from htmlTemplates import bot_template, user_template, css
def get_pdf_text(pdf_files): text = "" for pdf_file in pdf_files: reader = PdfReader(pdf_file) for page in reader.pages: text += page.extract_text() return text
Bahagikan teks besar kepada ketulan yang lebih kecil dan boleh diurus menggunakan CharacterTextSplitter LangChain.
def get_chunk_text(text): text_splitter = CharacterTextSplitter( separator="\n", chunk_size=1000, chunk_overlap=200, length_function=len ) chunks = text_splitter.split_text(text) return chunks
Janakan pembenaman untuk ketulan teks dan simpannya dalam pangkalan data vektor menggunakan FAISS.
def get_vector_store(text_chunks): embeddings = OpenAIEmbeddings(openai_api_key=OPENAI_API_KEY, model=OPENAI_EMBEDDING_MODEL_NAME) vectorstore = FAISS.from_texts(texts=text_chunks, embedding=embeddings) return vectorstore
Tentukan rantaian yang mendapatkan semula maklumat daripada stor vektor dan berinteraksi dengan pengguna melalui LLM.
def get_conversation_chain(vector_store): llm = ChatOpenAI(openai_api_key=OPENAI_API_KEY, model_name=OPENAI_MODEL_NAME, temperature=0) memory = ConversationBufferMemory(memory_key='chat_history', return_messages=True) system_template = """ Use the following pieces of context and chat history to answer the question at the end. If you don't know the answer, just say that you don't know, don't try to make up an answer. Context: {context} Chat history: {chat_history} Question: {question} Helpful Answer: """ prompt = PromptTemplate( template=system_template, input_variables=["context", "question", "chat_history"], ) conversation_chain = ConversationalRetrievalChain.from_llm( verbose = True, llm=llm, retriever=vector_store.as_retriever(), memory=memory, combine_docs_chain_kwargs={"prompt": prompt} ) return conversation_chain
Proses input pengguna, hantarkannya ke rantai perbualan dan kemas kini sejarah sembang.
def handle_user_input(question): try: response = st.session_state.conversation({'question': question}) st.session_state.chat_history = response['chat_history'] except Exception as e: st.error('Please select PDF and click on Process.')
Untuk mencipta antara muka sembang tersuai untuk kedua-dua mesej pengguna dan bot menggunakan CSS, reka templat tersuai dan gayakannya dengan CSS.
css = ''' <style> .chat-message { padding: 1rem; border-radius: 0.5rem; margin-bottom: 1rem; display: flex } .chat-message.user { background-color: #2b313e } .chat-message.bot { background-color: #475063 } .chat-message .avatar { width: 10%; } .chat-message .avatar img { max-width: 30px; max-height: 30px; border-radius: 50%; object-fit: cover; } .chat-message .message { width: 90%; padding: 0 1rem; color: #fff; } ''' bot_template = ''' <div> <h3> Displaying chat history </h3> <p>Show the user and AI conversation history in a reverse order with HTML templates for formatting.<br> </p> <pre class="brush:php;toolbar:false">def display_chat_history(): if st.session_state.chat_history: reversed_history = st.session_state.chat_history[::-1] formatted_history = [] for i in range(0, len(reversed_history), 2): chat_pair = { "AIMessage": reversed_history[i].content, "HumanMessage": reversed_history[i + 1].content } formatted_history.append(chat_pair) for i, message in enumerate(formatted_history): st.write(user_template.replace("{{MSG}}", message['HumanMessage']), unsafe_allow_html=True) st.write(bot_template.replace("{{MSG}}", message['AIMessage']), unsafe_allow_html=True)
Sediakan antara muka apl utama untuk muat naik fail, input soalan dan paparan sejarah sembang.
def main(): st.set_page_config(page_title='Chat with PDFs', page_icon=':books:') st.write(css, unsafe_allow_html=True) if "conversation" not in st.session_state: st.session_state.conversation = None if "chat_history" not in st.session_state: st.session_state.chat_history = None st.header('Chat with PDFs :books:') question = st.text_input("Ask anything to your PDF:") if question: handle_user_input(question) if st.session_state.chat_history is not None: display_chat_history() with st.sidebar: st.subheader("Upload your Documents Here: ") pdf_files = st.file_uploader("Choose your PDF Files and Press Process button", type=['pdf'], accept_multiple_files=True) if pdf_files and st.button("Process"): with st.spinner("Processing your PDFs..."): try: # Get PDF Text raw_text = get_pdf_text(pdf_files) # Get Text Chunks text_chunks = get_chunk_text(raw_text) # Create Vector Store vector_store = get_vector_store(text_chunks) st.success("Your PDFs have been processed successfully. You can ask questions now.") # Create conversation chain st.session_state.conversation = get_conversation_chain(vector_store) except Exception as e: st.error(f"An error occurred: {e}") if __name__ == '__main__': main()
Berikut ialah pelaksanaan kod lengkap untuk Aplikasi Sembang PDF. Ia menyepadukan persediaan pembolehubah persekitaran, pengekstrakan teks, storan vektor dan ciri RAG ke dalam penyelesaian yang diperkemas:
from dotenv import load_dotenv import os load_dotenv() OPENAI_API_KEY = os.getenv("OPENAI_API_KEY") OPENAI_MODEL_NAME = os.getenv("OPENAI_MODEL_NAME") OPENAI_EMBEDDING_MODEL_NAME = os.getenv("OPENAI_EMBEDDING_MODEL_NAME") import streamlit as st from PyPDF2 import PdfReader from langchain.text_splitter import CharacterTextSplitter from langchain.prompts import PromptTemplate from langchain_community.embeddings import OpenAIEmbeddings from langchain_community.vectorstores import FAISS from langchain.memory import ConversationBufferMemory from langchain.chains import ConversationalRetrievalChain from langchain_community.chat_models import ChatOpenAI from htmlTemplates import bot_template, user_template, css def get_pdf_text(pdf_files): text = "" for pdf_file in pdf_files: reader = PdfReader(pdf_file) for page in reader.pages: text += page.extract_text() return text def get_chunk_text(text): text_splitter = CharacterTextSplitter( separator="\n", chunk_size=1000, chunk_overlap=200, length_function=len ) chunks = text_splitter.split_text(text) return chunks def get_vector_store(text_chunks): embeddings = OpenAIEmbeddings(openai_api_key=OPENAI_API_KEY, model=OPENAI_EMBEDDING_MODEL_NAME) vectorstore = FAISS.from_texts(texts=text_chunks, embedding=embeddings) return vectorstore def get_conversation_chain(vector_store): llm = ChatOpenAI(openai_api_key=OPENAI_API_KEY, model_name=OPENAI_MODEL_NAME, temperature=0) memory = ConversationBufferMemory(memory_key='chat_history', return_messages=True) system_template = """ Use the following pieces of context and chat history to answer the question at the end. If you don't know the answer, just say that you don't know, don't try to make up an answer. Context: {context} Chat history: {chat_history} Question: {question} Helpful Answer: """ prompt = PromptTemplate( template=system_template, input_variables=["context", "question", "chat_history"], ) conversation_chain = ConversationalRetrievalChain.from_llm( verbose = True, llm=llm, retriever=vector_store.as_retriever(), memory=memory, combine_docs_chain_kwargs={"prompt": prompt} ) return conversation_chain def handle_user_input(question): try: response = st.session_state.conversation({'question': question}) st.session_state.chat_history = response['chat_history'] except Exception as e: st.error('Please select PDF and click on OK.') def display_chat_history(): if st.session_state.chat_history: reversed_history = st.session_state.chat_history[::-1] formatted_history = [] for i in range(0, len(reversed_history), 2): chat_pair = { "AIMessage": reversed_history[i].content, "HumanMessage": reversed_history[i + 1].content } formatted_history.append(chat_pair) for i, message in enumerate(formatted_history): st.write(user_template.replace("{{MSG}}", message['HumanMessage']), unsafe_allow_html=True) st.write(bot_template.replace("{{MSG}}", message['AIMessage']), unsafe_allow_html=True) def main(): st.set_page_config(page_title='Chat with PDFs', page_icon=':books:') st.write(css, unsafe_allow_html=True) if "conversation" not in st.session_state: st.session_state.conversation = None if "chat_history" not in st.session_state: st.session_state.chat_history = None st.header('Chat with PDFs :books:') question = st.text_input("Ask anything to your PDF:") if question: handle_user_input(question) if st.session_state.chat_history is not None: display_chat_history() with st.sidebar: st.subheader("Upload your Documents Here: ") pdf_files = st.file_uploader("Choose your PDF Files and Press Process button", type=['pdf'], accept_multiple_files=True) if pdf_files and st.button("Process"): with st.spinner("Processing your PDFs..."): try: # Get PDF Text raw_text = get_pdf_text(pdf_files) # Get Text Chunks text_chunks = get_chunk_text(raw_text) # Create Vector Store vector_store = get_vector_store(text_chunks) st.success("Your PDFs have been processed successfully. You can ask questions now.") # Create conversation chain st.session_state.conversation = get_conversation_chain(vector_store) except Exception as e: st.error(f"An error occurred: {e}") if __name__ == '__main__': main()
Laksanakan apl dengan Streamlit menggunakan arahan berikut.
streamlit run app.py
Anda akan mendapat output seperti berikut,
Terima kasih kerana membaca artikel ini !!
Terima kasih Gowri M Bhatt kerana menyemak kandungan.
Jika anda menyukai artikel ini, sila klik pada butang hati ♥ dan kongsi untuk membantu orang lain menemuinya!
Kod sumber penuh untuk tutorial ini boleh didapati di sini,
codemaker2015/pdf-chat-using-RAG | github.com
Atas ialah kandungan terperinci Panduan muktamad untuk Retrieval-Augmented Generation (RAG). Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!