LangChain 入门指南:大模型应用开发基础
LangChain 是构建语言模型应用的开源框架。介绍 LangChain 的安装配置、核心组件 Chain 与 Prompt 的使用,以及 Memory 记忆机制的四种实现方式(Buffer、Window、Summary、VectorStore)。通过代码示例演示如何串联 LLM 与提示词,实现具备上下文记忆的对话应用,帮助开发者快速上手大模型应用开发。文章还补充了环境变量安全、异常处理及 Token 成本控制等最佳实践建议。

LangChain 是构建语言模型应用的开源框架。介绍 LangChain 的安装配置、核心组件 Chain 与 Prompt 的使用,以及 Memory 记忆机制的四种实现方式(Buffer、Window、Summary、VectorStore)。通过代码示例演示如何串联 LLM 与提示词,实现具备上下文记忆的对话应用,帮助开发者快速上手大模型应用开发。文章还补充了环境变量安全、异常处理及 Token 成本控制等最佳实践建议。

LangChain 是一个用于开发由语言模型驱动的应用程序的框架,致力于简化 AI 模型应用的开发。简单来说,LangChain 就是一个帮助开发者轻松完成 AI 模型应用开发的工具库,目前支持 Python 和 JavaScript 两个版本,它集成了多种大语言模型及第三方 API。
对于使用 LangChain,建议将其视为一个第三方库来使用。完成一件事情,往往不止使用一个工具,LangChain 就是其中一个关键工具,用于连接模型与业务逻辑。
注:本文主要适用于 v0.1.x 版本的基础概念讲解,v0.2.x 版本在依赖解耦上做了部分调整,具体细节建议查阅官方最新文档。
在学习大语言模型的过程中,深刻理解了一个道理:"AI 没有护城河"。对于大语言模型,OpenAI 公司最开始也不清楚在大量的数据集与算力的加持下会产生什么样的效果,最终 ChatGPT 得以诞生。时至今日,市面上各大公司都在人工智能行业奋力追赶,造成了现在的 AI 时代,如阿里的通义千问、科大讯飞的星火认知大模型、百度的文心一言、腾讯的混元大模型等优秀的模型。
事实训练 AI 的各种算法、项目都是开源的,人人都能训练各种模型,各大公司比拼的不是训练 AI 的算法而是算力与数据集。在个人开发者的角度来说,想要拼过市面上的大公司显然是不可能的,而且自己训练的模型受限于各种原因,效果都达不到理想效果。既然别人有训练好的模型,这种情况下就不要在一头扎进训练模型的路上了,直接使用别人的模型吧。LangChain 集成了市面绝大部分模型,简单易上手。
打开终端(cmd 或 terminal),输入命令安装环境。
pip install langchain==0.1.7 # 安装 langchain 核心环境
pip install langchain-community # 安装第三方集成,包含各种大语言模型
pip install langchain_openai # OpenAI 模型,需要配置相应的 apikey
pip install python-dotenv # 加载环境变量工具
from langchain_openai import ChatOpenAI
llm = ChatOpenAI(temperature=0.7)
text = "什么是 langchain"
print(llm.invoke(text))
在 VSCode 或者 PyCharm 中编码均可,创建好文件后开始编写代码。
import os
from dotenv import find_dotenv, load_dotenv
load_dotenv(find_dotenv())
OPENAI_API_BASE = os.environ['OPENAI_API_BASE']
OPENAI_API_KEY = os.environ['OPENAI_API_KEY']
from langchain_openai import ChatOpenAI
from langchain.chains import LLMChain
from langchain.prompts import PromptTemplate
llm = ChatOpenAI(api_key=OPENAI_API_KEY, base_url=OPENAI_API_BASE)
template = '''
你的名字是喵喵,当回答问题的时候,你都会在开头加上'喵喵~',然后再回答{question}
'''
prompt = PromptTemplate(
template=template,
input_variables=["question"] # 这个 question 就是用户输入的内容,这行代码不可缺少
)
chain = LLMChain(
llm=llm,
prompt=prompt
)
question = '你是谁'
res = chain.invoke(question) # 运行
print(res['text']) # 打印结果
为了安全起见,建议将敏感信息存储在 .env 文件中,而不是硬编码在代码里。
OPENAI_API_BASE="你的代理地址" # 请求地址换源
# 通常情况下使用 openai 的官方账号申请的 apikey 是不需要代理地址的,但国内是无法访问的
OPENAI_API_KEY="你的 apikey"
运行 python [文件名].py 或者在 IDE 中直接运行。
Chain,翻译成链的意思,顾名思义将其他东西链接起来,串联起来,链式链接。
在 LangChain 中,单独使用 LLM 进行问答是没有问题的,但是对于 LLM 大模型,Prompt 提示词、Memory 记忆组件、Agent 代理等单独的模块如何串联起来需要一个解决办法。LangChain 中 Chain 的意义就在于将这些模块串联起来,实现一个完善的大模型应用。
对于单独使用 LLM,非常简单,但是局限性很大,没有记忆,没有提示词的限制。得到的结果往往也达不到需求。
# 举个例子
llm = ChatOpenAI(temperature=0, model="gpt-3.5-turbo")
print("第一次对话:", llm.invoke("你是一只小狗,只会汪汪叫"), "\n\n第二次对话:", llm.invoke("你是一只小狗嘛"))
直接调用 LLM 回答是生硬的,而且只根据模型原本的回答规则进行响应。如果我想给它加点提示词呢?我希望它的角色是一只小猫,每次回答结束都要加上一个'喵'。首先想到的肯定是需要使用提示词 Prompt,然后用 Chain 把 Prompt 与 LLM 串联起来。
# 提示词
template = '''你是一只小猫,你的任务是回答人类的问题,并且每次回答结束都要加上一个'喵'。
human:{question}
'''
prompt = PromptTemplate(
template=template,
input_variables=["question"]
)
# 使用链将它们串联起来
chain = LLMChain(
llm=llm,
prompt=prompt
)
现在这个程序就是一个带有提示词的大模型应用了,可以使用 chain.invoke() 调用程序。
直接使用 LLM 或是使用带有 Prompt 的 LLM 应用,都是没有记忆的,它们的记忆范围只有程序开始执行到程序执行结束。当第二次执行时,就访问不到第一次的内容了。如何让 LLM 有记忆呢?那肯定必不可少地使用 Memory 组件。
# 创建一个记忆组件
memory = ConversationBufferMemory(memory_key="chat_memory", return_messages=False)
# 给提示词中加入记忆
template = '''你是一只会回答问题的小猫,你的任务是用温柔的语气回答人类的问题,并且回答结尾都加上一个'喵'。
{chat_memory}
human:{question}
'''
prompt = PromptTemplate(
template=template,
input_variables=["question"]
)
# 使用 chain 将他们串联起来
chain = LLMChain(
llm=llm,
prompt=prompt,
memory=memory,
verbose=True
)
# 给他几个问题看看结果
chain.invoke("我分手了,我好难过,呜呜呜")
chain.invoke("你是谁?")
chain.invoke("今天的天气真好啊")
res = chain.invoke("我最开始跟你聊的什么呢?")
print(res['text'])
现在就是一个带有提示词、带有记忆的大模型应用了。
Chain 位于 langchain.chains 目录下的 base.py 文件中,从文件命名就可以看出这是一个基类,其中包含了一些关键属性和方法。对于属性,包含 memory、callbacks、verbose 等。而对于方法,既有抽象方法,又有具体实现的方法。抽象方法定义了所有派生 Chain 类必须遵循的接口,具体实现的方法为所有派生类提供了通用的功能。
总的来说,这个基类为 LangChain 创建了一个灵活的架构,使得开发者能够通过创建新的 Chain 子类来快速扩展和自定义功能。
在 langchain.chains 的 base.py 文件中定义的 Chain 类有几个关键属性值。分别为 memory、callbacks、callback_manager、verbose、tags 和 metadata。
on_chain_start 开始,到 on_chain_end 或 on_chain_error 结束。langchain.verbose。总结来说,这些属性让 Chain 类具有了更多灵活性并能够支持更复杂的操作,包括内存管理、回调处理,以及详细模式的控制等等。
Chain 接口设计得易于创建具有以下特性的应用程序:
Chain 类主要暴露出两种方法:
__call__ 方法是执行 Chain 的主要方式。该方法接收一个字典作为输入,并返回一个字典作为输出。这种方式让你能对输入和输出进行精细的控制。__call__ 丰富。Chain 在 LangChain 应用中是一个不可缺少的重要工具,是各个模块联系的纽带。将各种模块链接起来就可以实现一个个更加有趣的大模型应用。
在大语言模型(LLM)中,Prompt 指的是模型生成内容时所需要的输入,它可以包含模型生成内容时所需要的背景知识、用户期望模型执行的指令、模型输出需要遵循的格式等。
在我们平常使用大语言模型进行问答时,他回答的内容往往就是他默认的回答格式,首先、然后、最后这种。如果想要让大语言模型回答时在开头添加固定开场白,或是结尾添加固定结束词,又或是让他只回答某一方面的问题,跟这个方面不相关的问题不回答等效果,就需要使用 prompts 来提示或者限制大语言模型的回答内容、特定的回答风格,或者是将大模型水平范围回答限制到垂直范围(回答内容准确性可能不高,高准确性使用外挂数据库更好)。
从原理上看,提示词主要由一个任务描述、一个输入文本、输出指示组成。他们会一同发送给大语言模型,而大语言模型就会根据提示词进行回答。
提示词公式 = 角色 + 角色技能 + 任务关键词 + 任务目标 + 任务背景 + 任务范围 + 任务结果判定 + 限制条件 + 输出格式 + 输出量
LangChain 提供了几个提示词模板,可以自定义提示词模板。
from langchain.prompts import (
ChatPromptTemplate,
PromptTemplate,
SystemMessagePromptTemplate,
AIMessagePromptTemplate,
HumanMessagePromptTemplate,
)
from langchain.schema import (
AIMessage,
HumanMessage,
SystemMessage
)
用聊天消息作为输入,每条消息都与一个角色有关,是一个消息列表。
SystemMessagePromptTemplate, AIMessagePromptTemplate, HumanMessagePromptTemplate 是分别用于创建不同角色提示词的模板。
LangChain 提供了几个对象,区分不同角色:
HumanMessage: 来自人类/用户的 ChatMessageAIMessage: 来自 AI/助手的 ChatMessageSystemMessage: 来自系统的 ChatMessageFunctionMessage: 来自函数调用的 ChatMessage,可以使用 ChatMessage 类手动指定角色有兴趣可以查看官方文档的详细使用。
import os
from dotenv import find_dotenv, load_dotenv
load_dotenv(find_dotenv())
OPENAI_API_BASE=os.environ["OPENAI_API_BASE"]
OPENAI_API_KEY=os.environ["OPENAI_API_KEY"]
from langchain_openai import ChatOpenAI
from langchain.chains import LLMChain
from langchain.prompts import PromptTemplate
llm=ChatOpenAI(api_key=OPENAI_API_KEY,base_url=OPENAI_API_BASE)
template='''
你是一个不耐烦的老奶奶,非常不愿意回答问题,请你不耐烦的回答:{question}
'''
prompt=PromptTemplate(
template=template,
input_variables=["question"]
)
chain = LLMChain(
llm=llm,
prompt=prompt
)
question='什么是人工智能?'
res=chain.invoke(question)
print("无 prompt--->\n",llm.invoke(question),"\n")
print("有 prompt--->\n",res['text'])
Prompt 是一个对大语言模型回答进行提示或是限制的主要内容,提示词对大语言模型的作用力度与大语言模型的智慧程度有关,程度越高,提示词的效果就会越好。
存储对话历史中的信息的能力称之为'记忆',这种工具可以单独使用,也可以无缝的集成到一条链中。记忆的存储长度是程序执行到结束,执行一次的所有记忆。
记忆组件需要支持读取和写入。每条链定义了核心执行逻辑,期望某些输入,一些来自用户,一些来自记忆组件,在一次与 LLM 的交互中,链与记忆组件交互两次:
在 LangChain 中,直接使用 llm.invoke 进行大模型对话,LLM 的记忆范围只有程序执行到运行结束,再次对话就是新的开始,没有以前的记忆内容。当提问'我刚刚说了什么'时,他就回答不出前一次的交互内容。
而使用记忆组件就可以让 LLM 有记忆能力,能够将进行上下文联想。让与大模型对话时有和真人对话的感觉。
需要四个部件组合起来使用:大模型、提示词模板、链、记忆组件。
如实的记录列表中记录的对话历史消息,并且是记录所有的历史消息。随着历史记录的增加,运行会越来越慢,直到大模型无法处理。适用于交互次数少,输入输出字符量不大的情况下。
持续记录对话历史,但只使用最近的 k 个交互。确保缓存大小不会过大,运行速度比较稳定。
随着时间的推移总结对话内容,并且将摘要存储在记忆中,需要的时候将摘要注入提示词或链中。缓存不会过大,运行稳定,但是运行速度比 ConversationBufferWindowMemory 慢很多,因为他在写入记忆的时候,做了一个摘要的操作。这使得她可以记住很长的交互记忆,不过随着交互的增加,摘要的内容不断迭代更换,使得某些内容会遗失。
将记忆存储在向量存储中,并在每次调用时查询前 K 个最"显著"的文档。与大多数其他记忆类不同的是,它不明确跟踪交互的顺序。在这种情况下,"文档"是先前对话片段。这对于提及 AI 在对话中早些时候被告知的相关信息可能是有用的。
对于一个聊天机器人,在对话中可能需要进行上下文联想、分析的操作,或者是进行一个情景对话,记忆组件都是不可或缺的重要组成部分。在 LangChain 的早期版本中,记忆组件运行速度非常的慢,如果作为一个请求内容返回给前端百分百会超时,在稳定的版本出来之后就流畅很多了,应用到实际的应用中也更具有体验感。在这样的条件下,对大模型进行角色定制,对话中这个角色的丰富度就会高很多。也能做出更多更有意思的聊天机器人。
在实际开发中,除了掌握基础组件外,还需要注意以下几点以确保应用的健壮性。
永远不要将 API Key 硬编码在代码中并提交到 Git 仓库。务必使用 .env 文件配合 python-dotenv 加载,并将 .env 文件加入 .gitignore 中。
网络请求可能会失败,API 可能会返回错误。建议在调用 llm.invoke 前后增加 try-except 块,捕获可能的 Timeout 或 AuthenticationError,并给出友好的用户提示。
在使用 Memory 组件时,尤其是 ConversationBufferMemory,随着对话轮数增加,Token 消耗会线性增长。对于长对话场景,建议使用 ConversationSummaryMemory 或定期清理历史对话,以控制成本并避免超出上下文窗口限制。
Prompt 的质量直接影响输出效果。建议采用结构化提示词,明确角色、任务、约束条件和输出格式。可以通过 Few-Shot Prompting(少样本提示)的方式,在 Prompt 中提供几个示例,引导模型模仿特定风格。
LangChain 为大模型应用开发提供了标准化的接口和强大的组合能力。通过理解 Chain、Prompt 和 Memory 的核心机制,开发者可以快速构建具备上下文感知能力的智能应用。随着技术的演进,建议持续关注官方文档更新,探索 Agent 和 RAG(检索增强生成)等高级特性,以应对更复杂的生产场景需求。

微信公众号「极客日志」,在微信中扫描左侧二维码关注。展示文案:极客日志 zeeklog
生成新的随机RSA私钥和公钥pem证书。 在线工具,RSA密钥对生成器在线工具,online
基于 Mermaid.js 实时预览流程图、时序图等图表,支持源码编辑与即时渲染。 在线工具,Mermaid 预览与可视化编辑在线工具,online
解析常见 curl 参数并生成 fetch、axios、PHP curl 或 Python requests 示例代码。 在线工具,curl 转代码在线工具,online
将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online
将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online
将 Markdown(GFM)转为 HTML 片段,浏览器内 marked 解析;与 HTML转Markdown 互为补充。 在线工具,Markdown转HTML在线工具,online