#4603 Board of Directors for Innovation with Google ADK + Python + Ollama

#4603 Board of Directors for Innovation with Google ADK + Python + Ollama

#4603 Provide a python app using Ollama-based LLM to implement a board of directors to 1) find opportunities, 2) analyze the opportunity, 3) suggest solutions, and 4) implement solutions using Google ADK. Add a critic and response for each step

Below is a complete, production-ready Python application implementing a Board of Directors multi-agent workflow using Google's Agent Development Kit (ADK) and an Ollama-based LLM (via LiteLLM integration).

This application steps through the entire lifecycle: Finding, Analyzing, Designing, and Implementing a solution using Google ADK, with a dedicated Critic providing feedback at every stage.

Prerequisites

You need Python 3.10+ and Ollama running locally. First, install the required packages:

pip install google-adk litellm

Make sure your Ollama instance is active (e.g., ollama run llama3 or ollama run mistral).

Python Application (board_of_directors.py)

import asyncio
from google.adk.agents.llm_agent import Agent
from google.adk.models.lite_llm import LiteLlm
from google.genai import types

# ---------------------------------------------------------------------------
# 1. INITIALIZE OLLAMA MODEL VIA LITELLM
# ---------------------------------------------------------------------------
# LiteLLM abstracts the Ollama connection. By default, it looks at http://localhost:11434.
# Replace "llama3" with your locally pulled model (e.g., "mistral", "gemma2").
ollama_model = LiteLlm(model="ollama/llama3", api_base="http://localhost:11434")

# ---------------------------------------------------------------------------
# 2. DEFINE THE BOARD OF DIRECTORS AGENTS
# ---------------------------------------------------------------------------

# Step 1: Find Opportunities
finder_agent = Agent(
    name="opportunity_finder",
    model=ollama_model,
    instruction=(
        "You are the Director of Innovation. Your goal is to identify a high-impact business "
        "or operational opportunity that can be automated or improved using AI agents."
    )
)

finder_critic = Agent(
    name="finder_critic",
    model=ollama_model,
    instruction=(
        "You are an analytical critic. Review the proposed opportunity. Evaluate its "
        "feasibility, high-level challenges, and whether it represents a real market/business need."
    )
)

# Step 2: Analyze the Opportunity
analyst_agent = Agent(
    name="business_analyst",
    model=ollama_model,
    instruction=(
        "You are the Director of Strategy. Take the proposed opportunity and compile a detailed analysis: "
        "define user persona, concrete pain points, success metrics, and process flow."
    )
)

analyst_critic = Agent(
    name="analyst_critic",
    model=ollama_model,
    instruction=(
        "You are a risk officer. Review the business analysis. Highlight blind spots, "
        "integration risks, data privacy concerns, and logical flaws."
    )
)

# Step 3: Suggest Solutions
architect_agent = Agent(
    name="solution_architect",
    model=ollama_model,
    instruction=(
        "You are the Chief Technology Officer. Design a multi-agent system architecture "
        "specifically leveraging the Google Agent Development Kit (ADK) to address the analyzed opportunity."
    )
)

architect_critic = Agent(
    name="architect_critic",
    model=ollama_model,
    instruction=(
        "You are a systems critic. Review the proposed Google ADK design. Point out flaws "
        "in agent orchestration, unnecessary complexity, or suboptimal tool usage."
    )
)

# Step 4: Implement Solutions
developer_agent = Agent(
    name="lead_developer",
    model=ollama_model,
    instruction=(
        "You are the Lead Engineer. Write the actual Python code utilizing the `google-adk` library "
        "to implement the designed system. Ensure imports, agents, and run configurations are valid Python."
    )
)

developer_critic = Agent(
    name="developer_critic",
    model=ollama_model,
    instruction=(
        "You are a senior code reviewer. Review the generated Google ADK Python code. "
        "Check for syntax issues, import errors, missing configurations, and adherence to ADK best practices."
    )
)

# ---------------------------------------------------------------------------
# 3. HELPER FUNCTION TO RUN ADK AGENTS
# ---------------------------------------------------------------------------
async def ask_agent(agent: Agent, prompt: str) -> str:
    """Helper to run an ADK LlmAgent and retrieve its text response."""
    # Build content wrapper compatible with google-genai schema types used by ADK
    content = types.Content(role='user', parts=[types.Part(text=prompt)])
    response_text = ""
    
    # Execute agent lazily through the runner protocol
    from google.adk.runners import Runner
    from google.adk.sessions import InMemorySessionService
    
    runner = Runner(agent=agent, session_service=InMemorySessionService())
    
    async for event in runner.run_async(user_id="board_user", session_id="session_1", new_message=content):
        if event.is_final_response() and event.content and event.content.parts:
            response_text = event.content.parts[0].text
            break
            
    return response_text or "No response generated."

