在 Spring Boot 中使用 OpenAI ChatGPT API

1、概览

在本教程中,我们将学习如何在 Spring Boot 中调用 OpenAI ChatGPT API。我们将创建一个 Spring Boot 应用程序,通过调用 OpenAI ChatGPT API 来生成对提示的回复。

2、OpenAI ChatGPT API

在开始本教程之前,让我们先了解一下本教程中将使用的 OpenAI ChatGPT API。我们将调用 create chat completion API 来生成对提示的回复。

2.1、API 参数和认证

让我们来看看 API 强制的请求参数:

  • model - 是我们将向其发送请求的模型版本。该模型有几个版本。我们将使用 gpt-3.5-turbo 模型,它是 该模型的最新公开版本

  • messages - 发送给模型的提示。每条 message 都需要两个字段:rolecontentrole 字段指定信息的发送者。在请求中是 user,在回复中是 assistantcontent 字段是实际的消息。

API 调用需要认证,我们需要生成一个 OpenAI API key。在调用 API 时在 Authorization 头中设置该 key。

cURL 格式的请求示例如下:

$ curl https://api.openai.com/v1/chat/completions \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $OPENAI_API_KEY" \
  -d '{
    "model": "gpt-3.5-turbo",
    "messages": [{"role": "user", "content": "Hello!"}]
  }'

此外,API 还接受一些可选参数来修改响应。

  • n - 如果我们想增加要生成的响应数,可以指定。默认值为 1。
  • temperature - 控制响应的随机性。默认值为 1(最随机)。
  • max_tokens - 用于限制响应中字词(token)的最大数量。默认值为无穷大,这意味着模型能生成多长,响应就会有多长。一般来说,最好将此值设置为一个合理的数字,以避免生成过长的响应和产生过高的成本。

2.2、API 响应

API 响应将是一个 JSON 对象,其中包含一些元数据和一个 choices 字段。choices 字段是一个对象数组。每个对象都有一个 text 字段,其中包含对提示的回复。

choices 数组中对象的数量等于请求中的可选参数 n。如果未指定 n 参数,choices 数组将只包含一个对象。

下面是一个响示例:

{
  "id": "chatcmpl-123",
  "object": "chat.completion",
  "created": 1677652288,
  "choices": [{
    "index": 0,
    "message": {
      "role": "assistant",
      "content": "\n\nHello there, how may I assist you today?"
    },
    "finish_reason": "stop"
  }],
  "usage": {
    "prompt_tokens": 9,
    "completion_tokens": 12,
    "total_tokens": 21
  }
}

响应中的 usage 字段将包含提示和响应中使用的字词数量。这将用于计算 API 调用的成本。

3、示例代码

我们将创建一个使用 OpenAI ChatGPT API 的 Spring Boot 应用程序。为此,我们将创建一个 Spring Boot Rest API,接受提示作为请求参数,将其传递给 OpenAI ChatGPT API,并将响应作为响应体返回。

3.1、依赖

首先,让我们创建一个 Spring Boot 项目。添加 spring boot starter web 依赖:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>

3.2、DTO

接下来,让我们创建一个与 OpenAI ChatGPT API 的请求参数相对应的 DTO:

public class ChatRequest {

    private String model;
    private List<Message> messages;
    private int n;
    private double temperature;

    public ChatRequest(String model, String prompt) {
        this.model = model;
        
        this.messages = new ArrayList<>();
        this.messages.add(new Message("user", prompt));
    }

    // 省略 get/set 方法
}

以及 Message 类:

public class Message {

    private String role;
    private String content;

    // 忽略构造函数、get、set 方法
}

同样,让我们为响应创建一个 DTO:

public class ChatResponse {

    private List<Choice> choices;

    // 忽略构造函数、get、set 方法
    
    public static class Choice {

        private int index;
        private Message message;

        // 忽略构造函数、get、set 方法
    }
}

3.3、Controller

接下来,让我们创建一个 controller,接受提示作为请求参数,并返回响应作为响应体:

@RestController
public class ChatController {
    
    @Qualifier("openaiRestTemplate")
    @Autowired
    private RestTemplate restTemplate;
    
    @Value("${openai.model}")
    private String model;
    
    @Value("${openai.api.url}")
    private String apiUrl;
    
    @GetMapping("/chat")
    public String chat(@RequestParam String prompt) {
        // 创建 request
        ChatRequest request = new ChatRequest(model, prompt);
        
        // 调用 API
        ChatResponse response = restTemplate.postForObject(apiUrl, request, ChatResponse.class);
        
        if (response == null || response.getChoices() == null || response.getChoices().isEmpty()) {
            return "No response";
        }
        
        // 返回第一个响应
        return response.getChoices().get(0).getMessage().getContent();
    }
}

让我们来看看代码的一些重要部分:

  • 我们使用 @Qualifier 注解注入了一个 RestTemplate Bean,我们将在下一节创建该 Bean。
  • 通过 RestTemplate Bean,我们使用 postForObject() 方法调用了 OpenAI ChatGPT API。postForObject() 方法的参数包括 URL、request 对象和响应类
  • 最后,我们读取了响应的 choices 列表,并返回了第一个回复。

3.4、RestTemplate

接下来,让我们定义一个自定义 RestTemplate Bean,它将使用 OpenAI API key 进行认证:

@Configuration
public class OpenAIRestTemplateConfig {

    @Value("${openai.api.key}")
    private String openaiApiKey;

    @Bean
    @Qualifier("openaiRestTemplate")
    public RestTemplate openaiRestTemplate() {
        RestTemplate restTemplate = new RestTemplate();
        restTemplate.getInterceptors().add((request, body, execution) -> {
            request.getHeaders().add("Authorization", "Bearer " + openaiApiKey);
            return execution.execute(request, body);
        });
        return restTemplate;
    }
}

在这里,我们在基本的 RestTemplate 中添加了一个拦截器,并添加了 Authorization 请求头。

3.5、Properties

最后,让我们在 application.properties 文件中配置 API 的属性:

openai.model=gpt-3.5-turbo
openai.api.url=https://api.openai.com/v1/chat/completions
openai.api.key={你的 API key}

4、运行应用

现在,我们可以运行应用程序,并在浏览器中进行测试:

在浏览器中调用 API 获取 ChatGPT 响应

我们可以看到,应用生成了对提示的响应。请注意,模型生成的回复可能会有所不同。

5、总结

在本文中,我们学习了 OpenAI ChatGPT API 接口的参数、认证方式和响应信息,以及如何在 Spring Boot 应用中进行调用。


参考:https://www.baeldung.com/spring-boot-chatgpt-api-openai