本次提交包含完整的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>
165 lines
4.8 KiB
Python
165 lines
4.8 KiB
Python
#!/usr/bin/env python3
|
||
"""
|
||
LLM集成配置助手
|
||
"""
|
||
import os
|
||
import shutil
|
||
import yaml
|
||
|
||
def main():
|
||
print("🤖 AI SOC分析平台 LLM集成配置助手")
|
||
print("=" * 50)
|
||
|
||
# 创建.env文件
|
||
if not os.path.exists(".env"):
|
||
if os.path.exists(".env.example"):
|
||
shutil.copy(".env.example", ".env")
|
||
print("✅ 已创建 .env 文件")
|
||
else:
|
||
print("❌ .env.example 文件不存在")
|
||
return
|
||
else:
|
||
print("ℹ️ .env 文件已存在")
|
||
|
||
# 显示配置选项
|
||
print("\n🎯 选择你的LLM提供商:")
|
||
print("1. Claude 4 (推荐,需API密钥)")
|
||
print("2. 本地模型 (免费,需安装Ollama)")
|
||
print("3. OpenAI (需API密钥)")
|
||
print("4. 暂不配置 (使用模板生成)")
|
||
|
||
try:
|
||
choice = input("\n请输入选项 (1-4): ").strip()
|
||
|
||
if choice == "1":
|
||
configure_claude()
|
||
elif choice == "2":
|
||
configure_local()
|
||
elif choice == "3":
|
||
configure_openai()
|
||
elif choice == "4":
|
||
print("✅ 将使用模板生成,你可以稍后配置LLM")
|
||
else:
|
||
print("❌ 无效选项")
|
||
return
|
||
|
||
print(f"\n🎉 配置完成!请重启后端服务生效")
|
||
print("重启命令: python3 run_backend.py")
|
||
|
||
except KeyboardInterrupt:
|
||
print("\n\n👋 配置已取消")
|
||
|
||
def configure_claude():
|
||
print("\n🎨 配置Claude 4")
|
||
print("请访问 https://console.anthropic.com/ 获取API密钥")
|
||
|
||
api_key = input("请输入Claude API Key (sk-ant-...): ").strip()
|
||
if not api_key.startswith("sk-ant-"):
|
||
print("⚠️ API密钥格式可能不正确")
|
||
|
||
# 更新.env文件
|
||
update_env_file("CLAUDE_API_KEY", api_key)
|
||
|
||
# 更新llm.yaml配置
|
||
update_llm_config("claude")
|
||
|
||
print("✅ Claude 4 配置完成")
|
||
|
||
def configure_local():
|
||
print("\n🏠 配置本地模型")
|
||
print("请确保已安装Ollama: https://ollama.ai/")
|
||
|
||
print("\n推荐模型:")
|
||
print("- qwen2.5:7b (中文优秀, ~4.4GB)")
|
||
print("- qwen2.5:14b (性能更强, ~8.2GB)")
|
||
print("- llama3.1:8b (英文强, ~4.7GB)")
|
||
|
||
model = input("请输入模型名称 (默认: qwen2.5:7b): ").strip()
|
||
if not model:
|
||
model = "qwen2.5:7b"
|
||
|
||
port = input("请输入Ollama端口 (默认: 11434): ").strip()
|
||
if not port:
|
||
port = "11434"
|
||
|
||
# 更新llm.yaml配置
|
||
update_llm_config("local", model, f"http://localhost:{port}/v1")
|
||
|
||
print(f"✅ 本地模型配置完成")
|
||
print(f"请确保运行: ollama pull {model}")
|
||
print("然后启动服务: ollama serve")
|
||
|
||
def configure_openai():
|
||
print("\n🌐 配置OpenAI")
|
||
|
||
api_key = input("请输入OpenAI API Key (sk-proj-...): ").strip()
|
||
if not api_key.startswith("sk-"):
|
||
print("⚠️ API密钥格式可能不正确")
|
||
|
||
model = input("请输入模型名称 (默认: gpt-3.5-turbo): ").strip()
|
||
if not model:
|
||
model = "gpt-3.5-turbo"
|
||
|
||
# 更新.env文件
|
||
update_env_file("OPENAI_API_KEY", api_key)
|
||
|
||
# 更新llm.yaml配置
|
||
update_llm_config("openai", model)
|
||
|
||
print("✅ OpenAI 配置完成")
|
||
|
||
def update_env_file(key, value):
|
||
"""更新.env文件"""
|
||
try:
|
||
# 读取现有内容
|
||
lines = []
|
||
if os.path.exists(".env"):
|
||
with open(".env", "r") as f:
|
||
lines = f.readlines()
|
||
|
||
# 更新或添加键值
|
||
found = False
|
||
for i, line in enumerate(lines):
|
||
if line.startswith(f"{key}="):
|
||
lines[i] = f"{key}={value}\n"
|
||
found = True
|
||
break
|
||
|
||
if not found:
|
||
lines.append(f"{key}={value}\n")
|
||
|
||
# 写回文件
|
||
with open(".env", "w") as f:
|
||
f.writelines(lines)
|
||
|
||
except Exception as e:
|
||
print(f"❌ 更新.env文件失败: {e}")
|
||
|
||
def update_llm_config(provider, model=None, api_base=None):
|
||
"""更新LLM配置文件"""
|
||
try:
|
||
config_path = "configs/llm.yaml"
|
||
|
||
# 读取现有配置
|
||
with open(config_path, "r", encoding="utf-8") as f:
|
||
config = yaml.safe_load(f)
|
||
|
||
# 更新提供商
|
||
config["provider"] = provider
|
||
|
||
# 更新具体配置
|
||
if model and provider in config.get("providers", {}):
|
||
config["providers"][provider]["model"] = model
|
||
|
||
if api_base and provider in config.get("providers", {}):
|
||
config["providers"][provider]["api_base"] = api_base
|
||
|
||
# 写回文件
|
||
with open(config_path, "w", encoding="utf-8") as f:
|
||
yaml.dump(config, f, default_flow_style=False, allow_unicode=True)
|
||
|
||
except Exception as e:
|
||
print(f"❌ 更新配置文件失败: {e}")
|
||
|
||
if __name__ == "__main__":
|
||
main() |