Langchain 新手完全指南

news2025/2/21 21:15:04

Langchain 可能是目前在 AI 领域中最热门的事物之一,仅次于向量数据库。

在这里插入图片描述

它是一个框架,用于在大型语言模型上开发应用程序,例如 GPT、LLama、Hugging Face 模型等。

它最初是一个 Python 包,但现在也有一个 TypeScript 版本,在功能上逐渐赶上,并且还有一个刚刚开始的 Ruby 版本。

为什么需要 Langchain?

但是,为什么首先需要它呢?我们是否可以简单地发送一个 API 请求或模型,然后就可以结束了?你是对的,对于简单的应用程序这样做是可行的。

但是,一旦您开始增加复杂性,比如将语言模型与您自己的数据(如 Google Analytics、Stripe、SQL、PDF、CSV 等)连接起来,或者使语言模型执行一些操作,比如发送电子邮件、搜索网络或在终端中运行代码,事情就会变得混乱和重复。

在这里插入图片描述

LangChain 通过组件提供了解决这个问题的方法。我们可以使用文档加载器从 PDF、Stripe 等来源加载数据,然后在存储在向量数据库中之前,可以选择使用文本分割器将其分块。在运行时,可以将数据注入到提示模板中,然后作为输入发送给模型。我们还可以使用工具执行一些操作,例如使用输出内容发送电子邮件。

在这里插入图片描述

实际上,这些 抽象 意味着您可以轻松地切换到另一个语言模型,以节约成本或享受其他功能,测试另一个向量数据库的功能,或者摄取另一个数据源,只需几行代码即可实现。链(chains)是实现这一魔法的方式,我们将组件链接在一起,以完成特定任务。而代理(agents)则更加抽象,首先考虑使用语言模型来思考它们需要做什么,然后使用工具等方式来实现。

如果您对将语言模型与自己的数据和外部世界连接的强大之处感兴趣,可以查看与 LangChain 发布时间相近的研究论文,例如 Self-Ask、With Search 和 ReAct。

新手应该了解哪些模块?

现在让我们来看看幕后的真实情况。目前有七个模块在 LangChain 中提供,新手应该了解这些模块,包括模型(models)、提示(prompts)、索引(indexes)、内存(memory)、链(chains)和代理(agents)。

在这里插入图片描述

核心模块的概述

模型在高层次上有两种不同类型的模型:语言模型(language models)和文本嵌入模型(text embedding models)。嵌入模型将文本转换为数字数组,然后我们可以将文本视为向量空间。
在这里插入图片描述

在这个图像中,我们可以看到在一个二维空间中,“man”是“king”,“woman”是“queen”,它们代表不同的事物,但我们可以看到一种模式。这使得语义搜索成为可能,我们可以在向量空间中寻找最相似的文本片段,以满足给定的论点。

例如,OpenAI 的文本嵌入模型可以精确地嵌入大段文本,具体而言,8100 个标记,根据它们的词对标记比例 0.75,大约可以处理 6143 个单词。它输出 1536 维的向量。

在这里插入图片描述

我们可以使用 LangChain 与多个嵌入提供者进行接口交互,例如 OpenAI 和 Cohere 的 API,但我们也可以通过使用 Hugging Faces 的开源嵌入在本地运行,以达到 免费和数据隐私 的目的。

在这里插入图片描述

现在,您可以使用仅四行代码在自己的计算机上创建自己的嵌入。但是,维度数量可能会有所不同,嵌入的质量可能会较低,这可能会导致检索不太准确。

LLMs 和 Chat Models

接下来是语言模型,它有两种不同的子类型:LLMs 和 Chat Models。LLMs 封装了接受文本输入并返回文本输出的 API,而 Chat Models 封装了接受聊天消息输入并返回聊天消息输出的模型。尽管它们之间存在细微差别,但使用它们的接口是相同的。我们可以导入这两个类,实例化它们,然后在这两个类上使用 predict 函数并观察它们之间的区别。但是,您可能不会直接将文本传递给模型,而是使用提示(prompts)。

在这里插入图片描述

提示(prompts)

提示(prompts)是指模型的输入。我们通常希望具有比硬编码的字符串更灵活的方式,LangChain 提供了 Prompt Template 类来构建使用多个值的提示。提示的重要概念包括提示模板、输出解析器、示例选择器和聊天提示模板。

在这里插入图片描述

提示模板(PromptTemplate)

