No ano passado, trabalhamos com equipes que criaram agentes LLM (Large Language Model) em vários setores. De forma consistente, descobrimos que as implementações mais bem-sucedidas não usam estruturas complexas ou bibliotecas especializadas, mas são construídas com padrões simples e compostáveis.
Nesta publicação, compartilharemos nossas experiências de trabalho com clientes e agentes de construção e forneceremos aos desenvolvedores conselhos práticos para a criação de agentes eficientes.
Inteligente/agente/Agente tem o mesmo significado no seguinte.
O que é um agente?
"Agente" pode ser definido de várias maneiras. Alguns clientes definem agentes como sistemas totalmente autônomos que podem ser executados de forma independente por longos períodos de tempo, usando uma variedade de ferramentas para executar tarefas complexas. Outros o utilizam para descrever implementações mais prescritivas que seguem fluxos de trabalho predefinidos. Na Anthropic, nós nos referimos a essas variantes coletivamente como Sistemas AgenciadosMas há um desafio arquitetônico para a fluxo de trabalho responder cantando agir em nome de alguém em uma posição de responsabilidade Foram feitas distinções importantes:
- fluxo de trabalho é um sistema que orquestra LLMs e ferramentas por meio de caminhos de código predefinidos.
- agir em nome de alguém em uma posição de responsabilidade é um sistema no qual o LLM dirige dinamicamente seus próprios processos e o uso de ferramentas para manter o controle sobre como as tarefas são realizadas.
A seguir, exploramos esses dois sistemas com agentes em mais detalhes. No Apêndice 1 ("Agentes na prática"), descrevemos duas áreas em que o uso desses sistemas pelos clientes tem sido particularmente valioso.
Quando (e quando não) usar proxies
Ao criar aplicativos com o LLM, recomendamos que se busque a solução mais simples possível, acrescentando complexidade somente quando necessário. Isso pode significar não criar sistemas com agentes de forma alguma. Os sistemas com proxy geralmente trocam a latência e o custo por um melhor desempenho da tarefa, e você precisa considerar se essa troca vale a pena.
Os fluxos de trabalho oferecem previsibilidade e consistência para tarefas bem definidas quando é necessária maior complexidade, enquanto os agentes têm melhor desempenho quando é necessária flexibilidade e escalonamento de decisões baseadas em modelos. No entanto, para muitos aplicativos, a otimização de uma única chamada de LLM, combinada com exemplos contextuais e de recuperação, costuma ser suficiente.
Quando e como usar a estrutura
Há várias estruturas que facilitam a implementação de sistemas com agentes, incluindo:
- LangGraph de LangChain;
- Amazon Bedrock's Estrutura do agente de IA.;
- RebiteO construtor de fluxo de trabalho do LLM é um construtor de fluxo de trabalho do LLM com GUI de arrastar e soltar;
- VelinoOutra ferramenta GUI para criar e testar fluxos de trabalho complexos.
Essas estruturas facilitam o processo de desenvolvimento, simplificando as tarefas padrão de baixo nível, como chamar LLMs, definir e analisar ferramentas e vincular chamadas. Entretanto, elas tendem a adicionar camadas extras de abstração que podem obscurecer as dicas e respostas subjacentes, dificultando a depuração. Isso também pode inclinar a balança a favor do aumento da complexidade, quando, na realidade, uma configuração mais simples pode ser suficiente.
Recomendamos que os desenvolvedores usem primeiro a API do LLM diretamente: muitos padrões podem ser implementados com poucas linhas de código. Se estiver usando uma estrutura, certifique-se de entender o código subjacente. Falsas suposições sobre a lógica subjacente da estrutura são uma fonte comum de erros do cliente.
Veja nossa livro de receitas para alguns exemplos de implementações.
Blocos de construção, fluxos de trabalho e agentes
Nesta seção, exploraremos os padrões comuns de sistemas com agentes que vemos em ambientes de produção. Começaremos com o bloco de construção básico, o LLM Aprimorado, e depois aumentaremos gradualmente a complexidade de fluxos de trabalho combinatórios simples para agentes autônomos.
Blocos de construção: LLM aprimorado
O componente básico do sistema agente é o LLM aprimorado, que integra recursos aprimorados, como pesquisa, ferramentas e memória. Nosso modelo atual pode usar esses recursos de forma proativa, gerando suas próprias consultas de pesquisa, selecionando ferramentas apropriadas e decidindo quais informações devem ser retidas.
Recomendamos que você se concentre em dois aspectos principais da implementação: personalizar esses recursos para que se adaptem ao seu caso de uso específico e garantir que eles ofereçam uma interface fácil de usar e bem documentada para o LLM. Embora esses aprimoramentos possam ser implementados de várias maneiras, uma abordagem é usar nosso protocolo de contexto de modelo lançado recentemente, que permite que os desenvolvedores se integrem ao crescente ecossistema de ferramentas de terceiros por meio de uma implementação simples no lado do cliente.
No restante deste documento, presumimos que esses aprimoramentos são acessíveis em todas as chamadas ao LLM.
Fluxo de trabalho: encadeamento de prompts
A cadeia de dicas divide a tarefa em uma série de etapas, com cada chamada do Modelo de Linguagem Grande (LLM) processando a saída da etapa anterior. Você pode adicionar verificações de procedimento (veja "gate" na figura abaixo) em qualquer etapa intermediária para garantir que o processo ainda esteja no caminho certo.
Quando usar esse fluxo de trabalho:
Esse fluxo de trabalho é ideal quando as tarefas podem ser fácil e claramente divididas em subtarefas fixas. O principal objetivo é melhorar a precisão e reduzir a latência, simplificando cada chamada LLM em tarefas mais gerenciáveis.
Exemplos de onde a cadeia de dicas se aplica:
- Gerar textos de marketing e depois traduzi-los para diferentes idiomas.
- Escreva um esboço do documento, verifique se o esboço atende a determinados critérios e, em seguida, escreva o documento com base no esboço.
Fluxo de trabalho: roteamento
O roteamento categoriza a entrada e a direciona para uma tarefa de acompanhamento especializada. Esse fluxo de trabalho permite a separação das preocupações e a construção de prompts mais especializados. A otimização para um tipo de entrada pode prejudicar o desempenho de outras entradas se esse fluxo de trabalho não for usado.
Quando usar esse fluxo de trabalho:
Os fluxos de trabalho de roteamento têm bom desempenho quando tarefas complexas têm categorias diferentes que precisam ser processadas separadamente e a classificação pode ser tratada com precisão pelo LLM ou por modelos/algoritmos de classificação mais tradicionais.
Exemplos aplicáveis de roteamento:
- Direcionar diferentes tipos de consultas de atendimento ao cliente (perguntas gerais, solicitações de reembolso, suporte técnico) para diferentes processos, dicas e ferramentas de downstream.
- Encaminhar problemas simples/comuns para modelos menores (por exemplo Claude 3.5 Haiku), enquanto encaminha problemas complexos/incomuns para modelos mais avançados (por exemplo, Claude 3.5 Sonnet) para otimizar o custo e a velocidade.
Fluxo de trabalho: paralelização (Paralelização)
Às vezes, os LLMs podem processar tarefas simultaneamente, e seus resultados são agregados programaticamente. Há duas variações principais de fluxos de trabalho paralelizados:
- Seccionamento: Decompor tarefas em subtarefas independentes que podem ser executadas em paralelo.
- Votação: Execute a mesma tarefa várias vezes para obter resultados diferentes.
Quando usar esse fluxo de trabalho:
A paralelização é eficaz quando as subtarefas decompostas podem ser processadas em paralelo para aumentar a velocidade, ou quando são necessárias várias perspectivas ou tentativas para obter resultados mais confiáveis. Para tarefas complexas com várias considerações, cada consideração é geralmente melhor executada por uma chamada separada do LLM para processá-la, concentrando-se assim em cada aspecto específico.
Exemplos de onde a paralelização se aplica:
- Seccionamento:
- Implemente proteções em que uma instância do modelo lide com as consultas do usuário e a outra faça a triagem de conteúdo ou solicitações inadequadas. Isso geralmente é melhor do que ter a mesma chamada de LLM para lidar com as proteções e a resposta principal.
- Avaliação automatizada do desempenho do LLM, em que cada chamada do LLM avalia um aspecto diferente do desempenho do modelo em uma determinada pista.
- Votação:
- Revisão do código em busca de vulnerabilidades, verificando o código várias vezes por meio de diferentes prompts e sinalizando os problemas encontrados.
- Avaliar a inadequação do conteúdo, usando vários prompts para avaliar diferentes aspectos ou exigindo diferentes limites de votação para equilibrar falsos positivos e omissões.
Fluxo de trabalho: Orquestrador-trabalhadores
Em um fluxo de trabalho coordenador-trabalhador, o LLM central decompõe dinamicamente as tarefas, delega-as aos LLMs trabalhadores e sintetiza seus resultados.
Quando usar esse fluxo de trabalho:
Esse fluxo de trabalho é muito adequado quando a tarefa é complexa e as subtarefas necessárias não podem ser previstas (por exemplo, na codificação, em que o número de arquivos a serem alterados e a natureza das alterações em cada arquivo podem depender da tarefa específica). Semelhante aos fluxos de trabalho paralelos, mas a principal diferença é a flexibilidade - as subtarefas não são predefinidas, mas são decididas pelo coordenador com base em entradas específicas.
Exemplos de aplicação de coordenador-trabalhador:
- Produtos de codificação que fazem alterações complexas em vários arquivos ao mesmo tempo.
- Uma tarefa de pesquisa que envolve a coleta e a análise de informações de várias fontes para encontrar informações que possam ser relevantes.
Fluxo de trabalho: Avaliador-Otimizador
No fluxo de trabalho do avaliador-otimizador, uma chamada do Large Language Model (LLM) gera a resposta, enquanto a outra fornece avaliação e feedback, formando um loop.
Quando usar esse fluxo de trabalho: O fluxo de trabalho é particularmente eficaz quando temos critérios de avaliação claros e a otimização iterativa proporciona um valor mensurável. Duas marcas registradas aplicáveis são, primeiro, que as respostas do LLM podem ser significativamente aprimoradas quando os humanos expressam feedback e, segundo, que o LLM é capaz de fornecer esse feedback. Isso é análogo ao processo de escrita iterativo pelo qual um escritor humano pode passar ao escrever um documento polido.
Exemplos de aplicabilidade do otimizador-avaliador:
- Traduções literárias, em que o LLM do tradutor pode não captar inicialmente todas as nuances, mas o LLM do avaliador pode fornecer críticas úteis.
- Tarefas de pesquisa complexas que exigem várias rodadas de pesquisa e análise para reunir informações abrangentes, com o avaliador decidindo se são necessárias mais pesquisas.
Intelligentsia/Agentes
Os agentes (Agents) estão aparecendo gradualmente na produção à medida que o LLM amadurece em recursos importantes, como compreensão de entradas complexas, raciocínio e planejamento, uso confiável de ferramentas e recuperação de erros. Os agentes começam seu trabalho com instruções de um usuário humano ou por meio de discussões interativas. Quando a tarefa está clara, os agentes planejam e operam de forma independente, possivelmente retornando ao ser humano para obter mais informações ou julgamento. Durante a execução, o agente deve obter "informações reais" do ambiente (por exemplo, resultados de chamadas de ferramentas ou execução de código) em cada etapa para avaliar seu progresso. O agente pode fazer uma pausa nos pontos de controle ou quando encontrar obstáculos para obter feedback humano. As tarefas geralmente terminam quando são concluídas, mas muitas vezes incluem condições de parada (por exemplo, número máximo de iterações) para manter o controle.
Os agentes podem lidar com tarefas complexas, mas suas implementações geralmente são relativamente simples. Em geral, são apenas grandes modelos de linguagem baseados em loops de feedback ambiental para o uso da ferramenta. Portanto, o projeto de um conjunto de ferramentas e sua documentação precisam ser claros e bem pensados. No Apêndice 2 ("Engenharia de dicas para ferramentas"), falamos mais sobre as práticas recomendadas para o desenvolvimento de ferramentas.
Quando usar proxies: Os agentes podem ser usados para problemas abertos em que o número de etapas necessárias não pode ser previsto e em que os caminhos fixos não podem ser codificados. O LLM pode exigir várias rodadas de operações, portanto, é preciso ter alguma confiança em seus recursos de tomada de decisão. A autonomia do agente o torna adequado para tarefas de escalonamento em um ambiente confiável.
A autonomia do agente implica custos mais altos e o risco potencial de acúmulo de erros. Recomendamos testes extensivos em um ambiente sandbox com medidas de segurança adequadas.
Exemplo de aplicativo de proxy:
Os exemplos a seguir são de nossas implementações reais:
- Agente de codificação para resolver tarefas do SWE-bench que envolvem a edição de vários arquivos de acordo com a descrição da tarefa;
- nosso "Realização da referência "Uso do computadorNesse caso, Claude usou um computador para concluir a tarefa.
Combine e personalize esses modelos
Esses blocos de construção não são obrigatórios. Eles são padrões comuns que os desenvolvedores podem adaptar e combinar para diferentes casos de uso. Como acontece com qualquer recurso do LLM, a chave para o sucesso é medir o desempenho e iterar a implementação. Mais uma vez: você só deve considerar a adição de complexidade se ela melhorar significativamente os resultados.
resumos
O sucesso no campo da Modelagem de Linguagem Ampla (LLM) não se trata de criar o sistema mais complexo, mas de criar o sistema que melhor atenda às suas necessidades. Comece com dicas simples, otimize-as por meio de uma avaliação completa e adicione sistemas de agentes de várias etapas somente quando as soluções simples não atenderem às suas necessidades.
Ao implementar proxies, seguimos três princípios fundamentais:
- Atualização de projetos de agentes simplicidade .
- Priorize as etapas de planejamento demonstrando claramente a transparência .
- Por meio de ferramentas detalhadas Documentação e testes Projete cuidadosamente sua interface agente-computador (ACI).
As estruturas podem ajudá-lo a começar rapidamente, mas não hesite em reduzir as camadas de abstração e construir com componentes básicos ao passar para a produção. Seguindo esses princípios, você pode criar agentes que não sejam apenas poderosos, mas também confiáveis, passíveis de manutenção e que tenham a confiança dos usuários.
uma nota de agradecimento
Este artigo foi escrito por Erik Schluntz e Barry Zhang. Este trabalho baseia-se em nossa experiência na criação de agentes na Anthropic e nos valiosos insights compartilhados por nossos clientes, pelos quais somos gratos.
Apêndice 1: Aplicações práticas de proxies
Nosso trabalho com nossos clientes revelou duas aplicações particularmente promissoras de agentes de IA que demonstram o valor prático dos padrões descritos acima. Esses aplicativos mostram que os agentes são mais valiosos em tarefas que exigem uma combinação de diálogo e ação, têm critérios claros de sucesso, suportam ciclos de feedback e permitem uma supervisão humana eficaz.
A. Suporte ao cliente
O suporte ao cliente combina a interface familiar do chatbot com funcionalidade aprimorada para integração de ferramentas. Esse cenário é perfeito para agentes mais abertos, como:
- Apoiar interações que sigam naturalmente um fluxo de diálogo, ao mesmo tempo em que exigem acesso a informações externas e execução de ações;
- As ferramentas podem ser integradas para extrair dados de clientes, histórico de pedidos e artigos da base de conhecimento;
- As operações (como a emissão de reembolsos ou a atualização de ordens de serviço) podem ser tratadas de forma programática;
- O sucesso pode ser claramente medido por soluções definidas pelo usuário.
Várias empresas demonstraram a viabilidade dessa abordagem por meio de um modelo de preços baseado no uso que cobra apenas pelos casos resolvidos com sucesso, demonstrando confiança na eficácia da agência.
B. Agentes de programação
O campo de desenvolvimento de software mostrou um potencial significativo para a funcionalidade LLM, evoluindo do preenchimento de código para a solução autônoma de problemas. Os agentes são particularmente eficazes porque:
- As soluções de código podem ser verificadas por meio de testes automatizados;
- Os agentes podem usar os resultados dos testes como feedback para iterar a solução;
- As áreas problemáticas são claras e estruturadas;
- A qualidade do resultado pode ser medida de forma objetiva.
Em nossa implementação, o proxy foi capaz de resolver individualmente as descrições de pull requests com base no SWE-bench Verificado Problemas reais do GitHub na avaliação comparativa. No entanto, embora os testes automatizados possam ajudar a validar a funcionalidade, a revisão manual ainda é vital para garantir que a solução atenda aos requisitos mais amplos do sistema.
Apêndice 2: Projeto de dica de ferramenta
Independentemente do tipo de sistema de agente que você está criando, as ferramentas provavelmente são uma parte importante do seu agente. As ferramentas permitem que o Claude interaja com serviços externos e APIs, especificando sua estrutura e definições exatas. Quando o Claude responde, se ele planeja invocar uma ferramenta, ele incluirá na resposta da API um bloco de uso de ferramentas . As definições e especificações de ferramentas devem estar sujeitas à engenharia de dicas tanto quanto as dicas gerais. Neste apêndice, descrevemos brevemente como as ferramentas podem ser projetadas com dicas.
Normalmente, há várias maneiras de especificar a mesma operação. Por exemplo, você pode especificar a edição de arquivos escrevendo diff ou reescrevendo o arquivo inteiro. Para saída estruturada, você pode retornar código em markdown ou código em JSON. Na engenharia de software, essas diferenças são cosméticas e podem ser convertidas umas para as outras sem perda. Entretanto, alguns formatos são mais difíceis de serem escritos pelo LLM do que outros. Por exemplo, escrever diff requer saber quantas linhas em um cabeçalho de bloco estão sendo alteradas antes que o novo código seja escrito. Escrever código em JSON (em vez de markdown) requer um escape adicional de quebras de linha e aspas.
As recomendações sobre o formato da ferramenta são apresentadas a seguir:
- Dê ao modelo o suficiente Tokens "Pense" para não ficar preso em uma rotina.
- Mantenha a formatação próxima ao texto que o modelo veria naturalmente na Internet.
- Certifique-se de que não haja "ônus extras" para o formato, como ter que calcular exatamente milhares de linhas de código ou escapar de qualquer código que ele escreva.
Uma regra geral é considerar quanto esforço é feito na interface homem-computador (HCI) e também planejar a criação de uma boa agir em nome de alguém em uma posição de responsabilidade -Empenho igual é investido na interface do computador (ACI). A seguir, algumas sugestões:
- Pense em termos de modelos. É óbvio usar essa ferramenta com base na descrição e nos parâmetros? Se isso exigir uma reflexão cuidadosa, provavelmente também o será para o modelo. Uma boa definição de ferramenta geralmente inclui exemplos de uso, casos de limite, requisitos de formato de entrada e limites claros com outras ferramentas.
- Como você pode alterar o nome ou a descrição de um parâmetro para torná-lo mais óbvio? Pense nisso como escrever ótimas notas de documentação (docstring) para os desenvolvedores juniores da sua equipe. Isso é especialmente importante quando se usa muitas ferramentas semelhantes.
- Teste como o modelo usa suas ferramentas: execute muitas entradas de amostra em nosso workbench, observe os erros que o modelo comete e repita.
- Poka-yoke Suas ferramentas. Altere os parâmetros para dificultar a ocorrência de erros.
Ao criar agentes para o SWE-bench, na verdade passamos mais tempo otimizando as ferramentas do que otimizando o prompt geral. Por exemplo, descobrimos que as ferramentas que usavam caminhos de arquivos relativos eram propensas a erros quando o agente era movido para fora do diretório raiz. Para corrigir esse problema, alteramos a ferramenta para que ela sempre exigisse caminhos de arquivo absolutos - descobrimos que o modelo não tinha nenhum problema com essa abordagem.