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)  # 输出模型对量子纠缠的解释

总结

这段代码创建了一个参数化的对话模板

  1. 定义角色:通过系统消息设定AI的专业领域
  2. 接收问题:通过用户消息模板接收具体问题
  3. 支持动态替换:使用 {domain}{question} 占位符实现模板的复用性
  4. 标准化格式:生成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 需要 domainquestion 两个参数

第二步:提示模板填充

| 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?

  1. 抽象化和模块化
# 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(...)  # 替换为本地模型
  1. 复杂的链式操作
# 构建复杂的工作流(纯Python实现会很繁琐)
from langchain_core.prompts import FewShotPromptTemplate
from langchain.chains import SequentialChain

# 多步处理:总结 -> 翻译 -> 格式化
complex_chain = (
    summary_chain 
    | translation_chain 
    | formatting_chain
)
  1. 内置工具和记忆
# 轻松添加对话历史记忆
from langchain.memory import ConversationBufferMemory

# 添加工具调用(如网络搜索、计算器等)
from langchain.agents import load_tools, initialize_agent
  1. 输出解析和处理
# 结构化输出解析(纯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)

更多推荐