“ 如果说大模型是智能体的大脑,那么工具就是大模型的手和脚。”
在Langgraph智能体开发框架中有几个核心概念,分别是状态图,节点和边;但在此之外还有其它的一些概念如工具,工具在智能体开发中的重要性就不言而喻了。
虽然这些概念说起来很简单,但在实际操作过程中却面临着各种各样的问题。
今天我们就主要介绍一下关于Langgraph中的工具的使用和注意事项。
Langgraph中的工具
工具是智能体开发过程中的核心,虽然大模型也很重要,但如果没有好的工具以及工具管理方式;在强大的大模型也是巧妇难为无米之炊,英雄无用武之地。
工具在智能体开发过程中主要扮演着大模型的手和脚的作用;而在Langgraph中工具是怎么管理的呢?
在前面的文章中介绍过,状态图是Langgraph中数据流转的载体,任何节点的操作结果都将被保存在状态图中;而边表示着节点之间的流转关系,某个节点执行完成之后就会顺着边流转到下一个节点或多个节点中。

如上图所示,就是一个简单的Langgraph流程图,图中存在start和end两个必须节点;以及chatbot机器人节点和tools工具节点。
def human_assistance(query: str) -> str:
"""Request assistance from a human."""
human_response = interrupt({"query": query})
return human_response["data"]
tool = TavilySearch(max_results=2)
tools = [tool, human_assistance]
llm = init_chat_model("anthropic:claude-3-5-sonnet-latest")
# 模型绑定节点
llm_with_tools = llm.bind_tools(tools)
如官网代码所示,声明了两个工具human_assistance和TavilySearch;在最后一行代码中,需要使用bind_tools对工具列表进行绑定;这个绑定的作用是什么?
刚开始看到这段代码以为其就类似于智能体开发过程中,工具函数的声明和实现,然后大模型就可以根据这些工具进行功能调用。
但在后面的代码中又出现了一个工具节点ToolNode,看到这里就觉得有点奇怪了,明明前面已经把工具绑定到了大模型上,为什么现在在这里还需要一个工具节点;那么它的作用是什么?
tool_node = ToolNode(tools=tools)
graph_builder.add_node("tools", tool_node)
事实上,在上面bind_tools的方法中,其作用类似于传统fc开发中的函数声明,即告诉大模型有哪些函数可以使用;但具体的调用工具并不是由大模型实现。
这里也是如此,在bind_tools绑定工具列表之后,在ToolNode节点负责工具的调用。
大模型会根据绑定的工具列表,然后根据自己的理解和判断去选择合适的工具函数。
工具的声明
在Langgraph中,工具函数声明使用@tool注解实现,其会根据函数名称和参数自动判断工具的作用并生成调用参数;如下代码所示:
而在函数的第一行有一个三引号注释符,其作用就类似于fc中的desc,用来描述函数的功能。通过这种方式就可以声明一个工具类。
def get_weather(location: str):
"""Call to get the current weather."""
if location.lower() in ["sf", "san francisco"]:
return "It's 60 degrees and foggy."
else:
return "It's 90 degrees and sunny."
当然,这只是简单的工具函数的使用;如果在Langgraph中的节点中需要实现多个智能体应该怎么办?其工具应该怎么管理,是分开管理还是集中管理?
比如说有的智能体节点需要调用地图和天气工具用来确定旅行计划和路线;而有的智能体需要订票订酒店,这样需要多个工具进行协作的情况下,应该怎么处理。
(文:AI探索时代)