问答要引用私有 PDF,不能把整本书塞进 prompt。检索器从索引里取出 Top-K 片段,再拼进提示。LangChain 用 Document 表示「一段文本 + 元数据」,用 Retriever 抽象「query → list[Document]」,与具体向量库解耦。
段末注释:Document = 带
page_content与metadata的文本单元;Retriever(检索器)= 根据 query 返回相关 Document 的 Runnable。
1. 一句话定位
| 维度 | 内容 |
|---|---|
| 角色 | 能力层 RAG 召回:query → 相关文档片段 |
| 输入 → 输出 | str query → list[Document] |
| 典型调用入口 | retriever.invoke("问题")、vectorstore.as_retriever() |
| 与 LangGraph | RAG 常作为图上一节点;线性链用 retriever | format_docs | prompt |
2. 实现逻辑
1 | 1. 离线:Loader → Document[] → Splitter → 入库(VectorStore 专篇) |
字段级变形:
1 | "什么是 LCEL?" |
3. 原理说明
3.1 Document
Document(数据类,langchain_core.documents.Document)
功能:一段文本 + 元数据,检索与引用的基本单元。
| 字段 | 类型 | 默认值 | 最小维度 |
|---|---|---|---|
page_content |
str | 必填 | 建议 ≥1 字符;空串可构造但检索无意义 |
metadata |
dict | {} |
可空;引用答案时至少 source |
id |
str / None | None |
更新/删除时建议非空 |
1 | Document(page_content="LCEL 用 | 连接 Runnable。", metadata={"source": "lcel.md"}) |
日志与引用依赖 metadata;塞 prompt 只用 page_content。
3.2 BaseRetriever
BaseRetriever(抽象类,Runnable)
功能:query: str → list[Document]。子类实现 _get_relevant_documents。
默认值:视实现。
最小维度:query 非空 str;返回 list,len 由 k 决定,无命中可为 []。
invoke(query, config=None)(方法)
与 similarity_search 结果同形,但是 LCEL 协议,能进 | 管道。
1 | docs = retriever.invoke("什么是 LCEL?") # list[Document] |
VectorStore.as_retriever(*, search_type="similarity", search_kwargs=None, **kwargs)(方法)
功能:把 VectorStore 包成 Retriever。
默认值:search_type="similarity";search_kwargs 默认常含 k=4(视实现,不传则用 store 默认 k)。
最小维度:store 内至少 1 条已索引 Document,否则恒返回 []。
1 | retriever = store.as_retriever(search_type="similarity", search_kwargs={"k": 2}) |
search_type:similarity / mmr / 部分实现的 similarity_score_threshold。
3.3 与 VectorStore 分工
VectorStore 管 存储与相似度;Retriever 管 搜索策略(k、score_threshold、filter)。换库时链上仍叫 retriever。
search_kwargs(dict)最小常用键:k: int ≥ 1(默认 4)。filter 视后端,可空。score_threshold 可选 float。MMR 时 fetch_k ≥ k。
3.4 不要直接把 Document 当 str
format_docs(docs)(应用层函数,非框架类)
功能:拼 prompt 用的 context。最小输入:list[Document],len≥0;空列表 → ""。
1 | def format_docs(docs: list[Document]) -> str: |
4. 最小可运行示例
1 | pip install -U langchain-openai langchain-huggingface sentence-transformers |
1 | from operator import itemgetter |
重要配置参数
| 参数(API 名) | 类型 / 默认值 | 功能说明 | 作用与影响 | 参考起点 | 配置指导 |
|---|---|---|---|---|---|
search_kwargs["k"] |
int,常默认 4 | 检索最多返回几条 Document | 过大噪声多、挤 context;过小漏召回 | 3~6 | 与 prompt 窗口一起算 |
search_type |
str,默认 similarity |
选近邻算法:纯相似或 MMR 去冗余 | mmr 更散、略慢;similarity 更贴 query | similarity | 文档重复多时用 mmr |
score_threshold |
float,可选 | 低于该相似度的结果丢掉 | 过高常返回空;过低噪声增加 | 0.7~0.85 | 无结果时先降 threshold |
filter |
dict,部分 store | 按 metadata 过滤后再搜 | 缩小候选集;键不存在则空结果 | {source:"hr"} |
多集合索引时常用 |
fetch_k |
int,mmr 用 | MMR 重排前先取多大候选池 | 须 fetch_k ≥ k;过小 MMR 无意义 |
k×3 | 影响 mmr 质量 |
metadata 字段 |
dict,Document 上,默认 {} |
片段来源、页码等溯源信息 | 不进模型也能在引用里展示 | source, page | 答案须引用时保留 |
5. 易踩坑
- retrieve 后直接 str(docs):得到对象 repr,模型读不到正文。
- k 过大挤爆 context:检索片段 + few-shot + 历史总和超窗。
- query 与索引语言不一致:跨语言检索质量差,需同语言或专用 embedding。
小结
- Document 承载片段与 metadata;Retriever 统一 query → docs。
- RAG 链典型:retriever → 拼 context → prompt → model。
- 搜索策略在 as_retriever(search_kwargs=…) 配置。
- 业务切分与评测见 RAG 目录;本篇只讲 LangChain API。