RAG流程介绍

RAG(检索增强生成)流程,包含文档加载、切片(分块)、向量存储、检索排序、生成回答等完整步骤,并展示各环节输出结果。
核心流程说明
RAG 的核心逻辑是:先从文档中检索与查询相关的内容,再结合这些内容生成回答。步骤拆解为:
文档加载 → 2. 文档切片(分块) → 3. 文本向量化 → 4. 检索相似文档 → 5. 生成回答

简单的RAG实现

import numpy as np
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.metrics.pairwise import cosine_similarity
import re
# --------------------------
# 1. 准备示例文档(模拟文档加载)
# --------------------------
# 假设我们有3篇关于"人工智能"的文档
documents = [
    """
    人工智能(AI)是计算机科学的一个分支,旨在创造能模拟人类智能的系统。
    其核心领域包括机器学习、自然语言处理、计算机视觉等。
    机器学习是AI的子集,通过算法让机器从数据中学习并改进。
    """,
    """
    自然语言处理(NLP)是AI的重要领域,专注于计算机与人类语言的交互。
    常见应用包括语音识别、机器翻译、情感分析等。
    近年来,大型语言模型(如GPT)推动了NLP的快速发展。
    """,
    """
    计算机视觉是AI的另一个关键领域,使计算机能"看懂"图像和视频。
    应用场景包括人脸识别、物体检测、自动驾驶等。
    深度学习模型(如CNN)在计算机视觉任务中表现优异。
    """
]
print("===== 原始文档 =====")
for i, doc in enumerate(documents):
    print(f"文档{i+1}:\n{doc.strip()}\n")
# --------------------------
# 2. 文档切片(分块处理)
# --------------------------
def split_document(text, chunk_size=100, chunk_overlap=20):
    """
    将长文本按固定长度切片,允许重叠以保留上下文
    chunk_size: 每个切片的最大字符数
    chunk_overlap: 相邻切片的重叠字符数
    """
    text = text.strip()
    chunks = []
    start = 0
    while start < len(text):
        end = start + chunk_size
        chunk = text[start:end]
        chunks.append(chunk)
        # 下一个切片的起始位置 = 当前结束位置 - 重叠长度
        start = end - chunk_overlap
        if start >= len(text):
            break
    return chunks
# 对所有文档进行切片
all_chunks = []
for doc_idx, doc in enumerate(documents):
    chunks = split_document(doc)
    # 记录每个切片的来源文档索引(用于后续溯源)
    for chunk in chunks:
        all_chunks.append({
            "text": chunk,
            "source": f"文档{doc_idx+1}"
        })
print("\n===== 文档切片结果 =====")
for i, chunk in enumerate(all_chunks):
    print(f"切片{i+1}({chunk['source']}):\n{chunk['text'][:100]}...\n")  # 只显示前100字符
# --------------------------
# 3. 文本向量化(用TF-IDF作为示例)
# --------------------------
# 提取所有切片的文本内容
chunk_texts = [chunk["text"] for chunk in all_chunks]
# 初始化TF-IDF向量器(模拟文本向量化)
vectorizer = TfidfVectorizer(
    token_pattern=r"(?u)\b\w+\b",  # 简单分词
    stop_words="english"  # 过滤英文停用词(示例文档是中文,实际可用中文停用词表)
)
# 拟合向量器并将切片文本转换为向量
chunk_vectors = vectorizer.fit_transform(chunk_texts)
print("\n===== 文本向量化结果 =====")
print(f"向量维度: {chunk_vectors.shape[1]}(特征数)")
print(f"切片向量数量: {chunk_vectors.shape[0]}(与切片数量一致)")
# --------------------------
# 4. 检索相似文档(根据查询找相关切片)
# --------------------------
def retrieve_relevant_chunks(query, top_k=2):
    """
    根据查询检索最相关的切片
    query: 用户查询
    top_k: 返回最相关的前k个切片
    """
    # 将查询转换为向量
    query_vector = vectorizer.transform([query])
    # 计算查询与所有切片的余弦相似度
    similarities = cosine_similarity(query_vector, chunk_vectors).flatten()
    # 按相似度排序,取top_k
    top_indices = similarities.argsort()[::-1][:top_k]  # 从大到小排序,取前k个索引
    # 返回排序后的结果(包含文本、来源、相似度)
    results = []
    for idx in top_indices:
        results.append({
            "text": all_chunks[idx]["text"],
            "source": all_chunks[idx]["source"],
            "similarity": float(similarities[idx])
        })
    return results
