大模型应用:基于Golang实现GPT模型API调用

在这里插入图片描述

1.背景

当前OpenAI提供了开放接口,支持通过api的方式调用LLM进行文本推理、图片生成等能力,但目前官方只提供了Python SDK。为了后续更方便集成和应用,可以采用Golang对核心推理调用接口进行封装,提供模型调用能力。

2.相关准备

官方OpenAPI文档:https://platform.openai.com/docs/overview

  1. 首先需要注册OpenAI账号,并且创建OpenAPI Key:https://platform.openai.com/api-keys,账号内需要充值5美元用于API调用计费。充值需要有美联储值卡,可以选择找代充,也可以直接买已有的账号,链接:https://eylink.cn/
  2. OpenAPI官方调用域名为:https://api.openai.com,国内需要开启全局科学上网才可调用,可以用代理域名:https://api.openai-proxy.com
  3. OpenAPI调用模型计费规则以消耗的Tokens计费:https://openai.com/api/pricing/
    1. gpt-3.5-turbo:2美元/百万Tokens
    2. gpt-4-turbo:40美元/百万Tokens
    3. gpt-4o:20美元/百万Tokens

3.实现代码

代码地址已上传:https://github.com/pbrong/llm_hub/blob/master/pkg/llm_caller/gpt_caller.go

  • helper.go
package llm_caller

import "context"

var (
   _ LLMCaller = &gptLLMCaller{}
)

type LLMCaller interface {
   Call(ctx context.Context, userPrompt string) (completions string, err error)
}

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

type GptCompletion struct {
   Created int `json:"created"`
   Usage   struct {
      CompletionTokens int `json:"completion_tokens"`
      PromptTokens     int `json:"prompt_tokens"`
      TotalTokens      int `json:"total_tokens"`
   } `json:"usage"`
   Model   string `json:"model"`
   ID      string `json:"id"`
   Choices []struct {
      FinishReason string `json:"finish_reason"`
      Index        int    `json:"index"`
      Message      struct {
         Role    string `json:"role"`
         Content string `json:"content"`
      } `json:"message"`
   } `json:"choices"`
   SystemFingerprint interface{} `json:"system_fingerprint"`
   Object            string      `json:"object"`
}
  • gpt_caller.go
package llm_caller

import (
   "context"
   "encoding/json"
   "fmt"
   "llm_hub/conf"
   "llm_hub/pkg/http"
)

const (
   // 请求路径
   CompletionsURL = "/v1/chat/completions"

   // 可用模型
   Gpt35TurboModel = "gpt-3.5-turbo"
)

type gptLLMCaller struct {
   openAiKey   string
   systemText  string
   temperature float64
   maxTokens   int64
}

func NewGptLLMCaller(ctx context.Context, systemText string, temperature float64, maxTokens int64) (*gptLLMCaller, error) {
   return &gptLLMCaller{
      openAiKey:   conf.LLMHubConfig.Openai.Key,
      systemText:  systemText,
      temperature: temperature,
      maxTokens:   maxTokens,
   }, nil
}

func (caller *gptLLMCaller) Call(ctx context.Context, userPrompt string) (completion string, err error) {
   reqURL := conf.LLMHubConfig.Openai.Host + CompletionsURL
   body := map[string]interface{}{
      "model":       Gpt35TurboModel,
      "temperature": caller.temperature,
      "stream":      false,
      "max_tokens":  caller.maxTokens,
      "messages":    nil,
   }
   body["messages"] = buildPromptMessages(caller.systemText, userPrompt)
   headers := buildAuthHeaders(caller.openAiKey)
   resp, err := http.PostWithHeader(reqURL, body, headers)
   if err != nil {
      return "", fmt.Errorf("GPT调用失败, err = %v", err)
   }
   var gptCompletion GptCompletion
   _ = json.Unmarshal(resp, &gptCompletion)
   if len(gptCompletion.Choices) > 0 {
      completion = gptCompletion.Choices[0].Message.Content
   }

   return completion, nil
}

func buildAuthHeaders(key string) map[string]string {
   headers := map[string]string{
      "Authorization": "Bearer " + key,
   }
   return headers
}

func buildPromptMessages(system string, user string) []*Message {
   var messages []*Message
   messages = append(messages, &Message{
      Role:    "system",
      Content: system,
   })
   messages = append(messages, &Message{
      Role:    "user",
      Content: user,
   })
   return messages
}
  • 测试:gpt_caller_test.go
package llm_caller

