编程 使用 LangChainGo + Gin 实现流式 AI 问答系统

2025-03-09 22:26:15 +0800 CST views 666

实战: 使用 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 这类框架来实现。
  • 实现更复杂的应用场景,例如问答搜索等。
复制全文 生成海报 AI 编程 Web开发 流式处理 后端开发

推荐文章

JavaScript中的常用浏览器API
2024-11-18 23:23:16 +0800 CST
PHP 8.4 中的新数组函数
2024-11-19 08:33:52 +0800 CST
如何在 Vue 3 中使用 Vuex 4?
2024-11-17 04:57:52 +0800 CST
Golang实现的交互Shell
2024-11-19 04:05:20 +0800 CST
Vue 3 中的 Watch 实现及最佳实践
2024-11-18 22:18:40 +0800 CST
在 Rust 中使用 OpenCV 进行绘图
2024-11-19 06:58:07 +0800 CST
使用Ollama部署本地大模型
2024-11-19 10:00:55 +0800 CST
robots.txt 的写法及用法
2024-11-19 01:44:21 +0800 CST
CSS 实现金额数字滚动效果
2024-11-19 09:17:15 +0800 CST
ElasticSearch集群搭建指南
2024-11-19 02:31:21 +0800 CST
JavaScript 流程控制
2024-11-19 05:14:38 +0800 CST
Node.js中接入微信支付
2024-11-19 06:28:31 +0800 CST
在 Rust 生产项目中存储数据
2024-11-19 02:35:11 +0800 CST
thinkphp swoole websocket 结合的demo
2024-11-18 10:18:17 +0800 CST
程序员茄子在线接单