1、下載ollama
1)https://ollama.com 進入網址,點選download下載
2)下載後直接安裝即可。
2、啟動配置模型
預設是啟動cmd視窗直接輸入
1 ollama run llama3
啟動llama3大模型 或者啟動千問大模型
1 ollama run qwen2
啟動輸入你需要輸入的問題即可
3、配置UI介面
安裝docker
並部署web操作介面
1 docker run -d -p 3000:8080 --add-host=host.docker.internal:host-gateway -v open-webui --restart always ghcr.io/open-webui/open-webui:main
安裝完畢後,安裝包較大,需等待一段時間。
localhost:3000即可開啟網址
4、搭建本地知識庫
AnythingLLM
5、配置檔案
開發11434埠,便於外部訪問介面,如果跨域訪問的話配置OLLAMA_ORIGINS=*
Windows版
只需要在系統環境變數中直接配置,
OLLAMA_HOST為變數名,"0.0.0.0:11434"為變數值
1 OLLAMA_HOST= "0.0.0.0:11434"
MAC版
配置OLLAMA_HOST
1 sudo sh -c 'echo "export OLLAMA_HOST=0.0.0.0:11434">>/etc/profile'launchctl setenv OLLAMA_HOST "0.0.0.0:11434"
Linux版
配置OLLAMA_HOST
1 Environment="OLLAMA\_HOST=0.0.0.0"
6、程式呼叫介面
golang實現例子:流式響應速度更快,使用者體驗更佳。
golang例子:非流式響應
package main
import (
"bufio"
"bytes"
"encoding/json"
"fmt"
"io/ioutil"
"net/http"
"os"
"strings"
"time"
)
const (
obaseURL = "http://localhost:11434/api"
omodelID = "qwen2:0.5b" // 選擇合適的模型
oendpoint = "/chat" //"/chat/completions"
)
// ChatCompletionRequest 定義了請求體的結構
type olChatCompletionRequest struct {
Model string `json:"model"`
Messages []struct {
Role string `json:"role"`
Content string `json:"content"`
} `json:"messages"`
Stream bool `json:"stream"`
//Temperature float32 `json:"temperature"`
}
// ChatCompletionResponse 定義了響應體的結構
type olChatCompletionResponse struct {
//Choices []struct {
Message struct {
Role string `json:"role"`
Content string `json:"content"`
} `json:"message"`
//} `json:"choices"`
}
// sendRequestWithRetry 傳送請求並處理可能的429錯誤
func olsendRequestWithRetry(client *http.Client, requestBody []byte) (*http.Response, error) {
req, err := http.NewRequest("POST", obaseURL+oendpoint, bytes.NewBuffer(requestBody))
if err != nil {
return nil, err
}
req.Header.Set("Content-Type", "application/json")
//req.Header.Set("Authorization", "Bearer "+apiKey)
resp, err := client.Do(req)
if err != nil {
return nil, err
}
if resp.StatusCode == http.StatusTooManyRequests {
retryAfter := resp.Header.Get("Retry-After")
if retryAfter != "" {
duration, _ := time.ParseDuration(retryAfter)
time.Sleep(duration)
} else {
time.Sleep(5 * time.Second) // 預設等待5秒
}
return olsendRequestWithRetry(client, requestBody) // 遞迴重試
}
return resp, nil
}
func main() {
client := &http.Client{} // 建立一個全域性的 HTTP 客戶端例項
// 初始化對話歷史記錄
history := []struct {
Role string `json:"role"`
Content string `json:"content"`
}{
{"system", "你是一位唐代詩人,特別擅長模仿李白的風格。"},
}
// 建立標準輸入的掃描器
scanner := bufio.NewScanner(os.Stdin)
for {
fmt.Print("請輸入您的問題(或者輸入 'exit' 退出): ")
scanner.Scan()
userInput := strings.TrimSpace(scanner.Text())
// 退出條件
if userInput == "exit" {
fmt.Println("感謝使用,再見!")
break
}
// 新增使用者輸入到歷史記錄
history = append(history, struct {
Role string `json:"role"`
Content string `json:"content"`
}{
"user",
userInput,
})
// 建立請求體
requestBody := olChatCompletionRequest{
Model: omodelID,
Messages: history,
Stream: false,
//Temperature: 0.7,
}
// 構建完整的請求體,包含歷史訊息
requestBody.Messages = append([]struct {
Role string `json:"role"`
Content string `json:"content"`
}{
{
Role: "system",
Content: "你是一位唐代詩人,特別擅長模仿李白的風格。",
},
}, history...)
// 將請求體序列化為 JSON
requestBodyJSON, err := json.Marshal(requestBody)
if err != nil {
fmt.Println("Error marshalling request body:", err)
continue
}
fmt.Println("wocao:" + string(requestBodyJSON))
// 傳送請求並處理重試
resp, err := olsendRequestWithRetry(client, requestBodyJSON)
if err != nil {
fmt.Println("Error sending request after retries:", err)
continue
}
defer resp.Body.Close()
// 檢查響應狀態碼
if resp.StatusCode != http.StatusOK {
fmt.Printf("Received non-200 response status code: %d\n", resp.StatusCode)
continue
}
// 讀取響應體
responseBody, err := ioutil.ReadAll(resp.Body)
if err != nil {
fmt.Println("Error reading response body:", err)
continue
}
//fmt.Println("0000" + string(responseBody))
// 解析響應體
var completionResponse olChatCompletionResponse
err = json.Unmarshal(responseBody, &completionResponse)
if err != nil {
fmt.Println("Error unmarshalling response body:", err)
continue
}
fmt.Printf("AI 回覆: %s\n", completionResponse.Message.Content) // choice.Message.Content
// 將使用者的訊息新增到歷史記錄中
history = append(history, struct {
Role string `json:"role"`
Content string `json:"content"`
}{
Role: completionResponse.Message.Role,
Content: completionResponse.Message.Content, // 假設使用者的訊息是第一個
})
}
}
golang例子:流式響應
1 package main 2 3 import ( 4 "bufio" 5 "bytes" 6 "encoding/json" 7 "fmt" 8 "io" 9 "net/http" 10 "os" 11 "strings" 12 "time" 13 ) 14 15 const ( 16 obaseURL = "http://localhost:11434/api" 17 omodelID = "qwen2:0.5b" // 選擇合適的模型 18 oendpoint = "/chat" //"/chat/completions" 19 ) 20 21 // ChatCompletionRequest 定義了請求體的結構 22 type olChatCompletionRequest struct { 23 Model string `json:"model"` 24 Messages []struct { 25 Role string `json:"role"` 26 Content string `json:"content"` 27 } `json:"messages"` 28 Stream bool `json:"stream"` 29 //Temperature float32 `json:"temperature"` 30 } 31 32 // ChatCompletionResponse 定義了響應體的結構 33 type olChatCompletionResponse struct { 34 //Choices []struct { 35 Message struct { 36 Role string `json:"role"` 37 Content string `json:"content"` 38 } `json:"message"` 39 //} `json:"choices"` 40 } 41 42 // sendRequestWithRetry 傳送請求並處理可能的429錯誤 43 func olsendRequestWithRetry(client *http.Client, requestBody []byte) (*http.Response, error) { 44 req, err := http.NewRequest("POST", obaseURL+oendpoint, bytes.NewBuffer(requestBody)) 45 if err != nil { 46 return nil, err 47 } 48 49 req.Header.Set("Content-Type", "application/json") 50 //req.Header.Set("Authorization", "Bearer "+apiKey) 51 52 resp, err := client.Do(req) 53 if err != nil { 54 return nil, err 55 } 56 57 if resp.StatusCode == http.StatusTooManyRequests { 58 retryAfter := resp.Header.Get("Retry-After") 59 if retryAfter != "" { 60 duration, _ := time.ParseDuration(retryAfter) 61 time.Sleep(duration) 62 } else { 63 time.Sleep(5 * time.Second) // 預設等待5秒 64 } 65 return olsendRequestWithRetry(client, requestBody) // 遞迴重試 66 } 67 68 return resp, nil 69 } 70 71 func main() { 72 client := &http.Client{} // 建立一個全域性的 HTTP 客戶端例項 73 74 // 初始化對話歷史記錄 75 history := []struct { 76 Role string `json:"role"` 77 Content string `json:"content"` 78 }{ 79 {"system", "你是一位唐代詩人,特別擅長模仿李白的風格。"}, 80 } 81 82 // 建立標準輸入的掃描器 83 scanner := bufio.NewScanner(os.Stdin) 84 85 for { 86 fmt.Print("請輸入您的問題(或者輸入 'exit' 退出): ") 87 scanner.Scan() 88 userInput := strings.TrimSpace(scanner.Text()) 89 90 // 退出條件 91 if userInput == "exit" { 92 fmt.Println("感謝使用,再見!") 93 break 94 } 95 96 // 新增使用者輸入到歷史記錄 97 history = append(history, struct { 98 Role string `json:"role"` 99 Content string `json:"content"` 100 }{ 101 "user", 102 userInput, 103 }) 104 105 // 建立請求體 106 requestBody := olChatCompletionRequest{ 107 Model: omodelID, 108 Messages: history, 109 Stream: true, 110 //Temperature: 0.7, 111 } 112 113 // 構建完整的請求體,包含歷史訊息 114 requestBody.Messages = append([]struct { 115 Role string `json:"role"` 116 Content string `json:"content"` 117 }{ 118 { 119 Role: "system", 120 Content: "你是一位唐代詩人,特別擅長模仿李白的風格。", 121 }, 122 }, history...) 123 124 // 將請求體序列化為 JSON 125 requestBodyJSON, err := json.Marshal(requestBody) 126 if err != nil { 127 fmt.Println("Error marshalling request body:", err) 128 continue 129 } 130 fmt.Println("wocao:" + string(requestBodyJSON)) 131 // 傳送請求並處理重試 132 resp, err := olsendRequestWithRetry(client, requestBodyJSON) 133 if err != nil { 134 fmt.Println("Error sending request after retries:", err) 135 continue 136 } 137 defer resp.Body.Close() 138 139 // 檢查響應狀態碼 140 if resp.StatusCode != http.StatusOK { 141 fmt.Printf("Received non-200 response status code: %d\n", resp.StatusCode) 142 continue 143 } 144 resutlmessage := "" 145 streamReader := resp.Body 146 buf := make([]byte, 1024) // 或者使用更大的緩衝區來提高讀取效能 147 var completionResponse olChatCompletionResponse 148 fmt.Print("AI 回覆:") 149 for { 150 n, err := streamReader.Read(buf) 151 if n > 0 { 152 // 處理接收到的資料,這裡簡單列印出來 153 //fmt.Print(string(buf[:n])) 154 err = json.Unmarshal(buf[:n], &completionResponse) 155 fmt.Print(string(completionResponse.Message.Content)) 156 resutlmessage+=string(completionResponse.Message.Content) 157 if err != nil { 158 fmt.Println("Error unmarshalling response body:", err) 159 continue 160 } 161 } 162 if err != nil { 163 if err == io.EOF { 164 fmt.Println("") 165 break 166 } 167 panic(err) 168 } 169 } 170 171 // 將使用者的訊息新增到歷史記錄中 172 history = append(history, struct { 173 Role string `json:"role"` 174 Content string `json:"content"` 175 }{ 176 Role: completionResponse.Message.Role, 177 Content: resutlmessage,//completionResponse.Message.Content, // 假設使用者的訊息是第一個 178 }) 179 } 180 }
感謝觀看,謝謝!