【自然语言处理与大模型】LangChain大模型应用框架入门①

单独为LangChain花大概五篇文章的内容,来和大家一起入门LangChain,这是第一篇重点放在,了解 LangChain 是什么、它的主要用途以及核心模块。了解 LangChain 的设计哲学:链式调用、模块化、可扩展性。安装 并学习其中的一个组件:模型组件

〇、快速安装

LangChain框架由下面这些库组成:

库名 描述
langchain-core 提供基础抽象和LangChain表达式 (LCEL)。
langchain-community 包含第三方集成。
合作伙伴库 例如 langchain-openailangchain-anthropic 等,这些集成已经被进一步拆分为自己的轻量级库,仅依赖于 langchain-core
langchain 组成应用程序认知架构的链、代理和检索策略。
LangGraph 通过将步骤建模为图中的边和节点,构建强大且有状态的多参与者应用程序。与LangChain无缝集成,但也可以单独使用。
LangServe 用于将LangChain链部署为REST API。
LangSmith 一个开发者平台,用于调试、测试、评估和监控LLM(语言模型)应用程序。

我们可以先下载langchain、langchain-core、langchain-openai即可完成本文中的代码。如果还有用到其他的,我们再去对应按照即可。

bash 复制代码
# 创建一个conda虚拟环境
conda create -n langchain python=3.10

# 激活进入
conda activate langchain

# 安装最有必要的几个包
pip install langchain langchain-core langchain-openai langchain_community

一、核心组件:模型

在 LangChain 中有三种主要类型的模型,它们分别是LLM、ChatModel和Text Embedding Model,我们一个个来学习。

(1) LLM

大语言模型LLM(Large Language Model),用于生成文本输出。LangChain 提供了统一接口来调用各种 LLM。这个模型的用途是来回答问题、生成文本、翻译、摘要等自然语言任务。支持HuggingFace 上的各种开源模型,也支持闭源的OpenAI 的 GPT 系列和Anthropic 的 Claude系列。

需求:使用modelscope下载qwen3-0.6b模型,然后封装成LangChain的LLM类进行使用。

首先我们使用modelscope的SDK来下载一下qwen3模型,cache_dir参数指定模型存放的位置。

bash 复制代码
# 下载Qwen3-0.6B模型
from modelscope import snapshot_download
model_dir = snapshot_download('Qwen/Qwen3-0.6B', cache_dir='./')

然后,用下面的代码进行调用

python 复制代码
# 导入LangChain的LLM基类
from langchain.llms.base import LLM
# 导入Transformers库中的tokenizer和model类
from transformers import AutoTokenizer, AutoModelForCausalLM
# 导入PyTorch
import torch
# 导入类型提示中的ClassVar
from typing import ClassVar

# 定义LocalQwen3类,继承自LLM
class LocalQwen3(LLM):
    # 初始化tokenizer,加载Qwen3-0.6B的tokenizer
    tokenizer: ClassVar = AutoTokenizer.from_pretrained("Qwen/Qwen3-0.6B")
    # 初始化model,加载Qwen3-0.6B的模型
    model: ClassVar = AutoModelForCausalLM.from_pretrained("Qwen/Qwen3-0.6B")

    # 定义LLM类型属性
    @property
    def _llm_type(self):
        return "qwen3-0.6b"

    # 实现调用方法
    def _call(self, prompt, stop):
        # 将输入文本转换为模型输入格式
        inputs = self.tokenizer(prompt, return_tensors="pt").to(self.model.device)
        # 生成文本,最大新token数为100
        outputs = self.model.generate(**inputs, max_new_tokens=100)
        # 将输出解码为文本并返回
        return self.tokenizer.decode(outputs[0], skip_special_tokens=True)

    # 定义模型标识参数
    @property
    def _identifying_params(self):
        return {"name": "qwen3-0.6b"}


# 主程序入口
if __name__ == "__main__":
    # 实例化LocalQwen3对象
    qwen3_local = LocalQwen3()
    # 调用模型进行推理
    response = qwen3_local.invoke("你好,Qwen3!")
    # 打印响应结果
    print(response)

(2) Chat Model

ChatModel专门用于对话场景的模型,输入输出为消息对象(Message),支持多轮上下文理解。它的主要用途是构建聊天机器人、处理结构化对话历史。ChatModel的输入各种Message对象。更适合与用户进行多轮对话。

