Using Web Search with Tavily

The Quarkus LangChain4j extension supports integrating the Tavily web search engine to enrich your AI services with up-to-date external knowledge.

Web search can be used in two main ways:

  • As a tool that the language model can invoke during function calling.

  • As a content retriever inside a Retrieval-Augmented Generation (RAG) pipeline.

Getting Started

To enable Tavily, add the quarkus-langchain4j-tavily extension to your project:

./mvnw quarkus:add-extension -Dextensions="quarkus-langchain4j-tavily"

Then configure your API key:

quarkus.langchain4j.tavily.api-key=your-api-key

Inject the engine as needed:

@Inject
WebSearchEngine engine;

You can now use it directly in your application via the search method, or make it available to the LLM using tools or RAG.

Using Tavily as a Tool

You can expose web search to the LLM as a tool in a function calling setup. This allows the model to invoke the search when needed and incorporate the results in its response.

There are two main approaches:

  • Use the provided dev.langchain4j.web.search.WebSearchTool from LangChain4j

  • Implement your own tool that wraps WebSearchEngine

Example AI service using the built-in tool:

@RegisterAiService
public interface Assistant {

    @ToolBox(WebSearchTool.class)
    String chat(String question);
}

For a full working example, see: chatbot-web-search sample.

Using Tavily in a RAG Pipeline

Tavily can also power content retrieval in a Retrieval-Augmented Generation (RAG) workflow. To do this, use the provided WebSearchContentRetriever in a RetrievalAugmentor.

Example:

@ApplicationScoped
public class WebSearchRetrievalAugmentor implements Supplier<RetrievalAugmentor> {

    @Inject
    WebSearchEngine webSearchEngine;

    @Inject
    ChatModel chatModel;

    @Override
    public RetrievalAugmentor get() {
        return DefaultRetrievalAugmentor.builder()
            .queryTransformer(question -> {
                String query = chatModel.generate("""
                    Transform the user's question into a suitable search query for Tavily.
                    The query should yield results relevant to answering the user's question.
                    User's question: """ + question.text());
                return Collections.singleton(Query.from(query));
            })
            .contentRetriever(new WebSearchContentRetriever(webSearchEngine, 10))
            .build();
    }
}

This approach lets you combine the strengths of LLM reasoning with up-to-date external information retrieved at runtime.

Choosing Between Tool and RAG

Use function calling when: - You want the LLM to choose when to query the web - The web search result is short and structured (e.g. 1–2 snippets)

Use RAG when: - You want to inject relevant documents into the prompt before generation - You need summarization or multi-document synthesis

Tavily Configuration Reference

Configuration property fixed at build time - All other configuration properties are overridable at runtime

Configuration property

Type

Default

Base URL of the Tavily API

Environment variable: QUARKUS_LANGCHAIN4J_TAVILY_BASE_URL

string

https://api.tavily.com

API key for the Tavily API

Environment variable: QUARKUS_LANGCHAIN4J_TAVILY_API_KEY

string

required

Maximum number of results to return

Environment variable: QUARKUS_LANGCHAIN4J_TAVILY_MAX_RESULTS

int

5

The timeout duration for Tavily requests.

Environment variable: QUARKUS_LANGCHAIN4J_TAVILY_TIMEOUT

Duration 

60S

Whether requests to Tavily should be logged

Environment variable: QUARKUS_LANGCHAIN4J_TAVILY_LOG_REQUESTS

boolean

false

Whether responses from Tavily should be logged

Environment variable: QUARKUS_LANGCHAIN4J_TAVILY_LOG_RESPONSES

boolean

false

The search depth to use. This can be "basic" or "advanced". Basic is the default.

Environment variable: QUARKUS_LANGCHAIN4J_TAVILY_SEARCH_DEPTH

basic, advanced

basic

Include a short answer to original query. Default is false.

Environment variable: QUARKUS_LANGCHAIN4J_TAVILY_INCLUDE_ANSWER

boolean

false

Include the cleaned and parsed HTML content of each search result. Default is false.

Environment variable: QUARKUS_LANGCHAIN4J_TAVILY_INCLUDE_RAW_CONTENT

boolean

false

A list of domains to specifically include in the search results. Default is [], which includes all domains.

Environment variable: QUARKUS_LANGCHAIN4J_TAVILY_INCLUDE_DOMAINS

list of string

[]

A list of domains to specifically exclude from the search results. Default is [], which doesn’t exclude any domains.

Environment variable: QUARKUS_LANGCHAIN4J_TAVILY_EXCLUDE_DOMAINS

list of string

[]

About the Duration format

To write duration values, use the standard java.time.Duration format. See the Duration#parse() Java API documentation for more information.

You can also use a simplified format, starting with a number:

  • If the value is only a number, it represents time in seconds.

  • If the value is a number followed by ms, it represents time in milliseconds.

In other cases, the simplified format is translated to the java.time.Duration format for parsing:

  • If the value is a number followed by h, m, or s, it is prefixed with PT.

  • If the value is a number followed by d, it is prefixed with P.