LangChain 基础使用

LangChain 基础使用

概述

LangChain 是一个强大的框架,用于构建基于大语言模型(LLM)的应用程序。它提供了丰富的工具和组件,让开发者能够轻松地创建复杂的 AI 应用。本文将详细介绍 LangChain 的核心功能,并通过实际代码示例展示其使用方法。

环境准备

安装依赖

首先,我们需要安装必要的依赖包:

pip install -r requirements.txt

requirements.txt 内容

langchain==0.1.0
langchain-community==0.0.10
langchain-text-splitters==0.0.1
langchain-huggingface==0.0.6
pydantic==2.5.0
requests==2.31.0
pypdf==3.17.4
chromadb==0.4.18
sentence-transformers==2.2.2
google-search-results==2.4.2

核心功能模块

1. 自定义 LLM 集成

由于网络访问限制,我们使用硅基流动平台的 API 替代 OpenAI。以下是如何创建自定义 LLM 类:

import json
from langchain.llms.base import LLM
from typing import Optional, List, Mapping, Any
from pydantic import Field
import requests

class SiluFlowLLM(LLM):
    """
    硅基流动平台 LLM 封装类
    
    该类封装了硅基流动平台的 API 调用,实现了 LangChain 的 LLM 接口。
    支持自定义 API 地址和密钥,提供统一的调用接口。
    """
    api_url: str = Field(..., description="硅基流动平台的API地址")
    api_key: str = Field(..., description="硅基流动平台的API密钥")

    def _call(self, prompt: str, stop: Optional[List[str]] = None) -> str:
        """
        执行 LLM 调用
        
        Args:
            prompt: 输入提示词
            stop: 停止词列表(可选)
            
        Returns:
            str: LLM 生成的文本响应
        """
        headers = {
            "Authorization": f"Bearer {self.api_key}",
            "Content-Type": "application/json"
        }
        payload = {
            # 模型,按需参考官网修改模型名
            "model": "moonshotai/Kimi-K2-Instruct",
            "messages": [
                {
                    "role": "user",
                    "content": prompt
                }
            ]
        }
        response = requests.post(self.api_url, json=payload, headers=headers, timeout=60)
        response.raise_for_status()
        data = response.json()
        return data['choices'][0]['message']['content']

    @property
    def _identifying_params(self) -> Mapping[str, Any]:
        """返回用于标识此 LLM 的参数"""
        return {"api_url": self.api_url}

    @property
    def _llm_type(self) -> str:
        """返回 LLM 类型标识符"""
        return "silu_flow"

def load_silu_llm():
    """
    加载硅基流动 LLM 实例
    
    Returns:
        SiluFlowLLM: 配置好的 LLM 实例
    """
    api_url = "https://api.siliconflow.cn/v1/chat/completions"
    api_key = "your_api_key_here"  # 请替换为您的实际 API 密钥
    return SiluFlowLLM(api_url=api_url, api_key=api_key)

2. Agent 智能代理

Agent 是 LangChain 的核心概念之一,它能够根据任务需求选择合适的工具并执行操作:

from langchain_community.agent_toolkits.load_tools import load_tools
from langchain.agents import initialize_agent, AgentType
import os

def user_agent() -> None:
    """
    演示 Agent 智能代理功能
    我们的联网搜索,并返回答案给我们。
    这里我们需要借助 Serpapi 来进行实现,Serpapi 提供了 google 搜索的 api 接口。
    首先需要我们到 Serpapi 官网上注册一个用户,https://serpapi.com/ 并复制他给我们生成 api key。
    然后我们需要api-key设置到环境变量里面去。
    该函数展示了如何创建一个能够使用外部工具的智能代理。
    代理可以执行搜索、计算等任务,并根据需要选择合适的工具。
    """
    os.environ["SERPAPI_API_KEY"] = "your SERPAPI_API_KEY"
    silu_llm = load_silu_llm()
    
    # 加载搜索工具 需要注册账号,
    tools = load_tools(["serpapi"])
    
    # 初始化 Agent
    agent = initialize_agent(
        tools,
        silu_llm,
        agent=AgentType.ZERO_SHOT_REACT_DESCRIPTION,
        verbose=True,
        handle_parsing_errors=True
    )
    
    # 执行任务
    agent.invoke("What's the date today? What great events have taken place today in history?")

功能说明:

  • AgentType.ZERO_SHOT_REACT_DESCRIPTION: 零样本代理,能够根据任务描述选择合适的工具
  • verbose=True: 显示详细的执行过程
  • handle_parsing_errors=True: 自动处理解析错误

3. 文档总结功能

LangChain 提供了强大的文档处理能力,包括文档加载、分割和总结:

from langchain.chains.summarize import load_summarize_chain
from langchain_community.document_loaders import PyPDFLoader
from langchain_text_splitters import RecursiveCharacterTextSplitter

