基于SpringAI搭建系统,解决GPT接口批量化请求问题

基于SpringAI搭建系统,采用线程池和负载均衡等技术对大量GPT接口请求进行优化,以解决科研和开发过程中对GPT接口进行批量化接口请求时所遇到的问题。

GitHub地址: https://github.com/linkcao/springai-Wave

大语言模型接口以OpenAI的GPT 3.5为例,JDK版本为17,其他依赖版本可见仓库

拟解决的问题

在处理大量提示文本时,我们面临以下挑战:

  1. API密钥请求限制:大部分AI服务提供商对API密钥的请求次数有限制,单个密钥每分钟只能发送有限数量的请求。
  2. 处理速度慢:大量的提示文本需要逐条发送请求,处理速度较慢,影响效率。
  3. 结果保存和分析困难:处理完成的结果需要保存到本地数据库中,并进行后续的数据分析,但这一过程相对复杂。

解决方案

为了解决上述问题,本文提出了一种基于Spring框架的批量化提示访问方案,如下图所示:

其中具体包括以下步骤:

  1. 多线程处理提示文本:将每个提示文本视为一个独立任务,采用线程池的方式进行多线程处理,提高处理效率。
  2. 动态分配API密钥:在线程池初始化时,通过读取本地数据库中存储的API密钥信息,动态分配每个线程单元所携带的密钥,实现负载均衡。
  3. 结果保存和管理:在请求完成后,将每个请求的问题和回答保存到本地数据库中,以便后续的数据分析和管理。
  4. 状态实时更新:将整个批量请求任务区分为进行中、失败和完成状态,并通过数据库保存状态码实时更新任务状态,方便监控和管理。

关键代码示例

多线程异步请求提示信息(所在包: ChatService)

// 线程池初始化
private static final ExecutorService executor = Executors.newFixedThreadPool(10);
/**
 * 多线程请求提示
 * @param prompts
 * @param user
 * @param task
 * @return
 */
@Async
public CompletableFuture<Void> processPrompts(List<String> prompts, Users user, Task task) {
    for (int i = 0; i < prompts.Size();i++) {
        int finalI = i;
        // 提交任务
        executor.submit(() -> processPrompt(prompts.get(finalI), user, finalI));
    }
    // 设置批量任务状态
    task.setStatus(TaskStatus.COMPLETED);
    taskService.setTask(task);
    return CompletableFuture.completedFuture(null);
}

如上所示,利用了Spring框架的 @Async 注解和 线程池 的功能,实现了多线程异步处理提示信息。

  • 首先,使用了 ExecutorService 创建了一个固定大小的线程池,以便同时处理多个提示文本。
  • 然后,通过 CompletableFuture 来实现异步任务的管理。
  • 在处理每个提示文本时,通过 executor.submit() 方法提交一个任务给线程池,让线程池来处理。
  • 处理完成后,将批量任务的状态设置为已完成,并更新任务状态。
  • 一个线程任务需要绑定请求的用户以及所在的批量任务,当前任务所分配的key由任务所在队列的下标决定。
... (后续内容略)
热门手游下载
下载排行榜