AI Development Workflow¶
This chapter presents a complete workflow for building Gaia-powered features using AI assistance in Cursor. The core loop is simple: Describe → Generate → Review → Iterate. Combined with the Cursor rules from this project, this approach lets you go from idea to working feature in minutes rather than hours.
The AI-First Development Loop¶
┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐
│ 1. Describe │────▶│ 2. Generate │────▶│ 3. Review │────▶│ 4. Iterate │
│ │ │ │ │ │ │ │──┐
│ What you │ │ AI writes │ │ You verify │ │ Refine & │ │
│ want built │ │ the code │ │ correctness │ │ improve │ │
└─────────────┘ └─────────────┘ └─────────────┘ └─────┬───────┘ │
│ │
└──────────┘
Repeat until
correct
Rules are the multiplier
Each step is dramatically more effective when Cursor rules are active. The AI doesn't generate generic code — it generates code that follows your project's Gaia patterns. See Using Cursor Rules for details.
Step 1: Describe Your Feature¶
Start by describing what you want in natural language. Be specific about the Gaia capability you're using and the user-facing behavior you want.
Good Feature Descriptions¶
"Create a FastAPI endpoint
POST /api/searchthat runs an exhaustive search against a specified dataset. It should accept a query string and dataset name, support pagination with apage_tokenparameter, and return results with document metadata. Use theGaiaClient.exhaustive_searchmethod and follow the existing route patterns in@backend/app/routes/.""Build a React component
SearchResultsthat displays a paginated list of documents returned by the/api/searchendpoint. Each result should show the document title, a snippet, and a relevance indicator. Include a 'Load More' button that uses the pagination token."
What Makes a Description Effective¶
| Element | Example | Why It Matters |
|---|---|---|
| Specific endpoint/component | POST /api/search | Tells the AI exactly what to create |
| Gaia method to use | GaiaClient.exhaustive_search | Avoids generic HTTP calls |
| Reference to existing patterns | @backend/app/routes/ | AI matches your conventions |
| User-facing behavior | "paginated list with Load More" | Guides UI decisions |
| Edge cases | "support pagination" | Prevents incomplete implementations |
Step 2: Generate Code with Rules¶
With your description ready, use Cursor's AI features to generate code. The .cursor/rules/ directory automatically provides context.
For New Files — Use Chat (Cmd+L)¶
Open the AI chat panel and paste your feature description. Reference specific files for context:
Create a new route file @backend/app/routes/search.py that implements exhaustive
search. Follow the patterns in @backend/app/routes/ask.py and use
@sdk/python/gaia_sdk/client.py for the GaiaClient interface.
For Modifications — Use Inline Edit (Cmd+K)¶
Select the code you want to modify, press Cmd+K, and describe the change:
Add pagination support to this search endpoint. Accept an optional page_token
query parameter and pass it to GaiaClient.exhaustive_search as pagination_token.
Include the next pagination token in the response.
For Multi-File Features — Use Composer (Cmd+Shift+I)¶
For features that span backend and frontend:
Add document search to the application:
1. Backend: POST /api/search endpoint using GaiaClient.exhaustive_search
2. Frontend: SearchPage component with query input, results list, and pagination
3. Add the route to the React router
Follow the existing patterns in @backend/app/routes/ and @frontend/src/pages/.
Reference @.cursor/rules/ for Gaia-specific conventions.
Step 3: Review Generated Code¶
AI-generated code is a strong starting point, but always review before committing.
Review Checklist¶
- Authentication — Does the backend route use
GaiaClientwith server-side API key injection? Is the API key never sent from the frontend? - Error handling — Are
GaiaError,GaiaAuthError,GaiaRateLimitErrorcaught and mapped to appropriate HTTP status codes? - Type safety — Do Pydantic models match the actual Gaia API response shapes? Are TypeScript types consistent with backend responses?
- Streaming — If using SSE, is
proxy_buffering offset in nginx? Does the frontend handle stream interruption gracefully? - Edge cases — Empty results, timeout, rate limiting, invalid dataset names?
- Imports — Are all imports correct and from the right packages?
Common AI mistakes to watch for
- Using
requestsinstead ofhttpx(synchronous vs. async). - Hardcoding the Gaia API URL instead of reading from settings.
- Using
EventSourcefor SSE POST requests (it only supports GET). - Missing
awaiton asyncGaiaClientmethod calls. - Importing from wrong module paths.
Step 4: Iterate and Refine¶
After reviewing, use Cursor to fix issues or enhance the generated code.
Common Iteration Prompts¶
Select the problematic code, press Cmd+K, and describe the fix:
| Issue | Prompt |
|---|---|
| Missing error handling | "Add try/except for GaiaAuthError and GaiaRateLimitError following the pattern in @backend/app/routes/ask.py" |
| No loading state | "Add loading and error states to this component with a spinner and error banner" |
| Missing pagination | "Add pagination support — include a next_page_token in the response and a Load More button in the UI" |
| Hardcoded values | "Extract the hardcoded timeout and dataset name into the Settings config" |
| No TypeScript types | "Add TypeScript interfaces for the API response matching @backend/app/models/search.py" |
Effective Prompts for Gaia Development¶
Here are battle-tested prompts for common Gaia development tasks. Copy and adapt them for your specific needs.
Backend Prompts¶
RAG Query Endpoint
Streaming Endpoint
Exhaustive Search with Pagination
Frontend Prompts¶
Streaming Chat Component
Dataset Selector
Search Results with Pagination
Full-Stack Prompts¶
Complete Feature
Add document upload functionality:
1. Backend: POST /api/upload that creates an upload session via GaiaClient,
accepts file upload, and triggers indexing
2. Frontend: FileUpload component with drag-and-drop, progress indicator,
and success/error states
3. Wire up the frontend to call the backend endpoint
Follow patterns in @backend/app/routes/ and @frontend/src/components/.
Common Pitfalls and How to Avoid Them¶
Pitfall 1: Over-Delegating to AI¶
Problem: Asking the AI to build an entire feature in one prompt produces code that's hard to review and often has subtle issues.
Solution: Break features into components. Generate the backend route, test it, then generate the frontend component.
Pitfall 2: Ignoring the Rules¶
Problem: Prompting without referencing rules or project files produces generic code.
Solution: Always reference @.cursor/rules/ or specific existing files in your prompts.
Pitfall 3: Not Testing Incrementally¶
Problem: Generating multiple files before testing any of them leads to cascading errors.
Solution: Follow this order for each component:
- Generate the code
- Run the linter / type checker
- Test with a manual request (curl, browser, or Postman)
- Fix issues, then move to the next component
Pitfall 4: Accepting Without Understanding¶
Problem: Committing AI-generated code without understanding what it does.
Solution: If a piece of generated code is unclear, select it and ask Cursor: "Explain what this code does and why it's structured this way."
When to Step In Manually vs. Let AI Handle It¶
| Task | AI | Manual | Notes |
|---|---|---|---|
| Boilerplate routes and components | AI excels at repetitive structure | ||
| Wiring up GaiaClient calls | Rules ensure correct patterns | ||
| Complex business logic | Domain-specific logic needs human judgment | ||
| Debugging runtime errors | AI can help analyze, but you need to run and observe | ||
| CSS/layout fine-tuning | Visual precision requires human eyes | ||
| Writing tests | AI generates good test scaffolding; review assertions | ||
| Security-sensitive code | Always manually review auth, secrets, and access control | ||
| Database schema design | Architectural decisions need human thought | ||
| Refactoring existing code | AI handles mechanical refactors well with @ context |
Putting It All Together: A Complete Example¶
Here's how the workflow plays out for adding a "dataset details" page:
1. Describe¶
I need a page that shows detailed information about a specific dataset.
Backend: GET /api/datasets/{name} that calls GaiaClient.get_dataset.
Frontend: DatasetDetails page with name, document count, status, and
indexing information.
2. Generate Backend (Cmd+L)¶
Create @backend/app/routes/datasets.py with a GET /api/datasets/{name}
endpoint. Use GaiaClient.get_dataset(name) and return a DatasetDetailsSchema.
Follow error handling patterns from @backend/app/routes/ask.py.
3. Test Backend¶
4. Generate Frontend (Cmd+L)¶
Create @frontend/src/pages/DatasetDetails.tsx that fetches from
GET /api/datasets/{name} (name from URL params) and displays the
dataset info. Add loading and error states. Follow patterns from
@frontend/src/pages/.
5. Review, Iterate, Ship¶
Review both files. Fix any issues with Cmd+K. Test end-to-end. Commit.
Next Steps¶
- Compound Engineering — The philosophy behind why this workflow compounds over time.
- Cursor IDE Setup — Configure Cursor for optimal Gaia development.
- Claude Code Setup — Run the same AI workflow in a terminal-first coding assistant.
- Using Cursor Rules — Understand and customize the rules powering this workflow.
- Production Checklist — Ensure your AI-generated code is production-ready.