paint-brush
Tutorial konplè sou bati yon aplikasyon RAG lè l sèvi avèk LangChainpa@bexgboost
354 lekti
354 lekti

Tutorial konplè sou bati yon aplikasyon RAG lè l sèvi avèk LangChain

pa Bex19m2024/09/03
Read on Terminal Reader

Twò lontan; Pou li

Aprann ki jan yo sèvi ak LangChain, fondasyon an twouve popilè pou bati sistèm RAG. Nan fen leson patikilye a, nou pral gen yon chatbot (ak yon koòdone Streamlit ak tout) ki pral RAG wout li nan kèk done prive bay repons a kesyon.
featured image - Tutorial konplè sou bati yon aplikasyon RAG lè l sèvi avèk LangChain
Bex HackerNoon profile picture

Gwo modèl lang jodi a gen aksè a yon kantite enfòmasyon ki toujou ap grandi. Sepandan, gen yon gwo kantite done prive ke modèl sa yo pa pwofite. Se poutèt sa youn nan aplikasyon ki pi popilè nan LLMs nan anviwònman antrepriz se rekiperasyon-augmented jenerasyon-RAG pou kout. Nan Vizly , platfòm analiz done AI ki mache ak pisans nou an, nou te jwenn bonjan enfòmasyon sou bati sistèm RAG efikas. Nan leson patikilye sa a, nou pral pataje kèk nan aprantisaj nou yo epi montre w kouman pou kreye pwòp sistèm RAG ou.


Ou pral aprann kijan pou sèvi ak LangChain, fondasyon twouve popilè pou bati sistèm RAG, pou konstwi yon sistèm RAG senp. Nan fen leson patikilye a, nou pral gen yon chatbot (ak yon koòdone Streamlit ak tout) ki pral RAG wout li nan kèk done prive bay repons a kesyon.

ki sa ki RAG?

Pou klarifye sa RAG ye, ann konsidere yon egzanp senp.


Chandler, yon etidyan premye ane nan kolèj, ap konsidere sote kèk klas men li vle asire li pa vyole politik prezans nan inivèsite a. Menm jan ak nenpòt bagay jou sa yo, li poze ChatGPT kesyon an.


Natirèlman, ChatGPT pa ka reponn li. Chatbot la pa bèbè - li jis pa gen aksè a dokiman inivèsite Chandler la. Se konsa, Chandler jwenn dokiman politik la tèt li epi li dekouvri ke li se yon lekti long, teknik li pa vle mache nan. Olye de sa, li bay tout dokiman an bay ChatGPT epi li poze kesyon an ankò. Fwa sa a, li jwenn repons li.


Sa a se yon ka endividyèl nan jenerasyon rekipere-ogmante. Repons modèl lang lan (jenerasyon) ogmante (anrichi) pa kontèks rekipere nan yon sous ki pa fè pati fòmasyon orijinal li.


Yon vèsyon évolutif nan yon sistèm RAG ta kapab reponn nenpòt kesyon elèv nan rechèch nan dokiman inivèsite tèt li, jwenn sa yo ki enpòtan, ak rekipere moso nan tèks ki gen plis chans gen repons lan.


Anjeneral pale, nan yon sistèm RAG, ou rekipere enfòmasyon ki soti nan yon sous done prive epi bay li nan yon modèl lang, ki pèmèt modèl la bay yon repons ki enpòtan pou kontèks.

Eleman nan yon aplikasyon RAG

Yon sistèm konsa, malgre kònen klewon dwat, ta gen anpil konpozan k ap deplase. Anvan nou bati youn tèt nou, nou bezwen revize sa yo ye ak ki jan yo jwe ansanm.

Dokiman

Premye eleman an se yon dokiman oswa yon koleksyon dokiman. Dapre kalite sistèm RAG n ap bati a, dokiman yo ka fichye tèks, PDF, paj wèb (RAG sou done ki pa estriktire) oswa graf, SQL, oswa baz done NoSQL (RAG sou done estriktire). Yo itilize yo pou enjere divès kalite done nan sistèm nan.

