Building My First RAG System in One Week with Kiro IDE šŸŽƒ

Published: (December 2, 2025 at 01:26 PM EST)
5 min read
Source: Dev.to

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)
  • pypdf 5.1.0 (PDF processing)

Frontend

  • Vanilla JavaScript (no frameworks)
  • Custom CSS with theme variables
  • Server‑Sent Events for real‑time progress

Testing

  • pytest 7.4.3
  • hypothesis 6.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 EventSource listener 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.py directly āŒ (breaks reusability)

After steering docs

  • Me: ā€œAdd a delete document featureā€
  • Kiro: Adds delete_document() to skeleton_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)
Back to Blog

Related posts

Read more Ā»

arreglar pinchazos cerca de mi en Alpedrete

Introducción Nuestro taller estÔ preparado para atender cualquier emergencia de neumÔticos de manera rÔpida y segura, ya sea que estés en Alpedrete o en Las Ro...