大家好!我是新人唱跳 rap 打篮球,是一个立志 2025 年开始每周都能水一篇文章的人
之前一段时间学习机器学习相关的文档,分享了一个机器学习的基础例子,今天换个口味,学习一下 LangChain 一些组件
这里主要从其他地方拿来的代码,走读,按自己的理解简单分享一下
python==3.9.23
requirements.txt
dotenv==0.9.9
langchain==0.3.27
langchain-community==0.3.27
langchain-core==0.3.72
langchain-openai==0.3.28
langsmith==0.4.10
openai==1.98.0
pyautogen==0.2.32
python-dotenv==1.1.1
通过.env 配置 base_url 和 api_key
有些依赖是其他代码会用,这里一起 copy 过来了
import os
from langchain_core.prompts import PromptTemplate
from dotenv import load_dotenv
from langchain_openai import ChatOpenAI
load_dotenv()
base_url = os.getenv('xiaoai')
api_key = os.getenv('xiaoai_api_key')
# ========== 1. 初始化 LLM(大语言模型) ==========
# LangChain 特点:统一的 LLM 接口,支持多种模型提供商
llm = ChatOpenAI(
base_url=base_url,
api_key=api_key,
model="gpt-4o",
temperature=0.7 # LangChain 特点:统一的参数配置
)
def demo_llm_chain():
"""
演示 LLMChain:支持变量注入与模板复用的核心组件
LangChain 特点:模板化提示词管理,支持变量替换
"""
print("=" * 50)
print("🔗 LLMChain 演示:Prompt → LLM → 输出链")
print("=" * 50)
# 创建提示词模板 - LangChain 特点:模板复用
prompt_template = PromptTemplate(
input_variables=["topic", "style"],
template="""
请以{style}的风格,写一段关于{topic}的介绍。
要求:简洁明了,不超过100字。
"""
)
# LangChain 0.3 推荐使用 LCEL (LangChain Expression Language)
# 这是新的链式组合方式:prompt | llm
chain = prompt_template | llm
# 执行链 - 变量注入
result = chain.invoke({"topic": "人工智能", "style": "科普"})
print(f"📝 LLMChain 输出:\n{result.content}\n")
return result.content
if __name__ == '__main__':
demo_llm_chain()
例子 1 是演示 LangChain 模板化提示词管理,支持变量替换的特点
首先我们通过ChatOpenAI
初始化 LLM 大语言模型
base_url
指定代理服务的 url 地址api_key
指定代理服务创建的 api_keymodel
指定要调用的模型temperature
模型回答多样性参数,区间为 0~1,值越大多样性越大通过PromptTemplate
创建提示词模板
PromptTemplate
主要参数为input_variables
和template
,input_variables
为 list 类型,指定 template 中使用{}包裹的变量的名PromptTemplate
我们创建了一个基础的模板,以什么样的风格写一段什么样的介绍,并指定简介明了,不超过 100 字使用 LCEL(LangChain Expression language)方式,进行 langchain 方式的语言表达语法
chain = prompt_template | llm
让模板与之前声明的llm
模型结合,形成一个链chain.invoke()
并传入字典参数{"topic": "人工智能", "style": "科普"}
,实现对链的调用Tools:工具系统
from langchain_core.tools import Tool
import datetime
# ========== 3. Tools:工具系统 ==========
def get_current_time(query: str) -> str:
"""获取当前时间的工具函数"""
return f"当前时间是:{datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')}"
def calculate_simple(expression: str) -> str:
"""简单计算器工具"""
try:
# 安全的数学表达式计算
allowed_chars = set('0123456789+-*/.() ')
if all(c in allowed_chars for c in expression):
result = eval(expression)
return f"计算结果:{expression} = {result}"
else:
return "错误:包含不允许的字符"
except Exception as e:
return f"计算错误:{str(e)}"
# LangChain 特点:统一的工具接口定义
tools = [
Tool(
name="get_time",
func=get_current_time,
description="获取当前的日期和时间信息"
),
Tool(
name="calculator",
func=calculate_simple,
description="执行简单的数学计算,如加减乘除运算"
)
]
def demo_tools():
"""演示 Tools 工具系统"""
print("=" * 50)
print("🛠️ Tools 演示:工具系统")
print("=" * 50)
for tool in tools:
print(f"工具名称:{tool.name}")
print(f"工具描述:{tool.description}")
# 测试工具
if tool.name == "get_time":
result = tool.run("现在几点了?")
else:
result = tool.run("10 + 5 * 2")
print(f"工具输出:{result}\n")
if __name__ == '__main__':
demo_tools()
例子 2 演示的是 LangChain 如何定义统一的工具,我们按照对应的接口定义即可自己编写自己想要的 tools
我们创建了get_current_time
和calculate_simple
两个方法作为我们的工具函数
get_current_time
用来获取当前时间calculate_simple
用来计算数学表达式通过Tool
去定义统一的工具
Tool
通过name
、func
、description
参数初始化Tool
工具类,name
为工具名称,func
为我们创建的函数,description
为工具描述我们可以通过初始化的示例,调用run
方法并传入参数并返回对应的工具调用结构
例子 03 演示简化版的 Agents
import os
import datetime
from dotenv import load_dotenv
from langchain_openai import ChatOpenAI
from langchain_core.prompts import ChatPromptTemplate
# 加载环境变量
load_dotenv()
base_url = os.getenv('xiaoai')
api_key = os.getenv('xiaoai_api_key')
# ========== 1. 初始化 LLM(大语言模型) ==========
# LangChain 特点:统一的 LLM 接口,支持多种模型提供商
llm = ChatOpenAI(
base_url=base_url,
api_key=api_key,
model="gpt-4o",
temperature=0.7 # LangChain 特点:统一的参数配置
)
def get_current_time(query: str) -> str:
"""获取当前时间的工具函数"""
return f"当前时间是:{datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')}"
def calculate_simple(expression: str) -> str:
"""简单计算器工具"""
try:
# 安全的数学表达式计算
allowed_chars = set('0123456789+-*/.() ')
if all(c in allowed_chars for c in expression):
result = eval(expression)
return f"计算结果:{expression} = {result}"
else:
return "错误:包含不允许的字符"
except Exception as e:
return f"计算错误:{str(e)}"
# ========== 4. 简化版 Agents:手动工具选择演示 ==========
def demo_simple_agents():
"""
演示简化版 Agents:手动工具选择和执行
LangChain 特点:工具集成和智能选择(这里用简化版演示概念)
"""
print("=" * 50)
print("🤖 简化版 Agents 演示:工具选择与执行")
print("=" * 50)
# 创建工具选择提示词
tool_selection_prompt = ChatPromptTemplate.from_messages([
("system", """你是一个智能助手,可以使用以下工具:
1. get_time - 获取当前时间
2. calculator - 执行数学计算
请分析用户问题,选择合适的工具并说明原因。
只回答工具名称和原因,格式:工具名称|原因"""),
("human", "{question}")
])
tool_chain = tool_selection_prompt | llm
test_questions = [
"现在几点了?",
"帮我计算 15 * 8 + 20",
"今天是什么日期?"
]
for question in test_questions:
print(f"👤 用户问题:{question}")
# 1. 工具选择
selection_result = tool_chain.invoke({"question": question})
print(f"🧠 工具选择:{selection_result.content}")
# 2. 执行工具(简化版手动执行)
if "get_time" in selection_result.content.lower():
result = get_current_time(question)
elif "calculator" in selection_result.content.lower():
# 提取数学表达式(简化处理)
if "15 * 8 + 20" in question:
result = calculate_simple("15 * 8 + 20")
else:
result = "需要具体的数学表达式"
else:
result = "未找到合适的工具"
print(f"🛠️ 工具执行结果:{result}\n")
if __name__ == '__main__':
demo_simple_agents()
例子 03 简化版 Agents 实现,但这里并没有直接让大模型调用函数,而是通过大模型的返回间接的调用了我们的工具函数
首先还是通过 ChatOpenAI 初始化 llm 模型
定义get_current_time
和calculate_simple
方法
通过ChatPromptTemplate
创建工具选择提示词
question
字符,表示可替换的变量,表示会传入的提问使用 LCEL(LangChain Expression language)方式,进行 langchain 方式的语言表达语法
tool_chain = tool_selection_prompt | llm
创建了一个链定义一个test_questions
的列表,是我们提出的问题
通过tool_chain.invoke({"question": question})
来让大模型返回要调用的方法的字符
通过我们代码去判断,手动代码选择要调用的方法并执行调用
可以看到这种 Agents 的实现还是有点弱智,但是确实实现了将自然语言转换为工具函数的调用并返回了结果。
例子 04 演示 Memory 的使用,让大模型调用有记忆
import os
from dotenv import load_dotenv
from langchain_openai import ChatOpenAI
from langchain_core.prompts import ChatPromptTemplate
# 加载环境变量
load_dotenv()
base_url = os.getenv('xiaoai')
api_key = os.getenv('xiaoai_api_key')
# ========== 1. 初始化 LLM(大语言模型) ==========
# LangChain 特点:统一的 LLM 接口,支持多种模型提供商
llm = ChatOpenAI(
base_url=base_url,
api_key=api_key,
model="gpt-4o",
temperature=0.7 # LangChain 特点:统一的参数配置
)
# ========== 5. Memory:记忆系统 ==========
def demo_memory():
"""
演示 Memory:对话记忆管理
LangChain 特点:自动管理对话历史
"""
print("=" * 50)
print("🧠 Memory 演示:记忆系统")
print("=" * 50)
# 使用简化的记忆管理方式
conversation_history = []
# 创建带记忆的对话提示词
memory_prompt = ChatPromptTemplate.from_messages([
("system", "你是一个友好的助手,能够记住之前的对话内容。以下是对话历史:{history}"),
("human", "{input}")
])
memory_chain = memory_prompt | llm
# 模拟多轮对话
conversations = [
"我叫张三,今年25岁",
"我喜欢编程和阅读",
"你还记得我的名字吗?",
"我的爱好是什么?"
]
for i, user_input in enumerate(conversations, 1):
print(f"👤 第{i}轮对话:{user_input}")
# 构建历史记录字符串
history_str = "\n".join([f"用户: {h['user']}\n助手: {h['assistant']}" for h in conversation_history])
# 获取回复
response = memory_chain.invoke({
"history": history_str,
"input": user_input
})
print(f"🤖 助手回复:{response.content}\n")
# 更新对话历史
conversation_history.append({
"user": user_input,
"assistant": response.content
})
# 显示当前记忆内容
print(f"💭 当前记忆:{len(conversation_history)} 轮对话")
print("-" * 30)
if __name__ == '__main__':
demo_memory()
首先初始化模型llm
,这里不多介绍了
demo_memory
方法来实现简单的记忆功能conversation_history
来简化记忆管理方式使用ChatPromptTemplate.from_messages
来创建带记忆的对话提示词
history
,来让system
获取到之前的对话历史input
,来让human
来进行提问通过history_str = "\n".join([f"用户: {h['user']}\n助手: {h['assistant']}" for h in conversation_history])
,构建历史记录字符串
调用memory_chain.invoke
函数,传入 history 和 input 参数,获取到最新的回复
通过conversation_history.append
更新对话历史
通过以上的示例,我们实现了一个简单的记忆功能,通过conversation_history
来保存对话历史,并通过history_str
来构建历史记录字符串,并通过memory_chain.invoke
函数来获取最新的回复。
例子 05 演示 LCEL(LangChain Expression Language)的使用
import os
from dotenv import load_dotenv
from langchain_openai import ChatOpenAI
from langchain_core.prompts import PromptTemplate
# 加载环境变量
load_dotenv()
base_url = os.getenv('xiaoai')
api_key = os.getenv('xiaoai_api_key')
# ========== 1. 初始化 LLM(大语言模型) ==========
# LangChain 特点:统一的 LLM 接口,支持多种模型提供商
llm = ChatOpenAI(
base_url=base_url,
api_key=api_key,
model="gpt-4o",
temperature=0.7 # LangChain 特点:统一的参数配置
)
# ========== 6. LCEL 演示:LangChain Expression Language ==========
def demo_lcel():
"""
演示 LCEL:LangChain 0.3 的新特性
LangChain 特点:更简洁的链式组合语法
"""
print("=" * 50)
print("🔗 LCEL 演示:LangChain Expression Language")
print("=" * 50)
# LCEL 语法:使用 | 操作符组合组件
prompt = PromptTemplate.from_template("请用{language}语言解释什么是{concept}")
# 创建链:prompt | llm
chain = prompt | llm
# 执行链
result = chain.invoke({
"language": "简单易懂的中文",
"concept": "区块链"
})
print(f"📝 LCEL 链式调用结果:\n{result.content}\n")
# 演示更复杂的链组合
from langchain_core.output_parsers import StrOutputParser
# 创建输出解析器
output_parser = StrOutputParser()
# 更复杂的链:prompt | llm | output_parser
complex_chain = prompt | llm | output_parser
result2 = complex_chain.invoke({
"language": "技术术语",
"concept": "机器学习"
})
print(f"📝 复杂 LCEL 链结果:\n{result2}\n")
if __name__ == '__main__':
demo_lcel()
demo_lcel
方法实现了简单的 lcel 和更复杂的链组合output_parser = StrOutputParser()
complex_chain = prompt | llm | output_parser
complex_chain.invoke
调用,获取到更复杂的链结果通过上面的例子,我们可以知道 LangChain 的一些特点,希望对你学习 LangChain 有一定帮助
当然, LangChain 还提供了很多的功能,比如:
"🔗 链式组合:使用 LCEL (|) 将多个组件串联",
"📝 模板管理:统一的提示词模板系统",
"🛠️ 工具集成:标准化的工具接口",
"🤖 智能代理:自动选择和使用工具(需模型支持)",
"🧠 记忆管理:灵活的对话历史管理",
"🔄 流程编排:灵活的工作流定义",
"📊 可观测性:详细的执行日志",
"🔌 模块化:组件可插拔设计",
"⚡ LCEL:简洁的表达式语言",
"🎯 类型安全:完整的类型提示支持"
如果感兴趣可以去官网自己再学习更多的内容
听说 LangGraph 现在也是很火,有机会也分享一下
今天就水到这里了,晚安!
我是新人唱跳 rap 打篮球,是一个立志 2025 年开始每周都能水一篇文章的人,希望我的文章可以给你带来好心情!