Skip to content

Commit c9b9428

Browse files
tkhouwtommywagz
authored andcommitted
product catalog ad generation agent update (#815)
1 parent 823f2da commit c9b9428

File tree

17 files changed

+705
-384
lines changed

17 files changed

+705
-384
lines changed

python/agents/product-catalog-ad-generation/README.md

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
This project is a Personalized Ad Generation Assistant that helps marketing teams generate short-form video ads grounded in their product catalog. The agent pulls product metadata from a catalog (e.g., BigQuery), validates demographic targeting, and generates a video using product imagery and corporate branding standards. A human-in-the-loop feedback mechanism allows for iterative refinement of the generated ad.
66

7-
The agent is defined in `content_gen_agent/agent.py` and uses the `gemini-2.5-pro` model. It orchestrates a multi-step workflow that includes product selection, storyline generation, image and video creation, and final ad assembly, with opportunities for human feedback at key stages.
7+
The agent is defined in `content_gen_agent/agent.py` and uses the `gemini-3-flash-preview` model. It orchestrates a multi-step workflow that includes product selection, storyline generation, image and video creation, and final ad assembly, with opportunities for human feedback at key stages.
88

99
This project contains default product imagery and a corporate logo that will get loaded into BigQuery as part of the deployment script.
1010

@@ -37,6 +37,11 @@ This project contains default product imagery and a corporate logo that will get
3737
└── ...
3838
```
3939

40+
## Requirements
41+
42+
Before you begin, ensure you have:
43+
- **Google Cloud SDK**: For GCP services - [Install](https://cloud.google.com/sdk/docs/install)
44+
4045
## Setup Scripts
4146

4247
The `scripts/` directory contains a series of automation scripts to set up the necessary Google Cloud infrastructure for the project. These scripts must be run in order.
@@ -95,6 +100,8 @@ To add your own products to the system, upload your product images to the `stati
95100

96101
## Usage
97102

103+
After installing dependencies, the product catalog ad generation agent can be run via the `adk web` command.
104+
98105
The main agent orchestrates the entire ad generation workflow, which can be broken down into the following steps:
99106

100107
1. **Product Selection & Demographic Targeting**: The user provides a product name and desired demographic. The agent queries a BigQuery table to fetch product details and validates that the product is suitable for the target audience.
@@ -107,17 +114,17 @@ The main agent orchestrates the entire ad generation workflow, which can be brok
107114

108115
### Bring Your Own Asset Sheet
109116

110-
You can provide your own "asset sheet" as long as it includes the product image you are asking for. You can do this by pasting the "GCS URI" into your chat, and the agent will take this and download it. The agent will then use that asset sheet as context to generate the storyline, and move forward through the rest of the flow. Note that this allows you to skip the "product image" upload as long as it exists in your asset sheet. The GCS URI can be from any bucket that the authenticated user has access to.
117+
You can provide your own "asset sheet" as long as it includes the product image you are asking for. You can either 1) upload the image directly through the ADK web UI or 2) paste the "GCS URI" of an asset sheet into your chat, and the agent will fetch it. The agent will then use your asset sheet as context to generate the storyline, and move forward through the rest of the flow. Note that this allows you to skip the "product image" upload as long as it exists in your asset sheet. The GCS URI can be from any bucket that the authenticated user has access to.
111118

112119
### Bring Your Own Product Photo
113120

114-
Similarly, you can provide a direct GCS URI for a product photo instead of relying on the product selection from BigQuery. If you provide a GCS URI for the `product_photo_filename` parameter when calling the agent, it will download the image from that URI and use it as the product photo for the ad generation process.
121+
Similarly, you can provide a product photo either directly through the ADK web UI or as a GCS URI instead of relying on the product selection from BigQuery. If you provide a GCS URI for the `product_photo_filename` parameter when calling the agent, it will download the image from that URI and use it as the product photo for the ad generation process.
115122

116123
### Hardcoded Configurations
117124

118125
The behavior of the agent is influenced by several hardcoded configurations in the `content_gen_agent` directory:
119126

120-
- **Models**: The agent uses `gemini-2.5-pro` for storyline generation and `gemini-3-pro-image-preview` for image generation. The video generation is handled by `veo-3.1-generate-preview`, and the audio is generated using `lyria-002` and `gemini-2.5-flash-preview-tts`.
127+
- **Models**: The agent uses `gemini-3-flash-preview` for storyline generation and `gemini-3-pro-image-preview` for image generation. The video generation is handled by `veo-3.1-generate-preview`, and the audio is generated using `lyria-002` and `gemini-2.5-flash-preview-tts`. Note that some of these models may only be available in the "global" region of Google Cloud.
121128
- **Company Name**: The `COMPANY_NAME` can be set in the `.env` file. If not set, it defaults to "ACME Corp". This influences the branding of the generated content.
122129
- **Video Aspect Ratio**: All generated videos adhere to a `9:16` aspect ratio, suitable for short-form content platforms.
123130
- **Logo**: The company logo is hardcoded in `static/uploads/branding/logo.png` and is uploaded to GCS during the `02-deploy-gcs-and-bq.sh` setup script.

python/agents/product-catalog-ad-generation/content_gen_agent/agent.py

Lines changed: 49 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,9 @@
2121
import os
2222

2323
from google.adk.agents import Agent
24-
from google.adk.tools import FunctionTool
24+
from google.adk.apps import App
25+
from google.adk.plugins.save_files_as_artifacts_plugin import SaveFilesAsArtifactsPlugin
26+
from google.adk.tools import FunctionTool, load_artifacts
2527

2628
from .func_tools.combine_video import combine
2729
from .func_tools.generate_audio import generate_audio_and_voiceover
@@ -31,49 +33,77 @@
3133
from .utils.storytelling import STORYTELLING_INSTRUCTIONS
3234

