Arquitetura
As notas entram por um observador e uma fila de tarefas; as perguntas voltam como citações com intervalos de linhas. Cada caixa nomeia o arquivo que a implementa.
Em uma tela estreita, leia a tabela de cada parte em vez dos desenhos.
Os dois fluxos
Recuperação, citações e avaliação precisam apenas de Postgres e do Ollama para os embeddings. Um modelo de linguagem acrescenta a resposta escrita em ask. Roda com Docker Compose ou de forma nativa com unidades systemd; a GPU é usada por Vulkan quando existe /dev/dri e nunca é obrigatória. As mensagens do programa, como No evidence found for that query., ficam em inglês porque são a saída literal. Fonte: core/README.md, core/docs/running.md.
Os componentes por trás deles
O mesmo sistema, agrupado por camada. Leia de cima para baixo: cada camada chama a de baixo, e a última linha é usada por todas. Cada caixa é um arquivo ou um pacote em core/src/knowman/.
A seta da esquerda vai da camada que chama para a camada da qual ela depende. Configuração, controle de acesso e registro ficam no fim porque todas as camadas acima os leem. Fonte: core/src/knowman/, core/README.md, core/docs/running.md.
Cada parte
Os nomes da coluna Parte estão traduzidos. Os nomes da coluna Código são os arquivos e as configurações reais.
| Parte | Código | Estado | O que faz |
|---|---|---|---|
| Notas (.md) | pasta CORPUS_PATH | real | Sua pasta Markdown. A indexação nunca a modifica; só o agente escreve nela. |
| Observador | watcher.py | real | Transforma cada arquivo .md adicionado, editado ou apagado em uma tarefa. |
| Fila de tarefas | store.py | real | As tarefas são linhas no Postgres: ingest_path e delete_path, com estado pending, processing, done ou failed. |
| Processador | worker.py | real | Pega uma tarefa por vez e a executa; uma tarefa que falha fica registrada, não é repetida em silêncio. |
| Fragmentador | chunking.py, ingest.py | real | Corta em linhas vazias mantendo o intervalo de linhas de cada trecho; ingest.py calcula os embeddings e guarda os trechos. |
| Embeddings | embeddings/base.py, embeddings/ollama.py | real | O Ollama transforma cada trecho em um vetor (modelo em EMBEDDINGS_MODEL). Uma interface, uma implementação. |
| Postgres + pgvector | store.py | real | Guarda trechos, tarefas, execuções de eval e rastros. Índice HNSW cosine na coluna embedding. |
| Embed consulta | retrieval.py | real | Transforma a pergunta em um vetor com o mesmo modelo. |
| Trechos próximos | store.py | real | Devolve os k trechos mais próximos (k padrão vem de RETRIEVAL_DEFAULT_K). |
| Filtro de distância | retrieval.py | real | Descarta os trechos mais distantes que RETRIEVAL_MAX_DISTANCE. Um resultado vazio é o negativo explícito. |
| Citações | retrieval.py | real | Cada citação carrega caminho, linha inicial, linha final, texto e distância. |
| Formatação | formatting.py | real | Escreve uma citação como path:Lstart-Lend mais o trecho, e um resultado vazio como "No evidence found for that query." |
| Resposta do LLM | ask.py, llm/*.py | opcional | Só quando LLM_PROVIDER está definido (Ollama, Claude, OpenAI ou Grok) e há evidência. search e eval nunca precisam dele. |
| Prompts | prompts/ask_v1.txt | opcional | O template com que a resposta é escrita; PROMPT_VERSION escolhe o arquivo, então um texto novo é um arquivo novo, não uma mudança de código. |
| Avaliação | eval.py, evaldata/dataset.json | real | Pontua um dataset rotulado contra a recuperação; nenhum modelo julga outro modelo. |
| Agente | agent.py | opcional | knowman write: um agente LangGraph sobre Ollama que pode buscar nas notas e escrever uma nova. |
| CLI | cli.py | real | db-init, ingest, search, ask, eval, worker, watch, mcp, write. |
| API HTTP | api.py | real | Search, ask, eval, tarefas de indexação, status; API_TOKEN e limite de taxa opcionais. |
| Controle de acesso | access.py | real | A checagem do token e o contador de requisições por minuto por trás dessas duas opções. Ambas ficam desligadas se não forem definidas, e nenhuma sabe o que search ou ask fazem. |
| Servidor MCP | mcp_server.py | real | Duas ferramentas somente leitura por stdio: search e ask. |
| Painel | dashboard.py | real | Uma página em /dashboard: índice contra disco, fila de tarefas, última avaliação, atividade recente. |
| Configuração | config.py | real | Um único objeto Settings lido do ambiente e do .env; cada módulo pede a ele em vez de interpretar variáveis. |
| Registro | logging_setup.py | real | Logs JSON no stdout, um registro por linha, para que os contêineres e as unidades systemd registrem o mesmo formato. |