← Voltar a AI Engineer — DEUS.ai

🔴 A — AI Agents

AI Engineer — DEUS.ai

Apresentação

🤖 AI Agents — Muito importante para esta vaga


Conceitos

Planeamento

Dividir tarefa em sub-tarefas. Planeamento antes de executar.

Uso de ferramentas

Agente chama ferramentas: search, calculator, API, DB.

Memória

Curto prazo (conversa), longo prazo (embeddings, vector store).

Ciclos de raciocínio

Observar → Pensar → Agir. ReAct pattern.


Como usar Tools — implementação prática

1. Definir a tool (schema)

O LLM escolhe tools pela descrição e parâmetros. Usa JSON Schema ou Pydantic.

# Exemplo: OpenAI function calling format
tools = [{
    "type": "function",
    "function": {
        "name": "search_documents",
        "description": "Pesquisa a base de conhecimento por documentos relevantes. Usa quando o utilizador pergunta sobre documentação da empresa.",
        "parameters": {
            "type": "object",
            "properties": {
                "query": {"type": "string", "description": "Query de pesquisa"}
            },
            "required": ["query"]
        }
    }
}]

Regra: Descrição clara = LLM escolhe melhor. "Use when..." ajuda o modelo a decidir.

2. Fluxo de execução (loop)

1. Mensagem do utilizador → LLM (com tools no prompt)
2. LLM responde: texto OU tool_calls
3. Se tool_calls: parse args → executar função → resultado
4. Adicionar tool result às mensagens: role=assistant (tool_call), role=user (tool_result)
5. Voltar ao passo 1 (LLM vê o resultado e continua)
6. Se LLM responde texto final → devolver ao utilizador

3. Código do loop (pseudocódigo)

messages = [{"role": "user", "content": user_input}]
while True:
    response = llm.chat(messages, tools=tools)
    if response.content:
        return response.content  # Resposta final
    for tool_call in response.tool_calls:
        result = execute_tool(tool_call.name, tool_call.args)
        messages.append({"role": "assistant", "content": None, "tool_calls": [tool_call]})
        messages.append({"role": "tool", "content": str(result), "tool_call_id": tool_call.id})

4. LangChain / LangGraph — como definir tools

from langchain.tools import tool

@tool
def search_documents(query: str) -> str:
    """Pesquisa a base de conhecimento. Usa quando o utilizador pergunta sobre documentação."""
    return vector_db.similarity_search(query)

# O decorator @tool extrai nome, descrição e schema automaticamente
agent = create_react_agent(llm, [search_documents, calculator_tool], prompt)

5. Erros comuns

  • Tool não chamada: Descrição vaga — ser mais explícito "Use when user asks X"
  • Args errados: Schema muito aberto — definir tipos e required
  • Loop infinito: Max iterations, timeout, detetar tool repetida com mesmos args

Como criar Multi-Agent Conversation

Arquitetura: Router + Specialized Agents

User: "Pesquisa docs e faz um resumo"
    ↓
Router Agent: analisa intent → decide "search" + "summarize"
    ↓
Search Agent: chama search_documents → devolve chunks
    ↓
Summarizer Agent: recebe chunks → gera resumo
    ↓
Resposta ao User

1. Router Agent — como implementar

O router é um LLM que recebe a mensagem e decide para onde enviar.

# Router prompt
task = "Classifica a intenção do utilizador: pesquisar | calcular | resumir | geral"
router_response = router_llm.invoke([{"role": "user", "content": f"{task}\nUser: {user_msg}"}])
intent = parse_intent(router_response)  # ex: "search"
# Encaminhar para o agente correto
agent = agents[intent]
result = agent.invoke(user_msg)

2. Passar mensagens entre agentes

Opção A — State partilhado: Todos os agentes leem/escrevem num dict de estado.

state = {"messages": [], "search_results": None, "final_answer": None}
# Agent 1 escreve em state["search_results"]
# Agent 2 lê state["search_results"] e escreve state["final_answer"]

