Ubuntu TechHive
getting-started-with-ai-agents.md
Getting Started With AI Agents
article.detalhe

Getting Started With AI Agents

reading.progresso 8 min de leitura

Descrição de Como Começar com Agentes de IA

Introdução

O que diabos é um Agente?

Conceitos relacionados a Agentes e LLMs

ReAct (Razão + Ação): [Sinergizando Raciocínio e Ação em Modelos de Linguagem](https: //arxiv.org/pdf/2210.03629)( Github)

Pense sobre o Prompt e faça algo a respeito (ou não?).

Self-Refine: [Refinamento Iterativo com Auto-Feedback](https: //arxiv.org/pdf/2303.17651)( Github)

Ao receber um prompt, execute uma ação iterativamente, inspecione seus resultados e tome ações adicionais conforme necessário para melhorar os resultados até que nenhuma melhoria adicional seja necessária ou alguma outra restrição seja atingida para forçar uma parada, então retorne o resultado final.

Engenharia de Fluxo: [Geração de Código com AlphaCodium: Da Engenharia de Prompt à Engenharia de Fluxo](https: //arxiv.org/pdf/2401.08500)( Github)

Um fluxo iterativo baseado em testes, multi-estágio e orientado a código, que melhora o desempenho de LLMs em problemas de código.

Estruturas de Agentes

CrewAI: [Agentes de IA para casos de uso reais](https: //www.crewai.com/)

A maioria das estruturas de agentes de IA são difíceis de usar. Oferecemos poder com simplicidade. Automatize seus fluxos de trabalho mais importantes rapidamente.

LangChain: [Agentes](https: //www.langchain.com/agents)

Construa a arquitetura cognitiva certa para sua aplicação. Identifique e implemente as melhores estratégias e arquiteturas de prompt para que seus LLMs funcionem como pretendido.

Vamos construir um Agente

O que é necessário para construir um Agente Alimentado por LLM?

  • Contexto: Informações para o Agente (Função, Objetivo, Dados Iniciais etc)

  • Prompt: Mensagem em linguagem natural para o Agente (Texto, Áudio etc)

  • Python: Codifique a magia usando Instructor

  • Ler: Leia mais para aprender mais sobre Agentes e codifique

Recuperação de Informação vs Geração de Dados vs Chamada de Função com a biblioteca Python Instructor

Até agora, temos usado o Instructor tanto para Recuperação de Informação quanto para Geração de Dados como Dados Estruturados. Agora vamos aprofundar nas Capacidades de Chamada de Função mais avançadas da biblioteca Python Instructor. Para o bloco de rascunhos, usaremos Notebooks Marimo.

Então, onde está o A?

Um agente é qualquer coisa que pode ser vista como percebendo seu ambiente através de sensores e agindo sobre esse ambiente através de atuadores -- Stuart Russel e Peter Norvig.

Empréstimo de Inteligência Artificial: Uma Abordagem Moderna Quarta Edição

Percepções

class SystemMessage(BaseModel):
    role: Literal ["system"] = "system"
    content: str

class UserMessage(BaseModel):
    role: Literal ["user"] = "user"
    content: str

class AssistantMessage(BaseModel):
    role: Literal ["assistant"] = "assistant"
    content: str

percept_seq: List [Union [SystemMessage, UserMessage, AssistantMessage]] = []

Tabela de ações

class DefaultFunc(OpenAISchema):
    response: str
    def run(self):
        msg = f"DefaultFunc->run: {self.response}"
        return msg

class UserFunc(OpenAISchema):
    name: str
    age: int

def run(self):
        msg = f"UserFunc->run: User's name is {self.name} and age is {self.age}"
        return msg

toolbox = [DefaultFunc, UserFunc]

Ações e Atuador

def actuate(self, tool_call: ChatCompletionMessageToolCall):
        Func = next(iter([func for func in toolbox if func.__name__ == tool_call.function.name]))

if not Func:
            available_function_names = [func.__name__ for func in toolbox]
            err_msg = f"Error: Function {tool_call.function.name} not found. Available functions: {available_function_names}"
            console.error(err_msg)
            return err_msg

try:
            console.log(f"Tool Call -> {tool_call.function.name} ->with {tool_call.function.arguments} of type {type(tool_call.function.arguments)}", style="bold blue")
            args = from_json(tool_call.function.arguments)
            console.log(f"Args -> {args} of type {type(args)}", style="bold blue")
            func = Func.model_validate(args)
            console.log(f"Func -> {repr(func)}", style="bold blue")
            output = func.run()
            return output
        except Exception as e:
            return f"Error: {e}"

Uma tentativa de Design de Agente

Este diagrama ajuda a visualizar o fluxo de ações e pensamentos através dos agentes, garantindo uma abordagem estruturada e iterativa para alcançar o resultado final.

graph TD
A [Início: Pensar sobre o prompt] --> B [Derivar entradas]
B --> T1{Caixa de Ferramentas}
T1 -->|Ferramenta 1| T2 [Pensar sobre os resultados da Ferramenta 1]
T1 -->|Ferramenta 2| T3 [Pensar sobre os resultados da Ferramenta 2]
T1 -->|Ferramenta 3| T4 [Pensar sobre os resultados da Ferramenta 3]
T1 -->|Ferramenta 4| T5 [Pensar sobre os resultados da Ferramenta 4]
T1 -->|Ferramenta 5| T6 [Pensar sobre os resultados da Ferramenta 5]

T2 --> T7{Caixa de Ferramentas}
T3 --> T7
T4 --> T7
T5 --> T7
T6 --> T7

T7 -->|Ferramenta 1| T8 [Pensar sobre os resultados da Ferramenta 1]
T7 -->|Ferramenta 2| T9 [Pensar sobre os resultados da Ferramenta 2]
T7 -->|Ferramenta 3| T10 [Pensar sobre os resultados da Ferramenta 3]
T7 -->|Ferramenta 4| T11 [Pensar sobre os resultados da Ferramenta 4]
T7 -->|Ferramenta 5| T12 [Pensar sobre os resultados da Ferramenta 5]

T8 --> T13{Caixa de Ferramentas}
T9 --> T13
T10 --> T13
T11 --> T13
T12 --> T13

T13 -->|Ferramenta 1| T14 [Resultado final da Ferramenta 1]
T13 -->|Ferramenta 2| T15 [Resultado final da Ferramenta 2]
T13 -->|Ferramenta 3| T16 [Resultado final da Ferramenta 3]
T13 -->|Ferramenta 4| T17 [Resultado final da Ferramenta 4]
T13 -->|Ferramenta 5| T18 [Resultado final da Ferramenta 5]

T14 --> F [Resultado Final]
T15 --> F
T16 --> F
T17 --> F
T18 --> F

style A fill:#f9f,stroke:#333,stroke-width:2px

style B fill:#bbf,stroke:#333,stroke-width:2px

style T1 fill:#bfb,stroke:#333,stroke-width:2px

style T2 fill:#ff9,stroke:#333,stroke-width:2px

style T3 fill:#ff9,stroke:#333,stroke-width:2px

style T4 fill:#ff9,stroke:#333,stroke-width:2px

style T5 fill:#ff9,stroke:#333,stroke-width:2px

style T6 fill:#ff9,stroke:#333,stroke-width:2px

style T7 fill:#bfb,stroke:#333,stroke-width:2px

style T8 fill:#ff9,stroke:#333,stroke-width:2px

style T9 fill:#ff9,stroke:#333,stroke-width:2px

style T10 fill:#ff9,stroke:#333,stroke-width:2px

style T11 fill:#ff9,stroke:#333,stroke-width:2px

style T12 fill:#ff9,stroke:#333,stroke-width:2px

style T13 fill:#bfb,stroke:#333,stroke-width:2px

style T14 fill:#f99,stroke:#333,stroke-width:2px

style T15 fill:#f99,stroke:#333,stroke-width:2px


style T16 fill:#f99,stroke:#333,stroke-width:2px

style T17 fill:#f99,stroke:#333,stroke-width:2px

style T18 fill:#f99,stroke:#333,stroke-width:2px

style F fill:#9f9,stroke:#333,stroke-width:2px

Explicação- Início: Pensar sobre o prompt: O processo começa com o agente considerando o prompt fornecido.

  • Derivar entradas: O agente deriva as entradas necessárias para decidir qual(is) ferramenta(s) usar da caixa de ferramentas.

  • Caixa de ferramentas: O agente tem acesso a uma caixa de ferramentas contendo 5 ferramentas diferentes. Com base nas entradas derivadas, o agente seleciona uma ferramenta.

  • Pensar sobre os resultados da Ferramenta: Após usar a primeira ferramenta, o agente pensa sobre os resultados que obteve.

  • Invocação sequencial de ferramentas: O agente pode decidir invocar uma segunda e até uma terceira ferramenta com base nos resultados intermediários.

  • Resultado final: Eventualmente, o agente produz o resultado final após processar as ferramentas necessárias e as etapas de pensamento intermediárias.

#+begin_src python

from instructor import OpenAISchema

from getting_started_with_ai_agents.agents.club_bouncer import (
ClubBouncer,
Person,
Guest,
)
from getting_started_with_ai_agents.llm import gen_client, SystemMessage, UserMessage

client = gen_client()

class ClubSecurity(OpenAISchema):
""" Agente de segurança para o Club UbuntuTechHive. Ajuda o segurança a gerenciar a fila e verificar a lista de convidados seguindo as regras do clube. se a pessoa tiver pelo menos 21 anos e tiver pelo menos $20 em dinheiro, ela pode entrar no clube. se a pessoa estiver na lista de convidados, ela pode entrar no clube. se a pessoa for VIP, ela deve ter pelo menos $1000 em dinheiro para obter serviço de mesa. """

name: str # nome da pessoa
age: int # idade da pessoa
cash: float # quantidade de dinheiro que a pessoa tem
is_on_guest_list: bool # se a pessoa está na lista de convidados

def run(self): person = Person( name=self.name, age=self.age, cash=self.cash, is_on_guest_list=self.is_on_guest_list, ) return person

class ClubHost(OpenAISchema): """ Anfitriã do Club UbuntuTechHive. Cobra a taxa de entrada e atribui ingressos aos convidados. Verifica a lista de convidados e os atribui à fila VIP. Gerencia os VIPs e o serviço de mesa. Aceita VIPs com pelo menos $1000 em dinheiro e solicitações de serviço de mesa. Aceita pagamento pelo serviço de mesa e atribui mesas aos VIPs. Se a pessoa tiver dinheiro para um ingresso, deixe-a comprar o ingresso e marque-a como tendo um ingresso usando uma pulseira. Se o convidado estiver na lista de convidados, marque-o como presente na cópia da lista de convidados do clube e deixe-o entrar. Se o convidado tiver $1000 em dinheiro, ele é um VIP, marque-o como VIP e, em seguida, leve-o a uma mesa livre. """

name: str # name of the person age: int # age of the person cash: float # amount of cash the person has has_ticket: bool = False # whether the person has a ticket is_on_guest_list: bool = False # whether the person is on the guest list is_vip: bool = False # whether the person is a VIP

def run(self): guest = Guest(
name=self.name,
age=self.age,
cash=self.cash,
has_ticket=self.has_ticket,
is_on_guest_list=self.is_on_guest_list,
is_vip=self.is_vip,
)
return guest

bouncer = ClubBouncer(
context= [
SystemMessage(
content=""" Bem-vindo ao Club UbuntuTechHive! Eu sou o Segurança do Clube. Estarei gerenciando a fila esta noite para o clube. Estarei decidindo quem pode entrar no clube. Minhas decisões são baseadas nos seguintes critérios:

  • A pessoa deve ter pelo menos 21 anos de idade.

  • A pessoa deve ter pelo menos $20 em dinheiro.

  • A pessoa deve ter um ingresso ou estar na lista de convidados.

  • Haverá uma taxa de entrada de $20 para aqueles sem ingresso ou que não estão na lista de convidados.

  • VIPs devem ter pelo menos $1000 em dinheiro para obter serviço de mesa.

  • O serviço de mesa está disponível para VIPs apenas se houver um número limitado de mesas disponíveis.

  • Quando não houver mesas disponíveis, os VIPs devem esperar na fila VIP para que uma mesa se torne disponível. """ ) ], capacity=100, table_count=10, client=client, toolbox= [ClubSecurity, ClubHost],

)

ifname == "main": bouncer.manage_line( UserMessage( content=""" A pessoa é John Doe e tem 25 anos com $50 em dinheiro. Eles estão na lista de convidados. """ ) )

bouncer.manage_line( UserMessage( content=""" Lambert tem 21 anos com $20 em dinheiro. Eles querem comprar um ingresso. """ ) )

#+end_src

Conclusão

Este campo está a evoluir rapidamente e há poucos especialistas. Não tenha medo de ler, aprender e programar para ganhar compreensão. Depois, decida por si mesmo se adota uma biblioteca que se adapte às suas necessidades ou cria a sua própria!

Referências