提示模板是一个示例,首先需要创建一个 Prompt Template 对象。有两种方法可以做到这一点,一种是导入 Prompt Template,然后使用构造函数指定一个包含输入变量的数组,并将它们放在花括号中的模板字符串中。如果您感到麻烦,还可以使用模板的辅助方法,以便不必显式指定输入变量。

无论哪种情况,您都可以通过告诉它要替换占位符的值来格式化提示。

在内部,默认情况下它使用 F 字符串来格式化提示,但您也可以使用 Ginger 2。

但是,为什么不直接使用 F 字符串呢?提示提高了可读性,与其余生态系统很好地配合,并支持常见用例,如 Few Shot Learning 或输出解析。

在这里插入图片描述

让我们看看如何做到这一点?首先,创建一个包含几个示例的列表。

from langchain import PromptTemplate, FewShotPromptTemplate

examples = [
    {"word": "happy", "antonym": "sad"},
    {"word": "tall", "antonym": "short"},
]

然后,我们指定用于格式化提供的每个示例的模板。

example_formatter_template = """Word: {word}
Antonym: {antonym}
"""

example_prompt = PromptTemplate(
    input_variables=["word", "antonym"],
    template=example_formatter_template,
)
"""

最后,我们创建 Few Shot Prompt Template 对象,传入示例、示例格式化器、前缀、命令和后缀,这些都旨在指导 LLM 的输出。

此外,我们还可以提供输入变量 examples, example_prompt 和分隔符 example_separator="\n",用于将示例与前缀 prefix 和后缀 suffix 分开。现在,我们可以生成一个提示,它看起来像这样。

few_shot_prompt = FewShotPromptTemplate(
    examples=examples,
    example_prompt=example_prompt,
    prefix="Give the antonym of every input\n",
    suffix="Word: {input}\nAntonym: ",
    input_variables=["input"],
    example_separator="\n",
)

print(few_shot_prompt.format(input="big"))

这是一种非常有用的范例,可以控制 LLM 的输出并引导其响应。

输出解析器(output_parsers)

类似地,我们可能想要使用输出解析器,它会自动将语言模型的输出解析为对象。这需要更复杂一些,但非常有用,可以将 LLM 的随机输出结构化。

在这里插入图片描述

假设我们想要使用 OpenAI 创建笑话对象,我们可以定义我们的 Joke 类以更具体地说明笑话的设置和结尾。我们添加描述以帮助语言模型理解它们的含义,然后我们可以设置一个解析器,告诉它使用我们的 Joke 类进行解析。

我们使用最强大且推荐的 Pydantic 输出解析器,然后创建我们的提示模板。

from langchain.prompts import PromptTemplate
from langchain.output_parsers import PydanticOutputParser
from pydantic import BaseModel, Field


class Joke(BaseModel):
    setup: str = Field(description="question to set up a joke")
    punchline: str = Field(description="answer to resolve the joke")


parser = PydanticOutputParser(pydantic_object=Joke)

让我们传递模板字符串和输入变量,并使用部分变量字段将解析指令注入到提示模板中。然后,我们可以要求 LLM 给我们讲一个笑话。

现在,我们已经准备好发送它给 OpenAI 的操作是这样的:首先从我们的.env 文件中加载 OpenAI 的 API 密钥,然后实例化模型,调用其调用方法,并使用我们实例化的解析器解析模型的输出。

from langchain.llms import OpenAI
from dotenv import load_dotenv


load_dotenv()
model = OpenAI(model_name="text-davinci-003", temperature=0.0)

然后,我们就拥有了我们定义了设置和结尾的笑话对象。生成的提示非常复杂,建议查看 GitHub 以了解更多信息。

prompt = PromptTemplate(
    template="Answer the user query.\n{format_instructions}\n{query}\n",
    input_variables=["query"],
    partial_variables={"format_instructions": parser.get_format_instructions()},
)

joke_query = "Tell me a joke."
formatted_prompt = prompt.format_prompt(query=joke_query)

print(formatted_prompt.to_string())

打印的结果是:

Answer the user query.
The output should be formatted as a JSON instance 
that conforms to the JSON schema below.

As an example, for the schema
{
    "properties": {
        "foo": {
            "title": "Foo",
            "description": "a list of strings",
            "type": "array",
            "items": {
                "type": "string"
            }
        }
    },
    "required": [
        "foo"
    ]
} 
the object {"foo": ["bar", "baz"]} is a well-formatted 
instance of the schema. 
The object {"properties": {"foo": ["bar", "baz"]}} is 
not well-formatted.

Here is the output schema:

{
“properties”: {
“setup”: {
“title”: “Setup”,
“description”: “question to set up a joke”,
“type”: “string”
},
“punchline”: {
“title”: “Punchline”,
“description”: “answer to resolve the joke”,
“type”: “string”
}
},
“required”: [
“setup”,
“punchline”
]
}

Tell me a joke.
"""

