文章目录
- 一.背景介绍
- 二.LangChain简介
- 2.1 常见应用场景
- 三.LangChain特点
- 3.1 优点
- 3.2 不足
- 四.LangChain功能
- 4.1 基础功能
- 4.2 功能模块
- 4.2.1 LLM和Prompts
- 4.2.2 Chain
- 4.2.3 Agent
- 4.2.4 Memory
- 4.2.5 Embedding
- 4.2.6 Models
- 4.2.7 Indexes
- 五.实战案例
- 5.1 背景需求
- 5.2 数据准备
- 5.3 数据处理
- 5.4 通过openai的Embeddings训练
- 5.5 接入聊天api
一.背景介绍
在过去几年中,大型语言模型 (LLM) 席卷了人工智能世界。随着 OpenAI 的 GPT-3 在 2020 年的突破性发布,我们见证了 LLM 的受欢迎程度稳步上升,并且随着该领域最近的进步而愈演愈烈。这些强大的 AI 模型为自然语言处理应用开辟了新的可能性,使开发人员能够在聊天机器人、问答系统、摘要工具等中创建更复杂、更像人类的交互。
当前LLM模型本身的局限
1)它只有“脑子”没有“手臂”,无法在外部世界行动,不论是搜索网页、调用 API 还是查找数据库,这些能力都无法被 OpenAI 的 API 提供;
2)甚至它的“脑子”也不完美,OpenAI 的训练数据截止至 2021 年,并且没有任何企业和个人的私有数据,这让模型只能根据自己的“记忆”回答问题,并且经常给出与事实相悖的答案。一个解决方法是在 Prompt 中将知识告诉模型,但是这往往受限于 token 数量,在 GPT-4 之前一般是 4000 个字的限制;
3)进入到围绕模型构建“真正有用”的应用时,我们更多在使用它通过思想和记忆进行推理的能力。而简单直接地通过 API 调用模型无法将推理所需的一些事实和知识给到它,即这时候模型总是缺少“Context”(广义的上下文)。
LangChain旨在帮助开发人员充分利用 LLM 的全部潜力,用于广泛的应用程序。LangChain 围绕将不同组件“链接”在一起的核心概念构建,简化了与 GPT-3、GPT-4 等 LLM 合作的过程,使得我们可以轻松创建定制的高级用例。
二.LangChain简介
LangChain 是一个框架,用于开发由语言模型驱动的应用程序,它使基于AI模型工作和应用构建的复杂部分变的更容易。LangChain可以将LLMs与外部数据源链接,也允许LMMs模型间的交互。
模块化和可组合性是 LangChain 的关键理念,它是一个 LLM 增强工具,通过粘合一系列的模块增加了 LLM 可以融入的业务逻辑复杂度。LangChain的长期目标是帮助人们更容易地构建 LLM 支持的应用,有成为第一个被广泛认可的 LLM 应用开发框架的势头。
目前基于 LangChain 开发的第一用例是建立使用私有数据的问答机器人,而大多数开发者想到要导入私有数据,第一选择就是基于 LangChain 来做。可以说 LangChain 是目前将上下文信息注入 LLM 的重要基础设施。
2.1 常见应用场景
1)自治代理
LangChain 支持自治代理的开发,如 AutoGPT 和 BabyAGI,它们是长期运行的代理,执行多个步骤以实现目标。自治代理可以应用于各种领域,如金融、医疗、智能家居等,为用户提供更智能、更便捷的服务。
2)代理模拟
LangChain 促进了沙盒环境的创建,代理可以在沙盒环境中相互交互或对事件做出反应,从而深入了解他们的长期记忆能力。代理模拟可以帮助用户更好地理解和研究代理的工作方式,从而优化代理的性能和效果。
3)个人助理
LangChain 是构建个人助理的理想之选,这些个人助理可以采取行动、记住交互并可以访问您的数据,从而提供个性化的帮助。个人助理可以应用于各种场景,如日常生活、工作等,为用户提供更智能、更个性化的服务。
4)问答
LangChain 擅长回答针对特定文档的问题,利用这些文档中的信息构建准确且相关的答案。此外,LangChain 还可以分析并回答与文档相关的问题,以帮助您更好地理解和应用文档中的信息。问答功能可以应用于各种场景,如教育、咨询、客服等,为用户提供更快速、更准确的服务。
5)聊天机器人
利用语言模型的文本生成功能,LangChain 能够创建引人入胜的聊天机器人。此外,LangChain 还可以为聊天机器人提供自定义功能和行为,以满足特定需求。聊天机器人可以应用于各种场景,如娱乐、客服、教育等,为用户提供更友好、更互动的服务。
6)查询表格数据
LangChain 提供了有关使用语言模型查询以表格格式(例如 CSV 文件、SQL 数据库或数据框)存储的数据的指南。此外,LangChain 还可以协助您创建自定义的查询功能,以更方便地访问和分析数据。查询表格数据功能可以应用于各种领域,如商业、金融、医疗等,为用户提供更快速、更方便的服务。
7)代码理解
LangChain 协助使用语言模型从 GitHub 等平台查询和理解源代码。此外,LangChain 还可以为代码理解提供自定义功能和行为,以满足特定需求。代码理解功能可以应用于各种领域,如软件开发、数据分析等,为用户提供更快速、更准确的服务。
8)与 API 交互
LangChain 使语言模型能够与 API 交互,为它们提供最新信息和根据实时数据采取行动的能力。此外,LangChain 还可以协助您创建自定义的 API 功能,以满足特定需求。与 API 交互功能可以应用于各种领域,如金融、物流、医疗等,为用户提供更快速、更智能的服务。
9)提取
LangChain 帮助从非结构化文本中提取结构化信息,简化数据分析和解释。此外,LangChain 还可以协助您创建自定义的提取功能,以更方便地访问和分析数据。提取功能可以应用于各种领域,如数据分析、信息管理等,为用户提供更快速、更准确的服务。
10)摘要
LangChain 支持将较长的文档摘要成简洁、易于消化的信息块,使其成为数据扩充的强大工具。此外,LangChain 还可以为您提供自定义的摘要功能,以更好地满足特定需求。摘要功能可以应用于各种领域,如新闻、研究、分析等,为用户提供更快速、更准确的服务。
11)评估
由于使用传统指标评估生成模型具有挑战性,LangChain 提供提示和链来帮助使用语言模型本身进行评估过程。此外,LangChain 还可以协助您创建自定义的评估功能,以更好地满足特定需求。评估功能可以帮助用户更好地了解和优化模型的性能和效果。
三.LangChain特点
3.1 优点
从开发者视角看,LangChain 是个挺友好且优美的库:
- 它非常模块化,通过 Chain、Agent、Memory 对 LLM 的抽象帮助开发者提高了构建较复杂逻辑应用的效率;而且每个模块有很好的可组合性,有点像“为 LLM 提供了本 SOP”,能实现 LLM 与其他工具的组合、Chain 与 Chain 的嵌套等逻辑;
- 它一站式集成了所有工具,从各种非结构化数据的预处理、不同的 LLM、中间的向量和图数据库和最后的模型部署,贡献者都帮 LangChain 跟各种工具完成了迅速、全面的集成。全过程一站式的集成,从非结构化数据的预处理到不同模型结果的评估,开发者所需要的工具和库 LangChain 基本都有现成的集成。
- LangChain 作为 Universal Layer 在 LLM 身上包了一层,让用户可以更自由地在多个 LLM、Embedding 引擎等之间切换,以避免单点风险和降低成本。
- LangChain 有一定的编排价值,用几行代码实现在多个 LLM 之间切换的逻辑,一个 LLM 如果服务挂掉了就自动试下一个。
- LangChain 是大模型能力“B2B2C”的一个重要中间站。
- 使用 LangChain 可能帮助很多公司避免过多的 Prompt Engineering 开发资源浪费。
- 组件化,LangChain 容易替换语言模型需要的抽象和组件。
- 自定义链,LangChain 为使用和自定义"chain"(串在一起的一系列actions)提供了开箱即用的支持。
- 更新快,LangChain 团队更新速度非常快,开发者更快体验最新的LLM功能。
- 社区支持,精彩的讨论交流区和社区支持
3.2 不足
目前的不足:
- LangChain本身还太早期,远没到成长逻辑;
- 随着 ChatGPT Plug-In 出现和 OpenAI 的更多边界延伸,LangChain 的价值可能被取代,很快像机器学习历史上的其他明星库一样隐入尘埃;
- LangChain 本身的壁垒也比较薄,是“其他开源库身上的开源库”,没有太多技术壁垒,只是替大家省下来了码的时间;
四.LangChain功能
4.1 基础功能
- LLM调用
- 多种接口支持,AI21,Anthropic,OpenAI,Cohere,HuggingFace
- Fake LLM ,用于测试
- Caching,in-mem,SQLite,Redis,SQLAlchemy
- Usage tracking
- Streaming support
- Prompt管理,模板,few-shot
- 海量的document loader支持,Airbyte json,email,Markdown,Google Drive,PDF,PowerPoint,YouTube……
- Indexing支持,低配版gpt_index
- 文档切分
- 向量化,如OpenAI Embeddings API等
- 对接向量存储与搜索,Chroma,Milvus,Pinecone,Weaviate,Qdrant
- Chains
- LLMChain:prompt格式化 + LLM调用
- 各类工具Chain,API,Math,Bash,web request,SQL db……
- LangChainHub
- Chat支持,ChatGPT API之前和之后
4.2 功能模块
4.2.1 LLM和Prompts
LangChain在这一层让切换底层使用的 LLM、管理 Prompt、优化 Prompt 变得非常容易。此处最基础的能力是 Prompt Template。一个 Prompt 通常由 Instructions、Context、Input Data(比如输入的问题)和 Output Indicator(通常是对输出数据格式的约定)。使用 LangChain 的 Prompt Template 很好地定义各个部分,同时将 Input Data 留作动态输入项。
from langchain import PromptTemplate
template = """ Answer the question based on the context below. If the question cannot be answered using the information provided answer with "I don't know".
Context:Large Language Models(LLMs) are the latest models used in NLP.Their superior performance over smaller models has made them incredibly userful for developers building NLP enabled applications.These models can be accessed via HuggingFace's 'transformers' library,via OpenAI using the 'openai' library,and via Cohere using the 'cohere' library.
Quesion:{query}
Answer:"""
prompt_template = PromptTemplate(
input_variables = ["query"],
template = template
)
4.2.2 Chain
当一个应用稍微复杂点,单纯依赖 Prompting 已经不够了,这时候需要将 LLM 与其他信息源或者 LLM 给连接起来,比如调用搜索 API 或者是外部的数据库等。我们可以把 Chain 理解为任务。一个 Chain 就是一个任务,当然也可以像链条一样,一个一个的执行多个链。LangChain 在这一层提供了与大量常用工具的集成(比如上文的 Pincone)、常见的端到端的 Chain。
4.2.3 Agent
Agent 封装的逻辑和赋予 LLM 的“使命”比 Chain 要更复杂。在 Chain 里,数据的来源和流动方式相对固定。而在Agent 里,LLM 可以自己决定采用什么样的行动、使用哪些工具,这些工具可以是搜索引擎、各类数据库、任意的输入或输出的字符串,甚至是另一个 LLM、Chain 和 Agent。
Agent深度体现了LLM思维链的能力,充当了交通指挥员或者路由者的角色。
4.2.4 Memory
Memory是在Chain/Agent调用之间持久化状态的概念,记录之前的对话内容,将其放到 Prompt 的 Context 里。记录有很多的 tricks,比如直接传递上下文,或者对之前的对话内容进行总结,然后将总结放 Prompt 里。
比如,LangChain的Entity Memory能力可以为 LLM 和用户聊天时 Entity 提供长期记忆上下文的能力:
4.2.5 Embedding
用于衡量文本的相关性。这个也是 OpenAI API 能实现构建自己知识库的关键所在。
他相比 fine-tuning 最大的优势就是,不用进行训练,并且可以实时添加新的内容,而不用加一次新的内容就训练一次,并且各方面成本要比 fine-tuning 低很多。
4.2.6 Models
LangChain 提供对各种模型类型和模型集成的支持。它使得我们能够轻松地集成和使用不同的语言模型,从而增强应用程序的功能。例如,我们可以使用 LangChain 将自然语言处理模型集成到我们的机器学习模型中,从而提高模型的准确性和性能。
4.2.7 Indexes
为了增强语言模型的力量,LangChain 帮助我们将它们与我们自己的文本数据有效地结合起来。它提供了索引和搜索数据源的最佳实践。使用 LangChain,我们可以轻松地搜索和查找文本数据,以便更好地训练和优化模型。
五.实战案例
5.1 背景需求
由于ChatGPT的训练数据库仅更新至2021年,因此对于2022年的发生的事情如果不做训练,那么它肯定是不知道的,如果对它提问2022年世界杯冠军是谁,肯定回答不出来。
2022年世界杯冠军是谁
得到回复是
作为AI语言模型,我没有预测未来的能力,也无法预测2022年世界杯的冠军。预测体育比赛结果需要考虑很多因素,包括球队实力、球员状态、比赛场地和气候等等,这些因素都是非常难以预测的。最终的结果只能由比赛的实际情况决定。
为了让大模型能够回答对该问题,我们可以通过应用LangChain来训练OpenAI模型。
5.2 数据准备
在网上找一段2022年世界杯的新闻描述,并将其内容保存为“2022世界杯.txt”。
在卡塔尔当地时间2022年12月18日,梅西带领阿根廷男足在2022年世界杯决赛中通过点球大战以7-5击败法国男足,为阿根廷队夺得队史的第三座世界杯冠军奖杯,这也是阿根廷队时隔36年再度捧起世界杯冠军奖杯。夺冠后梅西深情亲吻大力神杯,尽情宣泄心中的激动和喜悦。值得一提的是,阿根廷夺得2022世界杯冠军之后,梅西等阿根廷球员纷纷在个人社交媒体发表了对于夺冠的喜悦之情。对于梅西而言,个人足球职业生涯再无遗憾,而对于年轻的阿根廷小将们则意味着职业生涯奠定了一个非常好的开端。而对于梅西的老帮手迪马利亚来说,他改变了自己从阿根廷国家队退役的决定,希望能够以冠军身份继续为潘帕斯雄鹰效力。阿根廷队本来是准备在首都布宜诺斯艾利斯的市中心共和国广场进行庆祝,但是由于球迷实在过于热情,最终庆祝仪式被迫提前结束,球员们改为直升飞机绕城飞行庆祝,但这也依然不能熄灭球迷的火热激情。所有看到阿根廷夺冠球员的球迷都激动万分,有的球迷更是兴奋的直接泣不成声,场面十分令人动容。梅西在夺得2022世界杯冠军之后也是情绪激动,以世界杯冠军结束自己的世界杯旅程,对于梅西而言毫无疑问是最完美的结局,而梅西的家人们也在比赛现场见证了梅西的巅峰时刻,一家人的幸福合影令人羡慕。
5.3 数据处理
import jieba as jb
from langchain.llms import OpenAI
from langchain.document_loaders import DirectoryLoader, PyPDFLoader
from langchain.embeddings.openai import OpenAIEmbeddings
from langchain.text_splitter import TokenTextSplitter
from langchain.vectorstores import Chroma
from langchain.chains import ConversationalRetrievalChain, ChatVectorDBChain
from langchain.chat_models import ChatOpenAI
file='2022世界杯.txt'
my_file = f"./data/{file}"
# 从本地读取文件
with open(my_file, "r", encoding='utf-8') as f:
data = f.read()
# 对内容按空格进行分词处理
cut_data = " ".join(w for w in list(jb.cut(data)))
# 保存分词后的内容
cut_file = f"./data/cut/cut_{file}"
with open(cut_file, 'w') as f:
f.write(cut_data)
f.close()
print("写入文件完成")
分词后的新闻文本如下:
在 卡塔尔 当地 时间 2022 年 12 月 18 日 , 梅西 带领 阿根廷 男足 在 2022 年 世界杯 决赛 中 通过 点球 大战 以 7 - 5 击败 法国 男足 , 为 阿根廷队 夺得 队史 的 第三座 世界杯 冠军 奖杯 , 这 也 是 阿根廷队 时隔 36 年 再度 捧起 世界杯 冠军 奖杯 。 夺冠 后梅西 深情 亲吻 大力神杯 , 尽情 宣泄 心中 的 激动 和 喜悦 。 值得一提的是 , 阿根廷 夺得 2022 世界杯 冠军 之后 , 梅西 等 阿根廷 球员 纷纷 在 个人 社交 媒体 发表 了 对于 夺冠 的 喜悦之情 。 对于 梅西 而言 , 个人 足球 职业生涯 再 无 遗憾 , 而 对于 年轻 的 阿根廷 小将 们 则 意味着 职业生涯 奠定 了 一个 非常 好 的 开端 。 而 对于 梅西 的 老 帮手 迪 马利亚 来说 , 他 改变 了 自己 从 阿根廷 国家队 退役 的 决定 , 希望 能够 以 冠军 身份 继续 为 潘帕斯 雄鹰 效力 。 阿根廷队 本来 是 准备 在 首都 布宜诺斯艾利斯 的 市中心 共和国 广场 进行 庆祝 , 但是 由于 球迷 实在 过于 热情 , 最终 庆祝 仪式 被迫 提前结束 , 球员 们 改为 直升飞机 绕城 飞行 庆祝 , 但 这 也 依然 不能 熄灭 球迷 的 火热 激情 。 所有 看到 阿根廷 夺冠 球员 的 球迷 都 激动 万分 , 有 的 球迷 更是 兴奋 的 直接 泣不成声 , 场面 十分 令人 动容 。 梅西 在 夺得 2022 世界杯 冠军 之后 也 是 情绪 激动 , 以 世界杯 冠军 结束 自己 的 世界杯 旅程 , 对于 梅西 而言 毫无疑问 是 最 完美 的 结局 , 而梅西 的 家 人们 也 在 比赛 现场 见证 了 梅西 的 巅峰 时刻 , 一家人 的 幸福 合影 令人羡慕 。
5.4 通过openai的Embeddings训练
# 通过目录加载器读取分词数据
loader = DirectoryLoader('./data/cut', glob='**/*.txt')
docs = loader.load()
# 这里要进行分块处理,因为openai的接口是有限制的,chunk_size表示块大小,chunk_overlap表示块重叠部分多少
text_splitter = TokenTextSplitter(chunk_size=1000, chunk_overlap=0)
doc_texts = text_splitter.split_documents(docs)
print(doc_texts)
>>> [Document(page_content='在 卡塔尔 当地 时间 2022 年 12 月 18 日 , 梅西 带领 阿根廷 男足 在 2022 年 世界杯 决赛 中 通过 点球 大战 以 7 - 5 击败 法国 男足 , 为 阿根廷队 夺得 队史 的 第三座 世界杯 冠军 奖杯 , 这 也 是 阿根廷队 时隔 36 年 再度 捧起 世界杯 冠军 奖杯 。 夺冠 后梅西 深情 亲吻 大力神杯 , 尽情 宣泄 心中 的 激动 和 喜悦 。 值得一提的是 , 阿根廷 夺得 2022 世界杯 冠军 之后 , 梅西 等 阿根廷 球员 纷纷 在 个人 社交 媒体 发表 了 对于 夺冠 的 喜悦之情 。 对于 梅西 而言 , 个人 足球 职业生涯 再 无 遗憾 , 而 对于 年轻 的 阿根廷 小将 们 则 意味着 职业生涯 奠定 了 一个 非常 好 的 开端 。 而 对于 梅西 的 老 帮手 迪 马利亚 来说 , 他 改变 了 自己 从 阿根廷 国家队 退役 的 决定 , 希望 能够 以 冠军 身份 继续 为 潘帕斯 雄鹰 效力 。 阿根廷队 本来 是 准备 在 首都 布宜诺斯艾利斯 的 市中心 共和国 广场 进行 庆祝 , 但是 由于 球迷 实在 过于 热情 , 最终 庆祝 仪式 被迫 提前结束 , 球员 们 改为 直升飞机 绕城 飞行 庆祝 , 但 这 也 依然 不能 熄灭 球迷 的 火热 激情 。 所有 看到 阿根廷 夺冠 球员 的 球迷 都 激动 万分 , 有 的 球迷 �', metadata={'source': 'data/cut/cut_2022世界杯.txt'}), Document(page_content='��是 兴奋 的 直接 泣不成声 , 场面 十分 令人 动容 。 梅西 在 夺得 2022 世界杯 冠军 之后 也 是 情绪 激动 , 以 世界杯 冠军 结束 自己 的 世界杯 旅程 , 对于 梅西 而言 毫无疑问 是 最 完美 的 结局 , 而梅西 的 家 人们 也 在 比赛 现场 见证 了 梅西 的 巅峰 时刻 , 一家人 的 幸福 合影 令人羡慕 。', metadata={'source': 'data/cut/cut_2022世界杯.txt'})]
通过调用openai的embeddings接口,去训练数据,训练以后,接口会返回一组向量数据。langchain也提供封装了很多种向量数据库。网上很多是用Pinecone来保存,这个是一个三方的服务商来着,要申请。这里通过Chroma保存向量数据。Chroma是一款开源的向量数据库,可以来替换Pinecone。通过chroma把向量数据储存在本地目录。
# 调用openai的embeddings接口,然后保存返回的向量数据
os.environ["OPENAI_API_KEY"] = "这里替换成自己在openai申请的api key"
embeddings = OpenAIEmbeddings(openai_api_key=os.environ["OPENAI_API_KEY"])
# 指定保存目录
vectordb = Chroma.from_documents(doc_texts, embeddings, persist_directory="./data/cut")
vectordb.persist()
>>> Using embedded DuckDB with persistence: data will be stored in: ./data/cut
它会在./data/cut目录下生成chroma-collections.parquet文件和chroma-embeddings.parquet文件,
./data/cut/index/目录下生成相关索引。到此,数据模型训练完毕。
5.5 接入聊天api
模型训练完了,现在可以再次向ChatGPT发起提问2022年世界杯冠军。
## 创建聊天对象
chain = ChatVectorDBChain.from_llm(OpenAI(temperature=0,
model_name="gpt-3.5-turbo"), vectordb,
return_source_documents=True)
# 聊天对话,获取回复
def get_answer(question):
chat_history=[]
result=chain({
"question":question,
"chat_history":chat_history
})
return result["answer"]
question = '谁带阿根廷男足赢了2022年世界杯?'
print(get_answer(question))
梅西带领阿根廷男足赢了2022年世界杯。