# Azure AI 搜索与 Manticore 搜索对比

对 Azure AI 搜索和 Manticore 搜索在混合全文 + 向量搜索方面的实用对比，重点聚焦于块级文档工作负载、相关性调整、操作模式和成本。

向量搜索非常适合搜索中“差不多相似”的部分。令人烦恼的是其他一切：精确短语、必须遵守的过滤器、拼写容错、可以向产品经理解释的相关性，以及结果不会因为模型打喷嚏而随机翻转。

因此这不是一篇“向量 vs 关键字”的文章。它关于的是无聊但实用的组合：**向量 + 全文搜索**，在同一个系统中，具有可预测的行为。

Azure AI 搜索和 Manticore 搜索都可以执行混合搜索。但它们在日常操作中感觉非常不同。

Azure 优化了快速交付。Manticore 优化了长期使用搜索。这种差异在第一周不太明显——但在第六个月会变得非常明显。

---

## 通用搜索失效之处

有一类搜索问题看起来简单，直到你将其部署：文档搜索、知识库、内部工具、任何包含“小块”（段落/部分）和大量元数据的内容。

这就是托管抽象开始失效的地方，也是默认设置不再成为你朋友的地方。

你最终会关心诸如：

- 严格过滤器（工作区/项目、地区、所有者/团队、时间戳、文档类型、可见性、版本）  
- 短语/邻近性（因为措辞很重要）  
- 稳定的排名（使结果在周与周之间不会漂移）  
- 看起来像实际引用而非“AI 感觉”的高亮/片段

是的，语义/向量搜索有帮助——但它不能替代全文基础或可解释性。

一旦你进入那个世界（过滤器、短语、稳定排名、“为什么这个排名？”），搜索就不再是你可以“开启”的东西，而成为你将随时间调整和调试的东西。这时真正的选择出现：接受托管服务的抽象层，或运行一个排名和执行更明确的引擎。

这种划分与 Azure AI 搜索 vs Manticore 非常接近。

---

## 解决方案的两种方式

最清晰的思考方式：

- **Azure AI 搜索** 是你租用的托管服务。你用便利性换取控制权（并获得 Azure 风格的防护措施）。  
- **Manticore 搜索** 是你运行的搜索引擎。你获得旋钮和调节器，以及对运行它的机器的责任。

如果你只需要“足够好”的搜索加上轻松集成，Azure 难以匹敌。如果你需要与相关性争论并获胜，Manticore 更容易相处。

---

## 成本对比：托管 vs 自托管

这是这两种方法之间最大的实际差异之一，通常在生产环境中运行几个月后才变得明显。

### Azure AI 搜索成本

Azure AI 搜索作为 **托管云服务** 计费。你分配容量（副本和分区），并按小时支付该容量的费用，无论是否完全使用。

这种模式有几个实际后果：

- 成本随着 *分配的容量* 而不是实际查询量增长。
- 高可用性和更高吞吐量会增加成本（副本 × 分区）。
- 向量搜索增加内存压力，这通常会比预期更早地将你推向更高层级。
- 你无法“缩放到零”——只要服务存在，它就会产生费用。

在实际部署中，团队通常从小规模开始，然后随着索引增长、查询量增加或延迟要求收紧而逐步扩展。随着时间推移，Azure AI 搜索每月成本通常会达到 **数百美元**，对于更苛刻的工作负载，**每月数千美元** 也不罕见。

这一切都不令人意外——你为一个完全托管的服务付费，该服务具有 SLA、内置冗余和紧密的 Azure 集成。但重要的是，**成本增长可能感觉间接**：你并不总是能清楚地看到“我们更改了 X”和“账单上涨”之间的线性关系。

### Manticore 搜索成本

Manticore 搜索本身是 **免费且开源** 的。没有授权成本。你支付的是基础设施和运营成本。

实际上，这通常意味着：

- 一个或多个虚拟机（或容器）
- 存储
- 监控和备份
- 一些运维时间