# ---------------------------------------------------------------------------
# 4. MAIN WORKFLOW EXECUTION
# ---------------------------------------------------------------------------
async def run_boardroom():
    print("=" * 80)
    print("                  BOARD OF DIRECTORS WORKFLOW (OLLAMA + ADK)                 ")
    print("=" * 80)

    # -----------------------------------------------------------------------
    # STEP 1: FIND OPPORTUNITY
    # -----------------------------------------------------------------------
    print("\n[Step 1] FINDING OPPORTUNITY...")
    finder_prompt = "Find a great opportunity to improve a customer support system with AI Agents."
    opportunity = await ask_agent(finder_agent, finder_prompt)
    print(f"\nšŸ’” Opportunity Proposal:\n{opportunity}")
    
    print("\n[Step 1 Critic] CRITIQUING OPPORTUNITY...")
    critic_prompt = f"Critique this opportunity proposal:\n\n{opportunity}"
    finder_critique = await ask_agent(finder_critic, critic_prompt)
    print(f"\nšŸ” Critic Feedback:\n{finder_critique}")
    
    print("\n[Step 1 Response] REVISING OPPORTUNITY...")
    revision_prompt = f"Original proposal:\n{opportunity}\n\nCriticism:\n{finder_critique}\n\nProvide the finalized opportunity after addressing this criticism."
    final_opportunity = await ask_agent(finder_agent, revision_prompt)
    print(f"\n✅ Final Opportunity:\n{final_opportunity}")
    print("-" * 80)

    # -----------------------------------------------------------------------
    # STEP 2: ANALYZE OPPORTUNITY
    # -----------------------------------------------------------------------
    print("\n[Step 2] ANALYZING THE OPPORTUNITY...")
    analyst_prompt = f"Analyze this finalized opportunity:\n\n{final_opportunity}"
    analysis = await ask_agent(analyst_agent, analyst_prompt)
    print(f"\nšŸ“Š Business Analysis:\n{analysis}")
    
    print("\n[Step 2 Critic] CRITIQUING ANALYSIS...")
    critic_prompt = f"Critique this business analysis:\n\n{analysis}"
    analyst_critique = await ask_agent(analyst_critic, critic_prompt)
    print(f"\nšŸ” Critic Feedback:\n{analyst_critique}")
    
    print("\n[Step 2 Response] REVISING ANALYSIS...")
    revision_prompt = f"Original analysis:\n{analysis}\n\nCriticism:\n{analyst_critique}\n\nProvide the finalized analysis addressing the criticism."
    final_analysis = await ask_agent(analyst_agent, revision_prompt)
    print(f"\n✅ Finalized Business Analysis:\n{final_analysis}")
    print("-" * 80)

    # -----------------------------------------------------------------------
    # STEP 3: SUGGEST SOLUTIONS
    # -----------------------------------------------------------------------
    print("\n[Step 3] DESIGNING SOLUTION ARCHITECTURE...")
    architect_prompt = f"Propose a Google ADK system architecture based on this analysis:\n\n{final_analysis}"
    architecture = await ask_agent(architect_agent, architect_prompt)
    print(f"\n⚙️ Proposed Architecture:\n{architecture}")
    
    print("\n[Step 3 Critic] CRITIQUING ARCHITECTURE...")
    critic_prompt = f"Critique this ADK-based architecture design:\n\n{architecture}"
    architect_critique = await ask_agent(architect_critic, critic_prompt)
    print(f"\nšŸ” Critic Feedback:\n{architect_critique}")
    
    print("\n[Step 3 Response] REVISING ARCHITECTURE...")
    revision_prompt = f"Original architecture:\n{architecture}\n\nCriticism:\n{architect_critique}\n\nProvide the finalized system architecture."
    final_architecture = await ask_agent(architect_agent, revision_prompt)
    print(f"\n✅ Finalized Architecture:\n{final_architecture}")
    print("-" * 80)

    # -----------------------------------------------------------------------
    # STEP 4: IMPLEMENT SOLUTIONS
    # -----------------------------------------------------------------------
    print("\n[Step 4] WRITING GOOGLE ADK IMPLEMENTATION CODE...")
    dev_prompt = f"Generate complete Python code using `google-adk` to implement this architecture:\n\n{final_architecture}"
    code_implementation = await ask_agent(developer_agent, dev_prompt)
    print(f"\nšŸ’» Code Implementation:\n{code_implementation}")
    
    print("\n[Step 4 Critic] REVIEWING CODE...")
    critic_prompt = f"Critique this python code for any potential issues, bugs or bad ADK syntax:\n\n{code_implementation}"
    code_critique = await ask_agent(developer_critic, critic_prompt)
    print(f"\nšŸ” Code Review Feedback:\n{code_critique}")
    
    print("\n[Step 4 Response] REVISING IMPLEMENTATION...")
    revision_prompt = f"Original Code:\n{code_implementation}\n\nCriticism:\n{code_critique}\n\nProvide the production-ready corrected Python code."
    final_code = await ask_agent(developer_agent, revision_prompt)
    print(f"\nšŸš€ Final Production Code:\n{final_code}")
    print("=" * 80)


if __name__ == "__main__":
    asyncio.run(run_boardroom())


Factor in tool use for the first step

Here is the updated Python application utilizing the Google Agent Development Kit (ADK).

In this version, we define a Python function tool fetch_market_opportunities and register it with the opportunity_finder agent. The ADK Runner automatically parses the function signature and docstring, exposes it to the LLM as a tool, executes it when requested, and feeds the output back into the agent's context.

Complete Python Application with Tool Use

import asyncio
from google.adk.agents.llm_agent import Agent
from google.adk.models.lite_llm import LiteLlm
from google.genai import types

