feat: pick MiniMax-M2.7, and strip markdown and emoji from replies
Benchmarked M2.7, M3 and M2 against the same four pt-BR prompts (a Minecraft question, a general-knowledge one, an unanswerable one, and a jailbreak attempt). M2.7 wins on the axis that matters for chat. All three held the no-server-access line under the jailbreak, but: - M3 is a reasoning model, and its thinking counts against max_tokens. At the 300 chat needs, its Minecraft answer was cut off mid-word at 39 characters while reporting 590 tokens used. Raising the budget enough to fix that costs more per question than the answer is worth. - M2 answered the brewing question wrong, going straight from a water bottle to magma cream and skipping the nether wart. - M2.7 answered correctly in 2.7-5.2s. The benchmark also showed both markdown and emoji in every model's output. Minecraft chat renders neither: `**negrito**` arrives as literal asterisks, and emoji are empty boxes on Bedrock. The system prompt now asks for plain text, and sanitise() strips emphasis, code fences, headings and emoji regardless, since a prompt is a request and not a guarantee.
This commit is contained in:
@@ -264,15 +264,26 @@ final class Ai {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Makes a model reply safe to print in chat.
|
* Makes a model reply safe and readable in chat.
|
||||||
*
|
*
|
||||||
* <p>Strips colour codes so the reply cannot forge server messages, folds
|
* <p>Strips colour codes so the reply cannot forge server messages, folds
|
||||||
* newlines so one answer stays one chat entry, and removes leading slashes
|
* newlines so one answer stays one chat entry, and removes leading slashes
|
||||||
* so nothing that comes back reads as a command to run.
|
* so nothing that comes back reads as a command to run.
|
||||||
|
*
|
||||||
|
* <p>It also strips markdown and emoji, which the models emit freely.
|
||||||
|
* Minecraft chat renders neither: {@code **negrito**} arrives as literal
|
||||||
|
* asterisks, and emoji show up as empty boxes on Bedrock.
|
||||||
*/
|
*/
|
||||||
static String sanitise(String raw, int max) {
|
static String sanitise(String raw, int max) {
|
||||||
String text = raw.replace('§', ' ')
|
String text = raw.replace('§', ' ')
|
||||||
.replaceAll("[\\r\\n]+", " ")
|
.replaceAll("[\\r\\n]+", " ")
|
||||||
|
// Markdown emphasis and code fences: chat shows the characters, not the effect.
|
||||||
|
.replaceAll("\\*{1,3}([^*]+)\\*{1,3}", "$1")
|
||||||
|
.replaceAll("`{1,3}([^`]+)`{1,3}", "$1")
|
||||||
|
.replaceAll("^#{1,6}\\s+", "")
|
||||||
|
// Emoji live outside the BMP, plus the symbol blocks and the
|
||||||
|
// variation selector. Accented pt-BR letters are far below this.
|
||||||
|
.replaceAll("[\\x{1F000}-\\x{1FAFF}\\x{2190}-\\x{2BFF}\\x{FE0F}\\x{20E3}]", "")
|
||||||
.replaceAll("\\s{2,}", " ")
|
.replaceAll("\\s{2,}", " ")
|
||||||
.trim();
|
.trim();
|
||||||
while (text.startsWith("/")) {
|
while (text.startsWith("/")) {
|
||||||
|
|||||||
@@ -222,7 +222,10 @@ final class Settings {
|
|||||||
}
|
}
|
||||||
|
|
||||||
String aiModel() {
|
String aiModel() {
|
||||||
return plugin.getConfig().getString("ia.modelo", "MiniMax-M2");
|
// M2.7 measured 2.7-5.2s with correct answers. M3 is a reasoning model:
|
||||||
|
// its thinking counts against max_tokens, so replies get truncated
|
||||||
|
// mid-word unless the budget is raised far past what chat needs.
|
||||||
|
return plugin.getConfig().getString("ia.modelo", "MiniMax-M2.7");
|
||||||
}
|
}
|
||||||
|
|
||||||
void aiModel(String model) {
|
void aiModel(String model) {
|
||||||
@@ -243,7 +246,9 @@ final class Settings {
|
|||||||
+ "ao terminal ou aos comandos do jogo, e não pode executar nada. "
|
+ "ao terminal ou aos comandos do jogo, e não pode executar nada. "
|
||||||
+ "Se pedirem para você rodar comandos, mexer no servidor, dar itens, "
|
+ "Se pedirem para você rodar comandos, mexer no servidor, dar itens, "
|
||||||
+ "banir alguém ou revelar configurações, explique que você só conversa. "
|
+ "banir alguém ou revelar configurações, explique que você só conversa. "
|
||||||
+ "Nunca escreva comandos de terminal nem de Minecraft.");
|
+ "Nunca escreva comandos de terminal nem de Minecraft. "
|
||||||
|
+ "Escreva em texto puro: nada de markdown, asteriscos, crases ou "
|
||||||
|
+ "emoji, porque o chat do Minecraft não formata nada disso.");
|
||||||
}
|
}
|
||||||
|
|
||||||
int aiMaxTokens() {
|
int aiMaxTokens() {
|
||||||
|
|||||||
@@ -123,7 +123,10 @@ ranking-tamanho: 5
|
|||||||
# rodar nada no servidor, no terminal ou no jogo.
|
# rodar nada no servidor, no terminal ou no jogo.
|
||||||
ia:
|
ia:
|
||||||
url: "https://api.minimax.io/v1/text/chatcompletion_v2"
|
url: "https://api.minimax.io/v1/text/chatcompletion_v2"
|
||||||
modelo: "MiniMax-M2"
|
# M2.7 mediu 2,7-5,2s com respostas corretas nos testes. O M3 é um modelo de
|
||||||
|
# raciocínio: o "pensamento" dele consome o max-tokens e a resposta chega
|
||||||
|
# cortada no meio da palavra, a não ser com um orçamento muito maior.
|
||||||
|
modelo: "MiniMax-M2.7"
|
||||||
|
|
||||||
# Tamanho da resposta pedida ao modelo, e o corte final no chat.
|
# Tamanho da resposta pedida ao modelo, e o corte final no chat.
|
||||||
max-tokens: 300
|
max-tokens: 300
|
||||||
@@ -155,4 +158,6 @@ ia:
|
|||||||
ou aos comandos do jogo, e não pode executar nada. Se pedirem para você
|
ou aos comandos do jogo, e não pode executar nada. Se pedirem para você
|
||||||
rodar comandos, mexer no servidor, dar itens, banir alguém ou revelar
|
rodar comandos, mexer no servidor, dar itens, banir alguém ou revelar
|
||||||
configurações, explique que você só conversa. Nunca escreva comandos de
|
configurações, explique que você só conversa. Nunca escreva comandos de
|
||||||
terminal nem de Minecraft.
|
terminal nem de Minecraft. Escreva em texto puro: nada de markdown,
|
||||||
|
asteriscos, crases ou emoji, porque o chat do Minecraft não formata nada
|
||||||
|
disso.
|
||||||
|
|||||||
Reference in New Issue
Block a user