I go into a lot of meetings. Client calls, partner intros, job interviews. The prep ritual is always the same: open LinkedIn, Google the person, scan a few headlines, try to remember something useful before they say hello. It's inefficient and often incomplete.
Je participe à beaucoup de réunions. Appels clients, présentations de partenaires, entretiens. Le rituel de préparation est toujours le même : ouvrir LinkedIn, chercher la personne sur Google, parcourir quelques titres, essayer de me souvenir de quelque chose d'utile avant qu'ils disent bonjour. C'est inefficace et souvent incomplet.
So I automated it. The result is a tool that takes a name and company, searches the web in three directions, and uses an LLM to synthesize a clean briefing. The whole thing runs serverless on AWS and costs less than a cent per use.
J'ai donc automatisé ça. Le résultat est un outil qui prend un nom et une entreprise, effectue trois types de recherches web, et utilise un LLM pour synthétiser une fiche propre. Le tout tourne sans serveur sur AWS et coûte moins d'un cent par utilisation.
→ Try the tool first, then come back and read how it was built.
→ Essayez l'outil d'abord, puis revenez lire comment il a été construit.
Why Lambda as a container image?
Pourquoi Lambda avec une image conteneur ?
Lambda supports two deployment models: a zip file (classic) or a container image stored in ECR. The zip model is simpler but has a 250MB limit. I chose the container path intentionally — it's a better learning surface. You learn Docker, ECR, and Lambda container support in one shot.
Lambda supporte deux modèles de déploiement : un fichier zip ou une image conteneur stockée dans ECR. Le modèle zip est plus simple mais limité à 250 Mo. J'ai choisi le conteneur intentionnellement — c'est un meilleur terrain d'apprentissage. On apprend Docker, ECR et Lambda en une seule fois.
The cost difference is negligible. ECR's free tier covers 500MB/month — this image is ~190MB. Lambda itself is free for the first 1M invocations/month. For a personal tool used a few times a week, the total bill rounds to zero.
La différence de coût est négligeable. Le niveau gratuit d'ECR couvre 500 Mo/mois — cette image fait ~190 Mo. Lambda est gratuit pour le premier million d'invocations/mois. Pour un outil personnel utilisé quelques fois par semaine, la facture totale s'arrondit à zéro.
What the Lambda actually does
Ce que fait réellement le Lambda
1 — Validate input
1 — Valider les entrées
Name, company, and context are trimmed and capped at 100/100/300 characters before touching any external API. This is the prompt injection guard — user input goes into a clearly-labelled data block, never directly into the system prompt.
Le nom, l'entreprise et le contexte sont nettoyés et limités à 100/100/300 caractères avant de toucher une API externe. C'est la protection contre l'injection de prompt — les entrées utilisateur vont dans un bloc de données clairement étiqueté, jamais directement dans le système de prompt.
2 — Run three SerpAPI searches
2 — Effectuer trois recherches SerpAPI
General search, LinkedIn-targeted search, and a news search. All three run sequentially — Lambda's 30s timeout is not a bottleneck. Each failed search is caught and logged; if all three fail, the function returns a 502.
Recherche générale, recherche ciblée LinkedIn, et actualités. Les trois s'exécutent séquentiellement — le délai Lambda de 30s n'est pas un goulot d'étranglement. Chaque recherche échouée est capturée et journalisée.
3 — Deduplicate and pack results
3 — Dédupliquer et regrouper les résultats
Results from three searches overlap. A set is used for O(1) deduplication by title. Up to 15 unique results are packed into a structured research block before being sent to Bedrock.
Les résultats des trois recherches se chevauchent. Un set est utilisé pour une déduplication O(1) par titre. Jusqu'à 15 résultats uniques sont regroupés dans un bloc de recherche structuré avant d'être envoyés à Bedrock.
4 — Call Claude Haiku on Bedrock
4 — Appeler Claude Haiku sur Bedrock
The research block and a tight system prompt are sent to us.anthropic.claude-haiku-4-5-20251001-v1:0 — the cross-region inference profile ID. The us. prefix enables cross-region routing from ca-central-1. Without it, Bedrock returns a ValidationException.
Le bloc et le système de prompt sont envoyés à us.anthropic.claude-haiku-4-5-20251001-v1:0 — l'ID du profil d'inférence inter-région. Le préfixe us. permet le routage inter-région depuis ca-central-1. Sans lui, Bedrock retourne une ValidationException.
handler.py — the Bedrock call
def call_bedrock(system: str, user_message: str) -> str:
body = json.dumps({
"anthropic_version": "bedrock-2023-05-31",
"max_tokens": 1500,
"system": system,
"messages": [{"role": "user", "content": user_message}],
})
response = bedrock.invoke_model(
modelId=MODEL_ID, # us.anthropic.claude-haiku-4-5-20251001-v1:0
body=body,
contentType="application/json",
accept="application/json",
)
return json.loads(response["body"].read())["content"][0]["text"]
Why Bedrock and not the Anthropic API?
Pourquoi Bedrock et non l'API Anthropic ?
Bedrock bills to your AWS account — the same account you're already monitoring. The Anthropic API is a separate balance. For a tool built to showcase AWS skills, keeping everything in one bill is the right call. At this scale (~$0.004/brief), the cost difference is irrelevant; the architectural consistency is not.
Bedrock facture sur votre compte AWS — le même compte que vous surveillez déjà. L'API Anthropic est une balance séparée. Pour un outil conçu pour mettre en valeur les compétences AWS, tout garder dans une seule facture est le bon choix. À cette échelle (~0,004 $/fiche), la différence de coût est négligeable ; la cohérence architecturale ne l'est pas.
The Docker build gotcha that will cost you an hour
Le piège Docker qui vous coûtera une heure
Building on Windows with Docker Desktop and pushing to Lambda? By default, Docker BuildKit creates an OCI image index (a multi-platform manifest list), even when you only target one platform. Lambda needs a single-platform manifest and will reject the image. The fix is one flag:
Vous construisez sur Windows avec Docker Desktop et poussez vers Lambda ? Par défaut, Docker BuildKit crée un index d'images OCI, même pour une seule plateforme. Lambda rejette l'image. La solution est un seul paramètre :
The one flag that fixes it
L'option qui règle le problème
docker buildx build \
--platform linux/amd64 \
--provenance=false # ← this is the fix
--load \
-t meeting-prep .
--provenance=false disables the provenance attestation that forces the multi-platform manifest. Without it, Lambda sees a manifest list. With it, you get a clean single-arch image Lambda accepts.
--provenance=false désactive l'attestation de provenance qui force le manifeste multi-plateforme. Sans cela, Lambda voit une liste de manifestes. Avec, vous obtenez une image mono-architecture propre que Lambda accepte.
CORS: Lambda headers aren't enough
CORS : les en-têtes Lambda ne suffisent pas
When you add an API Gateway trigger to a Lambda, API Gateway gets its own CORS configuration — separate from whatever headers your Lambda returns. Configure CORS in two places: Lambda response headers (for the actual request) and API Gateway CORS settings (for the preflight). Both must allow the same origins.
Quand vous ajoutez un déclencheur API Gateway à un Lambda, API Gateway obtient sa propre configuration CORS — distincte des en-têtes Lambda. Configurez CORS en deux endroits : les en-têtes Lambda (pour la vraie requête) et les paramètres CORS d'API Gateway (pour le preflight). Les deux doivent autoriser les mêmes origines.
What it costs
Ce que ça coûte
| ServiceService |
UsageUtilisation |
Cost / briefCoût / fiche |
| Lambda | ~5s · 256MB | $0.000021 |
| API Gateway | 1 request1 requête | $0.000001 |
| Bedrock (Haiku 4.5) | ~3K in · ~1K out | $0.0037 |
| SerpAPI | 3 searches3 recherches | $0.003 |
| TotalTotal | | ~$0.007 |
SerpAPI has a free tier of 100 searches/month — that's 33 briefs for free. Bedrock has no free tier, but at $0.0037/brief, a year of daily use costs about $1.35.
SerpAPI offre un niveau gratuit de 100 recherches/mois — soit 33 fiches gratuites. Bedrock n'a pas de niveau gratuit, mais à 0,0037 $/fiche, une année d'utilisation quotidienne coûte environ 1,35 $.
What I'd do differently
Ce que je ferais différemment
- Rate limiting — an API Gateway usage plan with per-IP throttle would prevent abuse.
- Limitation de débit — un plan d'utilisation API Gateway avec plafond par IP préviendrait les abus.
- Parallel SerpAPI calls — running three searches concurrently with
asyncio would cut ~2s of latency.
- Appels SerpAPI parallèles — les exécuter avec
asyncio réduirait la latence d'environ 2s.
- Caching — a DynamoDB TTL cache would eliminate redundant SerpAPI calls for the same person within the same day.
- Cache — un cache DynamoDB avec TTL éliminerait les appels SerpAPI redondants pour la même personne dans la même journée.
- Streaming — streaming the Bedrock response to the browser would make the brief appear instantly instead of after a 3s wait.
- Streaming — streamer la réponse Bedrock vers le navigateur ferait apparaître la fiche instantanément au lieu d'attendre 3s.
→ Try the meeting prep tool
→ Essayer l'outil de préparation
→ Back to the Lab
→ Retour au Lab