Guia de referência

Encontre rapidamente informações detalhadas sobre todos os componentes do Agent Framework nesta referência abrangente.

Estrutura de pastas

Para criar um agente, você cria uma pasta para ele, nomeada com o nome do agente e que contém pelo menos os seguintes arquivos:

  • agent.py: o arquivo principal do agente. Você precisa definir seu agente raiz na variável global root_agent.
  • __init__.py: o arquivo do módulo Python. Ele precisa conter pelo menos uma linha from agents import Agent para importar a classe Agent.

Opcionalmente, recomendamos que você adicione os seguintes arquivos:

  • requirements.txt: o arquivo de requisitos do Python para o agente.
  • README.md: o arquivo README do agente. Ele precisa conter as instruções de configuração e execução do agente.

O agente.py mínimo

A criação de um agente começa com a criação de uma instância da classe Agent. O agente mínimo precisa ter os seguintes atributos:

  • name: o nome do agente.
  • model: o nome do modelo de LLM a ser usado.
  • instruction: instruções em linguagem natural para o agente.

Exemplo:

from agents import Agent

root_agent = Agent(
    model='gemini-1.5-flash',
    name='root_agent',
    instruction="Be polite and answer all users' questions.",
)

Para criar um agente mínimo, copie a pasta _empty_agent e modifique o arquivo agent.py.

Atributos

nome

  name: str

O nome do agente.

  • Identificador

    • O nome precisa seguir a convenção de nomenclatura do identificador.
    • Uma string é considerada um identificador válido se conter apenas letras alfanuméricas (a-z) e (0-9) ou sublinhados (_). Um identificador válido não pode começar com um número nem conter espaços.
  • Exclusivo

    • O nome precisa ser exclusivo em toda a árvore de agentes.
  • Agente raiz

    • Embora a variável do agente raiz precise ser chamada de root_agent, você pode definir um atributo de nome mais significativo para o agente raiz.

modelo

  model: str

O nome do modelo de LLM a ser usado.

  • Obrigatório para o agente de LLM

    • O atributo "model" é obrigatório apenas para o agente LLM.
    • Não é necessário definir o atributo do modelo para agentes sequenciais, de loop ou outros que não sejam LLM.
  • Agente pai

    • Você pode omitir o atributo do modelo. Nesse caso, o agente vai usar o atributo de modelo do agente pai / ancestral.
  • Formato

    • O formato do nome do modelo varia de acordo com o fornecedor do LLM.
    • Para o Gemini, é gemini-1.5-flash ou gemini-2.0-flash-exp.
    • Para a Anthropic na Vertex, parece claude-3-5-sonnet-v2@20241022
    • Embora o design do framework permita qualquer fornecedor de modelo, atualmente só oferecemos suporte para Gemini e Anthropic no Vertex.

instrução

  instruction: str | InstructionProvider

As instruções de linguagem natural para o agente.

  • Obrigatório para o agente de LLM

    • A instrução é necessária apenas para o agente de LLM.
    • Não é necessário definir o atributo de instrução para sequencial, loop ou outros agentes que não sejam LLM.
  • Tipo de dado

    • A instrução pode ser uma string.
    • A instrução também pode ser um InstructionProvider invocável.
  • InstructionProvider

    • Um InstructionProvider é definido como Callable[[InvocationContext], str]
    • Ele permite fornecer uma função para gerar dinamicamente a instrução com base no contexto de invocação.
  • Estado

    • A instrução é um modelo de string. Você pode usar a sintaxe {var} para inserir valores dinâmicos na instrução.

    var

    é usado para inserir o valor da variável de estado chamada var.

    artifact.var

    é usado para inserir o conteúdo de texto do artefato chamado var.
    • Se a variável de estado ou o artefato não existir, o agente vai gerar um erro. Se você quiser ignorar o erro, adicione um ? ao nome da variável, por exemplo, {var?}.
  • Diretrizes

    • Comece dizendo quem é o agente, o que ele pode fazer e o que não pode.
    • Você pode usar o formato Markdown para tornar as diretrizes mais legíveis, tanto para humanos quanto para o modelo.
    • Se o agente puder realizar várias tarefas, forneça uma lista de tarefas e tenha seções separadas para cada uma delas.
    • Se uma tarefa tiver várias etapas, forneça uma lista de etapas e instruções detalhadas para cada uma.
    • Se o agente puder usar ferramentas, liste-as no atributo tools. A definição da ferramenta tem instruções sobre como usá-las, mas instruções detalhadas sobre quando usá-las podem ser adicionadas à instrução do agente para melhorar a performance.
    • Para um sistema multiagente, descreva quando ele precisa ser transferido para o outro agente.
    • Você pode incluir exemplos de entrada e saída esperada na instrução. Também é possível usar o atributo examples para fornecer exemplos.
    • Seja minucioso e específico na instrução. Trate o agente como um novo funcionário que está passando pelo processo de treinamento.
    • Não confie em instruções sobre regras que precisam ser seguidas 100% do tempo. O modelo tem um grau de liberdade e pode cometer erros. Use ferramentas e callbacks para aplicar regras rígidas.

