Skip to main content

Tavily Search

Tavily's Search API is a search engine built specifically for AI agents (LLMs), delivering real-time, accurate, and factual results at speed.

Overview

Integration details

ClassPackageSerializableJS supportPackage latest
TavilySearchResultslangchain-communityPyPI - Version

Tool features

Returns artifactNative asyncReturn dataPricing
Title, URL, content, answer1,000 free searches / month

Setup

The integration lives in the langchain-community package. We also need to install the tavily-python package.

%pip install -qU "langchain-community>=0.2.11" tavily-python

Credentials

We also need to set our Tavily API key. You can get an API key by visiting this site and creating an account.

import getpass
import os

if not os.environ.get("TAVILY_API_KEY"):
os.environ["TAVILY_API_KEY"] = getpass.getpass("Tavily API key:\n")

It's also helpful (but not needed) to set up LangSmith for best-in-class observability:

# os.environ["LANGCHAIN_TRACING_V2"] = "true"
# os.environ["LANGCHAIN_API_KEY"] = getpass.getpass()

Instantiation

Here we show how to instantiate an instance of the Tavily search tools, with

from langchain_community.tools import TavilySearchResults

tool = TavilySearchResults(
max_results=5,
search_depth="advanced",
include_answer=True,
include_raw_content=True,
include_images=True,
# include_domains=[...],
# exclude_domains=[...],
# name="...", # overwrite default tool name
# description="...", # overwrite default tool description
# args_schema=..., # overwrite default args_schema: BaseModel
)
API Reference:TavilySearchResults

Invocation

Invoke directly with args

The TavilySearchResults tool takes a single "query" argument, which should be a natural language query:

tool.invoke({"query": "What happened at the last wimbledon"})
[{'url': 'https://www.theguardian.com/sport/live/2023/jul/16/wimbledon-mens-singles-final-2023-carlos-alcaraz-v-novak-djokovic-live?page=with:block-64b3ff568f08df28470056bf',
'content': 'Carlos Alcaraz recovered from a set down to topple Djokovic 1-6, 7-6(6), 6-1, 3-6, 6-4 and win his first Wimbledon title in a battle for the ages'},
{'url': 'https://www.nytimes.com/athletic/live-blogs/wimbledon-2024-live-updates-alcaraz-djokovic-mens-final-result/kJJdTKhOgkZo/',
'content': "It was Djokovic's first straight-sets defeat at Wimbledon since the 2013 final, when he lost to Andy Murray. Below, The Athletic 's writers, Charlie Eccleshare and Matt Futterman, analyze the ..."},
{'url': 'https://www.foxsports.com.au/tennis/wimbledon/fk-you-stars-explosion-stuns-wimbledon-as-massive-final-locked-in/news-story/41cf7d28a12845cdab6be4150a22a170',
'content': 'The last time Djokovic and Wimbledon met was at the French Open in June when the Serb claimed victory in a third round tie which ended at 3:07 in the morning. On Friday, however, Djokovic was ...'},
{'url': 'https://www.cnn.com/2024/07/09/sport/novak-djokovic-wimbledon-crowd-quarterfinals-spt-intl/index.html',
'content': 'Novak Djokovic produced another impressive performance at Wimbledon on Monday to cruise into the quarterfinals, but the 24-time grand slam champion was far from happy after his win.'},
{'url': 'https://www.cnn.com/2024/07/05/sport/andy-murray-wimbledon-farewell-ceremony-spt-intl/index.html',
'content': "It was an emotional night for three-time grand slam champion Andy Murray on Thursday, as the 37-year-old's Wimbledon farewell began with doubles defeat.. Murray will retire from the sport this ..."}]

Invoke with ToolCall

We can also invoke the tool with a model-generated ToolCall, in which case a ToolMessage will be returned:

# This is usually generated by a model, but we'll create a tool call directly for demo purposes.
model_generated_tool_call = {
"args": {"query": "euro 2024 host nation"},
"id": "1",
"name": "tavily",
"type": "tool_call",
}
tool_msg = tool.invoke(model_generated_tool_call)

