实战: 使用 LangChainGo + Gin 实现流式 AI 问答系统
在本篇文章中,我们将使用 LangChainGo + Gin 框架,结合 Ollama 大语言模型,实现一个流式 AI 问答系统。最终,我们还会使用 curl 进行测试,由于是实战例子所以我会提供一个简单的 html+css+js 的前端来实时显示 AI 的回答。
流式响应的意义
在传统 API 调用中,我们往往要等到大语言模型(LLM)计算完成后,才能返回完整的回答。这会导致:
- 等待时间长:用户需要等待很久,体验不佳。
- 缺乏实时性:无法在模型生成内容的同时,逐步显示给用户。
而流式响应可以:
- 逐步输出生成的内容,前端可以即时渲染,提升用户体验。
- 优化带宽,避免一次性传输大数据,减少系统压力。
后端:Gin + LangChainGo 实现流式响应
我们闲话少说,开始今天的正题,具体步骤如下所示:
1. 创建项目并安装依赖
首先我们创建一个名为 robot-go
的项目,并安装其所需要的依赖。
mkdir robot-go
cd robot-go/
go mod init github.com/xxx/robot-go
go get github.com/gin-gonic/gin
go get github.com/tmc/langchaingo@v0.1.13
go get github.com/tmc/langchaingo/llms@v0.1.13
2. 编写代码
键入如下代码:
func chatHandler(c *gin.Context) {
var request struct {
Question string `json:"question"`
}
if err := c.ShouldBindJSON(&request); err != nil {
log.Printf("Invalid request: %v", err)
c.JSON(http.StatusBadRequest, gin.H{"error": "invalid request"})
return
}
if request.Question == "" {
log.Print("Empty question received")
c.JSON(http.StatusBadRequest, gin.H{"error": "question cannot be empty"})
return
}
ctx := context.Background()
// 设置 SSE 头部
c.Writer.Header().Set("Content-Type", "text/event-stream")
c.Writer.Header().Set("Cache-Control", "no-cache")
c.Writer.Header().Set("Connection", "keep-alive")
c.Writer.Flush()
content := []llms.MessageContent{
llms.TextParts(llms.ChatMessageTypeHuman, request.Question),
}
// 调用流式 API
_, err := llmClient.GenerateContent(ctx, content, llms.WithStreamingFunc(func(ctx context.Context, chunk []byte) error {
fmt.Fprintf(c.Writer, "data: %s\n\n", string(chunk))
c.Writer.Flush()
return nil
}))
if err != nil {
log.Printf("Failed to generate content: %v", err)
c.JSON(http.StatusInternalServerError, gin.H{"error": "failed to get response"})
return
}
fmt.Fprintln(c.Writer, "data: [DONE]\n")
c.Writer.Flush()
}
代码解析
llm.GenerateContent
:调用 LangChainGo 生成流式数据。llms.WithStreamingFunc
:注册一个回调函数,每当 LLM 生成新的文本,都会实时返回。c.Writer.Flush()
:确保数据立即推送到客户端,而不是缓存。
使用 curl 进行测试
我们先运行后端服务,具体命令如下所示:
go run main.go
然后,使用 curl 进行测试:
curl -X POST http://localhost:9527/api/chat \
-H "Content-Type: application/json" \
-d '{"question": "请介绍一下Go语言"}' \
--no-buffer
⚠️注意:
--no-buffer
让 curl 立即显示流式数据。
测试结果如下所示:
⚠️注意: 别忘记了在本地运行 Ollama,这里我使用的模型是
qwen2:7b
!!!
前端实现
由于是一个简单的例子所以就没有用 react 框架来做,前端的效果如下所示:
这里可以放置前端代码和截图(如果有的话)
总结
本篇文章,我们从后端实现到前端流式渲染,完整实现了一个流式 AI 问答系统:
- ✅ 使用 LangChainGo + Ollama 处理 LLM 调用
- ✅ Gin 提供 SSE(Server-Sent Events)流式 API
- ✅ curl 终端测试,逐步返回 AI 生成文本
- ✅ 简单的使用了 html+css+js 实现前端实时显示
🚀 完整代码已开源,你可以尝试改进并扩展,比如:
- 支持多轮对话,携带对话上下文记忆等。
- 接入更强大的 LLM 模型,例如 deepseek 等。
- 优化前端 UI 交互,可以使用 react 这类框架来实现。
- 实现更复杂的应用场景,例如问答搜索等。