Sunglasses开源框架:AI代理输入扫描与安全防护实战指南 在AI应用快速发展的今天如何确保AI代理接收到的输入数据是安全、合规且结构化的成为许多开发者面临的现实挑战。特别是在处理用户上传文件、解析外部数据源或构建自动化工作流时输入数据的质量和安全性直接影响到整个系统的稳定性。本文要介绍的Sunglasses正是为解决这一问题而生的开源输入扫描工具。Sunglasses是一个专为AI代理设计的轻量级输入扫描框架它能自动检测、验证和清理输入数据帮助开发者构建更可靠的AI应用。无论你是刚接触AI应用开发的新手还是正在优化现有系统的资深工程师本文都将带你完整掌握Sunglasses的核心概念、安装配置、实战应用以及生产环境最佳实践。1. Sunglasses核心概念与设计理念1.1 什么是输入扫描为什么AI代理需要它输入扫描Input Scanning指的是在数据进入系统处理流程前对数据进行自动化检查、验证和预处理的过程。与传统的数据验证不同输入扫描更注重于数据的安全性、结构完整性和内容质量。对于AI代理来说输入扫描尤为重要原因在于安全防护AI代理往往需要处理来自多种渠道的输入数据这些数据可能包含恶意代码、注入攻击或不当内容数据质量保证AI模型的输出质量高度依赖输入数据的质量低质量输入会导致不可预测的结果系统稳定性未经处理的异常输入可能导致AI代理崩溃或产生错误行为合规性要求在许多应用场景中需要对输入数据进行内容审核和合规检查1.2 Sunglasses的架构设计Sunglasses采用模块化设计核心架构包含三个主要组件扫描引擎Scanning Engine负责协调整个扫描流程管理扫描规则和处理器规则库Rule Library包含各种预定义的扫描规则如格式验证、内容检测、安全检查等处理器Processors对扫描结果进行处理包括数据清理、格式转换、异常处理等这种设计使得Sunglasses具有高度的可扩展性开发者可以根据具体需求定制扫描规则和处理逻辑。1.3 主要特性与优势Sunglasses提供了丰富的特性使其成为AI代理输入处理的理想选择多格式支持支持文本、图像、音频、JSON、XML等多种数据格式实时扫描能够在毫秒级别完成输入数据的扫描和处理可定制规则提供灵活的规则配置接口支持自定义扫描逻辑轻量级设计核心库依赖少资源占用低适合各种部署环境开源生态拥有活跃的社区支持持续更新和改进2. 环境准备与安装配置2.1 系统要求与依赖环境在开始使用Sunglasses之前需要确保你的开发环境满足以下要求Python版本3.8或更高版本Sunglasses主要基于Python开发操作系统支持Windows、Linux和macOS内存要求至少512MB可用内存具体取决于扫描数据量网络连接用于下载依赖包和更新规则库2.2 安装SunglassesSunglasses可以通过pip包管理器直接安装这是最推荐的安装方式# 安装稳定版 pip install sunglasses-ai # 或者安装开发版包含最新特性 pip install sunglasses-ai --pre # 验证安装 python -c import sunglasses; print(sunglasses.__version__)如果你需要从源码安装可以按照以下步骤操作# 克隆仓库 git clone https://github.com/sunglasses-ai/sunglasses.git cd sunglasses # 安装依赖 pip install -r requirements.txt # 安装开发版本 pip install -e .2.3 基础配置安装完成后需要进行基础配置。创建一个配置文件config.yaml# config.yaml sunglasses: # 扫描模式fast快速、standard标准、deep深度 scan_mode: standard # 最大文件大小单位MB max_file_size: 10 # 默认规则集 default_rules: - security.malicious_content - quality.format_validation - compliance.content_screening # 日志配置 logging: level: INFO file: sunglasses.log # 性能配置 performance: timeout: 30 # 超时时间秒 max_workers: 4 # 最大工作线程数2.4 验证安装结果创建一个简单的测试脚本来验证安装是否成功# test_installation.py import sunglasses from sunglasses.scanner import InputScanner def test_basic_functionality(): 测试基础功能 # 创建扫描器实例 scanner InputScanner() # 测试数据 test_input 这是一段正常的文本输入 # 执行扫描 result scanner.scan(test_input) print(f扫描状态: {result.status}) print(f扫描结果: {result.clean_data}) print(f检测到的问题: {result.issues}) return result.is_clean if __name__ __main__: success test_basic_functionality() print(f测试结果: {成功 if success else 失败})运行测试脚本确认一切正常python test_installation.py3. 核心功能与API详解3.1 扫描器初始化与配置Sunglasses的核心是InputScanner类它提供了丰富的配置选项from sunglasses.scanner import InputScanner from sunglasses.config import ScannerConfig # 方式1使用默认配置 scanner1 InputScanner() # 方式2自定义配置 config ScannerConfig( scan_modedeep, # 深度扫描模式 timeout60, # 超时时间60秒 max_file_size50, # 最大文件大小50MB enabled_rules[ # 启用特定规则 security.malicious_content, quality.format_validation, compliance.basic_screening ] ) scanner2 InputScanner(configconfig) # 方式3从配置文件加载 scanner3 InputScanner.from_config_file(config.yaml)3.2 基本扫描操作Sunglasses支持多种数据类型的扫描以下是一些常见用法# 文本数据扫描 text_result scanner.scan(用户输入的文本内容) # 文件扫描 with open(document.txt, r) as f: file_result scanner.scan_file(f) # JSON数据扫描 json_data {name: 张三, age: 25} json_result scanner.scan_json(json_data) # 批量扫描 inputs [输入1, 输入2, 输入3] batch_results scanner.scan_batch(inputs)3.3 扫描结果处理扫描结果包含丰富的信息可以帮助你做出相应的处理决策def process_scan_result(result): 处理扫描结果的示例函数 if result.status clean: # 数据安全直接使用 return result.clean_data elif result.status cleaned: # 数据经过清理可以使用清理后的版本 print(f数据已清理原问题: {result.issues}) return result.clean_data elif result.status rejected: # 数据存在严重问题应拒绝使用 print(f数据被拒绝原因: {result.issues}) return None else: # 扫描过程中出现错误 print(f扫描错误: {result.error_message}) return None # 使用示例 scan_result scanner.scan(需要检查的输入) processed_data process_scan_result(scan_result)3.4 自定义规则开发Sunglasses允许你创建自定义扫描规则满足特定业务需求from sunglasses.rules import BaseRule class CustomContentRule(BaseRule): 自定义内容检查规则 def __init__(self): super().__init__( rule_idcustom.content_check, severitymedium, # 严重程度low, medium, high, critical description检查特定业务内容 ) def check(self, data, context): 执行检查逻辑 issues [] # 示例检查是否包含敏感关键词 sensitive_keywords [违规词1, 违规词2] for keyword in sensitive_keywords: if keyword in data: issues.append(f包含敏感词: {keyword}) # 示例检查内容长度 if len(data) 1000: issues.append(内容长度超过限制) return issues def clean(self, data, issues): 执行清理逻辑 cleaned_data data # 移除敏感词 sensitive_keywords [违规词1, 违规词2] for keyword in sensitive_keywords: cleaned_data cleaned_data.replace(keyword, ***) # 截断过长内容 if len(cleaned_data) 1000: cleaned_data cleaned_data[:1000] ... return cleaned_data # 注册并使用自定义规则 scanner.add_rule(CustomContentRule())4. 完整实战案例构建安全的AI聊天代理4.1 项目需求分析假设我们要构建一个AI聊天代理需要处理用户的各种输入包括文本、图片和文件。主要安全需求包括防止恶意代码和注入攻击过滤不当内容验证文件格式和大小保护用户隐私信息4.2 项目结构设计ai_chat_agent/ ├── main.py # 主程序入口 ├── config/ │ ├── __init__.py │ └── scanner_config.yaml # 扫描器配置 ├── modules/ │ ├── __init__.py │ ├── scanner.py # 扫描模块 │ └── ai_agent.py # AI代理模块 ├── rules/ │ ├── __init__.py │ └── custom_rules.py # 自定义规则 └── tests/ └── test_scanner.py # 测试文件4.3 配置扫描器创建详细的扫描器配置文件# config/scanner_config.yaml sunglasses: scan_mode: deep max_file_size: 20 timeout: 45 # 规则配置 rules: security: - malicious_content - injection_attempts - file_safety quality: - format_validation - content_quality compliance: - content_screening - privacy_protection custom: - chat_safety # 自定义聊天安全规则 # 处理器配置 processors: - html_sanitizer - profanity_filter - privacy_scrubber logging: level: DEBUG file: logs/scanner.log4.4 实现扫描模块# modules/scanner.py import logging from typing import Any, Dict, Optional from sunglasses.scanner import InputScanner from sunglasses.config import ScannerConfig import yaml import os class ChatInputScanner: 聊天输入扫描器 def __init__(self, config_path: str config/scanner_config.yaml): self.config self._load_config(config_path) self.scanner self._initialize_scanner() self.logger self._setup_logging() def _load_config(self, config_path: str) - Dict[str, Any]: 加载配置文件 if not os.path.exists(config_path): raise FileNotFoundError(f配置文件不存在: {config_path}) with open(config_path, r, encodingutf-8) as f: return yaml.safe_load(f) def _initialize_scanner(self) - InputScanner: 初始化扫描器 scanner_config ScannerConfig( scan_modeself.config[sunglasses][scan_mode], timeoutself.config[sunglasses][timeout], max_file_sizeself.config[sunglasses][max_file_size] ) scanner InputScanner(configscanner_config) # 添加自定义规则 self._add_custom_rules(scanner) return scanner def _add_custom_rules(self, scanner: InputScanner): 添加自定义规则 from rules.custom_rules import ChatSafetyRule, PrivacyProtectionRule scanner.add_rule(ChatSafetyRule()) scanner.add_rule(PrivacyProtectionRule()) def _setup_logging(self) - logging.Logger: 设置日志 logger logging.getLogger(ChatScanner) if self.config[sunglasses][logging][level] DEBUG: logger.setLevel(logging.DEBUG) else: logger.setLevel(logging.INFO) return logger def scan_text(self, text: str) - Dict[str, Any]: 扫描文本输入 self.logger.info(f开始扫描文本长度: {len(text)}) try: result self.scanner.scan(text) response { status: result.status, clean_data: result.clean_data, issues: result.issues, is_safe: result.status in [clean, cleaned], scan_time: result.scan_time } self.logger.info(f文本扫描完成状态: {result.status}) return response except Exception as e: self.logger.error(f文本扫描错误: {str(e)}) return { status: error, error_message: str(e), is_safe: False } def scan_file(self, file_path: str) - Dict[str, Any]: 扫描文件输入 self.logger.info(f开始扫描文件: {file_path}) if not os.path.exists(file_path): return { status: error, error_message: 文件不存在, is_safe: False } try: with open(file_path, rb) as f: result self.scanner.scan_file(f) response { status: result.status, clean_data: result.clean_data, issues: result.issues, is_safe: result.status in [clean, cleaned], file_type: result.file_type, file_size: result.file_size } self.logger.info(f文件扫描完成状态: {result.status}) return response except Exception as e: self.logger.error(f文件扫描错误: {str(e)}) return { status: error, error_message: str(e), is_safe: False }4.5 实现AI代理集成# modules/ai_agent.py import logging from typing import Dict, Any, Optional from .scanner import ChatInputScanner class AIChatAgent: 集成Sunglasses的AI聊天代理 def __init__(self, scanner: ChatInputScanner): self.scanner scanner self.logger logging.getLogger(AIChatAgent) def process_message(self, user_input: Any, input_type: str text) - Dict[str, Any]: 处理用户输入消息 # 步骤1输入扫描 scan_result self._scan_input(user_input, input_type) if not scan_result[is_safe]: return self._create_rejection_response(scan_result) # 步骤2AI处理使用清理后的数据 ai_response self._call_ai_model(scan_result[clean_data]) # 步骤3输出扫描可选确保AI响应也安全 output_scan self.scanner.scan_text(ai_response) return { success: True, user_input_scan: scan_result, ai_response: output_scan[clean_data], response_scan: output_scan } def _scan_input(self, user_input: Any, input_type: str) - Dict[str, Any]: 根据输入类型执行扫描 if input_type text: return self.scanner.scan_text(str(user_input)) elif input_type file: return self.scanner.scan_file(user_input) else: return { status: error, error_message: f不支持的输入类型: {input_type}, is_safe: False } def _call_ai_model(self, clean_input: str) - str: 调用AI模型生成响应模拟实现 # 这里是实际的AI模型调用逻辑 # 示例中使用简单的响应生成 responses { 你好: 你好我是AI助手有什么可以帮你的吗, 天气: 我可以帮你查询天气信息请告诉我你所在的城市。, 帮助: 我可以回答问题、提供信息、协助处理各种任务。 } return responses.get(clean_input, 我理解你的问题了让我来帮你解决。) def _create_rejection_response(self, scan_result: Dict[str, Any]) - Dict[str, Any]: 创建拒绝响应 rejection_messages { rejected: 输入内容不符合安全要求请重新输入。, error: 输入处理时发生错误请稍后重试。 } return { success: False, rejection_reason: scan_result.get(issues, [未知原因]), message: rejection_messages.get(scan_result[status], 输入无法处理。), user_input_scan: scan_result }4.6 主程序实现# main.py import logging from modules.scanner import ChatInputScanner from modules.ai_agent import AIChatAgent def setup_logging(): 设置日志配置 logging.basicConfig( levellogging.INFO, format%(asctime)s - %(name)s - %(levelname)s - %(message)s, handlers[ logging.FileHandler(chat_agent.log), logging.StreamHandler() ] ) def main(): 主程序 setup_logging() logger logging.getLogger(Main) try: # 初始化扫描器 logger.info(初始化输入扫描器...) scanner ChatInputScanner() # 初始化AI代理 logger.info(初始化AI聊天代理...) agent AIChatAgent(scanner) # 测试示例 test_inputs [ (你好今天天气怎么样, text), (这是一个正常的对话, text), # 测试文件输入需要实际文件路径 # (test_document.txt, file) ] for user_input, input_type in test_inputs: logger.info(f处理输入: {user_input}) result agent.process_message(user_input, input_type) if result[success]: print(f用户: {user_input}) print(fAI: {result[ai_response]}) print(---) else: print(f输入被拒绝: {result[message]}) print(f原因: {result[rejection_reason]}) print(---) except Exception as e: logger.error(f程序运行错误: {str(e)}) raise if __name__ __main__: main()4.7 运行与测试创建测试脚本验证功能# tests/test_scanner.py import unittest import os import tempfile from modules.scanner import ChatInputScanner class TestChatScanner(unittest.TestCase): 测试聊天扫描器 def setUp(self): 测试前准备 self.scanner ChatInputScanner() def test_safe_text_scan(self): 测试安全文本扫描 safe_text 这是一个正常的聊天消息 result self.scanner.scan_text(safe_text) self.assertTrue(result[is_safe]) self.assertEqual(result[status], clean) def test_malicious_text_scan(self): 测试恶意文本扫描 # 注意这里使用示例恶意内容实际应根据规则库调整 malicious_text 尝试注入恶意代码 result self.scanner.scan_text(malicious_text) # 根据实际规则可能被标记为需要清理或拒绝 self.assertIn(result[status], [cleaned, rejected]) def test_file_scan(self): 测试文件扫描 # 创建临时测试文件 with tempfile.NamedTemporaryFile(modew, deleteFalse) as f: f.write(正常的文件内容) temp_file f.name try: result self.scanner.scan_file(temp_file) self.assertTrue(result[is_safe]) finally: os.unlink(temp_file) if __name__ __main__: unittest.main()运行测试python -m pytest tests/test_scanner.py -v5. 高级特性与定制化开发5.1 性能优化配置对于高并发场景需要进行性能优化# performance_optimized_scanner.py from sunglasses.scanner import InputScanner from sunglasses.config import ScannerConfig import asyncio class AsyncInputScanner: 异步输入扫描器 def __init__(self): self.config ScannerConfig( scan_modefast, max_workers8, # 增加工作线程数 timeout10, cache_size1000 # 启用结果缓存 ) self.scanner InputScanner(configself.config) async def scan_async(self, data): 异步扫描 loop asyncio.get_event_loop() return await loop.run_in_executor(None, self.scanner.scan, data) async def scan_batch_async(self, data_list): 异步批量扫描 tasks [self.scan_async(data) for data in data_list] return await asyncio.gather(*tasks) # 使用示例 async def main(): scanner AsyncInputScanner() inputs [输入1, 输入2, 输入3] results await scanner.scan_batch_async(inputs) for result in results: print(f状态: {result.status}) # asyncio.run(main())5.2 规则优先级与冲突解决当多个规则可能产生冲突时需要合理设置优先级from sunglasses.rules import RulePriority class PriorityManagedScanner: 优先级管理的扫描器 def __init__(self): self.scanner InputScanner() self._setup_rule_priorities() def _setup_rule_priorities(self): 设置规则优先级 # 安全规则最高优先级 self.scanner.set_rule_priority(security.malicious_content, RulePriority.HIGHEST) self.scanner.set_rule_priority(security.injection_attempts, RulePriority.HIGHEST) # 质量规则中等优先级 self.scanner.set_rule_priority(quality.format_validation, RulePriority.MEDIUM) # 合规性规则较低优先级 self.scanner.set_rule_priority(compliance.content_screening, RulePriority.LOW)5.3 监控与指标收集在生产环境中监控扫描器的性能十分重要# monitoring.py import time from dataclasses import dataclass from typing import Dict, List from sunglasses.scanner import InputScanner dataclass class ScannerMetrics: 扫描器指标 total_scans: int 0 successful_scans: int 0 failed_scans: int 0 average_scan_time: float 0.0 rule_hit_counts: Dict[str, int] None def __post_init__(self): if self.rule_hit_counts is None: self.rule_hit_counts {} class MonitoredScanner: 带监控的扫描器 def __init__(self): self.scanner InputScanner() self.metrics ScannerMetrics() self.scan_times: List[float] [] def scan_with_metrics(self, data): 带指标收集的扫描 start_time time.time() try: result self.scanner.scan(data) scan_time time.time() - start_time # 更新指标 self.metrics.total_scans 1 self.metrics.successful_scans 1 self.scan_times.append(scan_time) self.metrics.average_scan_time sum(self.scan_times) / len(self.scan_times) # 更新规则命中统计 for issue in result.issues: rule_id issue.get(rule_id, unknown) self.metrics.rule_hit_counts[rule_id] self.metrics.rule_hit_counts.get(rule_id, 0) 1 return result except Exception as e: self.metrics.total_scans 1 self.metrics.failed_scans 1 raise e def get_metrics_report(self) - Dict[str, any]: 获取指标报告 return { total_scans: self.metrics.total_scans, success_rate: self.metrics.successful_scans / self.metrics.total_scans if self.metrics.total_scans 0 else 0, average_scan_time: self.metrics.average_scan_time, top_triggered_rules: sorted( self.metrics.rule_hit_counts.items(), keylambda x: x[1], reverseTrue )[:5] }6. 常见问题与解决方案6.1 安装与配置问题问题1安装时出现依赖冲突错误Cannot uninstall package-x. It is a distutils installed project...解决方案# 使用虚拟环境避免系统包冲突 python -m venv sunglasses_env source sunglasses_env/bin/activate # Linux/macOS # 或 sunglasses_env\Scripts\activate # Windows pip install sunglasses-ai问题2配置文件加载失败解决方案确保配置文件格式正确使用YAML验证工具检查import yaml def validate_config(config_path): try: with open(config_path, r) as f: yaml.safe_load(f) print(配置文件格式正确) except yaml.YAMLError as e: print(f配置文件格式错误: {e})6.2 性能相关问题问题3扫描速度过慢解决方案调整扫描模式为fast增加超时时间限制使用异步扫描启用结果缓存config ScannerConfig( scan_modefast, timeout30, cache_size500 # 缓存500个扫描结果 )问题4内存占用过高解决方案限制最大文件大小使用流式处理大文件定期清理缓存config ScannerConfig( max_file_size5, # 限制为5MB cache_ttl300 # 缓存5分钟后过期 )6.3 规则与误报问题问题5误报率过高解决方案调整规则敏感度使用白名单机制自定义规则逻辑class AdjustedSafetyRule(BaseRule): def check(self, data, context): issues [] # 降低敏感度只有当连续出现时才报错 suspicious_patterns [pattern1, pattern2] count sum(1 for pattern in suspicious_patterns if pattern in data) if count 2: # 只有超过2个模式才报错 issues.append(检测到多个可疑模式) return issues问题6漏报问题解决方案使用深度扫描模式组合多种检测方法定期更新规则库config ScannerConfig( scan_modedeep, enabled_rules[ security.malicious_content, security.heuristic_analysis, # 启发式分析 security.behavior_analysis # 行为分析 ] )6.4 集成与API问题问题7与现有系统集成困难解决方案使用适配器模式class LegacySystemAdapter: 传统系统适配器 def __init__(self, scanner): self.scanner scanner def process_legacy_input(self, legacy_data): 处理传统系统数据格式 # 转换数据格式 modern_data self._convert_format(legacy_data) # 执行扫描 result self.scanner.scan(modern_data) # 转换回传统格式 return self._convert_back(result) def _convert_format(self, legacy_data): # 实现格式转换逻辑 pass def _convert_back(self, result): # 实现反向转换逻辑 pass7. 生产环境最佳实践7.1 安全部署建议在生产环境中部署Sunglasses时需要遵循以下安全实践1. 网络隔离# 生产环境网络配置 network: internal_only: true # 仅内部网络访问 ssl_required: true # 强制SSL加密 rate_limiting: # 速率限制 requests_per_minute: 10002. 访问控制# 身份验证中间件 class AuthenticationMiddleware: def __init__(self, scanner, allowed_tokens): self.scanner scanner self.allowed_tokens set(allowed_tokens) def scan_with_auth(self, data, auth_token): if auth_token not in self.allowed_tokens: raise PermissionError(未授权的访问) return self.scanner.scan(data)7.2 性能优化策略1. 水平扩展# 使用负载均衡的多实例部署 class ScannerCluster: def __init__(self, scanner_instances): self.instances scanner_instances self.current_index 0 def scan(self, data): # 简单的轮询负载均衡 instance self.instances[self.current_index] self.current_index (self.current_index 1) % len(self.instances) return instance.scan(data)2. 缓存策略from functools import lru_cache import hashlib class CachedScanner: def __init__(self, scanner, max_size1000): self.scanner scanner self._scan lru_cache(maxsizemax_size)(self._scan_impl) def _scan_impl(self, data_hash, data): # 实际扫描逻辑 return self.scanner.scan(data) def scan(self, data): data_hash hashlib.md5(data.encode()).hexdigest() return self._scan(data_hash, data)7.3 监控与告警建立完整的监控体系# monitoring_system.py import logging from datetime import datetime import statistics class ProductionMonitor: def __init__(self): self.metrics { scan_requests: 0, errors: 0, scan_times: [] } self.alert_thresholds { error_rate: 0.05, # 5%错误率 avg_scan_time: 2.0, # 平均扫描时间2秒 concurrent_scans: 100 # 最大并发扫描数 } def record_scan(self, successTrue, scan_timeNone): self.metrics[scan_requests] 1 if not success: self.metrics[errors] 1 if scan_time: self.metrics[scan_times].append(scan_time) self._check_alerts() def _check_alerts(self): error_rate self.metrics[errors] / self.metrics[scan_requests] if error_rate self.alert_thresholds[error_rate]: self._trigger_alert(f错误率过高: {error_rate:.2%}) if self.metrics[scan_times]: avg_time statistics.mean(self.metrics[scan_times][-100:]) # 最近100次 if avg_time self.alert_thresholds[avg_scan_time]: self._trigger_alert(f平均扫描时间过长: {avg_time:.2f}秒) def _trigger_alert(self, message): logging.error(f告警: {message} - 时间: {datetime.now()}) # 这里可以集成邮件、短信等告警方式7.4 灾难恢复与备份1. 配置备份import json from datetime import datetime import os class ConfigBackup: def __init__(self, backup_dirbackups): self.backup_dir backup_dir os.makedirs(backup_dir, exist_okTrue) def backup_config(self, config): timestamp datetime.now().strftime(%Y%m%d_%H%M%S) backup_file os.path.join(self.backup_dir, fconfig_{timestamp}.json) with open(backup_file, w) as f: json.dump(config, f, indent2) # 保留最近10个备份 self._cleanup_old_backups() def _cleanup_old_backups(self): backups sorted([f for f in os.listdir(self.backup_dir) if f.startswith(config_)]) if len(backups) 10: for old_backup in backups[:-10]: os.remove(os.path.join(self.backup_dir, old_backup))2. 规则库版本管理class RuleVersionManager: def __init__(self): self.versions {} def save_version(self, rules, version_name): self.versions[version_name] { timestamp: datetime.now(), rules: rules.copy() } def restore_version(self, version_name): if version_name in self.versions: return self.versions[version_name][rules] else: raise ValueError(f版本不存在: {version_name})通过本文的完整介绍你应该已经掌握了Sunglasses开源输入扫描框架的核心概念、安装配置、实战应用以及生产环境的最佳实践。在实际项目中建议先从基础功能开始逐步根据具体需求进行定制化开发。记得定期关注Sunglasses的官方更新及时获取最新的安全规则和性能优化。