description

  description: str

Descreve o que esse agente pode fazer. Essa descrição é enviada ao modelo como parte das instruções do sistema para:

  1. O próprio agente entende os próprios recursos com base na descrição.

  2. Um agente entende o que outros agentes podem fazer e decide se vai fazer a transferência com base nas descrições deles.

global_instruction

  global_instruction: str | InstructionProvider

A instrução global para toda a árvore de agentes.

Enquanto a instrução informa a um agente específico o que fazer e como fazer, a instrução global se aplica a todos os agentes em toda a árvore de agentes.

O uso da instrução global é semelhante ao atributo de instrução, incluindo o tipo de dados, o suporte ao InstructionProvider e a capacidade de acessar variáveis e artefatos de estado.

  • Identificação e comportamento
    • Você usa a instrução global para definir a identidade e o comportamento / padrão para toda a árvore de agentes, em vez de como fazer uma tarefa específica para um agente específico.

generate_content_config

  generate_content_config: google.genai.types.GenerateContentConfig

Configuração de modelo adicional para o agente. Elas serão mescladas na solicitação para o modelo.

Há alguns atributos que não devem ser definidos neste campo porque são gerenciados pelo framework: - tools - system_instruction - response_schema

exemplos

  examples: list[Example] | BaseExampleProvider

Os exemplos de few-shot para o agente. Pesquisas mostram que fornecer exemplos de poucas fotos pode melhorar o desempenho do agente.

  • Exemplos estáticos
    • Você pode fornecer uma lista de exemplos estáticos. Um exemplo é definido da seguinte forma, em que input é o conteúdo de entrada e output é o conteúdo de saída esperado.
class Example(BaseModel):
  input: types.Content
  output: list[types.Content]
  • Lista de saída

    • A saída pode ser uma lista de Content.
    • Assim, você pode definir uma sequência de conteúdos como a saída esperada. Por exemplo, o modelo precisa primeiro fazer uma chamada de função e depois gerar algum texto.
  • BaseExampleProvider

    • Também é possível fornecer uma instância da classe BaseExampleProvider.
    • A classe BaseExampleProvider tem um método get_examples(query: str) e retorna uma lista de Example.
    • Com o BaseExampleProvider, é possível gerar dinamicamente os exemplos com base na consulta.

greeting_prompt

  greeting_prompt: str

Você pode definir um comando que será enviado ao modelo para gerar uma mensagem de saudação. O comando de saudação será usado quando você ligar para o agente com uma sessão vazia e uma entrada do usuário vazia.

planejamento

  planning: bool

Se planning for definido como verdadeiro, o modo de planejamento será ativado para o agente. No modo de planejamento, o agente primeiro gera um plano para resolver a consulta do usuário e depois executa o plano passo a passo.

code_executor

  code_executor: BaseCodeExecutor

O agente que você criou tem a capacidade de resolver problemas escrevendo e executando o código.

