LangChain 入门指南
什么是 LangChain
LangChain 是一个强大的框架,旨在帮助开发人员使用语言模型构建端到端的应用程序。它提供了一套工具、组件和接口,可简化创建由大型语言模型 (LLM) 和聊天模型提供支持的应用程序的过程。LangChain 可以轻松管理与语言模型的交互,将多个组件链接在一起,并集成额外的资源,例如 API 和数据库。
如何使用 LangChain?
要使用 LangChain,开发人员首先要导入必要的组件和工具,例如 LLMs, chat models, agents, chains, 内存功能。这些组件组合起来创建一个可以理解、处理和响应用户输入的应用程序。
LangChain 为特定用例提供了多种组件,例如个人助理、文档问答、聊天机器人、查询表格数据、与 API 交互、提取、评估和汇总。
LangChain 的模型
LangChain model 是一种抽象,表示框架中使用的不同类型的模型。LangChain 中的模型主要分为三类:
- LLM(大型语言模型):这些模型将文本字符串作为输入并返回文本字符串作为输出。它们是许多语言模型应用程序的支柱。
- 聊天模型 (Chat Model):聊天模型由语言模型支持,但具有更结构化的 API。他们将聊天消息列表作为输入并返回聊天消息。这使得管理对话历史记录和维护上下文变得容易。
- 文本嵌入模型 (Text Embedding Models):这些模型将文本作为输入并返回表示文本嵌入的浮点列表。这些嵌入可用于文档检索、聚类和相似性比较等任务。
LangChain 的主要特点
LangChain 旨在为六个主要领域的开发人员提供支持:
- LLM 和提示:LangChain 使管理提示、优化它们以及为所有 LLM 创建通用界面变得容易。此外,它还包括一些用于处理 LLM 的便捷实用程序。
- 链 (Chain):这些是对 LLM 或其他实用程序的调用序列。LangChain 为链提供标准接口,与各种工具集成,为流行应用提供端到端的链。
- 数据增强生成:LangChain 使链能够与外部数据源交互以收集生成步骤的数据。例如,它可以帮助总结长文本或使用特定数据源回答问题。
- Agents:Agents 让 LLM 做出有关行动的决定,采取这些行动,检查结果,并继续前进直到工作完成。LangChain 提供了代理的标准接口,多种代理可供选择,以及端到端的代理示例。
- 内存:LangChain 有一个标准的内存接口,有助于维护链或代理调用之间的状态。它还提供了一系列内存实现和使用内存的链或代理的示例。
- 评估:很难用传统指标评估生成模型。这就是为什么 LangChain 提供提示和链来帮助开发者自己使用 LLM 评估他们的模型。
快速入门指南
安装与环境设置
首先,安装 LangChain。只需运行以下命令:
pip install langchain
由于 LangChain 经常需要与模型提供者、数据存储、API 等集成,我们将设置我们的环境。在这个例子中,我们将使用 OpenAI 的 API,因此我们需要安装他们的 SDK:
pip install openai
接下来,让我们在终端中设置环境变量:
export OPENAI_API_KEY="your_api_key_here"
或者,如果您更喜欢在 Jupyter notebook 或 Python 脚本中工作,您可以像这样设置环境变量:
import os
os.environ["OPENAI_API_KEY"] = "your_api_key_here"
构建语言模型应用程序:LLM
from langchain.llms import OpenAI
llm = OpenAI(temperature=0.9)
text = "What would be a good company name for a company that makes colorful socks?"
print(llm(text))
Prompt Templates: 管理 LLMs 的 Prompts
一般来说我们不会直接把输入给模型,而是将输入和一些别的句子连在一起,形成 prompts 之后给模型。
例如之前根据产品取名的用例,在实际服务中我们可能只想输入"socks",那么"What would be a good company name for a company that makes"就是我们的 template。
from langchain.prompts import PromptTemplate
prompt = PromptTemplate(
input_variables=["product"],
template="What is a good name for a company that makes {product}?",
)
print(prompt.format(product="colorful socks"))
构建语言模型应用程序:Chat Model
还可以使用聊天模型。这些是语言模型的变体,它们在底层使用语言模型但具有不同的界面。聊天模型使用聊天消息作为输入和输出,而不是'文本输入、文本输出'API。
要完成聊天,您需要将一条或多条消息传递给聊天模型。LangChain 目前支持 AIMessage、HumanMessage、SystemMessage 和 ChatMessage 类型。您将主要使用 HumanMessage、AIMessage 和 SystemMessage。
from langchain.chat_models import ChatOpenAI
from langchain.schema import (
AIMessage,
HumanMessage,
SystemMessage
)
chat = ChatOpenAI(temperature=0)
result = chat([HumanMessage(content="Translate this sentence from English to French. I love programming.")])
print(result)
使用 generate 为多组消息生成完成。这将返回一个带有附加消息参数的 LLMResult:
from langchain.chat_models import ChatOpenAI
from langchain.schema import (
AIMessage,
HumanMessage,
SystemMessage
)
batch_messages = [
[
SystemMessage(content="You are a helpful assistant that translates English to Chinese."),
HumanMessage(content="Translate this sentence from English to Chinese. I love programming.")
],
[
SystemMessage(content="You are a helpful assistant that translates English to Chinese."),
HumanMessage(content="Translate this sentence from English to Chinese. I love artificial intelligence.")
],
]
result = chat.generate(batch_messages)
print(result)
print(result.llm_output['token_usage'])
对于聊天模型,您还可以通过使用 MessagePromptTemplate 来使用模板。您可以从一个或多个 MessagePromptTemplates 创建 ChatPromptTemplate。
from langchain.chat_models import ChatOpenAI
from langchain.prompts.chat import (
ChatPromptTemplate,
SystemMessagePromptTemplate,
HumanMessagePromptTemplate,
)
chat = ChatOpenAI(temperature=0)
template="You are a helpful assistant that translates {input_language} to {output_language}."
system_message_prompt = SystemMessagePromptTemplate.from_template(template)
human_template="{text}"
human_message_prompt = HumanMessagePromptTemplate.from_template(human_template)
chat_prompt = ChatPromptTemplate.from_messages([system_message_prompt, human_message_prompt])
response = chat(chat_prompt.format_prompt(input_language="English", output_language="Chinese", text="I love programming.").to_messages())
print(response)
探索 Memory 与链
探索将内存与使用聊天模型初始化的链和代理一起使用。这与 Memory for LLMs 的主要区别在于我们可以将以前的消息保留为它们自己唯一的内存对象,而不是将它们压缩成一个字符串。
from langchain.prompts import (
ChatPromptTemplate,
MessagesPlaceholder,
SystemMessagePromptTemplate,
HumanMessagePromptTemplate
)
from langchain.chains import ConversationChain
from langchain.chat_models import ChatOpenAI
from langchain.memory import ConversationBufferMemory
prompt = ChatPromptTemplate.from_messages([
SystemMessagePromptTemplate.from_template("The following is a friendly conversation between a human and an AI. The AI is talkative and provides lots of specific details from its context. If the AI does not know the answer to a question, it truthfully says it does not know."),
MessagesPlaceholder(variable_name="history"),
HumanMessagePromptTemplate.from_template("{input}")
])
llm = ChatOpenAI(temperature=0)
memory = ConversationBufferMemory(return_messages=True)
conversation = ConversationChain(memory=memory, prompt=prompt, llm=llm)
print(conversation.predict(input="Hi there!"))
print(conversation.predict(input="I'm doing well! Just having a conversation with an AI."))
print(conversation.predict(input="Tell me about yourself."))
信息抽取
根据输入的内容抽取关键信息。
from langchain.prompts import PromptTemplate
from langchain.llms import OpenAIChat
from langchain.chains import LLMChain
import os
import openai
os.environ['OPENAI_API_KEY'] = 'your_api_key_here'
text = "北京市(Beijing),简称'京',古称燕京、北平,是中华人民共和国首都、直辖市、国家中心城市、超大城市,国务院批复确定的中国政治中心、文化中心、国际交往中心、科技创新中心,中国历史文化名城和古都之一。截至 2020 年,北京市下辖 16 个区,总面积 16410.54 平方千米。2022 年末,北京市常住人口 2184.3 万人。"
llm = OpenAIChat(model_name="gpt-3.5-turbo")
fact_extraction_prompt = PromptTemplate(
input_variables=["text_input"],
template="从下面的本文中提取关键事实。尽量使用文本中的统计数据来说明事实:\n\n {text_input}"
)
fact_extraction_chain = LLMChain(llm=llm, prompt=fact_extraction_prompt)
facts = fact_extraction_chain.run(text)
print(facts)
文档问答 (RAG)
import os
from langchain.embeddings.openai import OpenAIEmbeddings
from langchain.vectorstores import Chroma
from langchain.text_splitter import TokenTextSplitter
from langchain.llms import OpenAI
from langchain.chains import ChatVectorDBChain
from langchain.document_loaders import DirectoryLoader
import jieba as jb
import time
files=['xxx.txt','xxx.txt']
start_time = time.time()
for file in files:
my_file=f"./data/{file}"
try:
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', encoding='utf-8') as f:
f.write(cut_data)
except FileNotFoundError:
print(f"File {file} not found.")
loader = DirectoryLoader(,glob=)
docs = loader.load()
text_splitter = TokenTextSplitter(chunk_size=, chunk_overlap=)
doc_texts = text_splitter.split_documents(docs)
api_key = os.environ.get(, )
embeddings = OpenAIEmbeddings(openai_api_key=api_key)
vectordb = Chroma.from_documents(doc_texts, embeddings, persist_directory=)
vectordb.persist()
chain = ChatVectorDBChain.from_llm(OpenAI(temperature=, model_name=), vectordb, return_source_documents=)
():
chat_history = []
result = chain({: question, : chat_history})
result[]
question =
(get_answer(question))
end_time = time.time()
run_time = end_time - start_time
(run_time)
如果问题及答案在文档中会返回正确的结果,如果不在文本中,则会返回错误信息。
常见问题与解决方案
编码问题
可能出现的问题:
UnicodeEncodeError: 'gbk' codec can't encode character '\u0643' in position 58: illegal multibyte sequence
如果是 VSCode 编辑器可能是电脑设置的问题,解决方法:win+i > 时间和语言 > 时间 日期 区域格式设置 > 其他时间 日期 区域格式设置 > 区域更改日期,时间或数字格式 > 管理 > 更改系统区域设置。
Beta 打钩能解决这个问题,这个是针对 txt 文本(其他文档没试过),出现问题不一定是代码的问题,这个打钩可能会影响电脑其他应用乱码(大部分应用不会)。
版本兼容性问题
可能出现的问题:
ImportError: cannot import name 'load_tools' from 'langchain.agents'
这通常是因为 Python 版本过旧或 LangChain 版本不匹配。建议将 python 版本升级到了 3.9 或更高,并确保安装了最新版本的 langchain 依赖包。
安全最佳实践
- API Key 管理:永远不要将 API Key 硬编码在代码中并提交到版本控制系统。建议使用环境变量或
.env 文件配合 python-dotenv 库。
- 输入验证:对用户输入进行清理和验证,防止 Prompt Injection 攻击。
- 速率限制:在生产环境中实施速率限制,以防止滥用和超额费用。
总结
本文介绍了 LangChain 的核心概念、安装配置及基础应用场景。通过 LLM、Chat Model、Memory 和 RAG 等模块的组合,可以快速构建智能对话系统和知识问答应用。在实际开发中,注意处理编码兼容性、版本依赖及安全性问题,将有助于提升应用的稳定性和用户体验。