GPT-4凌晨已发布赶紧申请,前端小白用最近用刚学的golang对接了GPT-3.5的6个接口

GPT-4凌晨已发布赶紧申请,前端小白用最近用刚学的golang对接了GPT-3.5的6个接口

1、前言

GPT-4 API waitlist (openai.com) 有兴趣的赶紧申请一下吧。

  • GPT-4更新最大的变化是可以输入并识别图片了,前两天写的这篇文章,算了,就这样赶紧发了 哈哈

  • ChatGPT给人们日常生活带来的影响,尤其在软件科技圈,层出不穷的新品。

  • 或与十多年前的iPhone非常的相似,带来一轮变革或新陈代谢。

  • 必应日活最近也首次破亿,这一波微软真的是赢麻了。

  • ChatGPT正式整合进Azure中,相信对于开发者来说是更大的利好。

即将到来的GPT-4是多模态模型,可能同时理解图像、声音、文本和视频。也就是说,万物皆可作为输入和输出。这个真的是太刺激了。就看接下来发布之后,api的开放程度了,拭目以待啊。

再来说一下,最近学习的GPT-3.5吧,由于种种原因,其实官网的功能也是足够的强大,只不过需要我们做到科学的上网才能使用。而在GPT-3.5之前开放的api,返回给我们的数据可以说是没什么参考价值吧。

在3月1日发布的GPT-3.5之后,api接口的返回数据质量,也发生了质的提升,种种迹象表明,现在的GPT模型势必会给各行各业产生不小的冲击,引领我们被动的进行变革,也许不是现在,但绝对已经在路上了,因为更强大的GPT-4.0也马上蓄势待发,看着这个趋势,作为一个程序员的我,是怎么也安耐不住的,必须参与其中,哪怕只是进行了解学习,对其接口数据组织进行提前的预热学习吧。

种种迹象表明,得好好学习一波了。

2、对接openai接口的全过程

可以按照这个顺序来尝试一下

  • 科学上网这个有很多就不说了

  • openai官网注册账号也有非常的多,也不提了

  • openai官网创建apikey

  • 本地开发可以使用代理进行开发

  • 了解go语言初级开发

  • 了解go语言的gin框架和fasthttp框架

  • 了解openai官网的api

  • 开干写代码,其实如果代码遇到了问题很大程度上你可以把代码发送给openai,大概率它可以帮你找到问题

这里着重说一下代理的问题,通过本地调试的时候应该是没有办法访问接口 api.openai.com

这里一种是nodejs实现的腾讯云函数,一种是go语言实现的云函数,这两种方式相对来说是最简单的,当然还可以有其他的方式了

3、go语言初级开发

由于年后时间相对充裕,所以在结合自身状况的前提下,我开启了go语言的学习,这期间真的好多的问题甚至是代码异常都是通过openai解决的, 也就是它能给予我莫大的帮助

image.png

说句不太好听的话:最近掘金好像没怎么使用了,而且连签到都经常忘记了,百度和谷歌也就更不用说了,一定程度上,改变了我处理问题的方式。不知道掘金通过后台的访问数据,能否看出一点问题。

所以最近我就通过go语言,算是原生的来调用了几个openai官网对外提供的接口。

这里也有go语言开发的类库,当然其他语言的也都有

各个语言都有,发展可谓百家争鸣,当然自家的python可谓有得天独厚的优势

4、通过go对接openai

下面我简单说一下我通过go是如何来对接openai接口的,分为以下几个小节

4.1、gin框架

Gin 是一个使用 Go 语言编写的 Web 框架,具有轻量、快速和易于使用的特点。Gin 框架提供了许多 Web 开发中常用的功能和中间件,包括路由、请求参数解析、日志记录、错误处理、认证授权、Swagger 文档生成等,使得开发者可以更加方便快捷地进行 Web 开发。

  • 已经使用强大的路由,对外对前端提供接口路由(路由可以分组,还可以继续分组真的很棒)

  • 可以使用Swagger文档提供与前端交流的媒介(生成接口预览、参数说明、还可调试、返回数据等等)

  • 将会使用中间件 验证token、日志记录、错误处理等

swagger如下,目前开发的接口就这几个而已,后续会慢慢的增加业务,不断优化。

image.png

这是我目前对接openai 的几个路由

image.png

4.2、fasthttp

在go中我主要是通过fasthttp类库来实现调用openai的接口的,没有使用上面说到的类库,主要是想学习一下通过fasthttp来调用接口