Charger dokiman yo

LangChain aplike plizyè santèn klas ki rele charger dokiman pou li done ki soti nan plizyè sous dokiman tankou PDF, Slack, Notion, Google Drive, ak sou sa.


Chak klas loader dokiman inik, men yo tout pataje menm metòd .load() la. Pou egzanp, men ki jan ou ka chaje yon dokiman PDF ak yon paj wèb nan LangChain:

 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()


Klas PyPDFLoader la okipe dosye PDF lè l sèvi avèk pake PyPDF2 anba kapo a, pandan y ap WebBaseLoader la grate kontni pajwèb yo bay yo.


pdf_docs gen kat objè dokiman, youn pou chak paj:


 >>> len(pdf_docs) 4


Pandan ke web_docs genyen yon sèl:

 >>> 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


Objè dokiman sa yo pita bay modèl entegre pou konprann siyifikasyon semantik dèyè tèks yo.


Pou spesifik sou lòt kalite chajè dokiman, LangChain ofri yon dedye kòman pou paj .

Splitter tèks

Yon fwa ou te chaje dokiman ou yo, li enpòtan pou kraze yo an pi piti ak pi fasil jere moso tèks. Men rezon prensipal yo:

  1. Anpil modèl embedding (plis sou yo pita) gen yon limit maksimòm siy.
  2. Rekipere pi egzak lè ou gen pi piti moso.
  3. Modèl lang lan nouri kontèks egzak la.


LangChain ofri plizyè kalite divizyon tèks anba pake langchain_text_splitters li yo, epi yo diferan selon kalite dokiman.

Men ki jan yo sèvi ak RecursiveCharacterTextSplitter pou divize tèks klè ki baze sou yon lis separatè ak gwosè moso:

 !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}")

Sòti:

 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.

Splitter sa a se versatile ak travay byen pou anpil ka itilize. Li kreye chak moso ak yon konte karaktè pi pre chunk_size ke posib. Li ka rekursivman chanje ant ki separasyon yo divize nan kenbe konte karaktè a.


Nan egzanp ki anwo a, splitter nou an ap eseye divize sou newlines an premye, answit espas sèl, epi finalman ant nenpòt karaktè yo rive jwenn gwosè a moso vle.


Genyen anpil lòt splitters andedan pakè langchain_text_splitters . Men kèk:

  • HTMLSectionSplitter
  • PythonCodeTexSplitter
  • RecursiveJsonSplitter

ak sou sa. Gen kèk nan splitters yo kreye fragman semantik siyifikatif lè l sèvi avèk yon modèl transfòmatè anba kapo a.


Splitter tèks dwat la gen yon enpak siyifikatif sou pèfòmans yon sistèm RAG.


Pou plis detay sou fason yo sèvi ak divizyon tèks, gade ki enpòtan an ki jan-a gid isit la .

Embedding modèl

Yon fwa dokiman yo divize an tèks, yo bezwen kode nan reprezantasyon nimerik yo, ki se yon kondisyon pou tout modèl kalkil k ap travay ak done tèks.


Nan kontèks RAG, yo rele kodaj sa a embedding epi li fè pa embedding modèl . Yo kreye yon reprezantasyon vektè nan yon moso tèks ki kaptire siyifikasyon semantik yo. Lè w prezante tèks nan fason sa a, ou ka fè operasyon matematik sou yo, tankou rechèch baz done dokiman nou an pou tèks ki pi sanble nan siyifikasyon oswa jwenn yon repons a yon demann itilizatè.


LangChain sipòte tout gwo founisè modèl entegre, tankou OpenAI, Cohere, HuggingFace, ak sou sa. Yo aplike kòm klas Embedding epi yo bay de metòd: youn pou entegre dokiman yo ak youn pou entegre demann (envit).


Men yon egzanp kòd ki entegre moso tèks nou te kreye nan seksyon anvan an lè l sèvi avèk 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]}")


