这条链路做什么
用 LangChain 的文本切分器、向量库封装与检索器,几十行代码即可跑通「读取文本 → 切分 → 向量化 → 相似检索」的最小链路,适合做原型与评测基线。它不包含生成环节,先把检索效果调稳,再接生成与引用。
基本信息
| 适用 | Python 3.9+,LangChain 0.2 及以后版本 |
|---|---|
| 需单独安装 | langchain-text-splitters、langchain-openai、langchain-chroma |
| 默认参数 | chunk_size 800、chunk_overlap 120 是起步值,需按语料调整 |
| 验证方式 | 打印命中片段,人工确认是否切到答案所在段落 |
精简示例
精简示例
from langchain_text_splitters import RecursiveCharacterTextSplitter
from langchain_openai import OpenAIEmbeddings
from langchain_chroma import Chroma
with open("doc.md", encoding="utf-8") as f:
text = f.read()
splitter = RecursiveCharacterTextSplitter(chunk_size=800, chunk_overlap=120)
chunks = splitter.split_text(text)
store = Chroma.from_texts(chunks, OpenAIEmbeddings(model="text-embedding-3-small"))
retriever = store.as_retriever(search_kwargs={"k": 4})
for doc in retriever.invoke("问题文本"):
print(doc.page_content[:120])逐步验证顺序
- 先看切分结果:随机抽 10 块,确认没有半截句子与页眉噪声
- 再看向量化:确认维度与所用模型一致,是否做了归一化
- 再测检索:用已知答案的问题看目标片段是否进入前列
- 最后接生成:把命中片段拼进提示词并要求标注编号
常用组件对照
| 环节 | 类名 | 注意 |
|---|---|---|
| 切分 | RecursiveCharacterTextSplitter | 分隔符要加中文标点 |
| 向量化 | OpenAIEmbeddings 等 | 模型与维度需与索引一致 |
| 存储 | Chroma / FAISS / Milvus 封装 | 默认内存方案重启即丢 |
| 检索 | as_retriever | search_kwargs 里配 k 与过滤条件 |
0.2 之后切分器移到独立包 langchain-text-splitters,向量库封装也拆成 langchain-chroma 等独立包;安装时按报错补齐依赖即可。
与生产环境的差距
这段示例刻意保持最小:向量存在内存、没有重排、检索不带过滤条件,也没有引用标注。搬进生产至少还要补三件事:向量与原文持久化,检索结果携带 doc_id 与标题路径等元数据,以及面向固定评测集的召回率统计。缺了最后一项,后续任何参数调整都只能凭感觉。
常见扩展点
- 更换持久化向量库:按数据量在 Milvus、Qdrant、pgvector 之间选择,内存版只用于原型
- 加元数据过滤:把租户、文档类型、生效日期写进检索条件,避免跨范围召回
- 接入重排模型:召回池取 30 至 50 条,精排后只保留 5 至 8 条进上下文
- 补生成与引用:给命中片段编号后拼进提示词,要求答案逐句标注编号
- 加缓存与限流:同一问题的向量化结果与检索结果可短期缓存,降低延迟与费用
示例中的 k=4 只是演示值:候选太少时重排无从发挥,候选太多又会推高延迟与上下文成本,需按评测结果定档。