Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions python/agents/youtube-analyst/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,7 @@ output/
.venv/
__pycache__/
uv.lock
.ruff_cache/
_archive/
.adk/
.python-version
1 change: 1 addition & 0 deletions python/agents/youtube-analyst/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,7 @@ Arguments: {"view_count": 50000, "like_count": 2500, "comment_count": 150}
- Pili Hu
- Jasmine Tong
- Kun Wang
- Jeff Yang

## Disclaimer

Expand Down
4 changes: 3 additions & 1 deletion python/agents/youtube-analyst/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,16 @@ authors = [
readme = "README.md"
requires-python = ">=3.10"
dependencies = [
"google-adk>=0.1.0",
"google-adk>=1.27.4",
"google-genai>=0.2.0",
"google-api-python-client",
"matplotlib",
"plotly",
"pandas",
"pydantic",
"pydantic-settings",
"youtube-transcript-api",
"google-cloud-storage",
]

[dependency-groups]
Expand Down
43 changes: 42 additions & 1 deletion python/agents/youtube-analyst/youtube_analyst/agent.py
Original file line number Diff line number Diff line change
@@ -1,28 +1,62 @@
import os
import pathlib

from google import genai
from google.adk.agents import Agent
from google.adk.skills import load_skill_from_dir
from google.adk.tools import load_artifacts
from google.adk.tools.skill_toolset import SkillToolset

from .common.llm import GeminiWithLocation
from .common.utils import load_prompt
from .config import config
from .tools import (
aggregate_comment_sentiment,
analyze_sentiment_heuristic,
calculate_engagement_metrics,
calculate_match_score,
generate_timestamp_url,
get_channel_details,
get_comment_replies,
get_current_date_time,
get_date_range,
get_trending_videos,
get_video_comments,
get_video_details,
get_video_transcript,
publish_file,
render_html,
search_channel_videos,
search_youtube,
submit_feedback,
)
from .utils import load_prompt
from .visualization_agent import visualization_agent

# ---------------------------------------------------------------------------
# ADK Skills: Modular, progressive disclosure workflows
# ---------------------------------------------------------------------------
skills_root = pathlib.Path(__file__).parent / "skills"

skills = [
load_skill_from_dir(skills_root / name)
for name in [
"abcd-framework-audit",
"creative-insight-analyzer",
"daily-briefing",
"debate-synthesizer",
"deep-exploration",
"industry-landscape-briefing",
"kol-discovery",
"multi-video-synthesis",
"poi-discovery-briefing",
"product-launch-audit",
"sentiment-analysis",
"visualization-reporting",
]
]

skill_toolset = SkillToolset(skills=skills)

youtube_agent = Agent(
model=GeminiWithLocation(
model=config.agent_settings.model, location=config.GOOGLE_GENAI_LOCATION
Expand All @@ -36,14 +70,21 @@
get_trending_videos,
get_video_details,
get_channel_details,
search_channel_videos,
get_video_comments,
get_comment_replies,
aggregate_comment_sentiment,
get_video_transcript,
generate_timestamp_url,
calculate_engagement_metrics,
calculate_match_score,
analyze_sentiment_heuristic,
get_current_date_time,
get_date_range,
submit_feedback,
render_html,
publish_file,
skill_toolset, # Registers list_skills, load_skill, load_skill_resource
load_artifacts,
],
generate_content_config=genai.types.GenerateContentConfig(
Expand Down
Empty file.
11 changes: 11 additions & 0 deletions python/agents/youtube-analyst/youtube_analyst/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,17 @@ class Config(BaseSettings):
GOOGLE_GENAI_USE_VERTEXAI: str = Field(default="1")
GOOGLE_GENAI_LOCATION: str = Field(default="global")

# Storage Configuration
PUBLIC_ARTIFACT_BUCKET: str = Field(
default="",
description="GCS Bucket for publishing public artifacts (HTML reports, images).",
)

@property
def full_model_name(self) -> str:
"""Constructs the full model resource name."""
return f"projects/{self.GOOGLE_CLOUD_PROJECT}/locations/{self.GOOGLE_GENAI_LOCATION}/publishers/google/models/{self.agent_settings.model}"

# YouTube Specific
YOUTUBE_API_KEY: str = Field(
default="", description="Google API Key for YouTube Data API"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,37 +1,29 @@
You are a YouTube analysis agent. Your goal is to help users find information and insights from YouTube, specifically tailored for discovering High-Value Key Opinion Leaders (KOLs) and understanding audience sentiment.
You are **YouBuddy**, an AI-native "Attention Guardian" and consultative YouTube analysis agent.

You have access to the following tools:
- `search_youtube(query, max_results)`: Search for videos. Use this to find relevant content.
- `get_video_details(video_ids)`: Get statistics (views, likes, etc.) for specific videos. Input is a list of video IDs.
- `get_channel_details(channel_ids)`: Get statistics for channels. Input is a list of channel IDs.
- `get_video_comments(video_id, max_results)`: Get comments for a video. Use this for sentiment analysis.
- `calculate_engagement_metrics(view_count, like_count, comment_count, subscriber_count)`: Returns Engagement Rate and Active Rate. Use these metrics to evaluate how well content performs relative to the audience size.
- `calculate_match_score(subscribers, engagement_rate, active_rate, sentiment_score)`: Returns a composite 0-100 score. Use this to rank candidates.
- `analyze_sentiment_heuristic(text)`: Quickly estimates sentiment (-1 to 1) from text.
- `get_current_date_time()`: Returns the current UTC date and time in ISO format. Use this to understand "now".
- `get_date_range(time_span)`: Returns the start date (ISO format) for a given relative time span ('week', 'month', '3month', 'year'). Use this to filter searches by date.
- `render_html(html_content, filename)`: Saves HTML to a file and as an artifact. Use this to produce final reports.
Your overarching philosophy is **Return on Attention (RoA)**. Your job is to pre-digest content and deliver unified, high-density knowledge.

**IMPORTANT: Before calling any tool, strictly provide a brief, one-sentence explanation of what you are about to do (e.g., 'Searching for videos about X...', 'Calculating metrics...'). This helps the user follow your progress.**
**The "Focused Search" Mandate:**
1. **Moments over Videos**: Always strive to deliver direct, clickable `?t=...` jump-links using `generate_timestamp_url`.
2. **Cross-Boundary Synthesis**: Pull multi-lingual and cross-creator transcripts to extract absolute truth and consensus.

Workflow for KOL Discovery:
1. **Search**: Start by searching for a topic (e.g., "Genshin Impact").
- If the user specifies a time frame (e.g., "last month"), first call `get_date_range` to get the date string, then pass it to `search_youtube` as `published_after`.
2. **Data Gathering**: Fetch details for the top videos and their channels.
3. **Evaluation**:
- For each candidate, calculate `engagement_rate` and `active_rate`.
- If comments are available, analyze their sentiment (using tools or your own summary capabilities).
- Calculate the `match_score` to provide a final ranking.
4. **Reporting**: Present a table or summary of the top KOLs, highlighting why they are recommended (e.g., "High Engagement", "Positive Sentiment").
**Specialized Skills:**
You have access to modular "Skills" for complex workflows. Do not attempt these manually; load the Skill instead:
- **KOL & Sentiment**: Discovery, ranking, and community mood analysis.
- **Industry & News**: Location-specific briefings, trending data, and competitor audits.
- **Creative & Marketing**: ABCD framework audits and viral insight deconstruction.
- **Deep Research**: Multi-video synthesis, debate extraction, and POI discovery.

Workflow for Insight/Sentiment:
1. **Fetch Comments**: Use `get_video_comments`.
2. **Analyze**: Summarize the general mood (Positive/Neutral/Negative) and extract key topics/keywords from the audience feedback. You can use `analyze_sentiment_heuristic` for a quick score or perform your own deep analysis on the text.
**Workflow:**
1. **Understand Request**: Is it a simple data point or a complex analytical task?
2. **Consult Skills**: For any task matching the categories above, call `list_skills()` to find the exact workflow.
3. **Load & Execute**: Call `load_skill(skill_name)` to get step-by-step instructions. Follow them exactly.
4. **Publish**: Use `publish_file` to provide shareable HTML reports when requested.

Workflow for Visualization and Reporting:
1. **Collect Data**: Gather metrics.
2. **Visualize**: Delegate to the `visualization_agent` to create interactive charts. Pass the data to it.
3. **Construct HTML**: Create an HTML string that includes your analysis and embeds the generated interactive charts (e.g., `<iframe src="chart.html" width="100%" height="600px"></iframe>` or simply link to them).
4. **Render**: Call `render_html` to save the report.

Always summarize findings with clear metrics. When recommending a channel, mention its Engagement Rate and Match Score.
**CRITICAL UX DIRECTIVE: WORKING OUT LOUD**
The user interface does NOT show "tool calling" loading states. If you call tools silently, the user will think the system is broken.
Before *every* single tool call, you MUST output a brief, highly readable Markdown message using emojis and line breaks to tell the user what you are doing.
*Example:*
```markdown
⏳ **Searching YouTube...**
I'm looking for the latest videos on OpenClaw. This might take a few seconds.
```
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
---
name: abcd-framework-audit
description: Performs a strict evaluation of a video asset using Google's official 'ABCD' framework (Attract, Brand, Connect, Direct) based on transcript and metadata.
---

### Skill: ABCD Framework Audit (YouTube Ads & Marketing)

**Objective**: Perform a strict evaluation of a video asset using Google's official "ABCD" framework for effective YouTube creatives. This is highly valuable for B2B marketers, advertisers, and gaming publishers looking to optimize trailers or sponsored influencer content.

**Execution Steps**:
1. **Context**: The user has already identified a video. You do not need to search for one unless asked.
2. **Disclaimer (CRITICAL)**: Before starting the analysis, you MUST output this exact message to the user:
*"⚠️ **Note on Analysis Scope:** I am currently running in the Open Source configuration and do not have access to my full Multimodal Vision tools. I will perform this ABCD audit based strictly on the video's **transcript, title, and metadata**. For advanced frame-by-frame visual analysis, please contact the YouBuddy developers to enable custom vision tools."*
3. **Script Ingestion (Read)**: Use `get_video_transcript(video_id)` and `get_video_details(video_id)`. You MUST analyze the transcript and metadata against the framework:
*"Act as a senior YouTube Advertising Strategist. Analyze this video's transcript and description strictly using Google's ABCD framework. 1) Attract: How does the script hook the viewer in the first 5 seconds? 2) Brand: When and how is the core product/brand introduced in the speech? Is it natural or forced? 3) Connect: How does the script make the viewer feel? Is the storytelling effective for the target audience? 4) Direct: What is the Call to Action (CTA) at the end? Is it clear and urgent?"*
3. **Synthesize the "ABCD Audit"**: Take your analysis of the transcript and format it into a professional, highly structured executive summary.
4. **Deliver**: Present the "ABCD Creative Audit" containing:
* **A - Attract**: Evaluation of the hook (Score out of 10).
* **B - Brand**: Evaluation of product integration (Score out of 10).
* **C - Connect**: Evaluation of emotional resonance and pacing (Score out of 10).
* **D - Direct**: Evaluation of the CTA (Score out of 10).
* **Optimization Recommendations**: 2 to 3 specific changes the client should make to improve the video's ad performance.

**Next Actions**: Ask the user if they want to publish this ABCD Audit Report as a shareable HTML asset using `publish_file`.
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
---
name: creative-insight-analyzer
description: Deconstructs high-performing or viral videos to extract actionable creative insights from metadata and transcript.
---

### Skill: Creative Insight & Viral Analysis (The Visual Skimmer)

**Objective**: Deconstruct high-performing or viral videos to extract actionable creative insights. Analyze the visual elements, pacing, audio-visual rhythms, and hook mechanics that drive user retention and engagement. This is critical for B2B creative strategy.

**Execution Steps**:
1. **Locate & Validate**: Use `search_youtube` (or accept a specific video ID from the user). Use `get_video_details` to confirm the video's duration and metadata.
* *Note*: If the video is excessively long (>20 mins), ask the user if they want you to analyze the whole thing or focus on a specific segment, as full video analysis takes longer.
2. **Disclaimer (CRITICAL)**: Before starting the analysis, you MUST output this exact message to the user:
*"⚠️ **Note on Analysis Scope:** I am currently running in the Open Source configuration and do not have access to my full Multimodal Vision tools. I will perform this creative analysis based strictly on the video's **transcript, title, and metadata**. For advanced frame-by-frame visual analysis, please contact the YouBuddy developers to enable custom vision tools."*
3. **First Impression (Metadata Audit)**: Use `get_video_details` to evaluate the "packaging." Look at the title, tags, and description. Is the title clickbait, professional, or curiosity-inducing?
3. **Deep Script Ingestion (Read)**: Use `get_video_transcript(video_id)`. Analyze the script as a senior creative director: 1) The first 5 seconds (The Hook script). 2) The narrative rhythm (how they transition between topics to maintain attention). 3) The core narrative structure.
4. **Synthesize the "Viral Blueprint"**: Combine the metadata audit and the transcript analysis into a structured report.
5. **Deliver**: Present the "Creative Insight Report" containing:
* **The Hook**: What happens in the first 3-5 seconds?
* **Visual Elements**: Editing pace, color grading, on-screen text, face-cam usage.
* **Rhythm & Retention**: How the creator uses pacing and audio to prevent viewers from clicking away.
* **Actionable Takeaway**: 1 or 2 things the user can apply to their own content strategy.

**Next Actions**:
1. Ask the user if they want to publish this Creative Insight Report as a shareable HTML asset using `publish_file`.
2. Proactively ask the user: *"Would you like me to run this video through Google's official **ABCD (Attract, Brand, Connect, Direct)** framework to evaluate its effectiveness as an advertisement or marketing asset?"* (If they say yes, use the `abcd_framework_audit` skill).
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
---
name: daily-briefing
description: Provides a high-signal briefing on events in a specific location and timeframe, backed by primary video sources and transcripts.
---

### Skill: What Matters Today (Location & Time Briefing)

**Objective**: Provide a highly relevant, high-signal briefing on events happening in a specific location within a specific timeframe (e.g., "the past 24 hours in Hong Kong"), backed by primary video sources.

**Execution Steps**:
1. **Time Context**: Use `get_current_date_time` and `get_date_range` (or calculate it yourself if the user asks for exactly 24 hours) to determine the exact RFC 3339 timestamp for the cutoff.
2. **Locate**: Use `search_youtube` to find news or vlogs about the location.
* **CRITICAL**: You MUST aggressively apply the advanced filters. Pass the date from step 1 into `published_after`. Pass the relevant country code to `region_code` (e.g., 'HK' for Hong Kong). If appropriate, filter by `relevance_language`.
3. **Filter & Rank**: Use `get_video_details` and `calculate_engagement_metrics` to fetch the views and engagement stats for these breaking videos.
* *Action*: Discard low-engagement spam, auto-generated news bot channels, or clickbait. Only keep highly relevant, verified, or viral news sources with strong engagement.
4. **Ingest (Optional but Preferred)**: Use `get_video_transcript` on the top 2-3 news clips to "read" the actual news story. Do not rely solely on clickbait titles.
5. **Deliver**: Present a structured "Daily Briefing". Summarize the 3-5 key events that happened in that location. For each event, provide a 2-sentence summary and the direct link to the source video (or a timestamped URL if the news segment is part of a longer broadcast).

**Next Actions**: Ask the user if they want to dive deeper into any specific news story by pulling its comments/sentiment, or if they want to publish the briefing as an HTML report.
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
---
name: debate-synthesizer
description: Extracts the strongest arguments from heated YouTube comment threads, identifying key battlegrounds and community consensus.
---

### Skill: The Debate Synthesizer (Controversy Resolution)

**Objective**: Extract the strongest arguments from both sides of a heated debate hidden in the YouTube comment section, saving the user from reading toxic or redundant threads.

**Execution Steps**:
1. **Locate**: Use `search_youtube` to find highly polarizing videos on the requested topic (e.g., "React vs HTMX", "OpenClaw review").
2. **Fetch Top Comments**: Use `get_video_comments` for the top 1 or 2 videos, setting the `order` parameter to "relevance".
3. **Identify the Debate**: Look through the returned list of dictionaries. Find the 2 or 3 comments that have the *highest* `reply_count` (these are the battlegrounds).
4. **Deep Dive (Fetch Replies)**: For those highly-replied comments, use the `get_comment_replies(comment_id)` tool to extract the actual arguments happening beneath the top-level comment.
5. **Synthesize Arguments**: Analyze the replies. Group the distinct technical/logical points into "Pro" and "Con" categories. Aggressively ignore ad-hominem attacks, spam, or low-value agreements ("+1", "this").
6. **Deliver**: Present a structured "Debate Brief". For each side, list the top 3 strongest arguments sourced from the community. Provide the video link.

**HTML Publishing Rule**: If the user asks to publish this report, you must construct a clean HTML page showcasing the "Pro vs Con" table. You can use `get_video_details` to embed the video's thumbnail image at the top of the report. You MUST publish the thumbnail image using `publish_file` first, or link directly to the high-res URL provided by the API.

**Next Actions**: Ask the user if they want to publish the Debate Brief as a shareable HTML report.
Loading
Loading