Orkas Orkas
Início Blog Arquitetura
Arquitetura

Reescrever a base do agente: uma refatorização fundamental do Orkas

Como a Orkas reconstruiu a sua base de agentes ao longo da série de versões 1.0: ambiente de execução no processo, rotação de fornecedores, orquestração dinâmica de conversas em grupo, alojamento aberto, memória e autoevolução.

Quando um produto de agente de IA amadurece, o mais caro não são as funcionalidades, mas a base. Este artigo aborda a refatorização fundamental que o Orkas fez na sua série de versões 1.0 — uma revisão completa da invocação de modelos, do ciclo do agente, da orquestração multiagente e do ecossistema de ferramentas — e os compromissos subjacentes a cada decisão.

Em resumo Para que serviu a reescrita O resultado é a aplicação que pode instalar hoje: de código aberto sob a licença MIT, com prioridade ao processamento local e a funcionar com as suas próprias chaves, se quiser.
Descarregar o Orkas — grátis

Porquê mexer na base

Orkas é um espaço de trabalho local para agentes de IA no computador: todo o trabalho do agente é executado dentro de um processo na própria máquina do utilizador, os dados residem localmente e a sincronização de ponta a ponta na nuvem acontece a pedido. As funcionalidades acumularam-se rapidamente nas primeiras versões — uma biblioteca de competências, uma base de conhecimento, conectores, múltiplos agentes em conversas em grupo — mas, quanto mais avançávamos, mais claro ficava: o verdadeiro estrangulamento não era uma funcionalidade isolada, mas três aspetos "de base".

  1. Se a camada de invocação de modelos seguir o antigo caminho conversacional, ficará presa a uma série de pressupostos errados. Invocar um modelo de grande dimensão como se fosse uma "conversa de uma pergunta e uma resposta" introduz uma série de predefinições que fazem sentido para uma conversa, mas não para um agente: um limite fixo de tokens de saída, chamadas de ferramentas sequenciais, tempos limite ocultos, um único fornecedor ligado. Um agente é um fluxo de longa duração que executa dezenas de turnos seguidos, atinge regularmente o limite da janela de contexto, precisa de ler ficheiros em paralelo e pode ser interrompido pelo utilizador a qualquer momento — cada uma destas predefinições irá causar problemas em produção. Pior ainda, as capacidades mais valiosas de um agente no computador – operações precisas sobre ficheiros, pesquisa local, execução de uma shell, execução paralela de vários agentes de trabalho, resolução de tarefas de longo horizonte – são precisamente aquelas que esta camada de pressupostos exclui.

  2. A orquestração era um "planeamento estático". A versão inicial era um mecanismo de plano/DAG: primeiro, o modelo dividia a tarefa num grafo de planeamento e, em seguida, fazia um executor percorrer o grafo. Parece simples, mas a realidade de um agente é altamente dinâmica: a leitura de um ficheiro revela que é preciso mudar de direção, e o resultado de uma subtarefa decide a quem cabe o próximo passo. Fixar decisões num grafo previamente gerado significa que cada situação em que "o plano não consegue acompanhar a realidade" precisa de ser corrigida dentro do executor.

  3. O ecossistema era um catálogo fechado. As competências só podiam vir do mercado oficial, os conectores eram um catálogo definido no código e as ferramentas de agentes externos já existentes na máquina do utilizador eram uma caixa negra completa para o Orkas. Um utilizador pode querer ligar um projeto de terceiros, o seu próprio servidor MCP ou permitir que um agente já instalado na sua máquina aceda às competências e à base de conhecimento do Orkas. Em termos de arquitetura, nada disto era possível.

A tese desta refatorização é simples: voltar a ter a base do agente nas nossas próprias mãos. Concretamente, resulta em quatro vertentes interligadas: um ambiente de execução próprio dentro do processo, uma camada de modelos independente do fornecedor, orquestração dinâmica de conversas em grupo e a passagem de um catálogo fechado para um sistema de alojamento aberto. Vamos analisá-las uma a uma.

