跳到主要内容

R2R 是什么 · 全景与阅读地图

30 秒导读: R2R(SciPhi-AI 出品)是一套围绕 RESTful API 的 agentic 检索系统。 你把文档喂进去,它帮你做搜索(search)、检索增强问答(RAG),以及能自己反复检索、边查边想的 研究型 agent。它的价值不在"又一个向量库",而在于:把语义 / 全文 / 图谱三路搜索两级排名融合带出处的方括号引用,和**"检索本身就是 agent 的一个工具"**这几件事, 拼成一条从 HTTP 请求到带引用答案的完整流水线。

本章是顶层导览(Layer 0 + Layer 1):讲清"这是什么、大盘怎么转、一次 agent 请求怎么走完", 再给你一张往下钻的阅读地图。任何具体机制的实现都留给分章,本章不进代码细节。


1. 这是什么(零基础也能懂)

一句话定义: R2R = Retrieval to Riches(检索到富信息),一个把"搜索 + RAG + 研究 agent" 封装成 RESTful API 的检索系统。

解决谁的什么问题。 假设你有一大堆内部文档(PDF、网页、音频转写……),想让 AI 基于它们回答问题, 而不是瞎编。你不想自己从零拼"切块 → 向量化 → 混合检索 → 重排 → 塞进 prompt → 让模型带出处回答" 这一整套。R2R 把这套做成了一个服务:文档管理、混合搜索、知识图谱、用户与权限、agent,一次给全。

它能做什么(核心能力):

能力白话
多模态摄取.txt / .pdf / .json / .png / .mp3 等切块、向量化、入库
混合搜索语义搜索 + 关键词搜索,用 reciprocal rank fusion(倒数排名融合)合并
知识图谱自动抽实体与关系,支持基于图的检索
Agentic RAG一个会反复调用检索工具、边查边推理的 agent
Deep Research多步推理:能查你的知识库,也能查互联网,综合出答案

用起来什么样。 三行代码就是这个库对外的全部"表面积"——三个检索入口,从浅到深:

# 1) 纯搜索:只要命中的文档片段
results = client.retrieval.search(query="What is DeepSeek R1?")

# 2) RAG:检索 + 让模型生成带引用的答案
response = client.retrieval.rag(query="What is DeepSeek R1?")

# 3) Agent:把检索当工具,自己反复查、反复想(Deep Research)
response = client.retrieval.agent(
message={"role": "user", "content": "What does DeepSeek R1 imply? Think about market and societal implications."},
rag_generation_config={"model": "anthropic/claude-3-7-sonnet-20250219", "extended_thinking": True},
)

(取自 py/README.md:33-52。)

一句话直觉。search 当"一次性查字典",rag 当"查完让助理替你写段带脚注的答复", agent 当"派一个研究员:他能反复查字典、查网,直到把问题想透"——而三者用的是同一套底层检索

本节到此不碰任何实现。下面上大盘。


2. 顶层全景(它大概怎么转)

2.1 一张全景图

R2R 的检索侧是分层的:HTTP 路由层很薄,真正的编排在 RetrievalService,它再往下调策略层 → 三路底层搜索 → 聚合 → 生成/agent

怎么读这张图: 从上往下是"请求越走越深";search / rag / agent 三个入口共用下方的检索栈, 区别只在栈顶是否叠加"生成"或"agent 循环"。