# The content is a JSON string of results
print(tool_msg.content[:400])
[{"url": "https://www.radiotimes.com/tv/sport/football/euro-2024-location/", "content": "Euro 2024 host cities. Germany have 10 host cities for Euro 2024, topped by the country's capital Berlin. Berlin. Cologne. Dortmund. Dusseldorf. Frankfurt. Gelsenkirchen. Hamburg."}, {"url": "https://www.sportingnews.com/ca/soccer/news/list-euros-host-nations-uefa-european-championship-countries/85f8069d69c9f4
# The artifact is a dict with richer, raw results
{k: type(v) for k, v in tool_msg.artifact.items()}
{'query': str,
'follow_up_questions': NoneType,
'answer': str,
'images': list,
'results': list,
'response_time': float}
import json

# Abbreviate the results for demo purposes
print(json.dumps({k: str(v)[:200] for k, v in tool_msg.artifact.items()}, indent=2))
{
"query": "euro 2024 host nation",
"follow_up_questions": "None",
"answer": "Germany will be the host nation for Euro 2024, with the tournament scheduled to take place from June 14 to July 14. The matches will be held in 10 different cities across Germany, including Berlin, Co",
"images": "['https://i.ytimg.com/vi/3hsX0vLatNw/maxresdefault.jpg', 'https://img.planetafobal.com/2021/10/sedes-uefa-euro-2024-alemania-fg.jpg', 'https://editorial.uefa.com/resources/0274-14fe4fafd0d4-413fc8a7b7",
"results": "[{'title': 'Where is Euro 2024? Country, host cities and venues', 'url': 'https://www.radiotimes.com/tv/sport/football/euro-2024-location/', 'content': \"Euro 2024 host cities. Germany have 10 host cit",
"response_time": "3.97"
}

Chaining

We can use our tool in a chain by first binding it to a tool-calling model and then calling it:

pip install -qU langchain-openai
import getpass
import os

if not os.environ.get("OPENAI_API_KEY"):
os.environ["OPENAI_API_KEY"] = getpass.getpass("Enter API key for OpenAI: ")

from langchain_openai import ChatOpenAI

llm = ChatOpenAI(model="gpt-4o-mini")
import datetime

from langchain_core.prompts import ChatPromptTemplate
from langchain_core.runnables import RunnableConfig, chain

today = datetime.datetime.today().strftime("%D")
prompt = ChatPromptTemplate(
[
("system", f"You are a helpful assistant. The date today is {today}."),
("human", "{user_input}"),
("placeholder", "{messages}"),
]
)

# specifying tool_choice will force the model to call this tool.
llm_with_tools = llm.bind_tools([tool])

llm_chain = prompt | llm_with_tools


@chain
def tool_chain(user_input: str, config: RunnableConfig):
input_ = {"user_input": user_input}
ai_msg = llm_chain.invoke(input_, config=config)
tool_msgs = tool.batch(ai_msg.tool_calls, config=config)
return llm_chain.invoke({**input_, "messages": [ai_msg, *tool_msgs]}, config=config)


tool_chain.invoke("who won the last womens singles wimbledon")
AIMessage(content="The last women's singles champion at Wimbledon was Markéta Vondroušová, who won the title in 2023.", response_metadata={'token_usage': {'completion_tokens': 26, 'prompt_tokens': 802, 'total_tokens': 828}, 'model_name': 'gpt-4o-2024-05-13', 'system_fingerprint': 'fp_4e2b2da518', 'finish_reason': 'stop', 'logprobs': None}, id='run-2bfeec6e-8f04-477e-bf51-9500f18bd514-0', usage_metadata={'input_tokens': 802, 'output_tokens': 26, 'total_tokens': 828})

Here's the LangSmith trace for this run.

API reference

For detailed documentation of all TavilySearchResults features and configurations head to the API reference: https://python.langchain.com/api_reference/community/tools/langchain_community.tools.tavily_search.tool.TavilySearchResults.html


Was this page helpful?