Langchain이있는 Edge 장치에서 자체 호스팅 래그 응용 프로그램
소개
라즈베리 파이에 래그 응용 프로그램 구축에 관한 시리즈의 두 번째 부분에서 우리는 핵심 파이프 라인을 만들고 테스트 한 첫 번째 부분에 놓인 기초를 확장 할 것입니다. 첫 번째 부분에서는 핵심 파이프 라인을 만들어 예상대로 모든 것이 작동하도록 테스트했습니다. 이제 우리는 Rag Pipeline에 서비스를 제공하기 위해 FastApi 응용 프로그램을 구축하고 사용자에게 간단하고 대화식에 액세스 할 수있는 방법을 제공하여 반사 앱을 만들어 한 단계 더 나아갈 것입니다. 이 부분은 Fastapi 백엔드 설정, 반사로 프론트 엔드를 설계하고 Raspberry Pi에서 모든 것을 일으켜 실행하는 것을 안내합니다. 결국, 실제 사용 준비가 된 완전한 작업 애플리케이션이 있습니다.
학습 목표
- 기존 래그 파이프 라인 및 프로세스 쿼리와 효율적으로 통합하기 위해 FastApi 백엔드를 설정하십시오.
- Fastapi 백엔드 및 Rag 파이프 라인과 상호 작용하기 위해 Reflex를 사용하여 사용자 친화적 인 인터페이스를 설계하십시오.
- 쿼리 및 문서화를 위해 API 엔드 포인트를 작성하고 테스트하여 FastAPI로 원활한 작동을 보장합니다.
- Raspberry Pi의 전체 응용 프로그램을 배포하고 테스트하여 백엔드 및 프론트 엔드 구성 요소가 완벽하게 작동하도록합니다.
- 응집력있는 래그 애플리케이션 경험을 위해 Fastapi와 Reflex의 통합을 이해하십시오.
- Raspberry Pi에서 완전히 작동하는 Rag 애플리케이션을 제공하기 위해 Fastapi 및 Reflex 구성 요소를 구현 및 문제 해결하십시오.
이전 버전을 놓친 경우 여기에서 확인하십시오. Langchain 및 Ollama-Part I을 사용한 Edge Devices의 자체 호스팅 래그 애플리케이션 .
목차
- 파이썬 환경 생성
- Fastapi로 백엔드 개발
- 반사로 프론트 엔드 설계
- 테스트 및 배포
- 자주 묻는 질문
이 기사는 Data Science Blogathon 의 일부로 출판되었습니다 .
파이썬 환경 생성
응용 프로그램을 작성하기 전에 환경을 설정해야합니다. 환경을 만들고 아래 종속성을 설치하십시오.
Deeplake boto3 == 1.34.144 BOTOCORE == 1.34.144 Fastapi == 0.110.3 Gunicorn == 22.0.0 httpx == 0.27.0 huggingface-hub == 0.23.4 langchain == 0.2.6 Langchain-Community == 0.2.6 Langchain-Core == 0.2.11 Langchain-Experimental == 0.0.62 Langchain-text-splitters == 0.2.2 Langsmith == 0.1.83 마시멜로 == 3.21.3 Numpy == 1.26.4 팬더 == 2.2.2 Pydantic == 2.8.2 pydantic_core == 2.20.1 pymupdf == 1.24.7 pymupdfb == 1.24.6 Python-dotenv == 1.0.1 pytz == 2024.1 pyyaml == 6.0.1 반사 == 0.5.6 요청 == 2.32.3 반사 == 0.5.6 반사 호스팅 클리 == 0.1.13
필요한 패키지가 설치되면 장치에 필요한 모델이 있어야합니다. 우리는 Ollama를 사용하여 이것을 할 것입니다. 이 기사의 1 부에서 나온 단계를 따라 언어와 임베딩 모델을 모두 다운로드하십시오. 마지막으로 백엔드 및 프론트 엔드 애플리케이션을위한 두 가지 디렉토리를 만듭니다.
Ollama를 사용하여 모델을 가져 오면 최종 응용 프로그램을 구축 할 준비가되었습니다.
Fastapi로 백엔드 개발
이 기사의 1 부에서는 섭취와 QNA 모듈을 모두 갖춘 헝겊 파이프 라인을 만들었습니다. 우리는 일부 문서를 사용하여 두 파이프 라인을 테스트했으며 완벽하게 작동했습니다. 이제 소모품 API를 만들려면 Fastapi로 파이프 라인을 래핑해야합니다. 이를 통해 Streamlit, Chainlit, Gradio, Reflex, React, Angular 등과 같은 프론트 엔드 애플리케이션과 통합하는 데 도움이됩니다. 응용 프로그램의 구조를 구축하여 시작하겠습니다. 다음 구조를 따르는 것은 완전히 선택 사항이지만 다른 구조를 따라 앱을 생성하는 경우 종속성 가져 오기를 확인하십시오.
아래는 우리가 따라갈 나무 구조입니다.
백엔드 ├ ── app.py ├ ─) 요구 사항 .txt SRC config.py doc_loader base_loader.py │ │ │─퀴 __init__.py pdf_loader.py ├ 착 섭취 .py ├ ── __init__.py └ ── QNA.PY
config.py부터 시작하겠습니다. 이 파일에는 Ollama URL, LLM 이름 및 임베딩 모델 이름과 같은 응용 프로그램의 구성 가능한 모든 옵션이 포함됩니다. 아래는 예입니다.
language_model_name = "phi3" embeddings_model_name = "nomic-embed-text" Ollama_url = "http : // localhost : 11434"
base_loader.py 파일에는 어린이 문서 로더가 상속받는 상위 문서 로더 클래스가 포함되어 있습니다. 이 응용 프로그램에서는 PDF 파일 만 작업하고 있으므로 Child PDFloader 클래스는 다음과 같습니다.
Baseloader 클래스를 상속받을 수 있습니다.
다음은 base_loader.py 및 pdf_loader.py의 내용입니다.
# base_loader.py ABC 가져 오기 ABC, AbstractMethod 클래스 Baseloader (ABC) : def __init __ (self, file_path : str) -> 없음 : self.file_path = file_path @abstractmethod Async def load_document (self) : 통과하다 # pdf_loader.py OS 가져 오기 .base_loader 가져 오기 BANELOADER Langchain에서 Schema 가져 오기 문서 langchain.document_loaders.pdf import pymupdfloader에서 langchain.text_splitter import aratertextsplitter에서 클래스 pdfloader (Baseloader) : def __init __ (self, file_path : str) -> 없음 : super () .__ init __ (file_path) Async def load_document (self) : self.file_name = os.path.baseName (self.file_path) 로더 = pymupdfloader (file_path = self.file_path) text_splitter = charactertextsplitter ( 분리기 = "\ n", chunk_size = 1000, chunk_overlap = 200, )) pages = await loader.aload () Total_Pages = len (페이지) 청크 = [] idx의 경우, 열거 (페이지)의 페이지 : chunks.Append ( 문서( page_content = page.page_content, 메타 데이터 = dict ( { "file_name": self.file_name, "page_no": str (idx 1), "Total_Pages": str (Total_Pages), } ),) )) )) final_chunks = text_splitter.split_documents (청크) Final_Chunks를 반환합니다
우리는 기사의 1 부에서 pdf_loader의 작동에 대해 논의했습니다.
다음으로 섭취 클래스를 만들어 봅시다. 이것은 우리 가이 기사의 Part-1에서 구축 한 것과 동일합니다.
섭취 클래스 코드
OS 가져 오기 CFG로 구성을 가져옵니다 PENECONE 가져 오기 PENECONE에서 langchain.vectorstores.deeplake import deeplake에서 langchain.embeddings.ollama import ollamaembeddings에서 .doc_loader에서 pdfloader를 가져옵니다 수업 섭취 : "" "문서 섭취 파이프 라인" "" "" "" "" " def __init __ (self) : 노력하다: self.embeddings = ollamaembeddings ( model = cfg.embeddings_model_name, base_url = cfg.ollama_url, show_progress = true, )) self.vector_store = deeplake ( DataSet_Path = "data/text_vectorStore", 임베딩 = self.embeddings, num_workers = 4, verbose = false, )) E로 예외를 제외하고 : runtimeerror를 높이십시오 (f "섭취 시스템을 초기화하지 못했습니다. 오류 : {e}") Async def create_and_add_embeddings ( 본인, 파일 : str, ) : : 노력하다: 로더 = pdfloader ( file_path = 파일, )) 청크 = AWAIT LODER.LOAD_DOCUMENT () size = await self.vector_store.aadd_documents (documents = chunks) 리턴 렌 (크기) e : 예외를 높이십시오 (f "오류 : {e}")
이제 섭취 클래스를 설정 했으므로 QNA 클래스를 만들었습니다. 이것은 또한 우리 가이 기사의 1 부에서 만든 것과 동일합니다.
QNA 클래스 코드
OS 가져 오기 CFG로 구성을 가져옵니다 PENECONE 가져 오기 PENECONE에서 langchain.vectorstores.deeplake import deeplake에서 langchain.embeddings.ollama import ollamaembeddings에서 Langchain_community.llms.llams import Ollama에서 .doc_loader에서 pdfloader를 가져옵니다 클래스 QNA : "" "문서 섭취 파이프 라인" "" "" "" "" " def __init __ (self) : 노력하다: self.embeddings = ollamaembeddings ( model = cfg.embeddings_model_name, base_url = cfg.ollama_url, show_progress = true, )) self.model = Ollama ( model = cfg.language_model_name, base_url = cfg.ollama_url, verbose = true, 온도 = 0.2, )) self.vector_store = deeplake ( DataSet_Path = "data/text_vectorStore", 임베딩 = self.embeddings, num_workers = 4, verbose = false, )) self.retriever = self.vector_store.as_retriever ( search_type = "유사성", search_kwargs = { "K": 10, }, )) E로 예외를 제외하고 : runtimeerror를 높이십시오 (f "섭취 시스템을 초기화하지 못했습니다. 오류 : {e}") def create_rag_chain (self) : 노력하다: system_prompt = "" "<instructions> \ n \ ncontext : {context}" "" " 프롬프트 = chatprompttemplate.from_messages ( [의 뜻 ( "System", System_Prompt), ( "human", "{input}"), ]] )) question_answer_chain = create_stuff_documents_chain (self.model, prompt) rag_chain = create_retrieval_chain (self.retriever, Question_answer_chain) RAG_CHAIN을 반환하십시오 E로 예외를 제외하고 : runtimeerror rase (f "검색 체인을 생성하지 못했습니다. 오류 : {e}")</instructions>
이를 통해 우리는 Rag 앱의 코드 기능 생성을 완료했습니다. 이제 앱을 Fastapi로 감싸자.
FastApi 응용 프로그램 코드
SYS 가져 오기 OS 가져 오기 Uvicorn을 수입하십시오 SRC 가져 오기 QNA, 섭취 Fastapi import Fastapi, 요청, 파일, 업로드 파일로부터 FastApi. Respones import StreamingResponse app = fastapi () 섭취 = 섭취 () chatbot = qna () rag_chain = chatbot.create_rag_chain () @app.get ( "/") def hello () : return { "message": "서버 8089에서 실행되는 API"}} @app.post ( "/query") Async def ask_query (요청 : 요청) : data = await request.json () question = data.get ( "Question") Async def event_generator () : rag_chain.pick의 청크 ( "답변"). stream ({ "input": question}) : 수율 덩어리 return streamingResponse (event_generator (), media_type = "text/plain") @app.post ( "/insest") Async def ingest_document (파일 : uploadfile = file (...)) : 노력하다: os.makedirs ( "파일", extin_ok = true) file_location = f "files/{file.filename}" file_object로 Open (file_location, "wb")을 사용하여 : file_object.write (file.file.read ()) size = await encestion.create_and_add_embeddings (file = file_location) return { "message": f "파일 insested! 문서 수 : {size}"} E로 예외를 제외하고 : return { "message": f "오류가 발생했습니다 : {e}"} __name__ == "__main__"인 경우 : 노력하다: uvicorn.run (app, host = "0.0.0.0", port = 8089) e : keyboardinterrupt를 제외하고 : print ( "앱 중지!")
각 엔드 포인트별로 앱을 분류합시다.
- 먼저 Fastapi 앱, 섭취 및 QNA 객체를 초기화합니다. 그런 다음 QNA 클래스의 create_rag_chain 메소드를 사용하여 래그 체인을 만듭니다.
- 첫 번째 끝점은 간단한 GET 방법입니다. 이것은 우리가 앱의 건강 여부를 알 수 있도록 도와줍니다. 'Hello World'엔드 포인트처럼 생각하십시오.
- 두 번째는 쿼리 엔드 포인트입니다. 이것은 사후 방법이며 체인을 실행하는 데 사용됩니다. 요청 매개 변수를 사용하여 사용자의 쿼리를 추출합니다. 그런 다음 체인 주변의 비동기 래퍼 역할을하는 비동기 메소드를 만듭니다. Fastapi가 LLM의 스트림 함수 호출을 처리하고 채팅 인터페이스에서 ChatGpt와 같은 경험을 얻을 수 있도록이를 수행해야합니다. 그런 다음 StreamingResponse 클래스로 비동기 방법을 감싸서 반환합니다.
- 세 번째 종점은 섭취 종점입니다. 또한 전체 파일을 입력으로 바이트로 취하는 게시물 메소드입니다. 이 파일을 로컬 디렉토리에 저장 한 다음 Create_and_add_embeddings ensestion 클래스를 사용하여 수집합니다.
마지막으로, 호스트와 포트를 사용하여 uvicorn 패키지를 사용하여 앱을 실행합니다. 앱을 테스트하려면 다음 명령을 사용하여 응용 프로그램을 실행합니다.
Python app.py
응용 프로그램 테스트를 위해 우체부, 불면증 또는 브루노와 같은 API 테스트 IDE를 사용하십시오. Thunder Client Extension을 사용하여 동일한 작업을 수행 할 수도 있습니다.
섭취 종말점 테스트 :
쿼리 엔드 포인트 테스트 :
반사로 프론트 엔드 설계
우리는 Rag 응용 프로그램의 백엔드를위한 FastApi 앱을 성공적으로 만들었습니다. 이제 프론트 엔드를 구축 할 시간입니다. 이를 위해 프론트 엔드 라이브러리를 선택할 수 있지만이 특정 기사의 경우 반사를 사용하여 프론트 엔드를 구축합니다. 반사는 파이썬 전용 프론트 엔드 라이브러리로, 파이썬을 사용하여 웹 애플리케이션을 구축하도록 만들어졌습니다. 계산기, 이미지 생성 및 챗봇과 같은 일반적인 응용 프로그램을위한 템플릿을 증명합니다. Chatbot 응용 프로그램 템플릿을 사용자 인터페이스의 시작으로 사용합니다. 최종 앱에는 다음 구조가 있으므로 참조 할 수 있도록 여기에 두십시오.
프론트 엔드 디렉토리
우리는 다음을위한 프론트 엔드 디렉토리를 갖습니다.
프론트 엔드 ├ ─) 자산 favicon.ico Docs Demo.gif Chat contronents Chat.py file_upload.py │ │ ├ ├ 익 .py loading_icon.py modal.py navbar.py │ │ │─퀴 __init__.py Chat.py state.py ├ ─) 요구 사항 .txt RxConfig.py UPLODED_FILES
최종 앱을위한 단계
단계를 따라 최종 앱의 접지를 준비하십시오.
1 단계 : Frontend 디렉토리에서 채팅 템플릿 저장소를 복제하십시오
git 클론 https://github.com/reflex-dev/reflex-chat.git.
2 단계 : 디렉토리를 반사 앱으로 초기화하려면 다음 명령을 실행하십시오.
반사 초기
이것은 반사 앱을 설정하고 실행 및 개발 준비가됩니다.
3 단계 : 앱 테스트, 프론트 엔드 디렉토리 내부에서 다음 명령을 사용하십시오.
반사 실행
구성 요소 수정을 시작합시다. 먼저 chat.py 파일을 수정하겠습니다.
아래는 동일한 코드입니다.
Rx로 반사를 가져옵니다 reflex_demo.components import loading_icon을 가져옵니다 Reflex_demo.State import QA, State에서 message_style = dict ( display = "인라인-블록", 패딩 = "0 10px", border_radius = "8px", max_width = [ "30em", "30em", "50em", "50em", "50em", "50em"], )) def message (qa : qa) -> rx.component : "" "단일 질문/답변 메시지. Args : QA : 질문/답변 쌍. 보고: 질문/답변 쌍을 표시하는 구성 요소. "" " RX.box 반환 ( rx.box ( rx.markdown ( qa.question, background_color = rx.color ( "Mauve", 4), color = rx.color ( "Mauve", 12), ** message_style, ),) text_align = "right", margin_top = "1em", ),) rx.box ( rx.markdown ( qa.answer, background_color = rx.color ( "악센트", 4), color = rx.color ( "악센트", 12), ** message_style, ),) text_align = "left", padding_top = "1em", ),) 너비 = "100%", )) def chat () -> rx.component : "" "단일 대화에 모든 메시지를 나열하십시오." "" return rx.vstack ( rx.box (rx.foreach (state.chats [state.current_chat], 메시지), 너비 = "100%"), py = "8", flex = "1", 너비 = "100%", max_width = "50em", padding_x = "4px", align_self = "Center", 오버플로 = "숨겨진", padding_bottom = "5em", )) def action_bar () -> rx.component : "" "새 메시지를 보내는 액션 바." "" return rx.center ( rx.vstack ( rx.chakra.form ( rx.chakra.form_control ( rx.hstack ( rx.input ( rx.input.slot ( rx.tooltip ( rx.icon ( "정보", 크기 = 18), content = "응답을 얻으려면 질문을 입력하십시오.", )) ),) 자리 표시 자 = "뭔가 입력 ...", ,,, 너비 = [ "15EM", "20EM", "45EM", "50EM", "50EM", "50EM"], ),) RX.Button ( rx.cond ( state.processing, loading_icon (높이 = "1em"), rx.text ( "send", font_family = "ubuntu"), ),) type = "제출", ),) align_items = "Center", ),) is_disabled = state.processing, ),) on_submit = state.process_question, reset_on_submit = true, ),) rx.text ( "Resygpt는 사실적으로 부정확하거나 오도하는 응답을 반환 할 수 있습니다. 재량 사용.", text_align = "Center", font_size = ". 75em", color = rx.color ( "Mauve", 10), font_family = "ubuntu", ),) rx.logo (margin_top = "-1em", margin_bottom = "-1em"), align_items = "Center", ),) 위치 = "스티커", 하단 = "0", 왼쪽 = "0", padding_y = "16px", Backdrop_Filter = "Auto", Backdrop_Blur = "LG", border_top = f "1px solid {rx.color ( 'mauve', 3)}", background_color = rx.color ( "mauve", 2), align_items = "스트레치", 너비 = "100%", ))
변경은 템플릿에 기본적으로 존재하는 것과 최소입니다.
다음으로 chat.py 앱을 편집합니다. 이것은 주요 채팅 구성 요소입니다.
기본 채팅 구성 요소에 대한 코드
아래는 코드입니다.
Rx로 반사를 가져옵니다 reflex_demo.components import 채팅, navbar, upload_form Reflex_demo.STATE 가져 오기 상태에서 @rx.page (route = "/chat", title = "rag chatbot") def chat_interface () -> rx.component : rx.chakra.vstack을 반환합니다. navbar (), chat.chat (), chat.action_bar (), background_color = rx.color ( "mauve", 1), color = rx.color ( "Mauve", 12), min_height = "100vh", align_items = "스트레치", 간격 = "0", )) @rx.page (route = "/", title = "rag chatbot") def index () -> rx.component : rx.chakra.vstack을 반환합니다. navbar (), upload_form (), background_color = rx.color ( "mauve", 1), color = rx.color ( "Mauve", 12), min_height = "100vh", align_items = "스트레치", 간격 = "0", )) # 앱에 상태와 페이지를 추가하십시오. app = rx.app ( 테마 = rx.theme ( 외관 = "어두운", accent_color = "jade", ),) 스타일 시트 = "https://fonts.googleapis.com/css2?family=ubuntu&display=swap"], 스타일 = { "font_family": "ubuntu", }, )) app.add_page (색인) app.add_page (chat_interface)
이것은 채팅 인터페이스의 코드입니다. 우리는 글꼴 패밀리를 앱 구성에 추가했으며 나머지 코드는 동일합니다.
다음으로 state.py 파일을 편집하겠습니다. 이곳은 프론트 엔드가 응답을 위해 API 엔드 포인트를 호출 할 것입니다.
state.py 파일 편집
가져 오기 요청 Rx로 반사를 가져옵니다 클래스 QA (rx.base) : 질문 : str 답 : Str default_chats = { "Intros": [], } 클래스 상태 (rx.state) : 채팅 : dict [str, list [qa]] = default_chats current_chat = "intros" URL : str = "http : // localhost : 8089/query" 질문 : str 처리 : bool = false new_chat_name : str = "" def create_chat (self) : "" "새 채팅 만들기." "" " # 채팅 목록에 새 채팅을 추가하십시오. self.current_chat = self.new_chat_name self.chats [self.new_chat_name] = [] def delete_chat (self) : "" "현재 채팅 삭제." "" del self.chats [self.current_chat] Len (self.chats) == 0 : self.chats = default_chats self.current_chat = list (self.chats.keys ()) [0] def set_chat (self, chat_name : str) : "" "현재 채팅의 이름을 설정하십시오. Args : chat_name : 채팅의 이름. "" " self.current_chat = chat_name @rx.var def chat_titles (self) -> list [str] : "" "채팅 제목 목록을 얻으십시오. 보고: 채팅 이름 목록. "" " 반환 목록 (self.chats.keys ()) Async def process_question (self, form_data : dict [str, str]) : # 양식에서 질문을 받으십시오 Question = form_data [ "Question"] # 질문이 비어 있는지 확인하십시오 질문 == ""인 경우 : 반품 model = self.openai_process_question 모델의 값에 대한 비동기 (질문) : 수율 값 Async def openai_process_question (self, question : str) : "" "API로부터 응답을 받으십시오. Args : form_data : 현재 질문이있는 덕트. "" " # 질문 목록에 질문을 추가하십시오. qa = qa (question = question, derson = "") self.chats [self.current_chat] .append (Qa) 페이로드 = { "질문": 질문} # 입력을 지우고 처리를 시작하십시오. self.processing = true 생산하다 응답 = requests.post (self.url, json = payload, stream = true) # 결과를 스트리밍하여 모든 단어 후에 산출합니다. response의 answer_text의 경우 (chunk_size = 512) : # answer_text가 연결하기 전에 아무것도 아님을 확인하십시오 answer_text = answer_text.decode () answer_text가 없다면 : self.chats [self.current_chat] [-1] .answer = Answer_text 또 다른: Answer_Text = "" self.chats [self.current_chat] [-1] .answer = Answer_text self.chats = self.chats 생산하다 # 처리 플래그를 전환합니다. self.processing = false
이 파일에서는 쿼리 엔드 포인트의 URL을 정의했습니다. 또한 OpenAI_Process_Question 메소드를 수정하여 쿼리 엔드 포인트에 게시물 요청을 보내고 스트리밍을 가져옵니다.
채팅 인터페이스에 표시됩니다.
file_upload.py 파일의 내용 작성
마지막으로 file_upload.py 파일의 내용을 작성해 봅시다. 이 구성 요소는 처음에 표시되어 섭취를 위해 파일을 업로드 할 수 있습니다.
Rx로 반사를 가져옵니다 OS 가져 오기 수입 시간 가져 오기 요청 클래스 uploadexample (rx.state) : 업로드 : bool = false 섭취 : bool = false 진행 : int = 0 Total_bytes : int = 0 ingestion_url = "http://127.0.0.1:8089/ingest" Async def handle_upload (자체, 파일 : List [rx.uploadfile]) : self.ingesting = true 생산하다 파일 파일의 경우 : file_bytes = await file.Read () file_name = file.filename 파일 = { "파일": (os.path.baseName (file_name), file_bytes, "multipart/form-data") } 응답 = requests.post (self.ingestion_url, files = files) self.ingesting = false 생산하다 if response.status_code == 200 : # Rx.Rx.Rxirect ( "/Chat") self.show_redirect_popup () def handle_upload_progress (self, progress : dict) : self.uploading = true self.progress = Round (진행 [Progress [ "Progress"] * 100) self.progress> = 100 인 경우 : self.uploading = false def cancel_upload (self) : self.uploading = false rx.cancel_upload를 반환합니다 ( "upload3") def upload_form () : return rx.vstack ( rx.upload ( rx.flex ( rx.text ( "여기서 파일을 드래그 앤 드롭하거나 파일을 선택하려면 클릭하십시오", font_family = "ubuntu", ),) rx.icon ( "업로드", 크기 = 30), 방향 = "열", align = "Center", ),) ,,, Border = "1px 고체 RGB (233, 233,233, 0.4)", 마진 = "5em 0 10px 0", background_color = "RGB (107,99,246)", border_radius = "8px", 패딩 = "1em", ),) rx.vstack (rx.foreach (rx.selected_files ( "upload3"), rx.text)), rx.cond ( ~ uploadexample.inging, RX.Button ( "업로드", on_click = uploadexample.handle_upload ( rx.upload_files ( upload_, on_upload_progress = uploadexample.handle_upload_progress, ),) ),) ),) rx.flex ( rx.spinner (size = "3", loading = uploadexample.ingesting), RX.Button ( "취소", on_click = uploadexample.cancel_upload, ),) align = "Center", 간격 = "3", ),) ),) rx.alert_dialog.root ( rx.alert_dialog.trigger ( rx.button ( "계속 채팅", color_scheme = "green"), ),) rx.alert_dialog.content ( rx.alert_dialog.title ( "채팅 인터페이스로 리디렉션?"), rx.alert_dialog.description ( "당신은 채팅 인터페이스로 리디렉션됩니다.", 크기 = "2", ),) rx.flex ( rx.alert_dialog.cancel ( RX.Button ( "취소", 변형 = "소프트", color_scheme = "그레이", ),) ),) rx.alert_dialog.action ( RX.Button ( "계속하다", color_scheme = "녹색", variant = "solid", on_click = rx.redirect ( "/Chat"), ),) ),) 간격 = "3", margin_top = "16px", respitify = "end", ),) 스타일 = { "max_width": 450}, ),) ),) align = "Center", ))
이 구성 요소를 사용하면 파일을 업로드하여 벡터 저장소에 섭취 할 수 있습니다. Fastapi 앱의 ensest 엔드 포인트를 사용하여 파일을 업로드하고 수집합니다. 섭취 후 사용자는 단순히 움직일 수 있습니다
쿼리를 요청하기위한 채팅 인터페이스에.
이를 통해 우리는 응용 프로그램의 프론트 엔드를 작성했습니다. 이제 일부 문서를 사용하여 응용 프로그램을 테스트해야합니다.
테스트 및 배포
이제 일부 설명서 나 문서에서 응용 프로그램을 테스트 해 봅시다. 응용 프로그램을 사용하려면 백엔드 앱과 반사 앱을 별도로 실행해야합니다. 그것을 사용하여 디렉토리에서 백엔드 앱을 실행하십시오
다음 명령 :
Python app.py
Fastapi가 실행을 시작할 때까지 기다리십시오. 그런 다음 다른 터미널 인스턴스에서 다음 명령을 사용하여 프론트 엔드 앱을 실행합니다.
반사 실행
하나는 앱이 가동되고 실행 중이며 반사 앱에 액세스하기 위해 다음 URL에 도달했습니다. 처음에는 파일 업로드 페이지에 있습니다. 파일을 업로드하고 업로드 버튼을 누릅니다.
파일이 업로드되어 섭취됩니다. 문서 크기에 따라 시간이 걸리고
장치 사양. 완료되면 '채팅 계속'버튼을 클릭하여 채팅 인터페이스로 이동하십시오. 쿼리를 작성하고 보내기를 누릅니다.
결론
Thistwo Parteries에서는 이제 코어 파이프 라인 생성에서 Fastapi 백엔드로 포장하고 반사 기반 프론트 엔드를 개발하는 것에 이르기까지 Raspberry Pi에 완전하고 기능적인 Rag 애플리케이션을 구축했습니다. 이러한 도구를 사용하면 RAG 파이프 라인이 액세스 할 수 있고 대화식으로 사용자 친화적 인 웹 인터페이스를 통해 실시간 쿼리 처리를 제공합니다. 이러한 단계를 마스터하면 작고 효율적인 플랫폼에 엔드 투 엔드 애플리케이션을 구축하고 배포하는 데 귀중한 경험을 얻었습니다. 이 설정은 Raspberry Pi와 같은 자원으로 제한된 장치에 AI 중심 애플리케이션을 배포 할 수있는 수많은 가능성의 문을 열어 매일 사용하기에 최첨단 기술에 더 접근 가능하고 실용적으로 만듭니다.
주요 테이크 아웃
- Ollama를 사용하여 필요한 종속성 및 모델 설치를 포함하여 개발 환경 설정에 대한 자세한 안내서가 제공되어 애플리케이션이 최종 빌드 준비가되도록합니다.
- 이 기사는 모델 쿼리 및 문서 수집을위한 엔드 포인트 설정을 포함하여 Rag Pipeline을 Fastapi 응용 프로그램으로 래핑하는 방법을 설명합니다.
- RAG 응용 프로그램의 프론트 엔드는 파이썬 전용 프론트 엔드 라이브러리 인 Reflex를 사용하여 구축됩니다. 이 기사는 채팅 응용 프로그램 템플릿을 수정하여 RAG 파이프 라인과 상호 작용하기위한 사용자 친화적 인 인터페이스를 작성하는 방법을 보여줍니다.
- 이 기사는 Fastapi 백엔드를 Reflex 프론트 엔드와 통합하고 Raspberry Pi에 전체 응용 프로그램을 배포하여 완벽한 작동 및 사용자 접근성을 보장합니다.
- Postman 또는 Thunder Client와 같은 도구를 사용하여 섭취 및 쿼리 엔드 포인트를 모두 테스트하기위한 실용적인 단계와 반사 프론트 엔드를 실행하고 테스트하여 전체 응용 프로그램이 예상대로 기능하도록합니다.
자주 묻는 질문
Q1 : 보안을 손상시키지 않고 전 세계 어디에서나 나 자신이 앱에 액세스 할 수 있도록하려면 어떻게해야합니까?A. TailScale이라는 플랫폼이 있으며 장치를 개인 보안 네트워크에 연결할 수 있으며 귀하에게만 액세스 할 수 있습니다. Raspberry Pi 및 기타 장치를 테일 스케일 장치에 추가하고 VPN에 연결하여 전 세계 어디에서나 앱에 액세스 할 수 있습니다.
Q2 : 섭취와 QNA 측면에서 내 응용 프로그램은 매우 느립니다.A. 이는 Raspberry Pi의 하드웨어 사양이 낮기 때문에 제약입니다. 이 기사는 Raspberry Pi와 Ollama를 사용하여 Rag App을 구축하는 방법에 대한 Head Up 튜토리얼입니다.
이 기사에 표시된 미디어는 분석 Vidhya가 소유하지 않으며 저자의 재량에 따라 사용됩니다.
위 내용은 Langchain이있는 Edge 장치에서 자체 호스팅 래그 응용 프로그램의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

