a multi-agent system finding the intersection between product, trend, and audience
trends-2-creatives is a marketing tool for developing data-driven and culturally relevant marketing content. Built with Google’s Agent Development Kit (ADK), this multi-agent system helps users generate ad creatives from trending themes in Google Search and YouTube.
- Build LLM-based agents with models supported in Vertex AI's Model Garden
- Explore trending Search terms and trending YouTube videos
- Conduct web research to better understand the campaign, Search trend, and trending YouTube video
- Draft ad creatives (e.g., image and video) based on trends, campaign themes, or specific prompts
- Clone the repository
git clone https://github.com/tottenjordan/zghost.git- Create a virtual environment and install dependencies
poetry config virtualenvs.in-project true
poetry install- Authenticate and Enable Google Cloud APIs
gcloud auth application-default login
gcloud services enable artifactregistry.googleapis.com \
bigquery.googleapis.com \
logging.googleapis.com \
run.googleapis.com \
storage-component.googleapis.com \
eventarc.googleapis.com \
serviceusage.googleapis.com \
secretmanager.googleapis.com \
aiplatform.googleapis.com \
youtube.googleapis.com- Create and store YouTube API key
- See these instructions for getting a
YOUTUBE_DATA_API_KEY - Store this API key in Secret Manager as
yt-data-api(seeYT_SECRET_MNGR_NAMEin.envfile)- For step-by-step guidance, see create a secret and access a secret version
- Create and populate
.envfile(s)
GOOGLE_GENAI_USE_VERTEXAI=1
GOOGLE_CLOUD_PROJECT=<YOUR_GCP_PROJECT_ID>
GOOGLE_CLOUD_PROJECT_NUMBER=<YOUR_GCP_PROJECT_NUMBER> # e.g., 1234756
GOOGLE_CLOUD_LOCATION=<YOUR_LOCATION> # e.g., us-central1
BUCKET=gs://<YOUR_GCS_BUCKET_NAME> # create a GCS bucket
YT_SECRET_MNGR_NAME=<YOUR_SECRET_NAME> # e.g., yt-data-api
# SESSION_STATE_JSON_PATH=example_state_pixel.json # uncomment to use default config valuescopy .env file to root_agent dir:
cp .env trends_and_insights_agent/.env
cat trends_and_insights_agent/.env
source .env- Create Cloud Storage bucket
gcloud storage buckets create $BUCKET --location=$GOOGLE_CLOUD_LOCATION- Launch the adk developer UI
poetry run adk webOpen your browser and navigate to http://localhost:8000 and select an agent from the drop-down (top left)
INFO: Started server process [750453]
INFO: Waiting for application startup.
+-----------------------------------------------------------------------------+
| ADK Web Server started |
| |
| For local testing, access at http://localhost:8000. |
+-----------------------------------------------------------------------------+
INFO: Application startup complete.
INFO: Uvicorn running on http://0.0.0.0:8000 (Press CTRL+C to quit)If port :8000 in use
find any processes listening to port :8000, kill them, then return to step (7):
lsof -i :8000
kill -9 $PID
lsof -i :8000Example usage
Agent will ask user for campaign metadata in the UI
> [agent]: Hello! I'm your AI Marketing Research & Strategy Assistant... To start, what please provide the following campaign metadata:
* Brand
* Target Product
* Key Selling Points
* Target Audience
[Optional] preload campaign metadata
preload these values using one of the example json configs e.g., shared_libraries/profiles/example_state_pixel.json or upload your own. The json config you wish to reference should be set in your .env file like below. Note: remove or comment out this variable to use default option (1)
SESSION_STATE_JSON_PATH=example_state_prs.json
Note: this section is configured for human-in-the-loop i.e., agent will iterate with user when generating image and video creatives
- Choose a subset of ad copies to proceed with
- Choose a subset of visual concepts to proceed with
- Generate image and video creatives with visual concepts
This demo gives a quick overview of the end-to-end workflow
root_agent (orchestrator)
├── trends_and_insights_agent # Display/capture trend selections
├── research_orchestrator # Coordinate research pipeline
│ ├── combined_research_pipeline # Sub-agent for SequentialAgent workflow
│ │ ├── merge_parallel_insights # Parallel research coordination
│ │ │ ├── parallel_planner_agent # Runs 3 research types simultaneously
│ │ │ │ ├── yt_sequential_planner # YouTube trend analysis
│ │ │ │ ├── gs_sequential_planner # Google Search trend analysis
│ │ │ │ └── ca_sequential_planner # Campaign research
│ │ │ └── merge_planners # Combines research plans
│ │ ├── combined_web_evaluator # Quality check
│ │ ├── enhanced_combined_searcher # Expand web search
│ │ └── combined_report_composer # Generate unified research report
├── ad_content_generator_agent # Create comprehensive ad campaigns
│ ├── ad_creative_pipeline # Ad copy actor-critic framework
│ │ ├── ad_copy_drafter
│ │ ├── ad_copy_critic
│ ├── visual_generation_pipeline # Visual concept actor-critic framework
│ │ ├── visual_concept_drafter
│ │ ├── visual_concept_critic
│ │ └── visual_concept_finalizer
│ └── visual_generator # Image/video generation
└── save_creatives_and_research_report # Compile PDF reports
Expand sections below to visualize complex agent workflows
Research Orchestrator Pipeline
The research workflow has two phases:
- Parallel web research for individual topics: search trend, YouTube video, and campaign metadata e.g., target audience, product, brand, etc.
- Combined web research for the intersection of individual topics
This structure helps us achieve a deeper understanding of each subject first. And this helps us ask better questions for a second round of research where we are solely focused on finding any culturally relevant overlaps to exploit for ad creatives.
Ad Content Generator Pipeline
This agent uses the research report to generate relevant ad copy, visual concepts, and creatives (image and video).
Using pytest, users can test for tool coverage as well as Agent evaluations.
More detail on agent evaluations can be found here, along with how to run a pytest eval.
From the project root, run:
pytest tests/*.pyThe agent can be deployed in a couple of different ways
- Agent Engine
- Here's an end-to-end guide on deploying
- Be sure to first run the
setup_ae_sm_access.shscript to give Agent Engine access to Secret Manager - Run the deployment guide to deploy the agent
- Cloud Run
- Run
deploy_to_cloud_run.sh - Note this runs unit tests prior to deploying
- Run
Script for Cloud Run:
#!/bin/bash
source trends_and_insights_agent/.env
# run unit tests before deploying
pytest tests/*.py
# write requirements.txt to the agent folder
poetry export --without-hashes --format=requirements.txt > trends_and_insights_agent/requirements.txt
#deploy to cloud run
adk deploy cloud_run \
--project=$GOOGLE_CLOUD_PROJECT \
--region=$GOOGLE_CLOUD_LOCATION \
--service_name='trends-and-insights-agent' \
--with_ui \
trends_and_insights_agent/Create an Agent Engine in the notebooks/deployment_guide.ipynb notebook
Then note the Agent Engine ID (last numeric portion of the Resource Name). e.g.:
agent_engine = vertexai.agent_engines.get('projects/679926387543/locations/us-central1/reasoningEngines/1093257605637210112')Update the agent_config_example.json, then run:
./publish_to_agentspace_v2.sh --action create --config agent_config.jsonUsage: ./publish_to_agentspace_v2.sh [OPTIONS]
Options:
-a, --action <create|update|list|delete> Action to perform (required)
-c, --config <file> JSON configuration file
-p, --project-id <id> Google Cloud project ID
-n, --project-number <number> Google Cloud project number
-e, --app-id <id> Agent Space application ID
-r, --reasoning-engine <id> Reasoning Engine ID (required for create/update)
-d, --display-name <name> Agent display name (required for create/update)
-s, --description <desc> Agent description (required for create)
-i, --agent-id <id> Agent ID (required for update/delete)
-t, --instructions <text> Agent instructions/tool description (required for create)
-u, --icon-uri <uri> Icon URI (optional)
-l, --location <location> Location (default: us)
-h, --help Display this help message./publish_to_agentspace_v2.sh --action create --config agent_config.json
./publish_to_agentspace_v2.sh --action update --config agent_config.json
./publish_to_agentspace_v2.sh --action list --config agent_config.json
./publish_to_agentspace_v2.sh --action delete --config agent_config.jsonCreate agent:
./publish_to_agentspace_v2.sh --action create --project-id my-project --project-number 12345 \
--app-id my-app --reasoning-engine 67890 --display-name 'My Agent' \
--description 'Agent description' --instructions 'Agent instructions here'Update agent:
./publish_to_agentspace_v2.sh --action update --project-id my-project --project-number 12345 \
--app-id my-app --reasoning-engine 67890 --display-name 'My Agent' \
--agent-id 123456789 --description 'Updated description'List agents:
./publish_to_agentspace_v2.sh --action list --project-id my-project --project-number 12345 \
--app-id my-appDelete agent:
./publish_to_agentspace_v2.sh --action delete --project-id my-project --project-number 12345 \
--app-id my-app --agent-id 123456789