1. Trazer um conjunto completo de capacidades de agente de programação para o computador

O computador é a casa do agente — aqui há um sistema de ficheiros real, uma shell real, um conjunto de ferramentas locais real. Um assistente que só consegue conversar está a desperdiçar este ambiente; o que realmente aproveita a vantagem do computador é um conjunto completo de capacidades de agente de programação: leitura e escrita de ficheiros por intervalo de caracteres, pesquisa entre ficheiros, execução de bash e ferramentas do sistema, ativação de vários agentes de trabalho em paralelo e resolução de problemas de longo horizonte para continuar a executar dezenas de turnos até que uma tarefa complexa esteja realmente concluída.

O principal resultado da refatorização existe precisamente para trazer esse conjunto de capacidades nativamente para o próprio processo do Orkas — um ambiente de execução de agentes dentro do processo, independente e carregável dinamicamente (chamado core-agent no código). Já não é um invólucro de conversa; é um motor de agentes que o Orkas controla.

A principal decisão de arquitetura foi dividi-la em duas camadas:

  • Camada do motor (pacote independente): mecanismos puros do agente — o ciclo de chamadas de ferramentas, eventos de transmissão contínua, compactação de contexto, classificação de erros e novas tentativas, abstração do fornecedor, ambiente isolado, verificação de competências, memória, autoevolução. Esta camada não sabe nada sobre a lógica de negócio do Orkas: não lê diretórios de dados de negócio, não entende o formato do ficheiro de conversação e nunca toca no IPC.
  • Camada adaptadora (dentro do processo principal): liga o motor ao Orkas — persistência de sessões, rotação de fornecedores, permissões de ferramentas, registo de competências, conectores, base de conhecimento, as diversas ferramentas de geração. Traduz os eventos nativos do motor para os formatos de eventos do próprio Orkas, de forma que a camada de negócio veja apenas uma interface estável.

Esta fronteira entre motor/adaptador é a raiz de toda a flexibilidade que se segue. O motor pode ser testado e evoluir de forma independente; a camada do adaptador pode absorver com segurança a complexidade específica do Orkas (rotação, períodos de espera, isolamento, permissões) sem poluir o motor. A revisão da arquitetura pela equipa resumiu tudo numa linha: isto é complexidade adquirida — não a misture.

Qual ​​é realmente o conjunto de capacidades

Ter o ambiente de execução nas próprias mãos não significa exibicionismo; trata-se de deixar o agente realmente “sujar as mãos” no computador. O conjunto de capacidades divide-se em aproximadamente quatro grupos:

  • Operações precisas sobre ficheiros e pesquisa local. read_file suporta leitura por intervalo de caracteres e extrai automaticamente texto de documentos PDF/Office; edit_file faz uma substituição precisa de "cadeia de caracteres antiga → nova cadeia de caracteres" e exige uma leitura antes de qualquer escrita; write_file obtém o artefacto e mantém um registo do mesmo; stat_file verifica o tamanho; search_files localiza por nome/glob, grep_files pesquisa conteúdo em ficheiros. Este grupo permite que o agente "explore o código, altere ficheiros" num espaço de trabalho real como um engenheiro, em vez de apenas absorver e emitir blocos inteiros.
  • Bash e ferramentas de sistema. Um executor de shell num ambiente isolado, com um modo de execução em segundo plano (as tarefas longas são separadas do turno atual, os registos vão para um ficheiro) e controlos classificados por risco para operações perigosas. Uma grande parte da vantagem de um agente no computador vem precisamente da capacidade de comandar diretamente a cadeia de ferramentas do sistema.
  • Vários agentes de trabalho em paralelo. Num único turno, as ferramentas independentes apenas de leitura são executadas simultaneamente; ao nível da tarefa, o comandante também pode distribuir subtarefas independentes por vários agentes de trabalho em paralelo (ver Secção 3). Paralelizar onde é seguro é a chave para reduzir as "tarefas de longo horizonte" a um tempo decorrido aceitável.
  • Raciocínio de longo horizonte e resolução de tarefas. Um ciclo que pode executar dezenas de iterações seguidas, gerir o seu próprio contexto, recuperar de erros e nunca ficar bloqueado — esta é a linha divisória entre "terminar um trabalho complexo" e "responder a uma pergunta".

