""" SubAgent配置测试 测试所有SubAgent配置是否符合DeepAgents框架规范 """ import sys import os # 添加src目录到Python路径 sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..')) import pytest from src.agents.subagents import ( get_subagent_configs, validate_subagent_config, get_validated_subagent_configs ) class TestSubAgentConfigs: """SubAgent配置测试类""" def test_subagent_count(self): """测试SubAgent数量""" configs = get_subagent_configs() assert len(configs) == 6, f"应该有6个SubAgent,实际有{len(configs)}个" def test_required_fields(self): """测试所有必需字段是否存在""" configs = get_subagent_configs() required_fields = ["name", "description", "system_prompt"] for config in configs: for field in required_fields: assert field in config, f"SubAgent {config.get('name', 'unknown')} 缺少必需字段: {field}" def test_name_format(self): """测试name是否使用kebab-case格式""" configs = get_subagent_configs() for config in configs: name = config["name"] # 检查是否只包含小写字母和连字符 assert all(c.islower() or c == '-' for c in name), \ f"SubAgent name必须使用kebab-case格式: {name}" # 不应该以连字符开始或结束 assert not name.startswith('-') and not name.endswith('-'), \ f"SubAgent name不应该以连字符开始或结束: {name}" def test_system_prompt_not_empty(self): """测试system_prompt不为空""" configs = get_subagent_configs() for config in configs: system_prompt = config.get("system_prompt", "") assert system_prompt.strip(), \ f"SubAgent {config['name']} 的system_prompt不能为空" # 检查system_prompt应该相当详细(至少500字符) assert len(system_prompt) > 500, \ f"SubAgent {config['name']} 的system_prompt过短(应该>500字符)" def test_no_prompt_field(self): """测试配置中不应该使用'prompt'字段(常见错误)""" configs = get_subagent_configs() for config in configs: assert "prompt" not in config, \ f"SubAgent {config['name']} 使用了错误的字段'prompt',应该使用'system_prompt'" def test_description_present(self): """测试description字段存在且有意义""" configs = get_subagent_configs() for config in configs: description = config.get("description", "") assert description.strip(), \ f"SubAgent {config['name']} 的description不能为空" # 描述应该简洁(10-100字符) assert 10 <= len(description) <= 200, \ f"SubAgent {config['name']} 的description长度不合适(应该10-200字符)" def test_tools_field_type(self): """测试tools字段类型正确""" configs = get_subagent_configs() for config in configs: if "tools" in config: assert isinstance(config["tools"], list), \ f"SubAgent {config['name']} 的tools字段应该是列表" def test_specific_subagent_names(self): """测试6个SubAgent的具体名称""" configs = get_subagent_configs() expected_names = { "intent-analyzer", "search-orchestrator", "source-validator", "content-analyzer", "confidence-evaluator", "report-generator" } actual_names = {config["name"] for config in configs} assert actual_names == expected_names, \ f"SubAgent名称不匹配。期望: {expected_names}, 实际: {actual_names}" def test_system_prompt_mentions_files(self): """测试system_prompt是否提到虚拟文件系统路径""" configs = get_subagent_configs() # 某些SubAgent应该在system_prompt中提到文件路径 file_related_agents = [ "intent-analyzer", "search-orchestrator", "source-validator", "content-analyzer", "confidence-evaluator", "report-generator" ] for config in configs: if config["name"] in file_related_agents: system_prompt = config["system_prompt"] # 检查是否提到虚拟文件系统(以/开头的路径) assert "/" in system_prompt, \ f"SubAgent {config['name']} 的system_prompt应该提到虚拟文件系统路径" def test_search_orchestrator_has_tools(self): """测试search-orchestrator应该有搜索工具""" configs = get_subagent_configs() search_orchestrator = next( (c for c in configs if c["name"] == "search-orchestrator"), None ) assert search_orchestrator is not None, "未找到search-orchestrator" assert "tools" in search_orchestrator, "search-orchestrator应该有tools字段" assert len(search_orchestrator["tools"]) > 0, \ "search-orchestrator应该至少有一个工具" def test_validate_function(self): """测试validate_subagent_config函数""" # 有效配置 valid_config = { "name": "test-agent", "description": "测试agent", "system_prompt": "这是一个测试prompt" } assert validate_subagent_config(valid_config) == True # 缺少必需字段 invalid_config = { "name": "test-agent", "description": "测试agent" # 缺少system_prompt } with pytest.raises(ValueError, match="缺少必需字段"): validate_subagent_config(invalid_config) # 错误的name格式 invalid_name_config = { "name": "TestAgent", # 应该是kebab-case "description": "测试agent", "system_prompt": "测试" } with pytest.raises(ValueError, match="kebab-case"): validate_subagent_config(invalid_name_config) def test_get_validated_configs(self): """测试get_validated_subagent_configs函数""" configs = get_validated_subagent_configs() assert len(configs) == 6, "应该返回6个经过验证的SubAgent配置" def test_system_prompt_structure(self): """测试system_prompt是否有良好的结构""" configs = get_subagent_configs() for config in configs: system_prompt = config["system_prompt"] # 应该有清晰的任务说明 assert any(keyword in system_prompt for keyword in ["任务", "流程", "步骤"]), \ f"SubAgent {config['name']} 的system_prompt应该包含任务说明" # 应该有输入输出说明 assert any(keyword in system_prompt for keyword in ["输入", "输出", "读取", "写入"]), \ f"SubAgent {config['name']} 的system_prompt应该包含输入输出说明" def test_confidence_evaluator_mentions_formula(self): """测试confidence-evaluator是否提到置信度计算公式""" configs = get_subagent_configs() confidence_evaluator = next( (c for c in configs if c["name"] == "confidence-evaluator"), None ) assert confidence_evaluator is not None system_prompt = confidence_evaluator["system_prompt"] # 应该提到公式和百分比 assert "50%" in system_prompt and "30%" in system_prompt and "20%" in system_prompt, \ "confidence-evaluator应该包含置信度计算公式(50%+30%+20%)" def test_source_validator_mentions_tiers(self): """测试source-validator是否提到Tier分级""" configs = get_subagent_configs() source_validator = next( (c for c in configs if c["name"] == "source-validator"), None ) assert source_validator is not None system_prompt = source_validator["system_prompt"] # 应该提到Tier 1-4 for tier in ["Tier 1", "Tier 2", "Tier 3", "Tier 4"]: assert tier in system_prompt or tier.replace(" ", "") in system_prompt, \ f"source-validator应该包含{tier}分级说明" def print_subagent_summary(): """打印SubAgent配置摘要""" print("\n" + "=" * 60) print("SubAgent配置摘要") print("=" * 60) configs = get_subagent_configs() for i, config in enumerate(configs, 1): print(f"\n{i}. {config['name']}") print(f" 描述: {config['description']}") print(f" System Prompt长度: {len(config['system_prompt'])} 字符") if "tools" in config: print(f" 工具数量: {len(config['tools'])}") else: print(f" 工具数量: 0") print("\n" + "=" * 60) if __name__ == "__main__": # 运行测试 print("运行SubAgent配置测试...\n") # 打印摘要 print_subagent_summary() # 使用pytest运行测试 pytest.main([__file__, "-v", "--tb=short"])