数据截至 (上游 commit eb1f187f8722)
Agentset — 架构与原理
30 秒导读: Agentset 是一个开源的「生产级 RAG 平台」。你把文档(PDF、网页、YouTube、纯文本)喂给它,它负责切块、算嵌入、存进向量 库;之后你用一句话提问,它负责检索、重排、拼上下文、让 LLM 生成带引用的答案。它的差异化不在「能跑通 RAG」,而在两点:一层把 Pinecone / Turbopuffer / OpenAI / Voyage / Cohere / ZeroEntropy 等厂商抹平的引擎抽象,和之上两条会自我评估、自动追加查询的多轮检索管线。
1. 这是什么(零基础也能懂)
一句话定义: Agentset = 「RAG 的水电煤」——把「检索增强生成」从一堆零件(嵌入模型、向量数据库、重排模型、分块器、LLM)组装成一个开箱即用、可多租户托管的平台。
RAG 是什么(先把名词点破): RAG(Retrieval-Augmented Generation,检索增强生成)= 回答问题前,先去你自己的资料库里捞几段最相关的原文,把这几段连同问题一起塞给 LLM,让它基于这些原文作答。好处是答案有出处、能引用、不容易胡编。
解决什么问题 / 给谁用:
- 给做「跟我的文档对话」产品的开发者:你有一堆 PDF/网页/帮助文档,想让用户能用自然语言问、得到带引用的答案,但又不想自己从零接 5 个厂商的 SDK、自己写分块和重排。
- 给需要多租户的 B2B 团队:同一个库里,每个客户(tenant)的数据要互相隔离。
它能做什么(功能):
- 摄取:文件 / 纯文本 / 网页爬取 / YouTube 字幕 → 自动分块、嵌入、入库
- 检索:语义(向量)/ 关键词(BM25)/ 混合(hybrid)三种模式
- 重排:用 Cohere / ZeroEntropy 重排模型把检索结果再排一遍
- 三档「聊天」:普通单轮 RAG、agentic 多轮自评检索、deep research 深度研究成文
- 多租户、托管页面、API + SDK、计费/用量计量
用起来什么样: 最直观的是它的检索 API——一次 HTTP POST,拿回排好序的 chunk:
# 示意,真实路由见 v1/namespace/[namespaceId]/search/route.ts
curl -X POST https://api.agentset.ai/v1/namespace/ns_123/search \
-H "Authorization: Bearer $KEY" \
-d '{
"query": "我们的退款政策是几天?",
"topK": 10,
"mode": "semantic",
"rerank": true
}'
# 返回:[{ id, text, score, rerankScore, metadata }, ...] 按相关度排序
一句话直觉/类比: 把 Agentset 想成一座图书馆 + 一个金牌图书管理员。
- 图书馆(向量库)= 所有书被拆成卡片、按「语义坐标」摆放,能按相似度秒查。
- 金牌管理员(agentic / deep research 管线)= 你问一个模糊问题,他不会只查一次就交差,而是自己拟几个检索词、查、看够不够答、不够再补查,最后把最相关的几页摊在你面前。
2. 顶层全景(它大概怎么转)
Agentset 是个 monorepo(一个仓库装多个包)。两条主干:写入侧(摄取) 和 读取侧(检索 + 生成),中间用向量库作为交汇点。
┌──────────────────────── 写入侧:摄取 ────────────────────────┐
你上传文件 │ ① 创建摄取作业 ② 外部解析/分块服务 ③ 嵌入 + 落库 │
/URL/文本 ──▶│ packages/jobs (PARTITION_API_URL) packages/engine │
│ ingest.ts HTTP /ingest /crawl ... process-document │
│ → 建 Document 行 → 返回一批批 chunk → 算向量 → upsert│
└──────────────────────────────┬───────────────────────────────┘
▼
┌───────────────────────┐
│ 向量库 │
│ Turbopuffer / Pinecone│ ← 每个 namespace+tenant 一个隔离命名空间
└───────────┬───────────┘
▲
┌───────────────────────────────┴───────────────────────────────┐
│ ① 提问 ② 检索(可混合+重排) ③ 生成带引用答案 │
你提问 ───▶ │ apps/web /chat 或 @agentset/engine AI SDK streamText│
│ /v1/.../search queryVectorStore (LLM) │
│ ├─ 单轮:直接查一次 │
│ ├─ agentic:生成查询→查→自评→不够再查(lib/agentic) │
│ └─ deepResearch:规划→多轮搜→评估→过滤→成文(lib/deep-research)│
└──────────────────────── 读取侧:检索 + 生成 ────────────────────┘
部件一句话职责:
| 部件 | 干什么 | 在哪个包/文件 |
|---|---|---|
@agentset/engine | RAG 引擎核心:抹平向量库/嵌入/重排厂商,提供 queryVectorStore | packages/engine/src/ |
@agentset/jobs | 后台异步任务(Trigger.dev):摄取作业、逐文档处理、删除 | packages/jobs/src/tasks/ |
@agentset/db | Prisma 数据模型(Namespace / Document / IngestJob),存厂商配置 | packages/db/prisma/schema/ |
@agentset/validation | zod schema + 厂商常量(嵌入模型/重排模型/向量库配置) | packages/validation/src/ |
apps/web | Next.js 应用:API 路由、聊天三档管线、agentic / deep-research | apps/web/src/ |
| 外部 Partition 服务 | 不在本仓库:负责真正的解析/OCR/分块,通过 HTTP 调用 | PARTITION_API_URL(env) |
主线走一遍(高层):
- 写入: 你建一个「摄取作业」→
ingestJob任务把它拆成一 行行Document→ 每个文档丢给外部 Partition 服务切成 chunk →processDocument把每批 chunk 算嵌入、upsert进向量库。 - 读取: 你提问 → 根据模式选管线 →
queryVectorStore算 query 嵌入、查向量库(可混合检索 + RRF + 重排)→ 把命中的 chunk 文本拼进 prompt → LLM 流式生成答案 + 引用。
3. 三个关键设计(先有个印象,细节进各章)
这三点是读完全库该带走的「精华」,这里先白话点一下,细节分别在各章展开。
① 引擎是「厂商无关」的抽象层。 VectorStore 是个抽象类(packages/engine/src/vector-store/common/vector-store.ts:83),Turbopuffer 和 Pinecone 各实现一遍;嵌入和重排同理用工厂函数按 namespace 配置动态挑厂商。换厂商 = 换配置,业务代码不动。详见 第 2 章。
② 混合检索的「融合」是手写的 RRF。 Turbopuffer 同时跑向量检索和 BM25 关键词检索,两个排序列表用 Reciprocal Rank Fusion(倒数排名融合) 合成一个——作者特意没用现成功能,因为融合算法有很多种、要可控。详见 第 2 章。
③ 多轮检索会「自我评估」。 agentic 管线不是查一次就完:它让 LLM 生成查询 → 检索 → 再让 LLM 判断「这些资料够不够答」 → 不够就换一批查询继续,直到够了或烧完 token 预算。deep research 更进一步,加了规划、摘要、过 滤、成文。详见 第 3 章。
4. 阅读地图
建议顺序:
- 01-ingestion.md — 先看「数据怎么进来」。一份文件如何从上传变成向量库里的 chunk:摄取作业编排、外部分块、分批嵌入、
upsert。看完你懂写入侧。 - 02-engine-retrieval.md — 全库技术含量最高的一章。
@agentset/engine的向量库抽象、语义/关键词/混合检索、RRF 融合、Mongo 风格过滤器到各厂商方言的翻译、重排。 - 03-agentic-and-deep-research.md — 检索之上的智能层。两条会自评、会多轮的检索管线如何编排 LLM + 引擎。
如果你只关心「它和别的 RAG 框架比强在哪」,直接跳第 2、3 章的「巧妙之处」小节。
5. 代码地图(导航索引)
| 主题 | 文件路径 | 符号名 |
|---|---|---|
| 引擎统一出口 | packages/engine/src/index.ts | (re-exports) |
| 检索主函数 | packages/engine/src/vector-store/query.ts | queryVectorStore |
| 向量库抽象基类 | packages/engine/src/vector-store/common/vector-store.ts | VectorStore |
| 按配置挑向量库 | packages/engine/src/vector-store/index.ts | getNamespaceVectorStore |
| 按配置挑嵌入模型 | packages/engine/src/embedding/index.ts | getNamespaceEmbeddingModel |
| 摄取作业编排 | packages/jobs/src/tasks/ingest.ts | ingestJob |
| 逐文档处理 | packages/jobs/src/tasks/process-document.ts | processDocument |
| agentic 多轮检索 | apps/web/src/lib/agentic/search.ts | agenticSearch |
| deep research 管线 | apps/web/src/lib/deep-research/index.ts | DeepResearchPipeline |
| 聊天三档入口 | apps/web/src/app/api/(internal-api)/chat/route.ts | POST |