【LangChain 0.3 - 1 - 常用组件】 + 可运行 Agent 实战
·
目录
一、常用核心组件
1. 聊天模型 ChatModels
from langchain_openai import ChatOpenAI
# 初始化大模型(大脑)
llm = ChatOpenAI(
model="gpt-3.5-turbo",
api_key="sk-xxxxxxxxxxxxxxxx", # 替换为自己的API Key
temperature=0.1, # 数值越低,回答越精准稳定
max_tokens=1024
)
# 简单调用测试
from langchain_core.messages import HumanMessage
resp = llm.invoke([HumanMessage(content="你好")])
print(resp.content)
2. 提示词模板 ChatPromptTemplate
用法 1:基础对话模板(最常用)
from langchain_core.prompts import ChatPromptTemplate
# 定义带参数的对话模板
prompt = ChatPromptTemplate.from_messages([
("system", "你是{role},回答简洁专业,不冗余"),
("user", "{question}")
])
# 填充参数生成标准消息
messages = prompt.format_messages(
role="数学助手",
question="1+1等于几"
)
# 模型调用
resp = llm.invoke(messages)
print(resp.content)
用法 2:带历史对话模板
prompt = ChatPromptTemplate.from_messages([
("system", "你是电商客服助手"),
("user", "我的订单多久发货?"),
("ai", "您好,请提供一下订单号~"),
("user", "{user_input}")
])
3. 链 Chains(流水线)
from langchain_core.output_parsers import StrOutputParser
# 构建流水线:模板 → 模型 → 文本解析
chain = prompt | llm | StrOutputParser()
# 执行调用
result = chain.invoke({
"role": "数学助手",
"question": "3*4+5等于几"
})
print(result)
4. 工具 Tools
推荐:@tool 装饰器定义工具
定义两个工具:计算器(带参数)、查询当前日期(无参数)
from langchain.tools import tool
from datetime import datetime
# 工具1:数学计算器
@tool
def calculator(expression: str) -> str:
"""
数学计算器,支持加减乘除运算
:param expression: 数学表达式,例如 10+2*3
:return: 计算结果
"""
try:
res = eval(expression)
return f"计算结果:{expression} = {res}"
except Exception as e:
return f"计算失败:{str(e)}"
# 工具2:获取当前时间
@tool
def get_current_time() -> str:
"""获取当前系统日期与时间,无需传入参数"""
return f"当前时间:{datetime.now().strftime('%Y-%m-%d %H:%M:%S')}"
# 工具集合(Agent 调用)
tools = [calculator, get_current_time]
5. 工具调用介绍(普通模式、ReAct模式)
这两类工具调用模式都 支持问题拆解:
例如用户问题: 张三的同学李四的导师是谁?
例如有两个工具函数:
- search_classmates(" ") 获取同学列表
- search_advisor(" ")获取导师姓名
执行流程(普通模式 - create_tool_calling_agent)
第1轮:
- LLM推理:需要先查张三的同学有哪些
- 调用工具:
search_classmates("张三") - 工具返回:
张三的同学有:李四、赵六、王七
第2轮:
- LLM推理:李四确实是张三的同学,现在查李四的导师
- 调用工具:
search_advisor("李四") - 工具返回:
李四的导师是王五
第3轮:
- LLM推理:已经找到答案,不需要再调用工具
- 最终输出:
李四的导师是王五
最终答案:王五
基于以上案例,ReAct模式每一步都会多一个思考过程,让用户能看到 LLM 每一步在“想什么”,而 create_tool_calling_agent 只展示工具调用和结果。
二、Agent 工具调用实战
1. Agent 工具调用(普通模式)
该案例未实现上下文持久化功能,而点击跳转 - 【LangChain 0.3 - 2 - 上下文记忆持久化】实现了持久化。
# ================= LangChain 0.3 官方标准 Agent 示例 ==================
# 1. 导入依赖(0.3 标准导入路径)
from langchain_openai import ChatOpenAI
from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder
from langchain.tools import tool
from langchain.agents import create_tool_calling_agent, AgentExecutor
from datetime import datetime
import os
from dotenv import load_dotenv
load_dotenv() # 从 .env 文件读取
# 2. 初始化大模型
llm = ChatOpenAI(
model="gpt-3.5-turbo",
api_key=os.getenv("OPENAI_API_KEY"), # 从环境变量获取密钥key
temperature=0.1
)
# 3. 定义工具
@tool
def calculator(expression: str) -> str:
"""数学计算器,支持加减乘除,输入表达式如 10+2*3"""
try:
return f"结果:{expression} = {eval(expression)}"
except:
return "表达式格式错误"
@tool
def get_current_time() -> str:
"""获取当前日期时间,无需参数"""
return f"当前时间:{datetime.now().strftime('%Y-%m-%d %H:%M:%S')}"
# 组装工具列表
tools = [calculator, get_current_time]
# 4. Agent 专用提示词(0.3 固定规范)
prompt = ChatPromptTemplate.from_messages([
("system", """
你是智能助手,严格按照以下规则执行:
1. 常识类问题直接回答,无需调用工具
2. 涉及数学计算 → 调用 calculator 工具
3. 询问当前时间 → 调用 get_current_time 工具
4. 工具返回结果后,整理为自然语言回复用户
"""),
# 用户输入占位符
("user", "{input}"),
# Agent 思考过程占位符(0.3 固定写法,不可修改)
MessagesPlaceholder(variable_name="agent_scratchpad")
])
# 5. 创建 Agent(0.3 官方函数)
agent = create_tool_calling_agent(llm, tools, prompt)
# 创建执行器
agent_executor = AgentExecutor(
agent=agent,
tools=tools,
verbose=True, # 开启调试日志,查看思考&调用过程
max_iterations=5, # 限制最大工具调用次数,防止死循环
handle_parsing_errors=True # 自动处理解析异常
)
# 6. 执行测试
if __name__ == "__main__":
# 测试1:常识问题(不调用工具)
print("=== 测试1:常识问题 ===")
try:
res1 = agent_executor.invoke({"input": "什么是LangChain?"})
print("回复:", res1["output"])
except Exception as e:
print(f"执行出错:{e}")
# 测试2:数学计算(调用计算器工具)
print("=== 测试2:数学计算 ===")
res2 = agent_executor.invoke({"input": "100 + 20*3 - 15/5 等于多少?"})
print("回复:", res2["output"], "\n")
# 测试3:查询时间(调用时间工具)
print("=== 测试3:查询时间 ===")
res3 = agent_executor.invoke({"input": "现在的日期和时间是多少?"})
print("回复:", res3["output"])
2. Agent 工具调用(ReAct 模式)
ReAct 核心思想为推理 + 行动循环:
模型先思考问题分析需求,再调用外部工具获取信息,根据工具返回结果持续循环推理,直至信息充足后给出最终答案。
ReAct不适用场景
❌一步回答即可,不需要多步推理或工具
❌需要低延迟的场景(ReAct 比普通模式慢 3~10 倍)
ReAct适用场景
✅ 需要查实时数据(股价、天气、新闻)【 用普通 LLM 会过时/幻觉】
✅ 可接受延迟 5-15 秒
✅ 需要验证或纠错(0 容忍 LLM 幻觉 的场景)
✅ 任务可拆解为“思考-行动-观察”循环
基于以上案例改为 ReAct 模式
# 1. 导入依赖(完全不变)
from langchain_openai import ChatOpenAI
from langchain_core.prompts import PromptTemplate # 只改这里!
from langchain.tools import tool
from langchain.agents import create_react_agent, AgentExecutor # 改这里!
from datetime import datetime
import os
from dotenv import load_dotenv
load_dotenv()
# 2. 初始化大模型(完全不变)
llm = ChatOpenAI(
model="gpt-3.5-turbo",
api_key=os.getenv("OPENAI_API_KEY"),
temperature=0.1
)
# 3. 定义工具(完全不变!calculator、get_current_time 都不用动)
@tool
def calculator(expression: str) -> str:
"""数学计算器,支持加减乘除,输入表达式如 10+2*3"""
try:
return f"结果:{expression} = {eval(expression)}"
except:
return "表达式格式错误"
@tool
def get_current_time() -> str:
"""获取当前日期时间,无需参数"""
return f"当前时间:{datetime.now().strftime('%Y-%m-%d %H:%M:%S')}"
tools = [calculator, get_current_time]
# ======================== 重点:ReAct 必须用这个提示词!=========================
# 4. ReAct 专用提示词(固定格式,不能用 ChatPromptTemplate)
prompt = PromptTemplate.from_template("""
Answer the following questions as best you can. You have access to the following tools:
{tools}
Use the following format:
Question: the input question you must answer
Thought: you should always think about what to do
Action: the action to take, should be one of [{tool_names}]
Action Input: the input to the action
Observation: the result of the action
... (this Thought/Action/Action/Observation can repeat N times)
Thought: I now know the final answer
Final Answer: the final answer to the original input question
Begin!
Question: {input}
Thought:{agent_scratchpad}
""")
# 5. 创建 ReAct Agent(只改这个函数名)
agent = create_react_agent(llm, tools, prompt)
# 执行器(完全不变)
agent_executor = AgentExecutor(
agent=agent,
tools=tools,
verbose=True,
max_iterations=5,
handle_parsing_errors=True
)
# 6. 测试(完全不变)
if __name__ == "__main__":
print("=== 测试1:常识问题 ===")
res1 = agent_executor.invoke({"input": "什么是LangChain?"})
print("回复:", res1["output"])
print("=== 测试2:数学计算 ===")
res2 = agent_executor.invoke({"input": "100 + 20*3 - 15/5 等于多少?"})
print("回复:", res2["output"])
print("=== 测试3:查询时间 ===")
res3 = agent_executor.invoke({"input": "现在的日期和时间是多少?"})
print("回复:", res3["output"])
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐


所有评论(0)