我们给 model 传入 prompt 模板,并且用输出解析器解析结果:

output = model(formatted_prompt.to_string())
parsed_joke = parser.parse(output)
print(parsed_joke)

我们之前讲过 Few Shot Prompt 学习,我们传递一些示例来显示模型对某种类型的查询的预期答案。我们可能有许多这样的示例,我们不可能全部适应它们。而且,这可能很快就会变得非常昂贵。这就是示例选择器发挥作用的地方。

示例选择器(example_selector)

为了保持提示的成本相对恒定,我们将使用基于长度的示例选择器 LengthBasedExampleSelector。就像以前一样,我们指定一个示例提示。这定义了每个示例将如何格式化。我们策展一个选择器,传入示例,然后是最大长度。

默认情况下,长度指的是格式化器示例部分的提示使用的单词和新行的数量 max_length

from langchain.prompts import PromptTemplate
from langchain.prompts import FewShotPromptTemplate
from langchain.prompts.example_selector import LengthBasedExampleSelector

examples = [
    {"word": "happy", "antonym": "sad"},
    {"word": "tall", "antonym": "short"},
    {"word": "energetic", "antonym": "lethargic"},
    {"word": "sunny", "antonym": "gloomy"},
    {"word": "windy", "antonym": "calm"},
]

example_prompt = PromptTemplate(
    input_variables=["word", "antonym"],
    template="Word: {word}\nAntonym: {antonym}",
)

example_selector = LengthBasedExampleSelector(
    examples=examples, 
    example_prompt=example_prompt, 
    max_length=25,
)

dynamic_prompt = FewShotPromptTemplate(
    example_selector=example_selector,
    example_prompt=example_prompt,
    prefix="Give the antonym of every input",
    suffix="Word: {adjective}\nAntonym:", 
    input_variables=["adjective"],
)

print(dynamic_prompt.format(adjective="big"))

那么,与聊天模型互动如何呢?这就引出了我们之前提到的聊天提示模板。聊天模型以聊天消息列表为输入。这个列表被称为提示。它们的不同之处在于,每条消息都被预先附加了一个角色,要么是 AI,要么是人类,要么是系统。模型应紧密遵循系统消息的指示。一开始只有一个系统消息,有时它可能听起来相当催眠。“你是一个善良的客服代理人,对客户的问题做出逐渐的回应”……类似于这样,告诉聊天机器人如何行事。AI 消息是来自模型的消息,人类消息是我们输入的内容。角色为 LLM 提供了对进行中的对话的更好的上下文。

模型和提示都很酷,标准化了。

索引(indexes)

但我们如何使用我们自己的数据呢?这就是索引模块派上用场的地方。

数据就是新的石油,你肯定可以在任何地方挖掘,并找到大量的。

Langchain 提供了钻机,通过提供文档加载器,文档是他们说的文本的花哨方式。有很多支持的格式和服务,比如 CSV、电子邮件、SQL、Discord、AWS S3、PDF,等等。它只需要三行代码就可以导入你的。这就是它有多简单!

在这里插入图片描述

首先导入加载器,然后指定文件路径,然后调用 load 方法。这将在内存中以文本形式加载 PDF,作为一个数组,其中每个索引代表一个页面。

文本分割器 (text_splitter)

在这里插入图片描述

这很好,但是当我们想构建一个提示并包含这些页面中的文本时,它们可能太大,无法在我们之前谈过的输入令牌大小内适应,这就是为什么我们想使用文本分割器将它们切成块。

读完文本后,我们可以实例化一个递归字符文本分割器 RecursiveCharacterTextSplitter,并指定一个块大小和一个块重叠。我们调用 create_documents 方法,并将我们的文本作为参数。

然后我们得到了一个文档的数组。

from langchain.text_splitter import RecursiveCharacterTextSplitter


with open("example_data/state_of_the_union.txt") as f:
    state_of_the_union = f.read()

text_splitter = RecursiveCharacterTextSplitter(
    chunk_size=100,
    chunk_overlap=20,
)
texts = text_splitter.create_documents([state_of_the_union])
print(f"\nFirst chunk: {texts[0]}\n")
print(f"Second chunk: {texts[1]}\n")