Opção B — Encadeamento: Output do Agent 1 = input do Agent 2.

search_result = search_agent.invoke(user_msg)
final = summarizer_agent.invoke(f"Context: {search_result}\nResumir para o utilizador.")

3. LangGraph — multi-agent com state machine

from langgraph.graph import StateGraph, END

# Definir state
def add_messages(state, new_msg):
    return {"messages": state["messages"] + [new_msg]}

# Nós = funções que processam
graph = StateGraph(AgentState)
graph.add_node("router", router_node)
graph.add_node("search_agent", search_node)
graph.add_node("summarizer", summarizer_node)

# Edges: quem chama quem
graph.add_conditional_edges("router", lambda s: s["intent"], {"search": "search_agent", "summarize": "summarizer"})
graph.add_edge("search_agent", "summarizer")
graph.add_edge("summarizer", END)

app = graph.compile()
result = app.invoke({"messages": [{"role": "user", "content": user_input}]})

4. Conversa entre agentes (debate, consenso)

Para agentes que "falam" entre si (ex: debate):

Agent A: "Acho que a resposta é X porque..."
Agent B: "Discordo, Y faz mais sentido porque..."
Agent A: "Concordo com Y, mas adiciono Z"
→ Consolidator: combina e devolve resposta final

Implementação: Cada agente recebe o histórico da conversa (mensagens dos outros agentes). O consolidator vê todo o debate e sintetiza.

5. Shared memory em multi-agent

  • Conversation buffer: Últimas N mensagens em memória partilhada
  • Vector store: Cada agente pode escrever/ler embeddings (ex: factos descobertos)
  • Redis/DB: Estado persistente entre turns (ex: dados da sessão)

Multi-Agent Architecture (resumo)

User → Router Agent → Specialized Agents

Exemplos: search agent, coding agent, data agent, reasoning agent.

Coordenação: LangGraph (state graph), task planner (decompor tarefa), shared memory.


Chatbot com Tools — fluxo

User → LLM (com tools) → Tool selector (LLM decide) → API execution → Result → LLM (vê resultado) → Response

Tools: consulta à base de dados, pesquisa na web, calculator, APIs internas.


Frameworks

  • LangGraph — state machines, nós=agentes, edges=transições. add_node, add_edge, add_conditional_edges
  • LangChaincreate_react_agent, tools como list, prompt com ReAct template
  • AutoGenConversableAgent, GroupChat, GroupChatManager para multi-agent
  • CrewAIAgent (role, goal, backstory), Task, Crew (orquestra)
  • Swarm — multi-agent (OpenAI)
  • OpenAI Assistants — API managed, tools via API

Padrões

  • ReAct — Raciocínio + Ação, intercalar pensamento e ações
  • Planear-Executar — planeamento primeiro, depois execução
  • Reflexão — criticar e melhorar output

Human-in-the-loop

Agentes que param e pedem confirmação antes de ações críticas (ex: enviar email, fazer compra). Evita erros custosos. Implementar: detectar "action" de alto risco → pedir confirmação ao user → executar só se aprovado.


Tool design — boas práticas

  • Descrições claras: O LLM escolhe tools pela descrição. "search_documents(query: str) - Pesquisa a base de conhecimento por documentos relevantes. Usa quando o utilizador pergunta sobre documentação da empresa."
  • Schemas estritos: Parâmetros bem definidos (Pydantic, JSON Schema). Reduz erros de parsing.
  • Tool limitado: Não dar acesso a tudo. Princípio do menor privilégio.
  • Um tool, uma responsabilidade: Evitar tools que fazem demasiado.

Observability em agentes

  • Trace cada step: Pensamento, Ação, Observação. Langfuse, LangSmith.
  • Métricas: tokens por step, latência por tool call, taxa de sucesso.
  • Debug: Logs de qual tool foi chamado, com que argumentos, que resultado.

Zona de prática

Sem perguntas. Clica em Editar para adicionar.