2024年12月26日

使用golang开发AI大模型应用-langchaingo介绍

作者 柳 永强
内容目录

使用golang开发AI大模型应用-langchaingo介绍

随着生成式大模型的发展,AI大模型应用的开发也变得越来越重要。由于Python语言在AI领域良好的生态和丰富的库,因此Python语言成为AIGC领域的绝对统治者。在AI领域,Python成为开发AI应用的首选语言。2024在tiobe编程语言排行榜中,Python成为霸榜的编程语言。

但是在后端服务及云原生领域,Golang却是首选语言,相比Python,Golang有更好的性能和并发性。因此,如果你想开发基于AI大模型的后端应用,Golang一定是个不错的选择。美中不足的是,Golang在AI领域的生态相对较弱,能够使用的现成的库并不是很多。

LangChain Go 简介

Langchain目前成为使用python开发AI智能应用的首选框架,它提供了一套工具、组件和接口,使开发人员能够更轻松地构建智能应用。

LangChain 框架包含以下主要组件:

  • Models: 作为基础构建块,提供语言理解和生成能力。
  • Prompts: 用于指导模型生成特定输出的模板。
  • Indexes: 用于高效检索和提取信息。
  • Chains: 将多个组件连接起来,实现复杂的任务流程。
  • Agents: 具有自主决策能力的智能体,可以根据任务选择合适的工具。
  • Memory: 为对话型应用提供历史记忆功能,确保对话的连贯性。

LangChain Go是用Go语言实现的langchain库,基本功能对标了Python版本的langchain库。
使用LangChain Go,开发者可以使用Golang语言快速的构建AI服务及应用。

Github 地址: https://github.com/tmc/langchaingo
开发文档:https://tmc.github.io/langchaingo/docs/
接口文档:https://pkg.go.dev/github.com/tmc/langchaingo

准备工作

在开始之前,你需要安装Go语言环境,可以参考Go语言官方文档进行安装。

由于Golang 也存在多钟版本,如果你需要从多个Golang版本之间进行切换时,可以使用 Glang version manager 进行管理。

使用Google 的Gemini模型

我个人开发过程中,起初使用的Google的Gemini 1.5模型,但是由于免费版本对于请求有一些限制,我后来使用国产的Deepseek模型,其价格非常便宜,性能也不错。

最近Google发布了最新的Gemini 2.0 模型,相比1.5版本,Gemini 2.0 模型在生成式任务上有了更好的表现。目前Gemini 2.0 Flash 版本对开发者提供免费使用,可以通过Google AI Studio申请API key: https://aistudio.google.com/apikey

以下代码示范如何使用LangChain Go调用Google Gemini 2.0模型生成文本:

编译以下代码需要添加go.mod文件:


module your_module_name

go 1.22.0

toolchain go1.22.1

require github.com/tmc/langchaingo v0.1.13-pre.0

require (
    cloud.google.com/go v0.114.0 // indirect
    cloud.google.com/go/ai v0.7.0 // indirect
    cloud.google.com/go/aiplatform v1.68.0 // indirect
    cloud.google.com/go/auth v0.5.1 // indirect
    cloud.google.com/go/auth/oauth2adapt v0.2.2 // indirect
    cloud.google.com/go/compute/metadata v0.3.0 // indirect
    cloud.google.com/go/iam v1.1.8 // indirect
    cloud.google.com/go/longrunning v0.5.7 // indirect
    cloud.google.com/go/vertexai v0.12.0 // indirect
    github.com/dlclark/regexp2 v1.10.0 // indirect
    github.com/felixge/httpsnoop v1.0.4 // indirect
    github.com/go-logr/logr v1.4.1 // indirect
    github.com/go-logr/stdr v1.2.2 // indirect
    github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
    github.com/golang/protobuf v1.5.4 // indirect
    github.com/google/generative-ai-go v0.15.1 // indirect
    github.com/google/s2a-go v0.1.7 // indirect
    github.com/google/uuid v1.6.0 // indirect
    github.com/googleapis/enterprise-certificate-proxy v0.3.2 // indirect
    github.com/googleapis/gax-go/v2 v2.12.4 // indirect
    github.com/pkoukk/tiktoken-go v0.1.6 // indirect
    go.opencensus.io v0.24.0 // indirect
    go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.51.0 // indirect
    go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.51.0 // indirect
    go.opentelemetry.io/otel v1.26.0 // indirect
    go.opentelemetry.io/otel/metric v1.26.0 // indirect
    go.opentelemetry.io/otel/trace v1.26.0 // indirect
    golang.org/x/crypto v0.23.0 // indirect
    golang.org/x/net v0.25.0 // indirect
    golang.org/x/oauth2 v0.21.0 // indirect
    golang.org/x/sync v0.7.0 // indirect
    golang.org/x/sys v0.20.0 // indirect
    golang.org/x/text v0.15.0 // indirect
    golang.org/x/time v0.5.0 // indirect
    google.golang.org/api v0.183.0 // indirect
    google.golang.org/genproto v0.0.0-20240528184218-531527333157 // indirect
    google.golang.org/genproto/googleapis/api v0.0.0-20240604185151-ef581f913117 // indirect
    google.golang.org/genproto/googleapis/rpc v0.0.0-20240604185151-ef581f913117 // indirect
    google.golang.org/grpc v1.64.0 // indirect
    google.golang.org/protobuf v1.34.1 // indirect
)

