Skip to content

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

Text Only
┌─────────────┐     ┌─────────────┐     ┌─────────────┐     ┌─────────────┐
│  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/search that runs an exhaustive search against a specified dataset. It should accept a query string and dataset name, support pagination with a page_token parameter, and return results with document metadata. Use the GaiaClient.exhaustive_search method and follow the existing route patterns in @backend/app/routes/."

"Build a React component SearchResults that displays a paginated list of documents returned by the /api/search endpoint. 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:

Text Only
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:

Text Only
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:

Text Only
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 GaiaClient with server-side API key injection? Is the API key never sent from the frontend?
  • Error handling — Are GaiaError, GaiaAuthError, GaiaRateLimitError caught 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 off set 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 requests instead of httpx (synchronous vs. async).
  • Hardcoding the Gaia API URL instead of reading from settings.
  • Using EventSource for SSE POST requests (it only supports GET).
  • Missing await on async GaiaClient method 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

Text Only
Create a FastAPI endpoint that queries Gaia for [topic] using the session
auth pattern. Use GaiaClient.ask with conversation_id support for multi-turn
queries. Include error handling for auth failures and rate limits. Follow the
patterns in @backend/app/routes/ask.py.

Streaming Endpoint

Text Only
Create a streaming endpoint POST /api/ask/stream that forwards SSE events from
GaiaClient.ask_stream_iter to the client. Use FastAPI's StreamingResponse with
media_type="text/event-stream". Handle disconnection gracefully. Reference
@backend/app/routes/ for the existing patterns.

Exhaustive Search with Pagination

Text Only
Create a PUT /api/search/exhaustive endpoint that wraps
GaiaClient.exhaustive_search. Accept dataset_name, query, page_size, and
optional pagination_token. Return results with document metadata and the
next pagination token. Add Pydantic request/response models.

Frontend Prompts

Streaming Chat Component

Text Only
Build a React component that displays streaming Gaia responses. Use fetch
with ReadableStream (not EventSource) to consume SSE from POST /api/ask/stream.
Show tokens as they arrive with a typing indicator. Handle errors and stream
interruption. Use Tailwind CSS for styling.

Dataset Selector

Text Only
Create a DatasetSelector component that fetches datasets from GET /api/datasets
and renders them as a searchable dropdown. Allow multi-select. Store selected
datasets in React state and pass them to the query component. Follow the
patterns in @frontend/src/components/.

Search Results with Pagination

Text Only
Build a SearchResults page that displays exhaustive search results from
/api/search/exhaustive. Show document title, snippet, and source. Add a
"Load More" button that uses the pagination token to fetch the next page.
Include loading skeletons and empty state.

Full-Stack Prompts

Complete Feature

Text Only
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:

  1. Generate the code
  2. Run the linter / type checker
  3. Test with a manual request (curl, browser, or Postman)
  4. 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

Text Only
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)

Text Only
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

Bash
curl http://localhost:8000/api/datasets/my-dataset | python -m json.tool

4. Generate Frontend (Cmd+L)

Text Only
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