The search page on this blog has a natural-language “Ask AI” search powered by RAG (Retrieval-Augmented Generation), separate from the regular keyword search. This post covers how to use it, and how it works under the hood.
How to use it
Open
/search/Above the existing keyword search (PaperMod’s built-in fuse.js search), you’ll see an “Ask AI” question box
Type a question in plain language
Example: “Why does a non-root directory on CloudFront return a 403 instead of serving index.html?”
Submitting runs a Cloudflare Turnstile bot check in the background; once it passes, the question is sent to the backend
After a few seconds you’ll see an answer along with links to the source articles it was grounded in
If a question isn’t covered by anything on this blog, the model is instructed to say so honestly rather than answering from outside knowledge. This is a search feature grounded only in this blog’s own content.
How it works
Indexing (build time)
rag-index/ (a Java 17 / Maven CLI) reads every non-draft post under
content/posts/, splits each into chunks (by ## heading, falling back
to ~1500-character sliding windows for long or heading-less sections),
embeds each chunk with Voyage AI’s embeddings API (voyage-3-lite), and
uploads the resulting array of
{id, slug, title, url, chunkText, embedding} as index.json to a
dedicated S3 bucket (www.kanjtomi1967.net-rag-index).
This indexing step runs on every Jenkins deploy, between Build and
Deploy (the Rebuild RAG Index stage). So pushing a new or updated
post automatically shows up in the search index on the next deploy.
Answering a question (runtime)
Questions go through API Gateway to a Lambda function (blog-rag, in
lambda-rag/, Java 17) on POST /ask.
- Verify the Cloudflare Turnstile token server-side
- On a cold start, download
index.jsonfrom S3 and keep it in memory for the lifetime of the execution environment (warm invocations reuse it) - Embed the question via Voyage AI and rank every chunk by cosine similarity, brute-force (fine at this corpus size — no vector DB needed)
- Take the top 4 chunks
- Pass those chunks as grounding context to Claude (
claude-haiku-4-5) and have it answer based on them - Return
{answer, sources: [{title, url}]}
The API Gateway stage also has a conservative throttle (burst 5 / rate 2) as a second line of defense against a scripted caller running up the Claude bill.
Summary
- Answers are grounded only in the blog’s own posts, which keeps hallucination risk low and helps with “I remember reading this somewhere but can’t find it”
- Push a post and the index updates automatically on the next deploy
- Turnstile + throttling keep both cost and abuse in check
If you can’t quite recall the keyword for something you read here, give “Ask AI” a try.
Comments