搜尋
首頁科技週邊人工智慧帶有Langchain的邊緣設備上的自託管抹布應用

介紹

在我們在Raspberry Pi上構建RAG應用程序的系列文章的第二部分中,我們將在第一部分奠定的基礎上擴展,在該基礎上我們創建並測試了核心管道。在第一部分中,我們創建了核心管道並對其進行了測試,以確保一切按預期工作。現在,我們將通過構建FastApi應用程序來服務我們的破布管道並創建反射應用程序,從而為用戶提供一種簡單且交互式的方式來訪問它,從而進一步邁出一步。這部分將指導您設置FastApi後端,用Reflex設計前端,並在Raspberry Pi上啟動並運行所有內容。最後,您將擁有一個完整的工作應用程序,該應用程序已準備好現實使用。

學習目標

  • 設置FastApi後端,以與現有的RAG管道集成並有效地查詢。
  • 使用Reflex設計一個用戶友好的界面,以與FastApi後端和RAG管道進行交互。
  • 創建和測試用於查詢和文檔攝入的API端點,從而確保使用FastAPI平穩操作。
  • 在Raspberry Pi上部署和測試完整的應用程序,以確保後端和前端組件同時無縫函數。
  • 了解FastApi和Reflex之間的集成,以獲得凝聚力的RAG應用體驗。
  • 實施和故障排除FastApi和Reflex組件,以在Raspberry Pi上提供完全操作的抹布應用。

如果您錯過了上一版,請務必在此處查看:帶有Langchain和Ollama的邊緣設備上的自託管破布應用程序 - 第一部分

目錄

  • 創建Python環境
  • 使用FastApi開發後端
  • 用反射設計前端
  • 測試和部署
  • 常見問題

本文作為數據科學博客馬拉鬆的一部分發表

創建Python環境

在創建應用程序開始之前,我們需要設置環境。創建環境並安裝以下依賴關係:

深石 
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 
蘭鏈核== 0.2.11 
Langchain-驗證== 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
Reflex-hosting-cli == 0.1.13

安裝了所需的軟件包後,我們需要在設備中放置所需的型號。我們將使用Ollama來做到這一點。請按照本文第1部分的步驟下載語言和嵌入模型。最後,為後端和前端應用程序創建兩個目錄。

一旦使用Ollama拉動了模型,我們就準備構建最終應用程序。

使用FastApi開發後端

在本文的第1部分中,我們建立了具有攝入和QNA模塊的抹布管道。我們已經使用一些文檔對兩個管道進行了測試,並且它們正常工作。現在,我們需要用FastAPI包裝管道來創建易於使用的API。這將有助於我們將其與任何前端應用程序集成在一起,例如簡化,鏈條,Gradio,Reflex,React,Angular等。讓我們首先構建應用程序的結構。遵循結構是完全可選的,但是如果您遵循其他結構來創建應用程序,請確保檢查依賴關係導入。

以下是我們將遵循的樹結構:

後端
├ -  app.py
├ - ─txt
└ -  src
    ├─Config.py
    ├─doc_loader
    │││─-base_loader.py
    │├├前__init__.py
    PDF_LOADER.PY
    ├─攝取
    ├ -  __init__.py
    └─QNA.PY

讓我們從config.py開始。該文件將包含應用程序的所有可配置選項,例如Ollama URL,LLM名稱和嵌入式模型名稱。以下是一個示例:

 lanking_model_name =“ phi3”
embeddings_model_name =“ nomic-embed-text”
Ollama_url =“ http:// localhost:11434”

base_loader.py文件包含由孩子Document Loader繼承的父文檔加載程序類。在此應用程序中,我們僅使用PDF文件,因此Child PDFLoader類將是
創建將繼承基本負載類。

以下是base_loader.py和pdf_loader.py的內容:

 #base_loader.py
來自ABC Import ABC,AbstractMethod

班級加載工(ABC):
    def __init __(self,file_path:str) - >無:
        self.file_path = file_path

    @AbstractMethod
    異步def load_document(self):
        經過


#pdf_loader.py
導入操作系統

