Skip to content

Instantly share code, notes, and snippets.

@kishida
Last active June 29, 2023 10:04
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kishida/b473e1aabbb375cead2a9e5a7306ea9a to your computer and use it in GitHub Desktop.
Save kishida/b473e1aabbb375cead2a9e5a7306ea9a to your computer and use it in GitHub Desktop.
English Learning Text Generator with OpenAI GPT
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.util.Arrays;
import java.util.List;
import java.util.NoSuchElementException;
import java.util.concurrent.CompletableFuture;
public class EnglishGenerator {
static String token = System.getenv("OPENAI_API_KEY");
static HttpClient client = HttpClient.newHttpClient();
enum Model {
GPT35("gpt-3.5-turbo-0613"),
GPT4("gpt-4-0613");
String name;
private Model(String name) {
this.name = name;
}
@Override
public String toString() {
return name;
}
}
static class Article {
String text;
List<String> words;
List<String> wordDescriptions;
List<String> questions;
}
static CompletableFuture<Article> generate(String japanese) {
var instruction = prompt.formatted(japanese).replace("\n", "\\n");
var requestText = requestJson.formatted(Model.GPT4, instruction);
System.out.println(requestText);
var request = HttpRequest.newBuilder()
.uri(URI.create("https://api.openai.com/v1/chat/completions"))
.header("Content-Type", "application/json")
.header("Authorization", "Bearer " + token)
.POST(HttpRequest.BodyPublishers.ofString(requestText))
.build();
return client.sendAsync(request, HttpResponse.BodyHandlers.ofString())
.thenApply(HttpResponse::body)
.thenApply(EnglishGenerator::parse);
}
static Article parse(String json) {
try {
var arguments = json.lines().map(String::trim)
.filter(s -> s.startsWith("\"arguments")).findAny()
.map(s -> parseText(s, "arguments"))
.orElseThrow(() -> new NoSuchElementException(
"arguments is not found. it may not be function_call"));
var article = new Article();
String buf = null;
for (String line : arguments.lines().toList()) {
line = line.trim();
if (line.endsWith("[")) {
buf = line;
continue;
}
if (buf != null) {
buf += line;
if (line.endsWith(",")) {
buf += " ";
}
if (!line.startsWith("]")) {
continue;
}
line = buf;
}
if (line.startsWith("\"text")) {
article.text = parseText(line, "text");
} else if (line.startsWith("\"words")) {
article.words = parseTextArray(line, "words");
} else if (line.startsWith("\"word_descriptions")) {
article.wordDescriptions = parseTextArray(line, "word_descriptions");
} else if (line.startsWith("\"questions")) {
article.questions = parseTextArray(line, "questions");
}
}
return article;
} catch(Exception ex) {
System.out.println(ex);
throw ex;
}
}
static String parseText(String line, String name) {
line = line.trim();
var len = line.length();
var text = line.substring(name.length() + 5, len - 1 - (line.endsWith(",") ? 1 : 0));
return text.translateEscapes();
}
static List<String> parseTextArray(String line, String name) {
line = line.trim();
var len = line.length();
var text = line.substring(name.length() + 6, len - 2 - (line.endsWith(",") ? 1 : 0));
return Arrays.stream(text.split("\", \""))
.map(String::translateEscapes)
.toList();
}
static String prompt = """
You are English tutor. The student has vocablary level with 2000 words.
Make a English text with around 200 words by translating and summerizing the text below.
In addition, choose five difficult words from the English text and make three comprehension questions.
You must use the function `english_text`
---
%s
""";
static String requestJson = """
{
"model": "%s",
"messages": [
{"role": "system", "content": "%s"}
],
"functions": [
{
"name": "english_text",
"description": "Set the English articles to learn English",
"parameters": {
"type": "object",
"properties": {
"text": {
"type": "string",
"description": "The English text to learn"
},
"words": {
"type": "array",
"description": "5 difficult words in the text",
"items": {
"type": "string"
}
},
"word_descriptions": {
"type": "array",
"description": "descriptions about the difficult words",
"items": {
"type": "string"
}
},
"questions": {
"type": "array",
"description": "3 complehension questions about the text",
"items": {
"type": "string"
}
}
},
"required": ["text", "words", "word_descriptions", "questions"]
}
}
]
}
""";
}
@kishida
Copy link
Author

kishida commented Jun 29, 2023

bandicam.2023-06-29.13-22-46-582gpt4-cut-merged-1688012926426.mp4

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment