feat: updated coordinated team structure for product launch intelligence agent

This commit is contained in:
ShubhamSaboo 2025-07-13 20:31:54 -05:00
parent 7c1341642a
commit 8c4fd9193d
2 changed files with 58 additions and 30 deletions

View file

@ -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.

View file

@ -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")