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也拥有上下文了,爽歪歪。

相关推荐
GIS数据转换器10 小时前
城市基础设施安全运行监管平台
大数据·运维·人工智能·物联网·安全·无人机·1024程序员节
遇雪长安10 小时前
深度学习YOLO实战:4、模型的三要素:任务、类别与规模
人工智能·深度学习·yolo
搞科研的小刘选手10 小时前
【云计算专题会议】第二届云计算与大数据国际学术会议(ICCBD 2025)
大数据·人工智能·物联网·5g·云计算·6g·智能通信
电商软件开发 小银10 小时前
微信生态新机遇:视频号推客模式助力商家突围
大数据·人工智能·twitter·系统开发·实体店转型·数字化经济·视频号推客模式
综合热讯10 小时前
湖南粒界教育科技有限公司:专注影视职业教育,AI辅助教学提升学习实效
人工智能·科技·学习
深兰科技10 小时前
深兰科技法务大模型亮相,推动律所文书处理智能化
人工智能·scrapy·beautifulsoup·scikit-learn·pyqt·fastapi·深兰科技
taxunjishu11 小时前
欧姆龙 NX1P2 借助 Ethernet/ip 转 Modbus RTU,与德马泰克设备共创仓库精准货位管理方案
人工智能·嵌入式硬件·物联网·工业物联网·工业自动化
扫地的小何尚11 小时前
一小时内使用NVIDIA Nemotron创建你自己的Bash计算机使用智能体
开发语言·人工智能·chrome·bash·gpu·nvidia
UWA11 小时前
有什么指标可以判断手机是否降频
人工智能·智能手机·性能优化·memory·游戏开发
San3011 小时前
AI 歌词生成器:使用 OpenAI 打造你的专属作词助手
javascript·人工智能·node.js