Files
ForgeLM/tauri-app/docs/MULTI_AGENT_ARCHITECTURE.md
T
evandro 4f293dcb3b wip: snapshot das alterações não commitadas (2026-10-20)
Origem: D:/Documents/Github/ForgeLM
Arquivos omitidos (segredos, bancos de dados, logs, >50 MB): 1
2026-10-20 00:49:35 -03:00

13 KiB

Arquitetura: Multi-Agentes Especialistas para ForgeLM

Visão Geral

Sistema de especialistas que analisam e refinam iterativamente as respostas do assistente, utilizando a infraestrutura ForgeAgent existente.

1. Fluxo Conceitual

Usuário → ChatView → API Local → Resposta Inicial
                                    ↓
                    ┌───────────────┼───────────────┐
                    ↓               ↓               ↓
            [Especialista 1] [Especialista 2] [Especialista 3]
            CodeReviewer      StyleEditor      FactChecker
                    ↓               ↓               ↓
                    └───────────────┴───────────────┘
                                    ↓
                          Resposta Refinada
                                    ↓
                              ChatView UI

2. Estrutura de Dados

SpecialistDefinition (Configuração)

interface SpecialistDefinition {
  id: string;                    // "code-reviewer", "style-editor"
  name: string;                  // "Code Reviewer"
  title: string;                 // "Revisor de Código"
  systemPrompt: string;          // Prompt específico do especialista
  activationRules: ActivationRule[];  // Quando ativar
  modelTier: "fast" | "quality"; // Qual modelo usar
  maxTokens: number;
  temperature: number;
}

type ActivationRule = 
  | { type: "always" }
  | { type: "contains-code"; languages?: string[] }
  | { type: "length-threshold"; minChars: number }
  | { type: "content-pattern"; regex: string }
  | { type: "manual-toggle"; toggleId: string };

ReviewCycle (Execução)

interface ReviewCycle {
  id: string;                    // UUID da revisão
  originalMessageId: number;     // ID da mensagem original
  originalContent: string;       // Resposta inicial do assistente
  specialists: SpecialistReview[];
  finalContent: string;          // Resposta após todas as revisões
  status: "running" | "completed" | "error";
  startedAt: number;
  completedAt?: number;
}

interface SpecialistReview {
  specialistId: string;
  status: "pending" | "thinking" | "completed" | "error";
  thinking?: string;             // Chain of thought
  suggestions: Suggestion[];
  applied: boolean;              // Se as sugestões foram aplicadas
}

interface Suggestion {
  type: "improvement" | "correction" | "addition" | "deletion";
  original?: string;             // Texto original
  replacement?: string;          // Texto sugerido
  explanation: string;           // Por que mudar
  confidence: number;            // 0.0 - 1.0
}

3. Componentes Principais

A. SpecialistRegistry (src/lib/specialist-registry.ts)

Registro central de especialistas disponíveis.

class SpecialistRegistry {
  private specialists: Map<string, SpecialistDefinition> = new Map();
  
  register(def: SpecialistDefinition): void;
  unregister(id: string): void;
  getActiveForContent(content: string, context: Context): SpecialistDefinition[];
  getAll(): SpecialistDefinition[];
}

B. ReviewOrchestrator (src/lib/review-orchestrator.ts)

Orquestra o ciclo de revisão.

class ReviewOrchestrator {
  async startReview(
    messageId: number,
    content: string,
    context: MessageContext
  ): Promise<ReviewCycle>;
  
  private async runSpecialist(
    cycle: ReviewCycle,
    specialist: SpecialistDefinition,
    currentContent: string
  ): Promise<SpecialistReview>;
  
  private applySuggestions(content: string, review: SpecialistReview): string;
  
  onProgress(callback: (cycle: ReviewCycle) => void): void;
  onComplete(callback: (cycle: ReviewCycle) => void): void;
}

C. SpecialistService (Backend/Tauri)

Comandos Rust para executar revisões sem bloquear a UI.

#[tauri::command]
async fn run_specialist_review(
    specialist_id: String,
    content: String,
    context: MessageContext,
    server: String,
    model: String,
) -> Result<SpecialistReview, String>;

4. Integração ao ChatView

Modo Síncrono vs Assíncrono

Opção A: Assíncrono (Recomendado)

  • Resposta inicial aparece imediatamente
  • Especialistas processam em background
  • Badge/indicator mostra "Melhorando..."
  • Quando completo, mensagem é atualizada com versão refinada
  • Toggle "Agentic" controla se ativa especialistas

