How to Summarize Sprint Retros With Mistral on Vertex AI
Sprint retros generate real insight, then it evaporates into a Confluence page nobody reopens before the next planning meeting. If your team already exports the board or records the call, you can close that loop with a script instead of a scribe. Mistral on Vertex AI runs as a serverless, pay-as-you-go endpoint inside Google Cloud's Model Garden, so there's no GPU to provision and the bill lands next to the rest of your GCP spend.
By the end of this guide you'll have a Python script that takes raw retro notes, a Miro export, a call transcript, whatever your team dumps into a doc, and turns them into a structured summary: what went well, what didn't, and a clean list of action items with owners, ready to paste into Jira or Linear.
1. Turn on Vertex AI and accept the Mistral model terms
Model Garden's partner models need their license accepted once per project before you can call them. Enable the API first:
gcloud services enable aiplatform.googleapis.com --project=<your-project-id>
Then open Vertex AI Model Garden in the console, search for "Mistral," and click into Mistral Medium 3. Accept the terms of use there. Google's own Model Garden listing currently offers Mistral Medium 3, Mistral Small 3.1, Codestral 2, and Mistral OCR as the served, pay-as-you-go options; the older Mistral Large and Mistral Nemo listings from Model Garden's early days have been superseded by Medium 3 and Small 3.1, so use those current names instead of anything you find in older tutorials.
2. Install the Mistral SDK with GCP support
Mistral's official Python client ships a GCP-aware client that handles Vertex AI's auth and URL format for you:
pip install "mistralai[gcp]"
gcloud auth application-default login
The application-default login step is what google.auth.default() picks up inside the SDK, so you don't have to manage a service account key by hand for local testing.
3. Point the client at your project and region
Mistral models on Vertex AI default to the europe-west4 region. If your project's data residency or quota lives elsewhere, override it explicitly:
import os
from mistralai.gcp.client import MistralGCP
client = MistralGCP(
project_id=os.environ["GCP_PROJECT_ID"],
region="us-central1", # defaults to europe-west4 if omitted
)
4. Write the summarization prompt
Give the model a strict output shape instead of hoping it stays organized on its own. Structured, schema-like instructions in the prompt work well here since retro notes are messy and inconsistent between teams:
retro_notes = open("retro-notes.txt").read()
prompt = f"""You are summarizing a Scrum sprint retrospective.
From the raw notes below, produce:
1. "Went well": 3-5 bullet points
2. "Went poorly": 3-5 bullet points
3. "Action items": a list of objects with "item" and "owner"
(use "unassigned" if no owner was mentioned)
Return only valid JSON with keys: went_well, went_poorly, action_items.
Retro notes:
{retro_notes}
"""
resp = client.chat.complete(
model="mistral-medium-2505",
messages=[{"role": "user", "content": prompt}],
response_format={"type": "json_object"},
)
summary = resp.choices[0].message.content
print(summary)
The response_format flag forces valid JSON back, which matters if you're piping this straight into a Jira import script rather than reading it yourself.
5. Wire it into where your retro notes actually live
Most teams don't have retro notes sitting in a clean .txt file. Point the same script at whatever you actually use: a Zoom transcript download, a Miro board export, or a pasted Slack thread. The only change is how retro_notes gets populated before it hits the prompt. If your notes run long (a 45-minute call transcript can blow past a few thousand tokens), trim to the discussion and action-item sections before sending; you're paying per token either way.
6. Swap in Mistral Small for routine runs
Medium 3 is worth it when the retro was contentious or the notes are messy. For a clean, well-facilitated retro, Mistral Small 3.1 does the job for less:
resp = client.chat.complete(
model="mistral-small-2503",
messages=[{"role": "user", "content": prompt}],
response_format={"type": "json_object"},
)
Run both on a sample retro once and compare; for a mechanical summarization task like this one, the gap in quality is usually smaller than the gap in price.
Gotchas
- Model terms are per-model. Accepting Mistral Medium 3's license in Model Garden doesn't cover Small 3.1 or Codestral 2. Accept each one you plan to call.
- Region affects both latency and residency.
europe-west4is the SDK default regardless of where your other GCP resources live; if you're a US-based team, setregionexplicitly or you'll pay a transatlantic round trip on every call. - JSON mode still needs a schema in the prompt.
response_format={"type": "json_object"}guarantees parseable JSON, not the specific keys you asked for. Validate the output before you push it into Jira. - Codestral 2 is also on Model Garden but isn't the right tool here. It's tuned for code completion, not prose summarization; skip it for this use case even though it's sitting right next to Medium 3 in the console.
A five-minute retro summarizer beats a retro doc nobody rereads, and running it through Vertex AI means it's one more line item on a bill you're already reconciling, not one more service to keep alive.