Há duas maneiras de ativar a execução do código:

  1. Alguns modelos têm a capacidade de executar o código diretamente. Por exemplo, o modelo Gemini 2.0 no modo ativo gera e executa o código automaticamente, sem a necessidade de uma ferramenta de execução de código separada.

  2. É possível definir o atributo code_executor para uma instância da classe BaseCodeExecutor para ativar a execução do código. No momento, temos uma classe VertexCodeExecutor e UnsafeLocalCodeExecutor (como os códigos gerados pelo LLM podem ser devastadores, use apenas UnsafeLocalCodeExecutor para prototipagem) que pode ser usada para executar códigos na Vertex AI. Mais executores de código serão adicionados no futuro.

input_schema

  input_schema: type[BaseModel]

O agente vai aplicar o esquema de entrada quando você especificar um modelo Pydantic como input_schema. O conteúdo da entrada precisa ser uma string JSON que esteja em conformidade com o esquema.

output_schema

  output_schema: type[BaseModel]

O agente vai aplicar o esquema de saída quando você especificar um modelo Pydantic como output_schema. O conteúdo da saída será sempre uma string JSON que esteja em conformidade com o esquema.

output_key

  output_key: str

O agente vai armazenar a saída na variável de estado com o nome especificado pelo atributo output_key.

include_contents

  include_contents: Literal['default', 'none']

O agente vai incluir o conteúdo do histórico de sessão (histórico de chat) por padrão. É possível definir o atributo include_contents como none para desativar esse comportamento. Nesse caso, o agente específico não vai ter acesso ao histórico de chat. Isso é útil quando o agente não precisa saber sobre o histórico de chat.

Ferramentas

A capacidade de usar ferramentas diferencia os agentes do modelo. Assim como a capacidade de usar ferramentas de maneira complexa e versátil é considerada uma característica definidora dos humanos.

No framework do agente, você fornece ferramentas ao agente pelo atributo tools. O atributo tools é uma lista de ferramentas, e cada ferramenta pode ser:

  • Uma função Python.
  • Uma classe que implementa a classe BaseTool.

Ferramenta de função do Python

É possível definir uma função Python como uma ferramenta.

  • Parâmetros

    • Sua função pode ter qualquer número de parâmetros.
    • Cada parâmetro pode ser de qualquer tipo, desde que seja serializável em JSON.
    • Não defina um valor padrão para os parâmetros, porque eles não são compatíveis com o modelo.
  • Tipo de retorno

    • O tipo de retorno precisa ser um dicionário.
    • Se você retornar algo que não seja uma matriz, o framework vai convertê-lo em uma matriz com uma única chave result.
    • Tente descrever o valor de retorno. Por exemplo, em vez de retornar um código de erro numérico, retorne um error_message: str com uma mensagem de erro legível por humanos. Esse valor de retorno é para o modelo ler e entender, em vez de um trecho de código para executar.
    • É uma boa prática ter uma chave status para indicar success, error, pending etc., para que o modelo entenda o status geral da operação.
  • Docstring

    • O docstring da função será usado como a descrição da ferramenta e enviado para o modelo. Quanto melhor for o docstring, melhor o modelo poderá usar a ferramenta.
  • Simplicidade

    • Embora você tenha muita liberdade para definir sua função, é recomendável mantê-la simples e fácil para que o modelo possa usá-la com mais precisão.
    • Ter menos parâmetros é melhor do que ter muitos.
    • Use tipos de dados simples sempre que possível, por exemplo, str, int, em vez de classes personalizadas.
    • O nome da função e os parâmetros são muito importantes. Se você tiver uma função chamada do_stuff(), mesmo que informe ao modelo que ela é usada para cancelar um voo, o modelo ainda poderá se recusar a usá-la.
    • Separe funções complexas em funções menores. Por exemplo, separe update_profile(profile: Profile) em update_name(name: str), update_age(age: int) e assim por diante.
  • Referência na instrução

    • É possível fazer referência à ferramenta na instrução usando o nome dela.
    • Se o nome e a docstring da função forem detalhados o suficiente, você poderá se concentrar apenas em quando usar a ferramenta na instrução.
    • Instrua o agente a lidar com diferentes valores de retorno. Por exemplo, se a ferramenta retornar uma mensagem de erro, o agente deve desistir, tentar novamente ou pedir mais informações?
    • As ferramentas podem ser usadas em sequência, e uma pode depender da saída de outra. Descreva a sequência na instrução.