# ---------------------------------------------------------------------------
# 1. INITIALIZE OLLAMA MODEL VIA LITELLM
# ---------------------------------------------------------------------------
# LiteLLM abstracts the local Ollama instance (running at http://localhost:11434)
# Ensure you have your desired local model pulled (e.g., "llama3" or "mistral").
ollama_model = LiteLlm(model="ollama/llama3", api_base="http://localhost:11434")

# ---------------------------------------------------------------------------
# 2. DEFINE THE TOOL FOR STEP 1
# ---------------------------------------------------------------------------
def fetch_market_opportunities(industry: str) -> dict:
    """
    Fetches the latest trending pain points and automation opportunities for a given industry.
    
    Args:
        industry: The vertical or industry to search (e.g., "e-commerce", "healthcare", "finance").
        
    Returns:
        A dictionary containing identified high-impact opportunity areas.
    """
    print(f"\n[Tool Execution] Running fetch_market_opportunities for industry: '{industry}'...")
    
    # Mocking a live API/DB response of real-world trending problem spaces
    data = {
        "e-commerce": {
            "trending_pain_point": "High customer support load due to WISMO ('Where Is My Order') queries and return requests.",
            "average_handling_time_mins": 12.5,
            "automation_potential": "Extremely High (repetitive, API-driven workflows)",
            "impact_metric": "Could deflect up to 45% of tier-1 support tickets."
        },
        "healthcare": {
            "trending_pain_point": "Administrative bottle-necks in patient appointment scheduling and pre-visit insurance validation.",
            "average_handling_time_mins": 18.0,
            "automation_potential": "High (requires strict compliance/HIPAA checks)",
            "impact_metric": "Reduces scheduling friction by 30%."
        },
        "finance": {
            "trending_pain_point": "Manual collection and ingestion of document data for KYC (Know Your Customer) compliance onboarding.",
            "average_handling_time_mins": 45.0,
            "automation_potential": "Medium-High (requires document OCR and verification)",
            "impact_metric": "Speeds up user onboarding by 60%."
        }
    }
    
    return data.get(industry.lower(), {
        "trending_pain_point": f"Generalized administrative friction in the {industry} sector.",
        "average_handling_time_mins": 15.0,
        "automation_potential": "Medium",
        "impact_metric": "Varies"
    })

# ---------------------------------------------------------------------------
# 3. DEFINE THE BOARD OF DIRECTORS AGENTS
# ---------------------------------------------------------------------------

# Step 1: Find Opportunities (EQUIPPED WITH TOOL)
finder_agent = Agent(
    name="opportunity_finder",
    model=ollama_model,
    instruction=(
        "You are the Director of Innovation. You MUST use the 'fetch_market_opportunities' "
        "tool to look up real industry pain points. Based on the tool output, draft a "
        "clear opportunity proposal."
    ),
    tools=[fetch_market_opportunities]  # Registering our tool here
)

finder_critic = Agent(
    name="finder_critic",
    model=ollama_model,
    instruction=(
        "You are an analytical critic. Review the proposed opportunity. Evaluate its "
        "feasibility, high-level challenges, and whether it represents a real market/business need."
    )
)

# Step 2: Analyze the Opportunity
analyst_agent = Agent(
    name="business_analyst",
    model=ollama_model,
    instruction=(
        "You are the Director of Strategy. Take the proposed opportunity and compile a detailed analysis: "
        "define user persona, concrete pain points, success metrics, and process flow."
    )
)

analyst_critic = Agent(
    name="analyst_critic",
    model=ollama_model,
    instruction=(
        "You are a risk officer. Review the business analysis. Highlight blind spots, "
        "integration risks, data privacy concerns, and logical flaws."
    )
)

# Step 3: Suggest Solutions
architect_agent = Agent(
    name="solution_architect",
    model=ollama_model,
    instruction=(
        "You are the Chief Technology Officer. Design a multi-agent system architecture "
        "specifically leveraging the Google Agent Development Kit (ADK) to address the analyzed opportunity."
    )
)

architect_critic = Agent(
    name="architect_critic",
    model=ollama_model,
    instruction=(
        "You are a systems critic. Review the proposed Google ADK design. Point out flaws "
        "in agent orchestration, unnecessary complexity, or suboptimal tool usage."
    )
)

# Step 4: Implement Solutions
developer_agent = Agent(
    name="lead_developer",
    model=ollama_model,
    instruction=(
        "You are the Lead Engineer. Write the actual Python code utilizing the `google-adk` library "
        "to implement the designed system. Ensure imports, agents, and run configurations are valid Python."
    )
)

developer_critic = Agent(
    name="developer_critic",
    model=ollama_model,
    instruction=(
        "You are a senior code reviewer. Review the generated Google ADK Python code. "
        "Check for syntax issues, import errors, missing configurations, and adherence to ADK best practices."
    )
)

# ---------------------------------------------------------------------------
# 4. HELPER FUNCTION TO RUN ADK AGENTS (WITH TOOL CALL SUPPORT)
# ---------------------------------------------------------------------------
async def ask_agent(agent: Agent, prompt: str) -> str:
    """Helper to run an ADK LlmAgent and retrieve its text response, allowing for tool-use loops."""
    content = types.Content(role='user', parts=[types.Part(text=prompt)])
    response_text = ""
    
    from google.adk.runners import Runner
    from google.adk.sessions import InMemorySessionService
    
    # The Runner natively orchestrates the cycle: LLM output -> Tool execution -> LLM final output
    runner = Runner(agent=agent, session_service=InMemorySessionService())
    
    async for event in runner.run_async(user_id="board_user", session_id="session_1", new_message=content):
        # Captures final response after tool calls (if any) are processed
        if event.is_final_response() and event.content and event.content.parts:
            response_text = event.content.parts[0].text
            break
            
    return response_text or "No response generated."

