GPTでテキストからJavaコードを生成する

昨日のエントリでは歌詞と画像を生成したのだけど、歌詞を生成する部分のプロンプトを変えて、エンジンにCodexを使うとコードを生成できます。

GPTを呼び出す部分はこんな感じ

String prompt = "//Java\n" +
        text.getText().trim().lines()
                .map("// %s%n"::formatted)
                .collect(Collectors.joining());
CompletionRequest completionRequest = CompletionRequest.builder()
        .model("code-davinci-002") // or code-cushman-001
        .prompt(prompt)
        .echo(false)
        .temperature(0.3)
        .user("testing")
        .maxTokens(500)
        .build();

プロンプトは// Javaで始まるコメントになるようにしています。そしてモデルにcode-davinci-002を使っています。

あと、生成に時間がかかってデフォルトのままではタイムアウトするので、タイムアウト無制限にしています。

OpenAiService service = new OpenAiService(TOKEN, Duration.ZERO);

これだけでコードを生成してくれるようになりますが、コードを生成してくれるプロンプトを作るのが難しいです。英語でプロンプトを書いてますが、日本語にすると画面のつくりかたを日本語で説明する感じになったりします。

単純なアルゴリズムの指定であれば、比較的楽

生成コードはHTMLエンコードされていたりするので、対応が必要です。あと、最後に</code>がついてそれ以降に説明がついてくるので切り捨てる必要もあると思います。

コードの全体はこんな感じ

package naoki.openai;

import com.theokanning.openai.OpenAiService;
import com.theokanning.openai.completion.CompletionRequest;
import com.theokanning.openai.completion.CompletionResult;
import java.awt.BorderLayout;
import java.time.Duration;
import java.util.stream.Collectors;
import javax.swing.*;

public class GenerateCode {
    public static void main(String[] args) {

        var f = new JFrame("コード生成");
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        var p = new JPanel();
        var text = new JTextArea(4, 60);
        p.add(new JScrollPane(text));
        var button = new JButton("生成");
        p.add(button);
        f.add(p, BorderLayout.NORTH);
        var output = new JTextArea();
        f.add(new JScrollPane(output));
        f.setSize(800, 600);
        f.setVisible(true);
        
        OpenAiService service = new OpenAiService("your token", Duration.ZERO);

        button.addActionListener(al -> {
            String prompt = "//Java\n" +
                    text.getText().trim().lines()
                            .map("// %s%n"::formatted)
                            .collect(Collectors.joining());
            CompletionRequest completionRequest = CompletionRequest.builder()
                    .model("code-davinci-002") // or code-cushman-001
                    .prompt(prompt)
                    .echo(false)
                    .temperature(0.3)
                    .user("testing")
                    .maxTokens(500)
                    .build();

            CompletionResult result = service.createCompletion(completionRequest);
            var code = result.getChoices().get(0).getText()
                    .replace("&gt;", ">").replace("&lt;", "<");
            output.setText(code);
        });
    }
}