feat: User information in the application conversation log. (#2599)

This commit is contained in:
shaohuzhang1 2025-03-18 15:50:30 +08:00 committed by GitHub
parent aab6a2cdf3
commit 1a7f484a62
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
11 changed files with 93 additions and 38 deletions

View File

@ -124,9 +124,11 @@ def event_content(response,
request_token = 0
response_token = 0
write_context(step, manage, request_token, response_token, all_text)
asker = manage.context.get('form_data', {}).get('asker', None)
post_response_handler.handler(chat_id, chat_record_id, paragraph_list, problem_text,
all_text, manage, step, padding_problem_text, client_id,
reasoning_content=reasoning_content if reasoning_content_enable else '')
reasoning_content=reasoning_content if reasoning_content_enable else ''
, asker=asker)
yield manage.get_base_to_response().to_stream_chunk_response(chat_id, str(chat_record_id), 'ai-chat-node',
[], '', True,
request_token, response_token,
@ -137,8 +139,10 @@ def event_content(response,
logging.getLogger("max_kb_error").error(f'{str(e)}:{traceback.format_exc()}')
all_text = 'Exception:' + str(e)
write_context(step, manage, 0, 0, all_text)
asker = manage.context.get('asker', None)
post_response_handler.handler(chat_id, chat_record_id, paragraph_list, problem_text,
all_text, manage, step, padding_problem_text, client_id)
all_text, manage, step, padding_problem_text, client_id, reasoning_content='',
asker=asker)
add_access_num(client_id, client_type, manage.context.get('application_id'))
yield manage.get_base_to_response().to_stream_chunk_response(chat_id, str(chat_record_id), 'ai-chat-node',
[], all_text,
@ -150,7 +154,6 @@ def event_content(response,
'reasoning_content': ''})
class BaseChatStep(IChatStep):
def execute(self, message_list: List[BaseMessage],
chat_id,
@ -304,9 +307,11 @@ class BaseChatStep(IChatStep):
else:
reasoning_content = reasoning_result.get('reasoning_content') + reasoning_result_end.get(
'reasoning_content')
asker = manage.context.get('asker', None)
post_response_handler.handler(chat_id, chat_record_id, paragraph_list, problem_text,
content, manage, self, padding_problem_text, client_id,
reasoning_content=reasoning_content if reasoning_content_enable else '')
reasoning_content=reasoning_content if reasoning_content_enable else '',
asker=asker)
add_access_num(client_id, client_type, manage.context.get('application_id'))
return manage.get_base_to_response().to_block_response(str(chat_id), str(chat_record_id),
content, True,
@ -320,8 +325,10 @@ class BaseChatStep(IChatStep):
except Exception as e:
all_text = 'Exception:' + str(e)
write_context(self, manage, 0, 0, all_text)
asker = manage.context.get('asker', None)
post_response_handler.handler(chat_id, chat_record_id, paragraph_list, problem_text,
all_text, manage, self, padding_problem_text, client_id)
all_text, manage, self, padding_problem_text, client_id, reasoning_content='',
asker=asker)
add_access_num(client_id, client_type, manage.context.get('application_id'))
return manage.get_base_to_response().to_block_response(str(chat_id), str(chat_record_id), all_text, True, 0,
0, _status=status.HTTP_500_INTERNAL_SERVER_ERROR)

View File

@ -84,7 +84,8 @@ class WorkFlowPostHandler:
answer_text_list=answer_text_list,
run_time=time.time() - workflow.context['start_time'],
index=0)
self.chat_info.append_chat_record(chat_record, self.client_id)
asker = workflow.context.get('asker', None)
self.chat_info.append_chat_record(chat_record, self.client_id, asker)
# 重新设置缓存
chat_cache.set(chat_id,
self.chat_info, timeout=60 * 30)

View File

@ -0,0 +1,20 @@
# Generated by Django 4.2.18 on 2025-03-18 06:05
import application.models.application
import common.encoder.encoder
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('application', '0025_alter_application_prologue'),
]
operations = [
migrations.AddField(
model_name='chat',
name='asker',
field=models.JSONField(default=application.models.application.default_asker, encoder=common.encoder.encoder.SystemEncoder, verbose_name='访问者'),
),
]

View File

@ -115,10 +115,15 @@ class ApplicationDatasetMapping(AppModelMixin):
db_table = "application_dataset_mapping"
def default_asker():
return {'user_name': '游客'}
class Chat(AppModelMixin):
id = models.UUIDField(primary_key=True, max_length=128, default=uuid.uuid1, editable=False, verbose_name="主键id")
application = models.ForeignKey(Application, on_delete=models.CASCADE)
abstract = models.CharField(max_length=1024, verbose_name="摘要")
asker = models.JSONField(verbose_name="访问者", default=default_asker, encoder=SystemEncoder)
client_id = models.UUIDField(verbose_name="客户端id", default=None, null=True)
is_deleted = models.BooleanField(verbose_name="", default=False)

View File