Sòti:

 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]

Pwodiksyon ki anwo a montre ke modèl embedding la ap kreye yon vektè 1536 dimansyon pou tout moso nan dokiman nou yo.


Pou entegre yon sèl rechèch, ou ka itilize metòd 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]}")


Sòti:

 Shape of the query embedding: 1536 First few values of the query embedding: [-0.012426204979419708, -0.016619959846138954, 0.007880032062530518, -0.0170428603887558, 0.011404196731746197]

Magazen vektè

Nan aplikasyon RAG gwo-echèl kote ou ka gen gigabyte nan dokiman, ou pral fini ak moso tèks gazillion ak konsa, vektè. Pa gen okenn itilizasyon yo si ou pa ka estoke yo seryezman.


Se poutèt sa magazen vektè oswa baz done yo tout raj kounye a. Apa de estoke embeddings ou yo, baz done vektè pran swen fè rechèch vektè pou ou. Yo optimize baz done sa yo pou jwenn byen vit vektè ki pi sanble lè yo bay yon vektè rechèch, ki esansyèl pou rekipere enfòmasyon ki enpòtan nan sistèm RAG.


Isit la se yon ti bout nan kòd ki entegre sa ki nan yon paj wèb epi ki estoke vektè yo nan yon baz done vektè Chroma ( Chroma se yon solisyon baz done vektè sous ouvè ki kouri antyèman sou machin ou):

 !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)


Premyèman, nou chaje paj la ak WebBaseLoader epi kreye moso nou yo. Lè sa a, nou ka dirèkteman pase moso yo nan metòd from_documents nan Chroma ansanm ak modèl embedding nou an nan chwa:

 from langchain_openai import OpenAIEmbeddings from langchain_chroma import Chroma db = Chroma.from_documents(chunks, OpenAIEmbeddings())


Tout objè baz done vektè nan LangChain ekspoze yon metòd similarity_search ki aksepte yon seri rechèch:

 query = "What is indexing in the context of RAG?" docs = db.similarity_search(query) print(docs[1].page_content)


Sòti:

 If you are interested for RAG over structured data, check out our tutorial on doing question/answering over SQL data.Concepts​A 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:Indexing​Load: 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

Rezilta similarity_search se yon lis dokiman ki gen plis chans genyen enfòmasyon n ap mande nan rechèch la.


Pou plis detay sou fason yo sèvi ak magazen vektè, gade ki enpòtan an kòman pou gid isit la .

Retrievers

Malgre ke tout magazen vektè sipòte rekipere nan fòm rechèch resanblans, LangChain aplike yon koòdone Retriever dedye ki retounen dokiman yo bay yon rechèch san estrikti. Yon retriever sèlman bezwen retounen oswa rekipere dokiman, pa sere yo.


Men ki jan ou ka konvèti nenpòt magazen vektè nan yon retriever nan 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


Li posib pou limite kantite dokiman ki enpòtan nan tèt k lè l sèvi avè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

Ou ka pase lòt paramèt ki gen rapò ak rechèch bay search_kwargs. Aprann plis sou itilize retrievers de gid espesifik kijan pou yo fè .

Workflow etap pa etap pou konstwi yon aplikasyon RAG nan LangChain

Kounye a ke nou te kouvri eleman kle yo nan yon sistèm RAG, nou pral bati youn tèt nou. Mwen pral fè ou atravè yon aplikasyon etap pa etap nan yon chatbot RAG ki fèt espesyalman pou dokiman kòd ak leson patikilye. W ap jwenn li patikilyèman itil lè w bezwen asistans pou kodaj AI pou nouvo kad oswa nouvo karakteristik kad ki deja egziste ki poko fè pati konesans baz LLM jodi a.

0. Kreye estrikti pwojè a