來自.base_loader導入基本負載器
來自langchain.schema導入文檔
來自langchain.document_loaders.pdf導入pymupdfloader
來自langchain.text_splitter導入tarnextsplitter


PDFLOADER類(基本負載器):
    def __init __(self,file_path:str) - >無:
        super().__ INT __(file_path)

    異步def load_document(self):
        self.file_name = os.path.basename(self.file_path)
        loader = pymupdfloader(file_path = self.file_path)

        text_splitter = partinextsplitter(
            saparator =“ \ n”,
            chunk_size = 1000,
            chunk_overlap = 200,
        )
        頁面=等待loader.aload()
        total_pages = len(頁)
        塊= []
        對於IDX,枚舉(頁)中的頁面:
            chunks.append(
                文件(
                    page_content = pag.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的工作。

接下來,讓我們構建攝入類。這與我們在本文第1部分中構建的那個相同。

攝入的代碼

導入操作系統
導入config作為CFG

來自Pinecone Import Pinecone
來自langchain.Vectorstores.Deeplake Import Deeplake
來自langchain.embeddings.ollama進口Ollamaembeddings
來自.doc_loader導入pdfloader

類攝入:
    “”“記錄攝入管道。”“”
    def __init __(自我):
        嘗試:
            self.embeddings = ollamaembeddings(
                型號= 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,
                冗長= false,
            )
        除例外為E:
            提高RuntimeError(F“無法初始化攝入系統。錯誤:{e}”)

    異步def create_and_add_embeddings(
        自己,
        文件:str,,
    ):
        嘗試:
            loader = pdfloader(
                file_path =文件,
            )

            塊=等待loader.load_document()
            size =等待self.vector_store.aadd_documents(documents =塊)
            返回Len(尺寸)
        除(valueerror,runtimeerror,keyError,typeError)作為e:
            提高異常(f“錯誤:{e}”)

現在,我們已經設置了攝入類,我們將繼續創建QNA類。這也與我們在本文第1部分中創建的那個相同。

QNA類代碼

導入操作系統
導入config作為CFG

來自Pinecone Import Pinecone
來自langchain.Vectorstores.Deeplake Import Deeplake
來自langchain.embeddings.ollama進口Ollamaembeddings
來自langchain_community.llms.ollama import ollama
來自.doc_loader導入pdfloader

QNA類:
    “”“記錄攝入管道。”“”
    def __init __(自我):
        嘗試:
            self.embeddings = ollamaembeddings(
                型號= cfg.embeddings_model_name,
                base_url = cfg.ollama_url,
                show_progress = true,
            )
            self.model = ollama(
                型號= cfg.language_model_name,
                base_url = cfg.ollama_url,
                詳細= true,
                溫度= 0.2,
            )
            self.vector_store = deeplake(
                dataset_path =“ data/text_vectorstore”,
                嵌入= self.embeddings,
                num_workers = 4,
                冗長= false,
            )
            self.triever = self.vector_store.as_retriever(
                search_type =“相似性”,
                search_kwargs = {
                    “ K”:10,
                },,
            )
        除例外為E:
            提高RuntimeError(F“無法初始化攝入系統。錯誤:{e}”)

    def create_rag_chain(self):
        嘗試:
            system_prompt =“”“”
            ”“”
            提示= chatprompttemplate.from_messages(
                [
                    (“系統”,system_prompt),
                    (“人類”,“ {input}”),
                這是給出的
            )
            Question_answer_chain = create_stuff_documents_chain(self.model,提示)
            rag_chain = create_retrieval_chain(self.triever,Question_answer_chain)

            返回rag_chain
        除例外為E:
            提高RuntimeError(F“無法創建檢索鏈。錯誤:{e}”)

這樣,我們已經完成了創建RAG應用程序的代碼功能。現在,讓我們用fastapi包裝該應用程序。

FastAPI應用程序的代碼

導入系統
導入操作系統
導入紫外線

從SRC進口QNA攝入
來自FastAPI Import FastApi,請求,文件,uploadfile
來自fastapi.Respons import streamResponse

app = fastapi()

攝入=攝入()
chatbot = qna()
rag_chain = chatbot.create_rag_chain()


@app.get(“/”)
def hello():
    返回{“消息”:“在服務器8089中運行的API}


@app.post(“/query”)
異步def ask_query(請求:請求):
    data =等待請求.json()
    問題= data.get(“問題”)

    異步def event_generator():
        對於rag_chain.pick中的塊(“答案”)。
            產生塊

    返回streamingresponse(event_generator(),媒體_type =“ text/plain”)


@app.post(“/ingest”)
異步def ingest_document(文件:uploadfile = file(...)):
    嘗試:
        os.makedirs(“文件”,equent_ok = true)
        file_location = f“ files/{file.filename}”
        使用file_object的打開(file_location,“ wb”):
            file_object.write(file.file.read())

        size =等待攝入.create_and_add_embeddings(file = file_location)
        返回{“消息”:f“攝入文件!文檔計數:{size}”}
    除例外為E:
        返回{“消息”:f“發生錯誤:{e}”}


如果__name__ ==“ __ -main __”:
    嘗試:
        uvicorn.run(app,host =“ 0.0.0.0”,端口= 8089)
    除了鍵盤間斷為E:
        打印(“應用程序停止!”)

讓我們通過每個端點分解應用程序:

  • 首先,我們初始化FastApi應用程序,攝入和QNA對象。然後,我們使用QNA類的create_rag_chain方法創建一個抹布鏈。
  • 我們的第一個終點是一個簡單的獲取方法。這將有助於我們知道該應用是否健康。將其視為“ Hello World”終點。
  • 第二個是查詢端點。這是一種帖子方法,將用於運行鏈條。它採用一個請求參數,我們從中提取用戶的查詢。然後,我們創建了一種異步方法,該方法在鏈條函數呼叫周圍充當異步包裝器。我們需要這樣做,以允許FastApi處理LLM的流函數調用,以在聊天界面中獲得類似ChatGpt的體驗。然後,我們將異步方法與StreamResponse類包裝並返回。
  • 第三端點是攝入端點。這也是一種帖子方法,將整個文件作為輸入作為字節。我們將此文件存儲在本地目錄中,然後使用攝入類的create_and_add_embeddings方法攝入。

最後,我們使用主機和端口使用Uvicorn軟件包運行該應用程序。要測試應用程序,只需使用以下命令運行應用程序:

 python app.py

帶有Langchain的邊緣設備上的自託管抹布應用

使用Postman,失眠或Bruno等API測試IDE測試應用程序。您也可以使用Thunder Client Extension進行相同的操作。

測試攝入端點:

帶有Langchain的邊緣設備上的自託管抹布應用

測試查詢端點:

帶有Langchain的邊緣設備上的自託管抹布應用

用反射設計前端

我們已經成功創建了一個用於後端的FastApi應用程序。是時候建立我們的前端了。您可以為此選擇任何前端庫,但是對於本文,我們將使用Reflex構建前端。 Reflex是一個僅使用Python的前端庫,純粹是使用Python構建Web應用程序的。它通過用於計算器,圖像生成和聊天機器人等常見應用程序的模板證明了我們。我們將使用聊天機器人應用模板作為用戶界面的啟動。我們的最終應用程序將具有以下結構,因此讓我們在此處參考。

前端目錄

我們將擁有一個前端目錄:

前端
├ - 資產
│└└前favicon.ico
├ - 文檔
│└ -  emo.gif
├ - 聊天
組件
││││站
│││├站file_upload.py
││├ -  __init__.py
││││─..poting_icon.py
│││├站
Navbar.py
│├├前__init__.py
Chat.py
sate.py
├ - ─txt
├─-rxConfig.py
└ - 上傳_files

最終應用程序的步驟

按照步驟準備最終應用程序的接地。

步驟1:在前端目錄中克隆聊天模板存儲庫

git克隆https://github.com/reflex-dev/reflex-chat.git。

步驟2:運行以下命令將目錄初始化為反射應用

Reflex Init

帶有Langchain的邊緣設備上的自託管抹布應用

這將設置Reflex應用程序,並準備好運行和開發。

步驟3:測試應用程序,使用從前端目錄內部的以下命令

反射運行

帶有Langchain的邊緣設備上的自託管抹布應用

讓我們開始修改組件。首先,讓我們修改chat.py文件。

以下是相同的代碼:

導入反射為Rx
來自reflex_demo.com import incort loading_icon
來自reflex_demo.State Import QA,狀態

messages_style = dict(dict)(
    display =“ inline-block”,
    填充=“ 0 10px”,
    border_radius =“ 8px”,
    max_width = [“ 30em”,“ 30em”,“ 50em”,“ 50em”,“ 50em”,“ 50em”],
)


DEF消息(QA:QA) - > rx.component:
    “”“一個問題/答案消息。

    args:
        QA:問題/答案對。

    返回:
        顯示問題/答案對的組件。
    ”“”
    返回rx.box(
        rx.box(
            rx.markdown(
                QA.問題,
                background_color = rx.color(“淡紫色”,4),,
                color = rx.color(“淡紫色”,12),
                ** Message_Style,
            ),
            text_align =“ right”,
            margin_top =“ 1em”,
        ),
        rx.box(
            rx.markdown(
                QA.ANSWER,
                background_color = rx.Color(“ Accent”,4),,
                color = rx.Color(“ Accent”,12),
                ** Message_Style,
            ),
            text_align =“左”,
            padding_top =“ 1em”,
        ),
        寬度=“ 100%”,
    )


def chat() - > rx.component:
    “”“列出單個對話中的所有消息。”“”
    返回rx.vstack(
        rx.box(rx.foreach(state.chats [state.current_chat],消息),width =“ 100%”),
        py =“ 8”,
        flex =“ 1”,
        寬度=“ 100%”,
        max_width =“ 50em”,
        padding_x =“ 4px”,
        align_self =“中心”,
        溢出=“隱藏”,
        padding_bottom =“ 5em”,
    )


def Action_bar() - > rx.component:
    ”“”“動作欄發送新信息。 ”“”
    返回rx.center(
        rx.vstack(
            rx.chakra.form(
                rx.chakra.form_control(
                    rx.hstack(
                        rx。輸入(
                            rx.input.slot(
                                rx.tooltip(
                                    rx.icon(“ info”,size = 18),
                                    content =“輸入一個問題以獲取答复。”,,
                                )
                            ),
                            佔位符=“鍵入某物...”,
                            ,,,,
                            width = [“ 15em”,“ 20em”,“ 45em”,“ 50EM”,“ 50EM”,“ 50EM”],
                        ),
                        rx.button(
                            rx.cond(
                                state.processing,
                                loading_icon(高度=“ 1em”),
                                rx.text(“ send”,font_family =“ ubuntu”),
                            ),
                            type =“提交”,
                        ),
                        align_items =“中心”,
                    ),
                    is_disabled = state.processing,
                ),
                on_submit = state.process_question,
                reset_on_submit = true,
            ),
            rx.text(
                “反射可能會返回事實不正確或誤導性響應。使用酌處權。”,
                text_align =“中心”,
                font_size =“。75EM”,
                color = rx.Color(“淡紫色”,10),
                font_family =“ ubuntu”,
            ),
            rx.logo(margin_top =“  -  1em”,margin_bottom =“  -  1em”),
            align_items =“中心”,
        ),
        位置=“粘性”,
        底部=“ 0”,
        左=“ 0”,
        padding_y =“ 16px”,
        backdrop_filter =“自動”,
        backdrop_blur =“ lg”,
        border_top = f“ 1px solid {rx.color('mauve',3)}”,
        background_color = rx.color(“淡紫色”,2),
        align_items =“ stract”,
        寬度=“ 100%”,
    )

這些變化是從模板中本地存在的最小化。

接下來,我們將編輯chat.py應用程序。這是主要的聊天組件。

主聊天組件的代碼

以下是它的代碼:

導入反射為Rx
來自reflex_demo.com.ponents導入聊天,navbar,upload_form
來自reflex_demo.State Extiment State


@rx.page(路由=“/chat”,title =“ rag chatbot”)
def chat_interface() - > rx.component:
    返回rx.chakra.vstack(
        navbar(),
        chat.chat(),
        chat.action_bar(),
        background_color = rx.color(“淡紫色”,1),
        color = rx.color(“淡紫色”,12),
        min_height =“ 100VH”,
        align_items =“ stract”,
        間距=“ 0”,
    )


@rx.page(route =“/”,title =“ rag chatbot”)
def index() - > rx.component:
    返回rx.chakra.vstack(
        navbar(),
        upload_form(),
        background_color = rx.color(“淡紫色”,1),
        color = rx.color(“淡紫色”,12),
        min_height =“ 100VH”,
        align_items =“ stract”,
        間距=“ 0”,
    )


#將狀態和頁面添加到應用程序。
app = rx.app(
    主題= rx.theme(
        外觀=“黑暗”,
        accent_color =“玉”,
    ),
    stylesheets = [“ https://fonts.googleapis.com/css2?family=ubuntu&display=swap”],
    樣式= {
        “ font_family”:“ ubuntu”,
    },,
)
app.add_page(索引)
app.add_page(chan_interface)

這是聊天接口的代碼。我們僅將字體系列添加到應用程序配置中,其餘代碼是相同的。

接下來,讓我們編輯state.py文件。這是前端將呼叫API端點以進行響應的地方。

編輯狀態.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())

    異步def process_question(self,form_data:dict [str,str]):
        #從表格中獲取問題
        問題= form_data [“問題”]

        #檢查問題是否為空
        如果問題==“”:
            返回

        型號= self.openai_process_question

        在模型中的價值異步(問題):
            產量值

    異步def openai_process_question(自我,問題:str):
        “”“從API獲取響應。

        args:
            form_data:一個帶有當前問題的dict。
        ”“”
        #將問題添加到問題列表中。
        QA = QA(問題=問題,答案=“”)
        self.chats [self.current_chat] .append(QA)
        有效載荷= {“問題”:問題}

        #清除輸入並開始處理。
        self.processing = true
        屈服

        響應= requests.post(self.url,json =有效載荷,流= true)

        #流式傳輸結果,在每個單詞之後產生。
        for Answers_text in enthys.iter_content(chunk_size = 512):
            #確保答案_text在串聯之前不是沒有
            答案_text = wherme_text.decode()
            如果答案_text不是沒有:
                self.Chats [self.current_chat] [ -  1] .answer = answers_text
            別的:
                答案_text =“”
                self.Chats [self.current_chat] [ -  1] .answer = answers_text
            self.chats = self.chats
            屈服

        #切換處理標誌。
        self.processing = false

在此文件中,我們為查詢端點定義了URL。我們還修改了OpenAI_Process_Question方法,以將郵政請求發送到查詢端點並獲取流媒體
響應,將顯示在聊天接口中。

編寫file_upload.py文件的內容

最後,讓我們編寫file_upload.py文件的內容。此組件將在開頭顯示,這將使我們可以上傳文件以進行攝入。

導入反射為Rx
導入操作系統
進口時間

導入請求


類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(self,files:list [rx.uploadfile]):
        self.ingesting = true
        屈服
        用於文件中的文件:
            file_bytes =等待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
            屈服
            如果響應。 STATUS_CODE== 200:
                #屈服rx.redirect(“/chat”)
                self.show_redirect_popup()

    def handle_upload_progress(自我,進度:dict):
        self.uploading = true
        self.progress = rough(進度[“進度”] * 100)
        如果self.progress> = 100:
            self.uploading = false

    def cancel_upload(self):
        self.uploading = false
        返回rx.cancel_upload(“ upload3”)


def upload_form():
    返回rx.vstack(
        rx.upload(
            rx.Flex(
                rx.text(
                    “在這裡拖放文件或單擊以選擇文件”,
                    font_family =“ ubuntu”,
                ),
                rx.icon(“上傳”,大小= 30),
                方向=“列”,
                align =“中心”,
            ),
            ,,,,
            border =“ 1px固體RGB(233,233,233,0.4)”,
            margin =“ 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。
            rx.button(
                “上傳”,
                on_click = uploadexample.handle_upload(
                    rx.upload_files(
                        上傳_,
                        on_upload_progress = uploadexample.handle_upload_progress,
                    ),
                ),
            ),
            rx.Flex(
                rx.spinner(size =“ 3”,加載= uploadexample.ingesting),
                rx.button(
                    “取消”,
                    on_click = uploadexample.cancel_upload,
                ),
                align =“中心”,
                間距=“ 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 =“綠色”,
                            變體=“固體”,
                            on_click = rx.redirect(“/chat”),
                        ),
                    ),
                    間距=“ 3”,
                    margin_top =“ 16px”,
                    Justify =“ End”,
                ),
                樣式= {“ max_width”:450},
            ),
        ),
        align =“中心”,
    )

