当前位置:   article > 正文

超级详细 JAVA 对接 ChatGPT 教程,实现自己的AI对话小助手_chatgpt4 搭建 java

chatgpt4 搭建 java

1     前言

  大家好,由于近期需要对接了ChatGPT API所以特地记录下来,据介绍该模型是和当前官网使用的相同的模型,如果你还没体验过ChatGPT,那么今天就教大家如何打破网络壁垒,打造一个属于自己的智能助手把。本文包括API Key的申请以及网络代理的搭建,那么事不宜迟,我们现在开始。

  若有想体验的可联系我获取体验账号。

2     对接流程

2.1  API-Key的获取


  首先第一步要获取OpenAI接口的API Key,该Key是你用来调用接口的token,主要用于接口鉴权。获取该key首先要注册OpenAi的账号。

2.1.1      打开platform.openai.com网站,点击view API Key

2.1.2      点击创建key

2.1.3      弹窗显示生成的key,记得把key复制,不然等会就找不到这个key了,只能重新创建

将API Key保存好以备用

2.2  API用量的查看

   这里可以查看API的使用情况,新账号注册默认有5美元的试用额度,之前都是18美元,API成本降了之后试用额度也狠狠地砍了一刀。

2.3  核心代码实现

2.3.1      pom依赖

  其中引入包cdkj-core请参考另一开源项目 维基框架

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <project xmlns="http://maven.apache.org/POM/4.0.0"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4. xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  5. <parent>
  6. <artifactId>framewiki-gpt</artifactId>
  7. <groupId>com.framewiki.gpt</groupId>
  8. <version>1.0.0</version>
  9. </parent>
  10. <modelVersion>4.0.0</modelVersion>
  11. <artifactId>gpt-util</artifactId>
  12. <dependencies>
  13. <dependency>
  14. <groupId>com.cdkjframework</groupId>
  15. <artifactId>cdkj-core</artifactId>
  16. </dependency>
  17. <dependency>
  18. <groupId>com.cdkjframework</groupId>
  19. <artifactId>cdkj-util</artifactId>
  20. </dependency>
  21. <dependency>
  22. <groupId>commons-httpclient</groupId>
  23. <artifactId>commons-httpclient</artifactId>
  24. </dependency>
  25. <dependency>
  26. <groupId>org.springframework.boot</groupId>
  27. <artifactId>spring-boot-starter-validation</artifactId>
  28. </dependency>
  29. </dependencies>
  30. </project>

2.3.2      实体类ChatMessagesDto.java

  用于存放发送的消息信息,注解使用了lombok,如果没有使用lombok可以自动生成构造方法以及get和set方法

  1. package com.framewiki.gpt.dto.response;
  2. import lombok.AllArgsConstructor;
  3. import lombok.Data;
  4. import lombok.NoArgsConstructor;
  5. /**
  6. * @ProjectName: framewiki-gpt
  7. * @Package: com.framewiki.gpt.dto
  8. * @ClassName: ChatMessagesDto
  9. * @Description: java类作用描述
  10. * @Author: xiaLin
  11. * @Date: 2023/6/10 22:30
  12. * @Version: 1.0
  13. */
  14. @Data
  15. @NoArgsConstructor
  16. @AllArgsConstructor
  17. public class ChatMessagesDto {
  18. /**
  19. * 消息角色
  20. * system
  21. * user
  22. * assistant
  23. */
  24. private String role;
  25. /**
  26. * 消息内容
  27. */
  28. private String content;
  29. }

2.3.3      实体类CreateChatCompletionDto.java

  1. package com.framewiki.gpt.dto.request;
  2. import lombok.Data;
  3. /**
  4. * @ProjectName: framewiki-gpt
  5. * @Package: com.framewiki.gpt.dto.request
  6. * @ClassName: CreateChatCompletionDto
  7. * @Description: java类作用描述
  8. * @Author: xiaLin
  9. * @Date: 2023/6/21 22:07
  10. * @Version: 1.0
  11. */
  12. @Data
  13. public class CreateChatCompletionDto {
  14. /**
  15. * 内容
  16. */
  17. private String content;
  18. /**
  19. * 模型
  20. */
  21. private String model;
  22. /**
  23. * 用户
  24. */
  25. private String user;
  26. }

