Files
brunoandClaude 842fa8dbe5 feat: 完整AI SOC分析师平台 - LLM集成与前后端优化
本次提交包含完整的AI SOC(Security Operations Center)分析师平台,支持本地大模型和Claude API集成,实现端到端的安全威胁分析。

## 🚀 主要功能

### 后端架构 (FastAPI)
- **多源数据接入**: 支持JSON/CSV格式安全告警数据上传
- **智能预处理**: 基于YAML配置的字段映射和实体提取
- **图分析引擎**: NetworkX驱动的攻击链图构建和分析
- **评分系统**: 实体和子图的多维度风险评分算法
- **LLM集成**: 支持多提供商(Claude、OpenAI、本地模型)的智能报告生成
- **API接口**: 完整的RESTful API (Swagger文档: /docs)

### 前端界面 (Vue 3 + TypeScript)
- **拖拽上传**: 支持拖拽上传和实时预览
- **管道分析**: 可视化的数据处理管道状态
- **智能报告**: 动态生成的威胁分析报告和可视化
- **响应式设计**: 适配桌面和移动端的现代UI

### LLM智能分析
- **多模型支持**: qwen3(8B/32B)、deepseek-r1(70B)、Claude 4等
- **超时优化**: 分层超时配置(120s-600s)适配不同模型规模
- **内容清理**: 自动过滤模型思考过程,输出专业分析报告
- **中文优化**: 针对中文安全分析场景的prompt工程

## 🛠️ 技术栈

**后端**: FastAPI + SQLAlchemy + NetworkX + 多LLM提供商
**前端**: Vue 3 + TypeScript + Naive UI + Tailwind CSS + Vite
**数据处理**: YAML配置 + JSONPath表达式
**部署**: Docker支持 + 环境变量配置

## 🐛 修复的关键问题

1. **LLM超时问题**: 实现前后端分层超时配置,支持大模型长时间推理
2. **报告格式化**: 修复Markdown渲染和换行符显示问题
3. **数据映射**: 统一前后端字段命名和数据结构映射
4. **时间格式**: 修复时间戳解析和中文本地化显示
5. **思考标签清理**: 自动过滤qwen模型的<think>标签

## 📊 测试数据

包含完整的多阶段APT攻击场景测试数据:
- 钓鱼邮件 → 恶意软件执行 → C2通信
- 云凭证窃取 → 资源探测 → 横向渗透
- 后门用户创建 → 权限提升 → 容器控制

## 🔧 开发工具

- **模型切换**: switch_model.py 支持快速切换本地LLM模型
- **超时测试**: test_llm_timeout.py 验证不同模型性能
- **依赖安装**: install_llm_deps.py 自动安装LLM依赖

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-09-06 06:56:09 +08:00

119 lines
4.0 KiB
Python

#!/usr/bin/env python3
"""
测试不同LLM提供商的超时设置
"""
import requests
import time
import sys
def test_llm_generation(model_name):
"""测试指定模型的生成速度和超时"""
print(f"\n🧪 测试模型: {model_name}")
print("=" * 50)
# 切换模型
print(f"1. 切换到 {model_name}...")
try:
import subprocess
result = subprocess.run([
sys.executable, "switch_model.py", model_name
], capture_output=True, text=True)
if result.returncode == 0:
print("✅ 模型切换成功")
else:
print(f"❌ 模型切换失败: {result.stderr}")
return
except Exception as e:
print(f"❌ 切换失败: {e}")
return
# 等待服务重启
print("2. 等待服务重启...")
time.sleep(5)
# 检查LLM状态
print("3. 检查LLM状态...")
try:
response = requests.get("http://localhost:8000/api/debug/llm-status", timeout=10)
if response.status_code == 200:
data = response.json()
current_model = data.get("current_model", "unknown")
llm_available = data.get("llm_available", False)
print(f" 当前模型: {current_model}")
print(f" LLM可用: {llm_available}")
else:
print("❌ 无法获取LLM状态")
return
except requests.RequestException as e:
print(f"❌ 连接失败: {e}")
return
# 测试生成速度
print("4. 测试报告生成...")
start_time = time.time()
try:
response = requests.post(
"http://localhost:8000/api/reports/generate?use_llm=true",
timeout=120 # 2分钟测试超时
)
end_time = time.time()
if response.status_code == 200:
data = response.json()
generated = data.get("generated", 0)
duration = end_time - start_time
print(f"✅ 生成成功!")
print(f" 生成报告数: {generated}")
print(f" 耗时: {duration:.1f} 秒")
if generated > 0 and "report_ids" in data:
# 获取报告内容样本
report_id = data["report_ids"][0]
report_response = requests.get(f"http://localhost:8000/api/reports/{report_id}")
if report_response.status_code == 200:
report_data = report_response.json()
summary_length = len(report_data.get("summary", ""))
print(f" 报告长度: {summary_length} 字符")
else:
print(f"❌ 生成失败: {response.status_code}")
print(f" 错误信息: {response.text}")
except requests.Timeout:
end_time = time.time()
duration = end_time - start_time
print(f"⏰ 请求超时 ({duration:.1f}秒)")
except requests.RequestException as e:
print(f"❌ 请求失败: {e}")
def main():
print("🚀 LLM超时测试工具")
print("测试不同模型的生成速度和超时配置")
models_to_test = [
("local", "qwen3:latest - 8B模型"),
("local_powerful", "qwen3:32b - 32B模型"),
]
# 可选添加大模型测试 (需要更多资源)
add_large_model = input("\n是否测试70B大模型? (y/N): ").lower().strip()
if add_large_model == 'y':
models_to_test.append(("local_deepseek", "deepseek-r1:70b - 70B模型"))
for model_key, description in models_to_test:
test_llm_generation(model_key)
# 询问是否继续
if model_key != models_to_test[-1][0]: # 不是最后一个
continue_test = input(f"\n继续测试下一个模型? (Y/n): ").lower().strip()
if continue_test == 'n':
break
print(f"\n🏁 测试完成!")
print("\n建议的超时设置:")
print("- 8B模型 (qwen3:latest): 120秒")
print("- 32B模型 (qwen3:32b): 300秒")
print("- 70B模型 (deepseek-r1:70b): 600秒")
if __name__ == "__main__":
main()