핫 AI 도구

Undress AI Tool
무료로 이미지를 벗다

Undresser.AI Undress
사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover
사진에서 옷을 제거하는 온라인 AI 도구입니다.

Clothoff.io
AI 옷 제거제

Video Face Swap
완전히 무료인 AI 얼굴 교환 도구를 사용하여 모든 비디오의 얼굴을 쉽게 바꾸세요!

인기 기사

뜨거운 도구

메모장++7.3.1
사용하기 쉬운 무료 코드 편집기

SublimeText3 중국어 버전
중국어 버전, 사용하기 매우 쉽습니다.

스튜디오 13.0.1 보내기
강력한 PHP 통합 개발 환경

드림위버 CS6
시각적 웹 개발 도구

SublimeText3 Mac 버전
신 수준의 코드 편집 소프트웨어(SublimeText3)

투자는 급성장하지만 자본만으로는 충분하지 않습니다. AI 중심 벤처 펀드의 가치가 높아지고 고유성이 희미 해지면서 핵심 결정을 내려야합니다. 구매, 구축 또는 파트너가 우위를 점할 수 있습니까? 각 옵션과 PR을 평가하는 방법은 다음과 같습니다

그것에 대해 이야기합시다. 혁신적인 AI 혁신에 대한이 분석은 다양한 영향력 AI 복잡성을 식별하고 설명하는 것을 포함하여 AI의 최신 Forbes 열 범위의 일부입니다 (여기 링크 참조). AGI로 향하고 있습니다