2.3.4      实体类ChatCompletionRequestDto.java

  用于发送的请求的参数实体类,参数释义如下:

  1. package com.framewiki.gpt.dto.request;
  2. import com.alibaba.fastjson.annotation.JSONField;
  3. import com.framewiki.gpt.dto.response.ChatMessagesDto;
  4. import lombok.Builder;
  5. import lombok.Data;
  6. import java.math.BigDecimal;
  7. import java.util.List;
  8. /**
  9. * @ProjectName: framewiki-gpt
  10. * @Package: com.framewiki.gpt.dto
  11. * @ClassName: ChatCompletionRequestDto
  12. * @Description: 请求实体
  13. * @Author: xiaLin
  14. * @Date: 2023/6/10 22:27
  15. * @Version: 1.0
  16. */
  17. @Data
  18. @Builder
  19. public class ChatCompletionRequestDto {
  20. /**
  21. * 模型
  22. * gpt-4
  23. * gpt-4-0314
  24. * gpt-4-32k
  25. * gpt-4-32k-0314
  26. * gpt-3.5-turbo
  27. * gpt-3.5-turbo-0301
  28. */
  29. private String model;
  30. /**
  31. * 温度,参数从0-2,越低表示越精准,越高表示越广发,回答的内容重复率越低
  32. */
  33. private BigDecimal temperature;
  34. /**
  35. * 消息
  36. */
  37. private List<ChatMessagesDto> messages;
  38. /**
  39. * 回复条数,一次对话回复的条数
  40. */
  41. private Integer n;
  42. /**
  43. * 是否流式处理,就像ChatGPT一样的处理方式,会增量的发送信息。
  44. */
  45. private Boolean stream;
  46. /**
  47. * 状态
  48. */
  49. private List<String> stop;
  50. /**
  51. * 生成的答案允许的最大token数
  52. */
  53. @JSONField(name = "max_tokens")
  54. private Integer maxTokens;
  55. /**
  56. * 对话用户
  57. */
  58. private String user;
  59. }

2.3.5      实体类ChatCompletionResponseDto.java

  用于接收请求返回的信息以及执行结果

  1. package com.framewiki.gpt.dto.response;
  2. import lombok.Data;
  3. import java.util.List;
  4. /**
  5. * @ProjectName: framewiki-gpt
  6. * @Package: com.framewiki.gpt.dto
  7. * @ClassName: ChatCompletionResponseDto
  8. * @Description: 响应
  9. * @Author: xiaLin
  10. * @Date: 2023/6/16 23:18
  11. * @Version: 1.0
  12. */
  13. @Data
  14. public class ChatCompletionResponseDto {
  15. /**
  16. * ID
  17. */
  18. private String id;
  19. /**
  20. * 返回的内容
  21. */
  22. private String object;
  23. /**
  24. * 模型
  25. */
  26. private String model;
  27. /**
  28. * 创建时间
  29. */
  30. private long created;
  31. /**
  32. * 用户
  33. */
  34. private String user;
  35. /**
  36. * 选择
  37. */
  38. private List<ChatCompletionChoiceDto> choices;
  39. /**
  40. * 用量
  41. */
  42. private ChatCompletionUsageDto usage;
  43. }

2.3.6      实体类ChatCompletionUsageDto.java

  1. package com.framewiki.gpt.dto.response;
  2. import com.alibaba.fastjson.annotation.JSONField;
  3. import lombok.Data;
  4. /**
  5. * @ProjectName: framewiki-gpt
  6. * @Package: com.framewiki.gpt.dto
  7. * @ClassName: ChatCompletionUsageDto
  8. * @Description: 用量信息
  9. * @Author: xiaLin
  10. * @Date: 2023/6/16 22:44
  11. * @Version: 1.0
  12. */
  13. @Data
  14. public class ChatCompletionUsageDto {
  15. /**
  16. * 输入 token 数量
  17. */
  18. @JSONField(name = "prompt_tokens")
  19. private int promptTokens;
  20. /**
  21. * 完成 token数量
  22. */
  23. @JSONField(name = "completion_tokens")
  24. private int completionTokens;
  25. /**
  26. * token 总数
  27. */
  28. @JSONField(name = "total_tokens")
  29. private int totalTokens;
  30. }

2.3.7      实体类ChatCompletionChoiceDto.java

  用于接收ChatGPT返回的数据

  1. package com.framewiki.gpt.dto.response;
  2. import lombok.Data;
  3. /**
  4. * @ProjectName: framewiki-gpt
  5. * @Package: com.framewiki.gpt.dto
  6. * @ClassName: ChatCompletionChoiceDto
  7. * @Description: java类作用描述
  8. * @Author: xiaLin
  9. * @Date: 2023/6/16 22:44
  10. * @Version: 1.0
  11. */
  12. @Data
  13. public class ChatCompletionChoiceDto {
  14. /**
  15. * 搜索
  16. */
  17. private Integer index;
  18. /**
  19. * 消息
  20. */
  21. private ChatMessagesDto message;
  22. /**
  23. * 完成的原因
  24. */
  25. private String finishReason;
  26. }

