Pular para conteúdo

Read Pipeline

Quando você chama memory.retrieve(), o SDK busca tudo que sabe sobre um agente e retorna os fatos mais relevantes pra sua query - ranqueados, pontuados e formatados numa string que você pode colar direto num prompt de LLM.

Você não precisa entender os internals pra usar. Basta chamar retrieve() e usar result.context. Esta página explica o que acontece por baixo dos panos, pra quando você quiser ajustar o comportamento ou debugar resultados.

flowchart LR
    A["Query"] --> B["Plan"]
    B --> C["Retrieve\n(3 signals)"]
    C --> D["Enhance"]
    D --> E["Rerank"]
    E --> F["RetrieveResult"]

Visão Geral

Toda chamada a memory.retrieve(agent_id, query) executa cinco estágios:

  1. Plan - Descobre o que buscar. Detecta saudações, padrões de agregação e queries amplas. Entity resolution roda deterministicamente em paralelo.
  2. Retrieve - Busca fatos usando três métodos em paralelo: similaridade de significado, match de palavras-chave e travessia do grafo de relacionamentos.
  3. Enhance - Expande o contexto seguindo relacionamentos entre entidades pra encontrar fatos relacionados que não foram diretamente matcheados.
  4. Rerank - Um LLM reavalia os top resultados e reordena pela relevância real pra sua query.
  5. Format - Comprime os fatos ranqueados numa string com orçamento de tokens, organizada por tiers de relevância.

Estágio 1: Planner Determinístico

Em português claro: Antes de buscar, o pipeline analisa sua query pra decidir que tipo de busca rodar. Detecta saudações (skip), queries de agregação ("quem são meus amigos?"), requests amplas ("me conta tudo") e identifica quais entidades são mencionadas. Tudo determinístico — mesma query sempre produz o mesmo plano, zero chamadas LLM.

O planner produz um RetrievalPlan usando regex pattern matching e lookups no schema. Nenhum LLM é envolvido.

Por que sem LLM no planner?

Antes da v0.13.0, o planner chamava um LLM pra reformulação de query e extração de entidades. Isso introduzia não-determinismo: a mesma query contra a mesma memória podia retornar fatos diferentes entre runs, porque APIs cloud de LLM não são determinísticas mesmo com temperature=0 (comportamento documentado — batching, fp16 rounding, roteamento de GPU introduzem variação). A v0.13.0 substitui o planner LLM por uma implementação totalmente determinística. A query vai direto pra busca semântica sem alteração, e extração de entidades é feita por um resolver determinístico dedicado.

O Que o Planner Decide

Campo Descrição Exemplo
strategy Estratégia de retrieval "multi_signal" (padrão) ou "skip" (para saudações)
similarity_query Query para busca semântica (sempre a original) "onde eu moro?" (passada sem alteração)
pattern_queries Padrões SQL LIKE para agregação ["person:%"] (de "quem são meus amigos?")
broad_query Se deve expandir o escopo do graph true para "me conte tudo sobre..."
reason Explicação da estratégia "deterministic", "aggregation", "broad", "greeting"

Entity Resolution

Quando você pergunta "Onde o Carlos mora?", o pipeline precisa descobrir que "Carlos" significa a entidade person:carlos no banco. Ele usa dois métodos determinísticos:

  1. Resolução determinística (primária) — Faz match de palavras da query contra aliases de entidades conhecidas (MemoryEntityAlias), display names (MemoryEntity.display_name) e slugs de entity_keys. Rápido (< 10ms), confiável, custo zero de LLM. Por exemplo, "Onde o Carlos mora?" resolve deterministicamente para person:carlos via slug match.

  2. Query expansion (priming de aliases)expand_query() resolve aliases e busca vizinhos 1-hop no KG, adicionando entidades relacionadas.

Ambas as fontes são unificadas antes do graph gate. Se qualquer fonte identificar uma entidade, o graph traversal roda.

O trace step "retrieval" inclui um breakdown entities_sources mostrando quais entidades vieram de cada fonte (deterministic, expansion).

Detecção de Agregação

Para queries como "quem são meus amigos?" ou "meus projetos", o planner faz match de keywords contra prefixos do schema e gera padrões SQL LIKE (ex: person:%). Isso só dispara quando o prefixo realmente existe no schema do usuário.

Estratégia Skip