对于许多文档和知识库工作负载，一个普通的虚拟机就足够了。这通常使每月基础设施成本保持在 **几十美元**，而不是数百美元。即使有冗余或水平扩展，成本往往以 **可预测的硬件相关方式** 增长。

关键差异在于可见性：如果 Manticore 的成本增加，通常是因为你明确添加了内存、CPU 或机器。中间没有不透明的服务单位计算。

### 转折点

如果你的优先事项是最低的运营努力和深度的 Azure 原生集成，Azure AI 搜索的定价可以是一个合理的权衡。

如果你的优先事项是 **可预测的长期成本**、**清晰的性能调节器**，并避免数据增长时的意外账单，运行 Manticore 通常会显著更便宜——尤其是在向量搜索加入后。

---

## Azure AI 搜索：快速运行，后期模糊

Azure 拥有坚实的关键词引擎：分析器、词干提取、短语/邻近性、同义词映射、评分配置文件、过滤器，以及可选的语义排名层。你可以快速部署某物。

开始刺痛的地方是你已经过了演示阶段，现在需要维护它：

- 调优主要是“调整这些权重”（评分配置文件），再加上可能的语义排序。  
- 评分在端到端上不如 Manticore 透明。你可以通过评分配置文件/分析器进行调优并测量结果，但你无法获得“读取查询，理解排序”的直观感受。  
- 混合合并是受管理的；关键字和向量结果通过倒数排名融合（Reciprocal Rank Fusion，RRF）进行融合。这很方便。但当前10名看起来有问题时，检查起来也更困难。

在实践中，这通常会变成应用层的补偿逻辑：通过加权、过滤或对结果进行后处理，因为搜索引擎无法完全满足你的需求。这种逻辑更难测试，更难解释，也更难在后期移除。

如果你从未不得不向一个愤怒的人解释“为什么这是第一名？”，这没问题。如果你经历过，你已经知道这种痛苦了。

另外：整个系统都通过服务条款定义——schema JSON、Azure API、Azure 限制。实际的缺点是供应商锁定：一旦你的索引模型、分析器、评分配置文件和查询模式都变成了 Azure 风格，后续迁移将是一项真正的工程。

---

## Manticore Search：明确，而且说实话……调试起来更友好

Manticore 来源于经典的信息检索（IR）领域，并且将全文功能置于显要位置：BM25 风格的评分、字段级匹配、短语/邻近性、过滤，以及类似 SQL 的查询语言。你可以查看一个查询并知道它会做什么。更重要的是：你可以向不从事搜索的人解释它。

#### 示例：一个“普通”的全文查询

```sql
SELECT doc_id, WEIGHT()
FROM documents
WHERE MATCH('"data retention policy"~3')
  AND department = 'Finance'
  AND effective_date >= '2022-01-01'
ORDER BY WEIGHT() DESC
LIMIT 10;
```

那个“WEIGHT()”部分并不是魔法；它是思维模型的一部分。这比人们想象的更重要。

#### 无需猜测的混合搜索

在 Azure 中，混合搜索是“运行两者，用 RRF 融合”。在 Manticore 中，混合搜索是“先做这个，再做这个，然后过滤并应用二次排序”。这在幻灯片上看起来不够优雅，但非常实用。

示例（向量优先，然后文本，然后显式排序）：

```sql
SELECT doc_id, knn_dist(), WEIGHT()
FROM documents
WHERE knn(embedding, 50, 'how to rotate api keys safely')
  AND MATCH('"key rotation" | "rotate keys"')
ORDER BY knn_dist() ASC, WEIGHT() DESC
LIMIT 10;
```

你可以大声读出这个查询，它听起来不像祈祷文。这正是重点。

一个细微差别：KNN 结果主要按向量距离排序；额外的 `ORDER BY` 条件会在 KNN 集合内进行细化（例如：平局处理/二次排序），而不是将分数完全融合成一个混合排名。

