fix(chat): 拦截无依据的非业务问题
This commit is contained in:
@@ -108,10 +108,13 @@ def send_message(conversation: Conversation, content: str) -> tuple[Message, Mes
|
||||
|
||||
user_message = append_user_message(conversation, content)
|
||||
knowledge_context = build_knowledge_context(content)
|
||||
try:
|
||||
reply_content = generate_reply(conversation, content, knowledge_context=knowledge_context)
|
||||
except (LLMConfigurationError, LLMRequestError) as exc:
|
||||
reply_content = f"模型调用失败:{exc}"
|
||||
if should_refuse_ungrounded_chat(conversation, content, knowledge_context):
|
||||
reply_content = out_of_scope_reply()
|
||||
else:
|
||||
try:
|
||||
reply_content = generate_reply(conversation, content, knowledge_context=knowledge_context)
|
||||
except (LLMConfigurationError, LLMRequestError) as exc:
|
||||
reply_content = f"模型调用失败:{exc}"
|
||||
|
||||
assistant_message = append_assistant_message(conversation, reply_content)
|
||||
|
||||
@@ -127,6 +130,31 @@ def stream_message(conversation: Conversation, content: str):
|
||||
|
||||
user_message = append_user_message(conversation, content)
|
||||
assistant_parts: list[str] = []
|
||||
knowledge_context = build_knowledge_context(content)
|
||||
|
||||
if should_refuse_ungrounded_chat(conversation, content, knowledge_context):
|
||||
reply_content = out_of_scope_reply()
|
||||
assistant_message = append_assistant_message(conversation, reply_content)
|
||||
yield sse_event(
|
||||
"meta",
|
||||
{
|
||||
"conversation_id": conversation.pk,
|
||||
"title": conversation.title or build_conversation_title(content),
|
||||
"user_message_id": user_message.pk,
|
||||
"user_message": user_message.content,
|
||||
},
|
||||
)
|
||||
yield sse_event("chunk", {"delta": reply_content})
|
||||
yield sse_event(
|
||||
"done",
|
||||
{
|
||||
"assistant_message_id": assistant_message.pk,
|
||||
"conversation_id": conversation.pk,
|
||||
"title": conversation.title,
|
||||
},
|
||||
)
|
||||
return
|
||||
|
||||
route = route_message_intent(conversation, content)
|
||||
logger.info(
|
||||
"Stream message started",
|
||||
@@ -395,7 +423,6 @@ def stream_message(conversation: Conversation, content: str):
|
||||
|
||||
stream_failed = False
|
||||
stream_error = ""
|
||||
knowledge_context = build_knowledge_context(content)
|
||||
try:
|
||||
for chunk in stream_reply(conversation, content, knowledge_context=knowledge_context):
|
||||
assistant_parts.append(chunk)
|
||||
@@ -497,6 +524,76 @@ def build_knowledge_context(content: str, *, n_results: int = 5) -> str:
|
||||
return "\n\n".join(lines)
|
||||
|
||||
|
||||
def should_refuse_ungrounded_chat(
|
||||
conversation: Conversation,
|
||||
content: str,
|
||||
knowledge_context: str = "",
|
||||
) -> bool:
|
||||
if (knowledge_context or "").strip():
|
||||
return False
|
||||
if _is_business_related_question(content):
|
||||
return False
|
||||
if _has_active_attachments(conversation):
|
||||
return False
|
||||
return True
|
||||
|
||||
|
||||
def out_of_scope_reply() -> str:
|
||||
return (
|
||||
"没有在当前启用的知识库材料中找到可依据的内容,且这个问题与当前主营业务无关。"
|
||||
"为避免编造,我不能直接回答。请先上传或启用相关知识库材料,或改问体外诊断试剂注册资料审核、"
|
||||
"文件汇总、法规核查、申报填表等业务范围内的问题。"
|
||||
)
|
||||
|
||||
|
||||
def _is_business_related_question(content: str) -> bool:
|
||||
normalized = (content or "").lower()
|
||||
compact = "".join(normalized.split())
|
||||
if not compact:
|
||||
return True
|
||||
business_keywords = [
|
||||
"审核智能体",
|
||||
"体外诊断",
|
||||
"ivd",
|
||||
"nmpa",
|
||||
"cmde",
|
||||
"医疗器械",
|
||||
"注册资料",
|
||||
"注册申报",
|
||||
"注册检验",
|
||||
"注册证",
|
||||
"申报资料",
|
||||
"申报文件",
|
||||
"法规",
|
||||
"核查",
|
||||
"审评",
|
||||
"审核",
|
||||
"整改",
|
||||
"风险",
|
||||
"说明书",
|
||||
"临床",
|
||||
"性能",
|
||||
"安全",
|
||||
"适用范围",
|
||||
"预期用途",
|
||||
"附件",
|
||||
"文件",
|
||||
"压缩包",
|
||||
"目录",
|
||||
"页数",
|
||||
"清单",
|
||||
"汇总",
|
||||
"模板",
|
||||
"填表",
|
||||
"知识库",
|
||||
"检索",
|
||||
"报告",
|
||||
"材料",
|
||||
"资料",
|
||||
]
|
||||
return any(keyword in compact for keyword in business_keywords)
|
||||
|
||||
|
||||
def build_filename_matched_document_context(query: str, *, max_chars: int = 12000) -> str:
|
||||
terms = _knowledge_query_terms(query)
|
||||
if not terms:
|
||||
|
||||
Reference in New Issue
Block a user