Como a engenharia o preparou para produção

"Escrever o seu próprio ciclo" soa a procurar problemas e acarreta custos de manutenção. Mas o que se ganha é um controlo preciso sobre todo o ciclo de vida do agente. Esse controlo não é abstrato — é um conjunto de melhorias concretas, cada uma das quais garante que uma das capacidades acima "se aguenta" em produção:

  • Janela de contexto real + compactação apenas aos 80%. O mecanismo lê a janela de contexto real de cada modelo (incluindo modelos com uma janela de um milhão de tokens) e aciona a compactação apenas quando a utilização atinge 80% — em vez de começar de forma conservadora aos 60% e descartar 40% do contexto útil. Há também uma proteção contra a "compactação sem ganho": se a parte final retida já preencher a janela (por exemplo, um resultado de leitura de ficheiro muito grande nessa parte final), a compactação não pode libertar nada, pelo que apenas regista um aviso e avança, sem desperdiçar uma chamada de resumo. A capacidade de uma tarefa de longo horizonte "se lembrar do que veio antes" resume-se a isto.

  • Ferramentas adjacentes apenas de leitura em paralelo. Quando o modelo aciona a leitura de ficheiros, a pesquisa de ficheiros e a pesquisa na Web — várias ferramentas independentes apenas de leitura — de uma só vez, o motor agrupa num lote as ferramentas adjacentes que podem ser paralelizadas para execução simultânea; as ferramentas de escrita são barreiras naturais e mantêm a sua ordem declarada. As chamadas de ferramentas e os seus resultados são confirmados estritamente pela ordem declarada, para que a simultaneidade nunca viole o protocolo. As ferramentas apenas de leitura mais comuns passam de execução sequencial para paralela de uma só vez, e o tempo decorrido de todo o lote diminui visivelmente.

  • Leitura antes da escrita + controlo de concorrência otimista. Antes de editar um ficheiro, é preciso lê-lo; o motor regista um estado de referência do ficheiro lido e verifica se esse estado não mudou no momento da edição. Quando agentes de trabalho paralelos alteram o mesmo ficheiro ao mesmo tempo, o que perde recebe um erro claro de "desatualizado" em vez de substituir silenciosamente as alterações dos outros. Com vários agentes de trabalho a operar no mesmo espaço de trabalho em paralelo, esta proteção é indispensável.

  • A interrupção no meio da execução é implementada imediatamente. Quando um utilizador acrescenta outra linha a meio da execução do agente, o motor incorpora a mensagem em fila na entrada do turno atual na fronteira do ciclo de ferramentas, em vez de esperar para a transformar num turno separado. Isto transforma a "correção de rumo durante a execução" numa interação natural.

  • Deteção de ciclos. Quando a mesma chamada de ferramenta se repete consecutivamente, o motor primeiro dá um aviso (na 3ª) e depois interrompe a execução (na 5ª); qualquer assinatura diferente reinicia a contagem - variações legítimas como paginação/sondagem não falharão. Quando o modelo bloqueia, deixa de consumir tokens silenciosamente.

  • Remoção do limite máximo da saída do turno principal. A saída do turno principal deixa de estar limitada a um valor baixo, para que relatórios longos e edições grandes não sejam truncados silenciosamente; as chamadas auxiliares (compactação, reflexão) continuam a usar limites baixos de forma conservadora.

Há um detalhe muito "local" que vale a pena mencionar: estimativa de tokens para texto misto em chinês e inglês. Uma estimativa genérica subestima uma conversa inteiramente em chinês por um fator de duas ou três vezes; o motor trata os caracteres chineses e ingleses de forma diferente consoante a classe de caracteres, o que torna o limite de compactação fiável. Este é o tipo de coisa em que um SDK genérico não pensará por si.

