Brand Search Optimization¶
A multi-agent system that helps e-commerce teams optimize product titles for search visibility. A root router agent orchestrates three sub-agents: keyword finding (BigQuery), search results browsing (Selenium), and comparison reporting (generator + critic loop).
Architecture¶
root_agent (router) → keyword_finding_agent, search_results_agent, comparison_root_agent → [comparison_generator_agent, comparison_critic_agent]
Native ADK¶
The original uses 12 files across 6 directories:
brand_search_optimization/
├── __init__.py
├── agent.py
├── prompt.py
├── shared_libraries/
│ ├── __init__.py
│ └── constants.py
├── tools/
│ ├── __init__.py
│ └── bq_connector.py
└── sub_agents/
├── keyword_finding/
│ ├── __init__.py
│ ├── agent.py
│ └── prompt.py
├── search_results/
│ ├── __init__.py
│ ├── agent.py
│ └── prompt.py
└── comparison/
├── __init__.py
├── agent.py
└── prompt.py
shared_libraries/constants.py (click to expand)
MODEL = "gemini-2.5-flash"
AGENT_NAME = "brand_search_optimization"
DESCRIPTION = "A helpful assistant for brand search optimization."
sub_agents/keyword_finding/agent.py (click to expand)
from google.adk.agents.llm_agent import Agent
from ...shared_libraries import constants
from ...tools import bq_connector
from . import prompt
keyword_finding_agent = Agent(
model=constants.MODEL,
name="keyword_finding_agent",
description="A helpful agent to find keywords",
instruction=prompt.KEYWORD_FINDING_AGENT_PROMPT,
tools=[bq_connector.get_product_details_for_brand],
)
sub_agents/search_results/agent.py (click to expand)
from google.adk.agents.llm_agent import Agent
from google.adk.tools.load_artifacts_tool import load_artifacts_tool
from ...shared_libraries import constants
from . import prompt
# ... 9 Selenium tool function imports ...
search_results_agent = Agent(
model=constants.MODEL,
name="search_results_agent",
description="Get top 3 search results info for a keyword using web browsing",
instruction=prompt.SEARCH_RESULT_AGENT_PROMPT,
tools=[go_to_url, take_screenshot, find_element_with_text,
click_element_with_text, enter_text_into_element,
scroll_down_screen, get_page_source, load_artifacts_tool,
analyze_webpage_and_determine_action],
)
sub_agents/comparison/agent.py (click to expand)
from google.adk.agents.llm_agent import Agent
from ...shared_libraries import constants
from . import prompt
comparison_generator_agent = Agent(
model=constants.MODEL,
name="comparison_generator_agent",
description="A helpful agent to generate comparison.",
instruction=prompt.COMPARISON_AGENT_PROMPT,
)
comparsion_critic_agent = Agent(
model=constants.MODEL,
name="comparison_critic_agent",
description="A helpful agent to critique comparison.",
instruction=prompt.COMPARISON_CRITIC_AGENT_PROMPT,
)
comparison_root_agent = Agent(
model=constants.MODEL,
name="comparison_root_agent",
description="A helpful agent to compare titles",
instruction=prompt.COMPARISON_ROOT_AGENT_PROMPT,
sub_agents=[comparison_generator_agent, comparsion_critic_agent],
)
agent.py — root (click to expand)
from google.adk.agents.llm_agent import Agent
from . import prompt
from .shared_libraries import constants
from .sub_agents.comparison.agent import comparison_root_agent
from .sub_agents.keyword_finding.agent import keyword_finding_agent
from .sub_agents.search_results.agent import search_results_agent
root_agent = Agent(
model=constants.MODEL,
name=constants.AGENT_NAME,
description=constants.DESCRIPTION,
instruction=prompt.ROOT_PROMPT,
sub_agents=[keyword_finding_agent, search_results_agent, comparison_root_agent],
)
Fluent API¶
4 files, flat directory:
# agent.py
from adk_fluent import Agent
from dotenv import load_dotenv
from .prompt import (
COMPARISON_CRITIC_PROMPT, COMPARISON_PROMPT, COMPARISON_ROOT_PROMPT,
KEYWORD_FINDING_PROMPT, ROOT_PROMPT, SEARCH_RESULTS_PROMPT,
)
from .tools import (
analyze_webpage, click_element_with_text, enter_text_into_element,
find_element_with_text, get_page_source, get_product_details_for_brand,
go_to_url, scroll_down_screen, take_screenshot,
)
load_dotenv()
MODEL = "gemini-2.5-flash"
# --- Sub-agents ---
keyword_finding = (
Agent("keyword_finding_agent", MODEL)
.describe("A helpful agent to find keywords")
.instruct(KEYWORD_FINDING_PROMPT)
.tool(get_product_details_for_brand)
)
search_results = (
Agent("search_results_agent", MODEL)
.describe("Get top 3 search results info for a keyword using web browsing")
.instruct(SEARCH_RESULTS_PROMPT)
.tool(go_to_url)
.tool(take_screenshot)
.tool(find_element_with_text)
.tool(click_element_with_text)
.tool(enter_text_into_element)
.tool(scroll_down_screen)
.tool(get_page_source)
.tool(analyze_webpage)
)
# Comparison: generator + critic loop, managed by a routing sub-agent
comparison_generator = (
Agent("comparison_generator_agent", MODEL)
.describe("A helpful agent to generate comparison.")
.instruct(COMPARISON_PROMPT)
)
comparison_critic = (
Agent("comparison_critic_agent", MODEL)
.describe("A helpful agent to critique comparison.")
.instruct(COMPARISON_CRITIC_PROMPT)
)
comparison_root = (
Agent("comparison_root_agent", MODEL)
.describe("A helpful agent to compare titles")
.instruct(COMPARISON_ROOT_PROMPT)
.sub_agents([comparison_generator.build(), comparison_critic.build()])
)
# --- Root agent ---
root_agent = (
Agent("brand_search_optimization", MODEL)
.describe("A helpful assistant for brand search optimization.")
.instruct(ROOT_PROMPT)
.sub_agents([
keyword_finding.build(),
search_results.build(),
comparison_root.build(),
])
.build()
)
What Changed¶
constants.MODELreferenced everywhere → singleMODELvariable at top ofagent.pyconstants.AGENT_NAME,constants.DESCRIPTION→ inline stringsinstruction=prompt.X→.instruct(X)description="..."→.describe("...")tools=[fn1, fn2, ...]→.tool(fn1).tool(fn2)...Agent(sub_agents=[...])→.sub_agents([...])Nested sub-agents (comparison_root with generator + critic) work the same way with
.sub_agents()accepting.build()results12 original files across 6 directories → 4 files in 1 directory
No
shared_libraries/constants.pyneededNo
__init__.pychain through sub-agent directoriesTool functions simplified with stubs (no BigQuery/Selenium dependencies)
Metrics¶
Metric |
Native |
Fluent |
Reduction |
|---|---|---|---|
Agent definition files |
4 |
1 |
75% |
Total files |
12 |
4 |
67% |
Directories |
6 |
1 |
83% |
|
15 |
12 |
20% |
Constants/config files |
1 |
0 |
100% |
|
6 |
1 |
83% |