Opção B: Síncrono

  • Aguarda todos os especialistas antes de mostrar
  • Mais lento mas garante qualidade máxima
  • Mostra progresso em tempo real (SpecialistCards)

Proposta: Híbrido com Streaming

// No ChatView
const [reviewCycle, setReviewCycle] = useState<ReviewCycle | null>(null);

// Após receber resposta completa
if (agenticMode) {
  const cycle = await reviewOrchestrator.startReview(
    messageId, 
    responseContent,
    { chatId, previousMessages }
  );
  setReviewCycle(cycle);
  
  // Mostra mensagem inicial imediatamente
  // Atualiza quando especialistas completam
  cycle.onProgress((updated) => {
    setReviewCycle({ ...updated });
  });
}

UI Components

  1. ReviewProgressIndicator - Badge mostrando "3/5 especialistas completos"
  2. ReviewDiffViewer - Mostra diff entre original e refinado
  3. SpecialistSidebar - Panel mostrando thinking de cada especialista
  4. SuggestionAcceptReject - Controles para aceitar/rejeitar sugestões

5. Especialistas Padrão

1. CodeReviewer

{
  id: "code-reviewer",
  name: "Code Reviewer",
  title: "Revisor de Código",
  activationRules: [{ type: "contains-code" }],
  systemPrompt: `Você é um revisor de código sênior. Analise o código fornecido e sugira melhorias em:
- Eficiência e performance
- Legibilidade e clareza
- Boas práticas e padrões
- Possíveis bugs ou edge cases

Formato de resposta (JSON):
{
  "thinking": "sua análise passo a passo",
  "suggestions": [
    {
      "type": "improvement",
      "original": "código original",
      "replacement": "código melhorado",
      "explanation": "por que melhorar",
      "confidence": 0.95
    }
  ]
}`
}

2. StyleEditor

{
  id: "style-editor",
  name: "Style Editor", 
  title: "Editor de Estilo",
  activationRules: [{ type: "length-threshold", minChars: 200 }],
  systemPrompt: `Você é um editor de texto profissional. Melhore a clareza e fluidez do texto mantendo o significado original.

Foque em:
- Clareza e concisão
- Fluxo e coesão entre frases
- Tom apropriado ao contexto
- Eliminação de redundâncias

Formato de resposta (JSON):
{
  "thinking": "análise do estilo",
  "suggestions": [...]
}`
}

3. FactChecker

{
  id: "fact-checker",
  name: "Fact Checker",
  title: "Verificador de Fatos",
  activationRules: [{ type: "content-pattern", regex: "\b(sabe|sabia|fato|verdade|estudo|pesquisa|dado|estatística)\b" }],
  systemPrompt: `Você é um verificador de fatos. Identifique afirmações factuais no texto e avalie:
- Se são factualmente corretas (conhecimento até 2024)
- Se precisam de citação ou fonte
- Se há nuances ou contexto faltante

NÃO invente informações. Marque como "não verificável" se incerto.

Formato de resposta (JSON):
{
  "thinking": "análise factual",
  "suggestions": [
    {
      "type": "correction",
      "original": "afirmação incorreta",
      "replacement": "versão corrigida ou com ressalvas",
      "explanation": "por que precisa correção",
      "confidence": 0.85
    }
  ]
}`
}

4. ToneAdapter

{
  id: "tone-adapter",
  name: "Tone Adapter",
  title: "Adaptador de Tom",
  activationRules: [{ type: "always" }],
  systemPrompt: `Você adapta o tom da resposta ao contexto da conversa.

Analise o histórico recente e ajuste:
- Formalidade (técnico vs casual)
- Entusiasmo (neutro vs animado)
- Detalhamento (resumo vs aprofundado)
- Personalização (menção a fatos do usuário)

Formato de resposta (JSON):
{
  "thinking": "análise do contexto e tom adequado",
  "suggestions": [...]
}`
}

6. Fluxo de Execução

// 1. Usuário envia mensagem
// 2. Recebe resposta do assistente
// 3. Se agenticMode ativo:

async function processWithSpecialists(messageId: number, content: string) {
  // Determina quais especialistas ativar
  const activeSpecialists = specialistRegistry.getActiveForContent(content, context);
  
  // Cria ciclo de revisão
  const cycle: ReviewCycle = {
    id: generateUUID(),
    originalMessageId: messageId,
    originalContent: content,
    specialists: activeSpecialists.map(s => ({
      specialistId: s.id,
      status: "pending",
      suggestions: [],
      applied: false
    })),
    finalContent: content, // Começa com original
    status: "running",
    startedAt: Date.now()
  };
  
  // Executa sequencialmente (para builds contextuais)
  let currentContent = content;
  for (const specialist of activeSpecialists) {
    updateSpecialistStatus(cycle, specialist.id, "thinking");
    
    const review = await runSpecialist(specialist, currentContent, context);
    
    updateSpecialistStatus(cycle, specialist.id, "completed", review);
    
    // Aplica sugestões automaticamente (pode ser manual no futuro)
    currentContent = applySuggestions(currentContent, review);
    cycle.finalContent = currentContent;
    
    notifyProgress(cycle);
  }
  
  cycle.status = "completed";
  cycle.completedAt = Date.now();
  
  // Atualiza mensagem no DB com versão refinada
  await updateMessage(messageId, cycle.finalContent, cycle);
  
  return cycle;
}

7. Persistência

Tabela: specialist_reviews

CREATE TABLE specialist_reviews (
  id TEXT PRIMARY KEY,
  message_id INTEGER NOT NULL,
  original_content TEXT NOT NULL,
  final_content TEXT NOT NULL,
  specialists_json TEXT NOT NULL,  -- SpecialistReview[]
  status TEXT NOT NULL,
  created_at INTEGER NOT NULL,
  completed_at INTEGER
);

Tabela: specialist_definitions (configuração do usuário)

CREATE TABLE specialist_definitions (
  id TEXT PRIMARY KEY,
  name TEXT NOT NULL,
  title TEXT NOT NULL,
  system_prompt TEXT NOT NULL,
  activation_rules_json TEXT NOT NULL,
  is_enabled BOOLEAN DEFAULT 1,
  sort_order INTEGER DEFAULT 0
);

8. Configuração do Usuário

Settings UI

  • Lista de especialistas (drag-drop para reordenar)
  • Toggle individual para cada especialista
  • Editor de system prompts customizados
  • Regras de ativação configuráveis

Padrões do Sistema

const DEFAULT_SPECIALISTS: SpecialistDefinition[] = [
  toneAdapter,      // Sempre ativo
  codeReviewer,     // Só com código
  styleEditor,      // Textos longos
  factChecker,      // Quando detecta factualidade
];

9. Otimizações de Performance

  1. Caching: Especialistas memorizam contexto entre mensagens
  2. Lazy Loading: Só carrega especialistas quando necessário
  3. Parallel where safe: Especialistas independentes rodam em paralelo
  4. Early Exit: Se confiança < threshold, pula para o próximo
  5. Model Tier: Especialistas usam modelos menores/fasters quando possível

10. Considerações de UX

Quando Mostrar

  • ✅ Sempre mostrar resultado original primeiro
  • ✅ Mostrar progresso discreto (badge, não modal)
  • ✅ Permitir ver thinking de cada especialista (expansível)
  • ✅ Permitir toggle on/off global (já existe AgenticToggle)
  • ✅ Permitir ver diff original vs refinado

Quando NÃO Usar

  • ❌ Não bloquear a UI esperando especialistas
  • ❌ Não mostrar erros de especialista ao usuário (fail silently)
  • ❌ Não processar mensagens muito curtas (< 50 chars)
  • ❌ Não processar se modelo indisponível

11. MVP - Fase 1

Implementação mínima viável:

  1. 2 especialistas hardcoded: ToneAdapter (sempre) + CodeReviewer (se código)
  2. Execução sequencial síncrona (simplifica UI)
  3. Aplicação automática de sugestões
  4. UI mínima: Badge "Melhorando..." → "Melhorado ✓" + SpecialistCard expansível
  5. Sem persistência de review cycles (só resultado final)

Arquivos a Criar (Fase 1)

src/
  lib/
    specialist-definitions.ts       # Especialistas padrão
    review-orchestrator.ts          # Lógica de orquestração
  components/
    forgeagent/
      ReviewProgress.tsx            # Badge de progresso
      ReviewDiffViewer.tsx          # Diff original vs refinado
  hooks/
    useSpecialistReview.ts          # Hook para gerenciar ciclo

Arquivos a Modificar

src/components/ChatView.tsx       # Integrar ao fluxo de resposta
src/components/MessageBubble.tsx  # Mostrar badge de revisão
src/prompts/specialists/          # Prompts de cada especialista

12. Próximos Passos

  1. ✅ Validar arquitetura com o usuário
  2. Implementar Fase 1 (MVP)
  3. Testar com diferentes modelos (Qwen3 0.8B, 2B, 4B)
  4. Ajustar prompts baseado em resultados
  5. Adicionar especialistas adicionais
  6. Implementar modo paralelo assíncrono
  7. Adicionar configuração via UI Settings