Em conjunto, estas melhorias respondem à pergunta "porquê não usar apenas um SDK pronto a utilizar": porque as capacidades mais fortes de um agente no computador residem precisamente na camada que um SDK não expõe; para as preparar para produção, o ciclo tem de estar nas suas próprias mãos.

2. Manter o modelo sempre disponível: o invólucro multicamada do fornecedor

O objetivo da camada de modelos resume-se numa frase: independentemente do que corra mal com uma determinada chave, um determinado fornecedor ou uma determinada rede, esse turno da conversa do utilizador deve sobreviver, se possível. Para esse fim, a camada do adaptador sobrepõe alguns invólucros à abstração do fornecedor do motor — rotação, períodos de espera, registo, adaptação externa.

A decisão de conceção mais crítica é que o mecanismo de rotação fique abaixo do executor. O motor escreve a mensagem do utilizador na sessão persistente antes mesmo de chamar um fornecedor; se fizesse novas tentativas/rotação ao nível do motor, reenviaria a mensagem do utilizador ou teria de implementar a reversão de uma sessão inteira. Ao colocar o mecanismo de rotação abaixo do motor, a mensagem do utilizador é escrita exatamente uma vez e "tentar novamente com outro candidato" é completamente transparente para o estado da sessão.

O critério do mecanismo de rotação também é restrito, centrado na fronteira do primeiro evento de conteúdo:

  • Uma falha antes do modelo emitir qualquer conteúdo substantivo (texto/chamada de ferramenta) — é seguro mudar para o próximo candidato;
  • Depois de o primeiro evento de conteúdo ser emitido, interrompa a rotação e deixe o erro propagar-se, porque o modelo pode já ter executado uma iteração completa e repeti-la duplicaria os efeitos secundários.

A classificação do erro decide "rodar, não rodar ou tentar novamente". Falhas ao nível da conta, como falha de autenticação, saldo insuficiente, limitação de frequência, subscrição expirada — marque um período de espera e alterne; Falhas de rede transitórias, como reinicialização da ligação — sem período de espera, tente novamente algumas vezes sem manter estado; enquanto os pedidos malformados, a política de conteúdo e os erros de servidor 5xx – que falhariam da mesma forma com outra chave – passam diretamente sem rotação. O tempo de espera é uma indicação de dez minutos, dentro do processo, não persistente: é apenas um sinal de curto prazo, não vale a pena escrever no disco a cada falha, e uma reinicialização do processo é precisamente o momento certo para testar novamente.

Do lado da "lista" de fornecedores, a refatorização reúne três tipos de fontes numa abstração unificada:

  • LLM gerido pelo Orkas: um proxy do lado do servidor, pronto a utilizar assim que estiver ligado, com encaminhamento no servidor entre modelos de texto/imagem;
  • Traga a sua própria chave: fornecedores convencionais de modelos de grande dimensão;
  • Adaptadores externos de ligação direta: um conjunto de modelos que precisam de ligação direta ou têm faturação própria, adaptados manualmente à mesma interface de fornecedor.

Para as camadas acima, tudo isso aparece como apenas um par (provider, model) estável — rotação, períodos de espera e adaptação externa estão todos ocultos dentro da camada do adaptador.

3. Conversas em grupo como orquestração: do plano estático-DAG ao comandante no ciclo

Esta é a parte mais “reestruturante” da refatorização.

O modelo antigo era o planeamento estático: o modelo gera primeiro um plano/DAG e o executor percorre o grafo. O novo modelo elimina totalmente esse grafo e substitui-o por uma orquestração dinâmica e controlada de conversas em grupo.

A sua metáfora é uma sala de conversa em grupo:

  • O Comandante é o anfitrião da sala, não um middleware invisível;
  • Agentes de trabalho são membros iguais e de primeira classe na sala;
  • Todas as interações são mensagens assíncronas, colocadas em fila através de um único barramento de mensagens (não há caminho privado para distribuição paralela).