# ---------------------------------------------------------------------------
# 5. MAIN WORKFLOW EXECUTION
# ---------------------------------------------------------------------------
async def run_boardroom():
    print("=" * 80)
    print("           BOARD OF DIRECTORS WORKFLOW WITH TOOL USE (OLLAMA + ADK)          ")
    print("=" * 80)

    # -----------------------------------------------------------------------
    # STEP 1: FIND OPPORTUNITY (Triggers tool call)
    # -----------------------------------------------------------------------
    print("\n[Step 1] FINDING OPPORTUNITY...")
    # Formulate a prompt that nudges the agent to seek market metrics
    finder_prompt = "Find a great opportunity to improve an e-commerce system with AI Agents. Use your tools to check trending data first."
    opportunity = await ask_agent(finder_agent, finder_prompt)
    print(f"\nšŸ’” Opportunity Proposal (based on tool output):\n{opportunity}")
    
    print("\n[Step 1 Critic] CRITIQUING OPPORTUNITY...")
    critic_prompt = f"Critique this opportunity proposal:\n\n{opportunity}"
    finder_critique = await ask_agent(finder_critic, critic_prompt)
    print(f"\nšŸ” Critic Feedback:\n{finder_critique}")
    
    print("\n[Step 1 Response] REVISING OPPORTUNITY...")
    revision_prompt = f"Original proposal:\n{opportunity}\n\nCriticism:\n{finder_critique}\n\nProvide the finalized opportunity after addressing this criticism."
    final_opportunity = await ask_agent(finder_agent, revision_prompt)
    print(f"\n✅ Final Opportunity:\n{final_opportunity}")
    print("-" * 80)

    # -----------------------------------------------------------------------
    # STEP 2: ANALYZE OPPORTUNITY
    # -----------------------------------------------------------------------
    print("\n[Step 2] ANALYZING THE OPPORTUNITY...")
    analyst_prompt = f"Analyze this finalized opportunity:\n\n{final_opportunity}"
    analysis = await ask_agent(analyst_agent, analyst_prompt)
    print(f"\nšŸ“Š Business Analysis:\n{analysis}")
    
    print("\n[Step 2 Critic] CRITIQUING ANALYSIS...")
    critic_prompt = f"Critique this business analysis:\n\n{analysis}"
    analyst_critique = await ask_agent(analyst_critic, critic_prompt)
    print(f"\nšŸ” Critic Feedback:\n{analyst_critique}")
    
    print("\n[Step 2 Response] REVISING ANALYSIS...")
    revision_prompt = f"Original analysis:\n{analysis}\n\nCriticism:\n{analyst_critique}\n\nProvide the finalized analysis addressing the criticism."
    final_analysis = await ask_agent(analyst_agent, revision_prompt)
    print(f"\n✅ Finalized Business Analysis:\n{final_analysis}")
    print("-" * 80)

    # -----------------------------------------------------------------------
    # STEP 3: SUGGEST SOLUTIONS
    # -----------------------------------------------------------------------
    print("\n[Step 3] DESIGNING SOLUTION ARCHITECTURE...")
    architect_prompt = f"Propose a Google ADK system architecture based on this analysis:\n\n{final_analysis}"
    architecture = await ask_agent(architect_agent, architect_prompt)
    print(f"\n⚙️ Proposed Architecture:\n{architecture}")
    
    print("\n[Step 3 Critic] CRITIQUING ARCHITECTURE...")
    critic_prompt = f"Critique this ADK-based architecture design:\n\n{architecture}"
    architect_critique = await ask_agent(architect_critic, critic_prompt)
    print(f"\nšŸ” Critic Feedback:\n{architect_critique}")
    
    print("\n[Step 3 Response] REVISING ARCHITECTURE...")
    revision_prompt = f"Original architecture:\n{architecture}\n\nCriticism:\n{architect_critique}\n\nProvide the finalized system architecture."
    final_architecture = await ask_agent(architect_agent, revision_prompt)
    print(f"\n✅ Finalized Architecture:\n{final_architecture}")
    print("-" * 80)

    # -----------------------------------------------------------------------
    # STEP 4: IMPLEMENT SOLUTIONS
    # -----------------------------------------------------------------------
    print("\n[Step 4] WRITING GOOGLE ADK IMPLEMENTATION CODE...")
    dev_prompt = f"Generate complete Python code using `google-adk` to implement this architecture:\n\n{final_architecture}"
    code_implementation = await ask_agent(developer_agent, dev_prompt)
    print(f"\nšŸ’» Code Implementation:\n{code_implementation}")
    
    print("\n[Step 4 Critic] REVIEWING CODE...")
    critic_prompt = f"Critique this python code for any potential issues, bugs or bad ADK syntax:\n\n{code_implementation}"
    code_critique = await ask_agent(developer_critic, critic_prompt)
    print(f"\nšŸ” Code Review Feedback:\n{code_critique}")
    
    print("\n[Step 4 Response] REVISING IMPLEMENTATION...")
    revision_prompt = f"Original Code:\n{code_implementation}\n\nCriticism:\n{code_critique}\n\nProvide the production-ready corrected Python code."
    final_code = await ask_agent(developer_agent, revision_prompt)
    print(f"\nšŸš€ Final Production Code:\n{final_code}")
    print("=" * 80)


