LangChain_RAG_学习小结

LangChain / RAG 学习总结

整理自近期几个核心问题的梳理:从环境警告、文本切分、相似度检索到 MMR 算法。


目录

  1. [langchain-community 的 sunset 警告](#langchain-community 的 sunset 警告)
  2. [CharacterTextSplitter 的参数坑](#CharacterTextSplitter 的参数坑)
  3. [Embedding 的 ctx_length 开关](#Embedding 的 ctx_length 开关)
  4. [similarity_search_with_score 带分数检索](#similarity_search_with_score 带分数检索)
  5. [MMR 搜索:相关性与多样性的平衡](#MMR 搜索:相关性与多样性的平衡)
  6. 核心速查表

1. langchain-community 的 sunset 警告

现象

运行代码时出现:

复制代码
DeprecationWarning: `langchain-community` is being sunset and is no longer actively maintained.

以及:

复制代码
USER_AGENT environment variable not set

原因

langchain-community 这个包官方决定停止维护、逐步淘汰 。根本原因是这个包里塞了太多集成(各种加载器、向量库、模型接口),导致迭代困难、质量参差。LangChain 现在改成"一个集成一个独立包"的模式。

官方声明要点:

  • 过去两年已不再接收新功能,实质上 deprecation 状态已持续一年多
  • 现在正式官宣 sunset,立即生效
  • 新集成工作已全部转向独立包(如 langchain_faiss、langchain_huggingface、langchain_ollama)

为什么 warnings.filterwarnings 管不住

这条提示不是走 Python 标准 warnings 模块 ,而是 LangChain 内部机制在 import 时直接刷到 stderr,绕过了过滤器。

正确处理

python 复制代码
import os
os.environ["LANGCHAIN_SUPPRESS_DEPRECATION_WARNINGS"] = "true"  # 官方总开关
os.environ["USER_AGENT"] = "MyRAGApp/1.0"

# 上面必须在 import 之前
from langchain_community.document_loaders import TextLoader

学习/搭建 demo 阶段可直接忽略该警告;上生产环境再按官方迁移指南逐个换成独立包。


2. CharacterTextSplitter 的参数坑

报错代码

python 复制代码
fixed_splitter = CharacterTextSplitter(
    chunk_size=100,
    chunk_overlap=20,
    separators="",        # ❌ 错误
    length_function=len
)

错误原因

CharacterTextSplitter 的构造函数签名是:

python 复制代码
def __init__(self, separator: str = "\n\n",
             is_separator_regex: bool = False, **kwargs):

参数名是 separator(单数、字符串),不是 separators(复数、列表)。

separators= 被 **kwargs 一路传到父类 TextSplitter,父类不认识这个参数,于是抛出:

复制代码
TypeError: TextSplitter.__init__() got an unexpected keyword argument 'separators'

(separators 是 RecursiveCharacterTextSplitter 的参数,两个类极易记混。)

修正后

python 复制代码
fixed_splitter = CharacterTextSplitter(
    separator="\n\n",      # 单数!
    chunk_size=300,
    chunk_overlap=60,
    length_function=len,
    is_separator_regex=False
)
fixed_chunks = fixed_splitter.split_documents(pdf_docs)

两个类的参数对照

参数 CharacterTextSplitter RecursiveCharacterTextSplitter
分隔符 separator: str(单数) separators: list[str](复数)
正则开关 is_separator_regex is_separator_regex
保留分隔符 继承父类 keep_separator 自身 keep_separator,默认 True

选择建议

  • 中文文档 + 接大模型 → 推荐 RecursiveCharacterTextSplitter,对段落结构更友好
  • length_function=len 按字符数算;接 token 计费模型时注意块数会暴增

3. Embedding 的 ctx_length 开关

原文

Whether to check the token length of inputs and automatically split inputs

longer than embedding_ctx_length.

Set to False to send raw text strings directly to the API instead of

tokenizing. Useful for many non-OpenAI providers (e.g. OpenRouter, Ollama,

vLLM).

翻译

是否检查输入的 token 长度,并自动将超过 embedding_ctx_length 的输入进行拆分。

设为 False 时,会直接将原始文本字符串发送给 API,而不做分词处理。这对许多非 OpenAI 的提供商(例如 OpenRouter、Ollama、vLLM)非常有用。

要点

  • embedding_ctx_length:嵌入模型的最大 token 上限
  • True(默认):超出自动切段,防止报错,适合 OpenAI
  • False:交给服务端处理 token 化,适合 Ollama / vLLM / OpenRouter

4. similarity_search_with_score 带分数检索

作用

similarity_search_with_score = "带距离分数的相似度搜索 ",返回 (Document, score) 元组列表。

与普通搜索对比

方法 返回内容 场景
similarity_search(query) Document 列表 只拿结果
similarity_search_with_score(query) (Document, score) 列表 看相关性高低、调试、过滤

用法

python 复制代码
results = vectorstore.similarity_search_with_score("苹果手机用什么芯片", k=3)
for doc, score in results:
    # Chroma 返回的是距离,越小越相似
    print(f"分数: {score:.4f} | 内容: {doc.page_content}")

关键认知

  • 返回的是距离,不是"相似度百分比"
  • 没有上限 ,值域 [0, +∞)
  • 0 = 完全相同,越大越不相关
  • 距离函数取决于创建 Chroma 时的配置:
    • L2 距离 (默认):[0, +∞)
    • 余弦距离 :[0, 2]

实战用途

python 复制代码
# 1. 阈值过滤
if score < 0.5:
    print(doc.page_content)

# 2. 调试召回质量
#    最高分都 > 1.5 → 切块太碎 / embedding 不合适 / 库里没这内容
#    分数普遍很小   → 召回质量好,可放心喂给 LLM

5. MMR 搜索:相关性与多样性的平衡

两个方法的关系

max_marginal_relevance_search max_marginal_relevance_search_by_vector
输入 文本字符串 向量
内部行为 先 embed 再搜 直接用给定向量
多一次 embedding ✅ 有 ❌ 无

前者是后者的封装:

python 复制代码
def max_marginal_relevance_search(self, query, k=4, fetch_k=20, lambda_mult=0.5):
    query_vector = self.embedding.embed_query(query)   # 多这一步
    return self.max_marginal_relevance_search_by_vector(query_vector, ...)

核心参数

python 复制代码
vectorstore.max_marginal_relevance_search(
    query,
    k=4,            # 最终返回几条
    fetch_k=20,     # 先拉多少条候选(再从中 MMR 筛选)
    lambda_mult=0.5 # 相关性 vs 多样性
)

λ(lambda_mult)调节

λ 值 行为
1.0 退化成普通搜索,纯看相关性
0.5 均衡(默认)
0.3 更强调多样性,可能混入不相关内容
0.0 纯看多样性,可能全是跑题的

MMR 在解决什么问题

普通搜索的痛点:返回结果高度重复。

复制代码
普通搜索(挤在一团):          MMR(散开覆盖):
   ●A  都在讲 3nm+A17            ●A  芯片本身
   ●B  ┐ 信息重叠               ●D  代际对比
   ●C  ┘                        ●E  竞品视角
  (浪费 token)                 (信息互补)

MMR 的目标函数

复制代码
MMR = λ · 相关性(文档, 查询)  −  (1−λ) · 最大相似度(文档, 已选文档)

每一步选文档时同时问两个问题:

  1. 这条跟问题像不像?→ 保证相关性
  2. 这条跟已选的像不像?→ 保证多样性(主动排斥"近亲")

使用场景

场景 推荐
知识库主题集中、切块较多 ✅ MMR
想让 LLM 看到多角度信息 ✅ MMR
内容本身很分散 普通搜索即可
对延迟极度敏感 普通搜索
只需 1~2 条精准答案 普通搜索
相关推荐
技术卷1 小时前
DeepSeek 部分 API 中断事件:重要细节与事实
人工智能·后端·网络安全
流烟默1 小时前
Spring Boot 异常响应被序列化为 XML 的排查与修复
xml·spring boot·后端
张张123y1 小时前
后端第六课:Python 语法速通(0 基础入门,AI 应用开发的第一门语言)
开发语言·人工智能·python·ai·后端开发
小马不起床1 小时前
Django 后端实战指南_10:用户扩展档案信息表
python·django·sqlite
Want5951 小时前
Python跳动的爱心①
开发语言·python·数学建模
SamChan901 小时前
PDF 翻译后 1,250 变成 1.250,是错了吗?用 Python 核对数字格式
python·pdf·ocr·数据校验·文档翻译
Yolanda_20221 小时前
30.利用GPU训练(一)
python
迅猛龙办公室1 小时前
Python实现PM空气质量提醒
服务器·前端·python
小马不起床2 小时前
Django 后端实战指南_9:前后端完整联调和问题修复
python·django·状态模式