# Capstone: a real end-to-end Gemini workflow
Let's build one realistic thing end to end: a competitive intelligence assistant that reads your industry every morning, watches your competitors, and drops a grounded briefing into a Google Doc before you finish coffee. We'll make the architecture decisions out loud so you can swap the domain (legal, sales, research, recruiting) and reuse the skeleton.
The point of a capstone is not the demo. It is the set of choices: which model tier, where the work runs, how facts stay fresh, and what triggers the whole thing. Get those right and the workflow survives contact with reality.
The assistant has four jobs every weekday at 7:00 a.m.:
1. Pull the latest news and announcements about three named competitors.
2. Read any PDFs or slide decks you dropped in a Drive folder yesterday (pricing sheets, analyst reports).
3. Synthesize a one-page briefing with sources.
4. Append it to a running "Competitive Intel" Doc and email you the highlights.
Constraints that drive the design:
You have three real homes for Gemini work, and they are not interchangeable.
The clean split for this capstone: Apps Script is the orchestrator and Workspace integration layer; the Gemini API does the heavy reasoning and grounding. Apps Script gives you a built-in scheduler (time-driven triggers), native access to Drive/Docs/Gmail, and a place for teammates to read the prompt. The APIAPIApplication Programming Interface: a standardised interface that lets applications communicate and exchange data without knowing each other's internal workings.Voir la définition complète → gives you model control your Workspace UI does not expose, like grounding configuration and JSON schemas.
If this were a larger, multi-step agent with tool use and memory, you would reachreachThe number of unique people exposed to your message in a given period. Unlike impressions, reach counts each person once, no matter how often they see it.Voir la définition complète → for the Agent Development Kit (ADK) on Vertex AI instead. We will come back to that line in the sand.
You have Pro and Flash tiers. The instinct to use the biggest model everywhere is expensive and slow. Split by task.
This two-tier pattern (Flash for fan-out, Pro for the final judgment) is the single most useful cost lever in production Gemini work. Decide tier per *task*, not per *project*.
Your training-data knowledge is stale by definition, so the competitor news step uses grounding with Google Search. Grounding tells the model to issue real searches and return answers tied to live results, with citation metadatametadataDonnées sur les données, informations décrivant le contexte, la structure, la provenance et les caractéristiques d'un asset de données (auteur, date, format, source, définition). you can render as links.
You enable it as a tool on the request. Here is the core synthesis call in Python using the google-genai SDK, with search grounding on:
from google import genai
from google.genai import types
client = genai.Client() # reads GEMINI_API_KEY from env
grounding = types.Tool(google_search=types.GoogleSearch())
resp = client.models.generate_content(
model="gemini-2.5-pro",
contents=(
"Summarize this week's announcements, pricing changes, and "
"product launches for Acme, Globex, and Initech. Flag anything "
"that affects our positioning. Cite every claim."
),
config=types.GenerateContentConfig(
tools=[grounding],
temperature=0.3,
),
)
print(resp.text)
# resp.candidates[0].grounding_metadata holds the source URLsLow temperature because this is analysis, not brainstorming. The grounding_metadata on the response carries the supporting links, so your briefing can footnote every claim. That citation trail is what makes the output trustworthy enough to forward to an executive. Check the grounding docs for the current metadatametadataDonnées sur les données, informations décrivant le contexte, la structure, la provenance et les caractéristiques d'un asset de données (auteur, date, format, source, définition). shape.
The Drive folder may contain a competitor's PDF pricing sheet and a screenshot of a pricing table from a webinar. You do not OCR these separately. Gemini is natively multimodal: hand it the PDF bytes and the image directly in the same request, and its long context window lets you include several full documents at once instead of chunking them.
This is the part of the workflow where you genuinely do *not* need RAG. RAG earns its keep when your corpus is far bigger than the context windowcontext windowThe context window is the maximum amount of text (measured in tokens) a language model can process at once, including both the input prompt and the generated output.Voir la définition complète →. For "the three files someone dropped yesterday," stuffing them straight into a long-context prompt is simpler, cheaper to build, and loses no fidelity. Knowing when to skip the retrieval layer is an architecture skill.
from pathlib import Path
pdf = client.files.upload(file="reports/globex_pricing.pdf")
chart = client.files.upload(file="reports/webinar_chart.png")
extract = client.models.generate_content(
model="gemini-2.5-flash",
contents=[
pdf, chart,
"Extract every price, tier name, and feature change. "
"Return JSON: {items: [{vendor, tier, price, note}]}.",
],
config=types.GenerateContentConfig(
response_mime_type="application/json",
),
)Note response_mime_type="application/json". Asking for structured output instead of prose is what lets the next step (the Apps Script writer) consume the result reliably. Two more reasons this is Flash, not Pro: it runs once per file, and extraction is mechanical.
Now wire it together. The scheduler is an Apps Script time-driven trigger, the cheapest reliable cron you already own inside Workspace. The script calls your APIAPIApplication Programming Interface: a standardised interface that lets applications communicate and exchange data without knowing each other's internal workings.Voir la définition complète → endpoint (or calls Gemini directly via UrlFetchApp), then writes results into Docs and Gmail with native services.
Here the orchestrator lives in Apps Script. It runs at 7 a.m., calls your synthesis service, and appends the briefing:
function dailyBriefing() {
const payload = { date: new Date().toISOString().slice(0, 10) };
const res = UrlFetchApp.fetch("https://your-service/brief", {
method: "post",
contentType: "application/json",
payload: JSON.stringify(payload),
});
const brief = JSON.parse(res.getContentText());
const doc = DocumentApp.openById("YOUR_DOC_ID").getBody();
doc.appendParagraph(brief.title).setHeading(DocumentApp.ParagraphHeading.HEADING2);
doc.appendParagraph(brief.summary);
brief.sources.forEach(s => doc.appendListItem(s.url));
GmailApp.sendEmail("you@company.com", "Daily Intel: " + brief.title, brief.summary);
}You set the 7 a.m. trigger once in the Apps Script UI under Triggers, or programmatically with ScriptApp.newTrigger. No server to babysit, no separate scheduler bill. If you want this purely server-side instead, run the Python on Cloud Run with Cloud Scheduler; the trade-off is more infra control for more setup.
Vérification des acquis
1. According to the lesson, what is the real value of building a capstone workflow?
2. Why does the lesson rule out the Gemini chat app as the engine for this assistant?
3. In the context of Gemini, what best describes a 'Gem'?
4. Select ALL correct answers: which design constraints from the scenario directly drive specific technical requirements?
Sélectionnez toutes les réponses correctes.
5. Select ALL correct answers about the four daily jobs the assistant must perform.
Sélectionnez toutes les réponses correctes.
Read the data flowdata flowAn automated sequence of steps that moves data from source to destination: ingestion, transformation, validation, and loading, so it arrives clean and ready to use.Voir la définition complète → once, top to bottom:
1. 7:00 a.m. trigger (Apps Script time-driven trigger) fires dailyBriefing.
2. Ingest (Flash, multimodal): each new Drive file is uploaded and extracted to JSON.
3. Research (Pro, grounded): a search-grounded call gathers fresh competitor news with citations.
4. Synthesize (Pro): one call combines the extracted file facts and the grounded news into a one-page briefing, JSON out ({title, summary, sources}).
5. Deliver (Workspace): Apps Script appends to the running Doc and emails the summary.
Notice the model tiers mapmapUsing software to automate repetitive marketing tasks and campaigns, enabling personalisation at scale across channels like email, web, and social.Voir la définition complète → cleanly onto the steps: Flash fans out over many small inputs, Pro makes the two calls that require judgment. Notice too that grounding is scoped to exactly one step. You do not ground the extraction step, because those facts come from the documents in front of you, not the web. Grounding the wrong step adds latency and can pull in irrelevant search results.
if statements.Do not build top to bottom. Build the risky middle first.
1. In AI Studio, get the grounded synthesis prompt right by hand. This is where quality lives or dies.
2. Get the JSON extraction reliable on your real PDFs. Real files break naive prompts.
3. Only then wrap both in Apps Script and add the trigger.
Scheduling and Doc-writing are boring and reliable. The model prompts are where you will iterate ten times, so prove them first.