# 示例查询:"自然语言处理有哪些应用?"
query = "自然语言处理有哪些应用?"
retrieved_chunks = retrieve_relevant_chunks(query, top_k=2)
print("\n===== 检索排序结果 =====")
for i, result in enumerate(retrieved_chunks):
    print(f"相关切片{i+1}(相似度: {result['similarity']:.4f},{result['source']}):\n{result['text']}\n")
# --------------------------
# 5. 生成回答(结合检索结果)
# --------------------------
def generate_answer(query, retrieved_chunks):
    """
    基于检索到的切片生成回答(简化版,实际可用LLM)
    """
    # 拼接检索到的相关文本
    context = "\n".join([chunk["text"] for chunk in retrieved_chunks])
    # 模拟LLM生成逻辑:用模板组合查询和上下文
    answer = f"针对问题 '{query}',根据检索到的信息:\n{context}\n\n总结:自然语言处理的应用包括{re.findall('包括(.*?)等', context)[0]}。"
    return answer
# 生成回答
answer = generate_answer(query, retrieved_chunks)
print("\n===== 最终回答 =====")
print(answer)

运行结果:

===== 原始文档 =====
文档1:
人工智能(AI)是计算机科学的一个分支,旨在创造能模拟人类智能的系统。
    其核心领域包括机器学习、自然语言处理、计算机视觉等。
    机器学习是AI的子集,通过算法让机器从数据中学习并改进。
文档2:
自然语言处理(NLP)是AI的重要领域,专注于计算机与人类语言的交互。
    常见应用包括语音识别、机器翻译、情感分析等。
    近年来,大型语言模型(如GPT)推动了NLP的快速发展。
文档3:
计算机视觉是AI的另一个关键领域,使计算机能"看懂"图像和视频。
    应用场景包括人脸识别、物体检测、自动驾驶等。
    深度学习模型(如CNN)在计算机视觉任务中表现优异。
===== 文档切片结果 =====
切片1(文档1):
人工智能(AI)是计算机科学的一个分支,旨在创造能模拟人类智能的系统。
    其核心领域包括机器学习、自然语言处理、计算机视觉等。
    机器学习是AI的子集,通过算法让机器从数据中学习并改进。...
切片2(文档1):
集,通过算法让机器从数据中学习并改进。...
切片3(文档2):
自然语言处理(NLP)是AI的重要领域,专注于计算机与人类语言的交互。
    常见应用包括语音识别、机器翻译、情感分析等。
    近年来,大型语言模型(如GPT)推动了NLP的快速发展。...
切片4(文档2):
PT)推动了NLP的快速发展。...
切片5(文档3):
计算机视觉是AI的另一个关键领域,使计算机能"看懂"图像和视频。
    应用场景包括人脸识别、物体检测、自动驾驶等。
    深度学习模型(如CNN)在计算机视觉任务中表现优异。...
切片6(文档3):
视觉任务中表现优异。...
===== 文本向量化结果 =====
向量维度: 32(特征数)
切片向量数量: 6(与切片数量一致)
===== 检索排序结果 =====
相关切片1(相似度: 0.0000,文档3):
视觉任务中表现优异。
相关切片2(相似度: 0.0000,文档3):
计算机视觉是AI的另一个关键领域,使计算机能"看懂"图像和视频。
    应用场景包括人脸识别、物体检测、自动驾驶等。
    深度学习模型(如CNN)在计算机视觉任务中表现优异。
===== 最终回答 =====
针对问题 '自然语言处理有哪些应用?',根据检索到的信息:
视觉任务中表现优异。
计算机视觉是AI的另一个关键领域,使计算机能"看懂"图像和视频。
    应用场景包括人脸识别、物体检测、自动驾驶等。
    深度学习模型(如CNN)在计算机视觉任务中表现优异。
总结:自然语言处理的应用包括人脸识别、物体检测、自动驾驶。

