LangGraph中的基本输入及工具调用范式
新书预告《LangGraph智能体设计模式与多智能体开发》-CSDN博客
在LangGraph的智能体工作流构建中,提示词与工具类是衔接“任务逻辑”与“节点执行”的关键纽带。不同于普通LLM仅接收单向指令,LangGraph中的提示词需突破这种模式,深度嵌入节点交互规则,比如携带上下文调用标识、遵循跨节点数据格式约定,以此为智能体明确任务边界、梳理协作逻辑,确保指令能适配图结构的流转需求。
而工具类则作为核心载体,将提示词定义的行为逻辑转换为可落地的组件,使其能顺畅接入LangGraph的图节点体系,为后续节点执行提供合规、可调用的功能支撑,二者的适配是智能体高效运行的基础。
3.2.1 LangGraph中的提示词
如果把普通的AI模型调用比作“单次对话”——你问一句,模型答一句,那么LangGraph就像一场“多角色协作的舞台剧”:有不同的“角色”(节点)负责不同任务,有“剧本”(边)规定角色间的互动顺序,还有“背景板”(状态)记录剧情进展(比如对话历史、中间结果)。而提示工程就是给这场舞台剧里的每个角色编写“台词指南”,确保它们既能各司其职,又能默契配合,最终完成复杂任务。
在具体应用中,我们一般使用langchain.prompt构建对应的提示词模板,并使用“|”连接符将构建好的prompt提示词类与大语言模型。代码如下:
from langchain_core.prompts import PromptTemplate
from datetime import datetime
system_prompt=PromptTemplate(
input_variables=["user_query","datatime_now"],
template="你是一个有用的智能助手,帮助解决用户的问题{uesr_query},并根据注意{datatime_now}"
).partial(datatime_now=datetime.now())
print(system_prompt)
可以看到,这段代码首先导入了两个工具:从langchain_core.prompts模块导入PromptTemplate,用于创建提示词模板;从datetime模块导入datetime,用于获取当前时间。接着,通过PromptTemplate创建了一个名为system_prompt的提示词模板,该模板指定了两个输入变量:user_query和datatime_now,模板内容为“你是一个有用的智能助手,帮助解决用户的问题{user_query},并根据注意{datatime_now}”。随后,使用partial方法为datatime_now预先填充了当前时间(通过datetime.now()获取)。
最后一行代码print(system_prompt)用于打印这个提示词模板对象,会显示该模板的结构信息,包括定义的输入变量、模板字符串内容以及通过partial预先设置的datatime_now的值,从而直观呈现这个提示词模板的配置情况。
打印结果如下:
input_variables=['user_query']input_types={}partial_variables={'datatime_now':datetime.datetime(2025,11,9,21,54,44,665455)}template='你叫小华,是一个有用的智能助手,帮助解决用户的问题{user_query},并根据注意{datatime_now}'
当我们需要使用这个提示词工具对大模型进行设置时,即定义可以通过“链接”的方式对提示词和LangGraph中的大模型进行设置。示例代码如下:
import bigmodel
from langchain_core.prompts import PromptTemplate
from datetime import datetime
system_prompt=PromptTemplate(
input_variables=["user_query","datatime_now"],
template="你是小华,是一个有用的智能助手,帮助解决用户的问题{user_query},并根据注意{datatime_now}"
).partial(datatime_now=datetime.now())
llm=system_prompt | bigmodel.llm
print(llm.invoke("你是谁?").content)
这里的“|”是LangChain中的链操作符,表示将前一个组件的输出作为后一个组件的输入。system_prompt(提示模板)生成完整提示文本后,将其传递给bigmodel.llm(大模型实例)进行处理。
而llm.invoke("你是谁?")是向链中输入用户查询“你是谁?”,此时system_prompt会将user_query替换为“你是谁?”,并结合预先填充的datatime_now生成完整提示,再传给大模型处理。
最终我们使用content来获取大模型返回结果中的文本内容(假设bigmodel.llm的返回格式包含content字段)。最终打印大模型的回答。
输出结果如下:
你好!我是小华,一个乐于助人的智能助手。我的目标是帮助你解答问题、提供信息或协助完成各种任务。
当前时间是:2025年11月10日10:30:32(UTC+8)。
有什么我可以帮你的吗?
读者可以自行尝试。
3.2.2 LangGraph中的工具定义与调用
前面我们完成了模型提示词的设置,通过简单的链式组合方式,就能让大模型调整自身认知逻辑,明确角色定位以适配新的应用场景。而LangGraph的核心价值不止于此,它更擅长将“大模型的决策能力”与“外部工具的执行能力”深度融合,通过流程化编排实现更复杂的智能交互。
|
图3-4 LangGraph中的图 |
LangGraph作为LangChain生态中用于构建状态机和工作流的框架,其核心优势在于“结构化的决策流转”与“状态管理”。当我们将之前定义的get_weather这类工具接入LangGraph后,大模型不再是孤立的“问答模块”,而是能根据用户需求自主判断“是否需要调用工具”“调用哪个工具”“如何处理工具返回结果”的智能体。LangGraph中的图如图3-4所示。
具体来说,LangGraph会通过“节点(Node)”封装不同的逻辑单元,比如“大模型决策节点”负责分析用户问题(如判断“北京今天天气如何”需要调用天气工具),“工具调用节点”负责执行get_weather函数并获取返回值,“结果整合节点”负责将工具返回的结构化数据转换为自然语言回答。这些节点通过“边(Edge)”连接,形成可动态流转的工作流,而LangGraph会自动管理整个过程中的状态(包括用户提问、工具调用历史、中间结果等),确保流程不中断、逻辑不跑偏。
例如,当用户提出“上海今天的天气适合出游吗?”的问题时,整个流程会是:用户提问触发LangGraph工作流→大模型决策节点分析后,判断需要先调用get_weather工具获取上海当日天气数据→工具调用节点传入地点(上海)和当前日期,执行函数并返回天气结果(晴朗、21度)→大模型接收工具返回值,结合“出游适配性”的判断逻辑,整合出“上海今天天气晴朗、温度适宜,非常适合出游”的最终回答。
这种模式下,大模型的角色从“直接答题者”转变为“流程调度者”,而工具则成为其延伸的“能力手脚”。LangGraph通过可视化的流程编排和灵活的状态管理,解决了单纯依赖大模型时“无法获取实时数据”“缺乏特定功能执行能力”的痛点,让智能助手不仅能“懂用户”,还能“做事情”。
1. 函数工具的定义
下面是我们实现的一个简单的温度查询函数,为了便于读者理解,我们抽象出具体内容,而仅仅对地址和时间返回特定的内容。
from langchain.tools import tool
@tool
def get_weather(loc:str,now_data:datetime):
"""
用于查询指定地点在指定日期的天气情况。
参数:
loc:地点名称(字符串类型,例如"上海")
now_data:查询的日期(datetime类型,包含年/月/日)
返回:包含日期、地点和天气详情的字符串
"""
return f"今天的日期是{now_data},查询到{loc}的天气晴朗,风和日丽,温度为21度"
首先,我们使用from langchain.tools import tool(即@tool)来修饰定义的函数工具,这是一个简单且高效的“工具注册手段”——它能自动将普通Python函数转换为LangGraph、LangChain等框架可识别的“标准工具”,无须手动编写工具描述、参数解析等冗余代码,框架会自动读取函数的关键信息(如参数类型、文档字符串),生成工具调用所需的元数据。
函数工具定义的核心要求:
- 函数参数必须指定类型注解(如loc: str、now_data: datetime),且参数含义需清晰无歧义。
- 函数内部的文档字符串是工具的“说明书”,核心作用是给大模型提供工具用途、参数含义的解释,直接影响大模型是否能正确触发工具调用。
2. 定义好的函数工具的定义
在使用上,我们可以将定义好的工具绑定到LangGraph的大模型中,通过交流对其进行调用,完整的示例代码如下:
import bigmodel
from langchain_core.prompts import PromptTemplate
from datetime import datetime
system_prompt=PromptTemplate(
input_variables=["user_query","datatime_now"],
template="你是小华,是一个有用的智能助手,帮助解决用户的问题{user_query},并根据注意{datatime_now}"
).partial(datatime_now=datetime.now())
from langchain.tools import tool
@tool
def get_weather(loc:str,now_data:datetime):
"""
用于查询指定地点在指定日期的天气情况。
参数:
loc:地点名称(字符串类型,例如"上海")
now_data:查询的日期(datetime类型,包含年/月/日)
返回:包含日期、地点和天气详情的字符串
"""
returnf"今天的日期是{now_data},查询到{loc}的天气晴朗,风和日丽,温度为21度"
llm_withtool=system_prompt|bigmodel.llm.bind_tools([get_weather])
print(llm_withtool.invoke("上海的天气是什么"))
输出结果如下:
content=''additional_kwargs={'refusal':None}response_metadata={'token_usage':{'completion_tokens':57,'prompt_tokens':380,'total_tokens':437,'completion_tokens_details':None,'prompt_tokens_details':{'audio_tokens':None,'cached_tokens':0}},'model_provider':'openai','model_name':'qwen3-max','system_fingerprint':None,'id':'chatcmpl-af461d1c-b591-46e5-9e4a-385c1a6adb92','finish_reason':'tool_calls','logprobs':None}id='lc_run--1df35f33-bc89-40b5-95c4-2997621af199-0'tool_calls=[{'name':'get_weather','args':{'loc':'上海', 'now_data':'2025-11-10T15:27:04.460133'},'id':'call_743b4f1b85cb48e49bbde84d','type':'tool_call'}]usage_metadata={'input_tokens':380,'output_tokens':57,'total_tokens':437,'input_token_details':{'cache_read':0},'output_token_details':{}}
从结果可以看到,此时在LangGraph的输出内容中,tool_calls指定了模型需要调用的工具名称、参数及唯一标识,具体包含以理三部分关键信息。
- name:"get_weather":明确指定要调用的工具是我们定义的get_weather函数,说明模型通过分析用户问题“上海的天气是什么”,结合工具的文档字符串(“用于查询指定地点在指定日期的天气情况”),准确判断出需要调用该工具才能回答问题。
- args:{'loc':'上海','now_data':'2025-11-10...'}:包含工具所需的参数,其中loc被正确提取为用户问题中的“上海”,now_data则自动复用了system_prompt中通过partial预先填充的当前时间(datetime.now()的结果),体现了模型对上下文信息(系统提示中的时间)和用户输入(地点)的协同处理能力。
- id:"call_743b4f1b85cb48e49bbde84d":工具调用的唯一标识,用于后续跟踪该次调用的结果(比如在多轮工具调用中区分不同的调用记录)。
这一结果的核心意义在于:通过bind_tools([get_weather])方法,我们成功将工具“注入”大模型的能力体系中。模型不再局限于自身训练数据中的知识,而是能根据问题类型自主判断“是否需要外部工具支持”,并按照工具要求的格式生成调用指令——这正是“智能体(Agent)”与普通问答模型的核心区别:前者具备“感知需求→调用工具→获取结果→生成回答”的闭环能力,而tool_calls就是这个闭环的“启动信号”。
接下来,想要完成整个交互流程,还需要基于tool_calls的结果执行实际的工具调用,并将返回值反馈给模型以生成最终回答。例如,我们可以解析tool_calls中的参数,调用get_weather函数获取天气数据,再将数据回传给模型,让其整理成自然语言:
import bigmodel
from langchain_core.prompts import PromptTemplate
from datetime import datetime
system_prompt=PromptTemplate(
input_variables=["user_query","datatime_now"],
template="你是小华,是一个有用的智能助手,帮助解决用户的问题{user_query},并根据注意{datatime_now}"
).partial(datatime_now=datetime.now())
from langchain.tools import tool
@tool
def get_weather(loc:str,now_data:datetime):
"""
用于查询指定地点在指定日期的天气情况。
参数:
loc:地点名称(字符串类型,例如"上海")
now_data:查询的日期(datetime类型,包含年/月/日)
返回:包含日期、地点和天气详情的字符串
"""
returnf"今天的日期是{now_data},查询到{loc}的天气晴朗,风和日丽,温度为21度"
tools=[get_weather]
llm_withtool=system_prompt | bigmodel.llm.bind_tools([get_weather])
#解析工具调用指令
tool_calls=llm_withtool.invoke("上海的天气是什么").tool_calls
tools_by_name={tool.name:toolfortoolintools}
tool_results=[]
for tool_call in tool_calls:
tools_call_name=tool_call["name"]
tools_call_args=tool_call["args"]
tool_result=tools_by_name[tools_call_name].invoke(tools_call_args)
tool_results.append(tool_result)
#将工具结果回传给模型,生成最终回答
final_prompt=f"用户问的是上海的天气,工具返回结果:{tool_results},请整理成自然语言回答。"
final_answer=bigmodel.llm.invoke(final_prompt).content
print(final_answer)
输出结果如下:
今天是2025年11月10日,上海天气晴朗,风和日丽,气温为21摄氏度。
可以看到,通过这样的流程,get_weather工具真正成为模型的“外置能力”,而tool_calls则是连接模型决策与工具执行的关键桥梁。在LangGraph的框架中,这一过程会被进一步自动化——通过定义“工具调用节点”“结果处理节点”和流转规则,实现从用户提问到最终回答的全流程无缝衔接,让智能体的交互更贴近人类解决问题的自然逻辑。
3.2.3 基于LangGraph实现的工具使用智能体
前面我们完成了一个简单的基于大模型的工具调用,从其使用可以看到我们使用了手工编写的代码来实现对大模型调用工具输出结果的最终处理。
然而在具体使用上,我们目前实现的是需要人工介入解析工具调用指令、手动执行工具并回传结果的半自动化流程——不仅步骤烦琐,还存在明显的局限性:既无法应对多轮工具调用(如用户未明确地点时,需要先追问补充信息再调用天气工具)、多工具协同(如同时查询天气和景点开放时间)的场景,也缺乏对工具调用失败的重试机制、中间结果的动态更新能力。一旦场景复杂度提升,手工编写的代码会变得冗余且难以维护,无法满足智能体“自主决策、灵活适配”的核心需求。
而LangGraph的出现恰好解决了这一痛点。基于LangGraph构建的工具使用智能体能将此前分散的“决策-调用-反馈”步骤封装为结构化的自动化工作流,通过节点承载具体逻辑、边定义流转规则、状态模型管理全流程数据,实现无须人工干预的端到端工具使用能力。该智能体不仅能自主判断是否需要调用工具、调用哪个工具,还能自动处理工具返回结果,若遇到信息不足(如用户未说明查询地点),则主动追问,若工具调用失败,则触发重试逻辑,真正实现了“感知需求→自主调度→执行任务→生成结果”的完整闭环。
下面我们将通过代码构建这个智能体,核心将设计三大节点:决策节点负责分析当前状态(用户问题、已有的工具结果),直接调用工具生成结果,之后生成回答;工具执行节点负责解析决策结果,调用对应的工具并获取返回值;结果整合节点则将工具返回的结构化数据转换为自然语言回答。同时,借助LangGraph的状态管理能力,实时维护用户问题、工具调用历史、中间结果等关键信息,让整个工具使用流程既高效又可控。
下面是我们实现的一个直接对工具进行调用的示例,代码如下:
from datetime import datetime
from langchain.tools import tool
import bigmodel # 假设这是正确导入的LLM库
from langchain_core.messages import HumanMessage
from langgraph.graph import StateGraph, END,add_messages
from langgraph.prebuilt import ToolNode
from typing import Annotated, List
from pydantic import BaseModel, Field
@tool
def get_weather(loc: str, now_data: datetime):
"""
用于查询指定地点在指定日期的天气情况。
参数:
loc: 地点名称(字符串类型,例如"上海")
now_data: 查询的日期(datetime类型,包含年/月/日)
返回:包含日期、地点和天气详情的字符串
"""
return f"{now_data.date()},{loc}的天气晴朗,风和日丽,温度为21度"
class WeatherAgent(BaseModel):
messages: Annotated[List,add_messages] = Field(default=[], description="智能体传递的消息")
# 定义工具和LLM
tools = [get_weather]
tool_node = ToolNode(tools)
#配置LLM(直接绑定工具,不使用多余的提示模板)
llm_with_tools = bigmodel.llm.bind_tools(tools)
def chatbot(state: WeatherState):
"""生成工具调用指令"""
response = llm_with_tools.invoke(state.messages)
return {"messages": [response]}
graph_builder = StateGraph(WeatherState)
graph_builder.add_node("chatbot", chatbot)
graph_builder.add_node("tools", tool_node)
graph_builder.set_entry_point("chatbot")
graph_builder.add_edge("chatbot", "tools")
graph_builder.add_edge("tools", END)
graph = graph_builder.compile()
if __name__ == '__main__':
# 输入用户查询(使用标准消息格式)
user_input = "帮我查一下上海的天气"
initial_state = {"messages": [HumanMessage(content=user_input)]}
# 执行流程并获取结果
result = graph.invoke(initial_state)
# 提取并打印工具返回的结果
print(result["messages"][-1].content)
输出结果如下:
2023-10-10,上海的天气晴朗,风和日丽,温度为21度
在这段基于LangGraph构建的天气查询智能体代码中,tool_node = ToolNode(tools)是实现“工具调用执行”的核心组件,其作用是连接大模型的“工具调用决策”与“实际工具执行”,是智能体与外部工具交互的关键节点。
ToolNode是LangGraph提供的预定义工具执行节点(来自langgraph.prebuilt),专门用于处理 “工具调用”的实际执行逻辑。它的核心功能是:接收大模型生成的“工具调用指令”(包含要调用的工具名称、参数等信息),自动匹配对应的工具函数,执行函数并返回结果,最终将结果包装成消息格式反馈到智能体的状态中。
下面我们结合代码的状态图(StateGraph)来看:
- 流程从chatbot节点开始(大模型根据用户输入生成工具调用指令)。
- 指令通过边(add_edge("chatbot", "tools"))传递到tool_node节点,由其执行实际的天气查询工具调用。
- 工具执行完成后,结果通过add_edge("tools", END)结束流程,最终输出结果。
可以说,tool_node是“决策”与“行动”的桥梁:大模型负责“决定调用哪个工具”,tool_node 负责“实际执行这个工具并返回结果”,即tool_node = ToolNode(tools)创建了一个自动化的工具执行节点,它简化了“解析工具调用指令→执行工具→返回结果”的全流程,让开发者无须手动处理工具调用的解析和执行逻辑,只需关注工具函数的实现和智能体的流程设计即可。这是LangGraph中实现智能体与外部工具交互的核心机制之一。

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐




所有评论(0)