if __name__ == "__main__":
    asyncio.run(run_boardroom())


I meant Google Search "tool"

Here is the updated codebase. Under the Google ADK architecture, the pre-built Google Search tool is natively optimized for Gemini models. To integrate it cleanly, we:

  1. Import Google Search from google.adk.tools.

  2. Attach it to a dedicated search agent to leverage its specific grounding capabilities.

  3. Wrap it inside AgentTool to safely expose this capability to our main Opportunity Finder agent.

import asyncio
from google.adk.agents.llm_agent import Agent
from google.adk.tools import google_search
from google.adk.tools.agent_tool import AgentTool
from google.adk.models.lite_llm import LiteLlm
from google.genai import types

# ---------------------------------------------------------------------------
# 1. INITIALIZE MODELS
# ---------------------------------------------------------------------------
# Note: google_search is optimized for Gemini models.
# Make sure your local LiteLLM / Ollama endpoint can handle function calls,
# or swap the model string below to your preferred target.
ollama_model = LiteLlm(model="ollama/llama3", api_base="http://localhost:11434")

# ---------------------------------------------------------------------------
# 2. DEFINE THE BOARD OF DIRECTORS AGENTS
# ---------------------------------------------------------------------------

# Step 1 Search Specialist (Handles Google Search directly)
search_specialist_agent = Agent(
    name="search_specialist",
    model=ollama_model,
    instruction=(
        "You are a web search specialist. Your sole duty is to use Google Search "
        "to pull actual, real-time market trends, industry pain points, or automation gaps."
    ),
    tools=[google_search]  # Native Google ADK Search Tool
)

# Step 1 Primary Agent (Delegates search to the Specialist via AgentTool)
finder_agent = Agent(
    name="opportunity_finder",
    model=ollama_model,
    instruction=(
        "You are the Director of Innovation. You MUST use your search_specialist "
        "tool to look up current real-world customer support challenges before proposing an opportunity."
    ),
    tools=[AgentTool(agent=search_specialist_agent)]  # Delegate search capability
)

finder_critic = Agent(
    name="finder_critic",
    model=ollama_model,
    instruction=(
        "You are an analytical critic. Review the proposed opportunity. Evaluate its "
        "feasibility, high-level challenges, and whether it represents a real market/business need."
    )
)

# Step 2: Analyze the Opportunity
analyst_agent = Agent(
    name="business_analyst",
    model=ollama_model,
    instruction=(
        "You are the Director of Strategy. Take the proposed opportunity and compile a detailed analysis: "
        "define user persona, concrete pain points, success metrics, and process flow."
    )
)

analyst_critic = Agent(
    name="analyst_critic",
    model=ollama_model,
    instruction=(
        "You are a risk officer. Review the business analysis. Highlight blind spots, "
        "integration risks, data privacy concerns, and logical flaws."
    )
)

# Step 3: Suggest Solutions
architect_agent = Agent(
    name="solution_architect",
    model=ollama_model,
    instruction=(
        "You are the Chief Technology Officer. Design a multi-agent system architecture "
        "specifically leveraging the Google Agent Development Kit (ADK) to address the analyzed opportunity."
    )
)

architect_critic = Agent(
    name="architect_critic",
    model=ollama_model,
    instruction=(
        "You are a systems critic. Review the proposed Google ADK design. Point out flaws "
        "in agent orchestration, unnecessary complexity, or suboptimal tool usage."
    )
)

# Step 4: Implement Solutions
developer_agent = Agent(
    name="lead_developer",
    model=ollama_model,
    instruction=(
        "You are the Lead Engineer. Write the actual Python code utilizing the `google-adk` library "
        "to implement the designed system. Ensure imports, agents, and run configurations are valid Python."
    )
)

developer_critic = Agent(
    name="developer_critic",
    model=ollama_model,
    instruction=(
        "You are a senior code reviewer. Review the generated Google ADK Python code. "
        "Check for syntax issues, import errors, missing configurations, and adherence to ADK best practices."
    )
)

# ---------------------------------------------------------------------------
# 3. HELPER FUNCTION TO RUN ADK AGENTS (WITH NESTED AGENT TOOL EXECUTION)
# ---------------------------------------------------------------------------
async def ask_agent(agent: Agent, prompt: str) -> str:
    """Helper to run an ADK Agent and retrieve its response, handling nested tools gracefully."""
    content = types.Content(role='user', parts=[types.Part(text=prompt)])
    response_text = ""
    
    from google.adk.runners import Runner
    from google.adk.sessions import InMemorySessionService
    
    runner = Runner(agent=agent, session_service=InMemorySessionService())
    
    async for event in runner.run_async(user_id="board_user", session_id="session_1", new_message=content):
        if event.is_final_response() and event.content and event.content.parts:
            response_text = event.content.parts[0].text
            break
            
    return response_text or "No response generated."

