Ai Docs
Guias

Integrando Componentes RAG

Como todos os componentes se conectam para criar um sistema RAG completo

Integrando Componentes RAG

Esta seção explica como todos os componentes se conectam para criar um sistema RAG completo.

Arquitetura de Alto Nível

Como Tudo se Conecta

1. Fluxo de Dados

O fluxo de dados em um sistema RAG completo:

interface RAGSystem {
  vectorStore: VectorStore;
  chatMemory: ChatMemory;
  llmClient: LLM;
  agentInstructions: string;
}

async function processQuery(
  system: RAGSystem,
  query: string,
  userId: string
): Promise<string> {
  // 1. Obter contexto do histórico
  const chatHistory = await system.chatMemory.getMessages(userId);
  
  // 2. Gerar embedding da query
  const queryEmbedding = await generateEmbedding(query);
  
  // 3. Buscar documentos relevantes
  const relevantDocs = await system.vectorStore.search(queryEmbedding);
  
  // 4. Montar prompt com todos os componentes
  const prompt = buildCompletePrompt({
    instructions: system.agentInstructions,
    chatHistory,
    relevantDocs,
    query
  });
  
  // 5. Gerar resposta
  const response = await system.llmClient.complete(prompt);
  
  // 6. Atualizar memória de chat
  await system.chatMemory.addMessage(userId, {
    role: 'user',
    content: query
  });
  
  await system.chatMemory.addMessage(userId, {
    role: 'assistant',
    content: response
  });
  
  return response;
}

2. Responsabilidades dos Componentes

ComponenteFunçãoInterface Com
Base de ConhecimentoFonte de verdade factualBanco Vetorial
EmbeddingsTransformação semânticaLLM API, Banco Vetorial
Banco VetorialArmazenamento & RecuperaçãoBackend App
Chat MemoryContexto conversacionalRedis, Backend App
InstruçõesComportamento do agenteLLM
LLMGeração de respostasOpenAI/Anthropic/etc

3. Construção do Prompt

Um exemplo de como todos os componentes se unem no prompt:

function buildCompletePrompt({
  instructions,
  chatHistory,
  relevantDocs,
  query
}: {
  instructions: string;
  chatHistory: ChatMessage[];
  relevantDocs: Document[];
  query: string;
}): string {
  const historyText = chatHistory
    .map(msg => `${msg.role}: ${msg.content}`)
    .join('\n');
  
  const docsText = relevantDocs
    .map(doc => doc.content)
    .join('\n\n');
  
  return `
    ${instructions}
    
    === Histórico da Conversa ===
    ${historyText}
    
    === Informações Relevantes ===
    ${docsText}
    
    === Pergunta Atual ===
    Usuário: ${query}
    
    Assistente:
  `;
}

Implementação em Diferentes Camadas

Camada de Banco de Dados

// Exemplo com MongoDB
class MongoVectorStore implements VectorStore {
  constructor(private collection: Collection) {}
  
  async search(embedding: number[], limit = 5): Promise<Document[]> {
    return await this.collection.aggregate([
      {
        $vectorSearch: {
          queryVector: embedding,
          path: "embedding",
          numCandidates: 100,
          limit
        }
      },
      {
        $project: {
          _id: 0,
          content: 1,
          metadata: 1,
          score: { $meta: "vectorSearchScore" }
        }
      }
    ]).toArray();
  }
  
  async addDocument(doc: Document, embedding: number[]): Promise<void> {
    await this.collection.insertOne({
      content: doc.content,
      metadata: doc.metadata,
      embedding
    });
  }
}

Camada de Cache/Memory

// Exemplo com Redis
class RedisMemory implements ChatMemory {
  constructor(private redis: Redis, private ttl = 3600) {}
  
  async addMessage(userId: string, message: ChatMessage): Promise<void> {
    const key = `chat:${userId}`;
    await this.redis.rpush(key, JSON.stringify(message));
    await this.redis.expire(key, this.ttl);
  }
  
  async getMessages(userId: string): Promise<ChatMessage[]> {
    const key = `chat:${userId}`;
    const messages = await this.redis.lrange(key, 0, -1);
    return messages.map(m => JSON.parse(m));
  }
}

Camada de API

// Exemplo com Express
function setupRagEndpoints(app: Express, system: RAGSystem) {
  app.post('/api/chat', async (req, res) => {
    try {
      const { message, userId } = req.body;
      
      if (!message || !userId) {
        return res.status(400).json({ error: 'Missing required fields' });
      }
      
      const response = await processQuery(system, message, userId);
      
      res.json({ response });
    } catch (error) {
      console.error('Error processing chat:', error);
      res.status(500).json({ error: 'Failed to process request' });
    }
  });
  
  app.get('/api/chat/:userId/history', async (req, res) => {
    try {
      const { userId } = req.params;
      const history = await system.chatMemory.getMessages(userId);
      res.json({ history });
    } catch (error) {
      res.status(500).json({ error: 'Failed to retrieve chat history' });
    }
  });
}

Considerações de Produção

Para sistemas em produção:

1. Monitoramento e Logging

async function processQueryWithMonitoring(
  system: RAGSystem,
  query: string,
  userId: string
): Promise<string> {
  const startTime = Date.now();
  
  try {
    // Processo normal
    const response = await processQuery(system, query, userId);
    
    // Métricas
    const duration = Date.now() - startTime;
    metrics.recordQueryTime(duration);
    metrics.incrementQueryCount();
    
    return response;
  } catch (error) {
    // Logging de erros
    logger.error('Query processing failed', {
      userId,
      query,
      error: error.message,
      stack: error.stack
    });
    
    metrics.incrementErrorCount();
    throw error;
  }
}

2. Caching de Resultados

async function processQueryWithCache(
  system: RAGSystem,
  query: string,
  userId: string
): Promise<string> {
  // Gerar chave de cache
  const cacheKey = `query:${createHash(query)}:user:${userId}`;
  
  // Verificar cache
  const cachedResult = await cache.get(cacheKey);
  if (cachedResult) {
    metrics.incrementCacheHit();
    return cachedResult;
  }
  
  // Processar normalmente se não está em cache
  const response = await processQuery(system, query, userId);
  
  // Salvar no cache
  await cache.set(cacheKey, response, 3600); // 1 hora TTL
  metrics.incrementCacheMiss();
  
  return response;
}

3. Escalabilidade

// Configuração para escalabilidade
interface ScalableRAGConfig {
  // Vetorial
  vectorDb: {
    connectionPoolSize: number;
    readReplicas: number;
    writeTimeout: number;
  };
  
  // Cache
  redis: {
    clusterMode: boolean;
    nodes: number;
    maxConnections: number;
  };
  
  // LLM
  llm: {
    providerTimeout: number;
    maxConcurrentRequests: number;
    fallbackProviders: string[];
  };
}

A integração eficaz de todos esses componentes é o que cria um sistema RAG robusto e eficiente.

Integrando com Sistemas Existentes

A integração de sistemas de IA com aplicações existentes requer planejamento e consideração de vários aspectos.

Arquitetura de Integração