02. 使用langchaingo 和 ollama 交互

93 阅读2分钟

使用api访问 ollama

api文档

image.png

通过go进行访问

langchaingo githut
ollama
demo github

go get github.com/tmc/langchaingo v0.1.13

单次访问代码

package main

import (
    "context"
    "fmt"
    "github.com/tmc/langchaingo/llms"
    "github.com/tmc/langchaingo/llms/ollama"
)

func main() {
    llm, err := ollama.New(ollama.WithModel("qwen2.5:3b"), ollama.WithServerURL("http://127.0.0.1:11434"))
    if err != nil {
       fmt.Printf("连接ollama错误:%s\n", err.Error())
       return
    }

    res, err := llms.GenerateFromSinglePrompt(context.Background(), llm, "你是谁")
    if err != nil {
       fmt.Printf("请求失败:%s\n", err.Error())
       return
    }
    fmt.Printf("返回信息%s\n", res)
}

运行查看

$ go run .\cmd\chat\main.go
返回信息我是你的学习小助手,有什么问题我随时可以帮你解答。你需要了解些什么呢?

恭喜你,完成了与qwen模型的第一次交互

代码详解

ollama.New(ollama.WithModel("qwen2.5:3b"), ollama.WithServerURL("http://127.0.0.1:11434")) 设置ollama交互的模型, ollama api的请求地址

llms.GenerateFromSinglePrompt(context.Background(), llm, "你是谁") 是单次与模型进行交互,只适合单次。 让我们查看一下具体的方法

func GenerateFromSinglePrompt(ctx context.Context, llm Model, prompt string, options ...CallOption) (string, error) {
    msg := MessageContent{
       Role:  ChatMessageTypeHuman,
       Parts: []ContentPart{TextContent{Text: prompt}},
    }

    resp, err := llm.GenerateContent(ctx, []MessageContent{msg}, options...)
    if err != nil {
       return "", err
    }

    choices := resp.Choices
    if len(choices) < 1 {
       return "", errors.New("empty response from model")
    }
    c1 := choices[0]
    return c1.Content, nil
}

在方法中, msg 请求时设置了参数Role, 这个参数是用来让大模型请求某句话是谁说的。以下是基础的三个角色:

  • system:系统角色,可以理解为全局变量或前置条件,设置上这个角色之后,就会规定大模型的聊天范围,业界通常称之为“人设”。
  • user:人类角色,代表这句话是人类说的。在包括 LangChain 在内的很多框架和场景下,user 角色也会被写成 human。
  • assistant:AI 角色,代表这句话是大模型给我们的返回。在包括 LangChain 在内的很多框架和场景下,assistant 角色也会被写成 AI。

下面让我们通过这三个角色来进行交互

func main() {
    llm, err := ollama.New(ollama.WithModel("qwen2.5:3b"), ollama.WithServerURL("http://127.0.0.1:11434"))
    if err != nil {
       fmt.Printf("连接ollama错误:%s\n", err.Error())
       return
    }

    msg := []llms.MessageContent{
       {Role: llms.ChatMessageTypeSystem, Parts: []llms.ContentPart{llms.TextContent{Text: "你是一个熟读三国演义的专家,请尽可能的帮我回答与三国相关的问题"}}},
       llms.TextParts(llms.ChatMessageTypeHuman, "请问刘备是谁"),
    }
    res, err := llm.GenerateContent(context.Background(), msg)
    if err != nil {
       fmt.Printf("请求失败:%s\n", err.Error())
       return
    }
    choices := res.Choices
    if len(choices) < 1 {
       fmt.Printf("模型返回空消息")
       return
    }

    fmt.Printf("返回信息%s\n", choices[0].Content)
}

运行查看

go run .\cmd\chat\main.go

返回信息刘备字玄德,是三国时期蜀汉的政治家、军事家,东汉末年名士。刘备早年颠沛流离,困苦不堪,后依附于刘焉,担任县令,曾任豫州刺史等职。刘备在乱世中结识了诸葛亮、关羽、张飞等人,并与他们一起为兴复汉室而奋斗,最终建立蜀汉。

我们需要在请求完成后,基于上下文对继续进行对话,需要将历史数据携带请求, 在这个基础上去询问曹操是谁。 添加代码

// 携带历史数据进行访问
msg = append(msg, llms.TextParts(llms.ChatMessageTypeAI, choices[0].Content), llms.TextParts(llms.ChatMessageTypeHuman, "曹操呢"))
res, err = llm.GenerateContent(context.Background(), msg)
if err != nil {
    fmt.Printf("请求失败:%s\n", err.Error())
    return
}
choices = res.Choices
if len(choices) < 1 {
    fmt.Printf("模型返回空消息")
    return
}

fmt.Printf("返回信息%s\n", choices[0].Content)

执行后输出 image.png