Para saudações e mensagens casuais ("oi", "bom dia", "e aí"), o planner retorna strategy: "skip" via regex matching, fazendo short-circuit no pipeline. Sem queries no banco, sem chamadas LLM, resposta instantânea.

Resolução de Anáfora (Responsabilidade do Caller)

Se sua query contém pronomes ("Onde ela mora?"), o Arandu SDK não resolve. Resolução de pronomes depende do contexto de conversa (memória de curto prazo), que é domínio do caller. Resolva pronomes antes de chamar retrieve():

# O caller (seu agente) resolve "ela" → "Ana" usando contexto de conversa
resolved_query = "Onde a Ana mora?"  # não "Onde ela mora?"
result = await memory.retrieve(agent_id="user_123", query=resolved_query)

Paralelo com neurociência

O planner espelha pistas de recuperação na psicologia cognitiva. Quando você tenta lembrar algo, seu cérebro não faz uma busca exaustiva — ele usa pistas contextuais para estreitar o espaço de busca. O planner identifica entidades e detecta padrões de query como pistas que guiam os sinais de retrieval.

Passo a passo: ciclo de vida completo de uma query

Query: "Onde o Marcos Tavares mora?"

Estágio 1 — Planejamento (determinístico):

Check saudação: sem match → prossegue
Check agregação: sem match → sem pattern queries
Check broad: sem match → broad_query = false
Resolver determinístico: "marcos tavares" → person:marcos_tavares (slug match)
similarity_query = "Onde o Marcos Tavares mora?" (original, sem alteração)

Estágio 2 — Retrieval multi-signal (paralelo):

Semântico: embedding("Onde o Marcos Tavares mora?") → top match: "Marcos Tavares lives in Porto Alegre" (0.91)
Keyword: "marcos" + "tavares" → 4 fatos sobre Marcos
Graph: BFS a partir de person:marcos_tavares → encontra fatos via entity links + relationships

Estágio 3 — Enhancement:

Spreading activation: a partir do seed "lives in Porto Alegre" → encontra fatos relacionados:
  "Marcos Tavares is married to Carolina" (via entity hop)
  "Carolina is an architect" (via 2-hop)

Estágio 4 — Reranking (blend multiplicativo):

"Marcos Tavares lives in Porto Alegre" → formula=0.91, reranker=1.0 → final=0.91
"Marcos Tavares is a product manager at Vertix" → formula=0.65, reranker=0.2 → final=0.28
"Carolina is an architect" → formula=0.30, reranker=0.0 → final=0.09 → filtrado (< 0.15)

Estágio 5 — Formatação:

Known facts:
- Marcos Tavares lives in Porto Alegre

Resultado: 1 fato altamente relevante, 210ms, 800 tokens.


Estágio 2: Retrieval Multi-Signal

Em português claro: O pipeline busca fatos relevantes usando três métodos diferentes ao mesmo tempo - por significado, por palavras exatas e por conexões entre entidades. Isso captura fatos que qualquer método sozinho perderia.

Três sinais independentes rodam em paralelo via asyncio.gather(), cada um encontrando candidatos de um ângulo diferente:

flowchart TD
    P["RetrievalPlan"] --> S["Semantic Search\n(pgvector cosine)"]
    P --> K["Keyword Search\n(SQL ILIKE)"]
    P --> G["Graph Traversal\n(BFS 2-hop)"]
    S --> M["Merge & Rank\n(dedup + weighted scoring)"]
    K --> M
    G --> M

Usa similaridade de cosseno do pgvector para encontrar fatos cujos embeddings são próximos ao embedding da query.

  • Embeds a query (passada sem alteração pelo planner)
  • Busca na tabela MemoryFact com índice HNSW
  • Retorna top-N candidatos acima do threshold min_similarity
  • Filtros: agent_id, fatos ativos (valid_to IS NULL), confiança >= min_confidence

Este é o sinal primário - encontra fatos que são semanticamente similares à query, mesmo que não compartilhem keywords exatas.

Matching SQL ILIKE em fact_text para hits exatos ou parciais de keywords.

  • Extrai palavras significativas (> 2 caracteres) da query
  • Faz match contra o texto do fato (até 5 keywords)
  • Score = fração de palavras da query encontradas no fato

Complementa a busca semântica capturando matches exatos que a similaridade de embedding pode perder (ex: nomes próprios, termos técnicos, abreviações).

Sinal 3: Graph Retrieval