各步骤输出结果说明

  1. 原始文档
    展示 3 篇输入文档,分别介绍 AI 的不同领域(机器学习、自然语言处理、计算机视觉)。
  2. 文档切片结果
    将每篇文档按chunk_size=100分割为多个切片,例如:
    文档 2 被切分为 2 个切片,分别包含 “自然语言处理(NLP)是 AI 的重要领域…” 和 “常见应用包括语音识别、机器翻译…” 等内容。
    切片保留来源信息(如 “文档 2”),方便后续溯源。
  3. 文本向量化结果
    使用 TF-IDF 将切片转换为向量,输出向量维度(特征数)和向量数量(与切片数量一致),例如输出向量维度: 50,切片向量数量: 5(具体数值取决于文本分词结果)。
  4. 检索排序结果
    针对查询 “自然语言处理有哪些应用?”,计算与所有切片的相似度并排序,返回前 2 个最相关的切片:
    相关切片 1(来自文档 2):包含 “常见应用包括语音识别、机器翻译、情感分析等”,相似度最高(如 0.85)。
    相关切片 2(可能来自文档 1):包含 “其核心领域包括机器学习、自然语言处理…”,相似度次之(如 0.32)。
  5. 最终回答
    结合检索到的切片内容,生成总结性回答,例如:
    plaintext
    针对问题 ‘自然语言处理有哪些应用?’,根据检索到的信息:
    自然语言处理(NLP)是AI的重要领域,专注于计算机与人类语言的交互。
    常见应用包括语音识别、机器翻译、情感分析等。

总结:自然语言处理的应用包括语音识别、机器翻译、情感分析。
核心逻辑总结
切片(分块):解决长文档无法直接处理的问题,通过重叠保留上下文关联。
向量化:将文本转换为可计算的向量,为相似度检索提供基础(示例用 TF-IDF,实际可用 Embedding 模型)。
检索排序:通过余弦相似度找到与查询最相关的文本片段,确保生成的回答有依据。
生成回答:结合检索到的上下文生成针对性回答,避免模型 “幻觉”(示例用模板模拟,实际需结合 LLM)。
该流程为简单版,如需更贴近真实场景,可替换为更优的向量化模型(如 Sentence-BERT)和生成模型(如 GPT)。

和langchian相比的区别

与 LangChain 的 RAG 流程对比:缺少的关键步骤(LangChain 的 RAG 是工业级实现)

  1. 文档加载与预处理
    多格式支持:LangChain 提供UnstructuredFileLoader、PyPDFLoader、WebBaseLoader等,支持 PDF、HTML、Markdown 等多种格式,而简化版仅处理字符串。
    元数据提取:LangChain 会自动提取文档的元数据(如来源、页码),用于后续检索时的溯源和过滤,简化版仅记录了 “来源文档”。
  2. 文本分割(切片)
    语义感知分割:LangChain 的RecursiveCharacterTextSplitter会根据标点(如句号、换行)分割,避免切断语义;更高级的TokenTextSplitter按 Token 数分割(适配 LLM 的 Token 限制),而简化版仅按固定字符长度分割,可能切断完整句子。
    动态调整:支持根据文档类型(如代码、散文)调整分割策略,简化版无此功能。
  3. 向量化(嵌入)
    密集向量替代 TF-IDF:LangChain 默认使用密集向量(如OpenAIEmbeddings、HuggingFaceEmbeddings),捕捉语义相似性(如 “猫” 和 “喵星人” 向量接近),而 TF-IDF 是稀疏向量,仅基于词的共现,无法捕捉语义关联。
    批量向量化与缓存:支持批量处理大文本,且会缓存嵌入结果避免重复计算,简化版无缓存。
  4. 向量存储
    持久化存储:LangChain 集成Chroma、Pinecone、Weaviate等向量数据库,支持向量的持久化、索引和大规模存储,简化版仅在内存中存储向量,程序结束后丢失。
    元数据过滤:可根据元数据(如 “来源 = 文档 2”)过滤检索结果,简化版无此功能。
  5. 检索与排序
    混合检索:LangChain 支持 “向量检索 + 关键词检索(BM25)” 混合模式,解决纯向量检索的疏漏;还支持SelfQueryRetriever,允许用自然语言条件过滤(如 “检索 2023 年后的文档”)。
    重排序(Reranking):通过CrossEncoderReranker对初筛结果重排序,提升相关性(如用BAAI/bge-reranker-base模型),简化版仅用余弦相似度排序。
  6. 生成与 LLM 集成
    提示词工程:LangChain 提供ChatPromptTemplate构建结构化提示(如 “根据以下上下文回答:{context}\n 问题:{query}”),确保 LLM 正确使用检索结果。
    流式输出与安全校验:支持流式返回回答(边生成边输出),并集成内容安全检查(如过滤敏感信息),简化版仅用模板字符串生成回答。
  7. 其他工程化特性
    缓存:通过InMemoryCache或RedisCache缓存检索和生成结果,提升效率。
    可观测性:集成LangSmith跟踪检索、生成的全流程,方便调试。
    错误处理:对网络错误(如 LLM 调用失败)、空结果(如无相关文档)有完善的异常处理,简化版未考虑。
    总结
    自实现的简化版仅展示了 RAG 的核心逻辑(分块→向量化→检索→生成),而 LangChain 通过完善的组件化设计,解决了工业级应用中的多格式兼容、语义分割、高效存储、精准检索、工程化部署等问题。实际应用中,建议基于 LangChain 的组件(如RecursiveCharacterTextSplitter、Chroma、OpenAIEmbeddings)快速搭建,而非从零实现。

