随着本地部署 LLM(如 LLaMA、Gemma、Mistral)的需求增加,许多开发者希望能以原生语言如 Go 建构轻量的推理系统。本文将带你整合两个核心元件:
-
llm-go:负责 prompt 组装与聊天历史管理。
-
go-llama.cpp:封装了 C++ 的 llama.cpp GGUF 模型推理。
一、专案总览与架构
模组划分
Go-LLM-cpp/
├── cmd/
│ └── main.go # 主程式,控制聊天流程
├── llm/
│ ├── model.go # 包装 go-llama.cpp 初始化与推理
│ └── session.go # 组装 prompt,维护历史与人格
├── config/
│ └── persona.yaml # 可选的人格设定档
├── bin/
│ └── llm-go # llm-go 专案
│ └── go-llama.cpp # go-llama.cpp 专案
└── go.mod
二、模型准备与 go.mod 初始化
-
下载模型(GGUF 格式)
可使用 Ollama、huggingface 或 llama.cpp 社群提供的 gemma-2b.gguf、llama2-7b.gguf 模型。
建议放在 models/ 目录下:
models/gemma-2b.gguf
-
初始化 go module
go mod init github.com/yourname/llama-chatbot-go
go get github.com/go-skynet/go-llama.cpp
go get github.com/swdunlop/llm-go
三、模型包装(llm/model.go)
package llmimport (llama "github.com/go-skynet/go-llama.cpp"
)type Model struct {llm *llama.LLama
}func Load(modelPath string) (*Model, error) {m := llama.LoadModel(modelPath, llama.Params{ContextSize: 2048,Threads: 4,})return &Model{llm: m}, nil
}func (m *Model) Predict(prompt string) <-chan llama.PredictResult {return m.llm.Predict(llama.PredictOptions{Prompt: prompt,MaxTokens: 128,Stream: true,})
}func (m *Model) Close() {m.llm.Close()
}
四、聊天历史与 Prompt 构建(llm/session.go)
package llmimport "strings"type ChatSession struct {History []stringPersona string
}func NewSession(persona string) *ChatSession {return &ChatSession{History: []string{},Persona: persona,}
}func (s *ChatSession) BuildPrompt(input string) string {var builder strings.Builderbuilder.WriteString(s.Persona + "\n\n")for _, h := range s.History {builder.WriteString(h + "\n")}builder.WriteString("使用者: " + input + "\n助手:")return builder.String()
}func (s *ChatSession) Append(userInput, response string) {s.History = append(s.History, "使用者: "+userInput, "助手: "+response)
}
五、主程式:CLI 聊天循环(cmd/main.go)
package mainimport ("bufio""fmt""os""llama-chatbot-go/llm"
)func main() {model, err := llm.Load("models/gemma-2b.gguf")if err != nil {panic(err)}defer model.Close()session := llm.NewSession("你是一個冷靜理性的開發顧問,擅長邏輯推理與問題排查。")reader := bufio.NewReader(os.Stdin)for {fmt.Print(">> ")input, _ := reader.ReadString('\n')prompt := session.BuildPrompt(input)fmt.Println("🤖 回應中...")response := ""for r := range model.Predict(prompt) {fmt.Print(r.Content)response += r.Content}fmt.Println()session.Append(input, response)}
}
六、进阶扩展建议
| 模组 | 方向 |
|---|---|
| Web API | 加入 Gin or Fiber 替代 CLI,支援 JSON POST |
| 快取 | 用 BoltDB or SQLite 快取 prompt → response 映射 |
| 多人多角色 | 用 YAML 档定义多个角色风格,让 session 可切换人 |
| 长对话压缩 | 超过 n 条历史时,自动摘要前面纪录 |
七、结语
将 llm-go 负责 prompt 架构与会话逻辑、go-llama.cpp 提供高效 GGUF 本地推理引擎,这样的模组化设计,让 Go 语言也能构建出本地 LLM 系统。
Golang 开发者,这是一条稳定、高效的部署路径,尤其适合自用工具、私域问答机器人、终端 CLI 助理等场景。
参考链接:
-
本项目 README
🧾 GitCode 開源項目地址:
👉 GitCode - 全球开发者的开源社区,开源代码托管平台
我是一位独立开发者,加入使用者社群,一起讨论私有化 LLM 与 RAG 架构实践,欢迎 Star、Fork、Issue 交流。