Percorre relacionamentos de entidades para encontrar fatos conectados às entidades da query.

  • Começa das entidades identificadas pelo planner
  • Traversal BFS até 2 hops em MemoryEntityRelationship
  • Hop decay: Fatos no Hop 1 recebem score completo (1.0×). Fatos no Hop 2 recebem penalidade de 0.5×. Isso evita que fatos distantes dominem o pool de candidatos.
  • Fatos são buscados via entity links (MemoryFactEntityLink), não só pelo entity_key primário. Isso significa que um fato "Clara saiu da Vertix" (subject primário: Clara) também é encontrado ao buscar sobre Vertix - porque o fato tem um entity link secundário pra Vertix.
  • Fórmula de scoring: edge_strength × recency_factor × edge_recency_factor × query_bonus × hop_decay
  • query_bonus: 1.5x quando o nome da entidade aparece no texto da query
  • Fallback: se a tabela de entity links está vazia (pré-migration), retrieval faz fallback pra match direto por entity_key

Graph retrieval se destaca em encontrar fatos contextuais. Quando você pergunta sobre uma pessoa, ele também encontra fatos sobre seu local de trabalho, seus relacionamentos e seus projetos.

Passo a passo: retrieval cross-entity via entity links

Query: "O que aconteceu com a Vertix?"

Sem entity links (comportamento antigo):

Graph começa de organization:vertix
Busca MemoryFact WHERE entity_key = 'organization:vertix'
Encontra: apenas fatos onde Vertix é o subject PRIMÁRIO
Perde: "Clara Rezende left Vertix" (entity_key = person:clara_rezende)

Com entity links (comportamento atual):

Graph começa de organization:vertix
Busca MemoryFactEntityLink WHERE entity_key = 'organization:vertix'
Encontra fact_ids linkados à Vertix, independente do subject primário:
  → "Clara Rezende left Vertix" (primário: Clara, link: Vertix) ✅
  → "Vertix received Series A of R$ 20M" (primário: Vertix) ✅
  → "Ricardo Gomes is co-founder of Vertix" (primário: Ricardo, link: Vertix) ✅
  → "Vertix signed contract with Ambev" (primário: Vertix) ✅

Resultado: 4 fatos encontrados vs 2 sem links. A query sobre Vertix traz fatos de Clara, Ricardo e o deal da Ambev - todos linkados à Vertix mas não primariamente sobre a Vertix.

Merge & Rank

Depois que os três sinais retornam, os resultados são mesclados:

  1. Deduplicar por fact ID (o mesmo fato pode aparecer em múltiplos sinais)
  2. Aplicar decay de recência - Decay exponencial com half-life configurável (recency_half_life_days, padrão 14)
  3. Aplicar decay de confiança - Fatos mais antigos com menor confiança são penalizados
  4. Calcular score combinado - Soma ponderada:

O reranker faz blend com estes pesos

Por padrão, enable_reranker=True - o reranker LLM usa um blend multiplicativo com o score da fórmula computado a partir destes pesos. O score da fórmula continua sendo importante porque o reranker só pode atenuar ou amplificar, nunca zerar. Configure enable_reranker=False para depender apenas destes pesos no ranking final.

score = (
    score_weights["semantic"]   * semantic_score +    # default 0.70
    score_weights["recency"]    * recency_score +     # default 0.20
    score_weights["importance"] * importance_score     # default 0.10
)

Breakdown Completo do Score

Cada fato é pontuado em múltiplas dimensões. Você pode inspecionar em fact.scores pra entender por que um fato ficou onde ficou no ranking:

Cada dict ScoredFact.scores contém todos os 6 sinais computados ao longo do pipeline. A fórmula ponderada acima produz o score combinado base; estágios posteriores adicionam sinais que podem modificar o ranking final:

Chave Origem Range Descrição
semantic Busca semântica 0.0 - 1.0 Similaridade de cosseno entre embeddings da query e do fato. Sinal primário de retrieval.
keyword Busca por keyword 0.0 - 1.0 Fração de palavras da query encontradas no texto do fato. Complementa semântico para matches exatos.
recency Merge & Rank 0.0 - 1.0 Decay exponencial a partir do created_at, half-life = recency_half_life_days (padrão 14).
importance Importância dinâmica 0.0 - 1.0 Valor raw de importância do banco de dados. Computado pelo job de importância em background a partir de frequência de retrieval, recência de uso, correções do usuário e participação em padrões. Começa em 0.5 para fatos novos e evolui ao longo do tempo.
confidence Merge & Rank 0.0 - 1.0 Confiança efetiva após decay temporal. Presente no dict scores para debugging, mas NÃO faz parte da fórmula ponderada (score_weights usa apenas semantic, recency, importance). A confiança base é atribuída pelo LLM durante extração (tipicamente 0.95 para afirmações assertivas). Decai ao longo do tempo e é usada como filtro (min_confidence).
reranker Reranking 0.0 - 1.0 Score de relevância baseado em LLM. Presente apenas quando enable_reranker=True. Float contínuo retornado pelo reranker LLM.

Sinais adicionais computados durante enhancement (não estão em score_weights mas afetam o score final):

Chave Origem Descrição
pattern Enhancement Boost aditivo para fatos com alto reinforcement_count (até +0.10).
graph Graph traversal Score do traversal BFS de 2 saltos em relacionamentos de entidades.

Configuração

Parâmetro Default Descrição
topk_facts 20 Máximo de fatos a retornar
topk_events 8 Máximo de eventos a considerar
min_similarity 0.20 Similaridade de cosseno mínima para resultados semânticos
min_confidence 0.55 Confiança mínima do fato
recency_half_life_days 14 Half-life para decay de recência
score_weights Veja acima Pesos para cada sinal de scoring
min_score 0.15 Score final mínimo para fatos retornados
enable_reranker True Se deve usar reranking LLM

Paralelo com neurociência

O retrieval multi-signal espelha spreading activation em redes semânticas (Collins & Loftus, 1975). Quando você pensa em "médico", a ativação se espalha para conceitos relacionados ("hospital", "remédio", "consulta") através de links associativos. Da mesma forma, graph retrieval se espalha a partir de entidades da query ao longo de arestas de relacionamento, enquanto busca semântica ativa fatos através de proximidade de embedding.


Estágio 3: Enhancement

Em português claro: Depois de encontrar os resultados iniciais, o pipeline segue conexões pra descobrir fatos relacionados. Se você pergunta sobre uma pessoa, ele pode puxar fatos sobre o trabalho dela, projetos e equipe - coisas que você não perguntou diretamente mas que adicionam contexto útil.

Spreading Activation

A partir dos top-K fatos semente, o pipeline expande o contexto seguindo relacionamentos de entidades:

  • Para cada fato semente, encontra os relacionamentos da entidade
  • Percorre relacionamentos por N hops (spreading_activation_hops, padrão 2). Defina como 0 para desabilitar spreading completamente.
  • Aplica fator de decay por hop (spreading_decay_factor, padrão 0.50). Hop 1 usa o fator diretamente; Hop 2 usa o fator ao quadrado (decay composto).
  • Retorna até spreading_facts_per_entity fatos adicionais por entidade (padrão 3), aplicado tanto no Hop 1 quanto no Hop 2.

Isso captura contexto importante que não foi diretamente matcheado. Se você perguntar "o que o Rafael faz?", spreading activation pode trazer fatos sobre seu local de trabalho, time e projetos.

Quando o spreading activation faz diferença?

O spreading tem mais impacto com 20+ entidades e relações cruzadas entre domínios (ex: pessoas → projetos → clientes → tecnologias). Com datasets pequenos (< 15 entidades), os sinais semântico, keyword e graph já cobrem todo o espaço de fatos - o spreading pode retornar candidatos mas eles serão dedupados contra os resultados existentes. Os campos do trace spreading_candidates_returned e spreading_candidates_unique permitem confirmar se o spreading está contribuindo fatos novos pro seu dataset.

Sinal de Padrão

Fatos com alto reinforcement_count (incrementado por decisões NOOP no write) recebem um boost aditivo no score:

  • Alto reinforcement count → até 0.10 de score extra
  • Captura fatos frequentemente mencionados e bem estabelecidos

Configuração

Parâmetro Default Descrição
spreading_activation_hops 2 Máximo de hops a partir de fatos semente. Defina como 0 para desabilitar.
spreading_decay_factor 0.50 Decay de score por hop. Hop 1 = fator, Hop 2 = fator²
spreading_facts_per_entity 3 Máximo de fatos buscados por entidade no Hop 1 e Hop 2
spreading_max_related_entities 5 Máximo de entidades KG-relacionadas exploradas no Hop 1