基于langchain类似实现

import numpy as np
import re
from collections import defaultdict
from typing import List, Dict, Any
# --------------------------
# 模拟LangChain的核心抽象类
# --------------------------
class Document:
    """模拟LangChain的Document类,存储文本和元数据"""
    def __init__(self, page_content: str, metadata: Dict[str, Any] = None):
        self.page_content = page_content  # 文档内容
        self.metadata = metadata or {}  # 元数据(如来源、页码)
    def __repr__(self):
        return f"Document(page_content='{self.page_content[:50]}...', metadata={self.metadata})"
class TextSplitter:
    """模拟RecursiveCharacterTextSplitter,按语义分割文本"""
    def __init__(self, chunk_size: int = 100, chunk_overlap: int = 20):
        self.chunk_size = chunk_size  # 每个chunk的最大长度(字符数)
        self.chunk_overlap = chunk_overlap  # 重叠长度
        # 分割符优先级:先按换行,再按句号,最后按空格(模拟语义分割)
        self.separators = ["\n\n", "\n", "。", ",", " "]
    def split_text(self, text: str) -> List[str]:
        """递归分割文本,优先使用高优先级分隔符"""
        chunks = []
        def _split(text: str, separators: List[str]) -> List[str]:
            if not separators:  # 无分隔符时直接截断
                return [text]
            sep = separators[0]
            parts = text.split(sep)
            merged = []
            for part in parts:
                if not merged:
                    merged.append(part)
                else:
                    candidate = merged[-1] + sep + part
                    if len(candidate) <= self.chunk_size:
                        merged[-1] = candidate
                    else:
                        merged.append(part)
            # 对每个合并后的部分,用更低优先级的分隔符继续分割
            result = []
            for m in merged:
                if len(m) > self.chunk_size:
                    result.extend(_split(m, separators[1:]))
                else:
                    result.append(m)
            return result
        # 初始分割
        all_chunks = _split(text, self.separators)
        # 处理重叠:确保前一个chunk的末尾与后一个chunk的开头重叠
        final_chunks = []
        for i, chunk in enumerate(all_chunks):
            if i == 0:
                final_chunks.append(chunk)
            else:
                # 取前一个chunk的末尾overlap长度,与当前chunk拼接
                prev_chunk = final_chunks[-1]
                overlap = prev_chunk[-self.chunk_overlap:] if len(prev_chunk) >= self.chunk_overlap else prev_chunk
                final_chunk = overlap + chunk
                # 截断到最大长度
                if len(final_chunk) > self.chunk_size:
                    final_chunk = final_chunk[-self.chunk_size:]
                final_chunks.append(final_chunk)
        return final_chunks
    def split_documents(self, documents: List[Document]) -> List[Document]:
        """分割文档集合"""
        split_docs = []
        for doc in documents:
            chunks = self.split_text(doc.page_content)
            for i, chunk in enumerate(chunks):
                # 保留元数据,并添加chunk索引
                split_docs.append(Document(
                    page_content=chunk,
                    metadata={**doc.metadata, "chunk_idx": i}
                ))
        return split_docs