올해 초 Genai 산업을 방해 한 오픈 소스 중국 모델의 홍수를 기억하십니까? DeepSeek은 대부분의 헤드 라인을 가져 왔지만 Kimi K1.5는 목록에서 두드러진 이름 중 하나였습니다. 그리고 모델은 매우 시원했습니다.

그것에 대해 이야기합시다. 혁신적인 AI 혁신에 대한이 분석은 다양한 영향력 AI 복잡성을 식별하고 설명하는 것을 포함하여 AI의 최신 Forbes 열 범위의 일부입니다 (여기 링크 참조). h

20125 년 중반까지 AI“무기 경주”가 가열되고 있으며 Xai와 Anthropic은 플래그십 모델 인 Grok 4와 Claude 4를 발표했습니다.이 두 모델은 디자인 철학과 배포 플랫폼의 반대쪽 끝에 있습니다.

예를 들어, 모델에 "(x)가 (x) 회사에서 무엇을 하는가?" 시스템이 필요한 정보를 검색하는 방법을 알고 있다고 가정 할 때 다음과 같은 모습을 보이는 추론 체인을 볼 수 있습니다. CO에 대한 세부 사항 찾기

임상 시험은 약물 발달에서 엄청난 병목 현상으로, Kim과 Reddy는 PI Health에서 구축 한 AI 지원 소프트웨어가 잠재적으로 적격 환자의 풀을 확장하여 더 빠르고 저렴할 수 있다고 생각했습니다. 그러나

상원은 화요일 아침 99-1로 투표하여 옹호 단체, 국회의원 및 수만 명의 미국인들의 마지막 순간의 격렬한 후 위험한 것으로 보인다. 그들은 조용히 머물지 않았습니다. 상원은 들었습니다
