From 8c4fd9193de407c506e0b11f7077414764c4e438 Mon Sep 17 00:00:00 2001 From: ShubhamSaboo Date: Sun, 13 Jul 2025 20:31:54 -0500 Subject: [PATCH] feat: updated coordinated team structure for product launch intelligence agent --- .../README.md | 18 +++-- .../product_launch_intelligence_agent.py | 70 ++++++++++++------- 2 files changed, 58 insertions(+), 30 deletions(-) diff --git a/advanced_ai_agents/multi_agent_apps/product_launch_intelligence_agent/README.md b/advanced_ai_agents/multi_agent_apps/product_launch_intelligence_agent/README.md index f441d9e..a2f8276 100644 --- a/advanced_ai_agents/multi_agent_apps/product_launch_intelligence_agent/README.md +++ b/advanced_ai_agents/multi_agent_apps/product_launch_intelligence_agent/README.md @@ -3,7 +3,7 @@ A **streamlined intelligence hub** for Go-To-Market (GTM) & Product-Marketing teams. Built with **Streamlit + Agno (GPT-4o) + Firecrawl**, the app turns scattered public-web data into concise, actionable launch insights. -## 3 Specialized Agents +## 3 Specialized Agents in Coordinated Team | Tab | What You Get | |-----|--------------| @@ -14,7 +14,7 @@ Built with **Streamlit + Agno (GPT-4o) + Firecrawl**, the app turns scattered pu Additional goodies: * 🔑 **Sidebar key input** – enter OpenAI & Firecrawl keys securely (type="password") -* 🧠 **Specialised multi-agent core** – three expert agents collaborate for richer insight +* 🧠 **Coordinated multi-agent team** – three expert agents work together for richer insight * 🔍 Product Launch Analyst (GTM strategist) * 💬 Market Sentiment Specialist (consumer-perception guru) * 📈 Launch Metrics Specialist (performance analyst) @@ -27,7 +27,7 @@ Additional goodies: | Layer | Details | |-------|---------| | Data | **Firecrawl** async search + crawl API | -| Agents | **Agno** (GPT-4o) with FirecrawlTools | +| Agents | **Agno Team** (GPT-4o) with FirecrawlTools | | UI | **Streamlit** wide-layout, tabbed workflow | | LLM | **OpenAI GPT-4o** | @@ -67,7 +67,17 @@ streamlit run product_launch_intelligence_agent.py 1. Enter **API keys** in the sidebar (or ensure they are in your environment). 2. Type a **company / product / hashtag** in the main input box. -3. Pick a tab and hit the corresponding **Analyze** button – a spinner will appear while the agent works. +3. Pick a tab and hit the corresponding **Analyze** button – a spinner will appear while the coordinated team works. 4. Review the two-part analysis: * Bullet list of key findings * Expanded, richly-formatted report (tables, call-outs, recommendations) + +## 🤖 How the Coordinated Team Works + +The application uses a **coordinated team approach** where three specialized agents work together: + +- **Product Launch Analyst**: Evaluates competitive positioning, launch strategies, strengths, and weaknesses +- **Market Sentiment Specialist**: Analyzes social media sentiment, customer feedback, and brand perception +- **Launch Metrics Specialist**: Tracks KPIs, adoption rates, press coverage, and performance indicators + +The team coordinates based on the analysis type requested, ensuring the most appropriate agent handles each task while maintaining consistency and comprehensive coverage across all analysis types. diff --git a/advanced_ai_agents/multi_agent_apps/product_launch_intelligence_agent/product_launch_intelligence_agent.py b/advanced_ai_agents/multi_agent_apps/product_launch_intelligence_agent/product_launch_intelligence_agent.py index 226e1c2..930d515 100644 --- a/advanced_ai_agents/multi_agent_apps/product_launch_intelligence_agent/product_launch_intelligence_agent.py +++ b/advanced_ai_agents/multi_agent_apps/product_launch_intelligence_agent/product_launch_intelligence_agent.py @@ -1,5 +1,6 @@ import streamlit as st from agno.agent import Agent +from agno.team import Team from agno.models.openai import OpenAIChat from agno.tools.firecrawl import FirecrawlTools from dotenv import load_dotenv @@ -40,7 +41,7 @@ if openai_key: if firecrawl_key: os.environ["FIRECRAWL_API_KEY"] = firecrawl_key -# Initialize agents only if both keys are provided +# Initialize team only if both keys are provided if openai_key and firecrawl_key: # Agent 1: Competitor Launch Analyst launch_analyst = Agent( @@ -107,10 +108,29 @@ if openai_key and firecrawl_key: exponential_backoff=True, delay_between_retries=2, ) + + # Create the coordinated team + product_intelligence_team = Team( + name="Product Intelligence Team", + mode="coordinate", + model=OpenAIChat(id="gpt-4o"), + members=[launch_analyst, sentiment_analyst, metrics_analyst], + instructions=[ + "Coordinate the analysis based on the user's request type:", + "1. For competitor analysis: Use the Product Launch Analyst to evaluate positioning, strengths, weaknesses, and strategic insights", + "2. For market sentiment: Use the Market Sentiment Specialist to analyze social media sentiment, customer feedback, and brand perception", + "3. For launch metrics: Use the Launch Metrics Specialist to track KPIs, adoption rates, press coverage, and performance indicators", + "Always provide evidence-based insights with specific examples and data points", + "Structure responses with clear sections and actionable recommendations", + "Include sources section with all URLs crawled or searched" + ], + show_tool_calls=True, + markdown=True, + debug_mode=True, + show_members_responses=True, + ) else: - launch_analyst = None - sentiment_analyst = None - metrics_analyst = None + product_intelligence_team = None st.warning("⚠️ Please enter both API keys in the sidebar to use the application.") # ---------------- Helper to display response ---------------- @@ -127,7 +147,7 @@ def display_agent_response(resp): # Helper to expand bullet summary into 1200-word general report def expand_insight(bullet_text: str, topic: str) -> str: - if not launch_analyst: + if not product_intelligence_team: st.error("⚠️ Please enter both API keys in the sidebar first.") return "" @@ -142,12 +162,12 @@ def expand_insight(bullet_text: str, topic: str) -> str: f"Bullet Points:\n{bullet_text}\n\n" f"Ensure analysis is objective, evidence-based and references the bullet insights. Keep paragraphs short (≤120 words)." ) - long_resp = launch_analyst.run(prompt) + long_resp = product_intelligence_team.run(prompt) return long_resp.content if hasattr(long_resp, "content") else str(long_resp) # Helper to craft competitor-focused launch report for product managers def expand_competitor_report(bullet_text: str, competitor: str) -> str: - if not launch_analyst: + if not product_intelligence_team: st.error("⚠️ Please enter both API keys in the sidebar first.") return "" @@ -169,12 +189,12 @@ def expand_competitor_report(bullet_text: str, competitor: str) -> str: f"• Populate the tables with specific points derived from the bullets.\n" f"• Only include rows that contain meaningful data; omit any blank entries." ) - resp = launch_analyst.run(prompt) + resp = product_intelligence_team.run(prompt) return resp.content if hasattr(resp, "content") else str(resp) # Helper to craft market sentiment report def expand_sentiment_report(bullet_text: str, product: str) -> str: - if not sentiment_analyst: + if not product_intelligence_team: st.error("⚠️ Please enter both API keys in the sidebar first.") return "" @@ -188,12 +208,12 @@ def expand_sentiment_report(bullet_text: str, product: str) -> str: f"Provide a short paragraph (≤120 words) summarising the overall sentiment balance and key drivers.\n\n" f"Tagged Bullets:\n{bullet_text}" ) - resp = sentiment_analyst.run(prompt) + resp = product_intelligence_team.run(prompt) return resp.content if hasattr(resp, "content") else str(resp) # Helper to craft launch metrics report def expand_metrics_report(bullet_text: str, launch: str) -> str: - if not metrics_analyst: + if not product_intelligence_team: st.error("⚠️ Please enter both API keys in the sidebar first.") return "" @@ -209,7 +229,7 @@ def expand_metrics_report(bullet_text: str, launch: str) -> str: f"Brief paragraph (≤120 words) highlighting what the metrics imply about launch success and next steps.\n\n" f"KPI Bullets:\n{bullet_text}" ) - resp = metrics_analyst.run(prompt) + resp = product_intelligence_team.run(prompt) return resp.content if hasattr(resp, "content") else str(resp) # ---------------- UI ---------------- @@ -226,7 +246,7 @@ with st.container(): company_name = st.text_input( label="Company Name", placeholder="Enter company name (e.g., OpenAI, Tesla, Spotify)", - help="This company will be analyzed by all three specialized agents", + help="This company will be analyzed by the coordinated team of specialized agents", label_visibility="collapsed" ) with col2: @@ -289,12 +309,12 @@ with analysis_tabs[0]: st.info("⏳ Ready to analyze") if analyze_btn: - if not launch_analyst: + if not product_intelligence_team: st.error("⚠️ Please enter both API keys in the sidebar first.") else: - with st.spinner("🔍 Launch Analyst gathering competitive intelligence..."): + with st.spinner("🔍 Product Intelligence Team analyzing competitive strategy..."): try: - bullets = launch_analyst.run( + bullets = product_intelligence_team.run( f"Generate up to 16 evidence-based insight bullets about {company_name}'s most recent product launches.\n" f"Format requirements:\n" f"• Start every bullet with exactly one tag: Positioning | Strength | Weakness | Learning\n" @@ -353,12 +373,12 @@ with analysis_tabs[1]: st.info("⏳ Ready to analyze") if sentiment_btn: - if not sentiment_analyst: + if not product_intelligence_team: st.error("⚠️ Please enter both API keys in the sidebar first.") else: - with st.spinner("💬 Sentiment Specialist analyzing market perception..."): + with st.spinner("💬 Product Intelligence Team analyzing market sentiment..."): try: - bullets = sentiment_analyst.run( + bullets = product_intelligence_team.run( f"Summarize market sentiment for {company_name} in <=10 bullets. " f"Cover top positive & negative themes with source mentions (G2, Reddit, Twitter, customer reviews)." ) @@ -415,12 +435,12 @@ with analysis_tabs[2]: st.info("⏳ Ready to analyze") if metrics_btn: - if not metrics_analyst: + if not product_intelligence_team: st.error("⚠️ Please enter both API keys in the sidebar first.") else: - with st.spinner("📈 Metrics Specialist analyzing launch performance..."): + with st.spinner("📈 Product Intelligence Team analyzing launch metrics..."): try: - bullets = metrics_analyst.run( + bullets = product_intelligence_team.run( f"List (max 10 bullets) the most important publicly available KPIs & qualitative signals for {company_name}'s recent product launches. " f"Include engagement stats, press coverage, adoption metrics, and market traction data if available." ) @@ -448,7 +468,7 @@ with analysis_tabs[2]: with st.sidebar.container(): st.markdown("### 🤖 System Status") if openai_key and firecrawl_key: - st.success("✅ All agents ready") + st.success("✅ Product Intelligence Team ready") else: st.error("❌ API keys required") @@ -456,7 +476,7 @@ st.sidebar.divider() # Multi-agent system info with st.sidebar.container(): - st.markdown("### 🎯 Specialized Agents") + st.markdown("### 🎯 Coordinated Team") agents_info = [ ("🔍", "Product Launch Analyst", "Strategic GTM expert"), @@ -500,5 +520,3 @@ with st.sidebar.container(): **K** - Market sentiment **L** - Launch metrics """) - else: - st.info("Enter a company name to enable quick actions")