Pular para conteúdo

ADR-005 — amIA-Ingest: Serviço Dedicado de Ingestão e Busca Vetorial

Status: 🟡 Proposto Data: 2026-06-12

Contexto

O módulo AMS requer duas capacidades novas que envolvem interação com LLMs e vetores:

  1. Ingestão de documentos — extrair texto de arquivos (PDF, DOCX, TXT, MD), aplicar chunking, gerar embeddings e persistir no pgvector.
  2. Busca semântica RAG — recuperar chunks relevantes da base vetorial para compor o contexto do agente de chat.

O projeto já possui o serviço amIA-Agents (Python/LangChain), que concentra toda a lógica de agentes com LLM: qualificação de FAQs, geração de código, planejamento e outros workflows. A questão arquitetural foi: incluir as funções de ingestão e busca vetorial dentro do amIA-Agents, ou criar um serviço separado?

Alternativas avaliadas

# Opção Descrição
A Incorporar no amIA-Agents Adicionar consumers de ingestão e o endpoint de busca vetorial como novos módulos dentro do repositório e container do amIA-Agents.
B Criar amIA-Ingest (escolhida) Novo repositório, imagem Docker e App Service dedicado exclusivamente ao pipeline de ingestão e à interface de busca vetorial.

Decisão

Criar o serviço amIA-Ingest como um componente independente do amIA-Agents.

Justificativa

Isolamento de responsabilidades (SRP em nível de serviço)

O amIA-Agents é um serviço de execução de agentes: recebe um prompt, raciocina com o LLM e retorna uma resposta. A ingestão de documentos é um pipeline de processamento de dados: lê arquivos, transforma, chunka e persiste vetores. São ciclos de vida distintos, com dependências, taxas de falha e necessidades de escala diferentes.

Escalabilidade independente

A ingestão é intensiva em I/O (download de blobs, geração de embeddings em batch) e pode precisar de mais memória/CPU que os agentes de chat. Com serviços separados é possível escalar horizontalmente cada um conforme a demanda sem superprovisionar o container do amIA-Agents.

Isolamento de falha

Um erro em um documento corrompido (ex: PDF malformado) não afeta a disponibilidade do chat e dos agentes. Com um serviço dedicado, a fila de ingestão pode ter dead-letter queue e política de retry própria, sem impactar o throughput de respostas em tempo real.

Deploy independente

Atualizações no modelo de embeddings (ex: migrar de text-embedding-ada-002 para text-embedding-3-large) ou no chunking strategy não exigem redeploy do amIA-Agents, reduzindo risco e janela de indisponibilidade do chat.

Dependências divergentes

O amIA-Ingest consumirá LangChain Document Loaders e integrações de blob storage que não são necessárias nos agentes de chat. Manter dependências separadas evita imagem Docker inflada e conflitos de versão de bibliotecas.

Consequências

Positivas: - Cada serviço tem uma única responsabilidade bem definida, facilitando manutenção e onboarding - Falhas no pipeline de ingestão não afetam a experiência de chat em tempo real - Possibilidade de escalar ingestão independentemente em picos de upload - Histórico de deploys limpo por contexto (mudanças em embedding não aparecem no changelog do chat)

Negativas: - Mais um repositório, pipeline CI/CD e App Service a gerenciar - Necessidade de autenticação service-to-service entre amIA-Ingest e AMia Core (token de integração) - Overhead operacional inicial: provisionamento Terraform, secrets no Key Vault, Variable Groups no Azure DevOps

Riscos mitigados: - O padrão de repositório, Dockerfile e pipeline é copiado diretamente do amIA-Agents, reduzindo o esforço de bootstrap (ver Feature 1.4 do PLANNING.md)

Diagrama de responsabilidades

graph LR
    subgraph "amIA-Agents"
        A1[Agente de Qualificação de FAQ]
        A2[Agente de Chat RAG]
    end

    subgraph "amIA-Ingest"
        I1[Consumer IngestDocumentCommand]
        I2[Extração + Chunking]
        I3[Geração de Embeddings]
        I4[Persistência pgvector]
    end

    subgraph "AMia Core"
        C1[POST /ams/documents]
        C2[PATCH /ams/documents/:id/status]
    end

    C1 -->|publica IngestDocumentCommand| I1
    I1 --> I2 --> I3 --> I4
    I1 -->|PATCH status=Processing| C2
    I4 -->|PATCH status=Indexed| C2
    A2 -->|busca semântica| I4