Java代码完美实现ChatGPT问答能力(可嵌入项目中)

作为目前全球最火的AI模型ChatGPT,相信很多小伙伴和我一样,充满好奇心。根据官网所说,ChatGPT不仅可以完成交互式聊天,可以自然的和人类进行对话,可以通过类比的方式理解和回应自然语言,也可以根据文本信息提取关键字,生成不同创意和格式的文本内容,也可以生成代码,脚本,音乐,视频和信件等。看到如此强大的GPT,此时是否在考虑如何嵌入到自己的工程项目中,并发挥出其强大的数据处理能力和逻辑处理能力?下面这个Demo就是一个简单的java嵌入,供大家学习参考。

1.导入pom依赖:

现在有一些教程是通过HTTP请求,将认证的一些信息封装在请求头中,然后通过HTTP调用来完成逻辑与ChatGPT交互,这种方式可行,但不是很好用,自己需要写一大推Http Client端的代码。从OpenAI官方发现,现在已经有封装好的部分SDK,可以直接拿来使用,具体如下:

    <dependencies>

        <dependency>
            <groupId>com.theokanning.openai-gpt3-javagroupId>
            <artifactId>apiartifactId>
            <version>0.14.0version>
        dependency>

        <dependency>
            <groupId>com.theokanning.openai-gpt3-javagroupId>
            <artifactId>clientartifactId>
            <version>0.14.0version>
        dependency>

        <dependency>
            <groupId>com.theokanning.openai-gpt3-javagroupId>
            <artifactId>serviceartifactId>
            <version>0.14.0version>
        dependency>

    dependencies>
2.初始化OpenAiService

因为国内是无法直接访问OpenAi的,所以即使你有ApiKey,也需要通过"梯子"来实现proxy。下面这段代码通过一个静态代码块来初始化一个OpenAiService,然后根据OpenAiService来创建一个调用模型,执行你想提问的问题:

    protected static OpenAiService openAiService;

    //这块可以根据配置文件配置,我直接提出来了
    protected static final String enableProxy = "true";

    protected static final String apiKey = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";

    static {
        //因为我是读取的配置文件,为了简化,我直接写成成员变量,写死了
        boolean enable = Boolean.parseBoolean(enableProxy);
        if (!enable) {
            openAiService = new OpenAiService(apiKey);
        } else {
            String proxyIp = "localhost";
            int proxyPort = Integer.parseInt("7890");
            ObjectMapper mapper = defaultObjectMapper();
            Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress(proxyIp, proxyPort));
            OkHttpClient client = defaultClient(apiKey, Duration.ofSeconds(30))
                    .newBuilder()
                    .proxy(proxy)
                    .build();
            Retrofit retrofit = defaultRetrofit(client, mapper);
            OpenAiApi api = retrofit.create(OpenAiApi.class);
            openAiService = new OpenAiService(api);
        }
    }
3.调用模型:

这块我给模型定义了两个角色,一个角色是SYSTEM,我给他赋能为一个"中餐厨师,需要根据我传入的菜名返回这道菜的主要食材列表",然后我又用了一个助手ASSISTANT角色,来接收我的提问,我设置的最大返回token数是256(这块需要注意的新申请的账号是有15刀的token额度,当token额度用完之后,是需要购买的。在GPT3.5中提问和返回的token价格是一样的,但在GPT4.0以后,提问和返回的token价格数是不一样的,这增加了很大的使用成本。还有一点,如果你返回的结果比较长,maxTokens这个参数设置不够,那么返回的结果是不完整的)。

    public static ChatMessage chat(String msg) {
        List<ChatMessage> messages = new ArrayList<>();
        ChatMessage systemMessage = new ChatMessage(ChatMessageRole.SYSTEM.value(), "You are a Chinese chef, you need to return the list of main ingredients of this dish according to the name of the Chinese dish I requested");
        messages.add(systemMessage);

        ChatMessage firstMsg = new ChatMessage(ChatMessageRole.ASSISTANT.value(), msg);
        messages.add(firstMsg);
        ChatCompletionRequest request = ChatCompletionRequest
                .builder()
                .model("gpt-3.5-turbo")
                .messages(messages)
                .n(1)
                .maxTokens(256)
                .logitBias(new HashMap<>())
                .build();

        Flowable<ChatCompletionChunk> flowable = openAiService.streamChatCompletion(request);

        ChatMessage chatMessage = openAiService.mapStreamToAccumulator(flowable)
                .lastElement()
                .blockingGet()
                .getAccumulatedMessage();

        return chatMessage;
    }
4.测试执行:

通过控制台输入问题,我们可以向ChatGPT提问,以下这个例子成功实现了这样的功能:

    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        while (true) {
            System.out.print("Query: ");
            String nextLine = scanner.nextLine();
            ChatMessage chat = chat(nextLine);
            System.out.println(chat.getContent());
        }
    }

5.查看返回结果:

根据我提问的问题,成功返回了我想要的结果,但目前有一个问题,如何让每次提问返回的结果格式都能保持一致,这个我暂时还没有解决,目前正在研究中,后续有进展会持续跟新。

Query: 中餐 家常香干烧肉 主要食材取top5 只要菜名  json结构形式返回结果
"菜名": "家常香干烧肉",
"主要食材": ["猪肉", "香干", "姜蒜", "葱", "辣椒"]
Query: 中餐 鱼香肉丝 取主要菜名top5 json结构形式返回结果
{
  "dish_name": "鱼香肉丝",
  "main_ingredients": [
    "猪肉",
    "木耳",
    "胡萝卜",
    "香葱",
    "辣椒"
  ]
}
Query: 

你可能感兴趣的:(chatgpt,openAi,chatgpt,java,开发语言)