Premyèman, ranpli anyè travay ou a ak estrikti pwojè sa a:

 rag-chatbot/ ├── .gitignore ├── requirements.txt ├── README.md ├── app.py ├── src/ │ ├── __init__.py │ ├── document_processor.py │ └── rag_chain.py └── .streamlit/ └── config.toml


Men kòmandman yo:

 $ 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. Mete kanpe anviwònman an

Nan etap sa a, ou premye kreye yon nouvo anviwònman Conda epi aktive li:

 $ conda create -n rag_tutorial python=3.9 -y $ conda activate rag_tutorial


Apre sa, louvri fichye requirements.txt la epi kole depandans sa yo:

 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

epi enstale yo:

 $ pip install -r requirements.txt


Epitou, kreye yon fichye .gitignore pou kache fichye yo nan git Indexing:

 # .gitignore venv/ __pycache__/ .env *.pdf *.png *.jpg *.jpeg *.gif *.svg

2. mete kanpe dokiman chargeurs

Apre sa, louvri fichye src/document_processor.py a epi kole fragman kòd kap vini yo.


Enpòtasyon ki nesesè yo:

 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


Eksplikasyon sou enpòtasyon yo:

  • RecursiveCharacterTextSplitter : Divize tèks an pi piti fragman yon fason repetitif.
  • Language : Enum pou espesifye langaj pwogramasyon nan divize tèks.
  • PyPDFLoader : Chaje ak ekstrè tèks nan dosye PDF yo.
  • extract_from_images_with_rapidocr : Fonksyon OCR pou ekstrè tèks nan imaj yo.
  • Document : Reprezante yon dokiman ki gen kontni ak metadata.
  • logging : Ofri fonksyonalite antre pou debogaj ak enfòmasyon.


Lè sa a, yon fonksyon pou trete PDF yo:

 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)


Men ki jan li fonksyone:

  1. Li chaje PDF a lè l sèvi avèk PyPDFLoader .
  2. Li filtre paj analize lè li retire dokiman ki gen kontni vid.
  3. Li anrejistre kantite paj analize yo omisyon, si genyen.
  4. Si tout paj yo analize (sa vle di, pa gen okenn kontni tèks), li ogmante yon ValueError.
  5. Finalman, li divize rès dokiman ki pa tcheke yo an pi piti moso lè l sèvi avèk fonksyon split_documents.

Fonksyon an okipe ka kote yon PDF ka genyen yon melanj de tèks ak paj tcheke, asire ke sèlman paj ki baze sou tèks yo trete pi lwen. Sa enpòtan anpil pou travay analiz tèks kote paj analize san OCR ta pa ka itilize. Nou pral defini fonksyon split_documents pita.


Apre sa, nou ekri yon fonksyon pou rekipere enfòmasyon ki soti nan imaj (ekran nan fragman kòd ak / oswa paj wèb):


 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)


Fonksyon sa a trete yon fichye imaj pa ekstrè tèks lè l sèvi avèk OCR (Optical Character Recognition). Li li fichye imaj la, konvèti li an byte, ak Lè sa a, sèvi ak bibliyotèk la RapidOCR pou ekstrè tèks nan imaj la. Lè sa a, tèks ekstrè a vlope nan yon objè Dokiman ak metadata ki gen chemen fichye sous la. Finalman, fonksyon an divize dokiman an an pi piti moso lè l sèvi avèk fonksyon split_documents , ke nou defini pwochen:


 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)


Fonksyon an sèvi ak klas RecursiveCharacterTextSplitter ak sentaks Python pou divize tèks an fragman 1000 karaktè ak sipèpoze 200 karaktè.


Fonksyon final nou an konbine fonksyon PDF ak analiz imaj nan yon sèl:


 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}")


Fonksyon final sa a pral sèvi ak Streamlit UI a pou kreye, entegre ak estoke moso nan dokiman yo bay yo epi pase yo desann nan eleman RAG nan sistèm nou an.

3. Mete kanpe RAG

Koulye a, louvri fichye src/rag_chain.py a epi kole fragman kòd kap vini yo.