Contexto da ferramenta

Na função da ferramenta, é possível adicionar um parâmetro especial tool_context: ToolContext para receber mais informações sobre o contexto em que a ferramenta é chamada.

A classe ToolContext está no módulo agents.types e tem os seguintes atributos:

  • function_call_event_id: str
    • O ID do evento em que a chamada de ferramenta é acionada.
  • function_call_id: str
    • O ID da chamada de função.
  • state: State
    • Um objeto semelhante a uma matriz para ler e atualizar as variáveis de estado.
  • actions: EventActions
    • Ações adicionais que a ferramenta pode realizar.

A classe EventActions está no módulo agents.events e tem os seguintes atributos para permitir que a ferramenta realize outras ações:

  • skip_summarization: bool
    • Se definido como "True", o framework vai pular a etapa de resumo do evento em que a ferramenta é chamada.
  • transfer_to_agent: str
    • Se definido, o framework será transferido para o agente com o nome especificado pelo atributo transfer_to_agent.
  • escalate: bool
    • Se definida como "True", o agente vai encaminhar a consulta para o agente pai. A transferência de um agente filho em um LoopFlow significa o fim do ciclo.

AsyncFunctionTool

AsyncFunctionTool é uma subclasse de FunctionTool. Ele foi projetado para ferramentas que levam muito tempo para serem concluídas.

Para criar uma AsyncFunctionTool, você precisa definir uma função Python regular e agrupá-la na classe AsyncFunctionTool. Por exemplo: AsyncFunctionTool(func=your_function)

O AsyncFunctionTool ainda vai chamar sua função Python, em que você pode iniciar a tarefa que pode levar muito tempo. Você pode retornar um resultado intermediário ao modelo para informar que a tarefa ainda não foi concluída. Adicionar informações como status: 'pending', progress: 20, estimated_completion_time: '...' etc. ajudará o modelo a fornecer uma resposta significativa ao usuário.

Mais tarde, quando a operação for concluída, você poderá chamar o agente com uma nova FunctionResponse para fornecer o resultado final. Nesse momento, o agente vai gerar uma resposta final para o usuário.

AgentTool

A AgentTool permite chamar outro agente para realizar uma tarefa. Isso equivale a criar uma função Python, chamar outro agente com os argumentos da função e usar a resposta desse agente como o valor de retorno da função.

Uma ferramenta de agente é diferente de um agente filho:

  • Quando o Agente A chama o Agente B como uma ferramenta, a resposta do Agente B é transmitida ao Agente A, que vai resumir a resposta e gerar uma resposta para o usuário. As próximas entradas do usuário vão continuar sendo respondidas pelo Agente A.
  • Quando o Agente A chama o Agente B como um agente filho, a responsabilidade de responder ao usuário é totalmente transferida para o Agente B. O agente A vai sair da tela. Nesse caso, as próximas entradas do usuário serão respondidas pelo Agente B.

Para usar um agente como ferramenta, use a classe AgentTool para envolvê-lo. Por exemplo: tools=[AgentTool(agent=agent_b)]

A AgentTool tem os seguintes atributos para personalizar o comportamento:

  • skip_summarization
    • Se definido como "True", o framework vai pular a chamada do LLM para resumir a resposta do agente da ferramenta.

Retornos de chamada

Tipos de callback

É possível personalizar ainda mais o comportamento do agente definindo callbacks. Temos suporte para dois tipos de callbacks:

  • Os BeforeCallbacks são chamados antes de o agente realizar uma ação. Você pode modificar a ação, pular a ação ou realizar outras ações.
  • Os AfterCallbacks são chamados depois que o agente realiza uma ação. É possível usar esse callback para modificar o resultado da ação ou realizar outras ações.

Ações compatíveis

Temos BeforeCallbacks e AfterCallbacks para as seguintes ações:

  • Ligar para um agente.
  • Chamando um LLM.
  • Chamando uma ferramenta.

Lista de callbacks

