springboot整合chatgpt,并且让其可以记录上下文

整合很简单,不过需要几个小条件

1.必须要有openai官方的key

2.国内需要有代理服务器或者国外的服务器把项目部署出去也没问题

我没有使用spring的springAI,听说很方便,日后有机会去体验体验,我今天用了两种方式整合了gpt

1.Chatgpt-Java : 📖 项目简介 | Chatgpt-Java (unfbx.com)

这个巨巨巨方便,整合gpt,可以跟着官网的快速入门走,一下就解决了

先导入maven依赖

        <dependency>
            <groupId>com.unfbx</groupId>
            <artifactId>chatgpt-java</artifactId>
            <version>1.1.5</version>
        </dependency>

然后我直接写接口

@RestController
@RequestMapping("/ai")
@Api(tags = "ai")
public class AiController {

    @ApiOperation("ai对话")
    @PostMapping("/test")
    public ResultResponse test(String msg){

        OpenAiClient openAiClient = OpenAiClient.builder()
                .apiKey(Arrays.asList("xxxxxxxxxxxxxxxxxxxxxxxxxxxxx"))
                .build();

        Message message = Message.builder().role(Message.Role.USER).content(msg).build();
        ChatCompletion chatCompletion = ChatCompletion.builder().messages(Arrays.asList(message)).build();
        ChatCompletionResponse chatCompletionResponse = openAiClient.chatCompletion(chatCompletion);
//        chatCompletionResponse.getChoices().forEach(e -> {
//            System.out.println(e.getMessage());
//        });
        return ResultResponse.success(chatCompletionResponse.getChoices());
    }
}

xxxxxxxxxxxxxxx自己替换成自己的key哈。

结束,到这里就可以直接使用gpt了,自己去postman测试一下就行。

2.直接给官网api发请求

首先3个dto类

@Data
@NoArgsConstructor
@AllArgsConstructor
public class ChatBotRequest {

    private String model;
    private List<Message> messages;
    private int n;
    private double temperature;
    private int max_tokens;
}
------------------------------------------
@Data
@AllArgsConstructor
@NoArgsConstructor
public class ChatBotResponse {

    private List<Choice> choices;

    @Data
    @AllArgsConstructor
    @NoArgsConstructor
    public static class Choice {
        private int index;
        private Message message;
    }
}
------------------------------------------
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Message {

    private String role;
    private String content;

}

其次配置一下config

@Configuration
public class OpenAIChatGtpConfig {

    private final String openaiApiKey = "xxxxxxxxxxxxxxxxxxxxxxx";

    @Bean
    public RestTemplate restTemplate() {

        RestTemplate restTemplate = new RestTemplate();

        restTemplate.getInterceptors().add((request, body, execution) -> {
            request.getHeaders().add("Authorization", "Bearer " + openaiApiKey);
            return execution.execute(request, body);
        });
        
        return restTemplate;
    }
}

最后依然是直接写接口

@Api(tags = "chat")
@RestController
@RequestMapping("/chats")
public class ChatBotController {

    @Autowired
    private RestTemplate restTemplate;

    @ApiOperation("chat")
    @PostMapping("/chat")
    public ChatBotResponse chat(@RequestParam("prompt") String prompt) {

        ChatBotRequest request = new ChatBotRequest("gpt-3.5-turbo",
                Arrays.asList(new Message("user", prompt)),
                1,
                0,
                100);

        ChatBotResponse chatBotResponse = restTemplate.postForObject("https://api.openai.com/v1/chat/completions", request, ChatBotResponse.class);
        return chatBotResponse;
    }
}

至此第二种整合方式也结束了,其实就这种阻塞式整合真的很简单,不过体验感其实比不上流式整合,回头什么时候去试试流式整合。

Cannot resolve method 'of' in 'List' 或 找不到符号of

