1. 开篇:LangChain组件全景图
LangChain的核心工作流程:
本文将通过4个精心设计的Demo,带你逐步掌握这些核心组件:
2. 什么是LangChain?为什么要学习它?
LangChain是一个开源框架,专为开发基于大语言模型(LLM)的应用程序而设计。简单来说,它是连接大语言模型与各种应用场景的框架,适合面向AI上层应用的开发者。
LangChain的核心价值
如果你已经尝试过直接调用OpenAI的API,你可能会发现:虽然一个简单的请求很容易实现,但构建完整的应用流程却需要大量的重复工作。LangChain在传统API调用的基础上抽象出了多个关键组件:
- 提示词管理和模板化不同类型的模型交互方式输出解析和格式化组件连接和链式调用
一句话,LangChain简化了大模型应用开发流程。
谁适合学习LangChain?
- 已经了解基本Python语法的开发者对AI应用开发感兴趣,但不想深入了解模型底层细节的开发者希望快速构建基于大语言模型应用的创业团队需要在现有系统中集成AI能力的工程师
环境准备
关于环境搭建,你可以参考我之前的文章:无需购买OpenAI Token,LangChain开发本地化部署全攻略。本文将直接进入实战内容。
3. 与大模型的基础交互(Demo 1)
你将学到:如何使用两种不同方式与大语言模型进行基础交互
你可以用它做:构建任何需要AI文本生成或对话功能的应用基础
LangChain提供了两种主要的方式与大语言模型交互:LLMs
和ChatModels
。这两种方式针对不同的使用场景,让我们分别来看看。
2.1 使用LLMs进行基础交互
LLMs代表传统的语言模型调用方式,以字符串作为输入并返回字符串的语言模型。
from langchain_community.llms import Ollama# 初始化llama3模型# 默认连接到localhost:11434,如果Ollama运行在其他地址,可以通过base_url参数指定llm = Ollama(model="llama3.2")# 简单的文本生成response = llm.invoke("介绍一下llama3模型")print(response)
输出结果:
2.2 使用ChatModels进行对话交互
ChatModels则更像是与ChatGPT这样的对话模型交互,专门为多轮对话设计的抽象层。它接收一系列消息(可以有不同的角色,如system、user、assistant
),然后生成下一条消息。这种方式更适合多轮对话和需要角色设定的场景。
ChatModels 的输入是 message 列表,它不是一个纯文本的 prompt,而是一组有 “角色”和“内容” 的消息组成的列表,包含系统和用户输入。
[ {"role": "system", "content": "你是一个幽默的讲笑话机器人"}, {"role": "user", "content": "给我讲个冰淇淋的笑话"} ]
from langchain_core.messages import HumanMessage, SystemMessagefrom langchain_community.llms import Ollamallm = Ollama(model="llama3.2")# 构建对话消息messages = [ SystemMessage(content="你是一个编程高手"), HumanMessage(content="用Python实现冒泡排序算法")]# 调用模型获取结果response = llm.invoke(messages)print(response)
输出结果:
2.3 LLMs与ChatModels的使用场景对比
模型类型 | 适用场景 | 典型应用 |
---|---|---|
LLMs | 单次文本生成,无需多轮交互 | 文章生成、代码补全、文本摘要 |
ChatModels | 多轮对话,需要角色设定 | 客服聊天机器人、用户咨询 |
理解了如何与大模型进行基础交互后,我们面临的下一个问题是:如何更好地构建提示词,让AI能够理解我们的意图?这就是提示词模板要解决的问题。
4.提示词模板的构建与使用(Demo 2)
你将学到:如何使用结构化模板创建高质量、可复用的提示词
你可以用它做:标准化你的AI交互,实现一致性输出,支持动态变量注入
在实际应用中,我们经常需要根据用户输入动态生成提示词,而不是使用硬编码的固定提示。LangChain提供了一系列提示词模板工具,让这个过程变得更加简单和可复用。
3.1 为什么需要提示词模板?
通常LLM应用程序不会直接将用户输入传递给大模型。通常,会先将用户输入添加到一个更大的文本片段中,称为提示模板,该模板提供了有关特定任务的附加上下文。然后用这个完整的提示词模版和大模型交互。
想象你正在开发一个客服Bot,每次用户提问时,你需要:
- 设定AI的角色(专业客服)加入业务背景信息(产品知识)加入用户的具体问题可能还需要指定回复格式
如果每次都手动拼接字符串,不仅代码难以维护,而且容易出错。提示词模板正是为了解决这个问题。
3.2 基础提示词模板:PromptTemplate
最简单的提示词模板是PromptTemplate
,它允许你定义一个带有变量的字符串模板:
from langchain.prompts import PromptTemplatetemplate = "你是{product}品牌的手机专业客服。请回答以下问题:{question}"prompt = PromptTemplate.from_template(template)#构建完整的模版提示词formatted_prompt = prompt.format(product="OPPO",question="如何重置手机?")print(formatted_prompt )
输出:
3.3 聊天提示词模板:各种MessagePromptTemplate
前面提到过,ChatModels包括系统消息、用户消息等。所以我们需要更复杂的提示词结构,LangChain提供了相应的模板:
你可以看下coze平台中使用大模型节点也会要求系统提示词 + 用户提示词
from langchain_community.chat_models import ChatOllamafrom langchain.prompts import ( PromptTemplate ChatPromptTemplate, ChatMessagePromptTemplate, SystemMessagePromptTemplate, HumanMessagePromptTemplate)# 系统提示词模版template = "你是一个翻译专家,你擅长将 {input_language} 翻译成 {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])# 格式化输入,生成完整对话的消息message = chat_prompt.format_messages(input_language="English", output_language="中文",text ="I like swimming")# 使用llama3模型,执行对话并生成内容llm = ChatOllama(model="llama3.2")response = llm.invoke(message)print(message)print(response.content)
输出:
[SystemMessage(content='你是一个翻译专家,你擅长将 English 翻译成 中文', additional_kwargs={}, response_metadata={}), HumanMessage(content='I like swimming', additional_kwargs={}, response_metadata={})]我喜欢游泳。
3.4 提示词对比
项目 | PromptTemplate | ChatPromptTemplate.from_messages |
---|---|---|
目标模型类型 | 用于 LLMs(单轮问答模型) | 用于 ChatModels(多轮对话模型) |
提示词结构 | 单段文本模板 | 多角色消息(system/user/ai)列表 |
语境模拟能力 | 一般 | 强,适合模拟完整对话历史 |
输出格式支持 | 纯字符串 | 职责分明的消息结构(如 ChatMessage 类型) |
你可以这样理解:
PromptTemplate
更像是在构造一个 完整文本 prompt,适合“你一句我一句”的问答模型;ChatPromptTemplate
是在构造一段 模拟对话的消息结构,是面向现代对话模型的最佳方式。
掌握了提示词模板后,我们还需要解决一个问题:如何处理AI返回的文本,将其转换为程序可用的结构化数据?这就是输出解析器要解决的问题。
5. OutputParsers输出解析器的应用(Demo 3)
- 你将学到:如何将LLM的文本输出转换为程序可直接使用的结构化数据你可以用它做:解析结构化表格、分类标签、JSON数据、列表等,提升应用的可靠性
大语言模型返回的通常是一段自然语言文本,但在实际应用中,我们经常需要结构化数据,比如列表、map或自定义对象。OutputParser正是为此而设计的。
5.1 为什么需要输出解析器?
- 模型输出不稳定:即使有明确指示,模型的输出格式也可能略有不同容错性差:正则表达式容易因小变化而失效提示词耦合:提示词与解析逻辑紧密耦合
5.2 基本列表解析器
from langchain.prompts import PromptTemplatefrom langchain_community.chat_models import ChatOllamafrom langchain.output_parsers import CommaSeparatedListOutputParser# 初始化模型和输出解析器llm = ChatOllama(model="llama3.2")# 指定输出解析器,会使用“逗号分隔”来解析为列表parser = CommaSeparatedListOutputParser()# 告诉模型如何输出,提升格式准确率format_instructions = parser.get_format_instructions()# 构建提示模板,注意需要填入变量 format_instructionsprompt = PromptTemplate( template=""" 列出5种早餐食物,用英文逗号分隔,一行列出,不要加编号或多余解释。 {format_instructions}""",input_variables=["format_instructions"])# 生成最终提示文本prompt_text = prompt.format(format_instructions=format_instructions)# 模型调用response = llm.invoke(prompt_text)# 解析输出为 Python 列表parsed_output = parser.parse(response.content)print(parsed_output)
输出:
- 虽然我们用了OutputParser把大模型的输出结果转化为我们指定的格式,比如列表。但是
CommaSeparatedListOutputParser()
是一个专用解析器,用于将 逗号分隔的文本(如 "苹果, 鸡蛋, 牛奶"
)转换为 Python 的 list
类型。所以这就需要通过提示词告诉大模型生成我们想要的格式 ,所以你会看到PromptTemplate
的设置比之前讲的要复杂,目的就是告诉大模型按我们要求的来生成,否则解析会出错。提示词不严谨,生成的内容就会格式不对,那么这一步就会错parser.parse(response.content)
输出解析器的真正威力在于与提示词模板的结合使用,让整个过程更加流畅:现在我们已经掌握了三个核心组件:模型交互、提示词模板和输出解析器
。下一步,我们要学习如何将它们组合成一个完整的处理链。
6. 构建完整的LLMChain(Demo 4)
你将学到:如何将前面所有组件整合成一个端到端的处理流程
你可以用它做:构建完整的AI应用流程,实现从用户输入到可用输出的全流程处理
5.1 LLMChain的基本概念
LLMChain代表一个完整的处理链条,从用户输入到最终输出。它适用于那些流程相对固定、步骤明确的任务。它的主要组成部分包括:
- 提示词模板(Prompt)语言模型(LLM或Chat Model)可选的输出解析器(Output Parser)
5.3 构建LLMChain
我们可以将输出解析器与链结合,获得结构化输出:
from langchain_core.output_parsers import JsonOutputParserfrom langchain_core.prompts import PromptTemplatefrom langchain_community.chat_models import ChatOllamallm = ChatOllama(model="llama3.2")# 初始化 JSON 输出解析器,用于将模型返回的字符串结果解析成结构化的 Python 对象parser = JsonOutputParser()# 获取解析器推荐的格式化说明,这里是json格式format_instructions = parser.get_format_instructions()# 构建提示词模板,定义提示词结构# 其中使用了两个变量:genre(电影类型)和 format_instructions(格式化说明)prompt = PromptTemplate( input_variables=["genre", "format_instructions"], template="""你是一位电影推荐专家。请根据以下电影类型推荐一部电影,给出推荐理由,{format_instructions}电影类型:{genre}""")# 填充提示词模版,生成 PromptValue 对象prompt_value = prompt.format_prompt( genre="科幻", format_instructions=format_instructions)# 调用模型response = llm.invoke(prompt_value)# 使用 JSON 输出解析器,将模型返回的内容转换成 jsonparsed = parser.parse(response.content)print(parsed)
输出:
7. 总结
四个Demo的核心关系
这四个Demo展示了从基础到进阶的LangChain使用流程:
- 基础交互:与大模型直接对话的基本方式提示词模板:结构化AI交互的输入部分输出解析器:将AI输出转为程序可用的结构化数据LLMChain:将上述组件整合成完整流程
LangChain应用的基本流程:
LangChain的核心思想
LangChain本质是把大模型调用流程组件化,这种组件化思想带来了关键优势:
- 模块化设计:每个组件职责明确,可独立开发和测试可复用性:组件可在多个项目中重复使用可扩展性:可轻松替换组件而不影响整体架构标准化:提供标准接口,简化开发流程