Como resultado, temos os seis callbacks a seguir, todos atributos da classe Agent:

before_agent_callback

def before_agent_callback(invocation_context: InvocationContext) -> Content | None
  • Uma invocação pode incluir várias chamadas de agente. Esse callback pode ser chamado várias vezes.
  • Se você retornar um Content desse callback, o agente vai pular a chamada de agente atual e usar o Content retornado como a resposta.

after_agent_callback

def after_agent_callback(invocation_context: InvocationContext) -> Content | None
  • Uma invocação pode incluir várias chamadas de agente. Esse callback pode ser chamado várias vezes.
  • Se você retornar um Content desse callback, o agente vai anexar o Content retornado após a própria resposta.

before_model_callback

def before_model_callback(
    invocation_context: InvocationContext,
    llm_request: LlmRequest) -> LlmResponse | None
  • Uma chamada de agente pode incluir várias chamadas de LLM. Esse callback pode ser chamado várias vezes.
  • Se você retornar uma LlmResponse desse callback, o agente vai usar a LlmResponse retornada como a resposta e pular a chamada do modelo.

before_model_callback

def after_model_callback(
    invocation_context: InvocationContext,
    llm_response: LlmResponse) -> LlmResponse | None
  • Uma chamada de agente pode incluir várias chamadas de LLM. Esse callback pode ser chamado várias vezes.
  • Se você retornar um LlmResponse desse callback, o agente vai usar o LlmResponse retornado como a resposta, em vez da resposta gerada pelo modelo.

before_tool_callback

def before_tool_callback(
    invocation_context: InvocationContext,
    tool: BaseTool,
    args: dict[str, Any],
    tool_context: ToolContext) -> dict | None
  • Uma chamada de modelo pode incluir várias chamadas de ferramenta. Esse callback pode ser chamado várias vezes.
  • Se você retornar um dict desse callback, o agente vai usar o dict retornado como a resposta e pular a chamada da ferramenta.

after_tool_callback

def after_tool_callback(
    invocation_context: InvocationContext,
    tool: BaseTool,
    args: dict[str, Any],
    tool_context: ToolContext,
    response: dict) -> dict | None
  • Uma chamada de modelo pode incluir várias chamadas de ferramenta. Esse callback pode ser chamado várias vezes.
  • Se você retornar um dict desse callback, o agente vai usar o dict retornado como a resposta, em vez da resposta gerada pela ferramenta.

Sessões

Não é necessário manipular diretamente o objeto de sessão ao criar um agente. O framework vai gerenciar o objeto de sessão para você. No entanto, ainda é útil entender o que é e como a sessão funciona.

Uma sessão no Agent Framework tem dois componentes principais:

  • Eventos: uma lista de eventos.
  • Estado: um objeto semelhante a uma matriz de variáveis de estado.

Eventos

Os eventos são apenas uma lista simples de objetos de evento. Pense nisso como um histórico de conversas entre um usuário e um agente ou entre diferentes agentes. Ele não registra apenas as palavras do usuário ou do modelo, mas também todas as ações que o agente realiza, incluindo chamar uma ferramenta, a resposta da ferramenta, chamar outro agente etc.

A lista de eventos é uma lista somente de adição. Só é possível adicionar eventos à lista, mas não é possível remover ou modificar nenhum evento. Quando um evento acontece, ele acontece, não há como mudar isso. O sistema foi projetado dessa forma para ser simples, e podemos sempre voltar a um momento específico para conferir o snapshot exato do sistema.

Estado

O estado é um objeto semelhante a um dicionário que contém todas as variáveis de estado. Você pode acessar o recurso nos seguintes locais:

  • Na instrução, é possível usar a sintaxe {var} para inserir o valor da variável de estado chamada var.
  • Nos callbacks, é possível acessar a variável de estado usando invocation_context.state['key']. Também é possível atualizar a variável de estado usando invocation_context.state['key'] = value.
  • Nas ferramentas, é possível acessar a variável de estado usando tool_context.state['key']. Também é possível atualizar a variável de estado usando tool_context.state['key'] = value.

