refs #731: guard missing game identifiers in few-shot prompt

This commit is contained in:
devmrko
2026-07-24 16:14:18 +09:00
parent 00b62bfb41
commit da992ff524
2 changed files with 15 additions and 7 deletions

View File

@@ -33,6 +33,10 @@ public class SelectAiService {
private static final int MAX_FEW_SHOT_EXAMPLES = 3;
private static final int MAX_FEW_SHOT_SQL_CHARS = 4_000;
private static final int MAX_ENRICHED_PROMPT_LENGTH = 16_000;
private static final String POLICY_PREFIX =
"Answer the original user question using the current approved object list and policy. "
+ "If no game identifier resolves through game-alias metadata, do not select a prefix-specific object "
+ "and do not infer a default game. State that the required game identifier is missing instead.\n\n";
private static final Pattern UNSAFE_SQL = Pattern.compile(
"(?is)\\b(?:insert|update|delete|merge|alter|drop|create|truncate|grant|revoke|"
+ "commit|rollback|savepoint|lock|call|exec(?:ute)?|begin|declare|for\\s+update|"
@@ -174,20 +178,23 @@ public class SelectAiService {
.search(bearerToken, prompt, fewShotTopK(selectAi))
.examples();
if (examples.isEmpty()) {
return new EnrichedPrompt(prompt, "NO_MATCH", 0);
return new EnrichedPrompt(composePolicyPrompt(prompt), "NO_MATCH", 0);
}
return new EnrichedPrompt(
composeFewShotPrompt(prompt, examples), "APPLIED", Math.min(examples.size(), MAX_FEW_SHOT_EXAMPLES));
} catch (Exception ignored) {
// Vector retrieval is an optional prompt aid; preserve the normal Text2SQL path on failure.
return new EnrichedPrompt(prompt, "UNAVAILABLE", 0);
return new EnrichedPrompt(composePolicyPrompt(prompt), "UNAVAILABLE", 0);
}
}
static String composePolicyPrompt(String prompt) {
return POLICY_PREFIX + "Original user question:\n" + prompt;
}
static String composeFewShotPrompt(String prompt, List<QaVectorService.VectorExample> examples) {
StringBuilder enriched = new StringBuilder(
"Answer the original user question using the current approved object list and policy. "
+ "The verified examples below are guidance only: use only relevant SQL patterns, do not invent "
StringBuilder enriched = new StringBuilder(POLICY_PREFIX
+ "The verified examples below are guidance only: use only relevant SQL patterns, do not invent "
+ "identifiers, and do not override current metadata or game-alias resolution policy.\n\n"
+ "Verified few-shot examples:\n");
int included = 0;
@@ -208,7 +215,7 @@ public class SelectAiService {
included++;
}
if (included == 0) {
return prompt;
return composePolicyPrompt(prompt);
}
return enriched.append("Original user question:\n").append(prompt).toString();
}

View File

@@ -25,6 +25,7 @@ class SelectAiFewShotPromptTest {
.contains("Verified few-shot examples")
.contains("SELECT COUNT(*) AS AU_COUNT FROM APP_USER")
.contains("Original user question:\ncurrent active users")
.contains("current approved object list and policy");
.contains("current approved object list and policy")
.contains("do not infer a default game");
}
}