客户端 SDK
client.retrieval.{search|rag|agent}
│ HTTP POST /v3/retrieval/*

┌───────────────────────────────┐
│ retrieval_router.py (薄路由) │ 校验入参、合并搜索模式
└───────────────┬───────────────┘

┌───────────────────────────────┐
│ RetrievalService │ 编排中枢
│ search() / rag() / agent() │
└───────┬───────────────┬────────┘
│ │
①检索策略层 ④生成 / Agent 循环
basic/HyDE/RAG-Fusion RAG 生成 · AgentFactory
│ │ (agent 把 ①当成一个可反复调用的工具)
▼ ▼
┌──────────────────────┐ 引用系统:short-id 方括号 [abc1234]
│ ② 三路底层搜索 │ 回填到 core/utils 的引用抽取
│ 语义 / 全文 / 混合 │
│ (pgvector, chunks) │
│ ③ 图谱检索 + 多源聚合 │
│ → AggregateSearchResult
└──────────────────────┘

2.2 部件一句话职责

部件干什么在哪
路由层 RetrievalRouter定义 /retrieval/{search,rag,agent,completion,embedding} 端点、校验、合并搜索模式py/core/main/api/v3/retrieval_router.py:49
搜索模式准备basic/advanced/custom 模式默认值与用户覆盖项合并、套上权限过滤retrieval_router.py:59 _prepare_search_settings
编排中枢 RetrievalService所有检索/RAG/agent 逻辑的落点;search() 按策略分流py/core/main/services/retrieval_service.py:248
三路底层搜索语义 / 全文 / 混合三种 chunk 搜索(走 pgvector)py/core/providers/database/chunks.py:327,484,538
多源聚合chunk + graph 结果打包成一个 AggregateSearchResultretrieval_service.py:321 _basic_search
Agent 工厂mode(rag/research)× 流式 × 模型,造出对应 agent 实例retrieval_service.py:60 AgentFactory.create_agent
Agent 实现RAG agent 与 Research agent 的具体行为py/core/agent/rag.pypy/core/agent/research.py
引用系统从模型输出里抽 short-id 方括号引用、映射回源结果py/core/utils/__init__.py:29 extract_citations

2.3 主线走一遍(高层,不进代码)

拿最复杂的 client.retrieval.agent(...) 走一条端到端主线——把整条流水线一次点亮:

① 客户端 POST /v3/retrieval/agent,带 message + rag_generation_config

② 路由 agent_app 校验 message/messages、按 mode 选默认模型、
(router:546) _prepare_search_settings() 合并搜索模式并套上用户过滤
│ 调 services.retrieval.agent(...)
③ Service.agent 组装系统指令、按 mode 配好工具,交给 AgentFactory
(service:1268) create_agent() 造出 R2R(Streaming)RAGAgent / ResearchAgent
│ 关键:knowledge_search_method = self.search ← 检索"变成一个工具"
④ Agent 循环 模型自己决定何时调"搜索工具" → 每次调用就跑一遍
│ 策略层(basic/HyDE/RAG-Fusion)→ 三路搜索 → 图谱 → 聚合
⑤ 聚合结果回流 AggregateSearchResult 塞回上下文,模型继续想/继续查(可迭代)

⑥ 生成带引用答案 模型输出里带 [short-id] 方括号引用;引用系统把它映射回原文块

⑦ 返回 非流式:整包 WrappedAgentResponse;流式:SSE 事件
(thinking / tool_call / tool_result / citation / message / final_answer)

这条主线的题眼: 第 ③ 步那行 knowledge_search_method=self.search (retrieval_service.py:1497 附近)——同一个 RetrievalService.search 方法,既是 /search 端点 的实现,又被当作 agent 手里的一个可反复调用的检索工具。 这就是"agentic RAG"名副其实的地方: 检索不是一次性前置步骤,而是 agent 循环里可以被多次触发的动作。详见 05-Agentic-RAG与Deep-Research.md


3. 巧妙之处速览(带走三个"精华")

这里只点出妙在哪,具体实现各自有分章深讲。

  • 两级 RRF(倒数排名融合)。 第一级在单次混合搜索内部——把"语义排名"和"全文排名"用 RRF 合成一个列表(chunks.py:538 hybrid_search)。第二级在 RAG-Fusion 策略里——把 原查询 + 若干改写子查询各自的结果用 RRF 融合一次(retrieval_service.py:450 _reciprocal_rank_fusion_chunks)。同一个融合思想,在两个尺度上各用一次。见 02-检索策略与两级RRF.md

  • short-id 方括号引用。 每个检索结果对象都有一个 id;模型被要求在答案里用 [前几位短id] 的形式引用。回填时用"前缀匹配"把短 id 认回完整结果(retrieval_service.py:1248 _find_item_by_shortid,str(result_obj.id).startswith(sid))。短 id 省 token,又能精确回溯原文。 见 04-RAG生成与short-id引用.md

  • 检索 = 可迭代的 agent 工具。 不是"先检索再回答"的一锤子买卖,而是把 self.search 作为工具 句柄交给 agent(AgentFactory.create_agentknowledge_search_method 形参, retrieval_service.py:67-82),让模型自己决定查几次、查什么。见 05-Agentic-RAG与Deep-Research.md


4. 阅读地图(建议按 01→05 顺序)

由浅入深:先看"底层怎么查一次",再看"多路怎么融合",再叠"图谱与聚合",最后到"生成与 agent"。

顺序章节讲什么什么时候读
01底层三路检索语义 / 全文 / 混合三路搜索,pgvector 落地想知道"一次搜索最底层怎么执行"
02检索策略与两级RRFbasic / RAG-Fusion / HyDE 三种策略与两级 RRF想知道"多路结果怎么被融合排名"
03知识图谱检索与多源聚合图谱检索 + AggregateSearchResult 的多源打包想知道"chunk 与 graph 结果怎么合流"
04RAG生成与short-id引用RAG 生成与 short-id 方括号引用系统想知道"答案里的 [abc1234] 怎么来的"
05Agentic RAG 与 Deep Research把检索变成可迭代工具的 agent想知道"agent 怎么反复查、边查边想"

推荐路线: 完全新手 → 01 → 02 → 03 → 04 → 05 顺序读;只关心 agent → 先扫本章 §2.3 主线, 再直奔 05,遇到"它到底怎么检索的"回头补 01/02。


5. 顶层代码地图(agent 的跳转表)

三列:主题 | 文件路径 | 真实符号名。行号 as-of sourceCommit;行号漂移时用符号名 grep

主题文件路径符号名
检索路由(三入口)py/core/main/api/v3/retrieval_router.pyRetrievalRouter
search 端点py/core/main/api/v3/retrieval_router.py:141search_app
rag 端点py/core/main/api/v3/retrieval_router.py:297rag_app
agent 端点py/core/main/api/v3/retrieval_router.py:546agent_app
搜索模式合并py/core/main/api/v3/retrieval_router.py:59 / :33_prepare_search_settings / merge_search_settings
编排中枢py/core/main/services/retrieval_service.py:248RetrievalService
策略分流py/core/main/services/retrieval_service.py:259RetrievalService.search
basic 策略py/core/main/services/retrieval_service.py:281_basic_search
RAG-Fusion 策略py/core/main/services/retrieval_service.py:326_rag_fusion_search
HyDE 策略py/core/main/services/retrieval_service.py:554_hyde_search
两级 RRFpy/core/main/services/retrieval_service.py:450 / :509_reciprocal_rank_fusion_chunks / _reciprocal_rank_fusion_graphs
向量/图谱搜索逻辑py/core/main/services/retrieval_service.py:651 / :731_vector_search_logic / _graph_search_logic
RAG 生成py/core/main/services/retrieval_service.py:985RetrievalService.rag
Agent 编排py/core/main/services/retrieval_service.py:1268RetrievalService.agent
Agent 工厂py/core/main/services/retrieval_service.py:60AgentFactory.create_agent
short-id 回填py/core/main/services/retrieval_service.py:1248_find_item_by_shortid
三路底层搜索py/core/providers/database/chunks.py:327,484,538semantic_search / full_text_search / hybrid_search
Agent 实现py/core/agent/rag.pypy/core/agent/research.pyR2RRAGAgent / R2RResearchAgent
引用抽取py/core/utils/__init__.py:29,55extract_citations / extract_citation_spans