此組件將允許我們上傳文件並將其攝入矢量存儲。它使用我們的FastApi應用程序的攝入端點上傳和攝入文件。攝入後,用戶可以簡單地移動
到聊天界面詢問查詢。

這樣,我們已經完成了為我們的應用程序構建前端。現在,我們需要使用一些文檔來測試應用程序。

測試和部署

現在,讓我們在某些手冊或文檔上測試應用程序。要使用該應用程序,我們需要單獨運行後端應用程序和Reflex應用程序。使用該目錄運行後端應用
以下命令:

 python app.py

等待FastApi開始運行。然後在另一個終端實例中使用以下命令運行前端應用:

反射運行

應用程序正在啟動和運行,到達以下URL訪問Reflex應用程序。最初,我們將在文件上傳頁面中。上傳文件,然後按“上傳”按鈕。

帶有Langchain的邊緣設備上的自託管抹布應用

該文件將上傳並攝入。這將需要一段時間,具體取決於文檔的大小和
設備規格。完成後,單擊“繼續聊天”按鈕以移至聊天接口。編寫您的查詢,然後按發送。

結論

在Thistwo Parteries中,您現在您在Raspberry Pi上構建了一個完整且功能上功能的RAG應用程序,從創建核心管道到用FastApi後端包裝並開發基於反射的前端。借助這些工具,您的破布管道是可訪問且交互式的,可通過用戶友好的Web界面提供實時查詢處理。通過掌握這些步驟,您在緊湊,高效的平台上構建和部署端到端應用程序方面獲得了寶貴的經驗。這種設置為在Raspberry Pi(例如Raspberry Pi)上部署AI驅動應用程序的無數可能性打開了大門,這使得最先進的技術更容易訪問和實用。

