使用LangChain构建标准化AI应用开发框架
LangChain 是一个用于开发大语言模型(LLM)应用程序的框架,它提供了构建AI应用的标准化工具和组件。LangChain提供了更高层次的抽象,主要组件如下:
from langchain_core.prompts import PromptTemplate # 提示模板
from langchain_community.llms import OpenAI # 模型抽象
from langchain.chains import LLMChain # 任务链
from langchain.memory import ConversationBufferMemory # 记忆管理
from langchain.agents import initialize_agent, Tool # 智能体工具
from langchain.document_loaders import TextLoader # 文档加载
from langchain.embeddings import OpenAIEmbeddings # 向量嵌入
from langchain_core.output_parsers import PydanticOutputParser, StrOutputParser # 输出解析器
适合复杂应用开发,LangChain的核心价值在于降低复杂AI应用的开发门槛,提供标准化的最佳实践。
LangChain 工作流步骤
from langchain_core.prompts import ChatPromptTemplate
from langchain_openai import ChatOpenAI
from langchain_core.output_parsers import StrOutputParser
# 1. 创建提示模板
prompt_template = ChatPromptTemplate.from_messages([
("system", "你是一个专业的{domain}专家。"),
("human", "请解释一下:{question}")
])
# 2. 初始化模型
model = ChatOpenAI(model="gpt-3.5-turbo")
# 3. 创建链
chain = prompt_template | model | StrOutputParser()
# 4. 正确调用
result = chain.invoke({
"domain": "物理学",
"question": "什么是量子纠缠?"
})
print("回答结果:")
print(result)
详细解释这段代码
1.构建提示模板
prompt_template = ChatPromptTemplate.from_messages([
SystemMessagePromptTemplate.from_template("你是一个专业的{domain}专家。"),
HumanMessagePromptTemplate.from_template("请解释一下:{question}")
])
1. 代码功能
这段代码创建了一个对话提示模板,用于动态生成发送给大语言模型的提示信息。它定义了一个包含两条消息的对话结构:
- 第一条是系统消息,用于设定AI助手的角色和行为
- 第二条是用户消息,包含用户的具体问题
2. 组件分解
ChatPromptTemplate
- 这是对话提示模板的主要类
- 用于构建包含多条消息(系统、人类、AI等)的复杂提示
from_messages()是一个类方法,用于从一系列消息模板创建提示模板
SystemMessagePromptTemplate.from_template("你是一个专业的{domain}专家。")
- 创建一个系统消息模板
- 系统消息用于设定AI的角色、行为和上下文
{domain}是一个变量占位符,运行时会被实际值替换- 例如:如果
domain="物理学",生成的消息将是:“你是一个专业的物理学专家。”
HumanMessagePromptTemplate.from_template("请解释一下:{question}")
- 创建一个用户消息模板(在LangChain中,"Human"代表用户)
- 用户消息包含具体的查询或指令
{question}是另一个变量占位符- 例如:如果
question="量子力学",生成的消息将是:“请解释一下:量子力学”
3. 模板结构
最终生成的提示结构会是这样的:
System: 你是一个专业的{domain}专家。
Human: 请解释一下:{question}
4. 如何使用
这个模板需要提供具体的值来填充占位符:
# 填充模板变量
filled_prompt = prompt_template.invoke({
"domain": "物理学",
"question": "量子纠缠"
})
# 输出结果会是:
# [
# SystemMessage(content='你是一个专业的物理学专家。'),
# HumanMessage(content='请解释一下:量子纠缠')
# ]
5. 实际应用场景
这个模板通常用于构建一个可重用的问答系统:
# 组合成处理链
chain = (
{"domain": lambda x: "物理学", "question": RunnablePassthrough()}
| prompt_template
| model # 假设已经初始化了语言模型
| StrOutputParser()
)
# 使用链来获取答案
result = chain.invoke("量子纠缠")
print(result) # 输出模型对量子纠缠的解释
总结
这段代码创建了一个参数化的对话模板:
- 定义角色:通过系统消息设定AI的专业领域
- 接收问题:通过用户消息模板接收具体问题
- 支持动态替换:使用
{domain}和{question}占位符实现模板的复用性 - 标准化格式:生成LangChain标准的消息对象,便于后续处理
这种模式使得你可以轻松创建不同领域的专家问答系统,只需改变 domain 参数即可。
2. 模型初始化
这段代码注释说明了如何初始化和使用 LangChain 的聊天模型。我来详细解释:
1. 首先安装必要的库
pip install langchain-openai python-dotenv
2. 完整的模型初始化代码
import os
from langchain_openai import ChatOpenAI
from dotenv import load_dotenv
# 加载环境变量(从 .env 文件读取API密钥)
# load_dotenv() 是一个来自 python-dotenv 库的函数,它的作用是从 .env 文件加载环境变量到系统的环境变量中。
load_dotenv()
# 方式1:最基本初始化
model = ChatOpenAI(model="gpt-4")
# 方式2:带更多参数的初始化
model = ChatOpenAI(
model="gpt-4", # 模型名称
temperature=0.7, # 创造性程度 (0-1)
max_tokens=1000, # 最大输出token数
timeout=30, # 超时时间(秒)
max_retries=2, # 最大重试次数
api_key=os.getenv("OPENAI_API_KEY") # 显式传递API密钥
)
# 方式3:使用gpt-4-turbo(推荐)
model = ChatOpenAI(model="gpt-4-turbo-preview")
3. 环境变量设置
创建 .env 文件:
OPENAI_API_KEY=sk-your-openai-api-key-here
OPENAI_API_BASE=https://api.openai.com/v1 # 可选,如果是Azure或其他代理
或者在代码中设置:
import os
os.environ["OPENAI_API_KEY"] = "sk-your-openai-api-key-here"
4. 完整的示例代码
import os
from langchain_openai import ChatOpenAI
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.output_parsers import StrOutputParser
from dotenv import load_dotenv
# 加载环境变量
load_dotenv()
class ProductManagerAgent:
def __init__(self):
# 初始化模型
self.model = ChatOpenAI(
model="gpt-4-turbo-preview",
temperature=0.1, # 低temperature确保输出稳定
max_tokens=2000
)
# 创建处理链
self.chain = self._create_chain()
def _create_chain(self):
"""创建处理链"""
prompt_template = ChatPromptTemplate.from_messages([
("system", "你是一个专业的产品经理..."),
("human", "分析需求:{user_input}")
])
return (
{"user_input": RunnablePassthrough()}
| prompt_template
| self.model
| StrOutputParser()
)
def analyze(self, user_input):
"""分析用户需求"""
return self.chain.invoke(user_input)
# 使用示例
if __name__ == "__main__":
# 初始化agent
agent = ProductManagerAgent()
# 分析需求
result = agent.analyze("我们需要一个物流成本优化模型")
print(result)
5. 支持的不同模型
**OpenAI 模型:
# GPT-4
model = ChatOpenAI(model="gpt-4")
model = ChatOpenAI(model="gpt-4-32k") # 更长上下文
model = ChatOpenAI(model="gpt-4-turbo-preview") # 最新版本
# GPT-3.5
model = ChatOpenAI(model="gpt-3.5-turbo")
**Azure OpenAI:
from langchain_openai import AzureChatOpenAI
model = AzureChatOpenAI(
azure_deployment="your-deployment-name",
openai_api_version="2023-05-15",
azure_endpoint="https://your-endpoint.openai.azure.com/",
)
6. 重要参数说明
| 参数 | 说明 | 示例值 |
|---|---|---|
model | 模型名称 | "gpt-4", "gpt-3.5-turbo" |
temperature | 创造性程度 | 0.1 (保守) - 1.0 (创意) |
max_tokens | 最大输出长度 | 1000 |
timeout | 请求超时时间 | 30 (秒) |
max_retries | 最大重试次数 | 2 |
streaming | 是否流式输出 | True/False |
3.初始化输出解析器
output_parser = StrOutputParser() 是 LangChain 中用于处理和清理模型输出的组件。我来详细解释它的作用:
1. 基本功能
StrOutputParser() 是一个输出解析器,它的主要作用是:
- ✅ 提取纯文本内容:从模型的复杂响应中提取出核心文本
- ✅ 清理格式:移除多余的标记、代码块符号等
- ✅ 标准化输出:确保返回统一的字符串格式
2. 为什么需要它?
**没有输出解析器的情况:
# LLM可能返回各种格式的响应
raw_response = """
```json
{
"answer": "这是模型回答",
"reasoning": "推理过程"
}
或者带有多余文本的回答…
“”"
cleaned_response = raw_response.strip().replace('```json', '').replace('```', '')
**使用输出解析器:
output_parser = StrOutputParser()
cleaned_response = output_parser.invoke(raw_response)
# 直接得到干净的文本内容
3. 具体处理的内容
StrOutputParser() 会自动处理:
- 代码块标记:移除
json,python等 - 多余的空格和换行:规范化文本格式
- 意外的格式包装:提取真正的文本内容
4. 在处理链中的位置
chain = (
prompt_template
| model
| StrOutputParser() # 在这里清理和提取文本
)
5. 完整示例
from langchain_openai import ChatOpenAI
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.output_parsers import StrOutputParser
# 初始化组件
model = ChatOpenAI()
prompt_template = ChatPromptTemplate.from_template("回答这个问题:{question}")
output_parser = StrOutputParser()
# 创建处理链
chain = prompt_template | model | output_parser
# 使用链
result = chain.invoke({"question": "什么是人工智能?"})
print(result)
# 输出:干净整洁的文本回答,没有多余格式
6. 与其他解析器的对比
| 解析器 | 用途 | 输出类型 |
|---|---|---|
StrOutputParser() | 通用文本清理 | str |
JsonOutputParser() | 解析JSON响应 | dict/list |
CommaSeparatedListOutputParser() | 解析逗号分隔列表 | list |
7. 自定义处理逻辑
如果你需要更特定的处理,可以自定义:
from langchain_core.output_parsers import BaseOutputParser
class CustomOutputParser(BaseOutputParser):
def parse(self, text: str):
# 自定义清理逻辑
text = text.replace("```json", "").replace("```", "")
return text.strip()
output_parser = CustomOutputParser()
4. 创建链
这段代码是 LangChain 的核心魔法,它创建了一个完整的数据处理流水线。
1. 整体概念:数据处理工厂
想象一个汽车装配流水线:
原材料 → 车身组装 → 喷漆 → 质量检测 → 成品汽车
对应的代码:
输入数据 → 模板填充 → LLM处理 → 输出解析 → 最终结果
2. 代码分解
chain = prompt_template | model | StrOutputParser()
第一步:数据输入准备
- 作用:创建输入数据的结构
- 相当于:
{"domain": input_data, "question": input_data} - 为什么这样做:因为后面的
prompt_template需要domain和question两个参数
第二步:提示模板填充
| prompt_template
- 作用:将数据填充到提示词模板中
- 输入:
{"domain": "物理学", "question": "量子纠缠"} - 输出:格式化后的完整提示词
第三步:LLM 调用
| model
- 作用:调用大语言模型进行分析
- 输入:格式化后的提示词
- 输出:LLM 的原始响应文本
第四步:输出解析
| output_parser
- 作用:清理和解析 LLM 的输出
- 输入:LLM 的原始文本响应
- 输出:干净的处理结果(字符串或结构化数据)
4. 更合理的写法
实际上,通常需要不同的输入处理:
# 方式1:分别处理两个参数
chain = (
{
"domain": lambda x: "物理学", # 固定值
"question": RunnablePassthrough() # 传递输入
}
| prompt_template
| model
| output_parser
)
# 使用
result = chain.invoke("量子纠缠") # question = "量子纠缠", domain = "物理学"
# 方式2:使用字典输入
chain = (
prompt_template
| model
| output_parser
)
# 使用
result = chain.invoke({
"domain": "物理学",
"question": "量子纠缠"
})
5. 可视化流程
输入
↓
+-------------------------+
| {"domain": input, | ← 创建输入结构
| "question": input} |
+-------------------------+
↓
+-------------------------+
| prompt_template | ← 填充模板
+-------------------------+
↓
+-------------------------+
| model | ← LLM处理
+-------------------------+
↓
+-------------------------+
| output_parser | ← 解析输出
+-------------------------+
↓
最终结果
5.使用指定的参数调用处理链
result = chain.invoke({
"domain": "物理学",
"question": "什么是量子纠缠?"
})
为什么使用LangChain?
- 抽象化和模块化
# LangChain的模块化设计让你可以轻松替换组件
from langchain_community.chat_models import ChatAnthropic # 轻松切换模型
from langchain_community.llms import HuggingFacePipeline
# 只需修改一行代码就能切换模型
model = ChatAnthropic(model="claude-2") # 替换为Anthropic Claude
# 或者
model = HuggingFacePipeline.from_model_id(...) # 替换为本地模型
- 复杂的链式操作
# 构建复杂的工作流(纯Python实现会很繁琐)
from langchain_core.prompts import FewShotPromptTemplate
from langchain.chains import SequentialChain
# 多步处理:总结 -> 翻译 -> 格式化
complex_chain = (
summary_chain
| translation_chain
| formatting_chain
)
- 内置工具和记忆
# 轻松添加对话历史记忆
from langchain.memory import ConversationBufferMemory
# 添加工具调用(如网络搜索、计算器等)
from langchain.agents import load_tools, initialize_agent
- 输出解析和处理
# 结构化输出解析(纯Python需要手动处理)
from langchain_core.output_parsers import PydanticOutputParser
from pydantic import BaseModel, Field
class Answer(BaseModel):
explanation: str = Field(description="详细解释")
key_points: list[str] = Field(description="关键点列表")
difficulty: str = Field(description="理解难度")
parser = PydanticOutputParser(pydantic_object=Answer)
更多推荐
所有评论(0)