跳到主要内容
LangChain 入门指南:大模型应用开发基础 | 极客日志
Python AI
LangChain 入门指南:大模型应用开发基础 综述由AI生成 LangChain 是构建语言模型应用的开源框架。介绍 LangChain 的安装配置、核心组件 Chain 与 Prompt 的使用,以及 Memory 记忆机制的四种实现方式(Buffer、Window、Summary、VectorStore)。通过代码示例演示如何串联 LLM 与提示词,实现具备上下文记忆的对话应用,帮助开发者快速上手大模型应用开发。文章还补充了环境变量安全、异常处理及 Token 成本控制等最佳实践建议。
人间过客 发布于 2025/2/7 更新于 2026/6/2 34 浏览LangChain 入门指南:大模型应用开发基础
什么是 LangChain
LangChain 是一个用于开发由语言模型驱动的应用程序的框架,致力于简化 AI 模型应用的开发。简单来说,LangChain 就是一个帮助开发者轻松完成 AI 模型应用开发的工具库,目前支持 Python 和 JavaScript 两个版本,它集成了多种大语言模型及第三方 API。
对于使用 LangChain,建议将其视为一个第三方库来使用。完成一件事情,往往不止使用一个工具,LangChain 就是其中一个关键工具,用于连接模型与业务逻辑。
注:本文主要适用于 v0.1.x 版本的基础概念讲解,v0.2.x 版本在依赖解耦上做了部分调整,具体细节建议查阅官方最新文档。
为什么选择 LangChain
在学习大语言模型的过程中,深刻理解了一个道理:"AI 没有护城河"。对于大语言模型,OpenAI 公司最开始也不清楚在大量的数据集与算力的加持下会产生什么样的效果,最终 ChatGPT 得以诞生。时至今日,市面上各大公司都在人工智能行业奋力追赶,造成了现在的 AI 时代,如阿里的通义千问、科大讯飞的星火认知大模型、百度的文心一言、腾讯的混元大模型等优秀的模型。
事实训练 AI 的各种算法、项目都是开源的,人人都能训练各种模型,各大公司比拼的不是训练 AI 的算法而是算力与数据集。在个人开发者的角度来说,想要拼过市面上的大公司显然是不可能的,而且自己训练的模型受限于各种原因,效果都达不到理想效果。既然别人有训练好的模型,这种情况下就不要在一头扎进训练模型的路上了,直接使用别人的模型吧。LangChain 集成了市面绝大部分模型,简单易上手。
一、安装 LangChain
打开终端(cmd 或 terminal),输入命令安装环境。
pip install langchain==0.1.7
pip install langchain-community
pip install langchain_openai
pip install python-dotenv
使用 LLM 进行问答
from langchain_openai import ChatOpenAI
llm = ChatOpenAI(temperature=0.7 )
text = "什么是 langchain"
print (llm.invoke(text))
二、实现一个简单的 LangChain 应用
在 VSCode 或者 PyCharm 中编码均可,创建好文件后开始编写代码。
1. 导入相关包
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 PromptTemplate
import
2. 实例化一个 LLM,定义它的角色 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 (res['text' ])
3. 创建一个 .env 文件 为了安全起见,建议将敏感信息存储在 .env 文件中,而不是硬编码在代码里。
OPENAI_API_BASE ="你的代理地址"
OPENAI_API_KEY ="你的 apikey"
4. 直接运行 运行 python [文件名].py 或者在 IDE 中直接运行。
三、Chain 的意义 Chain,翻译成链的意思,顾名思义将其他东西链接起来,串联起来,链式链接。
在 LangChain 中,单独使用 LLM 进行问答是没有问题的,但是对于 LLM 大模型,Prompt 提示词、Memory 记忆组件、Agent 代理等单独的模块如何串联起来需要一个解决办法。LangChain 中 Chain 的意义就在于将这些模块串联起来,实现一个完善的大模型应用。
如何使用 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 = LLMChain(
llm=llm,
prompt=prompt,
memory=memory,
verbose=True
)
chain.invoke("我分手了,我好难过,呜呜呜" )
chain.invoke("你是谁?" )
chain.invoke("今天的天气真好啊" )
res = chain.invoke("我最开始跟你聊的什么呢?" )
print (res['text' ])
Chain 是一个基类 Chain 位于 langchain.chains 目录下的 base.py 文件中,从文件命名就可以看出这是一个基类,其中包含了一些关键属性和方法。对于属性,包含 memory、callbacks、verbose 等。而对于方法,既有抽象方法,又有具体实现的方法。抽象方法定义了所有派生 Chain 类必须遵循的接口,具体实现的方法为所有派生类提供了通用的功能。
总的来说,这个基类为 LangChain 创建了一个灵活的架构,使得开发者能够通过创建新的 Chain 子类来快速扩展和自定义功能。
属性 在 langchain.chains 的 base.py 文件中定义的 Chain 类有几个关键属性值。分别为 memory、callbacks、callback_manager、verbose、tags 和 metadata。
memory : 这是一个可选的 BaseMemory 对象,默认为 None。Memory 类在每个链条开始和结束时被调用。开始时,Memory 加载变量并在链中传递它们。最后,它保存任何返回的变量。
callbacks : 这是一个可选的回调处理器列表(或回调管理器),默认为 None。在链条的生命周期中,会始终调用回调处理器,从 on_chain_start 开始,到 on_chain_end 或 on_chain_error 结束。
verbose : 决定是否在详细模式下运行。在详细模式下,一些中间日志将打印到控制台。默认值是 langchain.verbose。
tags : 这是与链条相关联的可选标签列表,默认为无。这些标签会与每次对此链条的调用相关联,并作为参数传递给 callbacks 中定义的处理器。可以用这些标签来识别特定的链条实例及其用例。
metadata : 这是与链条相关联的可选元数据,默认为无。这些元数据会与每次对此链条的调用相关联,并作为参数传递给 callbacks 中定义的处理器。可以用这些元数据来识别特定的链条实例及其用例。
总结来说,这些属性让 Chain 类具有了更多灵活性并能够支持更复杂的操作,包括内存管理、回调处理,以及详细模式的控制等等。
方法 Chain 接口设计得易于创建具有以下特性的应用程序:
有状态 (Stateful) : 向任何 Chain 添加 Memory,使它具有状态。这意味着 Chain 可以在多次运行之间记住并持久化其数据。
可观察(Observable) : 将 Callbacks 传递给 Chain,以执行额外的功能,例如在组件调用的主流程之外进行日志记录。这让你可以更好地监控和管理链条的运行过程。
可组合(Composable) : Chain API 足够灵活,可以容易地将 Chains 与其他组件(包括其他 Chains)结合在一起。这样,你可以自由地设计和构建复杂的流程。
call : Chains 是可调用的。__call__ 方法是执行 Chain 的主要方式。该方法接收一个字典作为输入,并返回一个字典作为输出。这种方式让你能对输入和输出进行精细的控制。
invoke : 这是一个便捷方法,它将输入作为参数接收,返回字符串作为输出。这个方法只能被部分 Chain 使用,并且其返回结果不如 __call__ 丰富。
总结 Chain 在 LangChain 应用中是一个不可缺少的重要工具,是各个模块联系的纽带。将各种模块链接起来就可以实现一个个更加有趣的大模型应用。
四、什么是 Prompts 在大语言模型(LLM)中,Prompt 指的是模型生成内容时所需要的输入,它可以包含模型生成内容时所需要的背景知识、用户期望模型执行的指令、模型输出需要遵循的格式等。
为什么要用 Prompts 在我们平常使用大语言模型进行问答时,他回答的内容往往就是他默认的回答格式,首先、然后、最后这种。如果想要让大语言模型回答时在开头添加固定开场白,或是结尾添加固定结束词,又或是让他只回答某一方面的问题,跟这个方面不相关的问题不回答等效果,就需要使用 prompts 来提示或者限制大语言模型的回答内容、特定的回答风格,或者是将大模型水平范围回答限制到垂直范围(回答内容准确性可能不高,高准确性使用外挂数据库更好)。
提示词的组成 从原理上看,提示词主要由一个任务描述、一个输入文本、输出指示组成。他们会一同发送给大语言模型,而大语言模型就会根据提示词进行回答。
提示词公式 = 角色 + 角色技能 + 任务关键词 + 任务目标 + 任务背景 + 任务范围 + 任务结果判定 + 限制条件 + 输出格式 + 输出量
LangChain 中的提示词 LangChain 提供了几个提示词模板,可以自定义提示词模板。
from langchain.prompts import (
ChatPromptTemplate,
PromptTemplate,
SystemMessagePromptTemplate,
AIMessagePromptTemplate,
HumanMessagePromptTemplate,
)
from langchain.schema import (
AIMessage,
HumanMessage,
SystemMessage
)
用聊天消息作为输入,每条消息都与一个角色有关,是一个消息列表。
SystemMessagePromptTemplate, AIMessagePromptTemplate, HumanMessagePromptTemplate 是分别用于创建不同角色提示词的模板。
LangChain 提供了几个对象,区分不同角色:
HumanMessage: 来自人类/用户的 ChatMessage
AIMessage: 来自 AI/助手的 ChatMessage
SystemMessage: 来自系统的 ChatMessage
FunctionMessage: 来自函数调用的 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 是一个对大语言模型回答进行提示或是限制的主要内容,提示词对大语言模型的作用力度与大语言模型的智慧程度有关,程度越高,提示词的效果就会越好。
五、什么是 Memory 存储对话历史中的信息的能力称之为'记忆',这种工具可以单独使用,也可以无缝的集成到一条链中。记忆的存储长度是程序执行到结束,执行一次的所有记忆。
记忆组件需要支持读取和写入。每条链定义了核心执行逻辑,期望某些输入,一些来自用户,一些来自记忆组件,在一次与 LLM 的交互中,链与记忆组件交互两次:
读取记忆 : 将之前的交互内容进行读取,放入到本次交互中。
写入记忆 : 将本次的交互内容写入到记忆当中。
为什么需要使用记忆组件 在 LangChain 中,直接使用 llm.invoke 进行大模型对话,LLM 的记忆范围只有程序执行到运行结束,再次对话就是新的开始,没有以前的记忆内容。当提问'我刚刚说了什么'时,他就回答不出前一次的交互内容。
而使用记忆组件就可以让 LLM 有记忆能力,能够将进行上下文联想。让与大模型对话时有和真人对话的感觉。
使用步骤 需要四个部件组合起来使用:大模型、提示词模板、链、记忆组件。
实例化一个 LLM
定义记忆组件
创建提示词模板
使用链将他们链接起来
四种记忆组件
1. ConversationBufferMemory 会话缓冲区 如实的记录列表中记录的对话历史消息,并且是记录所有的历史消息。随着历史记录的增加,运行会越来越慢,直到大模型无法处理。适用于交互次数少,输入输出字符量不大的情况下。
2. ConversationBufferWindowMemory 会话缓冲窗口 持续记录对话历史,但只使用最近的 k 个交互。确保缓存大小不会过大,运行速度比较稳定。
3. ConversationSummaryMemory 会话摘要 随着时间的推移总结对话内容,并且将摘要存储在记忆中,需要的时候将摘要注入提示词或链中。缓存不会过大,运行稳定,但是运行速度比 ConversationBufferWindowMemory 慢很多,因为他在写入记忆的时候,做了一个摘要的操作。这使得她可以记住很长的交互记忆,不过随着交互的增加,摘要的内容不断迭代更换,使得某些内容会遗失。
4. VectorStoreRetrieverMemory 向量存储 将记忆存储在向量存储中,并在每次调用时查询前 K 个最"显著"的文档。与大多数其他记忆类不同的是,它不明确跟踪交互的顺序。在这种情况下,"文档"是先前对话片段。这对于提及 AI 在对话中早些时候被告知的相关信息可能是有用的。
总结 对于一个聊天机器人,在对话中可能需要进行上下文联想、分析的操作,或者是进行一个情景对话,记忆组件都是不可或缺的重要组成部分。在 LangChain 的早期版本中,记忆组件运行速度非常的慢,如果作为一个请求内容返回给前端百分百会超时,在稳定的版本出来之后就流畅很多了,应用到实际的应用中也更具有体验感。在这样的条件下,对大模型进行角色定制,对话中这个角色的丰富度就会高很多。也能做出更多更有意思的聊天机器人。
六、最佳实践与安全建议 在实际开发中,除了掌握基础组件外,还需要注意以下几点以确保应用的健壮性。
1. 环境变量安全 永远不要将 API Key 硬编码在代码中并提交到 Git 仓库。务必使用 .env 文件配合 python-dotenv 加载,并将 .env 文件加入 .gitignore 中。
2. 异常处理 网络请求可能会失败,API 可能会返回错误。建议在调用 llm.invoke 前后增加 try-except 块,捕获可能的 Timeout 或 AuthenticationError,并给出友好的用户提示。
3. Token 成本控制 在使用 Memory 组件时,尤其是 ConversationBufferMemory,随着对话轮数增加,Token 消耗会线性增长。对于长对话场景,建议使用 ConversationSummaryMemory 或定期清理历史对话,以控制成本并避免超出上下文窗口限制。
4. 提示词工程优化 Prompt 的质量直接影响输出效果。建议采用结构化提示词,明确角色、任务、约束条件和输出格式。可以通过 Few-Shot Prompting(少样本提示)的方式,在 Prompt 中提供几个示例,引导模型模仿特定风格。
结语 LangChain 为大模型应用开发提供了标准化的接口和强大的组合能力。通过理解 Chain、Prompt 和 Memory 的核心机制,开发者可以快速构建具备上下文感知能力的智能应用。随着技术的演进,建议持续关注官方文档更新,探索 Agent 和 RAG(检索增强生成)等高级特性,以应对更复杂的生产场景需求。
相关免费在线工具 RSA密钥对生成器 生成新的随机RSA私钥和公钥pem证书。 在线工具,RSA密钥对生成器在线工具,online
Mermaid 预览与可视化编辑 基于 Mermaid.js 实时预览流程图、时序图等图表,支持源码编辑与即时渲染。 在线工具,Mermaid 预览与可视化编辑在线工具,online
随机西班牙地址生成器 随机生成西班牙地址(支持马德里、加泰罗尼亚、安达卢西亚、瓦伦西亚筛选),支持数量快捷选择、显示全部与下载。 在线工具,随机西班牙地址生成器在线工具,online
curl 转代码 解析常见 curl 参数并生成 fetch、axios、PHP curl 或 Python requests 示例代码。 在线工具,curl 转代码在线工具,online
Base64 字符串编码/解码 将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online
Base64 文件转换器 将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online