Premyèman, enpòte modil ki nesesè yo:


 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")


Men yon eksplikasyon sou enpòtasyon yo:

os : entèraksyon sistèm operasyon • dotenv : Chaje varyab anviwònman • langchain konpozan:

  • PromptTemplate : Kreyasyon rapid koutim
  • FAISS : Yon magazen vektè ki lejè pou dokiman yo
  • StrOutputParser : Konvèti objè mesaj LLM an rezilta fisèl
  • RunnablePassthrough : Kreye chenn konpoze
  • ChatOpenAI , OpenAIEmbeddings : entèraksyon modèl OpenAI


Apre sa, nou kreye èd memwa nou an pou sistèm RAG la:


 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 sistèm rapid se youn nan faktè kritik nan siksè li. Vèsyon nou an se yon senp men yo pral fè travay la pi fò nan tan an. Nan pratik, ou ta pase anpil tan iterasyon ak amelyore sou èd memwa a.


Si w remake, n ap itilize yon klas PromptTemplate pou konstwi èd memwa a. Konstwiksyon sa a pèmèt nou enjere yon fason dinamik kontèks rekipere nan dokiman yo ak rechèch itilizatè a nan yon èd memwa final.


Pale de dokiman, nou bezwen yon fonksyon fòma yo anvan yo pase kòm kontèks nan èd memwa sistèm lan:


 def format_docs(docs): return "\n\n".join(doc.page_content for doc in docs)


Li se yon fonksyon ki senp ki konkate kontni paj dokiman yo rekipere.


Finalman, nou kreye yon fonksyon ki pral devlope chèn RAG nou an:


 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


Fonksyon an aksepte moso dokiman, ki pral bay fonksyon process_document anndan script document_processor.py .

Fonksyon an kòmanse pa defini modèl embedding ak estoke dokiman yo nan yon magazen vektè FAISS. Lè sa a, li se konvèti nan koòdone nan retriever ak rechèch resanblans ki retounen pi wo senk dokiman matche rechèch itilizatè a.


Pou modèl lang lan, nou pral sèvi ak gpt-4o-mini men ou ka itilize lòt modèl tankou GPT-4o selon bidjè ou ak bezwen ou.

Lè sa a, nou pral mete tout eleman sa yo ansanm lè l sèvi avèk LangChain Expression Language (LCEL). Premye eleman nan chèn lan se yon diksyonè ki gen context ak question kòm kle. Valè kle sa yo bay retriever fòma pa fonksyon fòma nou an ak RunnablePassthrough() , respektivman. Dènye klas la aji kòm yon anplasman pou demann itilizatè a.


Lè sa a, diksyonè a pase nan èd memwa sistèm nou an; se èd memwa a bay LLM a, ki jenere klas mesaj pwodiksyon. Yo bay klas mesaj la nan yon analizè pwodiksyon fisèl ki retounen yon repons tèks klè.

4. Kreye yon entèfas Streamlit

Nan seksyon sa a, nou pral konstwi UI ki anba a pou aplikasyon nou an:


Ekran nan Streamlit UI nou an.

Li se yon koòdone pwòp, minim ak de jaden antre - youn pou dokiman an, lòt la pou poze kesyon sou dokiman an. Nan ba bò gòch la, yo mande itilizatè a antre kle API yo.


Pou konstwi koòdone a, louvri script app.py a nan pi wo nivo anyè k ap travay ou a epi kole kòd sa a:


 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.")