@ -116,13 +116,15 @@ class ChatInfo:
}
def to_pipeline_manage_params(self, problem_text: str, post_response_handler: PostResponseHandler,
exclude_paragraph_id_list, client_id: str, client_type, stream=True):
exclude_paragraph_id_list, client_id: str, client_type, stream=True, form_data=None):
if form_data is None:
form_data = {}
params = self.to_base_pipeline_manage_params()
return {**params, 'problem_text': problem_text, 'post_response_handler': post_response_handler,
'exclude_paragraph_id_list': exclude_paragraph_id_list, 'stream': stream, 'client_id': client_id,
'client_type': client_type}
'client_type': client_type, 'form_data': form_data}
def append_chat_record(self, chat_record: ChatRecord, client_id=None):
def append_chat_record(self, chat_record: ChatRecord, client_id=None, asker=None):
chat_record.problem_text = chat_record.problem_text[0:10240] if chat_record.problem_text is not None else ""
chat_record.answer_text = chat_record.answer_text[0:40960] if chat_record.problem_text is not None else ""
is_save = True
@ -137,8 +139,17 @@ class ChatInfo:
if self.application.id is not None:
# 插入数据库
if not QuerySet(Chat).filter(id=self.chat_id).exists():
asker_dict = {'user_name': '游客'}
if asker is not None:
if isinstance(asker, str):
asker_dict = {
'user_name': asker
}
elif isinstance(asker, dict):
asker_dict = asker
Chat(id=self.chat_id, application_id=self.application.id, abstract=chat_record.problem_text[0:1024],
client_id=client_id, update_time=datetime.now()).save()
client_id=client_id, asker=asker_dict, update_time=datetime.now()).save()
else:
Chat.objects.filter(id=self.chat_id).update(update_time=datetime.now())
# 插入会话记录
@ -171,7 +182,8 @@ def get_post_handler(chat_info: ChatInfo):
answer_text_list=answer_list,
run_time=manage.context['run_time'],
index=len(chat_info.chat_record_list) + 1)
chat_info.append_chat_record(chat_record, client_id)
asker = kwargs.get("asker", None)
chat_info.append_chat_record(chat_record, client_id, asker=asker)
# 重新设置缓存
chat_cache.set(chat_id,
chat_info, timeout=60 * 30)
@ -310,6 +322,7 @@ class ChatMessageSerializer(serializers.Serializer):
stream = self.data.get('stream')
client_id = self.data.get('client_id')
client_type = self.data.get('client_type')
form_data = self.data.get("form_data")
pipeline_manage_builder = PipelineManage.builder()
# 如果开启了问题优化,则添加上问题优化步骤
if chat_info.application.problem_optimization:
@ -331,7 +344,7 @@ class ChatMessageSerializer(serializers.Serializer):
exclude_paragraph_id_list = list(set(paragraph_id_list))
# 构建运行参数
params = chat_info.to_pipeline_manage_params(message, get_post_handler(chat_info), exclude_paragraph_id_list,
client_id, client_type, stream)
client_id, client_type, stream, form_data)
# 运行流水线作业
pipeline_message.run(params)
return pipeline_message.context['chat_result']

View File

@ -1,5 +1,5 @@
SELECT
*
*,to_json(asker) as asker
FROM
application_chat application_chat
LEFT JOIN (

View File

@ -276,6 +276,25 @@ function handleInputFieldList() {
: { title: t('chat.userInput') }
})
}
const getRouteQueryValue = (field: string) => {
let _value = route.query[field]
if (_value != null) {
if (_value instanceof Array) {
_value = _value
.map((item) => {
if (item != null) {
return decodeQuery(item)
}
return null
})
.filter((item) => item != null)
} else {
_value = decodeQuery(_value)
}
return _value
}
return null
}
/**
* 校验参数
*/
@ -294,20 +313,8 @@ const checkInputParam = () => {
let msg = []
for (let f of apiInputFieldList.value) {
if (!api_form_data_context.value[f.field]) {
let _value = route.query[f.field]
let _value = getRouteQueryValue(f.field)
if (_value != null) {
if (_value instanceof Array) {
_value = _value
.map((item) => {
if (item != null) {
return decodeQuery(item)
}
return null
})
.filter((item) => item != null)
} else {
_value = decodeQuery(_value)
}
api_form_data_context.value[f.field] = _value
}
}
@ -315,6 +322,10 @@ const checkInputParam = () => {
msg.push(f.field)
}
}
if (!api_form_data_context.value['asker']) {
api_form_data_context.value['asker'] = getRouteQueryValue('asker')
}
if (msg.length > 0) {
MsgWarning(
`${t('chat.tip.inputParamMessage1')} ${msg.join('、')}${t('chat.tip.inputParamMessage2')}`

View File

@ -13,6 +13,7 @@ export default {
table: {
abstract: 'Title',
chat_record_count: 'Total Messages',
user: 'User',
feedback: {
label: 'User Feedback',
star: 'Agree',

View File

@ -13,6 +13,7 @@ export default {
table: {
abstract: '摘要',
chat_record_count: '对话提问数',
user: '用户',
feedback: {
label: '用户反馈',
star: '赞同',
@ -35,6 +36,6 @@ export default {
},
title: {
placeholder: '请给当前内容设置一个标题,以便管理查看'
},
}
}
}

View File

@ -13,6 +13,7 @@ export default {
table: {
abstract: '摘要',
chat_record_count: '對話提問數',
user: '用戶',
feedback: {
label: '用戶反饋',
star: '贊同',
@ -35,6 +36,6 @@ export default {
},
title: {
placeholder: '請給當前內容設定一個標題,以便管理查看'
},
}
}
}

View File

@ -142,21 +142,16 @@
</template>
</el-table-column>
<el-table-column prop="mark_sum" :label="$t('views.log.table.mark')" align="right" />
<el-table-column prop="asker" :label="$t('views.log.table.user')">
<template #default="{ row }">
{{ row.asker?.user_name }}
</template>
</el-table-column>
<el-table-column :label="$t('views.log.table.recenTimes')" width="180">
<template #default="{ row }">
{{ datetimeFormat(row.update_time) }}
</template>
</el-table-column>
<!-- <el-table-column label="操作" width="70" align="left">
<template #default="{ row }">
<el-tooltip effect="dark" :content="$t('common.delete')" placement="top">
<el-button type="primary" text @click.stop="deleteLog(row)">
<el-icon><Delete /></el-icon>
</el-button>
</el-tooltip>
</template>
</el-table-column> -->
</app-table>
</div>
<ChatRecordDrawer