顺带今天碰见了一点小报错,才知道Arrays.asList其实等同于List.of。不过List.of是jdk9里面新出的,jdk8没有,因此只能用自己的老东西Arrays.asList。( 参考的是【BUG】Cannot resolve method 'of' in 'List' 或 找不到符号of(非jdk8版本问题)_cannot resolve method 'of' in 'list-CSDN博客

两种整合方式都可以顺利连通,不过此时我发现gpt竟然无法联系上下文。去网上找了很久发现原来暂时没有可以直接自己联系上下文的大模型,因此得自己来做操作。感到疑惑可以看一下这个博客:手把手教会你如何通过ChatGPT API实现上下文对话 - 个人文章 - SegmentFault 思否

原理很简单,每次把之前得mes全部拼接起来,直接开始实现吧:

maven依赖:

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

@RestController
@RequestMapping("/ai")
@Api(tags = "ai")
public class AiController {
    public static final String token = "sk-proj-xElzheeQc3nqZrWm3J6lT3BlbkFJRCQpGjcqfdkj5jsdC1KM";

    private static final String CHAT_HISTORY_KEY = "chat_history";

    @Autowired
    private RedisTemplate<String, String> redisTemplate;

    @Autowired
    private AiService aiService;

    @ApiOperation("ai对话")
    @PostMapping("/tall")
    public ResultResponse tall(@RequestParam("msg") String msg,@RequestParam("userId") String userId) {
        String keyword = CHAT_HISTORY_KEY + "_tall" + userId;
        ListOperations<String, String> listOps = redisTemplate.opsForList();
        Message userMessage = Message.builder().role(Message.Role.USER).content(msg).build();
        List<String> history = listOps.range(keyword , 0, -1);
        List<Message> messages = new ArrayList<>();
        for (String historicalMessage : history) {
            messages.add(Message.builder().role(Message.Role.USER).content(historicalMessage).build());
        }
        messages.add(userMessage);
        OpenAiClient openAiClient = OpenAiClient.builder()
                .apiKey(Arrays.asList(token))
                .build();
        ChatCompletion chatCompletion = ChatCompletion
                .builder()
                .messages(messages)
                .model("gpt-3.5-turbo")
                .build();
        ChatCompletionResponse chatCompletionResponse = openAiClient.chatCompletion(chatCompletion);
        String gptResponse = chatCompletionResponse.getChoices().get(0).getMessage().getContent();
        if(redisTemplate.opsForList().size(keyword ) >= 6){
            listOps.leftPop(keyword );
        }
        listOps.rightPush(keyword, "user:"+msg); //指定role角色更有利于ai理解上下文信息
        listOps.rightPush(keyword, "assistant:"+gptResponse);
        return ResultResponse.success(gptResponse);
    }
}

很简单,就用了redis得list结构当作一个消息队列用,记录最近得6条上下文,每次拼接过去就好。

防止缓存一直占空间,可以自己弄个定时器每天或者每个月清理一次消息队列。

先再自己得application上面加个开关注解:

@EnableScheduling
@SpringBootApplication()
public class ExamsystemApplication extends SpringBootServletInitializer 

然后直接写定时器:

@Component
public class TimerTask {


    @Autowired
    private RedisTemplate<String, String> redisTemplate;

    @Scheduled(cron = "0 0 0 1 * ?") // 每个月1号的凌晨执行
    public void TaskMethod() {
        try {
            Set<String> keys = redisTemplate.keys("chat_history*");
            redisTemplate.delete(keys);
        } catch (Exception e) {
            System.err.println("Failed to reset frequency: " + e.getMessage());
        }
    }


}

到现在ai也拥有上下文了,爽歪歪。

相关推荐
小R资源11 分钟前
推荐3个AI论文、AI查重、AI降重工具
人工智能·ai论文·ai降重
醉后才知酒浓18 分钟前
图像直方图
人工智能·opencv·计算机视觉
吉小雨21 分钟前
PyTorch 目标检测教程
人工智能·pytorch·目标检测
云起SAAS31 分钟前
AI论文写作PPT思维导图PC小程序开发
人工智能·powerpoint
醉后才知酒浓41 分钟前
介绍一下大模型或者多模态?
人工智能
Amor风信子1 小时前
说说明计算机视觉(CV)技术的优势和挑战。
人工智能·计算机视觉
为啥不能修改昵称啊1 小时前
机器学习中求解模型参数的方法
人工智能·机器学习
AI大模型知识分享1 小时前
零基础入门AI:一键本地运行各种开源大语言模型 - Ollama
人工智能·gpt·语言模型·自然语言处理·chatgpt·开源·prompt
深度学习实战训练营2 小时前
VGG16模型实现新冠肺炎图片多分类
人工智能·分类·数据挖掘
网络研究院5 小时前
人工智能有助于解决 IT/OT 集成安全挑战
网络·人工智能·安全·报告·工业·状况