Estágio 4: Reranking (Opcional)

Em português claro: Os estágios anteriores encontram fatos relevantes, mas o ranking é baseado em matemática (scores de similaridade, keyword overlap). O reranker pergunta a um LLM: "Dado o que essa pessoa tá perguntando, quais desses fatos são realmente mais úteis?" Isso produz um ranking final mais inteligente.

Quando enable_reranker=True, os top candidatos são rerankeados por um LLM que considera a intenção da query:

  • O reranker avalia topk_facts candidatos (padrão: 40). Esse pool expandido garante que fatos semanticamente relevantes além do top-20 inicial cheguem no reranker. Aumente topk_facts pra expandir a cobertura do reranker.
  • Respeita o significado semântico da query (não apenas overlap de keywords)
  • Pode promover fatos que são indiretamente relevantes mas importantes
  • Degradação graceful: se o reranker falhar ou exceder reranker_timeout_sec (padrão 5.0s), o ranking original é preservado
  • O timeout é enforced via asyncio.wait_for - a chamada LLM é cancelada se exceder o timeout configurado
  • Usa o mesmo provider LLM configurado no client (não precisa de provider separado)

O reranker é o estágio mais custoso, mas fornece a maior melhoria de qualidade para queries complexas.

Configuração

Parâmetro Tipo Default Descrição
reranker_weight float 0.70 Peso do score do reranker no blend multiplicativo
min_reranker_score float 0.10 Score mínimo do reranker; fatos abaixo são eliminados
reranker_timeout_sec float 5.0 Timeout para a chamada LLM do reranker (segundos)

Veto do reranker: min_reranker_score

Quando enable_reranker=True, qualquer fato que recebe um score do reranker abaixo de min_reranker_score (padrão 0.10) é eliminado dos resultados (final_score definido como 0.0). Isso dá ao reranker poder de veto sobre fatos completamente irrelevantes - mesmo que o score da fórmula seja alto (ex: graph BFS dá 0.80 pra um fato distante e não relacionado). Quando enable_reranker=False, esta configuração não tem efeito. Ajuste: config_overrides={"min_reranker_score": 0.05} para resultados mais permissivos, 0.20 para filtragem mais rigorosa.

Scoring por multiplicative blend

O reranker NÃO substitui o score da fórmula. Ele usa um blend multiplicativo:

final_score = formula_score × (floor + reranker_weight × reranker_score)

onde floor = 1 - reranker_weight. Com o default reranker_weight=0.70, um fato com formula=0.9 e reranker=0.0 fica com final = 0.9 × (0.30 + 0) = 0.27 (não 0.0). Um fato com formula=0.9 e reranker=1.0 fica com final = 0.9 × (0.30 + 0.70) = 0.90. O reranker pode amplificar ou atenuar fatos mas não consegue zerar um fato com bons sinais de retrieval apenas pelo blend. Porém, min_reranker_score É uma exceção - fatos com score abaixo dele são zerados independentemente do score da fórmula. O dict scores preserva tanto formula (pré-reranker) quanto reranker (score do LLM) pra debugging.

Passo a passo: como o blend do reranker funciona

Query: "Qual o time de futebol do Bruno Almeida?"

Candidatos pré-reranker (scores da fórmula):

1. "Bruno Almeida runs marathons" → formula = 0.45 (semântico: similaridade com "sports")
2. "Bruno Almeida developed an ML model" → formula = 0.38
3. "Bruno Almeida works at Orion Tech" → formula = 0.35

Scores do reranker (avaliação do LLM):

1. "Bruno Almeida runs marathons" → reranker = 0.0 (maratona ≠ futebol)
2. "Bruno Almeida developed an ML model" → reranker = 0.0 (irrelevante)
3. "Bruno Almeida works at Orion Tech" → reranker = 0.0 (irrelevante)

Blend multiplicativo (weight=0.70, floor=0.30):

1. final = 0.45 × (0.30 + 0.70 × 0.0) = 0.45 × 0.30 = 0.135 → filtrado (< 0.15)
2. final = 0.38 × 0.30 = 0.114 → filtrado
3. final = 0.35 × 0.30 = 0.105 → filtrado

Resultado: 0 fatos retornados. Correto - não existe informação sobre o time de futebol do Bruno na memória.

Compare com uma query relevante - "O que o Bruno Almeida desenvolveu?":

