iTranslated by AI

The content below is an AI-generated translation. This is an experimental feature, and may contain errors. View original article
🔎

[Google ADK] Building a Custom "Deep Research" Tool for Superior Search Quality

に公開

https://qiita.com/advent-calendar/2025/adk

Introduction

AI agents like "Deep Research" found in ChatGPT and Gemini, which allow for "deep-dive investigations," are very convenient. However, as an engineer, the desire arises to "control the behavior more, such as changing the number of deep dives or limiting the search targets." Therefore, this time, I created my own Deep Research app using Google's Agent Development Kit (ADK).
I will share the benefits unique to ADK and the insights regarding the "depth" of agent design that I gained from the implementation.

Screen of the created app
Screen of the created app

The code for the app I created is available below, so please try it out for yourself! 💡
https://github.com/xxkuboxx/ADK-DeepResearch

Why build with ADK now?

In Deep Research-type tasks, the lifeline is "search quality." No matter how smart the LLM you use, if the information it gathers is mediocre, the quality of the output will not improve.
The biggest reason for adopting ADK is that Google Search is supported by default. The fact that an agent can naturally use Google Search—the most reliable and extensive search in modern times—as a tool is an advantage not found in other frameworks.

2. Opening the "Black Box"

While Deep Research is possible using off-the-shelf products like Gemini Advanced, I had the following dissatisfactions:

  • You cannot specify "how many more times to deep dive."
  • You cannot explicitly choose the model to use (Pro, Flash, etc.).
    By building it yourself, you can keep these parameters completely under your control.

3. Application to making RAG Chatbots DeepResearch-capable (The main goal)

Actually, this was the primary motivation. I thought that if this method could be established, it could be used to make not just Google Search, but also RAG chatbots that refer only to specific documents, DeepResearch-capable. I believe there is a high demand for deep investigation into specific matters.

Design Philosophy: "Depth" over "Breadth"

The aspect I focused on most in this implementation was the sequential process of "executing a query → analyzing the results → executing further queries based on those results."
While another implementation method involves generating multiple queries at the start and executing them in parallel (emphasizing breadth), this time I intentionally pivoted towards "depth." This is because I wanted to replicate the way humans conduct serious research—identifying the next question from a single discovered fact and closing in on the truth.
Note that since ADK's Google Search tool operates with a degree of parallelism by default, I believe "breadth" is also covered to some extent.

About the breadth and depth of search
About the breadth and depth of search

Agent Configuration: Creating an Opposing Structure

To extract deeper information, I coordinated the following three agents:

  • Research Agent (Researcher): Diligently searches for information.
  • Questioner Agent (Questioner): Tenaciously demands further deep dives into the research results, saying things like "this is not enough" or "give more details."
  • Reporter Agent (Reporter): Ultimately compiles the interaction between the above two into a clean report.

By intentionally creating an opposing structure of "Researcher vs. Questioner," I ensure that uncompromising research results are obtained.

Image of agent configuration
Image of agent configuration

Technical Insights (Tips)

These are the learnings regarding the challenges faced during development and ADK-specific behaviors.

1. Sub Agent vs. Agent as a Tool

In ADK, there are two main patterns for agent coordination, and this time I adopted the Sub Agent (Sequential Agent) approach.

  • Concerns: I was worried that using Sub Agents might cause the agent visible to the user to switch (degrading UX), but in this use case, where the agent instance is redefined for each request anyway, it wasn't an issue.
  • Challenges with Agent as a Tool: The method of calling an agent as a tool had debugging challenges because the internal details of the tools were not visible on the ADK Web interface. On the other hand, Sub Agents made it easier to track the behavior of each agent.

2. Trade-offs between Streamlit Integration and Deployment

This time, I adopted Streamlit for the UI, allowing users to specify the "model to use" and "number of deep dives" from the screen.

  • Implementation detail: Since dynamic configuration changes are difficult with standard ADK usage, I implemented a design that generates an agent instance for each request by wrapping it in a class.
  • Side effect: Due to this design change, deployment to ADK's Agent Engine became impossible (due to specification constraints). However, since the ability to adjust parameters like "model" and "number of deep dives" from outside the agent feels like a high-demand feature, I hope ADK will support this more flexibly in the future.

3. Explicit Citations are Mandatory

In Deep Research requirements, the "source of information" is the most critical item.
In this implementation, I ensured that all source links are displayed. This is not only for checking hallucinations but also a prerequisite for leading the user to take action, such as "actually purchasing a product" or "checking primary information."

You can implement it like "extract grounding_metadata when it exists in the event." An "event" is the return value when you run the ADK runner. There is one event for each step of the agent, and during search steps, grounding_metadata exists within the event and can be retrieved.

https://github.com/xxkuboxx/ADK-DeepResearch/blob/main/app/deep_research/agent.py#L106-L122

4. Avoiding Frequent Errors like model rate_limit

Since I'm using the free version of the Gemini API, I quickly hit rate_limit errors with even a little use. Therefore, it's nearly impossible to complete a Deep Research task without a mechanism to retry when such errors occur. To address this, I incorporated retry settings like the code shown below.

https://github.com/xxkuboxx/ADK-DeepResearch/blob/main/app/deep_research/agent.py#L25-L33

This implementation was based on the following article:
https://zenn.dev/google_cloud_jp/articles/genai-adk-reliability

Summary

By building my own Deep Research tool using Google ADK, I was able to implement a unique "deep-dive logic" while leveraging the strengths of Google Search.
While this project targeted web search, the "architecture of pitting a researcher against a questioner to pursue depth" should be directly applicable to RAG chatbots for any kind of document search.
The code is open-sourced on GitHub, so if you are interested in agent development with ADK or Deep Research, please feel free to try it out.

https://github.com/xxkuboxx/ADK-DeepResearch

Discussion