own-rag-cli 0.0.1-snapshot

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,285 @@
1
+ # How It Works — RAG Local + Claude Code
2
+
3
+ ## Por que BGE-M3?
4
+
5
+ Foram avaliados dois modelos para este RAG:
6
+
7
+ | Modelo | Dims | Context | Foco | Status |
8
+ |---|---|---|---|---|
9
+ | `all-MiniLM-L6-v2` | 384D | 256 tokens | Geral | Substituído |
10
+ | `jinaai/jina-embeddings-v2-base-code` | 768D | 8192 tokens | Código | Incompatível com transformers ≥4.40 |
11
+ | `BAAI/bge-m3` | 1024D | 8192 tokens | Multilingual | **Escolhido** |
12
+
13
+ O `jina-embeddings-v2-base-code` seria ideal para código puro, mas seu código customizado referencia `find_pruneable_heads_and_indices`, função removida do `transformers` na versão 4.40 e o modelo não foi atualizado. O BGE-M3 funciona com transformers 5.x, tem 1024D (representação mais rica) e contexto de 8192 tokens.
14
+
15
+ ---
16
+
17
+ ## O que é o BGE-M3
18
+
19
+ O `BAAI/bge-m3` (Beijing Academy of AI) é um modelo de **sentence embeddings** de última geração. Ele converte qualquer texto em um vetor de **1024 dimensões** que representa o significado semântico do conteúdo.
20
+
21
+ Textos semanticamente similares ficam próximos no espaço vetorial:
22
+
23
+ ```
24
+ "função que valida e-mail" → [0.04, -0.21, 0.67, ...] (1024 números)
25
+ "verificar formato de email" → [0.05, -0.20, 0.65, ...] (muito próximo!)
26
+ "conexão com banco de dados" → [0.81, 0.33, -0.12, ...] (distante)
27
+ ```
28
+
29
+ **Vantagens sobre all-MiniLM-L6-v2:**
30
+ - **8192 tokens** de contexto (era 256) — funções inteiras cabem em um chunk
31
+ - **1024 dimensões** (era 384) — representação muito mais rica e precisa
32
+ - **State-of-the-art** no MTEB benchmark (maior benchmark de retrieval)
33
+ - **Chunks maiores**: 6000 chars/chunk (era 2400) — menos fragmentação de código
34
+
35
+ ---
36
+
37
+ ## Visão Geral da Solução
38
+
39
+ ```mermaid
40
+ flowchart TD
41
+ subgraph SETUP["Fase 1 — Setup (uma vez)"]
42
+ A[rag-setup.run] --> B[Instala dependências Python em ~/.rag_venv]
43
+ B --> C[Sobe ChromaDB Docker localhost:8000]
44
+ C --> D[Instala mcp-rag-server em ~/.local/bin/]
45
+ D --> E[Configura ~/.claude.json com mcpServers]
46
+ end
47
+
48
+ subgraph INDEX["Fase 2 — Indexação"]
49
+ F[indexer_full.py /projeto] --> G[Varre arquivos .py .js .ts .md ...]
50
+ G --> H[Divide em chunks 6000 chars, overlap 800]
51
+ H --> I[BAAI/bge-m3 encode chunks → vetores 1024D]
52
+ I --> J[(ChromaDB coleção: codebase HNSW cosine index)]
53
+ end
54
+
55
+ subgraph QUERY["Fase 3 — Busca em tempo real"]
56
+ K[Claude Code CLI] -->|stdio| L[mcp-rag-server]
57
+ L --> M[BAAI/bge-m3 encode query → vetor 1024D]
58
+ M --> N{ChromaDB HNSW search cosine distance}
59
+ N --> O[Top-K chunks mais similares]
60
+ O --> L
61
+ L -->|resultados formatados| K
62
+ K --> P[Claude usa o contexto para responder]
63
+ end
64
+
65
+ SETUP --> INDEX
66
+ INDEX --> QUERY
67
+ ```
68
+
69
+ ---
70
+
71
+ ## Diagrama de Sequencia — Busca Semantica
72
+
73
+ ```mermaid
74
+ sequenceDiagram
75
+ actor User as Usuario
76
+ participant CC as Claude Code CLI
77
+ participant MCP as mcp-rag-server<br/>(stdio)
78
+ participant Model as BAAI/bge-m3<br/>(em memoria)
79
+ participant DB as ChromaDB<br/>(Docker :8000)
80
+
81
+ User->>CC: Pergunta sobre o codigo
82
+ CC->>CC: Decide chamar semantic_search_code
83
+ CC->>MCP: {tool: "semantic_search_code",<br/>query: "funcao de autenticacao", top_k: 7}
84
+
85
+ MCP->>Model: encode(["funcao de autenticacao"])
86
+ Model-->>MCP: vetor [0.04, -0.21, ...] (1024D)
87
+
88
+ MCP->>DB: POST /api/v2/collections/codebase/query<br/>{query_embeddings: [...], n_results: 7}
89
+ DB->>DB: HNSW search<br/>cosine distance entre<br/>query e todos os chunks
90
+ DB-->>MCP: [{doc, metadata, distance}, ...]
91
+
92
+ MCP->>MCP: Formata resultado<br/>similarity = (1 - distance) * 100
93
+
94
+ MCP-->>CC: "## [1] /projeto/src/auth.py\nSimilaridade: 91.2%\n..."
95
+ CC->>CC: Injeta resultado no contexto
96
+ CC-->>User: Resposta usando o codigo encontrado
97
+ ```
98
+
99
+ ---
100
+
101
+ ## Diagrama de Sequencia — Indexacao
102
+
103
+ ```mermaid
104
+ sequenceDiagram
105
+ actor Dev as Desenvolvedor
106
+ participant IDX as indexer_full.py
107
+ participant FS as Sistema de Arquivos
108
+ participant Model as BAAI/bge-m3
109
+ participant DB as ChromaDB
110
+
111
+ Dev->>IDX: python3 indexer_full.py /meu-projeto
112
+
113
+ IDX->>DB: heartbeat() — valida conexao
114
+ DB-->>IDX: OK
115
+
116
+ IDX->>Model: SentenceTransformer("BAAI/bge-m3", device="cpu")
117
+ Model-->>IDX: modelo carregado (~570MB)
118
+
119
+ IDX->>DB: get_or_create_collection("codebase", hnsw:space=cosine)
120
+ DB-->>IDX: collection handle
121
+
122
+ IDX->>FS: os.walk(root_path)
123
+ FS-->>IDX: lista de arquivos (ignora .git, node_modules, binarios...)
124
+
125
+ loop Para cada arquivo
126
+ IDX->>FS: read_text(encoding=utf-8)
127
+ FS-->>IDX: conteudo do arquivo
128
+
129
+ IDX->>IDX: RecursiveCharacterTextSplitter<br/>chunk_size=6000, overlap=800<br/>separators=["\n\n", "\n", " ", ""]
130
+
131
+ IDX->>Model: encode(chunks) → batch
132
+ Model-->>IDX: [[...1024 floats...], ...]
133
+
134
+ IDX->>IDX: make_chunk_id = MD5(file_path::chunk::index)
135
+
136
+ IDX->>DB: collection.upsert(<br/>ids=[md5...], embeddings=[...],<br/>documents=[chunks], metadatas=[...]<br/>)
137
+ DB-->>IDX: OK
138
+ end
139
+
140
+ IDX-->>Dev: "Indexacao concluida! N arquivos, M chunks"
141
+ ```
142
+
143
+ ---
144
+
145
+ ## Como o Modelo Funciona Internamente
146
+
147
+ O `BGE-M3` e baseado em arquitetura XLM-RoBERTa com camadas de attention empilhadas:
148
+
149
+ ```
150
+ Texto de entrada
151
+ |
152
+ [Tokenizacao SentencePiece — multilingual]
153
+ |
154
+ [N x Transformer Layers com Multi-Head Self-Attention]
155
+ |
156
+ [Mean Pooling sobre tokens nao-padding]
157
+ |
158
+ [Normalizacao L2]
159
+ |
160
+ Vetor de 1024 dimensoes (embedding normalizado)
161
+ ```
162
+
163
+ **Por que distancia cosseno?**
164
+
165
+ A distancia cosseno mede o angulo entre dois vetores, ignorando a magnitude. Ideal para embeddings normalizados porque:
166
+ - Textos curtos e longos sobre o mesmo topico ficam proximos
167
+ - A normalizacao L2 do BGE-M3 torna cosine = dot product (mais rapido)
168
+
169
+ ```
170
+ similarity = 1 - cosine_distance
171
+ = dot(A, B) # quando ambos sao vetores L2-normalizados
172
+ ```
173
+
174
+ ---
175
+
176
+ ## Fluxo de Dados Detalhado
177
+
178
+ ```mermaid
179
+ flowchart LR
180
+ subgraph INPUT["Entrada"]
181
+ Q["Query do usuario
182
+ 'funcao de login'"]
183
+ end
184
+
185
+ subgraph EMBED["Embedding BGE-M3"]
186
+ T1["Tokenizacao SentencePiece
187
+ tokens multilinguals"]
188
+ T2["Transformer Layers
189
+ Multi-Head Attention"]
190
+ T3["Mean Pooling + L2 Norm
191
+ → vetor 1024D"]
192
+ T1 --> T2 --> T3
193
+ end
194
+
195
+ subgraph SEARCH["Busca Vetorial HNSW"]
196
+ V1["Vetor da query
197
+ 1024 dimensoes"]
198
+ V2["HNSW Index
199
+ ~N vetores indexados"]
200
+ V3["Top-K vizinhos
201
+ por cosine similarity"]
202
+ V1 --> V2 --> V3
203
+ end
204
+
205
+ subgraph OUTPUT["Saida"]
206
+ R1["[1] auth.py — 91%
207
+ def login(user, pwd)..."]
208
+ R2["[2] session.py — 87%
209
+ def create_session()..."]
210
+ R3["[3] middleware.py — 82%
211
+ def require_auth()..."]
212
+ end
213
+
214
+ INPUT --> EMBED
215
+ EMBED --> SEARCH
216
+ SEARCH --> OUTPUT
217
+ ```
218
+
219
+ ---
220
+
221
+ ## Estrutura dos Chunks no ChromaDB
222
+
223
+ Cada chunk armazenado tem:
224
+
225
+ | Campo | Tipo | Exemplo |
226
+ |---|---|---|
227
+ | `id` | string | `MD5("src/auth.py::chunk::0")` |
228
+ | `embedding` | float[1024] | `[0.04, -0.21, ...]` |
229
+ | `document` | string | `"def login(user, pwd):\n ..."` |
230
+ | `file_path` | metadata | `/home/<usuario>/projeto/src/auth.py` |
231
+ | `chunk_index` | metadata | `0` |
232
+ | `file_name` | metadata | `auth.py` |
233
+ | `relative_path` | metadata | `src/auth.py` |
234
+
235
+ O ID e deterministico: o mesmo arquivo + mesmo indice sempre gera o mesmo MD5. Isso permite **upsert idempotente** — reindexar um arquivo nao cria duplicatas.
236
+
237
+ ---
238
+
239
+ ## Parametros e seus Impactos
240
+
241
+ | Parametro | Valor anterior | Valor atual | Impacto |
242
+ |---|---|---|---|
243
+ | `EMBEDDING_MODEL` | all-MiniLM-L6-v2 | BAAI/bge-m3 | Melhor qualidade, mais dimensoes |
244
+ | `CHUNK_SIZE` | 2400 chars | 6000 chars | Funcoes inteiras cabem em 1 chunk |
245
+ | `CHUNK_OVERLAP` | 400 chars | 800 chars | Mais continuidade entre chunks |
246
+ | `embedding dims` | 384D | 1024D | Representacao muito mais rica |
247
+ | `context window` | 256 tokens | 8192 tokens | Nao trunca mais codigo longo |
248
+ | `top_k` | 7 (padrao) | 7 (padrao) | Quantidade de chunks por busca |
249
+ | `MAX_FILE_SIZE` | 500KB | 500KB | Limite de tamanho de arquivo |
250
+ | `hnsw:space` | cosine | cosine | Melhor para embeddings normalizados |
251
+ | `device` | cpu | cpu | Sem dependencia de GPU |
252
+
253
+ ---
254
+
255
+ ## Integracao com Claude Code
256
+
257
+ O Claude Code se conecta ao `mcp-rag-server` via **stdio** (protocolo MCP). O servidor e iniciado como subprocesso quando o Claude Code carrega:
258
+
259
+ ```
260
+ claude (processo principal)
261
+ └── mcp-rag-server (subprocesso, stdio)
262
+ ├── carrega BAAI/bge-m3 em memoria (~570MB)
263
+ └── mantem conexao HTTP com ChromaDB
264
+ ```
265
+
266
+ A comunicacao e JSON-RPC sobre stdin/stdout. O Claude envia uma chamada de ferramenta e recebe o resultado formatado de volta — tudo sem expor portas ou APIs externas.
267
+
268
+ ---
269
+
270
+ ## Migracao do modelo antigo
271
+
272
+ Ao trocar de modelo, a colecao ChromaDB precisa ser recriada — as dimensoes sao incompativeis (384D vs 1024D). O procedimento:
273
+
274
+ ```bash
275
+ # 1. Deletar a colecao antiga
276
+ python3 -c "
277
+ import chromadb
278
+ c = chromadb.HttpClient(host='localhost', port=8000)
279
+ c.delete_collection('codebase')
280
+ print('Colecao deletada')
281
+ "
282
+
283
+ # 2. Reindexar o projeto com o novo modelo
284
+ python3 indexer_full.py /caminho/do/projeto
285
+ ```
package/package.json ADDED
@@ -0,0 +1,49 @@
1
+ {
2
+ "name": "own-rag-cli",
3
+ "version": "0.0.1-snapshot",
4
+ "description": "Local RAG setup with ChromaDB + MCP server (Jina/BGE hybrid support).",
5
+ "license": "MIT",
6
+ "private": false,
7
+ "repository": {
8
+ "type": "git",
9
+ "url": "https://github.com/JocsaPB/own-rag.git"
10
+ },
11
+ "bugs": {
12
+ "url": "https://github.com/JocsaPB/own-rag/issues"
13
+ },
14
+ "homepage": "https://github.com/JocsaPB/own-rag#readme",
15
+ "keywords": [
16
+ "rag",
17
+ "mcp",
18
+ "chromadb",
19
+ "embeddings",
20
+ "claude",
21
+ "cursor"
22
+ ],
23
+ "bin": {
24
+ "rag": "./bin/rag-wrapper.sh"
25
+ },
26
+ "scripts": {
27
+ "postinstall": "bash ./bin/postinstall.sh"
28
+ },
29
+ "files": [
30
+ "README.md",
31
+ "MCP_USAGE.md",
32
+ "how-its-work.md",
33
+ "chroma_monitor.sh",
34
+ "rag-setup.run",
35
+ "rag-setup-macos.run",
36
+ "bin/docker-compose.yml",
37
+ "bin/requirements.txt",
38
+ "bin/rag-wrapper.sh",
39
+ "bin/rag-remove.sh",
40
+ "bin/postinstall.sh",
41
+ "bin/indexer_full.py",
42
+ "bin/mcp_server.py",
43
+ "bin/download_model_from_hugginface.py",
44
+ "bin/download_model_from_modelscope.py"
45
+ ],
46
+ "engines": {
47
+ "node": ">=18"
48
+ }
49
+ }