O "despacho" do comandante não é um @somebody escrito em prosa - um LLM escrever @AgentA no corpo do texto é apenas uma reprodução dos dados de treino e não é fiável. O verdadeiro sinal de despacho é uma chamada de ferramenta estruturada e, após a refatorização, converge em três ações semanticamente claras:

  • dispatch_to — envia um agente para concluir a execução e devolve o resultado, cabendo ao comandante fazer a síntese. Várias tarefas independentes podem ser distribuídas simultaneamente.
  • run_worker — uma subtarefa da responsabilidade do próprio comandante, cujo resultado é devolvido de forma síncrona; um agente de trabalho anónimo é a "mão" do comandante (invisível para o utilizador), enquanto um agente de trabalho identificado pelo nome é um especialista visível.
  • hand_off_to — entrega a conversa a o agente; o comandante sai e o agente responde diretamente ao utilizador, sem qualquer síntese neste turno.

Porquê conversar em grupo, em vez de usar um orquestrador ou uma árvore de subagentes

Transformar múltiplos agentes numa conversa em grupo traz vários benefícios que um orquestrador ou uma árvore de subagentes tradicional não consegue oferecer:

  • Segmentos de visibilidade. Cada mensagem é anexada apenas ao segmento "aqueles que podem vê-la". Quando um agente de trabalho é iniciado, reproduz apenas o seu próprio segmento, pelo que a saída volumosa de outro agente não poluirá o seu contexto. O comandante vê tudo.
  • Estado mínimo. O estado central de toda a orquestração é apenas "quem detém atualmente a palavra" mais um registo simples de tarefas. Sem DAG, sem máquina de estados complexa.
  • Naturalmente reproduzíveis e sincronizáveis. As mensagens são naturalmente ordenadas por marca temporal, pelo que o recarregamento e a sincronização entre dispositivos se integram diretamente no fluxo de mensagens. O cliente móvel controla remotamente precisamente esse fluxo: todo o processamento do agente é executado no computador, e a interface móvel é apenas uma representação espelhada, sem necessidade de um protocolo de orquestração especial.

A revisão da arquitetura pela equipa foi igualmente direta neste ponto: um barramento de conversas em grupo mais um comandante no ciclo é o formato multiagente do Orkas; acrescentar outro caminho paralelo de despacho de subagentes dentro do processo violaria a invariante de "apenas um caminho de despacho de conversas em grupo".

O que há de novo nesta versão: transferência interativa

A peça mais recente desta linha é a transferência interativa de agentes.

O problema é concreto: um agente do tipo "tutor" ensina o utilizador durante um turno, o utilizador quer continuar a fazer perguntas de seguimento, mas o sistema força a devolução da palavra ao comandante, obrigando o utilizador a voltar a mencionar com @ aquele agente para cada linha.

A solução é um controlo da palavra com autoridade no servidor + um destinatário decidido pelo modelo:

  • A atribuição da palavra torna-se um campo de estado persistente, mantido entre recarregamentos, e utiliza o evento de mudança de estado existente para sincronização automática em todos os clientes, sem necessidade de um novo tipo de evento.
  • Depois de o comandante usar hand_off_to para dar a palavra a um agente interativo, as mensagens "sem @" subsequentes do utilizador vão diretamente para esse agente, até que o agente devolva a palavra por iniciativa própria ou o utilizador volte a dirigir-se ao comandante.
  • O agente devolve o controlo com um marcador <handback />; a análise verifica rigorosamente uma correspondência exata (pelo que um <handback solto que apareça em prosa não é interpretado erradamente como uma transferência).
  • Se houver um registo de tarefas por concluir no momento da devolução, o comandante retoma-o e continua.

Há também uma correção da experiência que o acompanha: balões do ciclo do comandante. O ciclo "despachar → ler resultado → voltar a despachar" do comandante dentro de um turno costumava ser condensado num único balão e, ao recarregar, chegava a saltar para o fim, fora de ordem. A refatorização divide um turno em múltiplos segmentos em cada limite de despacho visível, sendo cada segmento uma mensagem independente com uma marca temporal crescente – pela primeira vez, o utilizador pode ver o comandante "a percorrer o ciclo de orquestração" e a ordem após o recarregamento também está correta.