2.3.8      接口调用核心类ChatServiceImpl.java

  使用HttpURLConnection用于进行api接口的调用,支持post和get方法请求。

  url为配置文件open.ai.url的值,表示调用api的地址:https://api.openai.com/ ,token为获取的api-key。

  执行post或者get方法时增加头部信息headers.put("Authorization", "Bearer " + token); 用于通过接口鉴权。

  1. package com.framewiki.gpt.service.impl;
  2. import com.cdkjframework.constant.EncodingConsts;
  3. import com.cdkjframework.constant.IntegerConsts;
  4. import com.cdkjframework.entity.http.HttpRequestEntity;
  5. import com.cdkjframework.enums.HttpMethodEnums;
  6. import com.cdkjframework.util.log.LogUtils;
  7. import com.cdkjframework.util.network.http.HttpRequestUtils;
  8. import com.cdkjframework.util.tool.StringUtils;
  9. import com.framewiki.gpt.config.ChatConfig;
  10. import com.framewiki.gpt.config.ChatConfiguration;
  11. import com.framewiki.gpt.dto.request.ChatCompletionRequestDto;
  12. import com.framewiki.gpt.dto.request.CreateChatCompletionDto;
  13. import com.framewiki.gpt.dto.response.ChatCompletionResponseDto;
  14. import com.framewiki.gpt.dto.response.ChatMessagesDto;
  15. import com.framewiki.gpt.service.ChatService;
  16. import lombok.RequiredArgsConstructor;
  17. import org.springframework.stereotype.Service;
  18. import java.math.BigDecimal;
  19. import java.util.ArrayList;
  20. import java.util.HashMap;
  21. import java.util.List;
  22. import java.util.Map;
  23. /**
  24. * @ProjectName: framewiki-gpt
  25. * @Package: com.framewiki.gpt.service.impl
  26. * @ClassName: ChatServiceImpl
  27. * @Description: java类作用描述
  28. * @Author: xiaLin
  29. * @Date: 2023/6/16 22:58
  30. * @Version: 1.0
  31. */
  32. @Service
  33. @RequiredArgsConstructor
  34. public class ChatServiceImpl implements ChatService {
  35. /**
  36. * 日志
  37. */
  38. private LogUtils logUtils = LogUtils.getLogger(ChatServiceImpl.class);
  39. /**
  40. * 配置信息
  41. */
  42. private final ChatConfiguration configuration;
  43. /**
  44. * 地址
  45. */
  46. private final ChatConfig chatConfig;
  47. /**
  48. * 创建对话
  49. *
  50. * @param content 消息内容
  51. */
  52. @Override
  53. public ChatCompletionResponseDto createChatCompletion(CreateChatCompletionDto content) {
  54. if (StringUtils.isNullAndSpaceOrEmpty(content.getModel())) {
  55. content.setModel(model);
  56. }
  57. List<ChatMessagesDto> messages = new ArrayList<>();
  58. ChatMessagesDto systemMessage = new ChatMessagesDto(role, content.getContent());
  59. messages.add(systemMessage);
  60. ChatCompletionRequestDto chatCompletionRequest = ChatCompletionRequestDto.builder()
  61. .model(content.getModel())
  62. .messages(messages)
  63. .user(content.getUser())
  64. .maxTokens(IntegerConsts.ONE_HUNDRED * IntegerConsts.FIVE)
  65. .temperature(BigDecimal.ONE)
  66. .build();
  67. HttpRequestEntity request = new HttpRequestEntity();
  68. request.setRequestAddress(chatConfig.getCreateChatCompletion());
  69. request.setMethod(HttpMethodEnums.POST);
  70. request.setData(chatCompletionRequest);
  71. request.setCharset(EncodingConsts.UTF8);
  72. // 请求头
  73. Map<String, String> headerMap = new HashMap<>(IntegerConsts.ONE);
  74. headerMap.put(AUTHORIZATION, BEARER + configuration.getOpenaiApiKey());
  75. request.setHeaderMap(headerMap);
  76. ChatCompletionResponseDto response = null;
  77. try {
  78. response = HttpRequestUtils.httpRequest(request, ChatCompletionResponseDto.class);
  79. response.setUser(content.getUser());
  80. } catch (Exception e) {
  81. logUtils.error(e);
  82. }
  83. // 返回结果
  84. return response;
  85. }
  86. }

