開發個人Go-ChatGPT--5 模型管理 (一)

開發個人Go-ChatGP–5 模型管理 (一)

背景

開發一個chatGPT的網站,后端服務如何實現與大模型的對話?是整個項目中開發困難較大的點。
chat-GPT

如何實現上圖的聊天對話功能?在開發后端的時候,如何實現stream的響應呢?本文就先介紹后端的原理,逐步攻克這個課題。

環境部署

  • 啟動ollamadocker run -d -p 3000:8080 -p 11434:11434 -v ollama:/root/.ollama -v open-webui:/app/backend/data --name open-webui --restart always ollama/ollama

  • ollama 下載對話模型: docker exec -it open-webui ollama run gemma:2b

    pulling manifest 
    pulling c1864a5eb193... 100% ▕████████████████████████████████████████████████████████████████████████████████████████████████████████████████████▏ 1.7 GB                         
    pulling 097a36493f71... 100% ▕████████████████████████████████████████████████████████████████████████████████████████████████████████████████████▏ 8.4 KB                         
    pulling 109037bec39c... 100% ▕████████████████████████████████████████████████████████████████████████████████████████████████████████████████████▏  136 B                         
    pulling 22a838ceb7fb... 100% ▕████████████████████████████████████████████████████████████████████████████████████████████████████████████████████▏   84 B                         
    pulling 887433b89a90... 100% ▕████████████████████████████████████████████████████████████████████████████████████████████████████████████████████▏  483 B                         
    verifying sha256 digest 
    writing manifest 
    removing any unused layers 
    success
    

Stream reponse

