Go使用Google Gemini Pro API创建简单聊天机器人

 更新时间:2023年12月25日 11:21:53   作者:jiuyee 低配全栈  
这篇文章主要为大家介绍了Go使用Google Gemini Pro API创建简单聊天机器人实现过程详解,本文将通过最新的gemini go sdk来实现命令行聊天机器人

gemini go sdk实现命令行聊天机器人

最近Google 如期发布Gemini Pro API,目前为免费使用,Go的SDK也已经在github上发布了

具体地址见:https://github.com/google/generative-ai-go

本文将通过最新的gemini go sdk来实现命令行聊天机器人。

Go语言实现监听键盘输入

reader := bufio.NewReader(os.Stdin)
// 读取输入直到遇到第一个换行符
input, err := reader.ReadString('\n')

reader对象的ReadString方法即可实现我们需要的监听键盘的方法,这里设置为当监听到回车输入的时候,则读取用户输入的内容。

整合Gemini SDK

前提条件

  • 确保Go SDK版本为1.20+

  • 去Gemini SDK 后台(https://makersuite.google.com/app/apikey?hl=zh-cn)申请api key。

安装SDK

go get github.com/google/generative-ai-go

实例化一个gemini Client

func getGeminiClient() *genai.Client {
  ctx := context.Background()
  client, err := genai.NewClient(ctx, option.WithAPIKey("YOUR-API-KEY"))
  if err != nil {
    log.Fatal(err)
  }
  return client
}

根据用户输入向gemini 服务器发请求。

func handleChat(ctx context.Context, client *genai.Client, cs *genai.ChatSession, content string) error {
  if cs == nil {
    return errors.New("chat session is nil")
  }
  return geminiPro(ctx, cs, content)
}
func geminiPro(ctx context.Context, cs *genai.ChatSession, content string) error {
  prompt := genai.Text(content)
  iter := cs.SendMessageStream(ctx, prompt)
  fmt.Print("[Gemini]:")
  for {
    resp, err := iter.Next()
    if err == iterator.Done {
      break
    }
    if err != nil {
      fmt.Print("Something wrong, please try again later. \n")
      return err
    }
    printChatResponse(resp)
  }
  return nil
}
func printChatResponse(resp *genai.GenerateContentResponse) {
  for _, c := range resp.Candidates {
    for _, p := range c.Content.Parts {
      fmt.Printf("%v", p)
    }
  }
  fmt.Println()
}

这里就是整个Gemini SDK调用的核心代码了,每次使用ChatSession对象(geminiPro方法中的cs变量)发送消息,这里使用的的是流式子消息传输,所以,在geminiPro方法里面,需要启动一个for循环,等待消息的全部输出。

我们整个会话使用的都是同一个ChatSession对象,并且,在发送消息之后,内容会自动加到ChatSession对象的History里面,History也就是历史会话,Gemini SDK一样可以根据上下文来实现问答的实现。

如何实现ChatSession只实例化一次

前面已经说过,一个会话需要使用同一个ChatSession对象,我们自然而然就想到Go里面的sync.Once对象,但在使用Gemini Go SDK的过程中发现,经常会遇到请求出错的情况,一旦请求出错,就需要重新去创建一个会话对象,所以,Go语言提供的sync.Once并不能满足这个需求,所以,需要自己实现一个可以重置的Once对象,这里命名为ResetOnce对象,代码如下:

// ResettableOnce 结构体包含一个互斥锁和一个标记是否已执行的布尔值
type ResettableOnce struct {
  m    sync.Mutex
  done bool
}
// Do 方法类似于 sync.Once 的 Do,但可以通过调用 Reset 来重置
func (o *ResettableOnce) Do(f func()) {
  o.m.Lock()
  defer o.m.Unlock()
  if !o.done {
    defer func() { o.done = true }()
    f()
  }
}
// Reset 方法重置 Once,允许再次调用 Do
func (o *ResettableOnce) Reset() {
  o.m.Lock()
  defer o.m.Unlock()
  o.done = false
}

如何实现用户ChatSession重新创建之后,保持之前的History?

在实际的项目中,我们肯定会对History做持久化,但这里这里,仅使用一个全局的history来模拟持久化。

当ChatSession对象被新建之后,需要将全局history的内容复制给新创建的ChatSession对象,这里为了模拟这个过程,在用户输入内容的时候,添加一个检测内容是否为reset字符串的操作,当检测用户输入为reset字符串的时候,则主动新建一个ChatSession,同时将新的ChatSession的History赋值为之前的history内容,这样即使新建立一个ChatSession它还能保持之前的会话记录。

代码如下:

func handleReset(client *genai.Client, cs **genai.ChatSession, history *[]*genai.Content) {
  fmt.Println("[System]", "Resetting chat session.")
  once.Reset()
  once.Do(func() {
    *cs = startChatSession(client, *history)
  })
}
func startChatSession(client *genai.Client, history []*genai.Content) *genai.ChatSession {
  model := client.GenerativeModel("gemini-pro")
  cs := model.StartChat()
  if len(history) > 0 {
    cs.History = history
  }
  return cs
}

总结

如果在实际中使用这个SDK进行商业化开发,那么比如需要处理用户多会话的管理,其实这个过程也不麻烦,只要维护好用户以及它对应的history的关系,在用户每次开始登录进入系统,并且选择会话的时候,将对应的history给设好即可。但要注意的是,目前pro版本支持的最大的32K的上下文。另外SDK中还提供了gemini-pro-vision模型的使用,你们有兴趣的可以自己去探索。

以上就是Go使用Google Gemini Pro API创建简单聊天机器人的详细内容,更多关于go创建聊天机器人的资料请关注脚本之家其它相关文章!

相关文章

  • Golang Defer作用域及执行顺序使用案例

    Golang Defer作用域及执行顺序使用案例

    这篇文章主要为大家介绍了Golang Defer作用域及执行顺序使用案例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-12-12
  • Go语言之重要数组类型切片(slice)make,append函数解读

    Go语言之重要数组类型切片(slice)make,append函数解读

    这篇文章主要介绍了Go语言之重要数组类型切片(slice)make,append函数用法,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2023-09-09
  • Golang通过小程序获取微信openid的方法示例

    Golang通过小程序获取微信openid的方法示例

    这篇文章主要介绍了Golang通过小程序获取微信openid的方法示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-03-03
  • 一文带你搞懂Golang依赖注入的设计与实现

    一文带你搞懂Golang依赖注入的设计与实现

    在现代的 web 框架里面,基本都有实现了依赖注入的功能,可以让我们很方便地对应用的依赖进行管理。今天我们来看看 go 里面实现依赖注入的一种方式,感兴趣的可以了解一下
    2023-01-01
  • Golang之如何读取文件内容

    Golang之如何读取文件内容

    这篇文章主要介绍了Golang之如何读取文件内容问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-06-06
  • GO语言实现二维码扫码的示例代码

    GO语言实现二维码扫码的示例代码

    你对二维码扫码的流程有困惑吗,这篇文章就结合笔者自身的开发经验进行分享,让大家熟悉并掌握此功能,感兴趣的小伙伴快跟随小编一起学习一下吧
    2023-06-06
  • 利用go语言实现Git 重命名远程分支  

    利用go语言实现Git 重命名远程分支  

    这篇文章主要介绍了go语言实现Git 重命名远程分支,文章基于go语言的基础展开Git 重命名远程分支的实现过程,需要的小伙伴可以参考一下,希望对你的学习有所帮助
    2022-06-06
  • 一文带你入门Go语言中定时任务库Cron的使用

    一文带你入门Go语言中定时任务库Cron的使用

    在平时的开发需求中,我们经常会有一些重复执行的操作需要触发执行,说白了就是定时任务。这篇文章主要给大家介绍一下如何在go项目中实现一个crontab功能,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助
    2022-08-08
  • Go语言实现对称加密和非对称加密的示例代码

    Go语言实现对称加密和非对称加密的示例代码

    本文主要介绍了Go语言实现对称加密和非对称加密的示例代码,通过实际代码示例展示了如何在Go中实现这两种加密方式,具有一定的参考价值,感兴趣的可以了解一下
    2024-01-01
  • Go Excelize API源码解读GetSheetViewOptions与SetPageLayout

    Go Excelize API源码解读GetSheetViewOptions与SetPageLayo

    这篇文章主要为大家介绍了Go Excelize API源码解读GetSheetViewOptions与SetPageLayout方法示例,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-08-08

最新评论