Skip to content
Merged
Original file line number Diff line number Diff line change
Expand Up @@ -74,8 +74,9 @@ public void onSlashCommand(SlashCommandInteractionEvent event) {
public void onModalSubmitted(ModalInteractionEvent event, List<String> args) {
event.deferReply().queue();

String context = "";
Optional<String[]> optional =
chatGptService.ask(event.getValue(QUESTION_INPUT).getAsString());
chatGptService.ask(event.getValue(QUESTION_INPUT).getAsString(), context);
if (optional.isPresent()) {
userIdToAskedAtCache.put(event.getMember().getId(), Instant.now());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,30 @@
public class ChatGptService {
private static final Logger logger = LoggerFactory.getLogger(ChatGptService.class);
private static final Duration TIMEOUT = Duration.ofSeconds(90);

/** The maximum number of tokens allowed for the generated answer. */
private static final int MAX_TOKENS = 3_000;

/**
* This parameter reduces the likelihood of the AI repeating itself. A higher frequency penalty
* makes the model less likely to repeat the same lines verbatim. It helps in generating more
* diverse and varied responses.
*/
private static final double FREQUENCY_PENALTY = 0.5;

/**
* This parameter controls the randomness of the AI's responses. A higher temperature results in
* more varied, unpredictable, and creative responses. Conversely, a lower temperature makes the
* model's responses more deterministic and conservative.
*/
private static final double TEMPERATURE = 0.8;

/**
* n: This parameter specifies the number of responses to generate for each prompt. If n is more
* than 1, the AI will generate multiple different responses to the same prompt, each one being
* a separate iteration based on the input.
*/
private static final int MAX_NUMBER_OF_RESPONSES = 1;
private static final String AI_MODEL = "gpt-3.5-turbo";

private boolean isDisabled = false;
Expand All @@ -42,18 +65,16 @@ public ChatGptService(Config config) {

openAiService = new OpenAiService(apiKey, TIMEOUT);

ChatMessage setupMessage = new ChatMessage(ChatMessageRole.SYSTEM.value(),
"""
Please answer questions in 1500 characters or less. Remember to count spaces in the
character limit. For code supplied for review, refer to the old code supplied rather than
rewriting the code. Don't supply a corrected version of the code.\s""");
ChatMessage setupMessage = new ChatMessage(ChatMessageRole.SYSTEM.value(), """
For code supplied for review, refer to the old code supplied rather than
rewriting the code. DON'T supply a corrected version of the code.\s""");
ChatCompletionRequest systemSetupRequest = ChatCompletionRequest.builder()
.model(AI_MODEL)
.messages(List.of(setupMessage))
.frequencyPenalty(0.5)
.temperature(0.3)
.frequencyPenalty(FREQUENCY_PENALTY)
.temperature(TEMPERATURE)
.maxTokens(50)
.n(1)
.n(MAX_NUMBER_OF_RESPONSES)
.build();

// Sending the system setup message to ChatGPT.
Expand All @@ -68,26 +89,29 @@ public ChatGptService(Config config) {
* @see <a href="https://platform.openai.com/docs/guides/chat/managing-tokens">ChatGPT
* Tokens</a>.
*/
public Optional<String[]> ask(String question) {
public Optional<String[]> ask(String question, String context) {
if (isDisabled) {
return Optional.empty();
}

try {
ChatMessage chatMessage =
new ChatMessage(ChatMessageRole.USER.value(), Objects.requireNonNull(question));
String instructions = "KEEP IT CONCISE, NOT MORE THAN 280 WORDS";
String questionWithContext = "context: Category %s on a Java Q&A discord server. %s %s"
.formatted(context, instructions, question);
ChatMessage chatMessage = new ChatMessage(ChatMessageRole.USER.value(),
Objects.requireNonNull(questionWithContext));
ChatCompletionRequest chatCompletionRequest = ChatCompletionRequest.builder()
.model(AI_MODEL)
.messages(List.of(chatMessage))
.frequencyPenalty(0.5)
.temperature(0.3)
.frequencyPenalty(FREQUENCY_PENALTY)
.temperature(TEMPERATURE)
.maxTokens(MAX_TOKENS)
.n(1)
.n(MAX_NUMBER_OF_RESPONSES)
.build();

String response = openAiService.createChatCompletion(chatCompletionRequest)
.getChoices()
.get(0)
.getFirst()
.getMessage()
.getContent();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,11 @@ RestAction<Message> constructChatGptAttempt(ThreadChannel threadChannel,
String question = questionOptional.get();
logger.debug("The final question sent to chatGPT: {}", question);

chatGPTAnswer = chatGptService.ask(question);
ForumTag defaultTag = threadChannel.getAppliedTags().getFirst();
ForumTag matchingTag = getCategoryTagOfChannel(threadChannel).orElse(defaultTag);

String context = matchingTag.getName();
chatGPTAnswer = chatGptService.ask(question, context);
if (chatGPTAnswer.isEmpty()) {
return useChatGptFallbackMessage(threadChannel);
}
Expand Down Expand Up @@ -178,20 +182,6 @@ private Optional<String> prepareChatGptQuestion(ThreadChannel threadChannel,
.min(MAX_QUESTION_LENGTH - questionBuilder.length(), originalQuestion.length()));

questionBuilder.append(originalQuestion);

StringBuilder tagBuilder = new StringBuilder();
int stringLength = questionBuilder.length();
for (ForumTag tag : threadChannel.getAppliedTags()) {
String tagName = tag.getName();
stringLength += tagName.length();
if (stringLength > MAX_QUESTION_LENGTH) {
break;
}
tagBuilder.append(String.format("%s ", tagName));
}

questionBuilder.insert(0, tagBuilder);

return Optional.of(questionBuilder.toString());
}

Expand Down