🏆🏆欢迎大家来到我们的天空🏆🏆
🏆🏆如果文章内容对您有所触动,别忘了点赞、关注,收藏!
🏆 作者简介:我们的天空
🏆《头衔》:阿里云开发者社区专家博主,CSDN人工智能领域新星创作者。
🏆《博客》:人工智能,深度学习,机器学习,python,自然语言处理,AIGC等分享。
🏆🏆主页:我们的天空
想要学习和实践基于 LangChain/LangGraph 的链(Chain)构建、Agent 工具调用以及多轮对话流程的实现,这是 LangChain 生态中非常核心且实用的技能。
下面我会通过一个完整、可运行的示例,带你一步步实现这些功能,从基础的链构建,到 Agent 调用外部工具,再到多轮对话的流程管理。
一、前置准备
首先确保你安装了必要的依赖:
bash
pip install langchain langchain-openai langgraph python-dotenv
同时,你需要准备一个 OpenAI API Key(也可以替换为其他兼容的 LLM),并创建 .env 文件配置:
bash
OPENAI_API_KEY=your-api-key-here
二、完整实现代码
这个示例会实现:
- 构建基础的 LLM 链
- 定义一个外部工具(天气查询)
- 使用 LangGraph 构建 Agent 并实现工具调用
- 支持多轮对话记忆
python
import os
from dotenv import load_dotenv
from langchain_openai import ChatOpenAI
from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder
from langchain_core.tools import Tool
from langchain_core.messages import HumanMessage, AIMessage
from langgraph.graph import StateGraph, END
from langgraph.graph.state import StateSchema
from typing import List, TypedDict, Annotated
import operator
# 加载环境变量
load_dotenv()
# ====================== 1. 基础配置 ======================
# 初始化 LLM
llm = ChatOpenAI(
model="gpt-3.5-turbo",
temperature=0,
api_key=os.getenv("OPENAI_API_KEY")
)
# ====================== 2. 定义工具 ======================
# 模拟天气查询工具
def get_weather(city: str) -> str:
"""
模拟查询指定城市的天气
Args:
city: 城市名称
Returns:
天气信息字符串
"""
# 实际场景中可以替换为真实的天气 API 调用
weather_data = {
"北京": "晴,温度 -2~8℃,微风",
"上海": "多云,温度 5~12℃,东风3级",
"广州": "小雨,温度 18~22℃,南风2级"
}
return weather_data.get(city, f"暂未查询到{city}的天气信息")
# 将函数包装为 LangChain Tool
weather_tool = Tool(
name="WeatherTool", # 工具名称
func=get_weather, # 工具执行函数
description="用于查询指定城市的天气信息,输入参数为城市名称(如:北京、上海)" # 工具描述(关键,LLM 靠这个判断是否调用)
)
# 工具列表
tools = [weather_tool]
# ====================== 3. 定义对话状态(多轮对话核心) ======================
class ConversationState(TypedDict):
"""
定义对话状态结构,用于存储多轮对话的上下文和中间结果
"""
# 对话历史(包含用户和AI的消息)
messages: Annotated[List[HumanMessage | AIMessage], operator.add]
# 是否需要结束对话
is_finished: bool
# ====================== 4. 构建核心链和Agent逻辑 ======================
def llm_agent_node(state: ConversationState):
"""
Agent 核心节点:处理用户消息,决定是否调用工具或直接回答
"""
# 构建提示模板,包含对话历史
prompt = ChatPromptTemplate.from_messages([
("system", "你是一个智能助手,能够回答用户的问题,必要时可以调用工具获取信息。"),
MessagesPlaceholder(variable_name="messages"), # 插入对话历史
])
# 构建基础链:提示模板 + LLM
chain = prompt | llm.bind_tools(tools) # 绑定工具,让LLM知道可以调用哪些工具
# 执行链,获取AI的响应
response = chain.invoke({"messages": state["messages"]})
# 更新状态:添加AI的响应到对话历史
state["messages"].append(response)
# 判断是否需要调用工具
if response.tool_calls:
# 如果有工具调用请求,先不结束对话
state["is_finished"] = False
else:
# 直接回答,结束对话
state["is_finished"] = True
return state
def tool_execution_node(state: ConversationState):
"""
工具执行节点:执行Agent指定的工具调用
"""
# 获取最后一条AI消息(包含工具调用指令)
last_message = state["messages"][-1]
# 执行所有工具调用
tool_results = []
for tool_call in last_message.tool_calls:
# 根据工具名称找到对应的工具
tool = next(t for t in tools if t.name == tool_call["name"])
# 执行工具
result = tool.func(*tool_call["args"].values())
# 记录工具调用结果
tool_results.append(f"工具 {tool_call['name']} 调用结果:{result}")
# 将工具调用结果封装为AI消息,添加到对话历史
tool_result_message = AIMessage(
content="\n".join(tool_results),
tool_call_id=last_message.tool_calls[0]["id"] if last_message.tool_calls else None
)
state["messages"].append(tool_result_message)
# 工具执行完成后,需要让Agent再次处理结果,因此不结束对话
state["is_finished"] = False
return state
def should_continue(state: ConversationState):
"""
决策节点:判断流程是否继续(是否需要调用工具/处理工具结果)
"""
if state["is_finished"]:
return "end" # 结束流程
else:
return "tools" # 执行工具
# ====================== 5. 构建LangGraph流程 ======================
# 创建状态图
workflow = StateGraph(ConversationState)
# 添加节点
workflow.add_node("agent", llm_agent_node) # Agent思考节点
workflow.add_node("tools", tool_execution_node) # 工具执行节点
# 设置入口点
workflow.set_entry_point("agent")
# 添加条件边:Agent节点后根据判断结果走向工具节点或结束
workflow.add_conditional_edges(
"agent",
should_continue,
{
"tools": "tools", # 调用工具
"end": END # 结束
}
)
# 添加边:工具执行完成后回到Agent节点,让Agent处理工具结果
workflow.add_edge("tools", "agent")
# 编译图
app = workflow.compile()
# ====================== 6. 多轮对话交互函数 ======================
def chat():
"""
启动多轮对话交互
"""
print("欢迎使用智能助手!输入 '退出' 结束对话。")
# 初始化对话状态
state = {
"messages": [],
"is_finished": False
}
while True:
# 获取用户输入
user_input = input("\n你:")
if user_input == "退出":
print("助手:再见!")
break
# 将用户输入添加到对话状态
state["messages"].append(HumanMessage(content=user_input))
# 执行LangGraph流程
state = app.invoke(state)
# 获取最后一条AI消息(最终回答)
final_response = next(
msg for msg in reversed(state["messages"])
if isinstance(msg, AIMessage) and not msg.tool_call_id
)
# 输出助手回复
print(f"助手:{final_response.content}")
# 启动对话
if __name__ == "__main__":
chat()
三、代码关键部分解释
-
工具定义(Tool)
Tool是 LangChain 中标准化的工具封装方式,核心包含name(工具名)、func(执行函数)、description(工具描述)。LLM 会根据description判断是否需要调用该工具,因此描述要清晰、准确。 -
对话状态(ConversationState) 这是多轮对话的核心,通过
TypedDict定义状态结构,包含messages(对话历史)和is_finished(流程状态)。Annotated + operator.add确保多轮调用时消息列表能正确追加。 -
LangGraph 流程
StateGraph用于定义有状态的工作流agent节点:LLM 思考,决定是否调用工具tools节点:执行工具调用,返回结果- 条件边:根据
should_continue的结果,决定是调用工具还是结束流程 - 循环边:工具执行完成后,回到
agent节点,让 LLM 基于工具结果生成最终回答
-
多轮对话交互
chat()函数维护对话状态,每次用户输入后,将消息追加到状态中,调用app.invoke(state)执行流程,最终提取并输出 AI 的最终回答。
运行效果示例
html
欢迎使用智能助手!输入 '退出' 结束对话。
你:北京今天天气怎么样?
助手:北京今天晴,温度 -2~8℃,微风。
你:上海呢?
助手:上海今天多云,温度 5~12℃,东风3级。
你:退出
助手:再见!
四、总结
- 链(Chain)构建 :核心是通过
|运算符将PromptTemplate和LLM串联,形成基础的执行链,可灵活扩展(如绑定工具、添加输出解析器)。 - Agent 工具调用 :需先定义标准化的
Tool,再通过bind_tools()让 LLM 感知工具,最后通过 LangGraph 管理 "思考 - 调用工具 - 生成回答" 的流程。 - 多轮对话 :核心是维护对话状态(State),将每轮的消息存储在状态中,让 LLM 能基于历史上下文生成回答,LangGraph 天然支持状态管理,是实现复杂多轮流程的最佳选择。
这个示例是基础但完整的框架,你可以在此基础上扩展:添加更多工具(如搜索引擎、计算器)、优化提示词、支持更复杂的对话逻辑(如多轮工具调用、上下文清理)等。
推荐阅读:
1.【AIGC】Transformer模型:Postion Embedding概述、应用场景和实现方式的详细介绍。
2.【AIGC】Whisper语音识别模型概述,应用场景和具体实例及如何本地搭建Whisper语音识别模型?
3.【人工智能】TensorFlow lite介绍、应用场景以及项目实践:使用TensorFlow Lite进行数字分类