Engineering reference: the email assistant architecture
Same system as the rest of the series, drawn purely for engineers. Service names, resource identifiers, region, Bedrock model IDs, and the actual flow operations — everything you’d need to recreate this in your own AWS account.
Posts 1–6 walk through the system in plain language. This page is the dense version — nothing softened, just the architecture as you’d sketch it on a whiteboard during a design review.
Read this top-down, then column-by-column
Top row is the three external surfaces. Below it, the AWS account contains five subsystems: Build & Deploy across the top, then Config Sync, then three runtime columns (Reader, Brain, Sender), with a Cross-cutting strip at the bottom. Inbound mail arrives at SES on the verified domain, lands in S3, fans out to fn-reader, which writes a parsed envelope to tbl-messages. The DynamoDB stream then triggers fn-brain, which retrieves passages from S3 Vectors and invokes Bedrock with strict tool_use over four tools. The choice and confidence score get written back to tbl-messages, which triggers fn-sender — routing to SES outbound, the draft queue, escalate-forward, or just an audit row, depending on which tool fired.
Naming conventions used in the diagram
- Lambda functions:
fn-<purpose>—fn-reader,fn-brain,fn-sender,fn-config-sync,fn-archive. - DynamoDB tables:
tbl-messages(every inbound, with parsed envelope and current state),tbl-drafts(pending human approvals),tbl-audit(every action ever taken). - SNS topics:
t-alarmsfor general failures,t-draftsfor pending-draft pushes to the operator’s phone. - S3 layout: single bucket
email-assistant-datawith prefixesraw/{date}/,config/,archive/. - S3 Vectors index:
vec-knowledge— chunked + embedded knowledge file for top-k retrieval.
Region, model access, and email deliverability
Everything runs in ap-southeast-1 (Singapore) for low latency from the Philippines. Bedrock model invocations use the Global cross-Region inference profile (model IDs prefixed with global.) — data at rest stays in Singapore; inference may route to other regions for capacity. Pricing is the same as on-demand Singapore pricing.
Email deliverability is the part of email that catches out engineers who are used to webhooks. Three pieces have to be set up before any reply leaves your domain:
- SES domain identity — verify the domain via DKIM CNAMEs in your DNS provider. Verified domains can both receive (with the right MX records) and send.
- Custom MailFrom subdomain —
mail.yourdomain.com, with its own SPF/MX records, so SPF and DMARC alignment work correctly when SES sends on your behalf. - SES sandbox removal — new SES accounts are sandboxed (can only send to verified addresses). One short request form on the AWS console moves you to production limits.
The brain uses strict tool_use: four tool definitions (answer_directly, draft_for_review, escalate_to_human, archive_no_reply) with required parameter schemas including a confidence_score in [0, 1] and a citation_passage_id string. So the model can only emit a structured tool call — not a free-text reply. Free text would let it invent prices or promises; tool_use makes that mathematically impossible.
What’s deliberately not on the diagram
- IAM policy details — per-Lambda execution role inline policies are minimal (one bucket prefix, one or two tables, SES on a single sending identity, Bedrock invoke on one model).
- Per-business knowledge schema — the
knowledge.mdfile is a single Drive doc with sections for FAQs, hours, services, policies, and tone. Updating sections updates the assistant’s answers without a deploy. - X-Ray tracing — on for
fn-brainandfn-sender, sampling 100% during tuning, 10% in steady state. Mostly for confidence-score calibration, not latency. - The CloudFormation parameters for the Bedrock model ID and the embedding model are templated, so swapping models doesn’t require code changes.
- Amazon WorkMail — AWS’s managed inbox product. If you want the operator’s “normal inbox” to also live in AWS, this slots in next to SES; for most teams, the operator inbox is just the existing Gmail or Outlook setup and no WorkMail is needed.
- Bedrock Knowledge Bases — managed retrieval that can replace the explicit S3 Vectors + Titan Embeddings setup with a single connector. Bedrock Knowledge Bases now natively supports S3 Vectors as the storage engine, so the underlying primitives are the same; you just get an opinionated chunk-and-retrieve loop instead of running it yourself. Worth picking when the bring-your-own-knowledge-file pattern isn’t strictly required.
- Bedrock Guardrails contextual grounding check — Bedrock’s managed grounding-and-relevance scoring layer. The custom
confidence_scoreandcitation_passage_idtool parameters infn-brainare roughly the same idea hand-rolled; swapping to Guardrails moves the thresholds into console configuration and adds a second pair of eyes (PII redaction, prompt-attack detection, topic filters) on every model call. Worth turning on once the in-code thresholds are stable. - SES Mail Manager — the managed inbound rule engine. The April 2026 update added an
Invoke Lambda functionrule action plus optional mTLS on the ingress endpoint, making it a clean drop-in replacement forfn-reader’s lane-classification logic when the receipt-rule library grows beyond a handful of patterns. The traditional SES Receipt Rules path used in the diagram remains valid; Mail Manager is the upgrade, not a deprecation.
If you’re recreating this
Start with Build & Deploy alone (a single Lambda, no triggers). Once git push reliably updates an empty stack, verify a domain in SES and get a single “hello” auto-reply going on a hard-coded subject line. Then S3 inbound storage. Then fn-reader with just lane classification (no parsing yet). Then the parsed envelope. Then the Brain on a single hard-coded tool. Then the other three tools. Then the draft queue and the operator notifications. Cross-cutting (audit, logs, alarms, budget, archive) goes in from day one.