關鍵要點

  • 提供了有關設置開發環境的詳細指南,包括使用Ollama安裝必要的依賴項和模型,以確保該應用程序已準備好最終構建。
  • 本文解釋瞭如何將RAG管道包裹在FastAPI應用程序中,包括設置查詢模型和攝入文檔的終點,使該管道可以通過Web API訪問。
  • RAG應用程序的前端是使用Reflex(僅Python的前端庫Reflex構建的。本文演示瞭如何修改聊天應用程序模板以創建用於與RAG管道進行交互的用戶友好界面。
  • 本文指南將FastAPI後端與反射前端集成在一起,並在Raspberry Pi上部署完整的應用程序,以確保無縫操作和用戶可訪問性。
  • 提供了使用Postman或Thunder Client等工具來測試攝入和查詢端點的實用步驟,同時運行和測試反射前端,以確保整個應用程序按預期功能。

常見問題

問題1:如何使自己可以從世界任何地方訪問該應用程序而不會損害安全性?

答:有一個名為TailScale的平台,允許您的設備連接到私人安全網絡,僅可訪問您。您可以將Raspberry Pi和其他設備添加到尾部設備中,並連接到VPN以訪問您的應用程序。

Q2:我的攝入和QNA的應用非常慢。

答:由於覆盆子PI的硬件規格較低,這是限制。這篇文章只是有關如何使用Raspberry Pi和Ollama構建RAG應用程序的主題教程。

本文所示的媒體不由Analytics Vidhya擁有,並由作者酌情使用。

以上是帶有Langchain的邊緣設備上的自託管抹布應用的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
大多數使用的10個功率BI圖 - 分析Vidhya大多數使用的10個功率BI圖 - 分析VidhyaApr 16, 2025 pm 12:05 PM

用Microsoft Power BI圖來利用數據可視化的功能 在當今數據驅動的世界中,有效地將復雜信息傳達給非技術觀眾至關重要。 數據可視化橋接此差距,轉換原始數據i

AI的專家系統AI的專家系統Apr 16, 2025 pm 12:00 PM

專家系統:深入研究AI的決策能力 想像一下,從醫療診斷到財務計劃,都可以訪問任何事情的專家建議。 這就是人工智能專家系統的力量。 這些系統模仿Pro

三個最好的氛圍編碼器分解了這項代碼中的AI革命三個最好的氛圍編碼器分解了這項代碼中的AI革命Apr 16, 2025 am 11:58 AM

首先,很明顯,這種情況正在迅速發生。各種公司都在談論AI目前撰寫的代碼的比例,並且這些代碼的比例正在迅速地增加。已經有很多工作流離失所

跑道AI的Gen-4:AI蒙太奇如何超越荒謬跑道AI的Gen-4:AI蒙太奇如何超越荒謬Apr 16, 2025 am 11:45 AM

從數字營銷到社交媒體的所有創意領域,電影業都站在技術十字路口。隨著人工智能開始重塑視覺講故事的各個方面並改變娛樂的景觀

如何註冊5天ISRO AI免費課程? - 分析Vidhya如何註冊5天ISRO AI免費課程? - 分析VidhyaApr 16, 2025 am 11:43 AM

ISRO的免費AI/ML在線課程:通向地理空間技術創新的門戶 印度太空研究組織(ISRO)通過其印度遙感研究所(IIR)為學生和專業人士提供了絕佳的機會

AI中的本地搜索算法AI中的本地搜索算法Apr 16, 2025 am 11:40 AM

本地搜索算法:綜合指南 規劃大規模活動需要有效的工作量分佈。 當傳統方法失敗時,本地搜索算法提供了強大的解決方案。 本文探討了爬山和模擬

OpenAI以GPT-4.1的重點轉移,將編碼和成本效率優先考慮OpenAI以GPT-4.1的重點轉移,將編碼和成本效率優先考慮Apr 16, 2025 am 11:37 AM

該版本包括三種不同的型號,GPT-4.1,GPT-4.1 MINI和GPT-4.1 NANO,標誌著向大語言模型景觀內的特定任務優化邁進。這些模型並未立即替換諸如

提示:chatgpt生成假護照提示:chatgpt生成假護照Apr 16, 2025 am 11:35 AM

Chip Giant Nvidia週一表示,它將開始製造AI超級計算機(可以處理大量數據並運行複雜算法的機器),完全是在美國首次在美國境內。這一消息是在特朗普總統SI之後發布的

See all articles

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

AI Hentai Generator

AI Hentai Generator

免費產生 AI 無盡。

熱門文章

R.E.P.O.能量晶體解釋及其做什麼(黃色晶體)
4 週前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳圖形設置
4 週前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.如果您聽不到任何人,如何修復音頻
1 個月前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.聊天命令以及如何使用它們
1 個月前By尊渡假赌尊渡假赌尊渡假赌

熱工具

MantisBT

MantisBT

Mantis是一個易於部署的基於Web的缺陷追蹤工具,用於幫助產品缺陷追蹤。它需要PHP、MySQL和一個Web伺服器。請查看我們的演示和託管服務。

SAP NetWeaver Server Adapter for Eclipse

SAP NetWeaver Server Adapter for Eclipse

將Eclipse與SAP NetWeaver應用伺服器整合。

VSCode Windows 64位元 下載

VSCode Windows 64位元 下載

微軟推出的免費、功能強大的一款IDE編輯器

SublimeText3 英文版

SublimeText3 英文版

推薦:為Win版本,支援程式碼提示!

ZendStudio 13.5.1 Mac

ZendStudio 13.5.1 Mac

強大的PHP整合開發環境