2.3.9      定义接口常量配置类ChatConfig.class

  用于维护支持的api接口列表

  1. package com.framewiki.gpt.config;
  2. import org.springframework.beans.factory.annotation.Value;
  3. import org.springframework.context.annotation.Configuration;
  4. import org.springframework.stereotype.Component;
  5. /**
  6. * @ProjectName: framewiki-gpt
  7. * @Package: com.framewiki.gpt.config
  8. * @ClassName: GptConfig
  9. * @Description: GPT配置
  10. * @Author: xiaLin
  11. * @Date: 2023/6/10 18:16
  12. * @Version: 1.0
  13. */
  14. @Component
  15. @Configuration
  16. public class ChatConfig {
  17. /**
  18. * 环境
  19. */
  20. @Value("${spring.profiles.active}")
  21. private String active;
  22. /**
  23. * 默认环境
  24. */
  25. private final String defaultActive = "prod";
  26. /**
  27. * 地址
  28. */
  29. private final String OPEN_AI_URI = "https://api.openai.com/v1/";
  30. /**
  31. * 测试地址
  32. */
  33. private final String TEST_OPEN_AI_URI = "https://vpn.itizzy.com/v1/";
  34. /**
  35. * 请求机构
  36. * 列出模型
  37. * 检索模型
  38. */
  39. private final String MODEL_LIST = "models";
  40. /**
  41. * 聊天完成
  42. */
  43. private final String CREATE_CHAT_COMPLETION = "chat/completions";
  44. /**
  45. * 创建对话
  46. */
  47. private final String CREATE_COMPLETION = "completions";
  48. /**
  49. * ;
  50. * 聊天完成地址
  51. *
  52. * @return
  53. */
  54. public String getCreateChatCompletion() {
  55. StringBuffer address = new StringBuffer(getAddress());
  56. address.append(CREATE_CHAT_COMPLETION);
  57. // 返回结果
  58. return address.toString();
  59. }
  60. /**
  61. * 获取地址
  62. */
  63. private String getAddress() {
  64. if (active.startsWith(defaultActive)) {
  65. return OPEN_AI_URI;
  66. } else {
  67. return TEST_OPEN_AI_URI;
  68. }
  69. }
  70. }

2.3.10 接口调用OpenAi配置信息类ChatConfiguration.class

  1. package com.framewiki.gpt.config;
  2. import lombok.Data;
  3. import org.springframework.boot.context.properties.ConfigurationProperties;
  4. import org.springframework.context.annotation.Configuration;
  5. /**
  6. * @ProjectName: framewiki-gpt
  7. * @Package: com.framewiki.gpt.config
  8. * @ClassName: ChatConfiguration
  9. * @Description: java类作用描述
  10. * @Author: xiaLin
  11. * @Date: 2023/6/10 19:35
  12. * @Version: 1.0
  13. */
  14. @Data
  15. @Configuration
  16. @ConfigurationProperties(prefix = "open.ai.gpt")
  17. public class ChatConfiguration {
  18. /**
  19. * openai Api密钥
  20. */
  21. private String openaiApiKey;
  22. /**
  23. * 机构ID
  24. */
  25. private String organizationId;
  26. /**
  27. * appKey
  28. */
  29. private String appKey;
  30. }

3     常见问题

3.1  OpenAi接口调用不通

因为https://api.openai.com/ 地址也被限制了,但是接口没有对地区做校验,因此可以自己搭建一个代理。

我采用的是亚马逊云代理的模式(新账号可申请1H1G、8G硬盘的云服务器),具体代理配置流程如下:

下载及安装nginx就不在此详说了。

部署nginx并修改/nginx/nginx.conf文件,配置接口代理路径如下

  1. server {
  2. listen 443 ssl;
  3. server_name vpn.ai.com;
  4. ssl_certificate /usr/local/cert/vpn.ai.com.pem;
  5. ssl_certificate_key /usr/local/cert/vpn.ai.com.key;
  6. ssl_session_cache shared:SSL:1m;
  7. ssl_session_timeout 5m;
  8. ssl_ciphers HIGH:!aNULL:!MD5;
  9. ssl_prefer_server_ciphers on;
  10. location / {
  11. proxy_pass https://chat.openai.com/;
  12. proxy_ssl_server_name on;
  13. proxy_ssl_session_reuse off;
  14. }
  15. }
  16. }

3.2  接口返回401

检查请求方法是否增加token字段以及key是否正确

4     总结

至此JAVA对OpenAI对接就已经完成了,并且也支持连续对话,大家可以在此基础上不断地完善和桥接到web服务,定制自己的ChatGPT助手了。我自己也搭建了个平台,不断地在完善中,想要体验的可以用微信登录体验。

项目开源地址:https://gitee.com/cdkjframework/chatgpt-server

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/IT小白/article/detail/110293
推荐阅读
相关标签
  

闽ICP备14008679号