feat: updated coordinated team structure for product launch intelligence agent
This commit is contained in:
parent
7c1341642a
commit
8c4fd9193d
2 changed files with 58 additions and 30 deletions
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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")
|
||||
|
|
|
|||
Loading…
Reference in a new issue