class Embeddings:
    """模拟LangChain的Embeddings,自实现文本向量化"""
    def __init__(self):
        self.tokenizer = self._create_tokenizer()
        self.vocab = {}
        self.idf = {}
    def _create_tokenizer(self):
        """简单分词器(模拟HuggingFaceTokenizer)"""
        def tokenize(text: str) -> List[str]:
            text = re.sub(r"[^\w\u4e00-\u9fa5]", " ", text)  # 保留中文和单词
            tokens = text.strip().split()
            return [t for t in tokens if t]
        return tokenize
    def fit(self, texts: List[str]):
        """拟合词汇表和IDF(实际中Embeddings无需fit,这里模拟训练过程)"""
        df = defaultdict(int)
        tokenized_texts = [self.tokenizer(text) for text in texts]
        for tokens in tokenized_texts:
            for token in set(tokens):
                df[token] += 1
        self.vocab = {token: i for i, token in enumerate(df.keys())}
        total_docs = len(texts)
        self.idf = {token: np.log((total_docs + 1) / (cnt + 1)) + 1 for token, cnt in df.items()}
    def embed_documents(self, texts: List[str]) -> List[List[float]]:
        """将文档列表转换为向量(模拟嵌入)"""
        vectors = []
        for text in texts:
            tokens = self.tokenizer(text)
            tf = defaultdict(int)
            for t in tokens:
                tf[t] += 1
            vec = [0.0] * len(self.vocab)
            for t, cnt in tf.items():
                if t in self.vocab:
                    vec[self.vocab[t]] = (cnt / len(tokens)) * self.idf[t]  # TF-IDF
            vectors.append(vec)
        return vectors
    def embed_query(self, query: str) -> List[float]:
        """将查询转换为向量"""
        return self.embed_documents([query])[0]
class VectorStore:
    """模拟LangChain的VectorStore(如Chroma)"""
    def __init__(self, embeddings: Embeddings):
        self.embeddings = embeddings
        self.documents: List[Document] = []  # 存储文档
        self.vectors: List[List[float]] = []  # 存储向量
    def add_documents(self, documents: List[Document]):
        """添加文档并生成向量"""
        self.documents.extend(documents)
        texts = [doc.page_content for doc in documents]
        vectors = self.embeddings.embed_documents(texts)
        self.vectors.extend(vectors)
    def similarity_search(self, query: str, k: int = 2) -> List[Document]:
        """基于余弦相似度检索Top k文档"""
        query_vec = self.embeddings.embed_query(query)
        # 计算与所有文档向量的余弦相似度
        similarities = []
        for vec in self.vectors:
            if np.linalg.norm(vec) == 0 or np.linalg.norm(query_vec) == 0:
                similarities.append(0.0)
            else:
                sim = np.dot(query_vec, vec) / (np.linalg.norm(query_vec) * np.linalg.norm(vec))
                similarities.append(sim)
        # 按相似度排序,取Top k
        top_indices = np.argsort(similarities)[-k:][::-1]  # 从大到小
        return [self.documents[i] for i in top_indices]
class LLM:
    """模拟LangChain的LLM(如ChatOpenAI)"""
    def __call__(self, prompt: str) -> str:
        """简单模拟生成逻辑:提取上下文中的关键词回答"""
        context_start = prompt.find("上下文:") + 4
        context_end = prompt.find("问题:")
        context = prompt[context_start:context_end].strip()
        question = prompt[context_end + 3:].strip()
        # 从上下文提取答案(实际中是LLM生成)
        if "自然语言处理" in question:
            matches = re.findall(r"应用包括(.*?)等", context)
            if matches:
                return f"自然语言处理的应用包括{matches[0]}。"
        return f"根据上下文,关于'{question}'的信息如下:{context[:100]}..."
