Analyse des problèmes rencontrés dans le processus de développement logiciel côté PC basé sur l'API ChatGPT

Si vous aimez cet article, n'oubliez pas de le mettre en signet !
Suivez-moi et apprenez Java ensemble.

1. Analyse des problèmes rencontrés dans le processus de développement logiciel côté PC basé sur l'API ChatGPT

Le modèle GPT-4.0 récemment lancé par OpenAI est vraiment chaud. Bien sûr, comme OpenAI n'a pas officiellement ouvert l'API GPT-4.0 au monde extérieur, il utilise cette fois l'API GPT-3.5.

Voyons d'abord les rendus !

image-20230403175127354

Ce client est développé à l'aide de JavaFX. JavaFX Par rapport à Swing, JavaFX prend en charge les styles CSS. Si Java est utilisé pour développer des logiciels d'interface graphique, il est recommandé d'utiliser JavaFX. JavaFX est un projet lancé par Oracle Corporation en 2008. Il convient de noter que les API liées à JavaFX ne sont pas incluses dans les versions supérieures de JDK, vous devez donc installer JavaFX vous-même. Parce que j'ai développé et utilisé JDK 8, je peux appeler l'API JavaFX directement sans installer JavaFX moi-même.

Dans l'image ci-dessus, nous pouvons voir que l'interface utilisateur écrite par JavaFX n'est pas très belle. Il n'y a aucun moyen que Java soit mon langage de programmation principal, donc je ne peux utiliser Java que pour écrire l'interface utilisateur.

Il existe quatre fonctions principales, à savoir : envoyer, enregistrer, afficher, supprimer. Parmi eux, l'envoi est la fonction principale. L'API GPT-3.5 sera appelée indirectement lors de l'envoi. Pourquoi s'appelle-t-il ici appel indirect au lieu d'appel direct ? Tout le monde doit savoir que cette société OpenAI ne nous est pas ouverte en Chine. Bien que nous puissions directement visiter le site officiel d'OpenAI , mais le produit ChatGPT d'OpenAI n'est pas accessible . Nous devons donc ici utiliser un serveur étranger comme serveur de transit. Il est facile de comprendre pourquoi vous pouvez accéder à l'API GPT en utilisant un serveur de transit. Par exemple, vous êtes A, vous pouvez accéder à B, mais vous ne pouvez pas accéder à C, mais B peut accéder à C, alors vous pouvez dire à B de passer le renseignements à C.

Ici, je ne parle que des problèmes rencontrés lors du développement de logiciels clients, pas de la manière d'écrire des interfaces.

2. Le premier problème rencontré est qu'après que l'utilisateur a cliqué sur le bouton d'envoi, le fil est bloqué

Ce problème est principalement dû au fait qu'après que l'utilisateur a cliqué sur le bouton d'envoi, la méthode HttpRequest.post() de la classe d'outils Hutool sera appelée pour envoyer les données à l'interface auto-définie. code afficher comme ci-dessous:

sendButton.setOnAction(e -> sendMessage());
private void sendMessage() {
    
    
    // 获取用户输入的消息并将其添加到聊天区域
    String prompt = inputArea.getText();

    // 获取当前时间
    String nowTime = getNowTime();
    chatArea.appendText(nowTime + "\n");
    chatArea.appendText("我说:" + prompt + "\n\n");

    // 清空输入框
    inputArea.setText("");

    // 存储上下文语境
    messages.add(new Message("user", prompt));

    // 获取 ChatGPT 的回复
    String reply = httpRequest(messages);

    // 机器人回复时间
    String replyTime = getNowTime();
    chatArea.appendText(replyTime + "\n");
    // 把内容显示到 UI 界面上
    chatArea.appendText("机器人说:" + reply + "\n\n");

    messages.add(new Message("assistant", reply));
}

Dans le code ci-dessus, l'utilisateur se sent mal lors de l'exécution, car le thread sera bloqué lors de l'appel de httpRequest(messages). Comme il s'agit d'une opération qui prend beaucoup de temps lorsque le thread actuel fait des requêtes réseau, tout le thread principal sera bloqué, provoquant le blocage de l'application. Si ChatGPT n'a pas répondu, il y sera toujours bloqué.

