Building My First RAG System in One Week with Kiro IDE 🎃
Source: Dev.to
🎃 The Challenge
As a junior apps developer, I’d never built a RAG (Retrieval Augmented Generation) system before. The concept seemed intimidating: vector embeddings, semantic search, chunking strategies—all foreign territory. But the Kiroween hackathon’s “Skeleton Crew” category sparked an idea: what if I could build ONE reusable skeleton that transforms into ANY AI personality?
Seven days later, I had Project Corpus: a production‑ready RAG chatbot that can become a professional legal assistant, a mystical spirit, or anything else—just by swapping a config file.
🔗 Live Demo | GitHub Repo
🔮 What is Project Corpus?
Project Corpus is a document‑chat application with a twist: the same core logic powers radically different AI personalities.
Two Personalities, One Skeleton
⚖️ Legal Eagle
- Professional legal document analysis
- Formal responses with precise citations
- Blue corporate styling with typewriter sounds
- Ideal for contract analysis and legal research
👻 Ouija Board
- Mystical document exploration “from beyond the veil”
- Cryptic, atmospheric responses with spooky emojis
- Dark gothic theme with blood‑drip animations
- Ambient drone audio with static glitch effects
Both apps share the same skeleton_core module—only the config changes.
🛠️ The Tech Stack
Backend
- Python 3.13 + Flask 3.1.0
- ChromaDB 0.5.20 (vector database)
- Google Gemini API 0.8.3 (embeddings + generation)
pypdf5.1.0 (PDF processing)
Frontend
- Vanilla JavaScript (no frameworks)
- Custom CSS with theme variables
- Server‑Sent Events for real‑time progress
Testing
pytest7.4.3hypothesis6.92.1 (property‑based testing)
Development
- Kiro IDE (the secret weapon 🚀)
🤖 How Kiro Transformed My Development
1. 🎨 Vibe Coding: Learning While Building
As a junior developer, I needed to understand RAG, not just write code. Kiro’s conversational approach let me learn and build simultaneously.
Example conversation
Me: "How do I chunk PDFs by page and preserve page numbers?"
Kiro: *Explains chunking strategies, then generates code that:*
- Extracts PDF pages individually
- Chunks each page with 500 char / 50 overlap
- Stores metadata with source, page, chunk_index
- Retrieves page numbers in search results
Most Impressive Generation
Kiro produced the entire Server‑Sent Events upload pipeline in one conversation, including:
- Flask SSE streaming with
Response(stream_with_context()) - 4‑stage progress calculation (reading, parsing, vectorizing, finalizing)
- Client‑side
EventSourcelistener with progress bars - Graceful error handling
I had never used SSE before; Kiro not only wrote the code but also explained why SSE beats polling for this use case.
2. 📋 Specs: Systematic UI Polish
After building core features with vibe coding, I created .kiro/spec.md describing the desired user experience:
## 4. Implemented Features
1. **Document Upload (`/upload`):**
- Real‑time progress tracking via SSE
- Page‑aware chunking with metadata
- File validation (type, size, content)
2. **Chat Interface (`/chat`):**
- Semantic search with relevance filtering
- Source citations with page numbers
- Typewriter effect for responses
With the spec in place, I could say “implement section 4.1” and Kiro would systematically add all features—no back‑and‑forth needed.
Vibe Coding vs. Specs
- Vibe Coding: Exploratory, great for learning and core features.
- Specs: Systematic, perfect for polish and completeness.
3. 📚 Steering Docs: Teaching Kiro My Architecture
I created four steering documents that taught Kiro the project’s DNA.
structure.md – The game‑changer
### Skeleton + Config Pattern
The `skeleton_core` module contains all shared RAG functionality.
Individual app folders provide configuration objects that customize behavior.
Each `app_*/config.py` must define:
- `APP_NAME`: String for branding
- `THEME_CSS`: CSS theme identifier
- `SYSTEM_PROMPT`: AI personality instructions
- `CHUNK_SIZE`, `CHUNK_OVERLAP`, `TOP_K_RESULTS`, `RELEVANCE_THRESHOLD`
Before steering docs
- Me: “Add a delete document feature”
- Kiro: Modifies
app_legal/main.pydirectly ❌ (breaks reusability)
After steering docs
- Me: “Add a delete document feature”
- Kiro: Adds
delete_document()toskeleton_core/vector_store.py, creates/documents/DELETE route, updates frontend ✅ (maintains skeleton pattern)
Steering docs reduced “wrong suggestions” by ~80%, turning Kiro into a partner who understood the project’s philosophy, not just its syntax.
4. 🪝 Agent Hooks: Automated Quality Assurance
I built five hooks that caught bugs before deployment.
test-runner-on-save.kiro.hook
{
"when": { "type": "fileEdited", "patterns": ["**/*.py"] },
"then": { "type": "runCommand", "command": "pytest --tb=short -q" }
}
Runs tests automatically on every save, catching breaking changes instantly.
config-validator.kiro.hook – Validates that config files contain all required fields, preventing runtime errors.
env-check-on-session.kiro.hook – Verifies GOOGLE_API_KEY exists on session start, saving minutes of debugging.
Impact – Shifted workflow from reactive debugging to proactive validation, providing a safety net for a junior developer.
🧟 The Biggest Challenges
1. RAG Learning Curve
Understanding vector embeddings, semantic search, and chunking was overwhelming. Kiro became my teacher, offering explanations and solutions when search results were irrelevant.
Solution: Implemented relevance filtering that only shows documents within 0.3 distance units of the best match, ensuring accurate citations.
2. Page‑Aware Chunking
Preserving page numbers through extraction → chunking → embedding → storage → retrieval required careful metadata management.
Solution: Added page tracking at each stage with metadata, e.g.:
metadata = {
"source": filename,
"page": page_num,
"chunk_index": i
}
3. Theme Switching Architecture
Supporting radically different personalities from a single codebase demanded strong abstraction.
Solution: Adopted a config‑based approach; adding a new personality now takes ~10 minutes.
🏆 What I’m Proud Of
1. Learning RAG in One Week
Went from zero RAG knowledge to a production‑ready system with vector search, embeddings, and semantic retrieval in 7 days. Kiro’s vibe coding made this possible.
2. The Skeleton Pattern Works
The architecture is genuinely reusable. Adding a new personality is as simple as:
mkdir app_detective
# Add config.py with Config class
# Add main.py entry point
# Done! 🎉
3. Production‑Quality UI
- Smooth animations (typewriter effect, blood drips)
- Real‑time upload progress with SSE
- Document library with selective filtering
- Accessibility (ARIA labels, keyboard navigation)
- Theme‑specific audio (typewriter, ambient drone)