内容
<p align="center">
<img src="assets/dude-hero-02.png" width="760" alt="一位穿着彭德尔顿羊绒衫的悠闲男子,在一台充满知识图谱数据的发光平板电脑上做白俄罗斯人式的喷溅。">
</p>
# 嵌入顿
> _"有时候会有一个图——我不会说是一个英雄,因为什么是英雄?——但有时候会有一个图,恰到好处地出现在它的时间和地点。它正好融入其中。那就是嵌入顿,在你的机器上。"_
一个共享的 **ServiceNow 技术知识图谱**,安装在您的机器上并保持更新。数据始终如一。
这里的一切都源自一个真实来源: **[github.com/ServiceNow/ServiceNowDocs](https://github.com/ServiceNow/ServiceNowDocs)** — ServiceNow 自己的平台文档,由 ServiceNow 在 Apache License 2.0 下发布。嵌入顿不会取代这些文档,也不知道它们不知道的事情。它读取它们,提取散文中隐藏的实体和关系,并将结果作为您可以查询和遍历的内容提供给您。图谱中的每个三元组都带有它来源的 `source_document` 和生成它的 `source_quote`,因此任何声明都可以追溯到 ServiceNow 页面上的真实句子。
它分为两个部分,它们保持同步:
- **Qdrant** — 一个矢量集合(`technology`)用于文档的语义搜索。
- **ArangoDB** — 一个实体/关系图谱(`entities_v2` / `relationships_v2`)用于结构化遍历:什么依赖于什么,什么功能扩展,整个联系在一起的图谱。
您获得的是数据,而不是服务。嵌入顿将图谱作为 **基准** 加上 GitHub Releases 上的每日 **差异** 发布。您的副本会恢复基准一次,然后只拉取更改 — 幂等,并且可以在 _差异_ 粒度下恢复 — 中断的基准下载会从零重新启动(它流式传输到磁盘,因此不会占用您的 RAM)。非常容易。就像悠闲一样,为所有数据罪人提供便利。
一个捆绑的 MCP 服务器(`mcp/`)允许 Claude 直接查询图谱 — 矢量搜索和图谱遍历,由 Claude 推理,无需依赖任何外部模型或 API。加载到 Claude 中,它显示为 **嵌入顿**。
---
## 为什么值得一试(图谱 vs. 搜索 vs. 文档)
> _"你不是错的,沃尔特。你只是未被索引。"_ — 正确地找到答案的位置并不等同于获取答案。
ServiceNow 文档是权威的和公开的。那么,为什么还要构建其他东西?
因为有三种不同的方式可以提出问题,而且它们会以不同的方式失败。
**直接阅读文档** 可以为您提供真相,一次一个页面。当您知道需要哪个页面时,它是完美的。当答案不在任何单个页面上时,它是非常残酷的 — 在大约 48,000 个 markdown 文件中,大多数有趣的答案都不是。您最终成为连接引擎:打开十二个标签页,在脑海中保持关系,希望您没有错过第十三个。
**矢量搜索(普通 RAG)** 找到与您的问题 _相似_ 的段落。询问“什么是 MID 服务器”时,它会准确找到,因为某些段落确实说明了什么是 MID 服务器。询问“如果我们废除此集成,其他什么会中断?”时,它会为您提供与 _废除_ 和 _中断_ 相关的五个段落 — 这不是答案,因为 **没有段落包含答案**。答案仅存在于段落 _之间_ 的关系中,而相似性搜索无法遍历它从未表示的关系。它检索;它不连接。
**知识图谱** 事先完成了连接。提取读取每个页面一次,并将关系写入为类型化的边 — _此功能扩展了那个功能,此组件依赖于该服务,此插件需要另一个插件_。现在,多跳问题是一个两行的遍历,而不是一个下午,机器跟随链条而不是猜测它。
| 您的提问 | 文档 | 矢量搜索 | 图谱 |
| ------------------------------------------------------ | ------------------------------ | ---------------------------------- | ------------------------ |
| “什么是 MID 服务器?” | ✅ 如果您找到页面 | ✅ 命中 | ✅ 但多余 |
| “哪些组件依赖于 MID 服务器?” | ⚠️ 分散在多个页面上 | ⚠️ 返回 _提及_ 的页面 | ✅ 一跳,详尽 |
| “如果我们废除 X,什么会在下游两个步骤中中断?” | ❌ 您是连接引擎 | ❌ 没有单个段落说明此事 | ✅ 两跳 |
| “总结此功能实际上如何表现” | ✅ 文本就是重点 | ✅ 检索文本 | ⚠️ 边丢失细微差别 |
**所以两者都使用 — 这就是重点。** 嵌入顿提供矢量 _和_ 图谱,MCP 服务器将两者同时呈现给 Claude。Claude 遍历图谱以查找 _哪些_ 东西是连接的,然后拉取实际的段落来解释 _如何_。结构来自边,细微差别来自文本。两者单独都无法带您到达那里。
诚实的警告:提取是派生数据,而派生数据是有损的。边是句子的压缩,而压缩会丢弃东西。这就是为什么每个三元组都保留其 `source_document` 和 `source_quote` — 当图谱表示两个事物相关时,您可以阅读句子并自己判断。图谱告诉您在哪里查找。文档仍然是真相。
---
## 数字说明
> _"老杜德的脑袋里有很多线索。”_
**`baseline-2026-07b`** 基线(截至 **2026-07-09**)的快照。图谱随着每日差异的增加而增长,因此全新安装的图谱将比这稍大。
| 指标 | 数量 |
| ------------------------------------------- | ----------- |
| 矢量(Qdrant 块,`bge-m3`,1024 维) | **152,194** |
| 实体(图节点) | **310,364** |
| 关系/三元组(图边) | **683,651** |
| 实体类型 | 14 |
| 关系谓词 | 14 |
| 平均每个实体的关系 | ~2.2 |
每个边是一个主题-谓词-对象三元组,因此“关系”和“三元组”是相同的计数。距离度量是余弦;分块约为 1500 个令牌 / 200 重叠。
---
## 开始前(先决条件)
> _"这不是文档。这是嵌入顿。这里有规则。”_
- **Docker** (带有 Compose 插件)— 运行本地 Qdrant + ArangoDB + 嵌入器。
- **Python 3.12+**。
就是这个列表。无需帐户,无需令牌,无需访问请求 — 下载是一个普通的 HTTPS GET。
跨平台:Linux,macOS(Intel **和** Apple Silicon),以及通过 WSL2 的 Windows — 存储和嵌入器都在 Docker 中运行。
---
## 轻松开始(安装)
> _"杜德留存。”_
### 首先,了解您的立足点
几乎在此存储库中遇到的每个令人困惑的时刻都源于在错误目录中运行命令。只有 **两个** 目录很重要,每个目录都有不同的任务:
| 目录 | 存在内容 | 您在那里运行的命令 |
| --------------- | -------------------------------- | -------------------------------- |
| **存储库根目录** | `pyproject.toml`,`src/`,`mcp/` | `pip install -e .`,`pytest` |
| **`consumer/`** | `docker-compose.yml`,`.env` | 每个 `docker compose …` 命令 |
由此产生的两个规则涵盖了几乎所有情况:
- **`docker compose` 仅在 `consumer/` 中有效。** 那里有 compose 文件。从根目录运行它,Docker 会告诉您找不到配置文件。
- **`embeddington-consume` 从任何地方都有效**,一旦安装。它是一个真正的命令,位于您的 `PATH` 上,而不是您必须位于旁边的脚本。您无需 `cd` 到 `consumer/` 即可使用它。
下面的每个代码块都以 `# run from:` 注释开头。当有疑问时,就是答案。`~/embeddington` 用作克隆位置的示例 — 请替换为您自己的。
### 步骤
**1. 克隆。**
```bash
# run from: 任意存放代码的地方(例如 ~)
git clone https://github.com/whiffernet/embeddington.git
cd embeddington # <- 您现在位于存储库根目录
```
**2. 启动本地堆栈** (Qdrant + ArangoDB + 嵌入器)。这一步必须在 `consumer/` 中进行,因为那里有 `docker-compose.yml`:
```bash
# run from: 存储库根目录
cd consumer
cp .env.example .env # 然后打开 .env 并将 ARANGO_ROOT_PASSWORD 设置为您喜欢的任何内容
docker compose up -d # <- 必须从 consumer/ 运行
```
检查它是否启动并运行:
```bash
# run from: consumer/
docker compose ps # 所有服务都应该显示“running” — 嵌入服务在启动后的一段时间内会继续构建/下载
```
`embed` 服务在第一次运行后会构建并下载 `bge-m3` 模型(约 2 GB)— 第一次启动时就是这个一次性拉取为语义搜索提供支持。
> _"有时你吃掉吧台,有时吧台吃掉你。”_ 这个构建还会编译一个 CPU 嵌入器,它会拉取约 150 MB 的 PyTorch 并需要 **10-20 分钟** — Qdrant 和 ArangoDB 是快速预构建的拉取,但嵌入器是本地构建的,因此它在 Intel 和 Apple Silicon 上都可以运行。**如果构建超时** 在慢速连接上,只需重新运行 `docker compose up -d --build` — Docker 不会缓存失败的层,因此重试会干净地继续。杜德不为掉落的下载而烦恼。
**3. 安装消费者 CLI。** 这需要存储库根目录(`pyproject.toml` 位于此处)— `cd ..` 已经将您带回那里:
```bash
# run from: 存储库根目录
python -m venv .venv && . .venv/bin/activate # Windows: .venv\Scripts\activate
pip install -e .
```
确认它已安装。从现在开始,`embeddington-consume` 是一个位于您 `PATH` 上的普通命令:
```bash
# run from: 任意位置
embeddington-consume --help
```
> _"显然你不是高尔夫球手。”_ 如果它显示“command not found”,您很可能在 `consumer/` 而不是存储库根目录运行了 `pip install -e .`,或者您打开了一个新的 shell 并忘记重新激活 venv(`. .venv/bin/activate` 从存储库根目录)。
---
## 滚动更新(导入和更新)
> _"新的信息已经出现,伙计。”_
一条命令在第一次运行恢复基线,然后应用任何更新的差异。后续运行仅应用更改。
`embeddington-consume` 需要其环境中的 `ARANGO_ROOT_PASSWORD` — 与您在安装期间在 `consumer/.env` 中设置的相同值。下面第一行加载它。该相对路径(`consumer/.env`)就是为什么此块需要存储库根目录:
```bash
# run from: 存储库根目录
set -a; . consumer/.env; set +a # 将 ARANGO_ROOT_PASSWORD 加载到此 shell 中
embeddington-consume update
```
从其他地方运行?绝对定位到文件:
```bash
# run from: 任意位置
set -a; . ~/embeddington/consumer/.env; set +a
embeddington-consume update
```
您只需要每 shell 一次 `set -a` 行。对于 cron 作业,将两行放在一起 — cron 启动一个全新的 shell,而没有任何环境变量:
```bash
# crontab -e — 每天 06:00 更新
0 6 * * * set -a; . $HOME/embeddington/consumer/.env; set +a; $HOME/embeddington/.venv/bin/embeddington-consume update >> $HOME/embeddington-update.log 2>&1
```
第一次运行下载并恢复完整基线(几百 MB),因此需要几分钟。之后,更新很小。在您喜欢的计划上运行它(例如,每天 cron),以保持最新。
它打印的内容。**第一次运行** (或在剪切新基线后第一次运行)恢复整个图谱:
```
Embeddington 更新完成。
操作:恢复完整基线(baseline-2026-07b)
已加载:152,194 矢量 · 310,364 实体 · 683,651 边
版本:fd852b53bb07998ddc8e385971c25b94028fdf62
差异:0 个在基线之上应用
注意:在压缩后预计一次性完整重新下载 — 现有安装在单个步骤中重新恢复最新快照。
```
**后续运行** 仅应用更改,并说明如果没有更改:
```
Embeddington 更新完成。
操作:应用 3 个增量更新
版本:9f2a1c7e0b4d8a6f3e5c1b9d7a2f4e6c8b0d3a5f
```
```
Embeddington 更新完成。
操作:没有更改 — 已经是最新版本
版本:9f2a1c7e0b4d8a6f3e5c1b9d7a2f4e6c8b0d3a5f
```
基线恢复报告 `Diffs: 0` 是一个 **成功**,而不是空操作 — 这意味着它加载的快照已经是当前版本。无需更多内容,伙计。
---
## 在我们的时代(用 Claude 查询)
> _"你正在进入一个上下文世界。”_
`mcp/` 是一个 stdio MCP 服务器,暴露矢量搜索和图谱遍历到您的本地存储库。该存储库附带了一个项目范围的 **`.mcp.json`**,Claude Code 自动发现它,因此服务器显示为 **embeddington** (其工具为 `mcp__embeddington__…`)— 无需手动端点连接,只需设置 `ARANGO_ROOT_PASSWORD`。
需要连接的一点:服务器需要 `ARANGO_ROOT_PASSWORD` 在 Claude 启动的环境中 — 图形界面应用程序不会继承您的 shell 导出。最简单的路径:
```bash
# run from: 存储库根目录 — 使用密码加载 Claude Code
set -a; . consumer/.env; set +a
claude
```
对于 Claude Desktop,请将值放在 `mcp/.env` 中(复制 `mcp/.env.example`,填写 `ARANGO_PASSWORD`)— `server.py` 在启动时读取它。
> _"这是私人住宅,伙计。”_ `.mcp.json` 连接为 `ARANGO_USER: root`。那是 **您自己的** ArangoDB 容器 — 由 `consumer/docker-compose.yml` 启动,密码您在 `consumer/.env` 中选择。没有共享凭证随此存储库提供,这里没有任何内容访问您不拥有的数据库。
```bash
# run from: 存储库根目录 — 将 MCP 服务器的依赖项安装到您的活动 venv 中
pip install -r mcp/requirements.txt
```
然后在 Claude Code(或 Claude Desktop)中打开此存储库,并在提示时批准 `embeddington` MCP。参见 **mcp/README.md** 获取详细信息和 Claude Desktop 的 JSON 配置。
两种查询样式开箱即用:图谱遍历(`kg_find_entities`,`kg_neighbors`,`kg_path`,`kg_schema`,`kg_get_entity`)针对您的本地 ArangoDB 运行,`vector_search` / `enrich` 使用本地 `embed` 服务 — 与构建集合的相同 `bge-m3` 模型,因此查询落在数据的确切矢量空间中。无需外部嵌入 API。`.mcp.json` 已经将 `EMBED_URL` 指向它。
---
## 转一圈(示例提示)
> _"这是一个非常复杂的情况。很多输入,很多输出,很多你有的东西。”_
加载 embeddington MCP 后,向 Claude 提出需要图谱 **和** 文档的深度、多跳 ServiceNow 架构问题。像与了解一切的同事交谈一样:描述您实际遇到的情况,然后说明您想要的输出 — 建议、权衡、决策框架,任何有帮助的东西。两个示例可供参考:
**1. CI 识别和重复数据删除策略**
> 我们正在从三个地方加载 CMDB — 发现、服务图连接器和一个比我们有更多经验的遗留导入 — 并且我们在重复的 CI 中溺水。你能帮助我弄清楚如何解决识别问题吗?
>
> 我一直反复思考的部分:何时信任发现的识别规则与连接器提供的标识符与编写自己的 IRE 规则,以及数据源优先级如何解决两个来源声称相同属性时的问题。我还不确定从属和独立 CI 识别之间的界限在哪里。
>
> 与其直接给出答案,不如和我一起推理,然后制定一个默认的权威源模型,并说明它不应该适用的例外情况。如果您可以指出支持大决策的文档,那将有助于我内部推销。
**2. 大规模多实例平台和域策略**
> 我正在为一家全球性企业提供咨询 — 12 个业务部门,约 20 万名员工 — 我们必须在其他任何事情开始之前确定平台拓扑结构。单一实例和域分离?独立生产实例?某种中心辐射状结构?我实际上更愿意看到利弊而不是被告知结果。
>
> 两个事实是固定的:每个业务部门都需要隔离,但他们共享一个 CMDB。并且请坚持 GA 功能 — 我无法在明年推出的功能上制定计划。
>
> 一旦您做出决定,我就需要其余的故事:我们如何处理存档和表旋转的高容量表,跨实例集成的模式是什么样的,哪些性能杠杆实际上值得拉动,以及所有这些对我们的许可意味着什么。
>
> 先给我简短的建议,然后是背后的细节。最后附上我最担心的三个架构风险。
**首先使用 `enrich`** — 这是工具箱中最完整、最强大的工具。它在一个调用中运行矢量搜索 **和** 图谱遍历(实体匹配 + 邻居),并将两者都提供给 Claude,以便它拥有文档 **和** 连接结构来进行推理。其他 `kg_*` 工具适用于您想要深入到特定实体或跟踪单个路径的情况。
## 所需空间(存储)
> _"你想要一个脚趾?我可以给你一个脚趾…… 以及磁盘空间。相信我。"_
预计在所有内容稳定后,所需空间约为 **~8.5 GB**。详细列表如下:
| 组件 | 磁盘 |
| --------------------------------------------- | ------- |
| `bge-m3` 模型(首次启动,在一个卷中) | ~2.2 GB |
| `embed` 服务镜像(仅 CPU torch) | ~1.3 GB |
| Qdrant + ArangoDB 引擎镜像 | ~0.7 GB |
| 恢复的图(Qdrant ~2.4 GB + Arango ~0.9 GB) | ~3.3 GB |
| 基线下载(暂时的 — 可删除) | ~1.0 GB |
在首次下载期间,请预留一些额外的空间,因为压缩的基线和恢复的副本将共存,直到您清除 `data/work/` 目录。此外,还需要 **~6–8 GB RAM** — 仅嵌入器在加载 bge-m3 后就占用了约 2.3 GB 的内存,此外 Qdrant + ArangoDB 还为整个图提供服务。
随着基线的增长,大小也会随之增加:`baseline-2026-07` 相对于 `baseline-2026-06` 大致增加了两倍的向量计数,磁盘数字也随之增加。
---
## 更新内容
> _"你正在寻找的词是‘是’。"_
- 在 `diffs` 版本中,**清单** 列出了当前的基线和按顺序排列的、具有 SHA 校验的 diff 列表。CLI 跟踪一个本地 **光标**(它应用的最后一个点)。
- 每次运行时,它都会计算到当前的 shortest 路径:如果没有可用的光标,则恢复最新的基线,否则应用其光标之后的连续 diffs。
- 每个下载都经过校验和验证,每个写入都有键值(按 ID 更新/删除),并且仅在 diff 完全应用后,光标才会前进 — 因此,中断的 diff 应用运行会在下一个 diff 处干净地恢复。中断的基线下载会重新启动该资产(它流式传输到磁盘,因此不会占用您的 RAM)。
## 配置
`embeddington-consume update` 标志(均为可选 — `--repo` 默认值为 `whiffernet/embeddington`;仅在您已 fork 时覆盖):
| 标志 | 默认值 | 目的 |
| ------------------- | ------------------------- | ---------------------------------- |
| `--repo` | `whiffernet/embeddington` | 此版本的发布仓库 |
| `--cursor` | `data/.cursor` | 本地光标文件 |
| `--work-dir` | `data/work` | 下载的临时目录 |
| `--qdrant-url` | `http://localhost:6333` | 本地 Qdrant |
| `--collection` | `technology` | Qdrant 集合名称 |
| `--arango-url` | `http://localhost:8529` | 本地 ArangoDB |
| `--arango-db` | `technology_kg` | 目标数据库 |
| `--arango-user` | `root` | ArangoDB 用户 |
| `--arango-password` | `$ARANGO_ROOT_PASSWORD` | ArangoDB 密码 |
> _"这是当你浮动版本号时发生的情况。"_
>
> `docker-compose.yml` 将 Qdrant 固定到生成快照的确切版本 — Qdrant 快照恢复对版本敏感。不要将其浮动到 `:latest`。
## 运行测试
> _"标记为零。"_
有两个测试套件,它们从不同的目录运行。这不是疏忽 — MCP 服务器的测试需要 `mcp/` 作为 pytest 的 rootdir,因为仓库有一个名为 `mcp/` 的目录,否则会遮蔽它导入的官方 `mcp` SDK 包。
主要套件,从仓库根目录:
```bash
# 从仓库根目录运行
pip install -e ".[dev]"
pytest
```
MCP 服务器的套件,从 `mcp/`:
```bash
# 从 mcp/ 运行
cd mcp
pip install -r requirements-dev.txt
pytest
cd ..
```
---
## 谁有文件(许可证和数据出处)
> _"这是你的作业吗,拉里?"_
本仓库中的 **代码** — 消费者 CLI 和捆绑的 MCP 服务器 — 均在 **Apache License 2.0** 下许可。参见 [`LICENSE`](LICENSE)。
**数据** 是派生的,而不是原始的。向量和图均从 **[ServiceNow/ServiceNowDocs](https://github.com/ServiceNow/ServiceNowDocs)** 提取 — ServiceNow 自己的平台文档,© ServiceNow,在 Apache License 2.0 下发布。这里分发的派生工件(Qdrant 分片嵌入、`entities_v2`、`relationships_v2`)也在相同的条款下重新分发。
图中的任何内容本身都不具有权威性。每个关系都带有它来自的 `source_document` 和生成它的 `source_quote`,以便可以针对生成它的句子检查声明。当图和文档不一致时,**文档为准** — 提取是有损的,一个边是句子的压缩。
本项目与 ServiceNow 无关,不受 ServiceNow 支持或认可。
---
## 谨慎,伙计(第三方组件)
> _"谨慎,伙计,这里有饮料!"_
仓库根目录下的 `LICENSE` 涵盖了 **embeddington 自己的代码** — 消费者 CLI 和捆绑的 MCP 服务器 — 在 Apache 2.0 下。它 **不** 涵盖 embeddington 连接到的数据库,其中一个数据库有您需要了解的条款。
这里没有任何数据库。`consumer/docker-compose.yml` 命名了两个镜像;您的 Docker 从供应商那里拉取它们,您直接从他们那里接受他们的条款。embeddington 分发的是 **数据** — Qdrant 快照、ArangoDB 转储和每日差异。没有引擎源代码,没有二进制文件,没有镜像。
| 组件 | 固定版本 | 许可证 | 简介 |
| ------------------- | ------------------ | ------------ | -------------------------------------------------------------------------- |
| **Qdrant** | `v1.16.3` | Apache 2.0 | 没问题。使用它,发布它,销售它。 |
| **ArangoDB** | `3.12.4` | **BUSL 1.1** | 不是开源许可证。阅读下一部分。 |
| **BAAI/bge-m3** | — | MIT | 权重在首次运行时从 Hugging Face 下载;不会重新分发。 |
| **ServiceNow 文档** | 分支 `australia` | Apache 2.0 | 真相来源。参见上面的出处部分。 |
### ArangoDB 部分
ArangoDB 在 3.12 版本中更改为 **Business Source License 1.1**。它自己的文本非常直率:
> 商业源许可证 …… 不是开源许可证。
它授予您的内容,原封不动:
> 您可以在生产环境中在内部使用许可作品,但前提是您不得在允许一个或多个第三方(您的承包商除外)访问、创建或管理数据库(包括由该等第三方控制的数据)的商业产品中使用许可作品。
在我们的时代:
- **在您自己的机器上或在您自己的公司中运行 embeddington?** 这就是它的全部内容。放心使用。
- **销售一个托管服务,其中客户的数据存储在 ArangoDB 中?** 这是它所说的否定的内容。您需要从 ArangoDB 获得商业许可证。
- **等待它过去?** BUSL 在其更改日期转换为 Apache 2.0 — 2024 年 3 月发布的第四个周年纪念日,因此对于 3.12 版本,大约是 **2028 年 3 月**。时钟按版本计算:升级引擎,重启时钟。
此义务在 **您和 ArangoDB** 之间运行,而不是在您和此仓库之间。embeddington 向您提供一个 compose 文件,而不是数据库。
### 不是律师,伙计
> _"这只是你的意见,伙计。"_
本部分是出于善意总结的,不是法律建议。许可证本身是权威的: [Qdrant](https://github.com/qdrant/qdrant/blob/master/LICENSE), [ArangoDB](https://github.com/arangodb/arangodb/blob/devel/LICENSE)。如果有真正的钱涉及到 DBaaS 条款,请花十分钟时间与专业人士交流。
<p align="center"><em>图存在。</em></p>
MCP 配置
以下是此 MCP Server 的配置信息,可直接复制到 Cursor 或其他 MCP 客户端中使用。
mcp.json
连接信息
猜你喜欢
暂无推荐服务器