另外：当排名变化时，你通常可以指出查询中导致变化的确切部分。回归问题变得无聊，这正是你想要的。

---

### 以存储为核心的产品不会取代搜索（它们只会迫使你维护第二个系统）

在 Azure 上经常会出现这种情况：你选择一个文档存储（Cosmos DB、DocumentDB/Mongo API 等），并希望它也能覆盖搜索。

它不会，至少对于任何块级或相关性敏感的场景而言。你很快会想要：

- 短语/邻近性
- 超出基础文本匹配的相关性调优
- 更好的排序控制
- 你可以推理的混合（向量 + 关键字）搜索

因此，你最终还是会添加 Azure AI Search，现在你必须维护两个独立的东西：存储 + 搜索，以及中间的索引管道。这完全可以接受。只是不要假装它是一个系统。

---

### 新鲜度和“我的更新生效了吗？”

在 Azure 中，更新是带有自己语义的 API 调用（并且你需要注意部分更新）。当内容发生变化时，向量字段需要显式处理。这是可以做到的，只是……需要应用工作。

Manticore 的实时表行为更像数据库：插入/更新/删除，全文 + 向量索引会同步更新。如果你正在构建像产品搜索或文档搜索这样的系统，其中内容经常变化，这会感觉更简单。

---

### “我们想要 Azure，最好是托管的”（合理）

如果你公司的默认立场是“托管一切”，Azure AI Search 符合这种世界观。你插上它，接受服务模型，然后继续前进。

如果你想在 Azure 上使用 Manticore 并且尽量减少麻烦，诚实的建议是：它不托管，但可以很“无聊”。

Azure AI Search 在搜索作为基础设施依赖时表现最佳。Manticore 在搜索作为产品界面时表现最佳。

不会变成科学项目的典型设置：

- 将文档保留在你已经信任的任何 Azure 存储中（Blob、数据库等）
- 在 VNet 中的单个 VM（或稍后的小型 VMSS）上运行 Manticore
- 将块处理/分段 + 索引保持为简单的工作者管道（队列 + 工作者，或你已有的任何方式）
- 将搜索视为无状态服务：快照/备份、指标和替换，而不是“宠物服务器”

如果你身处合规性要求高的环境，这也是“无聊”的胜利：私有网络、可预测的数据流，以及无需“请打开互联网让托管服务与其他托管服务通信”的舞蹈。

你仍然拥有它，但如果你不需要，你不会被迫进入一个复杂的集群。

---

### 实用注意事项：为什么向量搜索会改变账单

混合搜索不仅仅是“关键字 + 向量”。它也是**CPU + 内存**。

- 关键字密集型工作负载主要消耗 CPU。
- 向量密集型工作负载主要消耗内存。
- 块级索引通常会同时增加两者：更多行、更多向量、更多元数据、更多过滤器。

在 Azure AI Search 中，这通常表现为“我们需要更多容量”（账单随之增加预配单元）。
在 Manticore 中，这通常表现为“我们需要更多 RAM/CPU”（你可以选择 VM 大小）。

同样的物理规则——不同的计费模型。

---

### 关于“也许 Elastic 吧？”的快速说明

Elastic 是有能力的，在 Azure 上它是一个熟悉的选择。通常的权衡是操作层面：更多的组件、更多的旋钮、更多的“集群维护和喂养”。

如果你已经运行得很好，那就太好了。如果你没有，而你只需要一个行为良好的块级文档搜索，它可能感觉像为了拉小提琴而组建整个管弦乐队。

---

### 开发者体验（在编辑器中的感觉）

| 区域 | Azure AI 搜索 | Manticore 搜索 |
|---|---|---|
| 查询风格 | REST + JSON | SQL + HTTP JSON |
| 全文逻辑 | 服务定义 | 显式，查询级别 |
| 向量 + 文本 | 管理融合 | 显式组合 |
| 调试相关性 | 间接 | 直接 |
| 可移植性 | Azure 专用 | 任何环境 |
| 透明度 | 低 | 高 |

