๐ Development Notes
Documents bugs, design decisions, and agent flow for a chatbot backend using Gemini, Pinecone, and a plugin system.
What this file does
Documents bugs, design decisions, and agent flow for a chatbot backend using Gemini, Pinecone, and a plugin system.
When to use it
- Debugging a multi-model AI backend with fallback logic
- Designing a RAG pipeline with vector database and session memory
- Planning a plugin architecture for external API integrations
- Reviewing production readiness of a chatbot service
Assumes this stack
๐ Development Notes
๐ค AI-Generated vs Manual Code
AI-Generat### 5. Memory Management
Problem: Risk of memory leaks with unlimited message storage Solution: Implemented automatic message cleanup:
// Keep only last 10 messages per session
if (session.messages.length > 10) {
session.messages = session.messages.slice(-10);
}
6. Pinecone Integration Issues
Problem: Dimension mismatch between Google GenAI embeddings and Pinecone index
// โ This failed - wrong dimensions
await index.upsert([{ id, values: embedding }]); // 768 dimensions
// โ
Fixed with proper embedding model
const embedding = await genAI.getGenerativeModel({ model: 'text-embedding-004' })
.embedContent(text); // 3072 dimensions
Solution: Used text-embedding-004 model and properly configured Pinecone index with 3072 dimensions.
7. Gemini API Overload Handling
Problem: Models returning 503 errors during high usage periods, fallback responses were confusing
// โ Generated fallback responses when APIs failed
return "I apologize, but I'm experiencing technical difficulties...";
// โ
Return proper HTTP error codes
return res.status(503).json({
error: "Service temporarily unavailable",
message: "All AI models are currently overloaded. Please try again later.",
code: 503
});
Solution: Implemented multi-model retry with exponential backoff and clean HTTP error responses.ents (with GitHub Copilot assistance):
- Initial project structure - Used Copilot for boilerplate Express setup
- TypeScript interfaces (
src/types/index.ts) - AI suggested comprehensive type definitions - Plugin templates - Basic plugin structure and math evaluation logic
- README sections - Parts of documentation and example curl commands
- Error handling patterns - Standard Express error handling structures
Manual Implementation (Human-written):
- Core architecture design - System design and component interaction patterns
- Vector store algorithm - Custom cosine similarity implementation
- Memory management strategy - Session-based conversation memory logic
- Prompt engineering - All system prompts and context injection logic
- Plugin intent detection - Custom keyword matching and query analysis
- Agent orchestration flow - Complete integration of RAG + Memory + Plugins
- Business logic - All controllers and service coordination
Mixed Approach:
- Vector search implementation - Started with AI template, heavily customized for our needs
- Plugin execution system - AI structure, manual business logic
- API responses - AI suggested JSON structure, manual error handling and metadata
๐ Bugs Faced and Solutions
1. Google GenAI API Issues
Problem: getGenerativeModel method not found, incorrect API initialization
// โ This didn't work
const genAI = new GoogleGenAI(apiKey);
// โ
Fixed with proper options object
const genAI = new GoogleGenAI({ apiKey });
Solution: Read the official Google GenAI documentation and corrected the initialization pattern.
2. TypeScript Strict Mode Conflicts
Problem: exactOptionalPropertyTypes causing issues with conditional properties
// โ This failed type checking
pluginsUsed: pluginsUsed.length > 0 ? pluginsUsed : undefined
// โ
Fixed with object spread
...(pluginsUsed.length > 0 && { pluginsUsed })
Solution: Used object spread syntax to conditionally include optional properties.
3. Vector Embedding Complexity
Problem: Initially tried to use ml-distance package but it had TypeScript issues
Solution: Implemented custom cosine similarity function with proper null checks:
function cosineSimilarity(a: number[], b: number[]): number {
// Custom implementation with safety checks
for (let i = 0; i < a.length; i++) {
const aVal = a[i] || 0; // Handle undefined values
const bVal = b[i] || 0;
}
}
4. File System Access Issues
Problem: Array indexing with potential undefined values in file reading
// โ Potential undefined access
const chunk = chunks[i];
await this.addDocument(chunks[i], metadata);
// โ
Added safety check
const chunk = chunks[i];
if (chunk) {
await this.addDocument(chunk, metadata);
}
Solution: Added explicit undefined checks before processing chunks.
5. Memory Management
Problem: Risk of memory leaks with unlimited message storage Solution: Implemented automatic message cleanup:
// Keep only last 10 messages per session
if (session.messages.length > 10) {
session.messages = session.messages.slice(-10);
}
๐ Agent Flow: RAG + Memory + Plugins
Complete Request Processing Flow:
-
Input Validation
- Check required fields (message, session_id)
- Validate API key availability
-
Memory Retrieval
// Add current message to session memoryManager.addMessage(session_id, message, 'user'); // Get conversation context const sessionSummary = memoryManager.getSessionSummary(session_id); -
RAG Context Retrieval
// Vector search for relevant documents const relevantContext = await vectorStore.search(message, 3); // Truncate contexts to fit prompt limits const contextDocs = relevantContext.map(doc => ({ ...doc, content: truncateContext(doc.content, 300) })); -
Plugin Execution
// Check which plugins can handle the query const pluginResults = await pluginManager.executePlugins(message); // Filter successful results const pluginsUsed = pluginResults .filter(result => result.success) .map(result => result.pluginName); -
Prompt Engineering
// Build comprehensive prompt with all context const prompt = PromptEngine.buildPrompt( message, // Current user message sessionSummary, // Conversation history contextDocs, // RAG retrieved documents pluginResults // Plugin execution results ); -
LLM Generation
// Generate response using Google Gemini const result = await model.generateContent(prompt); const aiResponse = result.response.text(); // Clean and format response const formattedResponse = PromptEngine.formatResponse(aiResponse); -
Memory Storage
// Store AI response for future context memoryManager.addMessage(session_id, formattedResponse, 'assistant'); -
Response Assembly
// Include metadata about what was used const response = { response: formattedResponse, sessionId: session_id, ...(pluginsUsed.length > 0 && { pluginsUsed }), ...(contextUsed.length > 0 && { contextUsed }) };
๐ฏ Key Design Decisions
1. Pinecone Vector Database over Custom Implementation
- Decision: Use Pinecone cloud vector database with Google GenAI embeddings
- Reason: Production-ready scaling, 3072-dimensional embeddings, better similarity search
- Trade-off: External dependency, requires API key, but much more robust than in-memory
2. Multi-Model Fallback Strategy
- Decision: Implement fallback chain: gemini-1.5-flash โ gemini-pro โ gemini-1.5-pro
- Reason: Reliability when models are overloaded, different quota limits
- Implementation: Exponential backoff retry with clean HTTP error codes
3. Plugin Architecture with Real APIs
- Decision: Interface-based plugin system with real API integrations
- Reason: Extensible, testable, production-ready data sources
- Implementation: OpenWeather API for weather, mathjs for calculations, realistic fallbacks
4. Prompt Engineering Approach
- Decision: Custom prompt builder with structured context injection
- Reason: Full control over how context, memory, and plugins are presented to the LLM
- Structure: System prompt + Memory + Context + Plugins + Current message
5. Clean Error Handling over Fallback Responses
- Decision: Return proper HTTP status codes (503, 500) instead of generated fallback content
- Reason: Professional API behavior, clear error communication, better debugging
- Implementation: 503 for overloaded models, 500 for configuration errors
โก Performance Considerations
Current Optimizations:
- Pinecone vector database for efficient similarity search
- Google GenAI embeddings (3072 dimensions) for better semantic understanding
- Session-based memory with automatic cleanup (10 messages max)
- Multi-model retry logic with exponential backoff
- Proper HTTP status codes for better client handling
Production Features:
- Real OpenWeather API integration with realistic fallbacks
- Comprehensive logging and error tracking
- Clean separation of concerns with proper TypeScript interfaces
- Environment-based configuration with validation
๐ Recent Improvements & Production Readiness
Latest Updates (August 2025):
1. Pinecone Vector Database Integration
- Migrated from in-memory vector storage to production Pinecone
- Auto-index creation with 3072-dimensional Google GenAI embeddings
- Successfully loaded 26 documents with proper chunking
- Eliminated O(n) search limitations with proper vector database
2. Multi-Model Fallback System
- Implemented robust retry logic: gemini-1.5-flash โ gemini-pro โ gemini-1.5-pro
- Exponential backoff with 2s, 4s delays between retries
- Comprehensive error handling for 503 (overloaded), 429 (quota), 404 (not found)
- Detailed logging with emoji indicators for better debugging
3. OpenWeather API Integration
- Real weather data integration with proper API key handling
- Realistic city-based fallback simulation when API key missing
- Professional error handling with graceful degradation
- Comprehensive weather data including temperature, humidity, wind speed
4. Clean Error Handling
- Removed fallback response generation in favor of proper HTTP codes
- 503 "Service temporarily unavailable" when all models overloaded
- 500 "Internal server error" for missing API keys
- Professional API behavior suitable for production clients
5. Enhanced Logging & Monitoring
- Detailed request tracing with emoji indicators
- Plugin execution tracking with success/failure states
- Model retry attempts with clear failure reasons
- Session and memory usage statistics
System Status:
- โ Production Ready: Clean error codes, proper fallbacks, comprehensive logging
- โ Scalable: Pinecone integration handles large document sets efficiently
- โ Reliable: Multi-model fallback ensures high availability
- โ Extensible: Plugin system ready for additional integrations
- โ Maintainable: Clear separation of concerns, comprehensive TypeScript types
๐งช Testing Strategy
Manual Testing Approach:
- Basic Agent: Test simple Q&A without context
- Memory: Multiple messages in same session
- RAG: Questions about dataset content
- Weather Plugin: Various weather queries
- Math Plugin: Different mathematical expressions
- Combined: Complex queries triggering multiple systems
Example Test Scenarios:
# Memory persistence test
curl -X POST http://localhost:3001/agent/message -d '{"message":"My name is John","session_id":"test1"}'
curl -X POST http://localhost:3001/agent/message -d '{"message":"What is my name?","session_id":"test1"}'
# Multi-plugin execution test
curl -X POST http://localhost:3001/agent/message -d '{"message":"Weather in Mumbai and calculate 5*7","session_id":"test2"}'
# RAG context test
curl -X POST http://localhost:3001/agent/message -d '{"message":"Tell me about markdown blogging","session_id":"test3"}'
# Error handling test (missing message)
curl -X POST http://localhost:3001/agent/message -d '{"session_id":"test4"}'
๐ Deployment Readiness
Environment Variables Required:
GEMINI_API- Essential - Google Gemini AI API key for LLM functionalityPINECONE_API- Essential - Pinecone vector database API key for RAGOPEN_WEATHER_API- Optional - OpenWeather API for real weather dataPORT- For platform deployment (Render, Railway, etc.)
Production Considerations:
- โ Rate limiting - Handled by Gemini API and Pinecone quotas
- โ Proper logging - Comprehensive emoji-based logging implemented
- โ
Health checks -
/statusendpoint with detailed system information - โ Error handling - Clean HTTP status codes and proper error messages
- โ API authentication - Individual API key management per service
- Database persistence - Currently using session-based memory (consider Redis)
- Error monitoring - Consider Sentry for production deployments
The system is production-ready with proper error handling, multi-model fallback, and comprehensive logging. All major functionality is implemented and tested successfully.
Total Development Time: ~8-10 hours (including architecture, implementation, debugging, API integrations, and comprehensive documentation) Current Status: Production-ready with 26 vectorized documents, multi-model AI fallback, real weather API integration, and professional error handling
What's inside
7 sections covering bugs, agent flow, design decisions, performance, improvements, testing, and deployment
Change this for your project
- Replace
GEMINI_APIwith your own Google Gemini API key environment variable name - Replace
PINECONE_APIwith your own Pinecone API key environment variable name - Replace
OPEN_WEATHER_APIwith your own OpenWeather API key environment variable name - Replace
gemini-1.5-flashwith your preferred Gemini model ID
Where it goes
Keep it in your repository where the agent or team that needs it will read it.
Worth borrowing
- Multi-model fallback chain with exponential backoff for API overload
- Session memory cleanup to keep only last N messages
- Conditional object spread for optional properties in TypeScript
Related Documents
Building SupportX AI Assist: A Multi-Agent IT Support System
Describes building a multi-agent IT support system with AutoGen, Azure AI Search, and Gemini embeddings for instant issue resolution and automatic escalation.
Intelligent Document Query Platform โ GitHub-ready Low-Level Design (LLD)
Provides a copy-ready low-level design for a serverless document query platform with vector search and LLM integration.
Graph Matching with Topological Features
Teaches enhanced graph matching by combining spatial distances with node2vec and commute times embeddings, then applying the Hungarian algorithm.
Pulse โ Life Cofounder | Build Log
Documents a full-stack monorepo that ingests LinkedIn and GitHub data, generates embeddings in-browser, and provides a RAG chat with an AI cofounder.