The Google Search Tool¶
1. Why would a LLM need to search anything ?¶
Large Language Models like Gemini are incredibly powerful. They have been trained on a vast amount of text and can reason, write, and summarize like nothing we've ever seen. They have one fundamental limitation: they are stuck in time.
Note
An LLM's knowledge is frozen at the point its training data was collected. It has no access to events that happened yesterday, real-time stock prices, or the current weather. Think of it as a brilliant historian locked in a library filled with books that are all a year old. They can tell you everything about the past, but they can't tell you today's news.
This is where a Search Tool come in.
2. But what is a Tool ?¶
A tool is simply a function that the LLM can decide to call to get information or perform an action in the "real world." By giving our agent a Google Search
tool, we are giving it a window to the live, up-to-the-minute internet.
An agent can be equipped with any number of tools to interact with the world. Few examples :
Query a DatabaseConnect to a SQL database to answer questions about company sales data.
Access APIUse a weather API or a Financial API for stocks or Connect to other Agents or access any Product via the API
Execute CodeRun Python code in a sandboxed environment to perform calculations or data analysis.
Possibilities are endlessthink what tool can aid to LLM capability and make life / goal easy for LLM
3. Building the Search Tool¶
Let's write some code. We'll create a simple Python script that defines our Google Search tool using the libraries we installed earlier.
Create a new file in your project directory called search_tool.py
and add the following code.
Breaking Down the Code¶
-
load_dotenv()
: This function is our starting point. It reads the.env
file we created earlier and securely loads ourGOOGLE_API_KEY
andGOOGLE_CSE_ID
into the environment, making them available to the LangChain wrappers without hardcoding them. -
GoogleSearchAPIWrapper()
: We initialize the wrapper class fromlangchain-google-community
. This class handles all the backend complexity of making authenticated requests to the Google Custom Search API. -
def google_search(query: str):
: This is the most important change in our new script! Instead of using the default.run
method, we've created our own custom function calledgoogle_search
.- This function takes a
query
string as input. - It calls
search_wrapper.results(query, num_results=10)
. Unlike the.run()
method which returns a simple string, the.results()
method returns a list of dictionaries. Each dictionary contains structured data about a search result, like itstitle
,link
, andsnippet
. - This approach gives us much more control over the data format and allows us to specify parameters like
num_results=10
on the fly.
- This function takes a
-
Tool(...)
: We define ourTool
object as before, but with one key difference:name
:google_search
, a simple name for the agent to use.description
: A clear explanation of what the tool does and when to use it. This is crucial for the agent's reasoning process.func=google_search
: We now pass our custom function to the tool. When the agent decides to usegoogle_search
, it will execute our function, which in turn calls the API and returns the structured list of results.
-
if __name__ == "__main__":
: Our test block has also been updated to reflect the new output format.- It calls
google_search_tool.run(query)
, which executes our custom function. - Because our function returns a list of dictionaries, we can now iterate through the
results
and cleanly print thetitle
andsnippet
for each item. This demonstrates the power of getting structured data back from our tools.
- It calls
A Reusable Building Block
One of the best parts about structuring our code this way is that search_tool.py
now acts as a self-contained module. The google_search_tool
object we created is not trapped inside this file; we can import it into any other part of our application.
For example, in our main agent file (which we'll create soon!), we can simply write:
This approach keeps our project organized and scalable. Our tools are defined in one place, and our agent's logic is defined in another.Running the Tool¶
If you run the script directly from your terminal, the if __name__ == "__main__:"
block will execute.
You should see an output similar to this (the news will, of course, be different!):
Right now, our tool is just a Python object in a script. It's not yet part of an agent. In the next section, we'll take this tool and integrate it into our very first LangGraph State Graph. This is where the magic (so perceived) really begins.