Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 44 additions & 10 deletions backend/apps/chat/task/llm.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,6 @@

warnings.filterwarnings("ignore")

base_message_count_limit = 6

executor = ThreadPoolExecutor(max_workers=200)

dynamic_ds_types = [1, 3]
Expand Down Expand Up @@ -95,6 +93,7 @@ class LLMService:
articles_number: int = 4

enable_sql_row_limit: bool = settings.GENERATE_SQL_QUERY_LIMIT_ENABLED
base_message_round_count_limit: int = settings.GENERATE_SQL_QUERY_HISTORY_ROUND_COUNT

def __init__(self, session: Session, current_user: CurrentUser, chat_question: ChatQuestion,
current_assistant: Optional[CurrentAssistant] = None, no_reasoning: bool = False,
Expand Down Expand Up @@ -185,6 +184,14 @@ async def create(cls, *args, **kwargs):
instance.enable_sql_row_limit = True
else:
instance.enable_sql_row_limit = False
if config.pkey == 'chat.context_record_count':
count_value = config.pval
if count_value is None:
count_value = settings.GENERATE_SQL_QUERY_HISTORY_ROUND_COUNT
count_value = int(count_value)
if count_value < 0:
count_value = 0
instance.base_message_round_count_limit = count_value
return instance

def is_running(self, timeout=0.5):
Expand All @@ -206,22 +213,23 @@ def init_messages(self):
filter(lambda obj: obj.pid == self.chat_question.regenerate_record_id, self.generate_sql_logs), None)
last_sql_messages: List[dict[str, Any]] = _temp_log.messages if _temp_log else []

# todo maybe can configure
count_limit = 0 - base_message_count_limit
count_limit = self.base_message_round_count_limit

self.sql_message = []
# add sys prompt
self.sql_message.append(SystemMessage(
content=self.chat_question.sql_sys_question(self.ds.type, self.enable_sql_row_limit)))
if last_sql_messages is not None and len(last_sql_messages) > 0:
# limit count
for last_sql_message in last_sql_messages[count_limit:]:
# 获取最后3轮对话
last_rounds = get_last_conversation_rounds(last_sql_messages, rounds=count_limit)

for _msg_dict in last_rounds:
_msg: BaseMessage
if last_sql_message['type'] == 'human':
_msg = HumanMessage(content=last_sql_message['content'])
if _msg_dict.get('type') == 'human':
_msg = HumanMessage(content=_msg_dict.get('content'))
self.sql_message.append(_msg)
elif last_sql_message['type'] == 'ai':
_msg = AIMessage(content=last_sql_message['content'])
elif _msg_dict.get('type') == 'ai':
_msg = AIMessage(content=_msg_dict.get('content'))
self.sql_message.append(_msg)

last_chart_messages: List[dict[str, Any]] = self.generate_chart_logs[-1].messages if len(
Expand Down Expand Up @@ -1666,3 +1674,29 @@ def get_lang_name(lang: str):
if normalized.startswith('ko'):
return '韩语'
return '简体中文'


def get_last_conversation_rounds(messages, rounds=settings.GENERATE_SQL_QUERY_HISTORY_ROUND_COUNT):
"""获取最后N轮对话,处理不完整对话的情况"""
if not messages or rounds <= 0:
return []

# 找到所有用户消息的位置
human_indices = []
for index, msg in enumerate(messages):
if msg.get('type') == 'human':
human_indices.append(index)

# 如果没有用户消息,返回空
if not human_indices:
return []

# 计算从哪个索引开始
if len(human_indices) <= rounds:
# 如果用户消息数少于等于需要的轮数,从第一个用户消息开始
start_index = human_indices[0]
else:
# 否则,从倒数第N个用户消息开始
start_index = human_indices[-rounds]

return messages[start_index:]
1 change: 1 addition & 0 deletions backend/common/core/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,7 @@ def SQLALCHEMY_DATABASE_URI(self) -> PostgresDsn | str:

# 是否启用SQL查询行数限制,默认值,可被参数配置覆盖
GENERATE_SQL_QUERY_LIMIT_ENABLED: bool = True
GENERATE_SQL_QUERY_HISTORY_ROUND_COUNT: int = 3

PARSE_REASONING_BLOCK_ENABLED: bool = True
DEFAULT_REASONING_CONTENT_START: str = '<think>'
Expand Down
2 changes: 2 additions & 0 deletions frontend/src/i18n/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@
"memo": "Memo update rules: Match table name and field name. If a match is found, update the table memo and field memo; otherwise, leave the memo unchanged.",
"parameter_configuration": "Parameter Config",
"question_count_settings": "Question Count Settings",
"context_record_count": "Context Record Count",
"context_record_count_hint": "Number of user question rounds",
"model_thinking_process": "Expand Model Thinking Process",
"rows_of_data": "Limit 1000 Rows of Data",
"third_party_platform_settings": "Third-Party Platform Settings",
Expand Down
2 changes: 2 additions & 0 deletions frontend/src/i18n/ko-KR.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@
"memo": "메모 업데이트 규칙: 테이블 이름과 필드 이름이 일치하는지 확인합니다. 일치하는 항목이 있으면 테이블 메모와 필드 메모를 업데이트하고, 그렇지 않으면 메모를 변경하지 않고 그대로 둡니다.",
"parameter_configuration": "매개변수 구성",
"question_count_settings": "질문 수 설정",
"context_record_count": "컨텍스트 기록 수",
"context_record_count_hint": "사용자 질문 라운드 수",
"model_thinking_process": "모델 사고 프로세스 확장",
"rows_of_data": "데이터 1,000행 제한",
"third_party_platform_settings": "타사 플랫폼 설정",
Expand Down
2 changes: 2 additions & 0 deletions frontend/src/i18n/zh-CN.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@
"memo": "备注更新规则:根据表名和字段名匹配,如果匹配则更新表备注和字段备注;如果匹配不上,备注保持不变。",
"parameter_configuration": "参数配置",
"question_count_settings": "问数设置",
"context_record_count": "上下文记录数",
"context_record_count_hint": "用户提问轮数",
"model_thinking_process": "展开模型思考过程",
"rows_of_data": "限制 1000 行数据",
"third_party_platform_settings": "第三方平台设置",
Expand Down
98 changes: 64 additions & 34 deletions frontend/src/views/system/parameter/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,13 @@ const loadData = () => {
})
}