Finalmente, duas redes de segurança estão presentes: o cancelamento em grupo é o único caminho de paragem para todos os intervenientes (no momento em que o utilizador clica em Parar, é acionado o sinal de cancelamento de cada agente de trabalho, e até os subagentes de trabalho anónimos são abrangidos por uma correspondência de recurso); e o já referido interrupt-steer, que incorpora a intervenção do utilizador a meio da execução no turno atual.

4. De um catálogo fechado a um sistema de alojamento aberto

Se as três primeiras vertentes se centraram em tornar a base sólida, esta centra-se em abrir todas as portas e janelas - transformar o Orkas de um catálogo fechado num sistema de alojamento aberto - mantendo os limites de segurança sem ceder um centímetro.

A refatorização desmontou sistematicamente vários pontos de estrangulamento "fechados":

  • Pacotes externos. O utilizador fornece o endereço de um repositório e o Orkas aloja-o localmente clonado literalmente para uma pasta — nunca normalizado, nunca reescrito, nunca sincronizado com a nuvem (porque contém diretórios de dependências de terceiros). Uma ferramenta de linha de comandos independente gere o ciclo de vida de instalação/atualização/início-paragem, verifica se tem "formato de competência" (contém um ficheiro de descrição de competência) ou "formato de CLI" (contém um ponto de entrada executável) e escreve os metadados num registo fora do diretório do pacote (para que futuras atualizações por pull nunca entrem em conflito). A instalação de dependências passa pela confirmação em duas etapas do tipo "perguntar uma vez, memorizar"; os pontos de entrada executáveis recebem correções geradas e injetadas no PATH da ferramenta bash, para que o modelo possa chamar diretamente estas CLIs de terceiros.

  • Carregamento de competências a partir de múltiplas raízes. O único ponto de entrada para a execução de competências passou do reconhecimento de apenas duas raízes para quatro níveis — personalizado/mercado/pacote externo/global — resolvidos por prioridade; os scripts dentro de um pacote externo dão preferência ao ambiente de dependências incluído no próprio pacote. Este é o ponto de estrangulamento com maior risco de regressão e é sustentado por uma matriz completa de dados de teste.

  • Interoperabilidade global de competências. O Orkas lê diretamente os diretórios de competências globais que outras ferramentas de agentes na máquina do utilizador já mantêm, alcançando a interoperabilidade ao nível das competências — uma competência que o utilizador reuniu num local também pode ser usada no Orkas. O ato de o próprio utilizador colocar uma competência nesses diretórios constitui a autorização, pelo que esta fica ativada por predefinição, mantendo-se um interruptor geral. Estas descrições de competências de terceiros são uma superfície não fiável de injeção de instruções, pelo que passam pelo carregador da "camada aberta", são visíveis apenas para o comandante e estruturalmente não podem entrar na lista de competências permitidas de um agente.

  • MCP configurado pelo utilizador. Os conectores já não são um catálogo definido no código. O utilizador pode adicionar qualquer servidor MCP — através de um formulário para HTTP remoto (baixo risco) ou de um formulário para subprocesso local (alto risco). O próprio formulário é a superfície de consentimento (o comando que o utilizador introduziu manualmente é mostrado literalmente), a configuração do transporte (incluindo segredos) vai inteiramente para o armazenamento cifrado e as instâncias personalizadas têm sempre um prefixo fixo para que nunca possam fazer-se passar por um conector oficial no catálogo.

  • Ponte inversa: permitir que os agentes externos da máquina, por sua vez, tenham acesso ao Orkas. Esta é a peça mais interessante. As ferramentas de agentes externos já instaladas na máquina do utilizador eram uma caixa negra para o Orkas; agora, quando o Orkas as aciona, injeta um canal de ligação que permite no sentido inverso listar/ler/executar as competências do Orkas, chamar conectores e pesquisar a base de conhecimento. A ponte é executada num canal local entre processos (sem portas de rede abertas), autenticada com uma credencial única, exclusiva de cada execução e destruída assim que a execução termina. Cada chamada de conector com um efeito secundário externo passa por uma caixa de diálogo de confirmação do utilizador — não uma avaliação heurística de leitura/escrita pelo nome da ferramenta (que seria um erro por ser demasiado vaga), mas uma confirmação por (agente, conector), com uma opção "permitir sempre".

  • Abordagem de programação de cauda longa. A árvore de decisão do comandante ganha uma ramificação: quando não há agente/habilidade/conector correspondente, avalie a solução diretamente com bash mais um script curto, faça-o neste turno, verifique a saída e, opcionalmente, ofereça-se para a transformar numa competência personalizada. Isto vem acompanhado da execução de bash em segundo plano (as tarefas longas são separadas do turno atual, os registos vão para um ficheiro) e de diretórios autorizados pelo utilizador.

