Tools
Decision-making is great, but that’s only half of the story. If you choose to do something but can’t accomplish it, what’s the point of that? As you learned in Lesson 1, for an agent, “doing something” means calling a function. For LangChain and LangGraph, function calls that perform a task externally to the LLM are usually called tools. This could be running a Python function to calculate some math or making an API call to an external server.
Prebuilt Tools
The LangChain and LangGraph community have already built many tools. Here are a few category examples:
- Search: Get up-to-date data from the web.
- Weather: Find the current weather in a city.
- Generators: Generate speech and images.
For most, if not all, you must obtain an API key from the tool provider.
The way you use these prebuilt tools is generally like this:
import some_tool
tool = SomeTool()
llm.bind_tools([tool])
You import the tool from the community library, instantiate it and then bind it to the model. LangGraph has built-in support to recognize when to use a tool. In the demo section that follows, you’ll see how to use the Tavily search tool.
Creating Tools
It isn’t difficult to create your own tool, either. LangGraph just needs to know the following details:
- The function that performs the tool task
- The tool name
- A description of what the tool does
- Any arguments that the function takes
The easiest way to create a tool is by placing the @tool decorator above a function:
@tool
def count_characters(text: str) -> int:
"""Counts the number of characters in the text"""
return len(text)
LangGraph derives the tool name from the function name. The docstring gives the description. The arguments are inferred from the type hinting in the function signature.
Then, you let the LLM know about the tool by providing the function name:
llm.bind_tools([count_characters])
You don’t have to call a local function. If you have an external API that you want to give your agent access to, you can also wrap that with a tool.
Using Tools in a Graph
A convenient way to incorporate a tool in a graph is to use a ToolNode:
graph.add_node("tools", ToolNode([tool]))
When this node receives a message list where the last message is an AIMessage with a tool call, ToolNode will invoke the specified tool. This is easiest to see with an entire example, which you’ll get to in just a bit.
Before you go on to the demo, though, one more topic is important to cover. LangChain has a set of message objects that represent the different types of messages that are sent to the LLM and back. Some of the more common ones are:
- HumanMessage: The user input.
- AIMessage: The response from the LLM.
- SystemMessage: Your instruction to the LLM for how to behave.
- ToolMessage: The response from a tool.
- BaseMessage: A generic message that the other message types subclass.
When interacting with a chatbot, the message history is generally a list of these objects.