现在我们有了文本块,我们会想要嵌入它们并存储它们,以便最终使用语义搜索检索它们,这就是为什么我们有向量存储。

与向量数据库的集成

索引模块的这一部分提供了多个与向量数据库的集成,如 pine cone、redis、Super Bass、chroma DB 等等。

在这里插入图片描述

向量空间中进行搜索

一旦你准备好了你的文档,你就会想选择你的嵌入提供商,并使用向量数据库助手方法存储文档。

现在我们可以写一个问题,在向量空间中进行搜索,找出最相似的结果 similarity_search,返回它们的文本。

from langchain.embeddings.openai import OpenAIEmbeddings
from langchain.text_splitter import CharacterTextSplitter
from langchain.vectorstores import Chroma


with open("example_data/state_of_the_union.txt") as f:
    state_of_the_union = f.read()

text_splitter = CharacterTextSplitter(
    chunk_size=1000,
    chunk_overlap=0,
)
texts = text_splitter.create_documents([state_of_the_union])

embeddings = OpenAIEmbeddings()
docsearch = Chroma.from_texts(texts, embeddings)

query = "What did the president say about Ketanji Brown Jackson"
docs = docsearch.similarity_search(query)


print(docs[0].page_content)

在这里插入图片描述
在这里插入图片描述

从构建提示到索引文档,再到在向量空间中进行搜索,都可以通过导入一个模块并运行几行代码来完成。

希望你喜欢这个旅程,让我们开始我们的聊天机器人之旅吧!

如果你有任何问题或想要查看更详细的实例,你可以在加入社群提问。我期待着你的反馈和你在社区中分享的任何创新。

🔗 Links

Source code: https://github.com/edrickdch/langchain-101
LangChain: https://python.langchain.com.cn
Self-Ask Paper: https://ofir.io/self-ask.pdf
ReAct Paper: https://arxiv.org/abs/2210.03629

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/734210.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Git gui教程---第五篇 Git gui的使用 查看提交历史

查看提交历史 1.点击菜单栏的“版本库”,选择“图示master分支的历史” 2.出现的界面就是显示当前分支的提交历史了

Java基础---Java中创建对象方式

目录 使用new关键字 使用反射机制 使用clone方法 使用反序列化 使用方法句柄 使用Unsafe分配内存 使用new关键字 这是最常见的也是最简单的创建对象的方式通过这种方式还可以调用任意的构造函数(无参的和有参的) 使用反射机制 运用反射手段&#…

单个电源模块带电感的直流压降仿真(一)

单个电源模块带电感的直流压降仿真(一) 下面实例分析单个电源模块带电感的直流压降仿真分析,以下图为例 具体操作如下 创建新的workspaceLoad a New/Different layout(把PCB文件加载进来)

【滑动窗口】209. 长度最小的子数组

