> ## Documentation Index
> Fetch the complete documentation index at: https://chatcli.edilsonfreitas.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Knowledge Base (RAG keyless)

> Transforme corpora de documentação ou repositórios de código/infra (Terraform, Kubernetes/Argo) em base de conhecimento: index card de ~900 tokens no prompt, retrieval híbrido BM25 + embeddings por turno, e a tool @knowledge para o agente investigar — tudo sem API key.

Um corpus de documentação de **6MB** vira **\~1,5M de tokens** se anexado inteiro — estoura a janela de qualquer modelo no primeiro turno. O modo `knowledge` do [`/context`](/pt/context/persistent-context) resolve com o mesmo padrão pull-first da [memória persistente](/pt/context/bootstrap-memory): a conversa recebe só um **index card** (o que a base cobre), e o conteúdo é **recuperado sob demanda** — automaticamente a cada turno e, no agente, iterativamente via tool `@knowledge`.

```bash theme={"system"}
# 1. Achate a doc (ex.: plugin @docs-flatten) → JSONL
@docs-flatten --repo https://github.com/org/docs.git --format jsonl --output docs.jsonl

# 2. Indexe como knowledge base (JSONL nativo; diretórios também funcionam)
/context create minha-doc docs.jsonl --mode knowledge

# 3. Anexe — custo fixo de ~900 tokens/turno, com 6MB ou 60MB
/context attach minha-doc
```

| | Attach tradicional (`full`) | `--mode knowledge` |
| - | - | - |
| Custo no prompt | corpus inteiro (\~1,5M tokens p/ 6MB) | **index card (\~900 tokens, fixo)** |
| Conteúdo | empurrado de uma vez | **puxado por relevância, a cada turno** |
| API key | — | **nenhuma** (BM25 puro-Go; embeddings = boost opcional) |
| Conhecimento | truncado/estourado | íntegro, pesquisável e citável por `source` |

***

## Como funciona

### Ingestão nativa do JSONL (docs-flatten)

Cada linha do JSONL vira um **documento virtual** preservando `source`, título e proveniência (`repoUrl`/`commit`) — em vez de entrar como um blob de texto único. Linhas malformadas são contadas e puladas, nunca fatais. Diretórios comuns também viram knowledge base (scanner normal, até 100MB).

O `@docs-flatten` aceita **três fontes** para o mesmo JSONL: `root=<dir>` (pasta local), `repo=<git-url>` (clone raso) e `url=<site>` (crawl raso mesmo-domínio para docs que só existem como site HTML, sem repo de Markdown).

### Código e infraestrutura (`kind=code`)

Além de documentação, o `@docs-flatten` ingere **repositórios de código-fonte, Terraform e GitOps (Kubernetes/Argo)** — no mesmo schema JSONL, então o knowledge mode não muda nada do lado de baixo. O parâmetro `kind` controla o que entra e como é fatiado:

| `kind` | O que ingere |
| - | - |
| `docs` (default) | Só Markdown/MDX. Comportamento legado — fluxos de doc existentes nunca passam a engolir código por acidente. |
| `code` | **Também** código-fonte, Terraform, YAML Kubernetes/Argo e shell, fatiados **por estrutura** (funções, recursos, manifests) com título de símbolo/recurso. É o modo "aponte para um repo de app/infra/GitOps". |
| `auto` | Por arquivo: Markdown fica Markdown, código/config fatia por estrutura, outro texto vira janela. |

O **fatiamento é agnóstico de linguagem** — não depende de uma lista de palavras-chave por linguagem, então não quebra ao trocar de stack:

| Arquivos | Unidade de chunk | Título |
| - | - | - |
| `.go .java .kt .ts .rs .cs .cpp .swift .scala .php` … | declaração de topo (balanço de chaves) | símbolo (`HandleCheckout`, `OrderService`) |
| `.tf .tfvars .hcl` | bloco Terraform | `tipo.nome` (`aws_eks_cluster.main`) |
| `.yaml .yml` | documento (`---`) | `Kind/nome` (`Rollout/checkout-api`) |
| `.py .rb` | `def`/`class` de topo (indentação) | símbolo |
| `.sh .bash` | função / bloco top-level | nome da função |
| qualquer outro texto | janela por tamanho | caminho do arquivo |

