update welcom message + fix clarification/search prompts to account for sql results
Browse files- app_web.py +22 -17
- src/prompts.py +21 -27
- src/query_engine.py +6 -3
app_web.py
CHANGED
|
@@ -357,7 +357,12 @@ def process_contact_request(original_query:str, qcat_result:Dict, uploaded_files
|
|
| 357 |
|
| 358 |
with st.chat_message("assistant"):
|
| 359 |
st.markdown(response)
|
| 360 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 361 |
export_outputs()
|
| 362 |
|
| 363 |
def process_stata_query(qcat_result, uploaded_files):
|
|
@@ -655,22 +660,22 @@ def main():
|
|
| 655 |
|
| 656 |
# Show KB summary on first visit (LLM-generated welcome summary)
|
| 657 |
if not st.session_state.messages:
|
| 658 |
-
|
| 659 |
-
|
| 660 |
-
|
| 661 |
-
welcome_msg = """
|
| 662 |
-
Welcome to WEAIBot, the AI-powered support assistant for the WEAI Helpdesk.\n\n
|
| 663 |
-
You can start by typing your question below, and WEAIBot will do its best to
|
| 664 |
-
provide an answer based on available WEAI resources.\n\n
|
| 665 |
-
If you would like assistance from a member of the WEAI team, simply send a
|
| 666 |
-
message through the chat and include the email address where we can reach you.
|
| 667 |
-
A support ticket will be created, and a team member will contact you as soon as they are available.
|
| 668 |
-
"""
|
| 669 |
-
st.markdown(welcome_msg)
|
| 670 |
-
|
| 671 |
-
|
| 672 |
-
|
| 673 |
-
|
| 674 |
|
| 675 |
render_sidebar()
|
| 676 |
render_chat()
|
|
|
|
| 357 |
|
| 358 |
with st.chat_message("assistant"):
|
| 359 |
st.markdown(response)
|
| 360 |
+
feedback = st.feedback(options="faces", key=f"fb_contact_{st.session_state.resolution_rounds-1}")
|
| 361 |
+
|
| 362 |
+
st.session_state.messages.append({"role": "assistant",
|
| 363 |
+
"content": response,
|
| 364 |
+
"feedback":feedback,
|
| 365 |
+
"verification_passed":None})
|
| 366 |
export_outputs()
|
| 367 |
|
| 368 |
def process_stata_query(qcat_result, uploaded_files):
|
|
|
|
| 660 |
|
| 661 |
# Show KB summary on first visit (LLM-generated welcome summary)
|
| 662 |
if not st.session_state.messages:
|
| 663 |
+
if "kb_welcome_summary" not in st.session_state:
|
| 664 |
+
st.session_state.kb_welcome_summary = summarize_kb_for_welcome(cfg)
|
| 665 |
+
kb_summary = st.session_state.kb_welcome_summary
|
| 666 |
+
# welcome_msg = """
|
| 667 |
+
# Welcome to WEAIBot, the AI-powered support assistant for the WEAI Helpdesk.\n\n
|
| 668 |
+
# You can start by typing your question below, and WEAIBot will do its best to
|
| 669 |
+
# provide an answer based on available WEAI resources.\n\n
|
| 670 |
+
# If you would like assistance from a member of the WEAI team, simply send a
|
| 671 |
+
# message through the chat and include the email address where we can reach you.
|
| 672 |
+
# A support ticket will be created, and a team member will contact you as soon as they are available.
|
| 673 |
+
# """
|
| 674 |
+
# st.markdown(welcome_msg)
|
| 675 |
+
|
| 676 |
+
if kb_summary:
|
| 677 |
+
with st.expander("Welcome!", expanded=True):
|
| 678 |
+
st.markdown(kb_summary)
|
| 679 |
|
| 680 |
render_sidebar()
|
| 681 |
render_chat()
|
src/prompts.py
CHANGED
|
@@ -22,8 +22,11 @@ ABSOLUTE RULE -- ZERO TOLERANCE FOR HALLUCINATION
|
|
| 22 |
all. Say: "I don't have enough information in the provided
|
| 23 |
sources to answer that question."
|
| 24 |
- If the ONLY local source is the Knowledge Base Overview (a
|
| 25 |
-
summary of what files and datasets exist),
|
| 26 |
-
|
|
|
|
|
|
|
|
|
|
| 27 |
information they asked about is not available in the current
|
| 28 |
knowledge base.
|
| 29 |
- Do NOT speculate, extrapolate, or fill in gaps with outside
|
|
@@ -46,6 +49,8 @@ CITATION RULES
|
|
| 46 |
and attach the endnote number immediately after.
|
| 47 |
3. Paraphrased claims still require a numbered endnote.
|
| 48 |
4. Only use endnotes of references included in the reference list.
|
|
|
|
|
|
|
| 49 |
|
| 50 |
---------------------------------------------------------------------
|
| 51 |
REFERENCE LIST FORMAT
|
|
@@ -149,6 +154,12 @@ RULES for SEARCH:
|
|
| 149 |
in the knowledge base. This ensures better retrieval matching.
|
| 150 |
(e.g., if the KB has a column "pts_a" for Political Terror Scale, rewrite
|
| 151 |
"terror scores" as "pts_a Political Terror Scale scores")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 152 |
|
| 153 |
RULES for CLARIFY:
|
| 154 |
- ONLY ask for clarification when the question is genuinely ambiguous
|
|
@@ -163,7 +174,10 @@ RULES for CLARIFY:
|
|
| 163 |
(e.g., instead of "Could you be more specific?", ask "Do you mean the
|
| 164 |
PTS scores from the hr_data.csv dataset, or the CIRI scores from
|
| 165 |
ciri_dataset.dta?")
|
| 166 |
-
|
|
|
|
|
|
|
|
|
|
| 167 |
{sql_routing_block}
|
| 168 |
{kb_overview_block}
|
| 169 |
CONVERSATION HISTORY:
|
|
@@ -174,10 +188,10 @@ USER'S QUESTION: {query}
|
|
| 174 |
Respond in JSON:
|
| 175 |
{{
|
| 176 |
"action": "search" or "clarify",
|
| 177 |
-
"route": "
|
| 178 |
"search_query": "keyword-optimized query for vector search (only if action is search)",
|
| 179 |
"display_query": "clear natural-language question for the AI to answer (only if action is search)",
|
| 180 |
-
"sql_query": "SQLite SELECT query
|
| 181 |
"clarification_question": "question to ask (only if action is clarify)",
|
| 182 |
"reasoning": "one sentence explaining your choice"
|
| 183 |
}}
|
|
@@ -185,30 +199,10 @@ Respond in JSON:
|
|
| 185 |
|
| 186 |
|
| 187 |
_SQL_ROUTING_INSTRUCTIONS = """\
|
| 188 |
-
SQL
|
| 189 |
-
|
| 190 |
-
When choosing a route:
|
| 191 |
-
- "sql" — for data lookups, filtering, aggregation, counting, comparisons
|
| 192 |
-
(e.g., "PTS scores for China", "how many countries", "average GDP")
|
| 193 |
-
- "vector" — for conceptual, definitional, or methodology questions
|
| 194 |
-
(e.g., "what does PTS measure?", "explain the methodology")
|
| 195 |
-
- "vector" — for meta-questions about what data is available
|
| 196 |
-
(e.g., "what datasets do you have?", "what is in the knowledge base?")
|
| 197 |
-
These are answered by codebooks and documentation, not by SQL queries.
|
| 198 |
-
- "both" — for mixed questions combining concepts with data
|
| 199 |
-
(e.g., "explain PTS methodology and show China's scores")
|
| 200 |
-
|
| 201 |
-
IMPORTANT: If the user asks about data summarization, counting, averaging,
|
| 202 |
-
filtering, or any question that requires looking at dataset rows, ALWAYS
|
| 203 |
-
set route to "sql" or "both".
|
| 204 |
-
|
| 205 |
-
When route is "sql" or "both", you MUST provide a valid SQLite SELECT query
|
| 206 |
-
in the "sql_query" field. When route is "vector", you SHOULD still include
|
| 207 |
-
a "sql_query" if the data tables might answer the question as a fallback.
|
| 208 |
-
Use exact equality (=) for text columns. The system will automatically
|
| 209 |
retry with fuzzy matching (LIKE) if the exact query returns no results.
|
| 210 |
Use only table/column names from the schema below.
|
| 211 |
-
|
| 212 |
{schema_text}
|
| 213 |
"""
|
| 214 |
|
|
|
|
| 22 |
all. Say: "I don't have enough information in the provided
|
| 23 |
sources to answer that question."
|
| 24 |
- If the ONLY local source is the Knowledge Base Overview (a
|
| 25 |
+
summary of what files and datasets exist), or a requested
|
| 26 |
+
resource cannot be found in WEAIbot's knowledge base, do not assume
|
| 27 |
+
that it does not exist. Explain that the WEAI team may have access to
|
| 28 |
+
additional resources that are not publicly available, and recommend
|
| 29 |
+
contacting the WEAI Helpdesk for assistance. Also note that the specific
|
| 30 |
information they asked about is not available in the current
|
| 31 |
knowledge base.
|
| 32 |
- Do NOT speculate, extrapolate, or fill in gaps with outside
|
|
|
|
| 49 |
and attach the endnote number immediately after.
|
| 50 |
3. Paraphrased claims still require a numbered endnote.
|
| 51 |
4. Only use endnotes of references included in the reference list.
|
| 52 |
+
5. ONLY use titles, authors, publication dates, and links (if available)
|
| 53 |
+
and DO NOT include any document paths
|
| 54 |
|
| 55 |
---------------------------------------------------------------------
|
| 56 |
REFERENCE LIST FORMAT
|
|
|
|
| 154 |
in the knowledge base. This ensures better retrieval matching.
|
| 155 |
(e.g., if the KB has a column "pts_a" for Political Terror Scale, rewrite
|
| 156 |
"terror scores" as "pts_a Political Terror Scale scores")
|
| 157 |
+
- ALWAYS include a sql query whenever a schema is provided and there are relevant documents in the sql database
|
| 158 |
+
- Give detailed reasoning whenever you choose not to include a sql query.
|
| 159 |
+
- DO NOT treat sources in the knowledge base as separate. Retrieve ALL relevant information from all available sources and present a unified response with the relevant citations.
|
| 160 |
+
- ONLY use titles, authors, publication dates, and links (if available) and DO NOT include any document paths
|
| 161 |
+
- ALWAYS note the specific WEAI version(s) in the user query and ONLY return results relevant to the version(s) specified. Ask for clarification if not sure
|
| 162 |
+
|
| 163 |
|
| 164 |
RULES for CLARIFY:
|
| 165 |
- ONLY ask for clarification when the question is genuinely ambiguous
|
|
|
|
| 174 |
(e.g., instead of "Could you be more specific?", ask "Do you mean the
|
| 175 |
PTS scores from the hr_data.csv dataset, or the CIRI scores from
|
| 176 |
ciri_dataset.dta?")
|
| 177 |
+
- ONLY use titles, authors, publication dates, and links (if available) and DO NOT include any document paths
|
| 178 |
+
- DO NOT treat sources in the knowledge base as separate. Retrieve ALL relevant information from all available sources and present a unified response with the relevant citations.
|
| 179 |
+
- ALWAYS note the specific WEAI version(s) in the user query and ONLY return results relevant to the version(s) specified. Ask for clarification if not sure
|
| 180 |
+
|
| 181 |
{sql_routing_block}
|
| 182 |
{kb_overview_block}
|
| 183 |
CONVERSATION HISTORY:
|
|
|
|
| 188 |
Respond in JSON:
|
| 189 |
{{
|
| 190 |
"action": "search" or "clarify",
|
| 191 |
+
"route": "both",
|
| 192 |
"search_query": "keyword-optimized query for vector search (only if action is search)",
|
| 193 |
"display_query": "clear natural-language question for the AI to answer (only if action is search)",
|
| 194 |
+
"sql_query": "SQLite SELECT query",
|
| 195 |
"clarification_question": "question to ask (only if action is clarify)",
|
| 196 |
"reasoning": "one sentence explaining your choice"
|
| 197 |
}}
|
|
|
|
| 199 |
|
| 200 |
|
| 201 |
_SQL_ROUTING_INSTRUCTIONS = """\
|
| 202 |
+
You have access to structured SQL tables in addition to vector search.Provide a valid SQLite SELECT query
|
| 203 |
+
in the "sql_query" field. Use exact equality (=) for text columns. The system will automatically
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 204 |
retry with fuzzy matching (LIKE) if the exact query returns no results.
|
| 205 |
Use only table/column names from the schema below.
|
|
|
|
| 206 |
{schema_text}
|
| 207 |
"""
|
| 208 |
|
src/query_engine.py
CHANGED
|
@@ -112,18 +112,21 @@ def understand_query(
|
|
| 112 |
from src.kb_meta import load_kb_meta
|
| 113 |
kb_overview = load_kb_meta(cfg)
|
| 114 |
|
|
|
|
|
|
|
| 115 |
prompt = build_query_understanding_prompt(
|
| 116 |
user_query, domain, history,
|
| 117 |
sql_schema_summary=schema_summary,
|
| 118 |
kb_overview=kb_overview,
|
| 119 |
)
|
| 120 |
-
|
|
|
|
| 121 |
try:
|
| 122 |
raw = generate(
|
| 123 |
"You are a query reformulation assistant. Return only JSON.",
|
| 124 |
prompt,
|
| 125 |
cfg,
|
| 126 |
-
max_tokens=
|
| 127 |
)
|
| 128 |
result = _parse_qu_result(raw, user_query)
|
| 129 |
except Exception:
|
|
@@ -136,7 +139,7 @@ def understand_query(
|
|
| 136 |
"route": "vector",
|
| 137 |
"sql_query": None,
|
| 138 |
}
|
| 139 |
-
|
| 140 |
return result
|
| 141 |
|
| 142 |
def _parse_qcat_result(raw:str) -> Dict:
|
|
|
|
| 112 |
from src.kb_meta import load_kb_meta
|
| 113 |
kb_overview = load_kb_meta(cfg)
|
| 114 |
|
| 115 |
+
# print(user_query)
|
| 116 |
+
# print("\n")
|
| 117 |
prompt = build_query_understanding_prompt(
|
| 118 |
user_query, domain, history,
|
| 119 |
sql_schema_summary=schema_summary,
|
| 120 |
kb_overview=kb_overview,
|
| 121 |
)
|
| 122 |
+
# print(prompt)
|
| 123 |
+
# print("\n")
|
| 124 |
try:
|
| 125 |
raw = generate(
|
| 126 |
"You are a query reformulation assistant. Return only JSON.",
|
| 127 |
prompt,
|
| 128 |
cfg,
|
| 129 |
+
max_tokens=1024,
|
| 130 |
)
|
| 131 |
result = _parse_qu_result(raw, user_query)
|
| 132 |
except Exception:
|
|
|
|
| 139 |
"route": "vector",
|
| 140 |
"sql_query": None,
|
| 141 |
}
|
| 142 |
+
print(raw)
|
| 143 |
return result
|
| 144 |
|
| 145 |
def _parse_qcat_result(raw:str) -> Dict:
|