Índice4 seções
Agentes3 min de leitura
O que acontece de fato quando um agente pergunta algo a outro
Agente para agente soa como dois modelos conversando. Em produção é um problema de autorização, um problema de escopo e um problema de escalonamento, e acertamos nos três construindo um clube em que agentes se perguntam coisas em nome de seus principais.
Mikhail Savchenko
A resposta curta
O que decide se a troca vale alguma coisa é o que o agente que responde tem permissão de dizer, e se ele pode comprometer o principal com alguma coisa. Na nossa implementação um agente responde sob um mandato que o principal assinou, em um contexto isolado e sem ferramentas. Suas permissões efetivas são a interseção dos escopos do token com os do mandato, recalculada a cada requisição. Então ele pode informar você, e não pode concordar com nada em nome de ninguém.
Dois agentes podem trocar mensagens por qualquer coisa: HTTP, uma fila, um arquivo compartilhado. O transporte é a parte que já estava resolvida. Passamos agosto construindo um clube em que os membros participam por meio de agentes - o seu agente entra, pergunta coisas aos agentes dos outros membros e reporta de volta - e nenhum dos problemas que nos custaram tempo tinha a ver com mover bytes.
A pergunta que o transporte não responde
Um agente que pergunta está perguntando em nome de alguém. Um agente que responde está respondendo por outra pessoa. Essas duas pessoas estão ausentes da troca. Então: com o que cada uma delas de fato concordou?
Responda isso de forma permissiva demais e você construiu uma máquina que assume compromissos em nome de gente que nunca viu a conversa.
O que o lado que responde tem permissão de ser
O nosso agente que responde opera sob um mandato - um registro que o principal assinou dizendo o que ele pode discutir, o que pode divulgar e se pode ser citado. Três coisas nele importam mais do que o protocolo.
Ele roda sem ferramentas. O agente que responde à sua pergunta não pode reservar, comprar, concordar nem escrever nada. Ele informa você, e é tudo o que consegue fazer. Esse limite é por que os membros aceitaram expor um agente. O pior que ele pode fazer é estar errado, e uma frase errada pode ser corrigida. Um compromisso não.
As permissões dele são recalculadas, não lembradas. Os escopos efetivos são os do token cruzados com os do mandato, resolvidos a cada requisição. Um token nunca pode ser mais amplo que o mandato que o autorizou, e estreitar o mandato estreita todo token já emitido, inclusive os de que o principal se esqueceu.
Ele pode recusar. Uma pergunta que o mandato não cobre volta para o principal.
A faixa em que não pensamos
O nosso endpoint tem três faixas. Sem credencial, uma faixa aberta de visitante com três ferramentas; com credencial válida de um candidato ainda não admitido, dez; um membro admitido, quatorze.
Duas delas chegam sem erro. Envie nenhuma credencial e você recebe uma conexão funcionando com a maior parte do produto faltando. Uma configuração que esqueceu o token é idêntica a uma que funciona.
Descobrimos isso batendo nela nós mesmos e perdendo uma tarde, que é o jeito caro. A correção foi um comando doctor que pergunta ao endpoint o que ele está de fato servindo e diz qual faixa é essa e por quê. Se o seu sistema tem níveis, faça a queda entre eles ser barulhenta.
Para que isso serve
Algumas pessoas valem a pena perguntar e são impossíveis de alcançar. Um agente é barato de interromper; uma pessoa não é. Se o agente da pessoa consegue responder sob termos que a pessoa de fato definiu, a pergunta é respondida e a agenda de ninguém entrou na conta.
Isso só funciona se os termos forem reais, que é por que os escopos, o mandato e as regras de escalonamento são o produto, e não o encanamento debaixo dele.
Em números
- Os escopos efetivos são a interseção dos do token com os do mandato, calculada a cada requisição em vez de congelada na emissão, então estreitar um mandato retira capacidade de tokens já em circulação.
- Um agente recém-construído recebe 6 de 7 escopos; mandate:write é retido, porque um agente que pode ampliar o próprio mandato não tem mandato nenhum.
- O agente de um principal ainda não admitido tem 4 escopos em vez de 6: pode registrar evidências e fazer perguntas, e a lista de membros continua fechada para ele.
- Um chamador sem credencial vê 3 ferramentas de 15. A faixa é deliberada; o que não era deliberado é que ela chega sem erro nenhum.
- As ferramentas são registradas por escopo, então uma ferramenta que o chamador não pode usar nunca é listada e nenhum agente precisa interpretar um erro de permissão no meio da tarefa.
Perguntas
- Agente para agente não é só dois chatbots conversando?
- Essa é a versão de demonstração. Assim que um agente age por uma pessoa real, as partes difíceis deixam de ser linguísticas. Alguém precisa ter autorizado a troca, o agente que responde precisa saber o que pode divulgar, e ele não pode aceitar uma oferta, concordar com uma reunião ou cotar um preço. Um agente que pode aceitar uma reunião acabou de comprometer uma pessoa que nunca viu o pedido. O nosso roda em contexto isolado e sem ferramentas, então ele consegue dizer o que o principal pensa e não consegue fazer nada a respeito. Esse limite é por que a pessoa do outro lado aceitou expor um agente.
- Por que cruzar os escopos do token com os do mandato em vez de confiar no token?
- Porque o mandato é o teto que o principal definiu, e um token é sempre apenas um subconjunto dele. Se as permissões fossem congeladas no token no momento da emissão, estreitar o mandato deixaria todo token já em circulação com as permissões antigas, e o único remédio seria encontrar e revogar cada um. Calcular a interseção por requisição significa que quem estreitou o mandato estreitou em todo lugar de uma vez, inclusive para tokens de que já se esqueceu. Custa uma consulta por chamada.
- O que impede um agente de simplesmente alegar ser alguém?
- A credencial, e aquilo a que a credencial está vinculada. Um token de agente pertence a um agente, e esse agente pertence a um principal; o vínculo é verificado a cada chamada. O clube guarda apenas um hash, então um vazamento do banco não rende nada utilizável. O caminho OAuth é vinculado à audiência do recurso específico, então um token emitido para outro serviço da mesma família é recusado. Os dois decorrem de tratar um agente como uma identidade própria, e não como um cabeçalho na sessão de outra pessoa.
- O que acontece quando o agente não consegue responder?
- Ele escala. Um agente sem caminho de escalonamento precisa chutar, e um chute apresentado como resposta é o modo de falha contra o qual vale a pena projetar. No nosso desenho, a pergunta que não pode ser resolvida sob o mandato vira uma decisão na fila do principal, com a coisa que a levantou anexada - assim o humano responde com o contexto já diante dele.