feat:增加预制问题-答案

This commit is contained in:
雷雨
2025-12-02 17:26:21 +08:00
parent 35da349712
commit a2309606bf
2 changed files with 247 additions and 5 deletions

View File

@@ -12,9 +12,9 @@ from decouple import config
from template.template import get_base_template
from util.utils import extract_nested_json, check_and_get_sql, get_chart_type_from_sql_answer
from datetime import datetime
from util import train_ddl,utils
from util import train_ddl, utils
from util.pre_question_answer import merged_dict
gen_history_llm = ChatOpenAI(
model=config('CHAT_MODEL_NAME', default=''),
@@ -37,6 +37,8 @@ gen_sql_llm = ChatOpenAI(
'''
用于生成sql,生成图表的agent上下文
'''
class SqlAgentState(TypedDict):
user_question: str
rewritten_user_question: Optional[str]
@@ -52,9 +54,13 @@ class SqlAgentState(TypedDict):
sql_retry_count: int
chart_retry_count: int
'''
基于上下文,历史消息,重写用户问题
'''
def _rewrite_user_question(state: SqlAgentState) -> dict:
logger.info(f"user:{state.get('user_id', '1')} ---------------进入 _rewrite_user_question 节点---------------")
user_question = state['user_question']
@@ -76,6 +82,17 @@ def _gen_sql(state: SqlAgentState) -> dict:
logger.info(f"user:{state.get('user_id', '1')} ---------------进入 _gen_sql 节点---------------")
question = state.get('rewritten_user_question', state['user_question'])
service = vn
# 预制问题-答案,后期如模型效果好,可以考虑删除
if state.get('user_question', '') in merged_dict.keys():
logger.info(f"预制问题-答案-】-{state.get('user_question', '')}-hit")
r = merged_dict[state.get('user_question', '')]
r['success'] = True
return {'gen_sql_result': r, "sql_retry_count": 0, "gen_sql_error": ""}
if state.get('rewritten_user_question', '') in merged_dict.keys():
r = merged_dict[state.get('rewritten_user_question', '')]
r['success'] = True
return {'gen_sql_result': r, "sql_retry_count": 0, "gen_sql_error": ""}
question_sql_list = service.get_similar_question_sql(question)
if question_sql_list and len(question_sql_list) > 3:
question_sql_list = question_sql_list[:3]
@@ -97,7 +114,7 @@ def _gen_sql(state: SqlAgentState) -> dict:
logger.info(f"gensql result: {result}")
result = orjson.loads(result)
retry = state.get("sql_retry_count", 0) + 1
return {'gen_sql_result': result, "sql_retry_count": retry,"gen_sql_error":""}
return {'gen_sql_result': result, "sql_retry_count": retry, "gen_sql_error": ""}
except Exception as e:
import traceback
traceback.print_exc()
@@ -122,7 +139,8 @@ def _gen_chart(state: SqlAgentState) -> dict:
[{'role': 'system', 'content': sys_char_temp}, {'role': 'user', 'content': user_char_temp}]).text()
rr = utils.remove_think_tags(rr)
retry = state.get("chart_retry_count", 0) + 1
return {"chart_retry_count": retry, 'gen_chart_result': orjson.loads(extract_nested_json(rr)),"gen_chart_error":""}
return {"chart_retry_count": retry, 'gen_chart_result': orjson.loads(extract_nested_json(rr)),
"gen_chart_error": ""}
except Exception as e:
import traceback
traceback.print_exc()
@@ -183,4 +201,4 @@ memory = MemorySaver()
sql_chart_agent = workflow.compile(checkpointer=memory)
# png_data=sql_chart_agent .get_graph().draw_mermaid_png()
# with open("D://graph.png", "wb") as f:
# f.write(png_data)
# f.write(png_data)

224
util/pre_question_answer.py Normal file
View File

@@ -0,0 +1,224 @@
q_a = {
"数信部上周有哪些人加班": {'sql': '''
SELECT DISTINCT p."id" AS "id",
p."code" AS "工号",
p."name" AS "姓名",
p."work_unit" AS "工作单位",
CASE WHEN ps."status" = '1008' THEN '加班' ELSE '其他' END AS "状态"
FROM "YJOA_APPSERVICE_DB"."t_pr3rl2oj_yj_person_database" p
JOIN "YJOA_APPSERVICE_DB"."t_yj_person_status" ps
ON p."code" = ps."person_id"
JOIN "IUAP_APDOC_BASEDOC"."org_orgs" o ON p."internal_dept" = o."id"
WHERE p."internal_dept" IN (SELECT "id" FROM "IUAP_APDOC_BASEDOC"."org_orgs" START
WITH ("name" || "shortname" LIKE '%数字信息部%') AND "dr" = 0 AND "enable" = 1 AND "code" LIKE '%CYJ%'
CONNECT BY PRIOR "id" = "parentid")
AND p."dr" = 0
AND ps."status" = '1008'
AND ps."date_value" >= TRUNC(SYSDATE) - (TO_CHAR(SYSDATE
, 'd') - 1 + 7)
AND ps."date_value" <= TRUNC(SYSDATE) - (TO_CHAR(SYSDATE
, 'd') - 1) LIMIT 1000
''', 'chart-type': 'table'}
,
"数信部上周有哪些人迟到": {'sql':'''
SELECT p."id" AS "id",
p."code" AS "工号",
p."name" AS "姓名",
p."work_unit" AS "工作单位",
CASE
WHEN ps."status" = '1006' THEN '迟到早退'
WHEN ps."status" = '1009' THEN '迟到'
WHEN ps."status" = '6002' THEN 'am迟到pm在岗'
WHEN ps."status" = '6004' THEN 'am迟到pm缺勤'
ELSE ps."status" END AS "状态"
FROM "YJOA_APPSERVICE_DB"."t_pr3rl2oj_yj_person_database" p
INNER JOIN "YJOA_APPSERVICE_DB"."t_yj_person_status" ps
ON p."code" = ps."person_id"
WHERE ps."status" IN ('1006', '1009', '6002', '6004')
AND ps."date_value" >= TRUNC(SYSDATE) - (TO_CHAR(SYSDATE, 'd') - 1 + 7)
AND ps."date_value" <= TRUNC(SYSDATE) - (TO_CHAR(SYSDATE, 'd') - 1)
AND p."internal_dept" IN (SELECT "id" FROM "IUAP_APDOC_BASEDOC"."org_orgs" START
WITH ("name" || "shortname" LIKE '%数字信息部%' AND "dr" = 0 AND "enable" = 1 AND "code" LIKE '%CYJ%')
CONNECT BY PRIOR "id" = "parentid") AND p."dr" = 0 AND ps."dr" = 0 LIMIT 1000
''','chart-type': 'table'},
"数信部本周有哪些人旷工": {'sql':'''
SELECT p."id" AS "id",
p."code" AS "工号",
p."name" AS "姓名",
p."work_unit" AS "工作单位",
CASE WHEN ps."status" = '1005' THEN '旷工' ELSE ps."status" END AS "状态"
FROM "YJOA_APPSERVICE_DB"."t_yj_person_status" ps
INNER JOIN "YJOA_APPSERVICE_DB"."t_pr3rl2oj_yj_person_database" p
ON p."code" = ps."person_id"
WHERE ps."status" = '1005'
AND ps."date_value" >= TRUNC(SYSDATE) - (TO_CHAR(SYSDATE, 'd') - 1)
AND ps."date_value" <= TRUNC(SYSDATE) - (TO_CHAR(SYSDATE, 'd') - 1) + 7
AND ps."dr" = 0
AND p."dr" = 0
AND p."internal_dept" IN (SELECT "id" FROM "IUAP_APDOC_BASEDOC"."org_orgs" START
WITH ("name" || "shortname" LIKE '%数字信息部%' OR "name" || "shortname" LIKE '%数信中心%') AND "dr" = 0 AND "enable" = 1 AND "code" LIKE '%CYJ%'
CONNECT BY PRIOR "id" = "parentid")
ORDER BY ps."date_value" DESC LIMIT 1000
''','chart-type': 'table'},
'数信部员工连续在藏天数查询': {'sql':'''
SELECT pt."year" AS "年份",
p."code" AS "人员编号",
pt."continuous_in_tibet_days" AS "连续在藏天数",
p."name" AS "姓名",
o."name" AS "部门"
FROM "YJOA_APPSERVICE_DB"."t_pr3rl2oj_yj_person_database" p
INNER JOIN "YJOA_APPSERVICE_DB"."t_yj_person_in_tibat" pt
ON p."code" = pt."person_id"
INNER JOIN "IUAP_APDOC_BASEDOC"."org_orgs" o ON p."internal_dept" = o."id"
WHERE p."dr" = 0
AND pt."dr" = 0
AND p."internal_dept" IN (SELECT "id" FROM "IUAP_APDOC_BASEDOC"."org_orgs" START
WITH ("name" || "shortname" LIKE '%数字信息部%' AND "dr" = 0 AND "enable" = 1 AND "code" LIKE '%CYJ%')
CONNECT BY PRIOR "id" = "parentid")
ORDER BY pt."year" DESC, pt."continuous_in_tibet_days" DESC LIMIT 1000
''','chart-type': 'table'}
,
'数信中心员工累计在藏天数前20名': {'sql':'''
SELECT p."code" AS "人员编号",
p."name" AS "姓名",
o."name" AS "部门",
SUM(pt."count_in_tibat") AS "累计在藏天数"
FROM "YJOA_APPSERVICE_DB"."t_pr3rl2oj_yj_person_database" p
INNER JOIN "YJOA_APPSERVICE_DB"."t_yj_person_in_tibat" pt
ON p."code" = pt."person_id"
INNER JOIN "IUAP_APDOC_BASEDOC"."org_orgs" o ON p."internal_dept" = o."id"
WHERE p."dr" = 0
AND pt."dr" = 0
AND p."internal_dept" IN (SELECT "id" FROM "IUAP_APDOC_BASEDOC"."org_orgs" START
WITH ("name" || "shortname" LIKE '%数信中心%' AND "dr" = 0 AND "enable" = 1 AND "code" LIKE '%CYJ%')
CONNECT BY PRIOR "id" = "parentid")
GROUP BY p."code", p."name", o."name"
ORDER BY SUM (pt."count_in_tibat") DESC LIMIT 20
''','chart-type': 'bar'},
'数信部员工昨日打卡记录查询':{'sql': '''
SELECT a."person_name" AS "person_name",
p."code" AS "employee_code",
a."attendance_time" AS "attendance_time",
a."attendance_address" AS "attendance_address",
CASE
WHEN a."status" = 1 THEN '在岗'
WHEN a."status" = 2 THEN '出差'
WHEN a."status" = 3
THEN '休假' END AS "status_desc",
CASE
WHEN a."enter_or_exit" = 1 THEN ''
WHEN a."enter_or_exit" = 2
THEN '' END AS "entry_exit",
o."name" AS "department_name"
FROM "YJOA_APPSERVICE_DB"."t_yj_person_attendance" a
JOIN "YJOA_APPSERVICE_DB"."t_pr3rl2oj_yj_person_database" p
ON a."person_id" = p."code"
JOIN "IUAP_APDOC_BASEDOC"."org_orgs" o ON p."internal_dept" = o."id"
WHERE a."dr" = 0
AND p."dr" = 0
AND a."attendance_time" >= TRUNC(SYSDATE - 1)
AND a."attendance_time" < TRUNC(SYSDATE)
AND o."id" IN (SELECT o2."id" FROM "IUAP_APDOC_BASEDOC"."org_orgs" o2
START WITH (o2."name" LIKE '%数字信息部%'
OR o2."shortname" LIKE '%数字信息部%')
AND o2."dr" = 0
AND o2."enable" = 1
AND o2."code" LIKE '%CYJ%'
CONNECT BY PRIOR o2."id" = o2."parentid")
ORDER BY a."attendance_time" DESC LIMIT 1000
''','chart-type': 'table'},
'数信中心员工昨日考勤查询':{'sql': '''
SELECT p."code" AS "工号",
p."name" AS "姓名",
o."name" AS "部门名称",
ps."date_value" AS "日期",
CASE
WHEN ps."status" = '1001' THEN '在岗'
WHEN ps."status" = '1002' THEN '出差'
WHEN ps."status" = '1003' THEN '休假,请假'
WHEN ps."status" = '1005' THEN '旷工'
WHEN ps."status" = '1006' THEN '迟到,早退'
WHEN ps."status" = '1007' THEN '休息日'
WHEN ps."status" = '1008' THEN '加班'
WHEN ps."status" = '1009' THEN '迟到'
WHEN ps."status" = '4001' THEN 'am在岗pm缺勤'
WHEN ps."status" = '4002' THEN 'am缺勤pm在岗'
WHEN ps."status" = '6001' THEN 'am在岗pm早退'
WHEN ps."status" = '6002' THEN 'am迟到pm在岗'
WHEN ps."status" = '6004' THEN 'am迟到pm缺勤'
WHEN ps."status" = '4006' THEN 'am缺勤pm早退'
ELSE ps."status" END AS "人员状态"
FROM "YJOA_APPSERVICE_DB"."t_yj_person_status" ps
JOIN "YJOA_APPSERVICE_DB"."t_pr3rl2oj_yj_person_database" p
ON ps."person_id" = p."code"
JOIN "IUAP_APDOC_BASEDOC"."org_orgs" o ON p."internal_dept" = o."id"
WHERE o."id" IN (SELECT id FROM "IUAP_APDOC_BASEDOC"."org_orgs" START
WITH ("name" LIKE '%数信中心%' OR "shortname" LIKE '%数信中心%') AND "enable" = 1 AND "dr" = 0 AND "code" LIKE '%CYJ%'
CONNECT BY PRIOR "id" = "parentid")
AND ps."date_value" = TO_CHAR(SYSDATE - 1
, 'YYYY-MM-DD')
AND ps."dr" = 0
AND p."dr" = 0
ORDER BY ps."date_value" DESC LIMIT 1000
''','chart-type': 'table'},
'外部单位人数最多的前五家是哪几个': {'sql':'''
SELECT o.name AS "外部单位名称", COUNT(p.id) AS "员工人数"
FROM "YJOA_APPSERVICE_DB"."t_pr3rl2oj_yj_person_database" p
INNER JOIN "YJOA_APPSERVICE_DB"."t_pr3rl2oj_outsourcing_org_new" o
ON p.external_unit = o.id
WHERE p.dr = 0
GROUP BY o.name
ORDER BY COUNT(p.id) DESC LIMIT 5
''','chart-type': 'column'},
'数信部员工10月在林芝工作天数排行': {'sql':'''
SELECT p."code" AS "工号",
p."name" AS "姓名",
COUNT(DISTINCT TO_CHAR(a."attendance_time", 'yyyy-MM-dd')) AS "在林芝工作天数"
FROM "YJOA_APPSERVICE_DB"."t_pr3rl2oj_yj_person_database" p
LEFT JOIN "YJOA_APPSERVICE_DB"."t_yj_person_attendance" a
ON p."code" = a."person_id"
LEFT JOIN "YJOA_APPSERVICE_DB"."t_yj_person_ac_area" ac
ON a."access_control_point" = ac."ac_point"
WHERE p."dr" = 0
AND a."dr" = 0
AND ac."region" = 5
AND
p."internal_dept" IN (SELECT "id" FROM "IUAP_APDOC_BASEDOC"."org_orgs" START
WITH ("name" LIKE '%数字信息部%' OR "shortname" LIKE '%数字信息部%') AND "dr" = 0 AND "enable" = 1 AND "code" LIKE '%CYJ%'
CONNECT BY PRIOR "id" = "parentid")
AND TO_CHAR(a."attendance_time"
, 'yyyy-MM') = '2025-10'
GROUP BY p."code", p."name"
ORDER BY "在林芝工作天数" DESC LIMIT 1000
''','chart-type': 'bar'},
'数信中心截止目前满足休假条件的员工有哪些': {'sql':'''
SELECT pt."year" AS "年份",
p."code" AS "人员编号",
pt."continuous_in_tibet_days" AS "连续在藏天数",
p."name" AS "姓名",
o."name" AS "部门"
FROM "YJOA_APPSERVICE_DB"."t_pr3rl2oj_yj_person_database" p
INNER JOIN "YJOA_APPSERVICE_DB"."t_yj_person_in_tibat" pt
ON p."code" = pt."person_id"
INNER JOIN "IUAP_APDOC_BASEDOC"."org_orgs" o ON p."internal_dept" = o."id"
WHERE p."dr" = 0
AND pt."dr" = 0
AND pt."continuous_in_tibet_days" >= 22
AND p."internal_dept" IN
(SELECT id FROM "IUAP_APDOC_BASEDOC"."org_orgs" START
WITH ("name" LIKE '%数信中心%' OR "shortname" LIKE '%数信中心%') AND "dr" = 0 AND "enable" = 1 AND "code" LIKE '%CYJ%'
CONNECT BY PRIOR "id" = "parentid")
ORDER BY pt."continuous_in_tibet_days" DESC
''','chart-type': 'table'}
}
q_a_extent = {
"数字信息部上周有哪些人加班": q_a['数信部上周有哪些人加班'],
"数字信息部上周有哪些人迟到": q_a['数信部上周有哪些人迟到'],
"数字信息部本周有哪些人旷工": q_a['数信部本周有哪些人旷工'],
"数字信息部员工连续在藏天数查询": q_a['数信部员工连续在藏天数查询'],
"数字信息部员工昨日打卡记录查询": q_a['数信部员工昨日打卡记录查询'],
"数字信息部10月在林芝工作天数排行": q_a['数信部员工10月在林芝工作天数排行'],
}
merged_dict = q_a | q_a_extent