Skip to content

Commit c10c6cb

Browse files
committed
docs: overhaul README to enhance clarity and detail about KernelBot functionality and structure
This update significantly expands the README, providing a comprehensive overview of KernelBot, its features, and usage instructions. Key sections include an introduction to the system, problem it addresses, operational workflow, unique features, folder structure, and limitations. Additionally, installation and execution instructions have been clarified, ensuring better guidance for users.
1 parent 693581d commit c10c6cb

1 file changed

Lines changed: 151 additions & 24 deletions

File tree

README.md

Lines changed: 151 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -2,58 +2,185 @@
22
<img src="frontend/assets/images/KernelBanner.webp" alt="KernelBot" width="100%" />
33
</p>
44

5-
# KernelBots (ACL)
5+
# KernelBot
66

7-
Agente de contexto local com RAG (BM25) sobre Markdown em `content/`, interface em `templates/` e respostas em streaming via OpenRouter.
7+
**Chatbot RAG local-first que transforma Markdown em base de conhecimento consultável via chat.**
88

9-
## Requisitos
9+
---
10+
11+
## O que é
12+
13+
O KernelBot — internamente chamado **ACL (Agente de Contexto Local)** — é um sistema que indexa arquivos Markdown de um diretório local (`content/`) usando BM25, recupera trechos relevantes e os injeta como contexto para um LLM via OpenRouter. A resposta chega em streaming (SSE) com rastreabilidade: você sabe de onde veio cada trecho usado.
14+
15+
Sem banco de dados, sem fila, sem infra pesada. Índice e estado ficam na memória do processo.
16+
17+
---
18+
19+
## Problema que resolve
20+
21+
Alunos precisam revisar gravações de aulas de ~2h para tirar dúvidas simples. Sem o KernelBot, a alternativa é reassistir o material bruto ou esperar resposta da secretaria/professores.
22+
23+
O sistema usa resumos estruturados das aulas como corpus RAG, permitindo perguntas diretas com respostas ancoradas no conteúdo real — não em "achismo" do modelo.
24+
25+
---
26+
27+
## Como funciona
28+
29+
```
30+
content/*.md ──► SearchEngine (BM25 por silo) ──► ContextManager ──► ChatProvider ──► SSE
31+
▲ │
32+
│ ▼
33+
Watchdog OpenRouter API
34+
(rebuild automático) (LLM com fallback)
35+
```
36+
37+
**Três etapas:**
38+
39+
1. **Indexação**`SearchEngine``content/**/*.md`, divide por headers em chunks e cria um índice BM25 separado por silo (subpasta). O Watchdog monitora alterações e reconstrói o índice automaticamente (~1.5s de debounce).
40+
41+
2. **Decisão de contexto**`ContextManager.build_messages()` interpreta comandos (`/python`, `/doc`, `/content`), campo `discipline` do JSON e pinned context por sessão para decidir quais chunks injetar no system prompt.
42+
43+
3. **Geração**`ChatProvider` chama o LLM via OpenRouter em streaming SSE. Suporta fallback automático entre modelos. Antes dos tokens, emite metadados (`[ACL_META]`) com rótulo do silo e fontes usadas.
44+
45+
---
46+
47+
## Diferenciais
48+
49+
| Recurso | O que faz |
50+
|---------|-----------|
51+
| **Silos BM25** | Cada subpasta de `content/` é um domínio isolado com índice próprio — evita mistura de contextos entre disciplinas |
52+
| **Comandos de escopo** | `/python`, `/doc`, `/content` etc. forçam onde a busca acontece |
53+
| **Pinned context** | Mantém contexto entre mensagens da mesma sessão para follow-ups curtos não "perderem o fio" |
54+
| **File watching** | Editou um `.md` em `content/`? Em ~1.5s o índice já reflete a mudança |
55+
| **Rastreabilidade** | Respostas incluem breadcrumbs com os arquivos fonte usados (via `[ACL_META]` no SSE) |
56+
| **Zero infra** | Sem banco, sem Redis, sem Docker obrigatório — `python main.py` e pronto |
57+
58+
---
59+
60+
## Estrutura de pastas
61+
62+
```
63+
KernelBot/
64+
├── main.py # Orquestração: serviços, watchdog, app FastAPI
65+
├── core/ # Settings (.env), logging centralizado
66+
├── engine/ # SearchEngine, ContentWatcher, ContextManager, ChatProvider, PinnedSessionStore
67+
├── api/ # Rotas FastAPI (GET /, POST /chat)
68+
├── app/ # create_app(), estado injetado (AppServices)
69+
├── content/ # Base de conhecimento — silos por subpasta
70+
│ ├── python/ # 16 aulas
71+
│ ├── visualizacao-sql/# 17 aulas
72+
│ ├── projeto-bloco/ # 9 aulas
73+
│ ├── planejamento-curso-carreira/ # 7 aulas
74+
│ └── doc/ # Documentação interna (silo /doc)
75+
├── frontend/ # Assets CSS e módulos JS da UI
76+
├── templates/ # index.html (Jinja2)
77+
├── tests/ # Smoke tests (pytest)
78+
└── requirements.txt
79+
```
80+
81+
---
82+
83+
## Como rodar
84+
85+
### Pré-requisitos
1086