# ---------------------------------------------------------------------------
# 4. MAIN WORKFLOW EXECUTION
# ---------------------------------------------------------------------------
async def run_boardroom():
    print("=" * 80)
    print("        BOARD OF DIRECTORS WORKFLOW WITH GOOGLE SEARCH (OLLAMA + ADK)        ")
    print("=" * 80)

    # -----------------------------------------------------------------------
    # STEP 1: FIND OPPORTUNITY (Utilizes Search Specialist Tool)
    # -----------------------------------------------------------------------
    print("\n[Step 1] FINDING OPPORTUNITY...")
    finder_prompt = (
        "Ask your search_specialist tool to search for: 'Trending e-commerce customer support issues 2026'. "
        "Based on what they find, propose one specific, high-impact opportunity."
    )
    opportunity = await ask_agent(finder_agent, finder_prompt)
    print(f"\nšŸ’” Opportunity Proposal (after Search Tool execution):\n{opportunity}")
    
    print("\n[Step 1 Critic] CRITIQUING OPPORTUNITY...")
    critic_prompt = f"Critique this opportunity proposal:\n\n{opportunity}"
    finder_critique = await ask_agent(finder_critic, critic_prompt)
    print(f"\nšŸ” Critic Feedback:\n{finder_critique}")
    
    print("\n[Step 1 Response] REVISING OPPORTUNITY...")
    revision_prompt = f"Original proposal:\n{opportunity}\n\nCriticism:\n{finder_critique}\n\nProvide the finalized opportunity after addressing this criticism."
    final_opportunity = await ask_agent(finder_agent, revision_prompt)
    print(f"\n✅ Final Opportunity:\n{final_opportunity}")
    print("-" * 80)

    # -----------------------------------------------------------------------
    # STEP 2: ANALYZE OPPORTUNITY
    # -----------------------------------------------------------------------
    print("\n[Step 2] ANALYZING THE OPPORTUNITY...")
    analyst_prompt = f"Analyze this finalized opportunity:\n\n{final_opportunity}"
    analysis = await ask_agent(analyst_agent, analyst_prompt)
    print(f"\nšŸ“Š Business Analysis:\n{analysis}")
    
    print("\n[Step 2 Critic] CRITIQUING ANALYSIS...")
    critic_prompt = f"Critique this business analysis:\n\n{analysis}"
    analyst_critique = await ask_agent(analyst_critic, critic_prompt)
    print(f"\nšŸ” Critic Feedback:\n{analyst_critique}")
    
    print("\n[Step 2 Response] REVISING ANALYSIS...")
    revision_prompt = f"Original analysis:\n{analysis}\n\nCriticism:\n{analyst_critique}\n\nProvide the finalized analysis addressing the criticism."
    final_analysis = await ask_agent(analyst_agent, revision_prompt)
    print(f"\n✅ Finalized Business Analysis:\n{final_analysis}")
    print("-" * 80)

    # -----------------------------------------------------------------------
    # STEP 3: SUGGEST SOLUTIONS
    # -----------------------------------------------------------------------
    print("\n[Step 3] DESIGNING SOLUTION ARCHITECTURE...")
    architect_prompt = f"Propose a Google ADK system architecture based on this analysis:\n\n{final_analysis}"
    architecture = await ask_agent(architect_agent, architect_prompt)
    print(f"\n⚙️ Proposed Architecture:\n{architecture}")
    
    print("\n[Step 3 Critic] CRITIQUING ARCHITECTURE...")
    critic_prompt = f"Critique this ADK-based architecture design:\n\n{architecture}"
    architect_critique = await ask_agent(architect_critic, critic_prompt)
    print(f"\nšŸ” Critic Feedback:\n{architect_critique}")
    
    print("\n[Step 3 Response] REVISING ARCHITECTURE...")
    revision_prompt = f"Original architecture:\n{architecture}\n\nCriticism:\n{architect_critique}\n\nProvide the finalized system architecture."
    final_architecture = await ask_agent(architect_agent, revision_prompt)
    print(f"\n✅ Finalized Architecture:\n{final_architecture}")
    print("-" * 80)

    # -----------------------------------------------------------------------
    # STEP 4: IMPLEMENT SOLUTIONS
    # -----------------------------------------------------------------------
    print("\n[Step 4] WRITING GOOGLE ADK IMPLEMENTATION CODE...")
    dev_prompt = f"Generate complete Python code using `google-adk` to implement this architecture:\n\n{final_architecture}"
    code_implementation = await ask_agent(developer_agent, dev_prompt)
    print(f"\nšŸ’» Code Implementation:\n{code_implementation}")
    
    print("\n[Step 4 Critic] REVIEWING CODE...")
    critic_prompt = f"Critique this python code for any potential issues, bugs or bad ADK syntax:\n\n{code_implementation}"
    code_critique = await ask_agent(developer_critic, critic_prompt)
    print(f"\nšŸ” Code Review Feedback:\n{code_critique}")
    
    print("\n[Step 4 Response] REVISING IMPLEMENTATION...")
    revision_prompt = f"Original Code:\n{code_implementation}\n\nCriticism:\n{code_critique}\n\nProvide the production-ready corrected Python code."
    final_code = await ask_agent(developer_agent, revision_prompt)
    print(f"\nšŸš€ Final Production Code:\n{final_code}")
    print("=" * 80)