O título é **metadado best-effort**: se a heurística não reconhecer a linguagem, ele cai na linha de assinatura limpa — **o conteúdo é sempre indexado e buscável**, um título perdido nunca custa recall. Ruído é pulado por default (`vendor/`, `node_modules/`, `.terraform/`, lockfiles, minificados, binários) e arquivos acima de **1 MiB** são ignorados.

```bash theme={"system"}
# Uma base por camada — app, infra e gitops
@docs-flatten root=./app   kind=code format=jsonl output=app.jsonl
@docs-flatten root=./infra kind=code format=jsonl output=infra.jsonl   # blocos .tf
@docs-flatten root=./argo  kind=code format=jsonl output=argo.jsonl    # manifests .yaml

/context create app   app.jsonl   --mode knowledge
/context create infra infra.jsonl --mode knowledge
/context create argo  argo.jsonl  --mode knowledge
/context attach app && /context attach infra && /context attach argo
```

Com as três bases anexadas, o `@knowledge search` faz **fan-out sobre todas** (cada hit marcado pela base de origem), então o modelo **conecta as camadas**: *"o Rollout `checkout-api` não sobe — conecte o manifesto do Argo, o node group do Terraform e o health check no código do serviço"*.

<Note>
  Você **não precisa** classificar o repo manualmente. O default é `docs` por segurança, mas o agente escolhe `kind=code` sozinho: pela intenção (o schema do tool descreve o uso), pela orientação do pipeline autônomo (abaixo), e por um **hint auto-corretivo** — rodar o default `docs` num repo sem Markdown devolve *"parece um repo de código, rode com `kind=code`"*, e ele se corrige no mesmo turno.
</Note>

### Index card (o que entra no prompt)