O estado está associado a uma sessão específica. Portanto, é o lugar ideal para armazenar informações úteis no contexto desta sessão.

O estado pode ser acessado por todos os agentes na árvore de agentes, tornando-o um local ideal para a comunicação entre agentes. Um agente pode realizar uma ação e armazenar o resultado no estado. Outro agente pode ler o resultado do estado e continuar o trabalho.

Artefatos

Quando o modelo ou a ferramenta cria um arquivo, seja uma imagem, um vídeo, um documento ou qualquer outro formato, é possível armazená-lo como um artefato. Um artefato é um arquivo associado a uma sessão específica e pode ser acessado pelos agentes ou pelo seu próprio código.

Casos de uso

  • Quando o agente trabalha com o usuário para criar / modificar um arquivo. Por exemplo, um agente que ajuda o usuário a gerar e editar uma imagem.
  • Quando você quer que o agente responda a perguntas sobre um arquivo ou edite o arquivo com base nas instruções do usuário.

Benefícios de desempenho

Outra maneira de lidar com arquivos grandes é armazená-los como bytes no histórico de chat. No entanto, essa abordagem tem algumas desvantagens:

  • Isso deixa o histórico de sessões lento.
  • É difícil recuperar o arquivo do histórico de chat.
  • Os bytes serão enviados ao modelo para todas as solicitações, mesmo que a conversa não tenha nada a ver com esses arquivos.

Como acessar artefatos

Há algumas maneiras de acessar os artefatos:

  • Na instrução, é possível usar a sintaxe {artifact.var} para inserir o conteúdo de texto do artefato chamado var. Os artefatos binários ainda não são aceitos.
  • Nos callbacks, é possível acessar o artefato usando invocation_context.get_artifact('key'). É possível atualizar o artefato usando invocation_context.set_artifact('key', value).
  • Nas ferramentas, é possível acessar o artefato usando tool_context.get_artifact('key'). É possível atualizar o artefato usando tool_context.set_artifact('key', value).

Sistemas multiagente

Um único agente e ferramentas de lista podem ajudar muito na criação de um sistema complexo. No entanto, às vezes, separar a lógica em vários agentes pode melhorar o desempenho e a manutenção do sistema como um todo.

Estes são os momentos em que você pode considerar o uso de vários agentes:

  • Quando a instrução do agente está ficando muito longa, com várias tarefas e etapas para cada uma delas.
  • Quando você tem um fluxo de trabalho mais determinístico para executar. Por exemplo, um agente de pesquisa sempre gera um plano, executa o plano e resume as descobertas.

Árvore de agentes hierárquica

  children: list[BaseAgent]

Você cria um sistema multiagente criando uma árvore de agentes hierárquica. O agente raiz é o ponto de entrada do sistema e pode chamar outros agentes com base na configuração.

Um agente pode ter vários agentes filhos. Os agentes filhos também podem ter agentes filhos. A árvore de agentes pode ser arbitrariamente profunda, mas, por motivos de performance, recomendamos uma árvore mais rasa.

Para formar a árvore de agentes, coloque outros agentes como filhos de um agente pai.

Fluxos

  flow: str | BaseFlow | FlowCallable

Quando um agente recebe uma consulta do usuário, ele pode processá-la ele mesmo ou encaminhar para outro agente. Isso é definido pelo atributo flow.

Há alguns fluxos predefinidos, e você também pode definir seus próprios fluxos.

  • sequential: o agente vai chamar os agentes filhos um por um em sequência.
  • loop: o agente chama os agentes filhos em um loop. Até que um dos agentes filhos defina tool_context.actions.escalate como verdadeiro.
  • single: este é um fluxo baseado em LLM. O agente vai chamar o LLM para responder à consulta do usuário e chamar as ferramentas quando necessário.
  • auto: este é um fluxo baseado em LLM. O agente vai chamar o LLM para responder à consulta do usuário e chamar as ferramentas quando necessário. Ele também pode transferir a consulta para os filhos, irmãos ou pai.
  • Fluxos personalizados: é possível definir seus próprios fluxos implementando a classe BaseFlow ou simplesmente definindo uma função Python seguindo a interface.