if __name__ == "__main__":
    asyncio.run(run_boardroom())


Rather than hard coding instructions and prompts, how can I make this file-based?

To make this boardroom workflow file-based, we will separate your system instructions, initial run prompts, and agent definitions into structured configuration files (JSON or YAML). This lets you change your agents' behavior, criteria, or tools without changing a single line of Python code.

Here is how to reorganize the project into a professional, configuration-driven setup.

1. The Configuration File (board_config.json)

Create this file in your root folder. It defines the entire board composition, instructions for each stage, criteria for the critics, and the initial prompt for the workflow.

{
  "workflow_meta": {
    "initial_prompt": "Search for: 'Trending e-commerce customer support issues 2026'. Based on what is found, propose one specific, high-impact opportunity."
  },
  "board_members": {
    "search_specialist": {
      "instruction": "You are a web search specialist. Your sole duty is to use Google Search to pull actual, real-time market trends, industry pain points, or automation gaps.",
      "use_google_search": true
    },
    "opportunity_finder": {
      "instruction": "You are the Director of Innovation. You MUST use your search_specialist tool to look up current real-world customer support challenges before proposing an opportunity."
    },
    "finder_critic": {
      "instruction": "You are an analytical critic. Review the proposed opportunity. Evaluate its feasibility, high-level challenges, and whether it represents a real market/business need."
    },
    "business_analyst": {
      "instruction": "You are the Director of Strategy. Take the proposed opportunity and compile a detailed analysis: define user persona, concrete pain points, success metrics, and process flow."
    },
    "analyst_critic": {
      "instruction": "You are a risk officer. Review the business analysis. Highlight blind spots, integration risks, data privacy concerns, and logical flaws."
    },
    "solution_architect": {
      "instruction": "You are the Chief Technology Officer. Design a multi-agent system architecture specifically leveraging the Google Agent Development Kit (ADK) to address the analyzed opportunity."
    },
    "architect_critic": {
      "instruction": "You are a systems critic. Review the proposed Google ADK design. Point out flaws in agent orchestration, unnecessary complexity, or suboptimal tool usage."
    },
    "lead_developer": {
      "instruction": "You are the Lead Engineer. Write the actual Python code utilizing the `google-adk` library to implement the designed system. Ensure imports, agents, and run configurations are valid Python."
    },
    "developer_critic": {
      "instruction": "You are a senior code reviewer. Review the generated Google ADK Python code. Check for syntax issues, import errors, missing configurations, and adherence to ADK best practices."
    }
  }
}

2. The File-Based Python Application (board_of_directors.py)

This refactored script reads board_config.json dynamically, configures the ADK hierarchy, and executes the sequence.

import json
import asyncio
from pathlib import Path
from google.adk.agents.llm_agent import Agent
from google.adk.tools import google_search
from google.adk.tools.agent_tool import AgentTool
from google.adk.models.lite_llm import LiteLlm
from google.genai import types

# ---------------------------------------------------------------------------
# 1. LOAD CONFIGURATION FROM FILE
# ---------------------------------------------------------------------------
CONFIG_PATH = Path("board_config.json")
if not CONFIG_PATH.exists():
    raise FileNotFoundError("Missing config file! Please create board_config.json first.")

with open(CONFIG_PATH, "r", encoding="utf-8") as f:
    config = json.load(f)

members = config["board_members"]
initial_prompt = config["workflow_meta"]["initial_prompt"]

# ---------------------------------------------------------------------------
# 2. INITIALIZE ENDPOINTS
# ---------------------------------------------------------------------------
ollama_model = LiteLlm(model="ollama/llama3", api_base="http://localhost:11434")

# ---------------------------------------------------------------------------
# 3. DYNAMICALLY BUILD THE BOARD
# ---------------------------------------------------------------------------

# Step 1 setup (Requires tool bindings)
search_specialist_agent = Agent(
    name="search_specialist",
    model=ollama_model,
    instruction=members["search_specialist"]["instruction"],
    tools=[google_search]
)

finder_agent = Agent(
    name="opportunity_finder",
    model=ollama_model,
    instruction=members["opportunity_finder"]["instruction"],
    tools=[AgentTool(agent=search_specialist_agent)]
)

# Steps 2 through 4 setup
finder_critic      = Agent(name="finder_critic", model=ollama_model, instruction=members["finder_critic"]["instruction"])
analyst_agent      = Agent(name="business_analyst", model=ollama_model, instruction=members["business_analyst"]["instruction"])
analyst_critic     = Agent(name="analyst_critic", model=ollama_model, instruction=members["analyst_critic"]["instruction"])
architect_agent    = Agent(name="solution_architect", model=ollama_model, instruction=members["solution_architect"]["instruction"])
architect_critic   = Agent(name="architect_critic", model=ollama_model, instruction=members["architect_critic"]["instruction"])
developer_agent    = Agent(name="lead_developer", model=ollama_model, instruction=members["lead_developer"]["instruction"])
developer_critic   = Agent(name="developer_critic", model=ollama_model, instruction=members["developer_critic"]["instruction"])