需求:使用modelscope下载qwen3-0.6b模型,然后封装成LangChain的ChatModel类进行使用。

用下面的代码来自定义Qwen3的ChatModel调用:

python 复制代码
# 导入基础聊天模型类
from langchain.chat_models.base import BaseChatModel
# 导入消息类型
from langchain.schema import AIMessage, HumanMessage, SystemMessage
# 导入Transformers相关组件
from transformers import AutoTokenizer, AutoModelForCausalLM, GenerationConfig
# 导入PyTorch
import torch
# 导入类型提示
from typing import List, Any, Optional
# 导入聊天输出相关类
from langchain_core.outputs import ChatGeneration, ChatResult


# 定义Qwen3聊天模型类
class ChatQwen3(BaseChatModel):
    # 默认模型路径
    model_name_or_path: str = "Qwen/Qwen3-0.6B"
    # tokenizer实例
    tokenizer: AutoTokenizer = None
    # 模型实例
    model: AutoModelForCausalLM = None
    # 设备类型
    device: str = "cuda"
    # 生成配置
    generation_config: GenerationConfig = None

    # 初始化方法
    def __init__(self, model_name_or_path: str = "Qwen/Qwen3-0.6B", device: str = "cuda", **kwargs):
        # 调用父类初始化
        super().__init__(**kwargs)
        # 设置模型路径
        self.model_name_or_path = model_name_or_path
        # 设置设备
        self.device = device
        # 加载tokenizer
        self.tokenizer = AutoTokenizer.from_pretrained(model_name_or_path, trust_remote_code=True)
        # 加载模型
        self.model = AutoModelForCausalLM.from_pretrained(
            model_name_or_path,
            device_map=device,
            trust_remote_code=True
        )
        # 加载生成配置
        self.generation_config = GenerationConfig.from_pretrained(model_name_or_path)

    # 定义模型类型属性
    @property
    def _llm_type(self):
        return "chat_qwen3"

    # 生成回复的方法
    def _generate(self, messages: List[Any], stop: Optional[List[str]] = None, **kwargs) -> ChatResult:
        # 将消息转换为提示文本
        prompt = self._convert_messages_to_prompt(messages)
        # 对输入进行编码
        inputs = self.tokenizer(prompt, return_tensors="pt").to(self.device)
        # 生成回复
        outputs = self.model.generate(**inputs, generation_config=self.generation_config, max_new_tokens=512)
        # 解码回复
        response = self.tokenizer.decode(outputs[0], skip_special_tokens=True)
        # 提取Assistant的回复部分
        if "Assistant:" in response:
            response = response.split("Assistant:")[-1].strip()
        # 创建AI消息对象
        message = AIMessage(content=response)
        # 创建聊天生成对象
        generation = ChatGeneration(message=message)
        # 返回聊天结果
        return ChatResult(generations=[generation])

    # 将消息列表转换为提示文本的方法
    def _convert_messages_to_prompt(self, messages):
        # 初始化提示文本
        prompt = ""
        # 遍历所有消息
        for msg in messages:
            # 处理人类消息
            if isinstance(msg, HumanMessage):
                prompt += f"User: {msg.content}\n"
            # 处理AI消息
            elif isinstance(msg, AIMessage):
                prompt += f"Assistant: {msg.content}\n"
            # 处理系统消息
            elif isinstance(msg, SystemMessage):
                prompt += f"System: {msg.content}\n"
        # 添加Assistant前缀
        prompt += "Assistant:"
        return prompt

# 主程序入口
if __name__ == "__main__":
    # 初始化模型
    chat_qwen3 = ChatQwen3(model_name_or_path="/root/autodl-tmp/Qwen/Qwen3-0.6B")

    # 构建消息列表
    messages = [
        SystemMessage(content="你是一个有帮助的助手。"),
        HumanMessage(content="请介绍下你自己。")
    ]

    # 调用模型生成回复
    response = chat_qwen3.invoke(messages)
    # 打印回复内容
    print(response.content)

(3)Text Embedding Model

文本嵌入模型,是将文本转化为向量表示(embedding),用于语义相似度计算、聚类、检索等任务。它主要用在构建知识库语义搜索和计算两个句子之间的相似性上。