import (
   "context"
   "github.com/stretchr/testify/assert"
   "llm_hub/conf"
   "testing"
)

func Test_gptLLMCaller_Call(t *testing.T) {
   conf.Init()
   ctx := context.Background()
   caller, err := NewGptLLMCaller(ctx, "hello gpt-3.5-turbo", 0.5, 128)
   assert.Nil(t, err)
   completion, err := caller.Call(ctx, "hello world")
   assert.Nil(t, err)
   t.Logf("gpt call success, completion = %v", completion)
}

成功实现gpt-3.5.turbo模型调用:

2024/05/26 22:17:11 post with header, url = https://api.openai-proxy.com/v1/chat/completions, request = {
    "max_tokens": 128,
    "messages": [
        {
            "role": "system",
            "content": "hello gpt-3.5-turbo"
        },
        {
            "role": "user",
            "content": "hello world"
        }
    ],
    "model": "gpt-3.5-turbo",
    "stream": false,
    "temperature": 0.5
}, response = {
  "id": "chatcmpl-9T8yMDeJDEHKyN70Skk3prHvHZBkz",
  "object": "chat.completion",
  "created": 1716733030,
  "model": "gpt-3.5-turbo-0125",
  "choices": [
    {
      "index": 0,
      "message": {
        "role": "assistant",
        "content": "Hello! How can I assist you today?"
      },
      "logprobs": null,
      "finish_reason": "stop"
    }
  ],
  "usage": {
    "prompt_tokens": 23,
    "completion_tokens": 9,
    "total_tokens": 32
  },
  "system_fingerprint": null
}
    gpt_caller_test.go:17: gpt call success, completion = Hello! How can I assist you today?
--- PASS: Test_gptLLMCaller_Call (1.31s)
PASS

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/646722.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Django框架过时了吗?新手学Flask还是Django?

文章目录 Django框架的优势与劣势优势劣势 Flask框架的优势与劣势优势劣势 如何选择? 近年来,随着Flask框架的崛起,一些人开始质疑Django框架是否已经过时。在选择学习框架时,新手们往往感到困惑,不知道是学习Flask还是…

2024宝藏工具EasyRecovery数据恢复软件免费版本下载

在这个数字化的时代,数据已经成为我们生活中的重中之重。无论是工作中的重要文件,还是手机中珍贵的照片,我们都依赖着这些数据。然而,数据丢失的情况时有发生,可能是误删,可能是设备故障,更可能…

移动端特效

一,触屏事件 1.触屏touch事件 2.触摸事件对象 如果侦听的是一个DOM元素,他俩是一样的 如果手指离开了,不能侦听到前两者,能侦听到第三个 我们一般都是触摸元素,所以一般都是第二个比较常用 第一个:屏幕…

Java核心:注解处理器

Java提供了一个javac -processor命令支持处理标注有特定注解的类,来生成新的源文件,并对新生成的源文件重复执行。执行的命令大概是这样的: javac -XprintRounds -processor com.keyniu.anno.processor.ToStringProcessor com.keyniu.anno.processor.Po…

java “错误:编码GBK 的不可映射字符”

环境:JDK-17 本机编码:utf-8 代码编码:GBK 错误:java “错误:编码GBK 的不可映射字符” 解决1:记事本打开java源文件,另存为选择ANSI编码 解决2:复制代码再将编码格式改为utf-8,…

CentOS 7安装alertmanager

说明:本文介绍如何在CentOS 7安装alertmanager; Step1:下载安装包 访问Github仓库,下载对应版本的alertmanager安装包 https://github.com/prometheus/alertmanager/releases 如何查看自己系统的信息,可参考下图中的…

2024.5组队学习——MetaGPT(0.8.1)智能体理论与实战(中):订阅智能体OSS实现

传送门: 《2024.5组队学习——MetaGPT(0.8.1)智能体理论与实战(上):MetaGPT安装、单智能体开发》《2024.5组队学习——MetaGPT(0.8.1)智能体理论与实战(下)&…

入门五(项目介绍及登录需求)

软件缺陷判定标准 项目中缺陷的管理流程 使用Excel对于缺陷进行管理 使用工具管理缺陷 一、项目背景 传智作为一个IT教育机构,拥有自己开发且实际运营的产品; 将开发和运营的技术作为授课的内容,对于学员而言学到的都是一手的真实案例和…

Redis数据类型(上篇)