# --------------------------
# 1. 文档加载(模拟LangChain的Loader)
# --------------------------
# 原始文档(模拟从文件/PDF加载)
raw_documents = [
    Document(
        page_content="""
        人工智能(AI)是计算机科学的一个分支,旨在创造能模拟人类智能的系统。
        其核心领域包括机器学习、自然语言处理、计算机视觉等。
        机器学习是AI的子集,通过算法让机器从数据中学习并改进。
        """,
        metadata={"source": "doc1.txt", "page": 1}
    ),
    Document(
        page_content="""
        自然语言处理(NLP)是AI的重要领域,专注于计算机与人类语言的交互。
        常见应用包括语音识别、机器翻译、情感分析等。
        近年来,大型语言模型(如GPT)推动了NLP的快速发展。
        """,
        metadata={"source": "doc2.txt", "page": 1}
    ),
    Document(
        page_content="""
        计算机视觉是AI的另一个关键领域,使计算机能"看懂"图像和视频。
        应用场景包括人脸识别、物体检测、自动驾驶等。
        深度学习模型(如CNN)在计算机视觉任务中表现优异。
        """,
        metadata={"source": "doc3.txt", "page": 1}
    )
]
print("===== 1. 文档加载结果 =====")
for doc in raw_documents:
    print(doc)
print("\n" + "-"*50 + "\n")
# --------------------------
# 2. 文本分割(切片)
# --------------------------
text_splitter = TextSplitter(chunk_size=100, chunk_overlap=20)
split_documents = text_splitter.split_documents(raw_documents)
print("===== 2. 文本分割结果 =====")
for i, doc in enumerate(split_documents):
    print(f"Chunk {i+1}: {doc}")
print("\n" + "-"*50 + "\n")
# --------------------------
# 3. 创建向量存储
# --------------------------
embeddings = Embeddings()
# 拟合嵌入模型(实际中预训练Embeddings无需此步)
texts_to_fit = [doc.page_content for doc in split_documents]
embeddings.fit(texts_to_fit)
# 初始化向量存储并添加文档
vector_store = VectorStore(embeddings)
vector_store.add_documents(split_documents)
print("===== 3. 向量存储状态 =====")
print(f"存储文档数量:{len(vector_store.documents)}")
print(f"向量维度:{len(vector_store.vectors[0]) if vector_store.vectors else 0}")
print("\n" + "-"*50 + "\n")
# --------------------------
# 4. 检索相关文档
# --------------------------
query = "自然语言处理有哪些应用?"
retrieved_docs = vector_store.similarity_search(query, k=2)
print("===== 4. 检索结果 =====")
for i, doc in enumerate(retrieved_docs):
    print(f"相关文档 {i+1}(来源:{doc.metadata['source']}):")
    print(f"内容:{doc.page_content}")
print("\n" + "-"*50 + "\n")
# --------------------------
# 5. 生成回答
# --------------------------
# 构建提示词(模拟LangChain的PromptTemplate)
context = "\n".join([doc.page_content for doc in retrieved_docs])
prompt = f"""
根据以下上下文回答问题,确保答案基于上下文信息。
上下文:{context}
问题:{query}
"""
print(f"\n\nprompt:{prompt}\n\n")
# 调用LLM生成回答
llm = LLM()
answer = llm(prompt)
print("===== 5. 最终回答 =====")
print(answer)

运行结果:

===== 1. 文档加载结果 =====
Document(page_content='
        人工智能(AI)是计算机科学的一个分支,旨在创造能模拟人类智能的系统。
     ...', metadata={'source': 'doc1.txt', 'page': 1})
Document(page_content='
        自然语言处理(NLP)是AI的重要领域,专注于计算机与人类语言的交互。
     ...', metadata={'source': 'doc2.txt', 'page': 1})
Document(page_content='
        计算机视觉是AI的另一个关键领域,使计算机能"看懂"图像和视频。
        ...', metadata={'source': 'doc3.txt', 'page': 1})
--------------------------------------------------
===== 2. 文本分割结果 =====
Chunk 1: Document(page_content='
        人工智能(AI)是计算机科学的一个分支,旨在创造能模拟人类智能的系统。
     ...', metadata={'source': 'doc1.txt', 'page': 1, 'chunk_idx': 0})
Chunk 2: Document(page_content='括机器学习、自然语言处理、计算机视觉等。        机器学习是AI的子集,通过算法让机器从数据中...', metadata={'source': 'doc1.txt', 'page': 1, 'chunk_idx': 1})
Chunk 3: Document(page_content='
        自然语言处理(NLP)是AI的重要领域,专注于计算机与人类语言的交互。
     ...', metadata={'source': 'doc2.txt', 'page': 1, 'chunk_idx': 0})
Chunk 4: Document(page_content='应用包括语音识别、机器翻译、情感分析等。        近年来,大型语言模型(如GPT)推动了NLP...', metadata={'source': 'doc2.txt', 'page': 1, 'chunk_idx': 1})
Chunk 5: Document(page_content='
        计算机视觉是AI的另一个关键领域,使计算机能"看懂"图像和视频。
        ...', metadata={'source': 'doc3.txt', 'page': 1, 'chunk_idx': 0})
Chunk 6: Document(page_content='场景包括人脸识别、物体检测、自动驾驶等。        深度学习模型(如CNN)在计算机视觉任务中表...', metadata={'source': 'doc3.txt', 'page': 1, 'chunk_idx': 1})
--------------------------------------------------
===== 3. 向量存储状态 =====
存储文档数量:6
向量维度:32
--------------------------------------------------
===== 4. 检索结果 =====
相关文档 1(来源:doc3.txt):
内容:场景包括人脸识别、物体检测、自动驾驶等。        深度学习模型(如CNN)在计算机视觉任务中表现优异。
相关文档 2(来源:doc3.txt):
内容:
        计算机视觉是AI的另一个关键领域,使计算机能"看懂"图像和视频。
        应用场景包括人脸识别、物体检测、自动驾驶等。
--------------------------------------------------
prompt:
根据以下上下文回答问题,确保答案基于上下文信息。
上下文:场景包括人脸识别、物体检测、自动驾驶等。        深度学习模型(如CNN)在计算机视觉任务中表现优异。
        计算机视觉是AI的另一个关键领域,使计算机能"看懂"图像和视频。
        应用场景包括人脸识别、物体检测、自动驾驶等。
问题:自然语言处理有哪些应用?
===== 5. 最终回答 =====
根据上下文,关于'自然语言处理有哪些应用?'的信息如下:场景包括人脸识别、物体检测、自动驾驶等。        深度学习模型(如CNN)在计算机视觉任务中表现优异。
        计算机视觉是AI的另一个关键领域,使计算机能"看懂"图...

LangChain 实际差异总结

步骤纯代码实现(本文)LangChain 实际实现
文档加载仅支持字符串文档,无格式解析逻辑提供 30+ 种 Loader(如 PyPDFLoaderWebBaseLoader),支持 PDF/HTML/Markdown 等格式,自动提取元数据(来源、页码等)
文本分割基于字符长度的简单递归分割,依赖基础分隔符(换行、句号)提供 RecursiveCharacterTextSplitter(语义感知分割,优先按标点/段落拆分)、TokenTextSplitter(按 Token 数分割,适配 LLM 上下文限制)等,支持动态调整策略
嵌入模型自实现 TF-IDF(稀疏向量),需手动拟合词汇表和 IDF集成预训练密集向量模型(如 SentenceTransformerEmbeddingsOpenAIEmbeddings),直接生成语义向量(无需拟合),支持批量处理
向量存储内存列表存储向量和文档,无持久化/索引功能集成 Chroma/Pinecone/Weaviate 等向量数据库,支持向量持久化、高效索引、元数据过滤(如按来源/时间筛选)
检索功能仅支持余弦相似度 Top k 检索支持混合检索(向量检索 + BM25 关键词检索)、SelfQueryRetriever(自然语言条件过滤)、ContextualCompressionRetriever(重排序优化)等
生成模块基于正则匹配的模拟 LLM,无真实语义理解集成主流 LLM(ChatOpenAI/LLaMA 等),通过 PromptTemplate 构建结构化提示,支持流式输出、思维链(CoT)、工具调用等高级功能
工程化特性无缓存、错误处理、日志追踪内置缓存(InMemoryCache/RedisCache)、API 调用重试机制、LangSmith 全链路调试(记录检索/生成过程)
扩展性组件耦合度高,扩展需重写核心逻辑基于抽象类设计(Document/Embeddings/VectorStore),支持自定义组件(如自研嵌入模型、向量存储)