3335
COMPANY_NAME = os.environ.get("COMPANY_NAME", "ACME Corp")
34-
SYSTEM_INSTRUCTION: str = f"""ROLE: You are a Personalized Ad Generation Assistant. \
35-
By default you are an assistant for {COMPANY_NAME}, \
36+
SYSTEM_INSTRUCTION: str = f"""
37+
ROLE: You are a Personalized Ad Generation Assistant.
38+
By default you are an assistant for {COMPANY_NAME},
3639
but the user can override your company name if they ask.
3740
38-
**🛑 CORE RULE: NEVER execute a function or call a tool without first receiving explicit verbal confirmation to proceed.**
41+
**🛑 CORE RULE: NEVER execute a function or call a tool without first
42+
receiving explicit verbal confirmation to proceed.**
3943
40-
TASK: Your goal is to orchestrate the generation of a short-form ad (under 15 seconds). You will use a team of specialized functions to accomplish this.
44+
TASK: Your goal is to orchestrate the generation of a short-form ad
45+
(under 15 seconds). You will use a team of specialized functions to
46+
accomplish this.
4147
4248
**Workflow:**
43-
1. **Storyline Generation:** Use the `generate_storyline` tool to create a compelling "before and after" narrative and a detailed visual style guide.
44-
2. **Image Generation:** After storyline and asset sheet are generated, generate a series of consistent images for the storyboard.
45-
3. **Video Generation:** Use the `generate_video` tool to bring the images to life.
46-
4. **Audio & Voiceover Generation:** Use the `generate_audio_and_voiceover` tool to create both a catchy soundtrack and a voiceover in one step.
47-
5. **Final Assembly:** Use the `combine` tool to merge the video, audio, and voiceover into the final ad.
49+
1. **Storyline Generation:** Use the `generate_storyline` tool to create a
50+
compelling "before and after" narrative and a detailed visual style guide.
51+
2. **Image Generation:** After storyline and asset sheet are generated,
52+
generate a series of consistent images for the storyboard.
53+
3. **Video Generation:** Use the `generate_video` tool to bring the images to
54+
life.
55+
4. **Audio & Voiceover Generation:** Use the `generate_audio_and_voiceover`
56+
tool to create both a catchy soundtrack and a voiceover in one step.
57+
5. **Final Assembly:** Use the `combine` tool to merge the video, audio, and
58+
voiceover into the final ad.
4859
4960
**Guidance:**
5061
- Always guide the user step-by-step.
51-
- Before executing any tool, present the proposed inputs and **STOP** to ask for the user's confirmation.
62+
- Before executing any tool, present the proposed inputs and **STOP** to ask
63+
for the user's confirmation.
5264
- Ensure all generated content adheres to a **9:16 aspect ratio**.
53-
- When possible, try to parallelize the video and audio generation functions upon user confirmation.
65+
- When possible, try to parallelize the video and audio generation functions
66+
upon user confirmation.
5467
- Avoid generating children.
55-
- Each scene generated is done so in isolation. Instruct prompts as though they were each generated distinctly, with only the asset sheet as reference across scenes.
68+
- Each scene generated is done so in isolation. Instruct prompts as though
69+
they were each generated distinctly, with only the asset sheet as reference
70+
across scenes.
5671
5772
**TOOLS:**
58-
- **generate_storyline**: Generates the ad's narrative and visual style guide. It can optionally accept a `style_guide` parameter to customize the visual style of the generated assets.
59-
- **generate_images_from_storyline**: Generates images based on the storyline and asset sheet.
60-
- **generate_video**: A longer async tool that generates a list of videos based on previously generated images and input prompts.
61-
- **generate_audio_and_voiceover**: A longer async tool that generates both a music clip and a voiceover in one step.
62-
- **combine**: The final step, combining video, audio, and voiceover into a single file.
73+
- **load_artifacts**: Call if the user uploaded a file that you're wanting to
74+
pass to other tools via the Tool Context
75+
- **generate_storyline**: Generates the ad's narrative and visual style guide.
76+
It can optionally accept a `style_guide` parameter to customize the visual
77+
style of the generated assets.
78+
- **generate_images_from_storyline**: Generates images based on the storyline
79+
and asset sheet.
80+
- **generate_video**: A longer async tool that generates a list of videos
81+
based on previously generated images and input prompts.
82+
- **generate_audio_and_voiceover**: A longer async tool that generates both a
83+
music clip and a voiceover in one step.
84+
- **combine**: The final step, combining video, audio, and voiceover into a
85+
single file.
6386
6487
{STORYTELLING_INSTRUCTIONS}
6588
6689
"""
6790

6891
root_agent = Agent(
6992
name="content_generation_agent",
70-
model="gemini-2.5-pro",
93+
model="gemini-3-flash-preview",
7194
instruction=SYSTEM_INSTRUCTION,
7295
tools=[
96+
load_artifacts,
7397
FunctionTool(func=generate_storyline),
7498
FunctionTool(func=generate_images_from_storyline),
7599
FunctionTool(func=combine),
76100
FunctionTool(func=generate_video),
77101
FunctionTool(func=generate_audio_and_voiceover),
78102
],
79103
)
104+
105+
app = App(
106+
name="content_gen_agent",
107+
root_agent=root_agent,
108+
plugins=[SaveFilesAsArtifactsPlugin()],
109+
)

python/agents/product-catalog-ad-generation/content_gen_agent/func_tools/combine_video.py

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -251,7 +251,11 @@ async def _combine_and_upload_video(
251251
try:
252252
final_clip = concatenate_videoclips(video_clips, method="compose")
253253
final_clip.audio = await _load_and_process_audio_clips(
254-
audio_file, voiceover_file, final_clip.duration, tool_context, temp_dir
254+
audio_file,
255+
voiceover_file,
256+
final_clip.duration,
257+
tool_context,
258+
temp_dir,
255259
)
256260

257261
filename = f"combined_video_{int(time.time())}.mp4"
@@ -294,7 +298,8 @@ async def combine(
294298
video_files (List[str]): A list of video artifact filenames.
295299
audio_file (str): The filename of the background audio artifact.
296300
num_images (int): The number of images in the storyline.
297-
tool_context (ToolContext): The context for tool execution and artifact management.
301+
tool_context (ToolContext): The context for tool execution and
302+
artifact management.
298303
voiceover_file (Optional[str]): The filename of the voiceover artifact.
299304
Defaults to None.
300305

0 commit comments

Comments
 (0)