前提:(key代表键) Redis常用的命令 命令作用keys *查看当前库所有的keyexists key判断某个key是否存在type key查看key是什么类型del key 删除指定的keyunlink key非阻塞删除,仅仅将keys从keyspace元数据中删除,真正的…

【论文复现】LSTM长短记忆网络

LSTM 前言网络架构总线遗忘门记忆门记忆细胞输出门 模型定义单个LSTM神经元的定义LSTM层内结构的定义 模型训练模型评估代码细节LSTM层单元的首尾的处理配置Tensorflow的GPU版本 前言 LSTM作为经典模型,可以用来做语言模型,实现类似于语言模型的功能&am…

空间注意力机制

第一步是沿着通道维度进行最大池化和平均池化,比如下面3*3的特征图,有3个通道。 第二步新特征图进行拼接并经过卷积调整通道数 第三步经过Sigmoid函数后乘到输入上 代码: class SpatialAttention(layers.Layer):def __init__(self):super(S…

弱类型解析

php中 转化为相同类型后比较 先判断数据类型后比较数值 var_dump("asdf"0);#bool(true) var_dump("asdf"1);#bool(false) var_dump("0asdf"0);#bool(true) var_dump("1asdf"1);#bool(true)1、md5撞库 例&#xff1a; <?php incl…

stm32-USART串口外设

配置流程 初始化配置 1.开启时钟&#xff08;打开USART和GPIO的时钟&#xff09; void RCC_AHBPeriphClockCmd(uint32_t RCC_AHBPeriph, FunctionalState NewState); void RCC_APB2PeriphClockCmd(uint32_t RCC_APB2Periph, FunctionalState NewState); void RCC_APB1Periph…

YOLOv10 论文学习

论文链接&#xff1a;https://arxiv.org/pdf/2405.14458 代码链接&#xff1a;https://github.com/THU-MIG/yolov10 解决了什么问题&#xff1f; 实时目标检测是计算机视觉领域的研究焦点&#xff0c;目的是以较低的延迟准确地预测图像中各物体的类别和坐标。它广泛应用于自动…

Ansible02-Ansible Modules模块详解

目录 写在前面4. Ansible Modules 模块4.1 Ansible常用模块4.1.1 Command模块4.1.2 shell模块4.1.3 scrpit模块4.1.4 file模块4.1.5 copy模块4.1.6 lineinfile模块4.1.7 systemd模块4.1.8 yum模块4.1.9 get_url模块4.1.10 yum_repository模块4.1.11 user模块4.1.12 group模块4.…

【每日刷题】Day49

【每日刷题】Day49 &#x1f955;个人主页&#xff1a;开敲&#x1f349; &#x1f525;所属专栏&#xff1a;每日刷题&#x1f34d; &#x1f33c;文章目录&#x1f33c; 1. 110. 平衡二叉树 - 力扣&#xff08;LeetCode&#xff09; 2. 501. 二叉搜索树中的众数 - 力扣&…

JavaSE 学习记录

1. Java 内存 2. this VS super this和super是两个关键字&#xff0c;用于引用当前对象和其父类对象 this 关键字&#xff1a; this 关键字用于引用当前对象&#xff0c;即调用该关键字的方法所属的对象。 主要用途包括&#xff1a; 在类的实例方法中&#xff0c;通过 this …

H3CNE-7-TCP和UDP协议

TCP和UDP协议 TCP&#xff1a;可靠传输&#xff0c;面向连接 -------- 速度慢&#xff0c;准确性高 UDP&#xff1a;不可靠传输&#xff0c;非面向连接 -------- 速度快&#xff0c;但准确性差 面向连接&#xff1a;如果某应用层协议的四层使用TCP端口&#xff0c;那么正式的…

DragonKnight CTF2024部分wp

DragonKnight CTF2024部分wp 最终成果 又是被带飞的一天&#xff0c;偷偷拷打一下队里的pwn手&#xff0c;只出了一题 这里是我们队的wp web web就出了两个ez题&#xff0c;确实很easy&#xff0c;只是需要一点脑洞(感觉)&#xff0c; ezsgin dirsearch扫一下就发现有ind…

让大模型变得更聪明三个方向

让大模型变得更聪明三个方向 随着人工智能技术的飞速发展&#xff0c;大模型在多个领域展现出了前所未有的能力&#xff0c;但它们仍然面临着理解力、泛化能力和适应性等方面的挑战。那么&#xff0c;如何让大模型变得更聪明呢&#xff1f; 方向一&#xff1a;算法创新 1.1算…