import pytest from review_agent.models import KnowledgeBaseDocument from review_agent.services import build_knowledge_context, send_message, stream_message pytestmark = pytest.mark.django_db def test_build_knowledge_context_ignores_irrelevant_rag_chunks(monkeypatch): monkeypatch.setattr( "review_agent.services.search_knowledge_base", lambda query, n_results=5: { "query": query, "results": [ { "source": "附件 4 体外诊断试剂注册申报资料要求及说明.doc", "text": "预期用途应明确产品用于检测的分析物和功能。", "score": 7.636, "metadata": {"source_type": "regulatory_document"}, } ], "error_message": "", }, ) context = build_knowledge_context("孙之烨是谁") assert context == "" def test_build_knowledge_context_uses_full_document_when_name_matches(settings, tmp_path, monkeypatch, django_user_model): settings.MEDIA_ROOT = tmp_path user = django_user_model.objects.create_user(username="owner", password="pass") document_path = tmp_path / "resume.txt" document_path.write_text( "孙之烨,负责审核智能体项目。\n完整经历:曾组织技术分享并带队参加竞赛。", encoding="utf-8", ) KnowledgeBaseDocument.objects.create( user=user, display_name="孙之烨简历", original_name="孙之烨-260510.txt", storage_path=str(document_path), file_size=document_path.stat().st_size, status=KnowledgeBaseDocument.Status.ACTIVE, is_active=True, indexed_chunk_count=2, ) monkeypatch.setattr( "review_agent.services.search_knowledge_base", lambda query, n_results=5: {"query": query, "results": [], "error_message": ""}, ) context = build_knowledge_context("孙之烨是谁") assert "全文材料" in context assert "来源:用户知识库/孙之烨-260510.txt" in context assert "完整经历:曾组织技术分享并带队参加竞赛" in context def test_send_message_refuses_out_of_scope_answer_without_knowledge_context(monkeypatch, django_user_model): from review_agent.models import Conversation user = django_user_model.objects.create_user(username="owner", password="pass") conversation = Conversation.objects.create(user=user, title="会话") monkeypatch.setattr( "review_agent.services.search_knowledge_base", lambda query, n_results=5: {"query": query, "results": [], "error_message": ""}, ) monkeypatch.setattr( "review_agent.services.generate_reply", lambda *args, **kwargs: pytest.fail("out-of-scope answer without knowledge context must not call LLM"), ) _, assistant_message = send_message(conversation, "孙之烨是谁") assert "没有在当前启用的知识库材料中找到" in assistant_message.content assert "与当前主营业务无关" in assistant_message.content def test_stream_message_refuses_out_of_scope_answer_without_knowledge_context(monkeypatch, django_user_model): from review_agent.models import Conversation user = django_user_model.objects.create_user(username="owner", password="pass") conversation = Conversation.objects.create(user=user, title="会话") monkeypatch.setattr( "review_agent.services.search_knowledge_base", lambda query, n_results=5: {"query": query, "results": [], "error_message": ""}, ) monkeypatch.setattr( "review_agent.services.stream_reply", lambda *args, **kwargs: pytest.fail("out-of-scope answer without knowledge context must not call streaming LLM"), ) monkeypatch.setattr( "review_agent.services.generate_reply", lambda *args, **kwargs: pytest.fail("out-of-scope answer without knowledge context must not call fallback LLM"), ) frames = list(stream_message(conversation, "给我一份红烧肉菜谱")) assert any("没有在当前启用的知识库材料中找到" in frame for frame in frames) assert any("与当前主营业务无关" in frame for frame in frames) assert any("done" in frame for frame in frames) def test_business_question_without_knowledge_context_can_use_llm(monkeypatch, django_user_model): from review_agent.models import Conversation user = django_user_model.objects.create_user(username="owner", password="pass") conversation = Conversation.objects.create(user=user, title="会话") monkeypatch.setattr( "review_agent.services.search_knowledge_base", lambda query, n_results=5: {"query": query, "results": [], "error_message": ""}, ) monkeypatch.setattr( "review_agent.services.generate_reply", lambda *args, **kwargs: "注册检验报告通常用于证明产品性能符合要求。", ) _, assistant_message = send_message(conversation, "注册检验报告有什么作用") assert "注册检验报告" in assistant_message.content