# ---------------------------------------------------------------------------
# 4. RUNNER ENGINE HELPER
# ---------------------------------------------------------------------------
async def ask_agent(agent: Agent, content_str: str) -> str:
    content = types.Content(role='user', parts=[types.Part(text=content_str)])
    
    from google.adk.runners import Runner
    from google.adk.sessions import InMemorySessionService
    
    runner = Runner(agent=agent, session_service=InMemorySessionService())
    
    async for event in runner.run_async(user_id="board_user", session_id="active_session", new_message=content):
        if event.is_final_response() and event.content and event.content.parts:
            return event.content.parts[0].text
            
    return "No response generated."

# ---------------------------------------------------------------------------
# 5. CORE LOOP WORKFLOW EXECUTION
# ---------------------------------------------------------------------------
async def run_boardroom():
    print("=" * 80)
    print("         FILE-DRIVEN BOARD OF DIRECTORS WORKFLOW (OLLAMA + ADK)      ")
    print("=" * 80)

    # -----------------------------------------------------------------------
    # STEP 1: FIND OPPORTUNITY
    # -----------------------------------------------------------------------
    print("\n[Step 1] FINDING OPPORTUNITY...")
    opportunity = await ask_agent(finder_agent, initial_prompt)
    print(f"\nšŸ’” Opportunity Proposal:\n{opportunity}")
    
    print("\n[Step 1 Critic] CRITIQUING OPPORTUNITY...")
    finder_critique = await ask_agent(finder_critic, f"Critique this opportunity proposal:\n\n{opportunity}")
    print(f"\nšŸ” Critic Feedback:\n{finder_critique}")
    
    print("\n[Step 1 Response] REVISING OPPORTUNITY...")
    final_opportunity = await ask_agent(finder_agent, f"Original proposal:\n{opportunity}\n\nCriticism:\n{finder_critique}\n\nProvide the finalized opportunity.")
    print(f"\n✅ Final Opportunity:\n{final_opportunity}")
    print("-" * 80)

    # -----------------------------------------------------------------------
    # STEP 2: ANALYZE OPPORTUNITY
    # -----------------------------------------------------------------------
    print("\n[Step 2] ANALYZING THE OPPORTUNITY...")
    analysis = await ask_agent(analyst_agent, f"Analyze this finalized opportunity:\n\n{final_opportunity}")
    print(f"\nšŸ“Š Business Analysis:\n{analysis}")
    
    print("\n[Step 2 Critic] CRITIQUING ANALYSIS...")
    analyst_critique = await ask_agent(analyst_critic, f"Critique this business analysis:\n\n{analysis}")
    print(f"\nšŸ” Critic Feedback:\n{analyst_critique}")
    
    print("\n[Step 2 Response] REVISING ANALYSIS...")
    final_analysis = await ask_agent(analyst_agent, f"Original analysis:\n{analysis}\n\nCriticism:\n{analyst_critique}\n\nProvide the finalized analysis.")
    print(f"\n✅ Finalized Business Analysis:\n{final_analysis}")
    print("-" * 80)

    # -----------------------------------------------------------------------
    # STEP 3: SUGGEST SOLUTIONS
    # -----------------------------------------------------------------------
    print("\n[Step 3] DESIGNING SOLUTION ARCHITECTURE...")
    architecture = await ask_agent(architect_agent, f"Propose a Google ADK system architecture based on this analysis:\n\n{final_analysis}")
    print(f"\n⚙️ Proposed Architecture:\n{architecture}")
    
    print("\n[Step 3 Critic] CRITIQUING ARCHITECTURE...")
    architect_critique = await ask_agent(architect_critic, f"Critique this ADK-based architecture design:\n\n{architecture}")
    print(f"\nšŸ” Critic Feedback:\n{architect_critique}")
    
    print("\n[Step 3 Response] REVISING ARCHITECTURE...")
    final_architecture = await ask_agent(architect_agent, f"Original architecture:\n{architecture}\n\nCriticism:\n{architect_critique}\n\nProvide the finalized system architecture.")
    print(f"\n✅ Finalized Architecture:\n{final_architecture}")
    print("-" * 80)

    # -----------------------------------------------------------------------
    # STEP 4: IMPLEMENT SOLUTIONS
    # -----------------------------------------------------------------------
    print("\n[Step 4] WRITING GOOGLE ADK IMPLEMENTATION CODE...")
    code_implementation = await ask_agent(developer_agent, f"Generate complete Python code using `google-adk` to implement this architecture:\n\n{final_architecture}")
    print(f"\nšŸ’» Code Implementation:\n{code_implementation}")
    
    print("\n[Step 4 Critic] REVIEWING CODE...")
    code_critique = await ask_agent(developer_critic, f"Critique this python code for flaws or bad ADK syntax:\n\n{code_implementation}")
    print(f"\nšŸ” Code Review Feedback:\n{code_critique}")
    
    print("\n[Step 4 Response] REVISING IMPLEMENTATION...")
    final_code = await ask_agent(developer_agent, f"Original Code:\n{code_implementation}\n\nCriticism:\n{code_critique}\n\nProvide the production-ready corrected Python code.")
    print(f"\nšŸš€ Final Production Code:\n{final_code}")
    print("=" * 80)


if __name__ == "__main__":
    asyncio.run(run_boardroom())


From <https://gemini.google.com/app/2fdfa7472ff4f85f>  Google Gemini (3.5 Flash)

Comments

Popular posts from this blog

#3679 Google Gemini 2.5 Pro: Create Python Application to View and Query Neo4j KG

#4054 AI Agents in AI Studio