Peut-être que ce que vous pensez est de créer un nouveau fil pour envoyer la requête http et cela sera résolu. En fait, ce n'est pas le cas. La racine du problème est que nous cliquons sur le bouton "Envoyer". Nous devrions créer un nouveau fil lorsque nous cliquons sur le bouton d'envoi Bien sûr, je suis là Un nouveau fil est également créé lors de l'envoi de http. code afficher comme ci-dessous:

sendButton.setOnAction(e -> {
    
    
    Task<Void> task = new Task<Void>() {
    
    
        @Override
        protected Void call() throws Exception {
    
    
            // 执行耗时操作,例如发送网络请求或执行计算密集型任务
            sendMessage();
            // 返回null
            return null;
        }
    };

    // 在后台线程上执行Task
    new Thread(task).start();

    // 将操作提交到JavaFX应用程序线程队列中
    Platform.runLater(() -> {
    
    
        // 在此更新UI或执行其他需要在JavaFX应用程序线程上执行的操作
    });
});
private void sendMessage() {
    
    
    // 获取用户输入的消息并将其添加到聊天区域
    String prompt = inputArea.getText();

    // 获取当前时间
    String nowTime = getNowTime();
    chatArea.appendText(nowTime + "\n");
    chatArea.appendText("我说:" + prompt + "\n\n");

    // 清空输入框
    inputArea.setText("");

    // 存储上下文语境
    messages.add(new Message("user", prompt));

    // 获取 ChatGPT 的回复
    // String reply = httpRequest(messages);

    // 创建新的线程去发送 ChatGPT 请求
    FutureTask<String> task = new FutureTask<String>(new Callable<String>() {
    
    
        @Override
        public String call() throws Exception {
    
    
            return httpRequest(messages);
        }
    });
    new Thread(task).start();
    try {
    
    
        String reply = task.get();

        // 机器人回复时间
        String replyTime = getNowTime();
        chatArea.appendText(replyTime + "\n");
        // 把内容显示到 UI 界面上
        chatArea.appendText("机器人说:" + reply + "\n\n");

        messages.add(new Message("assistant", reply));
    } catch (Exception e) {
    
    
        e.printStackTrace();
    }
}

Remarque : Si vous souhaitez mettre à jour le contenu de l'interface utilisateur, vous pouvez l'utiliser Platform.runLater().

3. Le deuxième problème est que ChatGPT ne peut pas mener un dialogue continu, c'est-à-dire qu'il n'y a pas de contexte

Ce problème traîne depuis longtemps. La documentation officielle de développement ne semble pas l'expliquer spécifiquement. J'ai étudié le code GitHub et recherché les idées d'autres personnes sur Internet, puis j'ai su que je devais à nouveau envoyer l'historique des discussions à l'API ChatGPT. Mais cela consommera plus de fonds. Parce que OpenAI n'est pas vraiment ouvert.

Nous envoyons simplement l'historique des discussions à ChatGPT à chaque fois.

Ici, nous utilisons une collection pour stocker les enregistrements de chat et ajoutons les enregistrements de chat à la collection à chaque fois. Envoyez ensuite la collection List à l'API ChatGPT.

// 存放上下文语境
private List<Message> messages = new ArrayList<>();
// 存储上下文语境
messages.add(new Message("system", "你是一个助手"));
messages.add(new Message("user", prompt));
messages.add(new Message("assistant", reply));

Le code de la classe Message est le suivant :

@Data
@NoArgsConstructor
@AllArgsConstructor
public class Message {
    
    
    private String role;
    private String content;
}

Le document de développement ChatGPT indique que le rôle a trois valeurs, l'une est le système, indiquant le rôle que ChatGPT doit jouer, la deuxième valeur est l'utilisateur, indiquant un utilisateur, et la troisième est l'assistant, indiquant ChatGPT. Le contenu correspondant au rôle est stocké dans la variable de contenu. Ceci est similaire à une collection de cartes, c'est-à-dire que le rôle est la clé et le contenu est la valeur.


Si vous avez d'autres questions, veuillez visiter le blog .

Je suppose que tu aimes

Origine blog.csdn.net/qq_43907505/article/details/129963946
conseillé
Classement