系列文章目录
01-玩转LangChain:从模型调用到Prompt模板与输出解析的完整指南
文章目录
- 系列文章目录
- 前言
- 一、LangChain 环境搭建与初始配置
- 1.1 安装依赖
- 1.2 环境变量加载
- 1.2.1 具体步骤
- 1.2.2 注意事项
- 1.3 初始化模型客户端
- 二、基础示例:与模型交互
- 2.1 直接调用模型
- 2.1.1 示例代码
- 2.1.2 示例输出
- 2.2 处理多行输入
- 2.2.1 示例代码
- 2.2.2 示例输出
- 三、Prompt 模板的使用
- 3.1 什么是 Prompt 模板?
- 3.2 创建 Prompt 模板
- 3.3 格式化 Prompt
- 3.3.1 示例代码
- 3.3.2 示例输出
- 3.4 调用模型
- 3.4.1 示例代码
- 3.4.2 示例输出
- 四、高级用法:信息提取与输出解析器
- 4.1 定义提取模板
- 4.2 格式化 Prompt 并调用模型
- 4.2.1 示例代码
- 4.2.2 示例输出
- 五、解析模型输出为结构化数据
- 5.1 为什么需要解析器?
- 5.2 定义解析规则
- 5.2.1 示例代码
- 5.3 获取解析格式说明
- 5.3.1 示例代码
- 5.3.2 示例输出
- 5.4 解析模型输出
- 5.4.1 示例代码
- 5.4.2 注意事项
- 六、总结与展望
- 6.1 总结
- 6.2 本文代码汇总
- 6.2.1 环境变量加载代码
- 6.2.2 初始化模型客户端
- 6.3.3 创建 Prompt 模板并调用模型
- 6.3.4 定义解析规则并解析输出
前言
在人工智能技术快速发展的背景下,大语言模型(LLM)
的应用场景越来越广泛,例如自动化文本生成、智能问答系统、知识提取等。然而,如何高效地与这些大模型交互,成为开发者面临的一大挑战。LangChain
正是为解决这一问题而生的。
LangChain 是一个开源框架,旨在帮助开发者更便捷地与大语言模型(如 OpenAI 的 GPT 系列、阿里云通义千问 Qwen)进行交互。通过 LangChain,开发者可以轻松整合模型调用、Prompt 模板管理、复杂任务链条设计以及输出解析等功能,大幅提升开发效率和应用的可靠性。
LangChain 的核心模块
LangChain 由以下核心模块组成,每个模块都有其特定的功能:
-
Model(模型)
- 提供与大语言模型交互的接口,例如 OpenAI、阿里云等的 LLM。
- 开发者可以轻松配置 API 调用和模型参数。
-
Prompt(提示词)
- 提供动态提示词模板管理功能,支持变量插值、Prompt 优化。
- 适用于创建灵活且高效的模型交互任务。
-
Chains(链条)
- 用于将多个任务步骤组合成一个链条,例如多次调用模型完成复杂的推理任务。
- 支持模块化设计,便于维护和扩展。
-
Memory(记忆)
- 提供上下文记忆功能,可以让模型在多轮对话中记住用户的输入和历史对话内容。
- 适合构建长时间、多轮交互的对话系统。
-
Output Parsers(输出解析器)
- 解析模型的返回结果,例如将文本解析为 JSON 结构,便于后续处理。
- 特别适用于信息提取、分类任务等。
-
Agents(代理)
- 集成多种工具(如 API、数据库、文件系统)与模型交互,使模型能够动态调用外部资源完成复杂任务。
- 适合构建更智能化的自动化工作流。
LangChain 的应用场景
LangChain 的灵活性和模块化设计使其广泛适用于以下场景:
- 文本生成与翻译:例如生成新闻稿、调整语气风格、翻译专业文档。
- 智能问答与知识库:构建基于文档、数据库的知识问答系统。
- 信息提取与分析:从非结构化文本中提取关键信息,例如用户评论分析、商业报告解析。
- 对话系统与聊天机器人:利用记忆模块支持上下文多轮对话,实现类似 ChatGPT 的应用。
- 自动化工作流:通过 Agents 模块集成外部工具,完成复杂的任务链,例如自动处理订单或执行 API 查询。
本文主题
本篇文章聚焦于 LangChain 的核心功能模块:Model、Prompt 和 Output Parser,并通过实际代码示例,帮助理解如何使用这些模块完成与大语言模型的交互任务。
通过阅读本文,将学会:
- 如何初始化并调用 LangChain 模型。
- 如何使用 Prompt 模板提高交互效率。
- 如何通过 Output Parser 解析模型返回的复杂数据。
一、LangChain 环境搭建与初始配置
在开始构建 LangChain 应用之前,需要完成基础环境的搭建和配置。
1.1 安装依赖
在项目环境中安装必要的 Python 包:
pip install langchain langchain-community python-dotenv openai
这些依赖包含了 LangChain 框架、环境变量管理工具 python-dotenv
和与 OpenAI 模型交互的接口。
1.2 环境变量加载
为了保护敏感信息(如 API Key 和 API URL),建议将这些信息存储在项目根目录下的一个名为 .env
的文件中。这样可以避免将敏感信息直接暴露在代码中,同时方便环境的统一配置。
1.2.1 具体步骤
-
创建
.env
文件
在项目根目录下创建一个名为.env
的文件。注意,这个文件不需要任何扩展名。
如果使用版本控制(如 Git),记得将.env
文件添加到.gitignore
中,避免敏感信息被提交到代码仓库。 -
编写
.env
文件内容
.env
文件的内容采用键值对的形式,每行一个键值对,格式如下:
阿里云通义千问(Qwen)API 配置
ALIYUN_API_KEY=你的阿里云API密钥
ALIYUN_API_URL=你的阿里云API地址,例如:https://dashscope.aliyuncs.com/compatible-mode/v1
DeepSeek API 配置
DEEPSEEK_API_KEY=你的DeepSeek API密钥
DEEPSEEK_API_URL=你的DeepSeek API地址,例如:https://api.deepseek.com
OpenAI API 配置
OPENAI_API_KEY=你的OpenAI API密钥
OPENAI_API_URL=https://api.openai.com/v1
- 键名:
ALIYUN_API_KEY
和ALIYUN_API_URL
是阿里云 API 的密钥和访问地址;DEEPSEEK_API_KEY
和DEEPSEEK_API_URL
是DeepSeek API 的密钥和地址;OPENAI_API_KEY
和OPENAI_API_URL
是OpenAI API 的密钥和地址。 - 值:具体的密钥和 URL 需要根据实际情况替换为你自己的值。
- 在代码中加载
.env
文件
使用python-dotenv
模块加载.env
文件中的内容到 Python 程序中。示例如下:
import os
from dotenv import load_dotenv
# 加载 .env 文件中的环境变量
load_dotenv()
# 获取环境变量的值
api_key = os.getenv("ALIYUN_API_KEY")
base_url = os.getenv("ALIYUN_API_URL")
1.2.2 注意事项
.env
文件应放在项目根目录下,与主代码文件(如main.py
)处于同一级目录。这样load_dotenv()
可以自动找到.env
文件。- 在使用其他环境变量(如
DEEPSEEK_API_KEY
和DEEPSEEK_API_URL
)时,直接通过os.getenv("<变量名>")
访问即可。 - 确保
.env
文件已正确加载。如果程序中获取不到变量值,请检查文件路径和格式是否正确。
通过这种方式,可以在保护敏感信息的同时,方便多环境配置和管理。
1.3 初始化模型客户端
使用 LangChain 提供的 ChatOpenAI
,连接阿里云通义千问模型(Qwen):
from langchain.chat_models import ChatOpenAI
llm = ChatOpenAI(
openai_api_key=api_key,
model_name="qwen-plus",
base_url=base_url
)
至此,环境已经完成初始化,可以开始与模型交互。
二、基础示例:与模型交互
2.1 直接调用模型
通过 invoke
方法调用模型并获取响应,以下是一个简单的示例,让模型输出一个笑话:
2.1.1 示例代码
response = llm.invoke("请讲一个笑话")
print(response.content)
2.1.2 示例输出
一个笑话:程序员的灯为什么一直亮着?因为他们在调试。哈哈!
2.2 处理多行输入
LangChain 能够轻松处理多行输入,例如将客户投诉翻译成文言文:
2.2.1 示例代码
customer_email = "搅拌机盖子坏了,奶昔飞溅了一地!"
style = "文言文,语气平静且尊重"
prompt = f"将以下文本翻译成 {style} 风格。文本: ```{customer_email}```"
response = llm.invoke(prompt)
print(response.content)
2.2.2 示例输出
吾甚恚,因搅拌机之盖骤飞,致奶昔四溅,污及厨壁。幸未伤人,惟祈妥善处理此事。
三、Prompt 模板的使用
3.1 什么是 Prompt 模板?
Prompt 模板允许我们通过动态变量插值,快速生成特定场景的 Prompt。例如:
template_string = """将用三个反引号分隔的文本,转换成{style}风格。
文本:```{text}```
"""
3.2 创建 Prompt 模板
使用 ChatPromptTemplate
构造模板对象:
from langchain.prompts import ChatPromptTemplate
prompt_template = ChatPromptTemplate.from_template(template_string)
3.3 格式化 Prompt
通过向模板插入变量生成完整的 Prompt:
3.3.1 示例代码
customer_style = "商业正式邮件语气"
customer_email = "哎呀,我真是气坏了,我的搅拌机盖子飞了出去,把我的厨房墙壁溅满了果汁!更糟糕的是,保修不包括清理厨房的费用。我现在需要你的帮助,伙计!!"
messages = prompt_template.format_messages(style=customer_style, text=customer_email)
print(messages[0].content)
3.3.2 示例输出
将用三个反引号分隔的文本,转换成商业正式邮件语气。
文本:```哎呀,我真是气坏了,我的搅拌机盖子飞了出去,把我的厨房墙壁溅满了果汁!更糟糕的是,保修不包括清理厨房的费用。我现在需要你的帮助,伙计!!```
3.4 调用模型
调用模型生成结果:
3.4.1 示例代码
response = llm.invoke(messages)
print(response.content)
3.4.2 示例输出
尊敬的客户服务团队:
您好!
我在使用贵公司的搅拌机时遇到了一些问题,希望能够得到您的协助。在最近一次操作过程中,搅拌机的盖子意外飞出,导致果汁溅满了厨房的墙壁。这一情况不仅影响了我的使用体验,也对厨房环境造成了一定的清理负担。
更让我困扰的是,根据产品的保修条款,清理相关费用似乎不在保修范围内。对此,我感到十分遗憾,并希望能与贵公司沟通,寻求一个合理的解决方案。
期待您的回复,并感谢贵公司对客户问题的关注和支持。
此致
敬礼
四、高级用法:信息提取与输出解析器
4.1 定义提取模板
通过 Prompt 模板提取文本中的特定信息(如礼物名称、送达时间和价格):
review_template = """\
对于以下文本,提取以下信息:
gift: 该商品是否作为礼物购买给他人?\
如果是,则回答 True;如果不是或未知,则回答 False。
delivery_days: 产品送达花了多少天?\
如果未找到此信息,则输出 -1。
price_value: 提取任何关于价值或价格的句子,\
并将其作为逗号分隔的 Python 列表输出。
将输出格式化为 JSON,包含以下键:
gift
delivery_days
price_value
text: {text}
"""
customer_review = """\
这个吹叶机非常棒。它有四种模式:\
蜡烛吹风、轻柔微风、城市大风和龙卷风。\
它在两天内送达,正好赶上我妻子的\
周年纪念礼物。\
我觉得我妻子非常喜欢它,以至于她都说不出话了。\
到目前为止,只有我在使用它,我每隔一天早上\
用它来清理我们草坪上的树叶。\
它比其他吹叶机稍微贵一些,\
但我觉得它的额外功能物有所值。
"""
4.2 格式化 Prompt 并调用模型
格式化 Prompt 后调用模型:
4.2.1 示例代码
messages = ChatPromptTemplate.from_template(review_template).format_messages(text=customer_review)
response = llm.invoke(messages)
print(response.content)
4.2.2 示例输出
注意,这里输出的内容其实是字符串。
{
"gift": "礼物",
"delivery_days": 2,
"price_value": "它比其他吹叶机稍微贵一些,\
但我觉得它的额外功能物有所值。"
}
五、解析模型输出为结构化数据
5.1 为什么需要解析器?
模型返回的输出通常是非结构化的字符串数据,对于后续操作(如存储、数据分析或集成到其他系统)会显得不方便。使用解析器可以直接将模型输出转换为结构化数据格式,如字典或 JSON,以便进一步处理和利用。
5.2 定义解析规则
使用 ResponseSchema
定义解析规则,指定需要从模型输出中提取的字段及其描述。以下示例中,我们提取了三个字段:gift
、delivery_days
和 price_value
。
5.2.1 示例代码
from langchain.output_parsers import ResponseSchema, StructuredOutputParser
# 定义每个字段的解析规则
gift_schema = ResponseSchema(
name="gift",
description="该商品是否作为礼物购买给他人?如果是,则回答 True,如果不是或未知,则回答 False。"
)
delivery_days_schema = ResponseSchema(
name="delivery_days",
description="产品送达花了多少天?如果未找到此信息,则输出 -1。"
)
price_value_schema = ResponseSchema(
name="price_value",
description="提取任何关于价值或价格的句子,并将其作为逗号分隔的 Python 列表输出。"
)
# 将所有规则组合成一个解析器
response_schemas = [gift_schema, delivery_days_schema, price_value_schema]
output_parser = StructuredOutputParser.from_response_schemas(response_schemas)
5.3 获取解析格式说明
为了让模型生成符合解析器要求的输出,我们需要打印并传递解析器的格式说明给模型。以下代码展示了如何获取格式说明:
5.3.1 示例代码
# 获取解析器的格式说明
format_instructions = output_parser.get_format_instructions()
print(format_instructions)
5.3.2 示例输出
{
"gift": "<True 或 False>",
"delivery_days": "<送达天数,或 -1 如果未知>",
"price_value": "<关于价值或价格的句子列表>"
}
可以将这个格式说明作为提示词的一部分,告知模型需要生成符合此格式的输出。
5.4 解析模型输出
一旦模型生成了符合解析器要求的输出,可以使用 StructuredOutputParser
将字符串解析为结构化数据。以下是示例代码:
5.4.1 示例代码
# 假设模型返回的内容如下:
response_content = """
{
"gift": true,
"delivery_days": 2,
"price_value": ["这个产品稍贵一些,但值得购买。"]
}
"""
# 使用解析器解析模型输出
output_dict = output_parser.parse(response_content)
# 示例:访问结构化数据中的某个字段
print(output_dict.get("delivery_days")) # 输出: 2
通过这种方法,可以轻松将模型的文本输出解析为结构化数据形式,方便后续操作。
5.4.2 注意事项
- 确保模型输出的格式与解析器的格式说明一致,否则解析可能会失败。
- 错误处理:当解析失败时,使用 try-catch 机制捕获异常,并根据实际需求进行处理或记录日志。
- 扩展性:可以根据具体应用场景,动态增加或调整
ResponseSchema
的字段及规则。
六、总结与展望
6.1 总结
在本篇文章中,我们详细介绍了 LangChain 的核心模块之一:Model、Prompt 和 Output Parser,并通过实际的代码示例展示了如何完成从环境搭建到模型调用、Prompt 模板使用以及输出解析的完整流程。以下是主要的学习收获:
-
模型调用:我们学习了如何通过 LangChain 初始化大语言模型(LLM),并简单高效地与其交互。
- 示例包括调用模型生成笑话以及处理客户投诉等任务。
-
Prompt 模板:通过
ChatPromptTemplate
动态生成交互提示,提高了 Prompt 的灵活性。- 示例展示了如何根据不同的场景(如商业正式邮件)动态插入变量生成 Prompt。
-
输出解析器:使用
StructuredOutputParser
将模型的非结构化字符串输出转换为结构化的 JSON 数据。- 我们定义了
ResponseSchema
来提取特定字段的信息,例如礼物购买信息、送达天数以及价格描述。 - 使用解析器极大地简化了后续的自动化处理流程。
- 我们定义了
LangChain 通过模块化设计,将复杂的 LLM 应用简化为标准化的任务步骤。无论是简单的模型调用,还是复杂的任务链条设计,LangChain 都能提供高效、灵活的解决方案。
6.2 本文代码汇总
以下是本篇文章中涉及的完整代码片段,方便读者快速复现:
6.2.1 环境变量加载代码
import os
from dotenv import load_dotenv
# 加载 .env 文件中的环境变量
load_dotenv()
# 获取环境变量
api_key = os.getenv("ALIYUN_API_KEY")
base_url = os.getenv("ALIYUN_API_URL")
6.2.2 初始化模型客户端
from langchain.chat_models import ChatOpenAI
llm = ChatOpenAI(
openai_api_key=api_key,
model_name="qwen-plus",
base_url=base_url
)
6.3.3 创建 Prompt 模板并调用模型
from langchain.prompts import ChatPromptTemplate
# 定义 Prompt 模板
template_string = """将用三个反引号分隔的文本,转换成{style}风格。
文本:```{text}```
"""
prompt_template = ChatPromptTemplate.from_template(template_string)
# 格式化 Prompt
customer_style = "商业正式邮件语气"
customer_email = "哎呀,我真是气坏了,我的搅拌机盖子飞了出去,把我的厨房墙壁溅满了果汁!更糟糕的是,保修不包括清理厨房的费用。我现在需要你的帮助,伙计!!"
messages = prompt_template.format_messages(style=customer_style, text=customer_email)
# 调用模型
response = llm.invoke(messages)
print(response.content)
6.3.4 定义解析规则并解析输出
from langchain.output_parsers import ResponseSchema, StructuredOutputParser
# 定义解析规则
gift_schema = ResponseSchema(
name="gift",
description="该商品是否作为礼物购买给他人?如果是,则回答 True;如果不是或未知,则回答 False。"
)
delivery_days_schema = ResponseSchema(
name="delivery_days",
description="产品送达花了多少天?如果未找到此信息,则输出 -1。"
)
price_value_schema = ResponseSchema(
name="price_value",
description="提取任何关于价值或价格的句子,并将其作为逗号分隔的 Python 列表输出。"
)
response_schemas = [gift_schema, delivery_days_schema, price_value_schema]
output_parser = StructuredOutputParser.from_response_schemas(response_schemas)
# 获取格式说明
format_instructions = output_parser.get_format_instructions()
print(format_instructions)
# 假设模型输出
response_content = """
{
"gift": true,
"delivery_days": 2,
"price_value": ["这个产品稍贵一些,但值得购买。"]
}
"""
# 解析输出
output_dict = output_parser.parse(response_content)
print(output_dict.get("delivery_days")) # 输出: 2
通过本文的代码示例和功能讲解,希望能帮助快速掌握 LangChain 的核心功能模块。如果有任何问题或建议,欢迎在评论区讨论交流!
标签:输出,Prompt,示例,模型,LangChain,API,玩转 From: https://blog.csdn.net/Kiradzy/article/details/144973054