sebdallais-git/PharmaCyberLLM
GitHub: sebdallais-git/PharmaCyberLLM
面向制药行业的本地化 AI 网络威胁情报系统,融合自愈式 RAG、自动化新闻采集与 N8N 编排,在完全离线环境下持续进化并提供可观测的情报问答服务。
Stars: 0 | Forks: 0
# PharmaCyberLLM
### 制药行业 AI 驱动的网络威胁情报
**本地 LLM** | **自愈式 RAG** | **监控仪表板** | **用户反馈** | **N8N 编排** | **零云依赖**
[](https://typescriptlang.org)
[](https://ollama.com)
[](https://www.trychroma.com)
[](https://n8n.io)
[](https://www.chartjs.org)
[](https://expressjs.com)
[](https://nodejs.org)
*一个完全离线、具有实时监控仪表板、用户反馈循环和自动化知识缺口解决能力的自愈式 RAG 聊天机器人——全由 N8N 编排。专为无法将敏感查询发送到云端的网络安全专业人士打造。*
## 为什么开发这个项目
PharmaCyberLLM **完全在你的机器上运行**。无需 API 密钥。无云端依赖。数据绝不离开你的笔记本电脑。
它结合了:
- 一个通过 Ollama 运行的**本地 LLM**,用于对话智能
- 一个包含 36+ 精选制药/网络安全文档的**双向量数据库**(嵌入式索引 + ChromaDB)
- **LLM 驱动的重排序**,用于更高精度的 RAG 检索
- 一个**自动化新闻代理**,每 24 小时从 Google News 抓取 90+ 个主题
- 每次查询都进行**实时网络搜索**增强
- 一个具备闭环解决验证功能的**自愈式知识缺口检测器**
- 一个带有 Chart.js 可视化的**实时监控仪表板**
- 一个追踪响应质量并识别薄弱环节的**用户反馈系统**
- 完整的 **N8N 工作流编排**,用于自动化缺口研究和知识摄入
结果是:一个始终保持最新、完全私有、自我进化的制药网络威胁专家——且具备完全的可观测性。
## 工作原理
```
User asks: "What ransomware attacks hit pharma in 2024?"
|
v
+-------------------------------------------------------------+
| PharmaCyberLLM Pipeline |
| |
| +----------+ +----------+ +----------+ |
| | Knowledge | | Web | | Ollama | |
| | Search | | Search | | LLM | |
| | (Hybrid) | | (Google) | | (Local) | |
| +-----+----+ +-----+----+ +-----+----+ |
| | | | |
| +------+-------+------+------+ |
| | | |
| Merged context Gap Detector |
| | | |
| v v |
| Streamed Low confidence? |
| response +---> N8N Webhook |
| with sources | --> SearXNG search |
| + response_id | --> Ollama extraction |
| +---> Auto-ingest to KB |
| +---> Resolution verification |
+-------------------------------------------------------------+
| |
v v
"In 2024, Change Healthcare Dashboard tracks:
suffered a $2.87B breach..." - Confidence rate
(citing: cyber-pharma-attacks.md) - Response latency
- User ratings
User can rate response (1-5) - Gap resolution
```
## 监控仪表板
位于 `/dashboard` 的实时深色主题仪表板,每 60 秒自动刷新。
**顶部行** — 4 个带有趋势箭头关键指标卡片:
- 今日问题数 / 置信率 / 平均用户评分 / 知识库大小
**图表** — 30 天时间序列:
- 问题数与置信度(双轴柱状图 + 折线图)
- 用户评分(带 3.0 基线参考)
**缺口情报**:
- 最近的缺口表格,带有颜色编码的状态徽章
- 热门缺口主题横向条形图
**系统健康**:
- 知识来源甜甜圈图
- 服务健康检查(Ollama, ChromaDB, SearXNG, SQLite)及延迟
所有指标缓存 30 秒,并由索引 SQL 查询提供支持。
## 自愈式知识闭环
核心功能。PharmaCyberLLM **知道自己何时不知道**——然后自我修复——并**验证修复是否有效**。
```
+------------------+ +-------------------+ +------------------+
| User Question | --> | Ollama Response | --> | Gap Detector |
| | | + response_id | | (Confidence?) |
+------------------+ +-------------------+ +--------+---------+
|
Confident? | Not confident?
(done) | (trigger)
v
+--------+---------+
| N8N Webhook |
| (with gap_id) |
+--------+---------+
|
+-----------------------------+----------------------------+
| | |
v v v
+---------+--------+ +-------------+---------+ +-------------+---------+
| Ollama: Generate | | SearXNG: Search Web | | Ollama: Extract |
| 3 search queries | | (3 queries x 3 results)| | relevant knowledge |
+---------+--------+ +-------------+---------+ +-------------+---------+
| | |
+-----------------------------+----------------------------+
|
v
+--------+---------+
| Store in KB |
| (ingest-text) |
+--------+---------+
|
v
+--------+---------+
| Resolution Check |
| Re-ask question |
| via full RAG |
+--------+---------+
|
+-------------+-------------+
| |
v v
Confident now? Still not?
status=resolved status=unresolved
log new response retry_count++
```
缺口检测器对每个主题使用 2 小时的冷却时间,在 SQLite 中记录每次检测,v2 N8N 工作流会自动验证解决情况。
## 用户反馈系统
每次聊天响应都包含一个 `response_id`。用户可以对响应进行 1-5 评分,并添加可选评论。
反馈系统追踪:
- 每个响应使用了哪些 RAG 块
- 响应是否包含 RAG 上下文,还是纯 LLM 生成
- 按主题、时间段以及 RAG 与非 RAG 分类的评分细目
- 低评分响应(<=2)被标记为待改进项
```
POST /api/feedback
{ "response_id": "uuid", "rating": 4, "comment": "helpful" }
GET /api/feedback/stats
-> avg ratings (7d, 30d, RAG vs non-RAG), best/worst topics
GET /api/feedback/low-rated
-> all responses rated <=2 with chunk IDs used
GET /api/feedback/weekly-digest
-> 7-day summary: questions, gaps, resolution rate, improvement priorities
```
## 系统架构
```
graph TB
subgraph CLIENT["Browser"]
CHAT["Chat Interface"]
KB["Knowledge Base Modal"]
NA["News Agent Modal"]
DASH["Monitoring DashboardChart.js - Auto-refresh"] end subgraph SERVER["Express Server -- Port 3000"] API_CHAT["/api/chat"] API_KB["/api/knowledge"] API_AGENT["/api/agent"] API_FB["/api/feedback"] API_DASH["/api/dashboard"] API_HEALTH["/api/health"] end subgraph INTELLIGENCE["Intelligence Layer"] RAG["RAG Engine
Dual Vector + LLM Re-ranking"] WEB["Web Search
Google News RSS"] AGENT["News Agent
90+ topics - 24h cycle"] PARSE["File Parser
PDF - DOCX - PPTX - CSV - MD"] GAP["Gap Detector
Confidence + Resolution Check"] RCACHE["Response Cache
In-memory - 1h TTL"] end subgraph ORCHESTRATION["N8N Workflow v2"] N8N_WH["Webhook Trigger"] N8N_SEARCH["SearXNG Search"] N8N_EXTRACT["Ollama Extraction"] N8N_STORE["Auto-Ingest to KB"] N8N_RESOLVE["Resolution Check"] end subgraph LLM["Local LLM -- Ollama"] MODEL["gemma2:9b / llama3.2
Chat + embeddings + re-ranking"] end subgraph STORE["Data Layer"] EMBEDDED["Embedded Index
1000+ chunks - .index.json"] CHROMA["ChromaDB
Persistent vector DB"] DOCS["36+ Curated Documents"] GAPDB["gap_log.db
Gaps + feedback + request log"] RAW["data/raw_documents/
Original content for re-indexing"] end CHAT -->|SSE Stream| API_CHAT DASH --> API_DASH DASH --> API_HEALTH KB --> API_KB NA --> API_AGENT CHAT -->|Rate| API_FB API_CHAT --> RAG API_CHAT --> WEB API_CHAT --> GAP API_CHAT --> RCACHE API_KB --> PARSE API_AGENT --> AGENT API_FB --> RCACHE API_DASH --> GAPDB GAP -->|Webhook| N8N_WH N8N_WH --> N8N_SEARCH N8N_SEARCH --> N8N_EXTRACT N8N_EXTRACT --> N8N_STORE N8N_STORE --> N8N_RESOLVE N8N_RESOLVE -->|check-resolution| API_KB N8N_STORE -->|Ingest| EMBEDDED GAP --> GAPDB RAG --> EMBEDDED RAG --> CHROMA AGENT --> WEB AGENT -->|Ingest| EMBEDDED PARSE -->|Embed & Store| EMBEDDED API_KB -->|Save raw| RAW RAG -->|Context| MODEL WEB -->|Context| MODEL N8N_EXTRACT -->|Process| MODEL MODEL -->|Tokens| API_CHAT EMBEDDED --- DOCS style CLIENT fill:#030712,stroke:#38bdf8,color:#e5e7eb style SERVER fill:#111827,stroke:#38bdf8,color:#e5e7eb style INTELLIGENCE fill:#1e1b4b,stroke:#a78bfa,color:#e5e7eb style ORCHESTRATION fill:#4a1d6b,stroke:#d946ef,color:#e5e7eb style LLM fill:#064e3b,stroke:#22d3ee,color:#e5e7eb style STORE fill:#7f1d1d,stroke:#f43f5e,color:#e5e7eb ``` ## LLM 重排序 Python RAG 流水线使用 **Ollama 作为相关性判断器**来对检索到的块进行重排序: ``` Query: "Dell cyber recovery ransomware" | v Retrieve top 15 from ChromaDB | v Send all 15 to Ollama (temp=0.1): "Score each chunk 0-10 for relevance..." | v Parse JSON scores, filter score >= 5 | v Take top 5 (or fallback top 3) | v Prefix with section context: "From section 'Ransomware Defense' of vendor-dell.md: ..." | v Final RAG prompt to LLM ``` 重排序结果记录到 `data/logs/reranking.log` 以供分析。 ## 知识库 PharmaCyberLLM 开箱即包含 **36+ 份精选情报文档**和 **1000+ 个嵌入式块**: ``` mindmap root((PharmaCyberLLM
Knowledge)) Cyber Threats Attack history by year Attack types & vectors Systems compromised Threat landscape Market value impact Costs & remediation IT/OT threats 2025 Pharma Industry Business fundamentals Drug market forecasts Phase 3 pipeline 2025-26 Science & pharmacology Regulation FDA/EMA Top 20 by revenue Top 20 by market cap Top 20 by reputation Manufacturing plants Vendor Intelligence Dell Cyber Recovery Snowflake SIEM Databricks Security ServiceNow SecOps Pure Storage SafeMode NetApp ONTAP HPE Zerto VAST Data SAP Security NVIDIA AI Infra WEKA Data Platform CrowdStrike / SentinelOne Splunk / Microsoft Sentinel Auto-Updated 90+ RSS topics daily N8N gap-fill on demand SearXNG web research Resolution-verified ``` ### 精选文档 | 类别 | 文档数 | 覆盖范围 | |----------|-----------|----------| | **网络攻击** | 8 个文件 | 2017-2025 年所有主要制药企业入侵事件、攻击向量、受损系统、财务影响、成本与补救措施 | | **制药业务** | 9 个文件 | 药品市场预测、3 期管线、前 20 强排名(营收、市值、声誉)、制造工厂、法规 | | **供应商情报** | 13 个文件 | Dell, Snowflake, Databricks, ServiceNow, Pure Storage, NetApp, HPE, VAST, SAP, NVIDIA, WEKA, CrowdStrike, Splunk | | **PDF 报告** | 2 个文件 | Everpure AI 制药挑战简报 | | **自动新闻** | 每日 | 涵盖业务、科学、网络和供应商类别的 90+ 个搜索主题 | | **缺口填补** | 按需 | 通过 N8N 自动研究,并在标记为完成前验证解决情况 | ## N8N 工作流 v2 — 闭环缺口解决 一个可导入的 N8N 工作流,用于填补知识缺口**并验证修复是否有效**。 ``` Webhook POST --> Ollama (3 queries) --> SearXNG (web search) --> Fetch pages --> Ollama (extraction) --> Filter relevance --> Store in KB --> Summary --> Resolution Check --> Log result ``` ### 工作流节点(共 15 个) | # | 节点 | 描述 | |---|------|-------------| | 1 | Knowledge Gap Webhook | 接收来自 gap-detector 的包含 `gap_id` 的 POST 请求 | | 2 | Generate Search Queries | Ollama 生成 3 个搜索查询 | | 3 | Parse Search Queries | 将查询提取为单独的项目 | | 4 | Search SearXNG | 每个查询进行网络搜索 | | 5 | Deduplicate Results | 按 URL 去重,最多 9 个结果 | | 6 | Fetch Page Content | 抓取页面(出错时跳过) | | 7 | Truncate & Clean | 去除 HTML,限制为 8000 字符 | | 8 | Extract Knowledge | Ollama 提取相关事实 | | 9 | Filter Relevant Only | 移除 NOT_RELEVANT 响应 | | 10 | Store in Knowledge Base | POST 到 `/api/knowledge/ingest-text` | | 11 | Summary & Log | 汇总统计信息 | | 12 | **Check Gap Resolution** | 调用 `/api/knowledge/gaps/check-resolution` | | 13 | **Resolution Result Log** | 记录已解决/未解决状态 | | 14 | SearXNG Error Handler | 优雅的错误处理 | | 15 | Ollama Query Error Handler | 回退到 search_topic | 导入方式:**N8N > Workflows > Import** > `n8n/knowledge_gap_workflow_v2.json` ## 智能分块 Python vectordb 使用智能文档分块策略: | 特性 | 详情 | |---------|--------| | 拆分策略 | 优先按段落边界,其次按句子 | | 拆分阈值 | 超过 600 个 token 的段落按句子拆分 | | 合并阈值 | 少于 100 个 token 的段落与下一段合并 | | 目标大小 | 每个块 300-500 个 token | | 章节检测 | Markdown 标题、全大写标题、编号章节 | | 元数据 | `section_header`, `chunk_index`, `source_url`, `ingested_at`, `document_title` | | 重建索引 | `POST /api/knowledge/reindex` 从 `data/raw_documents/` 重建 | ## 快速开始 ``` # 1. 安装 Ollama brew install ollama ollama pull gemma2:9b # 2. 克隆并安装 git clone https://github.com/sebdallais-git/PharmaCyberLLM.git cd PharmaCyberLLM npm install # 3. 启动 Ollama ollama serve & # 4. 启动 npm run dev # --> 聊天: http://localhost:3000 # --> 仪表盘: http://localhost:3000/dashboard # --> 健康检查: http://localhost:3000/api/health ``` 无需 API 密钥。无需 `.env` 文件。无需云账户。 ### 可选:启用自愈模式 + 完整技术栈 ``` # 5. 设置 N8N webhook URL export N8N_WEBHOOK_URL="http://localhost:5678/webhook/knowledge-gap" # 6. 将 v2 workflow 导入 N8N # N8N > Workflows > Import > n8n/knowledge_gap_workflow_v2.json # 7. 确保 SearXNG (端口 8888) 和 ChromaDB (端口 8100) 正在运行 # 8. 重启 npm run dev ``` ## 技术栈 | 层级 | 技术 | 用途 | |-------|-----------|---------| | **运行时** | Node.js 22 + TypeScript 5.6 | 类型安全服务器 | | **服务器** | Express 4.21 | REST API + 静态文件服务 | | **LLM** | Ollama (gemma2:9b) | 推理 + 嵌入 + 重排序 | | **向量数据库** | ChromaDB | 持久化向量存储 | | **仪表板** | Chart.js + 原生 HTML/CSS/JS | 实时监控 | | **编排** | N8N | 带解决检查的工作流自动化 | | **网络搜索** | SearXNG + Google News RSS | 隐私优先的网络搜索 | | **缺口检测** | 自定义 + SQLite | 置信度 + 冷却 + 解决验证 | | **反馈** | SQLite + 内存缓存 | 用户评分 + 响应追踪 | | **重排序** | Ollama (Python) | LLM 相关性评分 (0-10) | | **搜索** | 混合向量 + 关键词 | 双存储 RAG 检索 | | **解析** | pdf-parse, mammoth, JSZip | 多格式文档摄入 | | **流式传输** | Server-Sent Events | 逐 token 聊天输出 | | **Python** | 工具集 | 智能分块、重排序、向量数据库 | ## 项目结构 ``` PharmaCyberLLM/ +-- src/ | +-- server.ts # Express entry + news agent + DB init | +-- api/ | | +-- chat.ts # SSE streaming chat + timing + response_id | | +-- knowledge.ts # KB CRUD + gaps + resolution check + reindex | | +-- agent.ts # News agent status + manual trigger | | +-- feedback.ts # User feedback + stats + weekly digest | | +-- dashboard.ts # Dashboard metrics + health check | +-- services/ | +-- ollama.ts # Ollama chat, streaming, embeddings | +-- knowledge-store.ts # In-memory vector store + hybrid search | +-- chromadb-store.ts # ChromaDB client + delete/recreate | +-- gap-detector.ts # Confidence check + resolution + N8N webhook | +-- feedback-store.ts # Feedback table + stats + weekly digest | +-- response-cache.ts # In-memory response metadata (1h TTL) | +-- request-log.ts # Request logging + dashboard metrics + cache | +-- news-agent.ts # 90-topic Google News scraper | +-- web-search.ts # Real-time Google News RSS search | +-- file-parser.ts # PDF, DOCX, PPTX, CSV, JSON, MD parser +-- dashboard/ | +-- index.html # Monitoring dashboard (Chart.js, dark theme) +-- public/ | +-- index.html # Chat UI | +-- styles.css # Dark theme | +-- app.js # Frontend logic +-- knowledge/ # 36+ curated pharma/cyber documents +-- n8n/ | +-- knowledge_gap_workflow.json # N8N workflow v1 | +-- knowledge_gap_workflow_v2.json # N8N workflow v2 (with resolution check) | +-- README.md # N8N setup guide +-- python/ | +-- utils/ # Smart chunking, re-ranking, vector DB | +-- tests/ # Integration + vector DB tests +-- data/ | +-- chromadb/ # ChromaDB persistent storage | +-- raw_documents/ # Original content for re-indexing | +-- logs/ # Re-ranking logs | +-- gap_log.db # SQLite (gaps + feedback + request log) +-- package.json +-- tsconfig.json +-- .gitignore ``` ## API 参考 ### 聊天 | 端点 | 方法 | 描述 | |----------|--------|-------------| | `/api/chat` | POST | 带有 RAG 上下文 + `response_id` 的 SSE 流式响应 | | `/api/chat/models` | GET | 列出可用的 Ollama 模型 | ### 知识库 | 端点 | 方法 | 描述 | |----------|--------|-------------| | `/api/knowledge/stats` | GET | 知识库统计信息 | | `/api/knowledge/search` | POST | 搜索知识库 | | `/api/knowledge/ingest-text` | POST | 摄入纯文本(保存至 raw_documents/) | | `/api/knowledge/upload` | POST | 上传并摄入文件 | | `/api/knowledge/add` | POST | 添加到 ChromaDB(URL 或文本) | | `/api/knowledge/status` | GET | ChromaDB 状态 | | `/api/knowledge/reindex` | POST | 重新分块并重新嵌入所有原始文档 | | `/api/knowledge/gaps` | GET | 最近的缺口检测 | | `/api/knowledge/gaps/stats` | GET | 缺口分析 | | `/api/knowledge/gaps/check-resolution` | POST | 重新检查缺口是否已解决 | ### 反馈 | 端点 | 方法 | 描述 | |----------|--------|-------------| | `/api/feedback` | POST | 提交评分 (1-5) 及 `response_id` | | `/api/feedback/stats` | GET | 评分分析(RAG 与非 RAG,趋势) | | `/api/feedback/low-rated` | GET | 评分 <=2 的响应(改进候选项) | | `/api/feedback/weekly-digest` | GET | 7 天摘要及改进优先级 | ### 仪表板与健康检查 | 端点 | 方法 | 描述 | |----------|--------|-------------| | `/api/dashboard/metrics` | GET | 所有仪表板指标(缓存 30 秒) | | `/api/health` | GET | 服务健康状况(Ollama, ChromaDB, SearXNG, SQLite) | | `/dashboard` | GET | 监控仪表板 UI | ### 代理 | 端点 | 方法 | 描述 | |----------|--------|-------------| | `/api/agent/status` | GET | 新闻代理上次运行时间及主题 | | `/api/agent/run` | POST | 手动触发新闻代理 | ## 环境变量 全部为可选项——开箱即用,零配置。 | 变量 | 默认值 | 描述 | |----------|---------|-------------| | `PORT` | `3000` | 服务器端口 | | `HOST` | `0.0.0.0` | 绑定地址 | | `OLLAMA_URL` | `http://localhost:11434` | Ollama API 端点 | | `CHROMADB_URL` | `http://localhost:8100` | ChromaDB 服务器端点 | | `N8N_WEBHOOK_URL` | *(无)* | 用于缺口自动填补的 N8N Webhook | ## 与 PharmaCyber 的集成 PharmaCyberLLM 设计为 [PharmaCyber](https://github.com/sebdallais-git/CyberDemo) 事件响应仪表板的配套工具。 ``` +-------------------------------+ +--------------------------+ | PharmaCyber Dashboard | | PharmaCyberLLM | | (Port 8888) |---->| (Port 3000) | | | | | | Snowflake - ServiceNow - Dell | | Chat + Dashboard | | Live incident response demo | | + Self-healing RAG | +-------------------------------+ +----------+---------------+ | +-----------v-----------+ | N8N (Port 5678) | | Auto gap-fill | | Resolution verify | +-----------------------+ ```
**100% 本地。零云依赖。自愈式。可观测。始终保持最新。**
*Ollama LLM* · *双 RAG + 重排序* · *ChDB* · *监控仪表板* · *用户反馈* · *N8N 编排* · *36+ 份情报文档*
专为高度重视数据主权的制药网络安全专业人士打造。
专为高度重视数据主权的制药网络安全专业人士打造。
标签:AI风险缓解, ChromaDB, DLL 劫持, Express, GNU通用公共许可证, JSONLines, LLM评估, MITM代理, N8N, Node.js, Ollama, RAG, TypeScript, 仪表盘, 企业安全, 信息搜集, 医疗安全, 医药行业, 向量数据库, 向量检索, 大语言模型, 威胁情报, 安全插件, 实时处理, 工作流自动化, 开发者工具, 数据隐私, 新闻聚合, 智能问答, 本地部署, 检索增强生成, 离线AI, 网络安全, 网络资产管理, 自动化代理, 自动化攻击, 自愈系统, 逆向工具, 隐私保护, 零信任