主函数:


package main

import (
    "context"
    "fmt"
    "log"
    "os"

    "github.com/tmc/langchaingo/llms"
    "github.com/tmc/langchaingo/llms/googleai"
)

func main() {
    ctx := context.Background()
    apiKey := os.Getenv("GOOGLE_API_KEY")
    llm, err := googleai.New(ctx, googleai.WithAPIKey(apiKey), googleai.WithDefaultModel("gemini-2.0-flash-exp"))
    if err != nil {
        log.Fatal(err)
    }

    prompt := "简单介绍下langchain go库?"
    answer, err := llms.GenerateFromSinglePrompt(ctx, llm, prompt)
    if err != nil {
        log.Fatal(err)
    }

    fmt.Println(answer)

运行以上程序:


export GOOGLE_API_KEY="your-google-api-key"
go run main.go

使用OpenAI的模型生成内容

OpenAI几乎没有开放免费额度给开发者使用,同时国内用户也无法使用,这是比较可惜的。但是OpenAI的模型在生成式任务上表现非常优秀,因此很多开发者还是会选择使用OpenAI的模型。

go mod文件:


module module your_module_name

go 1.22.0

toolchain go1.22.1

require github.com/tmc/langchaingo v0.1.13-pre.0

require (
    github.com/dlclark/regexp2 v1.10.0 // indirect
    github.com/google/uuid v1.6.0 // indirect
    github.com/pkoukk/tiktoken-go v0.1.6 // indirect
)

package main

import (
    "context"
    "fmt"
    "log"

    "github.com/tmc/langchaingo/llms"
    "github.com/tmc/langchaingo/llms/openai"
)

func main() {
    llm, err := openai.New(openai.WithModel("gpt-4o-mini"))
    if err != nil {
        log.Fatal(err)
    }
    ctx := context.Background()
    completion, err := llms.GenerateFromSinglePrompt(ctx,
        llm,
        "The first man to walk on the moon",
        llms.WithTemperature(0.8),
        llms.WithStopWords([]string{"Armstrong"}),
    )
    if err != nil {
        log.Fatal(err)
    }

    fmt.Println("The first man to walk on the moon:")
    fmt.Println(completion)
}

运行以上程序:


export OPENAI_API_KEY="your-openai-api-key"
go run main.go

使用Deepseek的模型生成内容

Deepseek是国产模型,性能不错,价格也便宜。以下代码示范如何使用LangChain Go调用Deepseek模型生成文本,由于Deepseek支持OpenAI的接口标准,因此使用方法与OpenAI几乎一样。另外国产模型通义千问也是一种选择,但是目前langchang go并没有提供封装和支持,希望后续版本能够提供支持。

就在我发布该文章的第二天,deepseek发布了v3版本,性能相比v2有了大部的提升,强烈推荐国内的开发者使用deepseek模型。

申请API key: https://www.deepseek.com/

go mod文件:


module module your_module_name

go 1.22.0

toolchain go1.22.1

require github.com/tmc/langchaingo v0.1.13-pre.0

require (
    github.com/dlclark/regexp2 v1.10.0 // indirect
    github.com/google/uuid v1.6.0 // indirect
    github.com/pkoukk/tiktoken-go v0.1.6 // indirect
)

package main

import (
    "context"
    "fmt"
    "log"
    "os"

    "github.com/tmc/langchaingo/llms"
    "github.com/tmc/langchaingo/llms/openai"
)

func main() {
    apiKey := os.Getenv("DEEDSEEK_API_KEY")
    llm, err := openai.New(openai.WithModel("deepseek-coder"), openai.WithBaseURL("https://api.deepseek.com/beta"), openai.WithToken(apiKey))
    if err != nil {
        log.Fatal(err)
    }
    ctx := context.Background()
    completion, err := llms.GenerateFromSinglePrompt(ctx,
        llm,
        "介绍下docker",
        llms.WithTemperature(0.8),
        llms.WithStopWords([]string{"Armstrong"}),
    )
    if err != nil {
        log.Fatal(err)
    }

    fmt.Println("The first man to walk on the moon:")
    fmt.Println(completion)
}

运行以上程序:


export DEEDSEEK_API_KEY="your-openai-api-key"
go run main.go

其他使用示例

本文只是介绍了最基本的示例,后续文章会提供更多的示例。

关于langchain go的其他使用示例,可以参考该项目提供的exampls目录,里面包含了一些常见的使用示例。

https://github.com/tmc/langchaingo/tree/main/examples

参考文档

https://eli.thegreenplace.net/2024/using-gemini-models-in-go-with-langchaingo/
https://eli.thegreenplace.net/2024/using-gemini-models-in-go-with-langchaingo/