Construa um Agente Autônomo com Memória Híbrida e Arquitetura Modular com Despacho de Ferramentas Usando OpenAI
Neste tutorial, começamos explorando a arquitetura por trás de um agente autônomo com memória híbrida. Este sistema combina busca vetorial semântica, recuperação baseada em palavras-chave e um loop modular de despacho de ferramentas para criar um agente capaz de raciocinar, lembrar e agir de forma autônoma. Percorremos cada camada do design, desde interfaces abstratas que […] O posi
Neste tutorial, começamos explorando a arquitetura por trás de um agente autônomo com memória híbrida. Este sistema combina busca vetorial semântica, recuperação baseada em palavras-chave e um loop modular de despacho de ferramentas para criar um agente capaz de raciocinar, lembrar e agir de forma autônoma. Percorremos cada camada do design, desde interfaces abstratas que impõem uma clara separação de interesses, até um agente ativo que gerencia sua própria memória de longo prazo. Copiar Código Copiado Use um navegador diferente !pip install openai numpy rank_bm25 --quiet import os, json, math, re, time, getpass from abc import ABC, abstractmethod from dataclasses import dataclass, field from typing import Any, Callable, Dict, List, Optional, Tuple import numpy as np from rank_bm25 import BM25Okapi from openai import OpenAI OPENAI_API_KEY = os.getenv("OPENAI_API_KEY") or getpass.getpass(" Digite sua chave de API OpenAI (oculta): ") client = OpenAI(api_key=OPENAI_API_KEY) EMBED_MODEL = "text-embedding-3-small" CHAT_MODEL = "gpt-4o-mini" print(" Cliente OpenAI pronto.") Começamos instalando todas as dependências necessárias e configurando nosso ambiente Python com os imports necessários. Coletamos com segurança a chave de API da OpenAI usando getpass, garantindo que a chave nunca seja ecoada no terminal ou na saída do notebook. Também definimos as duas constantes globais, o modelo de embedding e o modelo de chat, das quais todos os snippets subsequentes dependem. Copiar Código Copiado Use um navegador diferente class MemoryBackend(ABC): @abstractmethod def store(self, text: str, metadata: Dict[str, Any]) -> str: ... @abstractmethod def search(self, query: str, top_k: int = 5) -> List[Dict[str, Any]]: ... @abstractmethod def list_all(self) -> List[Dict[str, Any]]: ... class LLMProvider(ABC): @abstractmethod def complete(self, messages: List[Dict], tools: Optional[List] = None) -> Dict: ... class Tool(ABC): name: str description: str @abstractmethod def run(self, **kwargs) -> str: ... def schema(self) -> Dict: return { "type": "function", "function": { "name": self.name, "description": self.description, "parameters": {"type": "object", "properties": {}, "required": []}, }, } @dataclass class MemoryChunk: id: str text: str metadata: Dict[str, Any] embedding: Optional[np.ndarray] = field(default=None, repr=False) def _embed(texts: List[str]) -> List[np.ndarray]: resp = client.embeddings.create(model=EMBED_MODEL, input=texts) vecs = [np.array(d.embedding, dtype=np.float32) for d in