Malgre li se sèlman 65 liy longè, li aplike fonksyonalite sa yo:

  1. Antre kle API: Pèmèt itilizatè yo antre kle API OpenAI yo an sekirite.
  2. Téléchargement fichye: Sipòte téléchargement fichiers PDF, PNG, JPG, ak JPEG.
  3. Pwosesis dokiman: Pwosesis dosye a telechaje epi kreye moso tèks.
  4. Kreyasyon chèn RAG: Konstwi yon chèn jenerasyon Retrieval-Ogmante lè l sèvi avèk moso dokiman trete yo.
  5. Manyen demann: Aksepte kesyon itilizatè yo sou dokiman an telechaje.
  6. Jenerasyon repons: Sèvi ak chèn RAG pou jenere repons ki baze sou dokiman ki telechaje a ak demann itilizatè a.
  7. Jesyon erè: Bay mesaj erè apwopriye pou kle API ki manke, dosye ki pa trete, oswa demann vid.
  8. Feedback itilizatè: Montre spinners pandan pwosesis ak mesaj siksè/erè pou kenbe itilizatè a enfòme.
  9. Jesyon Eta: Itilize eta sesyon Streamlit la pou kenbe chèn RAG atravè entèraksyon yo.

5. Deplwaye kòm yon chatbot Streamlit

Gen yon sèl etap ki rete—deplwaye aplikasyon Streamlit nou an. Gen anpil opsyon isit la men fason ki pi fasil la se lè w itilize Streamlit Cloud, ki gratis epi fasil pou mete kanpe.


Premyèman, louvri script .streamlit/config.toml epi kole konfigirasyon sa yo:


 [theme] primaryColor = "#F63366" backgroundColor = "#FFFFFF" secondaryBackgroundColor = "#F0F2F6" textColor = "#262730" font = "sans serif"


Sa yo se kèk ajisteman tèm ki soti nan preferans pèsonèl. Lè sa a, ekri dosye README.md la (ou ka kopye sa ki soti nan fichye hébergé sa a sou GitHub ).


Finalman, ale nan GitHub.com epi kreye yon nouvo depo. Kopi lyen li epi retounen nan anyè k ap travay ou a:


 $ 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


Kòmandman ki anwo yo inisyalize Git, kreye yon premye angajman epi pouse tout bagay nan repozitwa a (pa bliye ranplase lyen repo a ak pwòp ou a).


Koulye a, ou dwe enskri pou yon kont gratis nan Streamlit Cloud . Konekte kont GitHub ou a epi chwazi repozitwa ki gen aplikasyon w lan.


Lè sa a, konfigirasyon paramèt aplikasyon an:

  • Mete vèsyon an Python (egzanp, 3.9)
  • Mete chemen dosye prensipal la nan app.py
  • Ajoute nenpòt sekrè ki nesesè (tankou OPENAI_API_KEY ) nan paramèt aplikasyon an


Finalman, klike sou "Deplwaye"!


Aplikasyon an dwe operasyonèl nan kèk minit. Ou ka jwenn aplikasyon mwen te konstwi pou leson patikilye sa a nan lyen sa a . Eseye li!

Sistèm RAG an aksyon

Konklizyon

Tutorial sa a gade melanj ki pisan nan Retrieval-Augmented Generation (RAG) ak Streamlit ki fòme yon sistèm entèaktif pou reponn kesyon ki baze sou dokiman yo. Li pran lektè a atravè tout pwosesis la, soti nan mete kanpe yon anviwònman ak pwosesis dokiman yo bati yon chèn RAG ak deplwaye yon aplikasyon entènèt zanmitay.


Pwen enpòtan yo enkli:

  • RAG pou yon modèl lang ki pi entelijan (nan sans konesans ekstèn).
  • Chèn RAG yo ka bati lè l sèvi avèk LangChain, modèl OpenAI a, ak entegrasyon kominote twazyèm pati.
  • Yo ka fè aplikasyon an entèaktif lè l sèvi avèk Streamlit epi yo ka deplwaye pou itilizasyon piblik.


Pwojè sa a fòme baz pou aplikasyon ki pi avanse. Li ka pwolonje nan fason enpòtan, tankou enkòporasyon nan plizyè kalite dokiman, amelyore presizyon rekipere, ak karakteristik tankou rezime dokiman. Men, sa li vrèman sèvi se kòm yon demonstrasyon de pouvwa potansyèl teknoloji sa yo, endividyèlman ak konbine.