Como construir seu primeiro agente de IA com memória em Python

2026-04-20 · 7 min de leitura · Por equipe Brainiall

Um AI agent com memória é uma aplicação que: (1) conversa com LLM, (2) executa ferramentas quando necessário, e (3) lembra conversas anteriores. Aqui construímos um em ~100 linhas de Python usando a API do Brainiall + PostgreSQL para memória vetorial.

Arquitetura

  1. Chat loop: usuário envia mensagem → LLM responde
  2. Memória de curto prazo: últimas 20 mensagens no contexto
  3. Memória de longo prazo: embeddings das mensagens guardados em pgvector, retrieved por similaridade
  4. Tools: calcular, buscar web, ler arquivos, agendar — function calling

Setup

pip install openai psycopg2-binary numpy
export BRAINIALL_KEY=brnl_xxx
# PostgreSQL com pgvector extension

Código completo

from openai import OpenAI
import psycopg2, os, json

client = OpenAI(
    api_key=os.environ["BRAINIALL_KEY"],
    base_url="https://chat.brainiall.com/api/v1",
)

conn = psycopg2.connect(os.environ["DATABASE_URL"])

# Schema (rodar uma vez):
# CREATE EXTENSION vector;
# CREATE TABLE agent_memory (
#   id SERIAL PRIMARY KEY, role TEXT, content TEXT,
#   embedding VECTOR(1536), created_at TIMESTAMP DEFAULT NOW()
# );

def embed(text):
    r = client.embeddings.create(model="text-embedding-3-small", input=text)
    return r.data[0].embedding

def save_memory(role, content):
    emb = embed(content)
    with conn.cursor() as cur:
        cur.execute(
            "INSERT INTO agent_memory (role, content, embedding) VALUES (%s,%s,%s)",
            (role, content, str(emb))
        )
    conn.commit()

def recall_memory(query, top_k=5):
    emb = embed(query)
    with conn.cursor() as cur:
        cur.execute(
            "SELECT role, content FROM agent_memory ORDER BY embedding <-> %s::vector LIMIT %s",
            (str(emb), top_k)
        )
        return cur.fetchall()

def agent_reply(user_msg):
    # 1. Retrieve relevant memory
    memories = recall_memory(user_msg)
    memory_ctx = "\n".join([f"[{r}]: {c}" for r, c in memories])

    # 2. Build messages
    messages = [
        {"role": "system", "content": f"Você é um assistente útil. Memória relevante:\n{memory_ctx}"}
    ]
    messages.append({"role": "user", "content": user_msg})

    # 3. Call LLM
    r = client.chat.completions.create(
        model="anthropic/claude-sonnet-4-6",
        messages=messages,
    )
    reply = r.choices[0].message.content

    # 4. Save exchange
    save_memory("user", user_msg)
    save_memory("assistant", reply)
    return reply

# Chat loop
while True:
    msg = input("Você: ")
    if msg.lower() in ("sair", "exit"): break
    print("Agent:", agent_reply(msg))

Evoluções

Performance

Nosso benchmark: agent com 10k mensagens em memória responde em 2.3s médio (embed + retrieval + LLM). Com cache warm, chega a 1.4s. Custo por interação: ~R$0.05 (Claude Sonnet 4.6 + embedding).

Começar com API key grátis

Obter API key