1187
- Python 3.10+
12-
- Chave `OPENROUTER_API_KEY` no arquivo `.env` na raiz do repositório
88+
- Chave de API do [OpenRouter](https://openrouter.ai/)
1389

14-
## Instalação
90+
### Instalação
1591

1692
```bash
93+
git clone https://github.com/seu-usuario/KernelBot.git
94+
cd KernelBot
1795
pip install -r requirements.txt
1896
```
1997

20-
## Executar
98+
### Configuração
99+
100+
Crie um arquivo `.env` na raiz:
101+
102+
```
103+
OPENROUTER_API_KEY=sua-chave-aqui
104+
```
105+
106+
Variáveis opcionais:
107+
108+
| Variável | Default | Descrição |
109+
|----------|---------|-----------|
110+
| `ACL_GLOBAL_CONTEXT` | `geral` | Escopo BM25 sem filtro: `geral` (só silo geral) ou `all` (todos os silos) |
111+
| `ACL_PINNED_MAX_TURNS` | `5` | Turnos antes do pinned context expirar |
112+
| `ACL_PINNED_MAX_CHARS` | `24000` | Limite de caracteres no pinned context |
113+
| `ACL_PINNED_WEAK_SCORE` | `0.4` | Score BM25 abaixo do qual se reutiliza o pin |
114+
115+
### Executar
21116

22117
```bash
23118
python main.py
24119
```
25120

26-
Ou com Uvicorn:
121+
Ou com reload para desenvolvimento:
27122

28123
```bash
29-
uvicorn main:app --host 127.0.0.1 --port 8000
124+
uvicorn main:app --host 127.0.0.1 --port 8000 --reload
30125
```
31126

32-
Abra `http://127.0.0.1:8000`.
127+
Acesse `http://127.0.0.1:8000`.
33128

34-
## Estrutura
129+
---
35130

36-
| Caminho | Função |
37-
|--------|--------|
38-
| `main.py` | Orquestração: logging, `SearchEngine`, watchdog, `create_app` |
39-
| `core/` | Config (`Settings`), logging centralizado |
40-
| `engine/` | BM25 (`SearchEngine`), `ContentWatcher`, `ContextManager`, `ChatProvider` |
41-
| `api/` | Rotas FastAPI (`GET /`, `POST /chat`) |
42-
| `app/` | `create_app()`, estado injetado em `app.state` |
43-
| `content/` | Arquivos `.md` indexados |
44-
| `templates/` | UI (Jinja2) |
131+
## Comandos do chat
132+
133+
| Comando | Efeito |
134+
|---------|--------|
135+
| `/python <pergunta>` | Busca RAG restrita ao silo `python` |
136+
| `/visualizacao-sql <pergunta>` | Busca RAG restrita ao silo `visualizacao-sql` |
137+
| `/projeto-bloco <pergunta>` | Busca RAG restrita ao silo `projeto-bloco` |
138+
| `/planejamento-curso-carreira <pergunta>` | Busca RAG restrita ao silo `planejamento-curso-carreira` |
139+
| `/doc <pergunta>` | Injeta todo o conteúdo de `content/doc/` no prompt |
140+
| `/content <pergunta>` | Força RAG no escopo global (com fallback para os primeiros chunks se não houver hit) |
141+
| `/reset` ou `/limpar` | Limpa o pinned context da sessão |
142+
143+
Sem comando, o sistema usa o campo `discipline` do JSON (se enviado) ou o escopo global configurado.
144+
145+
---
45146

46147
## Testes
47148

48149
```bash
49150
python -m pytest tests/ -v
50151
```
51152

52-
## Logging
153+
---
154+
155+
## Limitações
156+
157+
- **BM25 é lexical, não semântico** — se o vocabulário da pergunta divergir do corpus, o retrieval pode falhar. Use `/content` para forçar contexto.
158+
- **Sem autenticação** — adequado para uso local (`127.0.0.1`). Não expor em rede sem proteção adicional.
159+
- **Pinned context em RAM** — reiniciar o servidor perde o estado de sessão.
160+
- **Comandos de silo não são automáticos** — novas subpastas em `content/` indexam automaticamente, mas o atalho `/nome` precisa ser adicionado manualmente em `_DISCIPLINE_COMMAND_PREFIXES` (`engine/context.py`).
161+
- **Versões não fixadas**`requirements.txt` sem pins exatos; risco de drift em novas instalações.
162+
163+
---
164+
165+
## Por que existe
166+
167+
Criado para resolver uma dor real: alunos do INFNET gastavam horas revisando gravações de aula para tirar dúvidas pontuais. O KernelBot transforma resumos estruturados dessas aulas em uma base pesquisável via chat — com controle de escopo, rastreabilidade e zero dependência de infra complexa.
168+
169+
---
170+
171+
## Stack
172+
173+
| Camada | Tecnologia |
174+
|--------|------------|
175+
| Servidor HTTP | FastAPI + Uvicorn |
176+
| Índice de busca | BM25Okapi (`rank-bm25`) |
177+
| File watching | Watchdog |
178+
| LLM gateway | OpenRouter API (`httpx` async) |
179+
| Frontend | HTML/CSS/JS puro (Jinja2) |
180+
| Streaming | Server-Sent Events (SSE) |
53181

54-
O projeto usa `logging` da biblioteca padrão com loggers prefixados `kernelbots.*` (ex.: `kernelbots.engine.search`, `kernelbots.api.chat`). Para logs estruturados em JSON no stdout, é possível estender `core/logging_config.py` com algo como `structlog` no mesmo ponto de configuração.
182+
---
55183

56-
## Comandos no chat
184+
## Licença
57185

58-
- `/content …` — força uso da base local (com fallback para os primeiros chunks se não houver hit BM25).
59-
- `/doc …` — injeta o conteúdo de `documentation.md` quando disponível no índice.
186+
Veja o arquivo [LICENSE](LICENSE).

0 commit comments

Comments
 (0)