def user_summarize() -> None:
    """
    演示文档总结功能
    
    该函数展示了完整的文档处理流程:
    1. 加载 PDF 文档
    2. 分割文档为小块
    3. 使用 LLM 进行总结
    4. 输出总结结果
    """
    # 加载 PDF 文档
    loader = PyPDFLoader("your_document.pdf")
    pages = loader.load()
    print(f'文档页数: {len(pages)}')

    # 初始化文本分割器
    text_splitter = RecursiveCharacterTextSplitter(
        chunk_size=500,      # 每个块的大小
        chunk_overlap=0      # 块之间的重叠
    )

    # 分割文档
    split_documents = text_splitter.split_documents(pages)
    print(f'分割后的文档块数: {len(split_documents)}')
    
    # 加载 LLM
    llm = load_silu_llm()
    
    # 创建总结链
    chain = load_summarize_chain(
        llm, 
        chain_type="map_reduce",  # 使用 map-reduce 方法
        verbose=True
    )

    # 执行总结(示例中只处理部分文档)
    result = chain.invoke(split_documents[200:205])
    print("=== 文档总结结果 ===")
    print(result.get('output_text', str(result)))

参数说明:

  • chunk_size=500: 每个文本块的最大字符数
  • chunk_overlap=0: 相邻块之间的重叠字符数
  • chain_type="map_reduce": 使用 map-reduce 方法进行总结,适合长文档

chain_type:这个参数主要控制了将 document 传递给 llm 模型的方式,一共有 4 种方式:

  • "stuff":将所有分割后的文档块直接拼接成一个大文本,一次性传递给 LLM 进行总结。适用于文档较短、内容不多的场景,速度快但容易超出 LLM 上下文长度限制。
  • "map_reduce":先对每个文档块分别总结(map 阶段),再将所有小总结合并后再次总结(reduce 阶段)。适合长文档,能够有效规避上下文长度限制,推荐优先使用。
  • "refine":先对第一个文档块总结,然后依次将后续文档块与前面总结结果结合,逐步 refine(细化)总结。适合需要逐步完善总结内容的场景,结果更连贯。
  • "map_rerank":对每个文档块分别总结并打分,最后选出分数最高的总结作为最终结果。适合需要从多个候选总结中选出最佳答案的场景。

4. 向量数据库和检索

LangChain 支持向量数据库集成,实现语义搜索和文档检索:

from langchain_huggingface import HuggingFaceEmbeddings
from langchain_community.vectorstores import Chroma
from langchain.chains import RetrievalQA

def user_embeddings() -> None:
    """
    演示向量数据库和语义检索功能
    
    该函数展示了完整的向量化检索流程:
    1. 加载嵌入模型
    2. 处理文档并创建向量
    3. 构建向量数据库
    4. 实现语义检索
    5. 构建问答链
    """
    # 加载嵌入模型
    embeddings = HuggingFaceEmbeddings()
    
    # 加载和分割文档
    loader = PyPDFLoader("your_document.pdf")
    pages = loader.load()
    
    text_splitter = RecursiveCharacterTextSplitter(
        chunk_size=500,
        chunk_overlap=0
    )
    split_documents = text_splitter.split_documents(pages)
    
    # 创建向量数据库
    db = Chroma.from_documents(split_documents[100:110], embeddings)
    
    # 构建检索器
    retriever = db.as_retriever()
    
    # 构建问答链
    qa_chain = RetrievalQA.from_chain_type(
        llm=load_silu_llm(),
        chain_type="stuff",        # 使用 stuff 方法
        retriever=retriever,
        verbose=True
    )
    
    # 执行问答
    query = "kafka架构是什么?"
    result = qa_chain.invoke({"query": query})
    print(result)
    
    # 直接进行向量检索
    query_embedding = embeddings.embed_query(query)
    docs = db.similarity_search_by_vector(query_embedding)
    
    # 输出检索结果
    for doc in docs:
        print(doc.page_content)

功能说明:

  • HuggingFaceEmbeddings: 使用 HuggingFace 的嵌入模型
  • Chroma: 轻量级向量数据库
  • RetrievalQA: 检索式问答链
  • chain_type="stuff": 将所有检索到的文档内容直接传递给 LLM

最佳实践

1. 错误处理

try:
    response = requests.post(api_url, json=payload, headers=headers, timeout=60)
    response.raise_for_status()
except requests.exceptions.RequestException as e:
    print(f"API 调用失败: {e}")
    return "抱歉,服务暂时不可用"

2. 配置管理

import os
from dotenv import load_dotenv

load_dotenv()

# 从环境变量读取配置
api_key = os.getenv("SILU_API_KEY")
api_url = os.getenv("SILU_API_URL")

3. 性能优化

# 使用缓存减少重复计算
from functools import lru_cache

@lru_cache(maxsize=128)
def cached_embedding(text):
    return embeddings.embed_query(text)

常见问题解决

1. API 密钥安全

  • 使用环境变量存储敏感信息
  • 避免在代码中硬编码 API 密钥
  • 定期轮换 API 密钥

2. 网络连接问题

  • 设置合理的超时时间
  • 实现重试机制
  • 使用代理服务器(如需要)

3. 内存管理

  • 合理设置文档块大小
  • 使用流式处理处理大文档
  • 及时清理不需要的对象

总结

LangChain 提供了强大的工具和框架,让开发者能够轻松构建复杂的 AI 应用。通过本文的示例,您应该能够:

  1. 集成自定义 LLM 服务
  2. 创建智能代理
  3. 处理文档并进行总结
  4. 构建向量数据库和检索系统
  5. 实现问答功能

记住要根据实际需求调整参数,并注意保护敏感信息的安全。LangChain 的生态系统正在快速发展,建议关注官方文档以获取最新的功能和最佳实践。

参考资料

posted @ 2025-08-07 18:34  lyu6  阅读(113)  评论(0)    收藏  举报