相对于标准库提供的net/http包,Fasthttp具有更高的性能和更低的内存占用。它也支持HTTP/1.x和HTTP/2协议。同样fasthttp也有极其强大的其他功能:

  • 快速的路由匹配。Fasthttp使用高效的路由匹配算法来快速地匹配请求。
  • 支持中间件。Fasthttp支持中间件,可以让开发人员在处理请求之前或之后添加自定义逻辑,例如身份验证、日志记录等。
  • 支持文件服务器。Fasthttp可以快速地为静态文件提供服务,这对于处理大量静态内容的Web应用程序非常有用。
  • 容易学习和使用。Fasthttp采用简单的API设计,并提供了丰富的文档和示例,使开发人员可以快速学习和使用。

4.3、代码实现

image.png

看openai官网可以发现,这个接口主要的参数就是model和messages,而messages中又嵌套了一个数组结构体

type ChatModel struct {
	Model    string    `json:"model"`
	Messages []Message `json:"messages"`
}

type Message struct {
	Role    string `json:"role"`
	Content string `json:"content"`
}

复制代码

所以这里我通过struct创建两个结构体,来组装参数,并通过后面的json:"model" 设置被转换为json后对应的字段

接下来看看整个函数,其中我也添加了我对代码的理解注释,毕竟刚学习可能理解的不到位

func GetChatCompletions(ctx *gin.Context) dto.ResponseResult {

	// 通过GetRawData获取前端传递的JSON数据结构
	data, _ := ctx.GetRawData()

	// 将data数据 包装成json数据
	var m map[string]interface{}
	_ = json.Unmarshal(data, &m)

	// 这里我定义的参数是content获取传入的参数
	content := m["content"].(string)

	// 组装openai 接口的参数实体
	chatModel := ChatModel{
		Model: "gpt-3.5-turbo",
		Messages: []Message{
			{Role: "user", Content: content},
		},
	}

	// 将实体结构转换为byte数组
	bytes, err := json.Marshal(chatModel)

	fmt.Println(string(bytes), "bytes")
	if err != nil {
		fmt.Println("error:", err)
		return dto.SetResponseFailure("数据转换错误")
	}

	// openai接口地址,可通过代理处理
	url := utils.OpenAIUrl + `/v1/chat/completions`

	// 定义fasthttp请求对象
	req := fasthttp.AcquireRequest()

	// 使用defer关键字可以确保在函数返回之前,即使出现了错误,也会释放请求对象的内存,从而避免内存泄漏和浪费。
	// 当请求处理完成时,应该调用fasthttp.ReleaseRequest(req)来将请求对象返回给对象池。
	defer fasthttp.ReleaseRequest(req)

	// 设置请求的url地址,请求头,以及通过SetBody设置请求的参数
	req.SetRequestURI(url)
	req.Header.SetMethod("POST")
	req.Header.Set("Content-Type", "application/json")
	// req.Header.Set("Content-Type", "application/octet-stream")
	req.Header.Set("Authorization", "Bearer "+utils.OpenAIAuthToken)
	//gpt-3.5-turbo-0301
	req.SetBody(bytes)

	// 这里跟上面AcquireRequest 类似的,一个是请求对象,一个是返回对象
	resp := fasthttp.AcquireResponse()
	defer fasthttp.ReleaseResponse(resp)

	// 通过fasthttp.Do真正的发起对象
	if err := fasthttp.Do(req, resp); err != nil {
		fmt.Println("Error:", err)
		// return dto.SetResponseFailure("调用openai发生错误")
		ctx.JSON(200, gin.H{"data": "调用openai发生错误"})
	}

	fmt.Println("Status:", resp.StatusCode())

	// 将返回对象中的body数据转换为json数据
	var obj map[string]interface{}
	if err := json.Unmarshal(resp.Body(), &obj); err != nil {
		panic(err)
	}
	fmt.Println("Body:", obj)

	// 最后我通过一个方法进行统一返回参数处理
	return dto.SetResponseData(obj)
}

复制代码

4.4、调试效果

image.png

目前初步完成了五个接口,细节的参数可能在需要的时候还会添加,具体后端代码 github.com/aehyok/go-a…

4.5、前端展示效果

image.png

目前接口算是写好了,准备跟前端进行联调了,其实前端还有很多工作要做的,慢慢的把自己使用的这个工具好好优化。

5、总结

看似对接几个接口很简单,但是整个过程要学习的东西还是蛮多的,如果你也有兴趣学习,欢迎大家一起交流。

我的go代码仓库: github.com/aehyok/go-a…

我的个人博客:vue.tuokecat.com/blog

我的个人github:github.com/aehyok

我的前端项目:pnpm + monorepo + qiankun + vue3 + vite3 + 工具库、组件库 + 工程化 + 自动化
不断完善中,整体框架都有了
在线预览:vue.tuokecat.com
github源码:github.com/aehyok/vue-…

本文正在参加「金石计划」