"Bruno developed an ML model for fraud detection" → formula=0.92, reranker=1.0
final = 0.92 × (0.30 + 0.70 × 1.0) = 0.92 × 1.0 = 0.92 ✅


Estágio 5: Formatação

Em portugues claro: O pipeline pega os fatos ranqueados e organiza numa string limpa, pronta pra consumo por LLM. O formato foi projetado para ser direto e sem ruido -- fatos aparecem como uma lista simples em "Known facts:", conversas relevantes em "Relevant conversations:", e padroes observados em "Observed patterns:". Tudo dentro de um orcamento de tokens pra nao estourar seu prompt.

Formato de Contexto

O contexto e organizado em tres secoes dentro de um orcamento de tokens (context_max_tokens):

context_max_tokens e um orcamento proporcional, nao um limite rigido

O parametro context_max_tokens controla o tamanho relativo do contexto de saida, mas a contagem real de tokens pode exceder o valor configurado. O pipeline garante um contexto minimo para fatos e usa o parametro como orcamento proporcional entre secoes. Trate como um target, nao um limite estrito.

Secao Conteudo
Known facts Lista limpa de fatos, ordenados por score. Sem timestamps, sem prefixo de entidade, sem qualificadores como "assert confidently"
Observed patterns Meta-observations (padroes, tendencias, insights detectados pelos background jobs)
Relevant conversations Texto original de eventos recentes (ate 300 caracteres cada), com data

O formato foi projetado para consumo direto por LLMs -- limpo, sem ruido, sem metadados desnecessarios.

Perfis de entidade nao sao injetados no contexto

Perfis de entidade (profile_text) sao usados internamente pelo write pipeline como contexto para a extracao informada. Eles nao sao incluidos no contexto de retrieval retornado por retrieve(). O retrieval retorna apenas fatos individuais, padroes e eventos.

Configuracao

Parametro Default Descricao
context_max_tokens 2000 Maximo de tokens no contexto formatado
hot_tier_ratio 0.50 Parcela do orcamento para fatos com scores mais altos
warm_tier_ratio 0.30 Parcela do orcamento para fatos de suporte

Formato de Output

A string context e formatada para injecao direta em prompts LLM:

Known facts:
- Lives in Sao Paulo
- Works at Acme Corp as a backend engineer
- Wife's name is Ana

Observed patterns:
- Prefers working late at night

Relevant conversations:
- (2026-03-28) Had a great meeting with the product team about the roadmap...

RetrieveResult

result = await memory.retrieve(agent_id="user_123", query="...")

# Contexto pré-formatado (pronto para prompts LLM)
print(result.context)

# Fatos individuais com scores
for fact in result.facts:
    print(f"[{fact.score:.2f}] {fact.entity_name}: {fact.fact_text}")
    print(f"  Scores: {fact.scores}")  # {"semantic": 0.85, "recency": 0.72, ...}

# Stats do pipeline
print(f"Candidates evaluated: {result.total_candidates}")
print(f"Duration: {result.duration_ms:.0f}ms")

Diagrama do Pipeline (Completo)

flowchart TD
    Q["User query"] --> AG["Planner Determinístico\n(regex + schema)"]
    AG -->|skip| SKIP["Return empty\n(greeting/casual)"]
    AG -->|multi_signal| PAR["Parallel retrieval"]
    PAR --> SEM["Semantic Search\n(pgvector cosine)"]
    PAR --> KW["Keyword Search\n(SQL ILIKE)"]
    PAR --> GR["Graph Traversal\n(BFS 2-hop)"]
    SEM --> MERGE["Merge & Rank\n(dedup + weighted scoring)"]
    KW --> MERGE
    GR --> MERGE
    MERGE --> SA["Spreading Activation\n(expand context along edges)"]
    SA --> RR{"Reranker\nenabled?"}
    RR -->|yes| RERANK["LLM Rerank"]
    RR -->|no| FMT["Format & Compress"]
    RERANK --> FMT
    FMT --> RES["RetrieveResult"]

Paralelo com neurociencia

O orcamento de tokens age como o limite de capacidade da working memory. Fatos com scores mais altos recebem prioridade (foco de atencao), enquanto padroes e eventos fornecem contexto de suporte. Isso espelha o modelo de processos embutidos de Cowan, onde um numero pequeno de itens esta no foco de atencao, cercado por memoria de longo prazo ativada.