---

### 一个具体示例：条款级文档搜索

如果你想进行一个能快速暴露搜索权衡的极限测试，这就是：将文档拆分为条款/部分，索引这些段块，然后让人们在严格过滤下查找*特定语言*。

为什么它非常严格：

- 短语/邻近性非常重要。一个仅仅是“相似”的系统会返回类似的结果，浪费时间。
- 过滤器不是可选的。用户会将其视为硬性约束，当“几乎匹配”悄悄出现时他们会注意到。
- 信任是脆弱的。如果人们无法理解为什么某个结果排名第一，他们将不再信任搜索并开始绕开它。

通常它会变成（大致）：

- 每个条款成为一行/文档，包含 `clause_id`、`document_id`、`clause_path`（或任意命名），以及条款文本
- 元数据字段成为硬性过滤器（工作区/案件、司法管辖区/地区、日期、版本、可见性等）
- 可选：每个条款的嵌入向量用于“查找类似语言”的部分
- UI 单独拉取完整文档并展示条款，附带易于验证的片段/高亮

全文基准（可预测，易于解释）。当人们知道他们要寻找的措辞时使用此方法：

```sql
SELECT clause_id, document_id, WEIGHT()
FROM clauses
WHERE MATCH('"limitation of liability"~3')
  AND jurisdiction = 'AU'
  AND effective_date >= '2022-01-01'
ORDER BY WEIGHT() DESC
LIMIT 10;
```

嵌入向量适用的场景：它们在扩大召回率（“查找类似语言”）方面可能非常有效，但它们不会“思考”。实际上，语义搜索可能会陷入尴尬的中间地带：一开始看起来很聪明，但因为不够可靠而让人感到挫败。

因此，通常表现良好的模式是：

- 如果用户输入精确的关键词 → 使用纯全文搜索（BM25/`WEIGHT()`）。
- 如果用户输入一个想法（“责任上限”，“排除的损害”） → 使用嵌入向量提取候选结果，然后通过全文 + 过滤器锁定结果。

混合示例（语义候选 → 严格文本 + 元数据 → 距离优先排序）：

```sql
SELECT clause_id, document_id, knn_dist(), WEIGHT()
FROM clauses
WHERE knn(embedding, 50, 'cap on liability and excluded damages')
  AND MATCH('"limitation of liability" | "consequential damages"')
  AND jurisdiction = 'AU'
ORDER BY knn_dist() ASC, WEIGHT() DESC
LIMIT 10;
```

实际上它做了什么：

- `knn(...)` 通过语义选择候选集。
- `MATCH(...)` + 过滤器保持可验证性（你可以指向页面上的单词）。
- 结果主要按向量距离排序；`WEIGHT()` 在 KNN 集内进一步细化。

如果你需要真正的推理，请在检索后进行（例如，对前 N 个候选结果运行 LLM）。

这也是 RAG 风格工作流程适用的地方。Manticore 的 RAG 支持已在 [路线图](https://roadmap.manticoresearch.com/) 中（参见 [问题 #2286](https://github.com/manticoresoftware/manticoresearch/issues/2286)）——当你阅读此内容时，它可能已经发布。

---

### 那么我会选择哪一个？

- 如果你想要“不必让我运行搜索基础设施”并且已经深入 Azure，Azure AI 搜索显然是最佳选择。你将快速推进。
- 如果搜索相关性是产品功能（而非复选框），并且你预计需要数月时间进行调整和调试，你可能会更倾向于 Manticore。你可以保持明确和精确，而无需与托管抽象进行斗争。

一个略显现实的规则：如果你的团队无法或不愿拥有搜索系统，请选择 Azure。如果你的团队 *可以* 拥有它，请选择让你能看清发生什么的选项——这通常意味着 Manticore 是更冷静的长期选择。
