内容
<div align="center">
<!-- 自定义高科技AI标志 -->
<img src="public/logo.png" alt="SAI路线图MCP标志" width="220" height="220" style="border-radius: 20%; filter: drop-shadow(0 0 25px rgba(0, 255, 255, 0.6));" />
<br />
# 🚀 SAI路线图MCP
**一个[MCP(模型上下文协议)](https://modelcontextprotocol.io)服务器,公开我的认证、项目和AI工程路线图作为可调用的工具 — 包括一个完全从头开始构建的语义搜索引擎。**
</div>
---
## 💻 核心技术与动画架构
<div align="center">
<img src="https://img.shields.io/badge/Node.js-43853D?style=for-the-badge&logo=node.js&logoColor=white" />
<img src="https://img.shields.io/badge/Python-3776AB?style=for-the-badge&logo=python&logoColor=white" />
<img src="https://img.shields.io/badge/NumPy-013243?style=for-the-badge&logo=numpy&logoColor=white" />
<img src="https://img.shields.io/badge/Model_Context_Protocol-6B21A8?style=for-the-badge&logo=data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNCAyNCIgZmlsbD0ibm9uZSIgc3Ryb2tlPSJ3aGl0ZSIgc3Ryb2tlLXdpZHRoPSIyIiBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS1saW5lam9pbj0icm91bmQiPjxwYXRoIGQ9Ik00IDEwaDEyIi8+PHBhdGggZD0iTTQgMTRoOSIvPjxwb2x5Z29uIHBvaW50cz0iMyAzIDEwIDEwIDMgMTcgMyAzIi8+PC9zdmc+&logoColor=white" />
<img src="https://img.shields.io/badge/Claude_Desktop-D97757?style=for-the-badge&logo=anthropic&logoColor=white" />
</div>
<br/>
### 🌐 1. 高级生态系统(MCP服务器拓扑)
```mermaid
graph TB
%% 核心样式采用高对比度网络主题
classDef client fill:#0f172a,stroke:#38bdf8,stroke-width:3px,color:#fff,stroke-dasharray: 5 5
classDef server fill:#1e1b4b,stroke:#a855f7,stroke-width:3px,color:#fff
classDef python fill:#064e3b,stroke:#34d399,stroke-width:3px,color:#fff
classDef data fill:#451a03,stroke:#fbbf24,stroke-width:3px,color:#fff
%% 客户端
subgraph Clients [MCP客户端]
ClaudeDesk[Claude桌面应用]:::client
ClaudeCode[Claude代码CLI]:::client
end
%% Node服务器
subgraph NodeServer [Node.js MCP服务器]
StdioTransport((stdio / JSON-RPC 2.0)):::server
ToolRouter{工具路由器}:::server
ProfileTool[get_profile]:::server
CertTool[get_certifications]:::server
ProjTool[get_projects]:::server
RoadmapTool[get_roadmap]:::server
SearchTool[semantic_search]:::server
end
%% Python后端
subgraph PythonEngine [Python机器学习子进程]
QueryParser[LSA查询解析器]:::python
LSAWeights[(lsa_model.npz)]:::data
MergeSet[(双字合并集)]:::data
PortfolioData[(data.json)]:::data
end
%% 流程映射
Clients == "stdio (JSON-RPC)" ==> StdioTransport
StdioTransport --> ToolRouter
ToolRouter --> ProfileTool
ToolRouter --> CertTool
ToolRouter --> ProjTool
ToolRouter --> RoadmapTool
ToolRouter ==> SearchTool
SearchTool -.->|生成子进程| PythonEngine
QueryParser <--> LSAWeights
QueryParser <--> MergeSet
QueryParser <--> PortfolioData
```
### ⚡ 2. 动画交互序列(语义搜索ML管道)
```mermaid
sequenceDiagram
autonumber
participant U as 用户查询(MCP客户端)
participant N as Node.js服务器
participant P as PythonLSA引擎(query.py)
participant C as 语料库构建器
participant M as 截断SVD数学
Note over C, M: 构建时间(npm run train)
C->>C: 从投资组合中提取51个句子
C->>C: 计算PMI和合并双字(min_count=3)
C->>M: 应用显式TF-IDF权重
M->>M: 计算numpy.linalg.svd(截断)
M-->>C: 保存lsa_model.npz和双字
Note over U, P: 运行时执行
U->>N: 调用`semantic_search`
activate N
N->>P: 生成带有查询参数的子进程
activate P
P->>P: 对查询应用相同的双字合并
P->>P: 将查询投影到潜在空间
P->>P: 计算与语料库的余弦相似度
P-->>N: 返回JSON匹配文档
deactivate P
N-->>U: 将格式化结果返回给Claude
deactivate N
```
---
使用官方的[`@modelcontextprotocol/sdk`](https://github.com/modelcontextprotocol/typescript-sdk)(v1.29.0)构建,stdio传输,使用Python/NumPy子进程驱动ML工具。
## 工具
| 工具 | 描述 | 可选输入 |
|---|---|---|
| `get_profile` | 基本个人资料信息 | — |
| `get_certifications` | 认证,可按技能筛选 | `skill: string` |
| `get_projects` | 项目投资组合,可按技术栈筛选 | `tech: string` |
| `get_roadmap` | 2026学习路线图,可按季度筛选 | `quarter: "Q1"–"Q4"` |
| `semantic_search` | 真正的语义检索,非关键词匹配 | `query: string`, `top_n: number` |
## 语义搜索引擎
**管道**(完整实现在[`src/ml/lsa.py`](src/ml/lsa.py)中):
1. **语料库**([`src/ml/corpus.py`](src/ml/corpus.py))— 从认证、详细项目描述和路线图条目中生成的51个自然语言句子。
2. **双字短语检测** — 点互信息(PMI),与word2vec的原始`word2phrase`工具相同的想法。在训练前,将紧密绑定的单词对(`machine_learning`、`medireach_ai`、`artificial_intelligence`)合并为单个标记。
3. **TF-IDF权重** — 项频率×平滑逆文档频率,显式计算。
4. **截断SVD** — `numpy.linalg.svd`,手动截断到前*k*个奇异向量(实际的潜在语义分析步骤 — 而不是`sklearn.fit_transform()`)。
5. **余弦相似度** 在生成的潜在空间中对文档进行排名。
### 两件事情我做错了,改正后
**双字阈值,第一次尝试:** 我的第一个PMI阈值(`min_count=2, threshold=3.0`)合并了**147个双字** — 几乎所有这些都是语法胶水,如`of_the`、`by_google`、`is_a`,而不是真正的短语。 Bug:只有51个句子,原始PMI噪声大,并且停用词不排除形成对。 通过从双字形成中排除停用词并提高到`min_count=3, threshold=15.0`修复 — 现在产生19个双字,每个都是真正的短语(`machine_learning`、`google_cloud`、`vibe_coding`、`iit_bombay`)。
**查询/训练词汇不匹配:** 在添加双字合并后,查询仍然使用普通的单词分割进行标记 — 因此像“machine learning”这样的查询保持为两个标记,而训练词汇只有合并的`machine_learning`。 沉默的不匹配,没有抛出错误,只是静默地降低检索。 通过在模型旁边持久保存学习的合并集,并在查询时应用它(`corpus.py`中的`apply_bigram_merges()`)修复。
### 量化评估 — 精确度@k
大多数小型ML项目显示出几个“看起来像它们有效”的查询。 `src/ml/evaluate.py`定义了10个带有显式相关性判断的手标查询,并报告精确度@k:
```
查询 P@1 P@3 P@5
----------------------------------------------------------------------
python认证 1.00 1.00 0.80
云计算认证 1.00 0.67 0.40
多智能体医疗保健助手 1.00 1.00 1.00
学生教育技术平台 1.00 1.00 1.00
前端动画和设计 0.00 0.00 0.00
黑客马拉松和竞赛经验 0.00 0.00 0.00
SQL和数据库技能 0.00 0.00 0.00
生成式AI和大型语言模型 1.00 0.67 0.40
路线图中深度学习季度 0.00 0.67 0.40
智能IDE开发工具 1.00 1.00 0.60
----------------------------------------------------------------------
平均 0.60 0.60 0.46
```
**三个查询得分为零 — 原因如下**,诊断而不是手波:
- `"前端动画和设计"` → 查询包含“animation”(单数);语料库只说“animations”(复数)。 词汇外,无信号。 这是经典的词袋弱点 — 没有词干提取,没有词形还原。
- `"黑客马拉松和竞赛经验"` → 相同问题:“competition”和“experience”在语料库中根本不出现(它说的是“Hackathon”,不是“competition”)。
- `"SQL和数据库技能"` → 这里没有OOV单词,但真正的排名失败:`idf("skills") == idf("database")`(两者均为3.833),因为两者恰好出现在一个文档中 — IDF无法区分“罕见且主题特定”和“罕见且巧合”。 单词“skills”然后将排名拉向错误(但技能丰富)的文档。
这些是小型语料库词袋检索的真正、被很好理解的局限性,而不是实现错误 — 精确记录它们比误导性地清理演示更有用。
### 用更大的语料库重温word2vec
我将语料库扩大了3倍(17 → 51个句子),部分是为了测试基于单词的skip-gram(仍在[`src/ml/word2vec.py`](src/ml/word2vec.py)中,Mikolov等,2013,负采样,完整的从头开始的NumPy训练)是否会变得可行。 诚实的结果:**否**。
```
'cloud' -> [('computing', 0.746), ('oac', 0.728), ('analytics', 0.698), ('infrastructure', 0.645)] ← 连贯
'python' -> [('generative_ai', 0.684), ('workflow', 0.599), ('sql', 0.595)] ← 噪音
'agents' -> [('good', 0.687), ('intensive', 0.681), ('5', 0.636)] ← 噪音
```
“cloud”产生了一个真正合理的邻域;“python”和“agents”仍然没有。 51个句子比17个更接近可行,但word2vec实际上需要至少几千个句子。 LSA仍然是这个语料库大小的正确选择 — 通过实际重新运行实验确认,而不是仅仅假设。
## 安装
```bash
git clone https://github.com/saichintamani/sai-roadmap-mcp.git
cd sai-roadmap-mcp
npm install
pip3 install -r requirements.txt --break-system-packages
npm run train # 构建语料库,检测双字,训练LSA模型
npm run evaluate # 运行上述精确度@k评估
```
## 独立运行
```bash
npm start
```
通过JSON-RPC 2.0在stdio上通信。 准备消息发送到stderr;stdout保留用于协议消息。
## 连接到Claude Desktop
```json
{
"mcpServers": {
"sai-roadmap": {
"command": "node",
"args": ["/absolute/path/to/sai-roadmap-mcp/src/index.js"]
}
}
}
```
## 连接到Claude Code
```bash
claude mcp add sai-roadmap -- node /absolute/path/to/sai-roadmap-mcp/src/index.js
```
## 仓库结构
```
sai-roadmap-mcp/
├── src/
│ ├── index.js # MCP服务器:5种工具,stdio传输
│ ├── data.json # 结构化投资组合数据
│ └── ml/
│ ├── corpus.py # 句子生成 + PMI双字检测
│ ├── word2vec.py # 跳过语法 + 负采样(保留,如此处所述不可行)
│ ├── lsa.py # TF-IDF + 截断SVD — 实际使用的模型
│ ├── train.py # 训练并保存模型 + 合并集
│ ├── query.py # CLI查询接口,由index.js调用
│ ├── evaluate.py # 精确度@k评估与手动标记的查询
│ └── lsa_model.npz # 预训练权重
├── requirements.txt
├── package.json
└── README.md
```
## 为什么存在
大多数学生AI投资组合展示了*使用*LLM API。 本项目展示了三种不同的内容:对**MCP协议层**的理解,该层用于生产AI工具;一个从头开始构建的**经典NLP/ML检索系统**;以及更重要的是,**衡量它,发现故障模式并精确记录它们**的工程学科,而不是挑选看起来不错的例子。
## 许可证
MIT