From fc5fdb79ab860ef41d9755baa44f1a0db9415bf5 Mon Sep 17 00:00:00 2001 From: ulleo Date: Mon, 28 Jul 2025 18:01:39 +0800 Subject: [PATCH] feat: chat template i18n --- backend/apps/chat/models/chat_model.py | 30 ++++++++--------- backend/apps/chat/task/llm.py | 7 +++- backend/template.yaml | 46 ++++++++++++-------------- 3 files changed, 43 insertions(+), 40 deletions(-) diff --git a/backend/apps/chat/models/chat_model.py b/backend/apps/chat/models/chat_model.py index 2f771051..7aba311d 100644 --- a/backend/apps/chat/models/chat_model.py +++ b/backend/apps/chat/models/chat_model.py @@ -105,52 +105,52 @@ class AiModelQuestion(BaseModel): rule: str = "" fields: str = "" data: str = "" - lang: str = "zh-CN" + lang: str = "简体中文" filter: str = [] def sql_sys_question(self): - return get_sql_template()['system'].format(engine=self.engine, schema=self.db_schema, question=self.question) + return get_sql_template()['system'].format(engine=self.engine, schema=self.db_schema, question=self.question, lang=self.lang) def sql_user_question(self): return get_sql_template()['user'].format(engine=self.engine, schema=self.db_schema, question=self.question, - rule=self.rule, lang=self.lang) + rule=self.rule) def chart_sys_question(self): - return get_chart_template()['system'].format(sql=self.sql, question=self.question) + return get_chart_template()['system'].format(sql=self.sql, question=self.question, lang=self.lang) def chart_user_question(self): - return get_chart_template()['user'].format(sql=self.sql, question=self.question, rule=self.rule, lang=self.lang) + return get_chart_template()['user'].format(sql=self.sql, question=self.question, rule=self.rule) def analysis_sys_question(self): - return get_analysis_template()['system'] + return get_analysis_template()['system'].format(lang=self.lang) def analysis_user_question(self): - return get_analysis_template()['user'].format(fields=self.fields, data=self.data, lang=self.lang) + return get_analysis_template()['user'].format(fields=self.fields, data=self.data) def predict_sys_question(self): - return get_predict_template()['system'] + return get_predict_template()['system'].format(lang=self.lang) def predict_user_question(self): - return get_predict_template()['user'].format(fields=self.fields, data=self.data, lang=self.lang) + return get_predict_template()['user'].format(fields=self.fields, data=self.data) def datasource_sys_question(self): - return get_datasource_template()['system'] + return get_datasource_template()['system'].format(lang=self.lang) def datasource_user_question(self, datasource_list: str = "[]"): - return get_datasource_template()['user'].format(question=self.question, data=datasource_list, lang=self.lang) + return get_datasource_template()['user'].format(question=self.question, data=datasource_list) def guess_sys_question(self): - return get_guess_question_template()['system'] + return get_guess_question_template()['system'].format(lang=self.lang) def guess_user_question(self, old_questions: str = "[]"): return get_guess_question_template()['user'].format(question=self.question, schema=self.db_schema, - old_questions=old_questions, lang=self.lang) + old_questions=old_questions) def filter_sys_question(self): - return get_permissions_template()['system'] + return get_permissions_template()['system'].format(lang=self.lang) def filter_user_question(self): - return get_permissions_template()['user'].format(sql=self.sql, filter=self.filter, lang=self.lang) + return get_permissions_template()['user'].format(sql=self.sql, filter=self.filter) class ChatQuestion(AiModelQuestion): diff --git a/backend/apps/chat/task/llm.py b/backend/apps/chat/task/llm.py index 2937a4f9..c5ed34c9 100644 --- a/backend/apps/chat/task/llm.py +++ b/backend/apps/chat/task/llm.py @@ -99,7 +99,7 @@ class LLMService: chart_id=chat_id)))) self.change_title = len(history_records) == 0 - chat_question.lang = current_user.language + chat_question.lang = get_lang_name(current_user.language) self.ds = (ds if isinstance(ds, AssistantOutDsSchema) else CoreDatasource(**ds.model_dump())) if ds else None self.chat_question = chat_question @@ -1044,3 +1044,8 @@ def get_token_usage(chunk: BaseMessageChunk, token_usage: dict = {}): token_usage['total_tokens'] = chunk.usage_metadata.get('total_tokens') except Exception: pass + +def get_lang_name(lang: str): + if lang and lang == 'en': + return '英文' + return '简体中文' diff --git a/backend/template.yaml b/backend/template.yaml index a88989f7..13f902df 100644 --- a/backend/template.yaml +++ b/backend/template.yaml @@ -1,6 +1,8 @@ template: sql: system: | + ### 请使用语言:{lang} 回答,若有深度思考过程,则思考过程也需要使用 {lang} 输出 + 任务: 根据表结构和问题生成符合{engine}数据库引擎规范的sql语句,以及sql中所用到的表名(不要包含schema和database,用数组返回)。 你必须遵守以下规则: @@ -42,29 +44,29 @@ template: ### 问题: {question} - ### 请使用 i18n: {lang} 对应的语言输出你的结果 - ### 其他规则: {rule} chart: system: | + ### 请使用语言:{lang} 回答,若有深度思考过程,则思考过程也需要使用 {lang} 输出 + ### 说明: 您的任务是通过给定的问题和SQL生成 JSON 以进行数据可视化。 请遵守以下规则: - 如果需要表格,则生成的 JSON 格式应为: - {{"type":"table", "title": "标题", "columns": [{{"name":"中文字段名1", "value": "SQL 查询列 1(有别名用别名,去掉外层的反引号、双引号、方括号)"}}, {{"name": "中文字段名 2", "value": "SQL 查询列 2(有别名用别名,去掉外层的反引号、双引号、方括号)"}}]}} + {{"type":"table", "title": "标题", "columns": [{{"name":"{lang}字段名1", "value": "SQL 查询列 1(有别名用别名,去掉外层的反引号、双引号、方括号)"}}, {{"name": "{lang}字段名 2", "value": "SQL 查询列 2(有别名用别名,去掉外层的反引号、双引号、方括号)"}}]}} 必须从 SQL 查询列中提取“columns”。 - 如果需要柱状图,则生成的 JSON 格式应为(如果有分类则在JSON中返回series): - {{"type":"column", "title": "标题", "axis": {{"x": {{"name":"x轴的中文名称", "value": "SQL 查询 x 轴的列(有别名用别名,去掉外层的反引号、双引号、方括号)"}}, "y": {{"name":"y轴的中文名称","value": "SQL 查询 y 轴的列(有别名用别名,去掉外层的反引号、双引号、方括号)"}}, "series": {{"name":"分类的中文名称","value":"SQL 查询分类的列(有别名用别名,去掉外层的反引号、双引号、方括号)"}}}}}} + {{"type":"column", "title": "标题", "axis": {{"x": {{"name":"x轴的{lang}名称", "value": "SQL 查询 x 轴的列(有别名用别名,去掉外层的反引号、双引号、方括号)"}}, "y": {{"name":"y轴的{lang}名称","value": "SQL 查询 y 轴的列(有别名用别名,去掉外层的反引号、双引号、方括号)"}}, "series": {{"name":"分类的{lang}名称","value":"SQL 查询分类的列(有别名用别名,去掉外层的反引号、双引号、方括号)"}}}}}} 必须从 SQL 查询列中提取“x”和“y”。 - 如果需要条形图,则生成的 JSON 格式应为(如果有分类则在JSON中返回series),条形图相当于是旋转后的柱状图,因此 x 轴仍为维度轴,y 轴仍为指标轴: - {{"type":"bar", "title": "标题", "axis": {{"x": {{"name":"x轴的中文名称", "value": "SQL 查询 x 轴的列(有别名用别名,去掉外层的反引号、双引号、方括号)"}}, "y": {{"name":"y轴的中文名称","value": "SQL 查询 y 轴的列(有别名用别名,去掉外层的反引号、双引号、方括号)"}}, "series": {{"name":"分类的中文名称","value":"SQL 查询分类的列(有别名用别名,去掉外层的反引号、双引号、方括号)"}}}}}} + {{"type":"bar", "title": "标题", "axis": {{"x": {{"name":"x轴的{lang}名称", "value": "SQL 查询 x 轴的列(有别名用别名,去掉外层的反引号、双引号、方括号)"}}, "y": {{"name":"y轴的{lang}名称","value": "SQL 查询 y 轴的列(有别名用别名,去掉外层的反引号、双引号、方括号)"}}, "series": {{"name":"分类的{lang}名称","value":"SQL 查询分类的列(有别名用别名,去掉外层的反引号、双引号、方括号)"}}}}}} 必须从 SQL 查询列中提取“x”和“y”。 - 如果需要折线图,则生成的 JSON 格式应为(如果有分类则在JSON中返回series): - {{"type":"line", "title": "标题", "axis": {{"x": {{"name":"x轴的中文名称","value": "SQL 查询 x 轴的列(有别名用别名,去掉外层的反引号、双引号、方括号)"}}, "y": {{"name":"y轴的中文名称","value": "SQL 查询 y 轴的列(有别名用别名,去掉外层的反引号、双引号、方括号)"}}, "series": {{"name":"分类的中文名称","value":"SQL 查询分类的列(有别名用别名,去掉外层的反引号、双引号、方括号)"}}}}}} + {{"type":"line", "title": "标题", "axis": {{"x": {{"name":"x轴的{lang}名称","value": "SQL 查询 x 轴的列(有别名用别名,去掉外层的反引号、双引号、方括号)"}}, "y": {{"name":"y轴的{lang}名称","value": "SQL 查询 y 轴的列(有别名用别名,去掉外层的反引号、双引号、方括号)"}}, "series": {{"name":"分类的{lang}名称","value":"SQL 查询分类的列(有别名用别名,去掉外层的反引号、双引号、方括号)"}}}}}} 其中“x”和“y”必须从SQL查询列中提取。 - 如果需要饼图,则生成的 JSON 格式应为: - {{"type":"pie", "title": "标题", "axis": {{"y": {{"name":"值轴的中文名称","value":"SQL 查询数值的列(有别名用别名,去掉外层的反引号、双引号、方括号)"}}, "series": {{"name":"分类的中文名称","value":"SQL 查询分类的列(有别名用别名,去掉外层的反引号、双引号、方括号)"}}}}}} + {{"type":"pie", "title": "标题", "axis": {{"y": {{"name":"值轴的{lang}名称","value":"SQL 查询数值的列(有别名用别名,去掉外层的反引号、双引号、方括号)"}}, "series": {{"name":"分类的{lang}名称","value":"SQL 查询分类的列(有别名用别名,去掉外层的反引号、双引号、方括号)"}}}}}} 其中“y”和“series”必须从SQL查询列中提取。 - 如果答案未知或者与生成JSON无关,则生成的 JSON 格式应为: {{"type":"error", "reason": "抱歉,我无法回答您的问题。"}} @@ -85,12 +87,12 @@ template: ### 问题: {question} - ### 请使用 i18n: {lang} 对应的语言输出你的结果 - ### 其他规则: {rule} guess: system: | + ### 请使用语言:{lang} 回答,不需要输出深度思考过程 + ### 说明: 您的任务是根据给定的表结构,用户问题以及以往用户提问,推测用户接下来可能提问的1-4个问题。 请遵循以下规则: @@ -106,14 +108,12 @@ template: - 最多返回4个你推测出的结果 - 若无法推测,则返回空数据JSON: [] - - 不需要思考过程,或者尽量精简思考过程(重要) + - 若你的给出的JSON不是{lang}的,则必须翻译为{lang} ### 响应, 请直接返回JSON结果: ```json user: | - ### 请使用 i18n: {lang} 对应的语言输出你的结果 - ### 表结构: {schema} @@ -124,12 +124,11 @@ template: {old_questions} analysis: system: | + ### 请使用语言:{lang} 回答,若有深度思考过程,则思考过程也需要使用 {lang} 输出 + ### 说明: 你是一个数据分析师,你的任务是根据给定的数据分析数据,并给出你的分析结果。 - user: | - ### 请使用 i18n: {lang} 对应的语言输出你的结果 - ### 字段(字段别名): {fields} @@ -137,16 +136,15 @@ template: {data} predict: system: | + ### 请使用语言:{lang} 回答,若有深度思考过程,则思考过程也需要使用 {lang} 输出 + ### 说明: - 你是一个数据分析师,你的任务是根据给定的数据进行数据预测,我将以json格式给你一组数据,你帮我预测之后的数据(一段可以展示趋势的数据,至少2个周期),用json数组的格式返回,返回的格式需要与传入的数据格式保持一致。 + 你是一个数据分析师,你的任务是根据给定的数据进行数据预测,我将以JSON格式给你一组数据,你帮我预测之后的数据(一段可以展示趋势的数据,至少2个周期),用json数组的格式返回,返回的格式需要与传入的数据格式保持一致。 ```json - 无法预测或者不支持预测的数据请直接返回(不需要返回JSON格式):"抱歉,该数据无法进行预测。(有原因则返回无法预测的原因)" + 无法预测或者不支持预测的数据请直接返回(不需要返回JSON格式,需要翻译为 {lang} 输出):"抱歉,该数据无法进行预测。(有原因则返回无法预测的原因)" 如果可以预测,则不需要返回原有数据,直接返回预测的部份 - user: | - ### 请使用 i18n: {lang} 对应的语言输出你的结果 - ### 字段(字段别名): {fields} @@ -154,6 +152,8 @@ template: {data} datasource: system: | + ### 请使用语言:{lang} 回答 + ### 说明: 你是一个数据分析师,你需要根据用户的提问,以及提供的数据源列表(格式为JSON数组:[{{"id": 数据源ID1,"name":"数据源名称1","description":"数据源描述1"}},{{"id": 数据源ID2,"name":"数据源名称2","description":"数据源描述2"}}]),根据名称和描述找出最符合用户提问的数据源,这个数据源后续将被用来进行数据的分析 @@ -166,8 +166,6 @@ template: ### 响应, 请直接返回JSON结果: ```json user: | - ### 请使用 i18n: {lang} 对应的语言输出你的结果 - ### 数据源列表: {data} @@ -175,6 +173,8 @@ template: {question} permissions: system: | + ### 请使用语言:{lang} 回答 + ### 说明: 提供给你一句SQL和一组表的过滤条件,从这组表的过滤条件中找出SQL中用到的表所对应的过滤条件,将用到的表所对应的过滤条件添加到提供给你的SQL中(不要替换SQL中原有的条件),生成符合{engine}数据库引擎规范的新SQL语句(如果过滤条件为空则无需处理)。 表的过滤条件json格式如下: @@ -197,8 +197,6 @@ template: ```json user: | - ### 请使用 i18n: {lang} 对应的语言输出你的结果 - ### sql: {sql}