如果你有OpenAI的API的话, 可以用下面的代码进行文本嵌入。

python 复制代码
from langchain_openai import OpenAIEmbeddings

api_key = "your-api-key-here"  # 请替换为你的OpenAI API密钥
base_url = "your-base-url-here"  # 请替换为你的base_url

embeddings = OpenAIEmbeddings(
    openai_api_key=api_key,
    openai_api_base=base_url
)

text = "人工智能改变世界"
vector = embeddings.embed_query(text)
print(f"文本 '{text}' 的向量表示长度为:{len(vector)}")

但很多时候我们都使用开源的embedding模型来做词嵌入任务的。

需求:使用modelscope下载bert-base-chinese模型,然后封装成LangChain的Text Embedding Model类进行使用。

使用modelscope的SDK下载:

python 复制代码
# 下载 embedding 模型
from modelscope import snapshot_download
model_dir = snapshot_download('tiansz/bert-base-chinese', cache_dir='./')

再代码里面继承Embeddings类,构建一个LangChain里面的Text Embedding Model来调用:

python 复制代码
# 导入langchain中的Embeddings基类
from langchain.embeddings.base import Embeddings
# 导入transformers中的自动分词器和模型类
from transformers import AutoTokenizer, AutoModel
# 导入PyTorch
import torch


# 定义一个使用本地BERT模型的词嵌入类,继承自Embeddings
class LocalBertEmbeddings(Embeddings):
    # 初始化函数,接收模型路径和设备参数
    def __init__(self, model_path: str, device: str = "cuda"):
        # 加载tokenizer
        self.tokenizer = AutoTokenizer.from_pretrained(model_path)
        # 加载模型并移至指定设备
        self.model = AutoModel.from_pretrained(model_path).to(device)
        # 保存设备信息
        self.device = device

    # 将多个文本转换为向量的函数
    def embed_documents(self, texts: list) -> list:
        # 对输入文本进行分词和编码
        inputs = self.tokenizer(texts, padding=True, truncation=True, max_length=512, return_tensors="pt").to(self.device)
        # 关闭梯度计算
        with torch.no_grad():
            # 使用模型进行前向传播
            outputs = self.model(**inputs)
        # 返回最后一层隐藏状态的平均值作为文本向量
        return outputs.last_hidden_state.mean(dim=1).cpu().numpy().tolist()

    # 将单个查询文本转换为向量的函数
    def embed_query(self, text: str) -> list:
        # 调用embed_documents并返回第一个结果
        return self.embed_documents([text])[0]

# 主程序入口
if __name__ == "__main__":
    # 实例化LocalBertEmbeddings类
    local_bert = LocalBertEmbeddings(model_path="/root/autodl-tmp/tiansz/bert-base-chinese")

    # 定义测试文本
    text = "深度学习是人工智能的重要分支"
    # 获取文本的向量表示
    vector = local_bert.embed_query(text)
    # 打印向量长度
    print(f"文本 '{text}' 的向量长度为:{len(vector)}")
    print(vector)
相关推荐
小森77676 分钟前
(六)机器学习---聚类与K-means
人工智能·机器学习·数据挖掘·scikit-learn·kmeans·聚类
RockLiu@80534 分钟前
探索PyTorch中的空间与通道双重注意力机制:实现concise的scSE模块
人工智能·pytorch·python
进取星辰37 分钟前
PyTorch 深度学习实战(23):多任务强化学习(Multi-Task RL)之扩展
人工智能·pytorch·深度学习
极客智谷1 小时前
Spring AI应用系列——基于ARK实现多模态模型应用
人工智能·后端
思悟小卒1 小时前
可以自我反思的检索增强生成
人工智能
学点技术儿1 小时前
torch.cuda.empty_cache()使用场景
人工智能
孔令飞1 小时前
如何在 Go 中实现各种类型的链表?
人工智能·云原生·go
XCristiano1 小时前
LLM魔法:让非结构化文本变身知识图谱
人工智能
redparrot20081 小时前
LeNet5 神经网络的参数解析和图片尺寸解析
人工智能·深度学习·神经网络
刘立军1 小时前
本地大模型编程实战(26)用langgraph实现基于SQL数据构建的问答系统(5)
人工智能·后端·python