Aberto, mas sem intervenção

O que mais se teme ao abrir as portas e janelas é uma corrente de ar. A disciplina desta refatorização: nenhum dos pontos de controlo de criação de processos para "ações perigosas" é alterado. O MCP é iniciado num único local, a execução de competências passa por um único executor e o bash passa por um único executor isolado. Além disso, sobrepõem-se várias camadas de defesa em profundidade:

  • As operações sobre ficheiros passam sempre pelo percurso isolado (espaço de trabalho + anexos atuais + diretórios a que o utilizador concedeu explicitamente acesso), enquanto os diretórios de credenciais, os diretórios do sistema e os próprios diretórios do Orkas não podem ser autorizados;
  • O bash perigoso (exfiltração, eliminação destrutiva, elevação de privilégios, caminhos confidenciais) aciona uma confirmação de permissão, com a decisão dividida em "só desta vez/para esta execução/negar", e os registos guardam apenas a categoria e o comprimento — nunca o texto do comando;
  • A instalação de pacotes externos bloqueia em caso de falha e recusa por completo pacotes com elementos de ligação simbólica (para evitar a utilização de uma ligação simbólica para ler ficheiros confidenciais fora do âmbito do ambiente isolado), e a origem do clone é restrita a uma lista de protocolos permitidos;
  • Todos os transportes/segredos com credenciais são cifrados em repouso e as credenciais da ponte são isoladas por execução;
  • A distribuição de código aberto/alojada elimina as funcionalidades exclusivas do sistema anfitrião através de uma regra de exclusão.

Numa frase: cada ação explícita do utilizador (instalar/conceder/submeter formulário/clicar em confirmar) constitui a credencial de consentimento, e todo o consentimento está confinado ao limite que lhe corresponde.

5. Tornar-se mais inteligente ao longo das sessões: memória e autoevolução

A revisão da base também reformulou dois subsistemas que "tornam o agente mais inteligente quanto mais é usado", ambos seguindo a mesma disciplina de engenharia — desativado por predefinição, limitado, observável.

Memória entre sessões usa recuperação híbrida: pesquisa semântica vetorial + pesquisa por palavra-chave (BM25), combinadas através de RRF (fusão de classificação recíproca) para evitar falhas num único canal; os dados ficam no armazenamento local (com um índice de texto integral). A memória tem dois tipos — as notas do próprio agente e o perfil de preferências do utilizador — cada um com um limite de caracteres, verificado quanto a ameaças de injeção antes da escrita e injetado como uma cópia fixa nas instruções do sistema no início de cada turno. Todo o sistema de memória serve apenas para fazer com que o agente compreenda melhor o utilizador atual; os dados permanecem sempre locais e o utilizador pode visualizá-los, editá-los e exportá-los a qualquer momento nas definições.