const onContextRecordCountChange = (count: number) => {
if (count < 0) {
state.parameterForm['chat.context_record_count'] = 0
}
state.parameterForm['chat.context_record_count'] = Math.floor(count)
}

const beforeChange = (): Promise<boolean> => {
return new Promise((resolve) => {
if (!state.parameterForm['chat.rows_of_data']) {
Expand Down Expand Up @@ -88,41 +95,66 @@ onMounted(() => {
<div class="card-title">
{{ t('parameter.question_count_settings') }}
</div>
<div class="card-item">
<div class="label">
{{ t('parameter.model_thinking_process') }}
<el-row>
<div class="card-item">
<div class="label">
{{ t('parameter.model_thinking_process') }}

<el-tooltip effect="dark" :content="t('parameter.closed_by_default')" placement="top">
<el-icon size="16">
<icon_info_outlined_1></icon_info_outlined_1>
</el-icon>
</el-tooltip>
<el-tooltip effect="dark" :content="t('parameter.closed_by_default')" placement="top">
<el-icon size="16">
<icon_info_outlined_1></icon_info_outlined_1>
</el-icon>
</el-tooltip>
</div>
<div class="value">
<el-switch v-model="state.parameterForm['chat.expand_thinking_block']" />
</div>
</div>
<div class="value">
<el-switch v-model="state.parameterForm['chat.expand_thinking_block']" />
<div class="card-item" style="margin-left: 16px">
<div class="label">
{{ t('parameter.rows_of_data') }}
<el-tooltip
effect="dark"
:content="t('parameter.excessive_data_volume')"
placement="top"
>
<el-icon size="16">
<icon_info_outlined_1></icon_info_outlined_1>
</el-icon>
</el-tooltip>
</div>
<div class="value">
<el-switch
v-model="state.parameterForm['chat.limit_rows']"
:before-change="beforeChange"
/>
</div>
</div>
</div>

<div class="card-item" style="margin-left: 16px">
<div class="label">
{{ t('parameter.rows_of_data') }}
<el-tooltip
effect="dark"
:content="t('parameter.excessive_data_volume')"
placement="top"
>
<el-icon size="16">
<icon_info_outlined_1></icon_info_outlined_1>
</el-icon>
</el-tooltip>
</div>
<div class="value">
<el-switch
v-model="state.parameterForm['chat.limit_rows']"
:before-change="beforeChange"
/>
</el-row>
<el-row>
<div class="card-item">
<div class="label">
{{ t('parameter.context_record_count') }}
<el-tooltip
effect="dark"
:content="t('parameter.context_record_count_hint')"
placement="top"
>
<el-icon size="16">
<icon_info_outlined_1></icon_info_outlined_1>
</el-icon>
</el-tooltip>
</div>
<div class="value">
<el-input-number
v-model.number="state.parameterForm['chat.context_record_count']"
min="0"
step="1"
@change="onContextRecordCountChange"
/>
</div>
</div>
</div>
</el-row>
</div>

<platform-param />
Expand Down Expand Up @@ -152,7 +184,6 @@ onMounted(() => {
}
.title {
font-weight: 500;
font-style: Medium;
font-size: 20px;
line-height: 28px;
margin-bottom: 16px;
Expand All @@ -164,12 +195,11 @@ onMounted(() => {
padding: 16px;
border: 1px solid #dee0e3;
display: flex;
flex-wrap: wrap;
flex-direction: column;
margin-top: 16px;

.card-title {
font-weight: 500;
font-style: Medium;
font-size: 16px;
line-height: 24px;
width: 100%;
Expand Down