refs #731: guard missing game identifiers in few-shot prompt
This commit is contained in:
@@ -33,6 +33,10 @@ public class SelectAiService {
|
|||||||
private static final int MAX_FEW_SHOT_EXAMPLES = 3;
|
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_FEW_SHOT_SQL_CHARS = 4_000;
|
||||||
private static final int MAX_ENRICHED_PROMPT_LENGTH = 16_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(
|
private static final Pattern UNSAFE_SQL = Pattern.compile(
|
||||||
"(?is)\\b(?:insert|update|delete|merge|alter|drop|create|truncate|grant|revoke|"
|
"(?is)\\b(?:insert|update|delete|merge|alter|drop|create|truncate|grant|revoke|"
|
||||||
+ "commit|rollback|savepoint|lock|call|exec(?:ute)?|begin|declare|for\\s+update|"
|
+ "commit|rollback|savepoint|lock|call|exec(?:ute)?|begin|declare|for\\s+update|"
|
||||||
@@ -174,19 +178,22 @@ public class SelectAiService {
|
|||||||
.search(bearerToken, prompt, fewShotTopK(selectAi))
|
.search(bearerToken, prompt, fewShotTopK(selectAi))
|
||||||
.examples();
|
.examples();
|
||||||
if (examples.isEmpty()) {
|
if (examples.isEmpty()) {
|
||||||
return new EnrichedPrompt(prompt, "NO_MATCH", 0);
|
return new EnrichedPrompt(composePolicyPrompt(prompt), "NO_MATCH", 0);
|
||||||
}
|
}
|
||||||
return new EnrichedPrompt(
|
return new EnrichedPrompt(
|
||||||
composeFewShotPrompt(prompt, examples), "APPLIED", Math.min(examples.size(), MAX_FEW_SHOT_EXAMPLES));
|
composeFewShotPrompt(prompt, examples), "APPLIED", Math.min(examples.size(), MAX_FEW_SHOT_EXAMPLES));
|
||||||
} catch (Exception ignored) {
|
} catch (Exception ignored) {
|
||||||
// Vector retrieval is an optional prompt aid; preserve the normal Text2SQL path on failure.
|
// 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) {
|
static String composeFewShotPrompt(String prompt, List<QaVectorService.VectorExample> examples) {
|
||||||
StringBuilder enriched = new StringBuilder(
|
StringBuilder enriched = new StringBuilder(POLICY_PREFIX
|
||||||
"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 "
|
+ "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"
|
+ "identifiers, and do not override current metadata or game-alias resolution policy.\n\n"
|
||||||
+ "Verified few-shot examples:\n");
|
+ "Verified few-shot examples:\n");
|
||||||
@@ -208,7 +215,7 @@ public class SelectAiService {
|
|||||||
included++;
|
included++;
|
||||||
}
|
}
|
||||||
if (included == 0) {
|
if (included == 0) {
|
||||||
return prompt;
|
return composePolicyPrompt(prompt);
|
||||||
}
|
}
|
||||||
return enriched.append("Original user question:\n").append(prompt).toString();
|
return enriched.append("Original user question:\n").append(prompt).toString();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ class SelectAiFewShotPromptTest {
|
|||||||
.contains("Verified few-shot examples")
|
.contains("Verified few-shot examples")
|
||||||
.contains("SELECT COUNT(*) AS AU_COUNT FROM APP_USER")
|
.contains("SELECT COUNT(*) AS AU_COUNT FROM APP_USER")
|
||||||
.contains("Original user question:\ncurrent active users")
|
.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");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user