Autoevolução é uma biblioteca de competências privadas do agente (armazenada separadamente da biblioteca de competências partilhadas da plataforma) mais uma camada de reflexão metacognitiva. O motor decide se deve refletir com base num conjunto de sinais ponderados: correção do utilizador (peso mais alto), recuperação de um erro não trivial, complexidade da tarefa, manifestação ou superação de uma fraqueza conhecida, ineficácia de uma competência... a reflexão só é acionada quando os sinais ponderados excedem um limite. A própria reflexão é uma tarefa periódica em segundo plano (aproximadamente uma iteração a cada 12 horas, um período de espera de várias horas, uma alternativa de recurso de vários dias) que usa um modelo pequeno e barato para ler um resumo da atividade recente e decidir se deve criar/corrigir uma competência e atualizar o "perfil de competência" do agente.

O ponto de segurança mais importante: a autoevolução só é ativada em sessões que têm um agente explicitamente associado — a sessão predefinida do comandante não evolui. O Reflection tem um limite duplo de tokens (contagem + total), a falha de um agente não bloqueia os outros e o custo por execução é extremamente baixo. Torne o agente mais inteligente, mas não o deixe escapar ao controlo.

Filosofia de engenharia: complexidade conquistada — não a simplifique

A equipa realizou várias rondas de revisão da arquitetura durante a refatorização, e uma conclusão surgiu repetidamente, merecendo ser destacada por si só: distinguir "hipertrofia organizacional" de "complexidade adquirida" e abordar apenas a primeira.

  • As múltiplas estratégias de fusão do mecanismo de sincronização, o ciclo de agente desenvolvido internamente, o invólucro multicamada do fornecedor, a fronteira do controlo remoto móvel — tudo isto parece complexo, mas cada camada justifica a sua existência (consistência eventual entre vários dispositivos, integração profunda, rotação de várias chaves, uma fronteira final decidida pelo produto). "Simplificá-los" à força apenas causaria perda de dados e confundiria as camadas.
  • O que realmente deve ser alterado são os "módulos divinos" e a duplicação local: extrair as funções puras sem estado do barramento de conversas em grupo sobrecarregado (montagem de instruções, ferramentas do comandante, turno da CLI) e reunir o padrão de "diálogo de confirmação", duplicado várias vezes, num componente partilhado.

O que sustenta este tipo de avaliação é um conjunto de regras rigorosas escritas no documento de restrições do projeto: fronteira (processo único, IPC como único caminho, o ambiente de execução só pode ser carregado dinamicamente), camadas (a direção das dependências de cada camada), fonte única de verdade (categorias, taxonomia de telemetria, domínios) e uma "auditoria imediata" obrigatória em cada commit relativo às instruções. O que permite rever a base sem entrar em colapso não é uma conceção inteligente – são estas invariantes mantidas continuamente.

Encerramento

Juntando as quatro vertentes, o que esta refatorização fundamental traz ao Orkas é uma base de agentes que é autocontrolada, independente do fornecedor, orquestrada dinamicamente, aberta ao exterior e capaz de autoevoluir:

  • Um ambiente de execução dentro do processo com duas camadas, motor/adaptador, que traz um conjunto completo de capacidades do agente de programação — operações sobre ficheiros, pesquisa local, ferramentas do sistema, vários agentes de trabalho em paralelo, resolução de longo horizonte — nativamente para o computador e prepara cada uma delas para produção;
  • Uma camada de modelos multicamada que mantém a conversa ativa perante problemas de chave/fornecedor/rede, tanto quanto possível;
  • Uma orquestração multiagente em forma de conversa em grupo, com o comandante no ciclo, que troca o "planeamento estático" pela "decisão dinâmica" e, pela primeira vez, faz com que as transferências entre agentes pareçam naturais;
  • Um ecossistema que passa de um catálogo fechado para um sistema de alojamento aberto, com pacotes externos, competências globais, MCP personalizado e a ponte inversa, todos abertos — enquanto os pontos de controlo de criação de processos não mudaram nem um centímetro;
  • E memória e autoevolução desativadas por predefinição, limitadas e observáveis.

As funcionalidades podem ser adicionadas uma de cada vez, mas só vale a pena rever seriamente uma base uma vez. Depois de concluída a revisão, tudo o que construir será mais rápido - e esse é precisamente o resultado que esta refatorização procurava.