<Note>
  Knowledge bases também são **nós no grafo de conhecimento** (kind `kbcontext`, ligadas pelas suas tags): `@memory map` as conta, `@memory neighbors` consegue navegar até elas, e elas viajam no cache persistido do grafo. Veja [Bootstrap e Memória › Grafo de conhecimento](/pt/context/bootstrap-memory#grafo-de-conhecimento-memory-neighbors--map).
</Note>

O attach injeta apenas um **TOC determinístico e budget-bounded** — nome, escala, origem e a lista de documentos — que vive no prefixo **cacheado** do prompt (estável byte a byte entre turnos). O modelo sabe *o que existe* sem pagar pelo conteúdo:

```
📚 KNOWLEDGE BASE: minha-doc
Origin: https://github.com/org/docs.git @ abc123def456
Scale: 87 document(s), 412 passage(s), ~1.5M tokens of source material (NOT in context)
Table of contents:
- guide/install.md (4 passages) — Install
- guide/deploy.md (12 passages) — Deploying to production
…
```

### Retrieval híbrido (keyless-first)

A cada turno, os trechos relevantes à pergunta são injetados num bloco **volátil** (fora do prefixo cacheado):

* **BM25 puro-Go** — sempre disponível, **sem API key**, neutro pt/inglês. É o piso. O tokenizer quebra `snake_case`, `kebab-case` e `camelCase`/`PascalCase` em sub-palavras (mantendo o token inteiro), então um identificador como `getUserName` ou `aws_eks_cluster` é achado por `user`, `eks` etc. — recall sobre código sem perder match exato.
* **Embeddings** ([Voyage/OpenAI/Bedrock](/pt/agents/harness/rag-hyde), se configurados) — boost semântico, fundido por ranking normalizado (0.55/0.45). Falha de embedding **degrada para o léxico** com warn; nunca quebra o turno.
* **União, fundida por ranking** — o top-k do próprio índice vetorial (sobre todas as passagens já embutidas) se junta ao pool do BM25, e a união é fundida por reciprocal rank fusion (rankings são comparáveis entre corpora, então um corpus de um único hit não pontua mais 1.0 por construção); uma passagem que diz a mesma coisa com outras palavras aparece mesmo quando o BM25 tem outros resultados. A query é embutida uma vez por turno e reaproveitada em todos os corpora anexados; o reranker via LLM manda a instrução uma vez como system message e contabiliza o uso como gasto de fundo.
* **Piso BM25** — hits léxicos abaixo de 5% do score do melhor hit saem do pool de candidatos, então uma pergunta que mal casa com o corpus devolve uma lista curta e honesta em vez de k passagens de ruído.
* **Estágio de rerank opcional** (`CHATCLI_KNOWLEDGE_RERANK`, padrão `off`) — reordena a cabeça do pool fundido (até 24 passagens) antes do corte. `mmr` é keyless: relevância marginal máxima sobre sobreposição de tokens, então as passagens devolvidas cobrem partes diferentes do corpus em vez de quase-duplicatas do melhor hit. `llm` pede ao modelo de compactação (`CHATCLI_COMPACT_MODEL`, senão o cliente da sessão) uma ordem listwise, limitada por timeout de 8 s; qualquer falha mantém a ordem fundida.
* **Pesos por corpus** — `/context attach <nome> --weight 1.5` escala os scores daquela base quando hits de várias bases anexadas são mesclados (`1.0` é neutro). O peso é persistido com os anexos da sessão.
* **Folding de acentos e stemming leve (opt-in)** — `CHATCLI_KNOWLEDGE_NORMALIZE=fold` faz `configuração` e `configuracao` serem o mesmo termo; `stem` também dobra terminações comuns pt/en (`configurações → configuracao`, `deploys → deploy`, `queries → query`, `rapidamente → rapida`) sem tocar em identificadores curtos como `s3` ou `oauth2`. O padrão `off` mantém o ranking byte-exato; mudar o modo reindexa o corpus (o modo faz parte do fingerprint do índice), e as buscas no transcript usam o mesmo tokenizer.
* **Embeddings locais e keyless** — `CHATCLI_EMBED_PROVIDER=ollama` usa um servidor Ollama local (`OLLAMA_HOST`, padrão `http://localhost:11434`; modelo `CHATCLI_EMBED_MODEL`, padrão `nomic-embed-text`, dimensão aprendida no primeiro uso) para o boost semântico sem API key e sem custo.
* **Aquecimento, não latência na primeira pergunta** — anexar uma base de conhecimento (ou `--rag`) e todo refresh que mudou algo embutem as passagens faltantes em background, em lotes, então a primeira pergunta depois disso não paga o embedding do corpus no turno. Ids de passagem são hashes de conteúdo: um refresh embute só o que mudou. O índice vetorial é escrito com rename atômico e fsync. Retrieval e aquecimento compartilham um único loop limitado (64 passagens por requisição ao provedor) atrás de um single-flight por contexto, então uma pergunta que chega durante o aquecimento espera por ele em vez de embutir os mesmos ids duas vezes. Um lote que o provedor rejeita é pulado e o resto ainda entra; o cache vetorial guarda cada lote que voltou antes de uma falha. Conteúdo binário (bytes NUL, UTF-8 inválido) e bundles minificados nunca chegam ao embedder, uma linha longa demais é cortada sem partir runa num teto fixo, e passagens truncadas mantêm a faixa de linhas da citação verdadeira.
* **Um budget por turno** — as passagens recuperadas de todas as bases anexadas compartilham um budget (\~24 K caracteres, em ordem de prioridade); passagens já emitidas por uma base de maior prioridade (mesmo id, ou o mesmo conteúdo no mesmo lugar) são descartadas, e a última base recebe o que sobra em vez de nada.
* **Citações estruturadas** — todo cabeçalho de passagem termina com `cite as [caminho:início-fim]` e o bloco pede ao modelo que referencie passagens assim, então uma resposta pode ser rastreada até as linhas exatas.
* **Custo de embedding visível** — toda chamada de embedding é medida (tokens estimados por caracteres na tarifa de lista do provedor) e aparece no `/cost` como `Embeddings: N chamada(s) · ~T tokens · $x`; Ollama mede a \$0.
* **Passagens conscientes de estrutura** — contextos criados a partir de agora cortam passagens em headings, linhas em branco e declarações (`func`, `def`, `class`, …) na parte final da janela, e a linha de fronteira abre a próxima passagem. Contextos existentes mantêm suas passagens de janela fixa e seus vetores; nada é re-embutido pelas suas costas.

***

## Tool `@knowledge` — o agente investiga a base

No **agent** e no **coder**, os index cards entram no system prompt e a tool `@knowledge` permite **investigação iterativa** — buscar, ler documentos inteiros em páginas, navegar a estrutura:

| Subcomando | O que faz |
| - | - |
| `search {query, top_k?, kb?}` | Passagens ranqueadas (híbrido) com citação de `source` |
| `get {source, offset?, kb?}` | Lê um documento inteiro, em páginas de \~3K tokens com offset de continuação |
| `toc {prefix?, kb?}` | Lista os documentos da base (filtro por prefixo de path) |
| `list` | Bases anexadas à sessão e suas escalas |

O caso de uso que fecha o ciclo — **criar skills a partir da doc** com a tool [`@skill`](/pt/extensions/skill-authoring):

```
/agent cria uma skill de deploy baseada na seção de produção da doc
  → @knowledge search "deploy production"
  → @knowledge get "guide/deploy.md"
  → @skill create deploy-prod …
```

***

## Pipeline autônomo — o agente constrói a base sozinho (`@context`)

Os passos acima (achatar → criar → anexar) o **agente faz por você**. Quando ele topa com uma lacuna de conhecimento — uma lib, framework ou API que não domina — em vez de chutar ou parar para perguntar, ele monta a própria base:

<Steps>
  <Step title="Descobre a fonte">
    `@websearch` pela documentação oficial (de preferência o repo Markdown do projeto), ou usa um repo/URL/caminho que você indicou.
  </Step>

  <Step title="Achata">
    `@docs-flatten` com `root=<dir>`, `repo=<git>` ou `url=<site>` → produz o corpus JSONL. Para um repo de código/infra, adiciona `kind=code` (uma base por camada: app, infra, gitops).
  </Step>

  <Step title="Cria e anexa">
    `@context create … --mode knowledge` → `@context attach …`.
  </Step>

  <Step title="Consulta">
    `@knowledge search/get` para fundamentar a resposta nos trechos recuperados.
  </Step>
</Steps>

A tool **`@context`** dá ao agente o mesmo poder de auto-serviço que ele já tem com [skills](/pt/extensions/skill-authoring), mas para conhecimento:

| Subcomando | O que faz |
| - | - |
| `create {name, paths[], mode?}` | Constrói uma base a partir de um corpus.jsonl, diretório ou arquivos (mode `knowledge` por default) |
| `update {name, paths?, mode?, …}` | Re-ingere/modifica uma base existente |
| `attach {name, rag?, priority?}` | Anexa à sessão; `rag` liga retrieval semântico top-K |
| `detach {name}` | Remove o anexo da sessão (a base fica no disco) |
| `list` / `status` | Lista todas as bases / mostra o que está anexado nesta sessão |
| `show {name}` / `inspect {name, chunk?}` | Metadados de uma base / visão profunda (arquivos, chunks) |
| `merge {name, sources[]}` | Combina bases numa nova (deduplicado) |
| `export {name, path}` / `import {path}` | Salva/carrega uma base em arquivo portável |
| `metrics` | Resumo do store: total de bases, anexadas, tamanho, por modo |
| `delete {name}` | Remove a base do disco |

A tool espelha **toda** a superfície do `/context`, então o agente lida com os contextos de ponta a ponta. As subcomandos de inspeção (`list`, `status`, `show`, `inspect`, `metrics`) são read-only.

**Você continua no controle:** tudo que o agente anexa aparece no `/context attached` e no `@context status`; remova com `/context detach` ou simplesmente peça ("desanexa a doc do react"). O `attach` detecta embeddings automaticamente — knowledge mode usa BM25 keyless + vetores quando configurados, e reporta qual modo está ativo. No `/agent` o agente faz tudo isso sozinho; no `/coder`, as operações que mexem em estado passam pela confirmação de política.

<Tip>
  O modo **`url`** do `@docs-flatten` é o que fecha o ciclo para docs que **só existem como site HTML** (sem repo de Markdown): um crawl raso, mesmo-domínio, reaproveitando o motor de fetch do [`@webfetch`](/pt/tools/web-tools) e emitindo o mesmo JSONL. Bounded por `maxPages`/`maxDepth` — sem truncamento silencioso.
</Tip>

***

## No chat também (exceção read-only)

O chat continua [tool-less por design](/pt/coder/interactive-ask) — mas a consulta à knowledge base é a **segunda exceção sancionada** (ao lado do `ask_user`), pela mesma razão: **não executa nada, só lê** o que você anexou. Anexe a base e converse normalmente; quando os trechos automáticos não bastam, o modelo puxa mais sozinho (até 4 pulls por turno: search → get → próxima página) antes de responder.

```bash theme={"system"}
/config chat knowledge off      # desliga a exceção (CHATCLI_CHAT_KNOWLEDGE=false)
/config chat knowledge on       # religa (default: on)
```

Funciona no caminho de tools **nativo** (API key) e no transporte **XML** (providers OAuth) — como todo o resto, agnóstico aos 14 providers.

***

## Referência rápida

| Superfície | Valor |
| - | - |
| Criar | `/context create <nome> <corpus.jsonl\|dir> --mode knowledge` |
| Anexar / desanexar | `/context attach <nome>` / `/context detach <nome>` |
| Agente faz sozinho | tool `@context` (`create`/`attach`/`detach`/`list`/`status`/`delete`) |
| Fontes do `@docs-flatten` | `root=<dir>` · `repo=<git>` · `url=<site>` (crawl) |
| Tipo do `@docs-flatten` | `kind=docs` (default, só Markdown) · `kind=code` (código/Terraform/YAML/shell, fatiado por estrutura) · `kind=auto` |
| Custo por turno | index card (\~900 tokens, cacheado) + top-K volátil |
| Toggle no chat | `/config chat knowledge on\|off\|toggle` (`CHATCLI_CHAT_KNOWLEDGE`, default `on`) |
| Embeddings (opcional) | `CHATCLI_EMBED_PROVIDER=voyage\|openai\|bedrock` — sem provider, BM25 cobre tudo |
| Limites | 100MB / 5.000 documentos por base; `get` paginado em \~12K chars |

<Tip>
  **Knowledge vs `--rag`:** o `/context attach --rag K` existente é vetor-puro (exige embedding provider) e só faz push por turno. O modo `knowledge` funciona **sem chave nenhuma**, dá ao modelo o índice do corpus e adiciona o lado pull (`@knowledge`) — para corpora de documentação ou de código/infra, prefira `--mode knowledge`.
</Tip>

## Próximos passos

<CardGroup cols={2}>
  <Card title="Contextos Persistentes" icon="box-archive" href="/pt/context/persistent-context" />

  <Card title="RAG + HyDE" icon="magnifying-glass" href="/pt/agents/harness/rag-hyde" />

  <Card title="Criação de Skills" icon="wand-magic-sparkles" href="/pt/extensions/skill-authoring" />

  <Card title="Bootstrap e Memória" icon="brain" href="/pt/context/bootstrap-memory" />
</CardGroup>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.