前端

        ....const [res, controller] = await generateChatCompletion(localStorage.token, {model: model,messages: messagesBody,options: {...($settings.options ?? {})},format: $settings.requestFormat ?? undefined,keep_alive: $settings.keepAlive ?? undefined,docs: docs.length > 0 ? docs : undefined});if (res && res.ok) {console.log('controller', controller);const reader = res.body.pipeThrough(new TextDecoderStream()).pipeThrough(splitStream('\n')).getReader();...

ollamaopen-webui 前端項目實現和人類一樣溝通的方法,使用的是stream監聽 messages事件收到的響應,保持長連接的狀態,逐漸將收到的消息顯示到前端,直到后端響應結束。

后端

  • gin.Stream
...c.Stream(func(w io.Writer) bool {select {case msg, ok := <-msgChan:if !ok {// 如果msgChan被關閉,則結束流式傳輸return false}fmt.Print(msg)// 流式響應,發送給 messages 事件,和前端進行交互c.SSEvent("messages", msg)return truecase <-c.Done():// 如果客戶端連接關閉,則結束流式傳輸return false}})
...
  • ollama 響應
...// llms.WithStreamingFunc 將ollama api 的響應內容逐漸返回,而不是一次性全部返回callOp := llms.WithStreamingFunc(func(ctx context.Context, chunk []byte) error {select {case msgChan <- string(chunk):case <-ctx.Done():return ctx.Err() // 返回上下文的錯誤}return nil})_, err := llaClient.Call(context.Background(), prompt, callOp)if err != nil {log.Fatalf("Call failed: %v", err) // 處理錯誤,而不是 panic}
...
  • 完整代碼
package mainimport ("context""fmt""io""log""net/http""github.com/gin-gonic/gin""github.com/tmc/langchaingo/llms""github.com/tmc/langchaingo/llms/ollama"
)func main() {router := gin.Default()router.GET("/ping", func(c *gin.Context) {c.JSON(http.StatusOK, gin.H{"message": "OK",})})router.POST("/chat", chat)router.Run(":8083")
}type Prompt struct {Text string `json:"text"`
}func chat(c *gin.Context) {var prompt Promptif err := c.BindJSON(&prompt); err != nil {c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})return}var msgChan = make(chan string)// 通過chan 將ollama 響應返回給前端go Generate(prompt.Text, msgChan)c.Stream(func(w io.Writer) bool {select {case msg, ok := <-msgChan:if !ok {// 如果msgChan被關閉,則結束流式傳輸return false}// fmt.Print(msg)c.SSEvent("messages", msg)return truecase <-c.Done():// 如果客戶端連接關閉,則結束流式傳輸return false}})
}var llaClient *ollama.LLMfunc init() {// Create a new Ollama instance// The model is set to "gemma:2b"// remote url is set to "http://ollama-ip:11434"url := ollama.WithServerURL("http://ollama-ip:11434")lla, err := ollama.New(ollama.WithModel("gemma:2b"), url)if err != nil {panic(err)}llaClient = llafmt.Println("connect to ollama server successfully")
}func Generate(prompt string, msgChan chan string) {// ctx, cancel := context.WithTimeout(context.Background(), time.Second*5) // 設置超時// defer cancel()                                                          // 確保在函數結束時取消上下文callOp := llms.WithStreamingFunc(func(ctx context.Context, chunk []byte) error {select {case msgChan <- string(chunk):case <-ctx.Done():return ctx.Err() // 返回上下文的錯誤}return nil})_, err := llaClient.Call(context.Background(), prompt, callOp)if err != nil {log.Fatalf("Call failed: %v", err) // 處理錯誤,而不是 panic}// 確保在所有數據處理完畢后關閉 msgChanclose(msgChan)
}

項目地址

jackwillsmith/openui-svelte-build (github.com)

GitHub - jackwillsmith/openui-backend-go: openui-backend-go

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/40629.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/40629.shtml
英文地址,請注明出處:http://en.pswp.cn/web/40629.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Vue-Router4.0 報“Cannot read property ‘forEach‘ of undefined”

Vue-Router4.0在創建路由時 報“Cannot read property ‘forEach‘ of undefined” 解決辦法 將路由規則名稱更改為routes&#xff0c;否則報錯 import { createWebHashHistory, createRouter } from vue-router; // 創建路由規定 const routes [{path: /login,name: login,co…

Linux Docker 防火墻設置 放通 MySQL(3306) Redis(6379) 端口

Linux Docker 防火墻設置 放通 MySQL(3306) Redis(6379) 端口&#xff0c;使用firewalld 防火墻或iptables &#xff0c;因此嘗試重新啟動 firewalld 服務&#xff0c;添加防火墻規則&#xff0c;并檢查防火墻狀態。以下是詳細步驟&#xff1a; 1. 啟動 firewalld 服務 首先啟…

qt opencv 應用舉例

在Qt中使用OpenCV可以實現各種圖像處理和計算機視覺任務。以下是一些Qt與OpenCV聯合應用的具體舉例&#xff1a; 1. 圖像讀取與顯示 讀取圖像&#xff1a;使用OpenCV的imread函數可以方便地讀取各種格式的圖像文件&#xff0c;如.bmp、.jpg、.png等。這個函數返回一個Mat對象…

【Unity數據交互】Unity中使用二進制進行數據持久化

&#x1f468;?&#x1f4bb;個人主頁&#xff1a;元宇宙-秩沅 &#x1f468;?&#x1f4bb; hallo 歡迎 點贊&#x1f44d; 收藏? 留言&#x1f4dd; 加關注?! &#x1f468;?&#x1f4bb; 本文由 秩沅 原創 &#x1f468;?&#x1f4bb; 專欄交流&#x1f9e7;&…

SqlSugar分表筆記

1、使用SqlSugar的分表功能時&#xff0c;.net要使用.net core&#xff1b; 我開始使用的是.net freamwork4.72&#xff0c;程序報異常&#xff0c;沒能解決&#xff0c;換到.net core下面就正常&#xff1b; 2、SqlSugar自帶分表支持按季度、月、周、日進行分表&#x…

ArcGIS Pro SDK (七)編輯 15 版本控制選項

ArcGIS Pro SDK &#xff08;七&#xff09;編輯 15 版本控制選項 文章目錄 ArcGIS Pro SDK &#xff08;七&#xff09;編輯 15 版本控制選項獲取和設置版本控制選項 環境&#xff1a;Visual Studio 2022 .NET6 ArcGIS Pro SDK 3.0 獲取和設置版本控制選項 var vOptions A…

PostgreSQL 技術內幕(十七):FDW 實現原理與源碼解析

對于一定規模的系統而言&#xff0c;數據倉庫往往需要訪問外部數據來完成分析和計算。外部數據包裝器&#xff08;Foreign Data Wrapper&#xff0c; 簡稱 FDW&#xff09;是 PostgreSQL 提供的訪問外部數據源機制。用戶可以使用簡單的 SQL 語句訪問和操作外部數據源&#xff0…

Python面試題:Python 中的生成器(generator)是什么?有什么優點?

在Python中&#xff0c;生成器&#xff08;generator&#xff09;是一種特殊的迭代器&#xff0c;使用yield關鍵字生成值&#xff0c;可以逐個生成序列中的值&#xff0c;而不需要一次性將所有值加載到內存中。生成器函數在定義時使用def關鍵字&#xff0c;并包含一個或多個yie…

[word] Word如何快速生成一段文本 #知識分享#學習方法

Word如何快速生成一段文本 Word如何快速生成一段文本&#xff1f;有時候我們會用一大段文字來做一些功能測試&#xff0c;不少朋友的做法就是臉滾鍵盤&#xff0c;一頓亂按&#xff0c;這樣看起來文筆不通&#xff0c;看著也會比較難受&#xff0c;測試功能的效果也不怎么理想…

uniapp中實現跳轉鏈接到游覽器(安卓-h5)

uniapp中實現跳轉鏈接到游覽器&#xff08;安卓-h5&#xff09; 項目中需要做到跳轉到外部鏈接&#xff0c;網上找了很多都不是很符合自己的要求&#xff0c;需要編譯成app后是跳轉到游覽器打開鏈接&#xff0c;編譯成web是在新窗口打開鏈接。實現的代碼如下&#xff1a; 效果&…

java基于ssm+vue 旅游信息資源平臺

1前臺首頁功能模塊 旅游資源網站 &#xff0c;在系統首頁可以查看首頁、景點信息、酒店信息、客房信息、交流論壇、紅色文化、個人中心、后臺管理、客服等內容&#xff0c;如圖1所示。 圖1系統功能界面圖 用戶登錄、用戶注冊&#xff0c;在注冊頁面可以填寫用戶名、密碼、姓名…

Redis GEO 功能解析

Redis GEO 功能解析 引言 Redis GEO 是 Redis 數據庫提供的一個特殊功能,用于存儲地理位置信息,并支持基于地理位置的查詢。這一功能對于需要處理地理位置數據的現代應用程序來說非常寶貴,如外賣配送、社交媒體、地圖服務等。本文將詳細介紹 Redis GEO 的功能、使用方法,…

DFS之剪枝與優化——AcWing 165. 小貓爬山

DFS之剪枝與優化 定義 DFS之剪枝與優化指的是在執行深度優先搜索(DFS, Depth-First Search)時&#xff0c;采取的一系列策略來減少搜索空間&#xff0c;避免無效計算&#xff0c;從而加速找到問題的解。剪枝是指在搜索過程中&#xff0c;當遇到某些條件不符合解的要求或者可以…

產科管理信息系統源碼:產科電子病歷、高危孕產婦五色管理系統源碼 孕產婦健康管理信息平臺源碼

產科管理信息系統源碼&#xff1a;產科電子病歷、高危孕產婦五色管理系統源碼 孕產婦健康管理信息平臺源碼 產科電子病歷系統是以采集病人在整個醫療護理過程中所產生的各種信息。包括病案首頁、門診病歷、住院病歷、出院記錄、病人病程記錄等全部病歷文書&#xff1b;涵蓋文字…

宿舍報修小程序的設計

管理員賬戶功能包括&#xff1a;系統首頁&#xff0c;個人中心&#xff0c;管理員管理&#xff0c;基礎數據管理&#xff0c;論壇管理&#xff0c;故障上報管理&#xff0c;新聞信息管理&#xff0c;維修人員管理 微信端賬號功能包括&#xff1a;系統首頁&#xff0c;新聞信息…

node.js外賣小程序-計算機畢業設計源碼81838

摘要 自從計算機發展開始&#xff0c;計算機軟硬件相關技術的發展速度越來越快&#xff0c;在信息化高速發展的今天&#xff0c;計算機應用技術似乎已經應用到了各個領域。在餐飲行業&#xff0c;除了外賣以外就是到店里就餐&#xff0c;在店里就餐如果需要等待點餐的話&…

轉盤輸入法-單獨鼠標版本

序 轉盤輸入法&#xff0c;給你的聊天加點新意。它不用常見的九宮格或全鍵盤&#xff0c;而是把字母擺在圓盤上&#xff0c;一滑一滑&#xff0c;字就出來了&#xff0c;新鮮又直接。 單獨鼠標版本GIF演示 演示軟件下載 轉盤輸入法https://download.csdn.net/download/u0146…

zdppy+vue3+antd 實現表格數據渲染

基本用法 <template><a-table :columns"columns" :data-source"data"><template #headerCell"{ column }"><template v-if"column.key name"><span>xxx Name</span></template></temp…

免費鼠標連點器有嗎?需要付費嗎?鼠標連點器電腦版免費推薦6款!

在數字化時代&#xff0c;鼠標連點器成為了許多用戶提高工作效率、優化游戲體驗的得力助手。然而&#xff0c;面對市場上琳瑯滿目的鼠標連點器軟件&#xff0c;很多用戶都會產生疑問&#xff1a;是否有免費的鼠標連點器&#xff1f;它們真的需要付費嗎&#xff1f;今天&#xf…

名企面試必問30題(二十二)——你對加班的看法?

1.思路 實際上&#xff0c;很多公司詢問此問題&#xff0c;并非表明一定要加班&#xff0c;只是想測試您是否愿意為公司奉獻。在回答時&#xff0c;一定不能有諸如不接受加班、不接受 996 等話語&#xff0c;因為沒有公司能承諾永遠不加班。主要回答應圍繞因何原因加班&#xf…