209. 长度最小的子数组 解题思路 滑动窗口设置前后指针滑动窗口内的元素之和总是大于或者等于s滑动窗口的起始位置: 如果窗口的值大于等于s 窗口向前移动窗口结束位置:for循环的j class Solution {public int minSubArrayLen(int target, int[] nums) {int left 0;// 滑动窗口…

UDS统一诊断服务【七】DTC控制0X85服务

文章目录 前言一、DTC控制服务介绍二、数据格式2.1 请求报文2.2 子功能2.3响应格式 三、举例总结 前言 大家好,我是嵌入式老林,从事嵌入式软件开发多年,今天分享的内容是UDS诊断故障码控制0X85服务介绍,希望能对你有所帮助 一、D…

[LeetCode周赛复盘] 第 353 场周赛20230709

[LeetCode周赛复盘] 第 353 场周赛20230709 一、本周周赛总结6451. 找出最大的可达成数字1. 题目描述2. 思路分析3. 代码实现 6899. 达到末尾下标所需的最大跳跃次数1. 题目描述2. 思路分析3. 代码实现 6912. 构造最长非递减子数组1. 题目描述2. 思路分析3. 代码实现 6919. 使…

人工智能与Chat GPT

一本书全面掌握ChatGPT,既有向ChatGPT提问的技巧, 也有构建自己的ChatGPT模型的方法,涵盖开发背景、关联技术、使用方法、应用形式、实用案例等 人工智能是我们这个时代最热门的话题,人们既希望它能代替我们做一些工作&#xff0c…

Python使用SQLAlchemy

Python使用SQLAlchemy 1 安装SQLAlchemy 备注:本文适用于SQLAlchemy>2.0 # 安装SQLAlchemy pip install SQLAlchemy# 安装pymysql pip install pymysql参考文档(SQLAlchemy>2.0) https://docs.sqlalchemy.org/en/20/创建数据库 # …

什么是敏捷测试?

目录 前言: 敏捷测试的定义 敏捷测试的特点 为什么要敏捷测试 缩短价值交付周期 强调质量属于大家 化繁为简节省成本 敏捷测试VS. 传统测试 传统测试如何迁移到敏捷测试 1. 组织文化的转变 2. 组织架构的调整 3. 人员培训与指导 4. 轻流程 敏捷测试成…

电视访问Samba

文章目录 问题描述方案一:当贝播放器方案二:nPlayer方案三:Kodi 问题描述 本人使用小米 AX9000 路由器 移动硬盘组了个轻 NAS,想通过电视访问 Samba 看视频(也可以电脑开 SMB) 开启 Samba 功能 文件夹开…

SpringMVC第一讲:SpringMVC基础知识

一、MVC设计模式 MVC的全名是Model View Controller,是模型(Model)-视图(view)-控制器(controller)的缩写,是一种设计模式。它是用一种业务逻辑、数据与界面显示分离的方法来组织代码,将众多的业务逻辑聚集到一个部件…

SIFT(尺度不变特征变换)

Sift(尺度不变特征变换),全称是Scale Invariant Feature Transform Sift提取图像的局部特征,在尺度空间寻找极值点,并提取出其位置、尺度、方向信息。 Sfit的应用范围包括物体辨别、机器人地图感知与导航、影像拼接、…

OpenCV 入门教程:膨胀和腐蚀操作

OpenCV 入门教程:膨胀和腐蚀操作 导语一、膨胀操作二、腐蚀操作三、示例应用3.1 图像增强3.2 边缘检测 总结 导语 膨胀和腐蚀是图像处理中常用的形态学操作,用于改变图像的形状和结构。在 OpenCV 中,膨胀和腐蚀是基于结构元素的像素操作&…

一零六三、进程调度算法模拟 (C语言实现)

目录 背景 程序实现 实现效果 背景 1、根据算法要求从键盘输入不少于四个进程信息(包括进程名称、进程到达时间、估计运行时间),RR算法输入不少于两种时间片的大小 2、输出进程的调度顺序、完成时间、周转时间、平均周转时间、平均带权周转…

Openlayers实战:点击某点,overlay显示经纬度坐标

在之前的实战中,我们在某个固定的位置显示鼠标位置的经纬度, 今天改变一种形式,即采用overlay的方式,点击某处,获得到经纬度坐标,显示在overlay层上面。 效果图 源代码 /* * @Author: 大剑师兰特(xiaozhuanlan),还是大剑师兰特(CSDN) * @此源代码版权归大剑师兰特…

23款迈巴赫S480升级原厂主动式氛围灯+电动后门+前后手势感应

23款迈巴赫S480升级原厂主动式氛围灯原厂电动后门原厂手势控制 新车刚提,原厂配置升级,全新配件 配件齐全,准备上车 全套主动式氛围灯配件 氛围灯模块 前排驾驶位顶棚的手势感应 手势感应电脑模块 后排顶棚的手势感应 电动后门配件有锁机、电…

基于simulink使用光流法跟踪汽车(附源码)

一、前言 此示例演示如何使用光流估计在视频序列中检测和跟踪汽车。 二、模型 下图显示了使用光流跟踪汽车模型: 三、用光流结果跟踪汽车 该模型使用光流估计技术来估计视频序列的每一帧中的运动矢量。通过阈值化运动矢量,该模型创建包含移动对象斑点…

mysql学习--使用navicat查看数据库密码

数据库通常分为两种:关系型数据库和非关系型数据库,关系型数据库通常会建立很多二维数据表,形成一对一、一对多、多对多等关系;之后利用SQL语句查询我们所需要的数据;非关系型数据库基于Key-Value的对应关系,并且查询的…

机器学习 day24(多类分类模型,Softmax回归算法及其损失函数)

多类分类 多类分类问题仍然是分类问题,所以预测y的可能结果是少量的,而不是无穷多个,且对于多类分类它>2 如上图:左侧为二分类,右侧为多分类,可以通过决策边界来划分区域 Softmax回归算法 …

记录--在高德地图实现卷帘效果

这里给大家分享我在网上总结出来的一些知识,希望对大家有所帮助 介绍 今天介绍一个非常简单的入门级小案例,就是地图的卷帘效果实现,各大地图引擎供应商都有相关示例,很奇怪高德居然没有,我看了下文档发现其实也是可以…