n2-qln 3.4.0 โ†’ 3.4.2

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.
package/README.ko.md CHANGED
@@ -1,470 +1,470 @@
1
- ๐Ÿ‡บ๐Ÿ‡ธ [English](README.md)
2
-
3
- # n2-qln
4
-
5
- [![npm](https://img.shields.io/npm/v/n2-qln?color=brightgreen)](https://www.npmjs.com/package/n2-qln) [![license](https://img.shields.io/npm/l/n2-qln)](LICENSE) [![node](https://img.shields.io/node/v/n2-qln?color=brightgreen)](https://nodejs.org) [![downloads](https://img.shields.io/npm/dm/n2-qln?color=blue)](https://www.npmjs.com/package/n2-qln)
6
-
7
- **QLN** = **Q**uery **L**ayer **N**etwork โ€” AI์™€ ๋„๊ตฌ ์‚ฌ์ด์— ์œ„์น˜ํ•˜๋Š” ์‹œ๋งจํ‹ฑ ๊ฒ€์ƒ‰ ๋ ˆ์ด์–ด.
8
-
9
- > **1,000๊ฐœ ์ด์ƒ์˜ ๋„๊ตฌ๋ฅผ 1๊ฐœ์˜ MCP ๋„๊ตฌ๋กœ ๋ผ์šฐํŒ…ํ•ฉ๋‹ˆ๋‹ค.** AI๋Š” ๋ผ์šฐํ„ฐ ํ•˜๋‚˜๋งŒ ๋ด…๋‹ˆ๋‹ค โ€” 1,000๊ฐœ ์ „์ฒด๊ฐ€ ์•„๋‹™๋‹ˆ๋‹ค.
10
-
11
- ![QLN Architecture โ€” Without vs With](docs/architecture.png)
12
-
13
- ## ๋ชฉ์ฐจ
14
-
15
- - [๊ธฐ๋Šฅ](#๊ธฐ๋Šฅ)
16
- - [๋ฌธ์ œ์ ](#๋ฌธ์ œ์ )
17
- - [์„ค์น˜](#์„ค์น˜)
18
- - [์„ค์ •](#์„ค์ •)
19
- - [์ž‘๋™ ๋ฐฉ์‹](#์ž‘๋™-๋ฐฉ์‹)
20
- - [API ๋ ˆํผ๋Ÿฐ์Šค](#api-๋ ˆํผ๋Ÿฐ์Šค)
21
- - [์„ค์ • ํŒŒ์ผ](#์„ค์ •-ํŒŒ์ผ)
22
- - [์‹œ๋งจํ‹ฑ ๊ฒ€์ƒ‰ ์„ค์ •](#์‹œ๋งจํ‹ฑ-๊ฒ€์ƒ‰-์„ค์ •-์„ ํƒ์‚ฌํ•ญ)
23
- - [ํ”„๋กœ์ ํŠธ ๊ตฌ์กฐ](#ํ”„๋กœ์ ํŠธ-๊ตฌ์กฐ)
24
- - [์‹ค์ „ ๊ฒ€์ฆ ์™„๋ฃŒ](#์‹ค์ „-๊ฒ€์ฆ-์™„๋ฃŒ)
25
- - [FAQ](#faq)
26
- - [๊ธฐ์—ฌํ•˜๊ธฐ](#๊ธฐ์—ฌํ•˜๊ธฐ)
27
-
28
- ## ๊ธฐ๋Šฅ
29
-
30
- ๐Ÿ” **ํ•˜๋‚˜์˜ ๋„๊ตฌ๋กœ ๋ชจ๋“  ๊ฒƒ์„** โ€” AI๋Š” `n2_qln_call` (~200 ํ† ํฐ)๋งŒ ๋ด…๋‹ˆ๋‹ค. 1,000๊ฐœ์˜ ๊ฐœ๋ณ„ ๋„๊ตฌ๊ฐ€ ์•„๋‹™๋‹ˆ๋‹ค. 99.6% ์ปจํ…์ŠคํŠธ ์ ˆ๊ฐ.
31
-
32
- โšก **5ms ์ดํ•˜ ๊ฒ€์ƒ‰** โ€” 3๋‹จ๊ณ„ ๊ฒ€์ƒ‰ ์—”์ง„ (ํŠธ๋ฆฌ๊ฑฐ + BM25 ํ‚ค์›Œ๋“œ + ์‹œ๋งจํ‹ฑ)์ด 1,000๊ฐœ ์ด์ƒ์˜ ๋„๊ตฌ์—์„œ๋„ 5ms ์ด๋‚ด์— ์ตœ์  ๋„๊ตฌ๋ฅผ ์ฐพ์Šต๋‹ˆ๋‹ค.
33
-
34
- ๐ŸŽฏ **BM25 ํ‚ค์›Œ๋“œ ๋žญํ‚น** *(v3.4)* โ€” Stage 2์— [Okapi BM25](https://en.wikipedia.org/wiki/Okapi_BM25) ์•Œ๊ณ ๋ฆฌ์ฆ˜ ์ ์šฉ. ํฌ๊ท€ํ•œ ๋‹จ์–ด์ผ์ˆ˜๋ก ๋†’์€ ์ ์ˆ˜, ๋ฌธ์„œ ๊ธธ์ด ์ •๊ทœํ™”. Google, Elasticsearch, Wikipedia ๊ฒ€์ƒ‰์˜ ํ•ต์‹ฌ ์•Œ๊ณ ๋ฆฌ์ฆ˜.
35
-
36
- ๐Ÿ“ˆ **์ž๋™ ํ•™์Šต ๋žญํ‚น** โ€” ๋งŽ์ด ์‚ฌ์šฉ๋˜๊ณ  ์„ฑ๊ณต๋ฅ ์ด ๋†’์€ ๋„๊ตฌ๋Š” ์ž๋™์œผ๋กœ ์ƒ์œ„์— ๋žญํฌ๋ฉ๋‹ˆ๋‹ค. ์ˆ˜๋™ ํŠœ๋‹ ๋ถˆํ•„์š”.
37
-
38
- ๐Ÿ”„ **๋Ÿฐํƒ€์ž„ ๋™์  ๊ด€๋ฆฌ** โ€” ์„œ๋ฒ„ ์žฌ์‹œ์ž‘ ์—†์ด ๋„๊ตฌ๋ฅผ ์ถ”๊ฐ€, ์ˆ˜์ •, ์‚ญ์ œํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. Provider ๋‹จ์œ„ ์ผ๊ด„ ๊ด€๋ฆฌ ์ง€์›.
39
-
40
- ๐Ÿ›ก๏ธ **๊ฐ•์ œ ํ’ˆ์งˆ ๊ฒ€์ฆ** โ€” ๋„๊ตฌ ๋“ฑ๋ก ์‹œ ์—„๊ฒฉํ•œ ๊ฒ€์ฆ: `verb_target` ๋„ค์ด๋ฐ, ์ตœ์†Œ ์„ค๋ช… ๊ธธ์ด, ์นดํ…Œ๊ณ ๋ฆฌ ์ œ์•ฝ. ์ž˜๋ชป๋œ ๋„๊ตฌ๋Š” ๊ฑฐ๋ถ€๋ฉ๋‹ˆ๋‹ค.
41
-
42
- ๐Ÿง  **์‹œ๋งจํ‹ฑ ๊ฒ€์ƒ‰ (์„ ํƒ)** โ€” [Ollama](https://ollama.ai) ์ถ”๊ฐ€ ์‹œ ๋ฒกํ„ฐ ์œ ์‚ฌ๋„ ๊ฒ€์ƒ‰ ํ™œ์„ฑํ™”. ์—†์–ด๋„ Stage 1 + 2๋งŒ์œผ๋กœ ์ถฉ๋ถ„ํ•œ ๊ฒฐ๊ณผ. Ollama๊ฐ€ ๋‹ค์šด๋˜์–ด๋„ ๊ฒ€์ƒ‰์€ ์ •์ƒ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค.
43
-
44
- ๐Ÿ“ฆ **๋„ค์ดํ‹ฐ๋ธŒ ์˜์กด์„ฑ ์ œ๋กœ** โ€” [sql.js](https://github.com/sql-js/sql.js) (WASM) ๊ธฐ๋ฐ˜. `node-gyp` ๋นŒ๋“œ ์—†์Œ, ํ”Œ๋žซํผ๋ณ„ ๋ฐ”์ด๋„ˆ๋ฆฌ ์—†์Œ. `npm install`์ด๋ฉด ๋.
45
-
46
- ๐Ÿ”Œ **์ด์ค‘ ์‹คํ–‰** โ€” ๋„๊ตฌ๋ฅผ ๋กœ์ปฌ ํ•จ์ˆ˜ ๋˜๋Š” HTTP ์—”๋“œํฌ์ธํŠธ๋กœ ์‹คํ–‰. ํ•ธ๋“ค๋Ÿฌ๋ฅผ ์ง์ ‘ ๋“ฑ๋กํ•˜๊ฑฐ๋‚˜ ์›๊ฒฉ ์„œ๋น„์Šค๋ฅผ ์—ฐ๊ฒฐ. ํ˜ผํ•ฉ๋„ ๊ฐ€๋Šฅ.
47
-
48
- ๐Ÿ“‹ **Provider ์ž๋™ ์ธ๋ฑ์‹ฑ** *(v3.3)* โ€” `providers/`์— JSON ๋งค๋‹ˆํŽ˜์ŠคํŠธ๋ฅผ ๋„ฃ์œผ๋ฉด ๋ถ€ํŒ… ์‹œ ์ž๋™ ๋“ฑ๋ก. ์ฝ”๋“œ ์ˆ˜์ • ๋ถˆํ•„์š”, ์ˆ˜๋™ `create` ํ˜ธ์ถœ ๋ถˆํ•„์š”. ๋ฉฑ๋“ฑ์„ฑ ๋ณด์žฅ ๋ฐ ์—๋Ÿฌ ๊ฒฉ๋ฆฌ.
49
-
50
- ๐Ÿ—๏ธ **10,000๊ฐœ ์ด์ƒ ํ™•์žฅ** โ€” ์นดํ…Œ๊ณ ๋ฆฌ๋ณ„ centroid hierarchy ํŒŒํ‹ฐ์…”๋‹. 100๊ฐœ ~1ms, 1,000๊ฐœ ~3ms, 10,000๊ฐœ ~5ms.
51
-
52
- ๐ŸŒ **๋ฒ”์šฉ MCP** โ€” Claude Desktop, Cursor, n2-soul ๋˜๋Š” ๋ชจ๋“  MCP ํ˜ธํ™˜ ํด๋ผ์ด์–ธํŠธ์—์„œ ๋™์ž‘. ํ‘œ์ค€ stdio ์ „์†ก.
53
-
54
- ## ๋ฌธ์ œ์ 
55
-
56
- MCP ๋„๊ตฌ๋ฅผ ๋“ฑ๋กํ•  ๋•Œ๋งˆ๋‹ค AI ์ปจํ…์ŠคํŠธ ํ† ํฐ์„ ์†Œ๋ชจํ•ฉ๋‹ˆ๋‹ค. 10๊ฐœ๋Š” ๊ดœ์ฐฎ์Šต๋‹ˆ๋‹ค. 100๊ฐœ๋ฉด ๋А๋ ค์ง‘๋‹ˆ๋‹ค. **1,000๊ฐœ๋ฉด ๋ถˆ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค** โ€” ๋Œ€ํ™”๊ฐ€ ์‹œ์ž‘๋˜๊ธฐ๋„ ์ „์— ์ปจํ…์ŠคํŠธ ์œˆ๋„์šฐ๊ฐ€ ๊ฐ€๋“ ์ฐน๋‹ˆ๋‹ค.
57
-
58
- QLN์€ **์‹œ๋งจํ‹ฑ ๊ฒ€์ƒ‰ ๋ผ์šฐํ„ฐ**๋กœ ์ด ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•ฉ๋‹ˆ๋‹ค:
59
-
60
- 1. ๋ชจ๋“  ๋„๊ตฌ๋ฅผ QLN์˜ SQLite ์ธ๋ฑ์Šค์— ๋“ฑ๋ก
61
- 2. AI๋Š” **ํ•˜๋‚˜์˜ ๋„๊ตฌ**๋งŒ ๋ด…๋‹ˆ๋‹ค: `n2_qln_call` (~200 ํ† ํฐ)
62
- 3. AI๊ฐ€ ๋„๊ตฌ๊ฐ€ ํ•„์š”ํ•˜๋ฉด **๊ฒ€์ƒ‰** โ†’ **์ตœ์  ๋งค์นญ** โ†’ **์‹คํ–‰**
63
-
64
- **๊ฒฐ๊ณผ: ~50,000 ํ† ํฐ ๋Œ€์‹  ~200 ํ† ํฐ. 99.6% ์ ˆ๊ฐ.**
65
-
66
- ---
67
-
68
- ## ์„ค์น˜
69
-
70
- ```bash
71
- npm install n2-qln
72
- ```
73
-
74
- **์š”๊ตฌ์‚ฌํ•ญ:** Node.js โ‰ฅ 18
75
-
76
- **์„ ํƒ์‚ฌํ•ญ:** ์‹œ๋งจํ‹ฑ ๋ฒกํ„ฐ ๊ฒ€์ƒ‰(Stage 3)์„ ์œ„ํ•ด [Ollama](https://ollama.ai) ์„ค์น˜. [์‹œ๋งจํ‹ฑ ๊ฒ€์ƒ‰ ์„ค์ •](#์‹œ๋งจํ‹ฑ-๊ฒ€์ƒ‰-์„ค์ •-์„ ํƒ์‚ฌํ•ญ) ์ฐธ์กฐ.
77
-
78
- ---
79
-
80
- ## ์„ค์ •
81
-
82
- QLN์€ MCP ์„œ๋ฒ„์ž…๋‹ˆ๋‹ค. ๋ชจ๋“  MCP ํ˜ธํ™˜ AI ํด๋ผ์ด์–ธํŠธ์— ์—ฐ๊ฒฐํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
83
-
84
- ### Claude Desktop
85
-
86
- Claude Desktop ์„ค์ • ํŒŒ์ผ์„ ํŽธ์ง‘ํ•ฉ๋‹ˆ๋‹ค:
87
-
88
- - **macOS:** `~/Library/Application Support/Claude/claude_desktop_config.json`
89
- - **Windows:** `%APPDATA%\Claude\claude_desktop_config.json`
90
-
91
- ```json
92
- {
93
- "mcpServers": {
94
- "n2-qln": {
95
- "command": "npx",
96
- "args": ["-y", "n2-qln"]
97
- }
98
- }
99
- }
100
- ```
101
-
102
- Claude Desktop์„ ์žฌ์‹œ์ž‘ํ•˜๋ฉด `n2_qln_call` ๋„๊ตฌ๊ฐ€ ๋ชฉ๋ก์— ๋‚˜ํƒ€๋‚ฉ๋‹ˆ๋‹ค.
103
-
104
- ### Cursor
105
-
106
- **Settings โ†’ MCP Servers โ†’ Add Server**์—์„œ ์„ค์ •:
107
-
108
- ```json
109
- {
110
- "name": "n2-qln",
111
- "command": "npx",
112
- "args": ["-y", "n2-qln"]
113
- }
114
- ```
115
-
116
- ### n2-soul
117
-
118
- Soul `config.local.js`์— ์ถ”๊ฐ€:
119
-
120
- ```javascript
121
- module.exports = {
122
- mcpServers: {
123
- 'n2-qln': {
124
- command: 'node',
125
- args: ['<path-to-qln>/index.js'],
126
- }
127
- }
128
- };
129
- ```
130
-
131
- npm์œผ๋กœ ์„ค์น˜ํ•œ ๊ฒฝ์šฐ:
132
-
133
- ```javascript
134
- module.exports = {
135
- mcpServers: {
136
- 'n2-qln': {
137
- command: 'npx',
138
- args: ['-y', 'n2-qln'],
139
- }
140
- }
141
- };
142
- ```
143
-
144
- ### ๊ธฐํƒ€ MCP ํด๋ผ์ด์–ธํŠธ
145
-
146
- QLN์€ **stdio ์ „์†ก** โ€” ํ‘œ์ค€ MCP ํ†ต์‹  ๋ฐฉ์‹์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ๋ชจ๋“  MCP ํ˜ธํ™˜ ํด๋ผ์ด์–ธํŠธ์—์„œ ์—ฐ๊ฒฐ ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค:
147
-
148
- ```
149
- command: npx
150
- args: ["-y", "n2-qln"]
151
- ```
152
-
153
- ์†Œ์Šค๋ฅผ ํด๋ก ํ•œ ๊ฒฝ์šฐ:
154
-
155
- ```
156
- command: node
157
- args: ["/absolute/path/to/n2-qln/index.js"]
158
- ```
159
-
160
- > **๐Ÿ’ก ํŒ:** ๊ฐ€์žฅ ์‰ฌ์šด ์„ค์ • ๋ฐฉ๋ฒ•? **๊ทธ๋ƒฅ AI ์—์ด์ „ํŠธ์—๊ฒŒ ๋ถ€ํƒํ•˜์„ธ์š”.** *"n2-qln์„ ๋‚ด MCP ์„ค์ •์— ์ถ”๊ฐ€ํ•ด์ค˜"* โ€” ์—์ด์ „ํŠธ๊ฐ€ ์•Œ์•„์„œ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค.
161
-
162
- ---
163
-
164
- ## ์ž‘๋™ ๋ฐฉ์‹
165
-
166
- ### ๋‹จ๊ณ„๋ณ„ ์˜ˆ์‹œ
167
-
168
- ```
169
- ์‚ฌ์šฉ์ž: "์ด ํŽ˜์ด์ง€ ์Šคํฌ๋ฆฐ์ƒท ์ฐ์–ด"
170
-
171
- Step 1 โ†’ AI ํ˜ธ์ถœ: n2_qln_call(action: "search", query: "screenshot page")
172
- QLN์ด 1,000๊ฐœ ์ด์ƒ์˜ ๋„๊ตฌ๋ฅผ <5ms์— ๊ฒ€์ƒ‰
173
- ์‘๋‹ต: take_screenshot (score: 8.0)
174
-
175
- Step 2 โ†’ AI ํ˜ธ์ถœ: n2_qln_call(action: "exec", tool: "take_screenshot", args: {fullPage: true})
176
- QLN์ด ์‹ค์ œ ๋„๊ตฌ๋กœ ๋ผ์šฐํŒ… ๋ฐ ์‹คํ–‰
177
- ์‘๋‹ต: โœ… ์Šคํฌ๋ฆฐ์ƒท ์ €์žฅ๋จ
178
- ```
179
-
180
- AI๋Š” `n2_qln_call`๋งŒ ์‚ฌ์šฉํ–ˆ์Šต๋‹ˆ๋‹ค. ๋‚˜๋จธ์ง€ 999๊ฐœ ๋„๊ตฌ๋Š” ์ „ํ˜€ ๋ณด์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค.
181
-
182
- ### 3๋‹จ๊ณ„ ๊ฒ€์ƒ‰ ์—”์ง„
183
-
184
- QLN์€ ์„ธ ๋‹จ๊ณ„์˜ ๊ฒ€์ƒ‰์œผ๋กœ ์ ํ•ฉํ•œ ๋„๊ตฌ๋ฅผ ์ฐพ์Šต๋‹ˆ๋‹ค:
185
-
186
- | ๋‹จ๊ณ„ | ๋ฐฉ์‹ | ์†๋„ | ์ž‘๋™ ์›๋ฆฌ |
187
- |:---:|--------|:---:|---------|
188
- | **1** | ํŠธ๋ฆฌ๊ฑฐ ๋งค์นญ | โšก <1ms | ๋„๊ตฌ ์ด๋ฆ„๊ณผ ํŠธ๋ฆฌ๊ฑฐ ํ‚ค์›Œ๋“œ ์ •ํ™• ๋งค์นญ |
189
- | **2** | BM25 ํ‚ค์›Œ๋“œ | โšก 1-3ms | [Okapi BM25](https://en.wikipedia.org/wiki/Okapi_BM25) ๋žญํ‚น ๊ฒ€์ƒ‰ โ€” IDF ๊ฐ€์ค‘์น˜ + ๋ฌธ์„œ ๊ธธ์ด ์ •๊ทœํ™” *(v3.4)* |
190
- | **3** | ์‹œ๋งจํ‹ฑ ๊ฒ€์ƒ‰ | ๐Ÿง  5-15ms | ์ž„๋ฒ ๋”ฉ ๋ฒกํ„ฐ ์œ ์‚ฌ๋„ ๊ฒ€์ƒ‰ *(์„ ํƒ, Ollama ํ•„์š”)* |
191
-
192
- ๋ชจ๋“  ๋‹จ๊ณ„์˜ ๊ฒฐ๊ณผ๋ฅผ ๋ณ‘ํ•ฉ ํ›„ ๋žญํ‚น:
193
-
194
- ```
195
- final_score = trigger_score ร— 3.0
196
- + bm25_keyword_score ร— 1.0
197
- + semantic_score ร— 2.0
198
- + log2(usage_count + 1) ร— 0.5
199
- + success_rate ร— 1.0
200
- ```
201
-
202
- ๋งŽ์ด ์‚ฌ์šฉ๋˜๊ณ  ์„ฑ๊ณต๋ฅ ์ด ๋†’์€ ๋„๊ตฌ๊ฐ€ ์‹œ๊ฐ„์ด ์ง€๋‚ ์ˆ˜๋ก ์ƒ์œ„์— ๋žญํฌ๋ฉ๋‹ˆ๋‹ค.
203
-
204
- ---
205
-
206
- ## API ๋ ˆํผ๋Ÿฐ์Šค
207
-
208
- QLN์€ **ํ•˜๋‚˜์˜ MCP ๋„๊ตฌ** โ€” `n2_qln_call` โ€” 5๊ฐœ์˜ ์•ก์…˜์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.
209
-
210
- ### search โ€” ์ž์—ฐ์–ด๋กœ ๋„๊ตฌ ๊ฒ€์ƒ‰
211
-
212
- ```javascript
213
- n2_qln_call({
214
- action: "search",
215
- query: "take a screenshot", // ์ž์—ฐ์–ด ์ฟผ๋ฆฌ (ํ•„์ˆ˜)
216
- category: "capture", // ์นดํ…Œ๊ณ ๋ฆฌ ํ•„ํ„ฐ (์„ ํƒ)
217
- topK: 5 // ์ตœ๋Œ€ ๊ฒฐ๊ณผ ์ˆ˜, ๊ธฐ๋ณธ: 5 (์„ ํƒ)
218
- })
219
- ```
220
-
221
- ### exec โ€” ์ด๋ฆ„์œผ๋กœ ๋„๊ตฌ ์‹คํ–‰
222
-
223
- ```javascript
224
- n2_qln_call({
225
- action: "exec",
226
- tool: "take_screenshot", // ๋„๊ตฌ ์ด๋ฆ„ (ํ•„์ˆ˜)
227
- args: { // ๋„๊ตฌ ์ธ์ˆ˜ (์„ ํƒ)
228
- fullPage: true,
229
- format: "png"
230
- }
231
- })
232
- ```
233
-
234
- ### create โ€” ์ƒˆ ๋„๊ตฌ ๋“ฑ๋ก
235
-
236
- ```javascript
237
- n2_qln_call({
238
- action: "create",
239
- name: "read_pdf", // ํ•„์ˆ˜, verb_target ํ˜•์‹
240
- description: "Read and extract text from PDF files", // ํ•„์ˆ˜, ์ตœ์†Œ 10์ž
241
- category: "data", // ํ•„์ˆ˜, ์•„๋ž˜ ์นดํ…Œ๊ณ ๋ฆฌ ์ฐธ์กฐ
242
- provider: "pdf-tools", // ์„ ํƒ, ์†Œ์Šค๋ณ„ ๋„๊ตฌ ๊ทธ๋ฃนํ™”
243
- tags: ["pdf", "read", "extract", "document"], // ์„ ํƒ, ๊ฒ€์ƒ‰ ๊ฐœ์„ 
244
- examples: [ // ์„ ํƒ, ํ‚ค์›Œ๋“œ ๊ฒ€์ƒ‰์— ์ƒ‰์ธ
245
- "read this PDF file",
246
- "extract text from PDF",
247
- "open the PDF"
248
- ],
249
- endpoint: "http://127.0.0.1:3100", // ์„ ํƒ, HTTP ๊ธฐ๋ฐ˜ ๋„๊ตฌ์šฉ
250
- toolSchema: { filePath: { type: "string" } } // ์„ ํƒ, ์ž…๋ ฅ ์Šคํ‚ค๋งˆ
251
- })
252
- ```
253
-
254
- **๊ฒ€์ฆ ๊ทœ์น™ (๊ฐ•์ œ โ€” ์œ„๋ฐ˜ ์‹œ ๊ฑฐ๋ถ€):**
255
-
256
- | ๊ทœ์น™ | ์š”๊ตฌ์‚ฌํ•ญ | ์˜ˆ์‹œ |
257
- |------|---------|------|
258
- | **์ด๋ฆ„** | `verb_target` ํ˜•์‹ (์†Œ๋ฌธ์ž + ๋ฐ‘์ค„) | `read_pdf`, `take_screenshot` |
259
- | **์„ค๋ช…** | ์ตœ์†Œ 10์ž | `"Read and extract text from PDF files"` |
260
- | **์นดํ…Œ๊ณ ๋ฆฌ** | ์œ ํšจํ•œ ์นดํ…Œ๊ณ ๋ฆฌ ์ค‘ ํ•˜๋‚˜ | `"data"` |
261
- | **๊ณ ์œ ์„ฑ** | ์ค‘๋ณต ์ด๋ฆ„ ๋ถˆ๊ฐ€ | โ€” |
262
-
263
- **์œ ํšจ ์นดํ…Œ๊ณ ๋ฆฌ:** `web` ยท `data` ยท `file` ยท `dev` ยท `ai` ยท `capture` ยท `misc`
264
-
265
- ### update โ€” ๊ธฐ์กด ๋„๊ตฌ ์ˆ˜์ •
266
-
267
- ```javascript
268
- n2_qln_call({
269
- action: "update",
270
- tool: "read_pdf", // ์ˆ˜์ •ํ•  ๋„๊ตฌ (ํ•„์ˆ˜)
271
- description: "Enhanced PDF text extractor", // ๋ณ€๊ฒฝํ•  ํ•„๋“œ๋งŒ ์ œ๊ณต
272
- examples: ["read this PDF", "parse PDF"],
273
- tags: ["pdf", "read", "parse"]
274
- })
275
- ```
276
-
277
- ๋ณ€๊ฒฝ๋œ ํ•„๋“œ๋งŒ ์ œ๊ณตํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค. ๋ฏธ๋ณ€๊ฒฝ ํ•„๋“œ๋Š” ๊ธฐ์กด ๊ฐ’ ์œ ์ง€. ๋™์ผํ•œ ๊ฒ€์ฆ ๊ทœ์น™ ์ ์šฉ.
278
-
279
- ### delete โ€” ๋„๊ตฌ ์‚ญ์ œ
280
-
281
- ```javascript
282
- // ์ด๋ฆ„์œผ๋กœ ๋‹จ์ผ ๋„๊ตฌ ์‚ญ์ œ
283
- n2_qln_call({
284
- action: "delete",
285
- tool: "read_pdf"
286
- })
287
-
288
- // Provider์˜ ๋ชจ๋“  ๋„๊ตฌ ์ผ๊ด„ ์‚ญ์ œ
289
- n2_qln_call({
290
- action: "delete",
291
- provider: "pdf-tools"
292
- })
293
- // โ†’ โœ… Deleted 3 tools from provider: pdf-tools
294
- ```
295
-
296
- ---
297
-
298
- ## ์„ค์ • ํŒŒ์ผ
299
-
300
- QLN์€ ์„ค์ • ์—†์ด ๋ฐ”๋กœ ๋™์ž‘ํ•ฉ๋‹ˆ๋‹ค. ์ปค์Šคํ„ฐ๋งˆ์ด์ฆˆํ•˜๋ ค๋ฉด QLN ๋””๋ ‰ํ† ๋ฆฌ์— `config.local.js`๋ฅผ ์ƒ์„ฑํ•˜์„ธ์š”:
301
-
302
- ```javascript
303
- module.exports = {
304
- dataDir: './data', // SQLite DB ์ €์žฅ ์œ„์น˜
305
- embedding: {
306
- enabled: true, // Stage 3 ์‹œ๋งจํ‹ฑ ๊ฒ€์ƒ‰ ํ™œ์„ฑํ™”
307
- provider: 'ollama',
308
- model: 'nomic-embed-text',
309
- baseUrl: 'http://127.0.0.1:11434',
310
- },
311
- };
312
- ```
313
-
314
- > **์ฐธ๊ณ :** `config.local.js`๋Š” gitignore ์ฒ˜๋ฆฌ๋ฉ๋‹ˆ๋‹ค. ๋กœ์ปฌ ์„ค์ •์€ ์ปค๋ฐ‹๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
315
-
316
- ---
317
-
318
- ## ์‹œ๋งจํ‹ฑ ๊ฒ€์ƒ‰ ์„ค์ • (์„ ํƒ์‚ฌํ•ญ)
319
-
320
- Ollama ์—†์ด๋„ QLN์€ Stage 1 (ํŠธ๋ฆฌ๊ฑฐ) + Stage 2 (ํ‚ค์›Œ๋“œ) ๋งค์นญ์„ ์‚ฌ์šฉํ•˜๋ฉฐ, ๋Œ€๋ถ€๋ถ„์˜ ๊ฒฝ์šฐ ์ถฉ๋ถ„ํ•œ ๊ฒฐ๊ณผ๋ฅผ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.
321
-
322
- ์ตœ๋Œ€ ์ •ํ™•๋„๋ฅผ ์›ํ•œ๋‹ค๋ฉด ์‹œ๋งจํ‹ฑ ๋ฒกํ„ฐ ๊ฒ€์ƒ‰(Stage 3)์„ ์ถ”๊ฐ€ํ•˜์„ธ์š”:
323
-
324
- ### 1. Ollama ์„ค์น˜
325
-
326
- [ollama.ai](https://ollama.ai)์—์„œ ๋‹ค์šด๋กœ๋“œ ํ›„ ์„ค์น˜.
327
-
328
- ### 2. ์ž„๋ฒ ๋”ฉ ๋ชจ๋ธ ๋‹ค์šด๋กœ๋“œ
329
-
330
- ```bash
331
- ollama pull nomic-embed-text
332
- ```
333
-
334
- ### 3. ์„ค์ • ํ™œ์„ฑํ™”
335
-
336
- `config.local.js` ์ƒ์„ฑ:
337
-
338
- ```javascript
339
- module.exports = {
340
- embedding: {
341
- enabled: true,
342
- provider: 'ollama',
343
- model: 'nomic-embed-text',
344
- baseUrl: 'http://127.0.0.1:11434',
345
- },
346
- };
347
- ```
348
-
349
- ### ๋น„๊ต
350
-
351
- | ์„ค์ • | ๊ฒ€์ƒ‰ ๋‹จ๊ณ„ | ์ •ํ™•๋„ | ์˜์กด์„ฑ |
352
- |:------|:---:|:---:|:---:|
353
- | **๊ธฐ๋ณธ** (Ollama ์—†์Œ) | Stage 1 + 2 | โญโญโญโญ ํ›Œ๋ฅญ | ์—†์Œ |
354
- | **Ollama ํฌํ•จ** | Stage 1 + 2 + 3 | โญโญโญโญโญ ์™„๋ฒฝ | Ollama ์‹คํ–‰ ํ•„์š” |
355
-
356
- ### ๋‹ค๊ตญ์–ด ์‚ฌ์šฉ์ž
357
-
358
- `nomic-embed-text`๋Š” ์˜์–ด์— ์ตœ์ ํ™”๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค. **ํ•œ๊ตญ์–ด, ์ผ๋ณธ์–ด, ์ค‘๊ตญ์–ด** ๋“ฑ ๋‹ค๋ฅธ ์–ธ์–ด๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค๋ฉด ๋‹ค๊ตญ์–ด ๋ชจ๋ธ๋กœ ๊ต์ฒดํ•˜์„ธ์š”:
359
-
360
- ```bash
361
- ollama pull bge-m3
362
- ```
363
-
364
- ```javascript
365
- // config.local.js
366
- module.exports = {
367
- embedding: {
368
- enabled: true,
369
- model: 'bge-m3', // ๋‹ค๊ตญ์–ด ์ง€์› (100๊ฐœ ์ด์ƒ ์–ธ์–ด)
370
- },
371
- };
372
- ```
373
-
374
- ์ฝ”๋“œ ์ˆ˜์ • ์—†์ด config์˜ ๋ชจ๋ธ๋ช…๋งŒ ๋ฐ”๊พธ๋ฉด ๋ฉ๋‹ˆ๋‹ค.
375
-
376
- ### ํด๋ผ์šฐ๋“œ ๋™๊ธฐํ™”
377
-
378
- ๋„๊ตฌ ์ธ๋ฑ์Šค๋ฅผ ์—ฌ๋Ÿฌ ๊ธฐ๊ธฐ์—์„œ ๋™๊ธฐํ™”ํ•˜๊ณ  ์‹ถ๋‹ค๋ฉด `dataDir`์„ ํด๋ผ์šฐ๋“œ ํด๋”๋กœ ์ง€์ •ํ•˜์„ธ์š”:
379
-
380
- ```javascript
381
- // config.local.js
382
- module.exports = {
383
- dataDir: 'G:/My Drive/n2-qln', // Google Drive, OneDrive, Dropbox, NAS...
384
- };
385
- ```
386
-
387
- [n2-soul ํด๋ผ์šฐ๋“œ ์Šคํ† ๋ฆฌ์ง€](https://github.com/choihyunsus/soul#%EF%B8%8F-cloud-storage--store-your-ai-memory-anywhere)์™€ ๋™์ผํ•œ ๋ฐฉ์‹์ž…๋‹ˆ๋‹ค. SQLite ํŒŒ์ผ์ด ํ•ด๋‹น ํด๋”์— ์ €์žฅ๋˜๊ณ , ๋™๊ธฐํ™” ์„œ๋น„์Šค๊ฐ€ ๋‚˜๋จธ์ง€๋ฅผ ์ฒ˜๋ฆฌํ•ฉ๋‹ˆ๋‹ค.
388
-
389
- ---
390
-
391
- ## ํ”„๋กœ์ ํŠธ ๊ตฌ์กฐ
392
-
393
- ```
394
- n2-qln/
395
- โ”œโ”€โ”€ index.js # MCP ์„œ๋ฒ„ ์ง„์ž…์ 
396
- โ”œโ”€โ”€ lib/
397
- โ”‚ โ”œโ”€โ”€ config.js # ์„ค์ • ๋กœ๋” (๊ธฐ๋ณธ + ๋กœ์ปฌ ๋ณ‘ํ•ฉ)
398
- โ”‚ โ”œโ”€โ”€ store.js # SQLite ์Šคํ† ๋ฆฌ์ง€ ์—”์ง„ (sql.js WASM)
399
- โ”‚ โ”œโ”€โ”€ schema.js # ๋„๊ตฌ ์Šคํ‚ค๋งˆ ์ •๊ทœํ™” + ๊ฒ€์ƒ‰ ํ…์ŠคํŠธ ๋นŒ๋”
400
- โ”‚ โ”œโ”€โ”€ validator.js # ๊ฐ•์ œ ๊ฒ€์ฆ (์ด๋ฆ„, ์„ค๋ช…, ์นดํ…Œ๊ณ ๋ฆฌ)
401
- โ”‚ โ”œโ”€โ”€ registry.js # ๋„๊ตฌ CRUD + ์‚ฌ์šฉ๋Ÿ‰ ์ถ”์  + ์ž„๋ฒ ๋”ฉ ์บ์‹œ
402
- โ”‚ โ”œโ”€โ”€ router.js # 3๋‹จ๊ณ„ ๊ฒ€์ƒ‰ ์—”์ง„ (BM25 v3.4)
403
- โ”‚ โ”œโ”€โ”€ vector-index.js # Float32 ๋ฒกํ„ฐ ์ธ๋ฑ์Šค (centroid hierarchy)
404
- โ”‚ โ”œโ”€โ”€ embedding.js # Ollama ์ž„๋ฒ ๋”ฉ ํด๋ผ์ด์–ธํŠธ (nomic-embed-text)
405
- โ”‚ โ”œโ”€โ”€ executor.js # HTTP/ํ•จ์ˆ˜ ๋„๊ตฌ ์‹คํ–‰๊ธฐ
406
- โ”‚ โ””โ”€โ”€ provider-loader.js # ๋ถ€ํŒ… ์‹œ providers/*.json ์ž๋™ ์ธ๋ฑ์‹ฑ
407
- โ”œโ”€โ”€ tools/
408
- โ”‚ โ””โ”€โ”€ qln-call.js # ํ†ตํ•ฉ MCP ๋„๊ตฌ (search/exec/create/update/delete)
409
- โ”œโ”€โ”€ providers/ # ๋„๊ตฌ provider ๋งค๋‹ˆํŽ˜์ŠคํŠธ (์ผ๊ด„ ๋“ฑ๋ก์šฉ)
410
- โ”œโ”€โ”€ config.local.js # ๋กœ์ปฌ ์„ค์ • ์˜ค๋ฒ„๋ผ์ด๋“œ (gitignored)
411
- โ””โ”€โ”€ data/ # SQLite ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค (gitignored, ์ž๋™ ์ƒ์„ฑ)
412
- ```
413
-
414
- ## ๊ธฐ์ˆ  ์Šคํƒ
415
-
416
- | ์ปดํฌ๋„ŒํŠธ | ๊ธฐ์ˆ  | ์ด์œ  |
417
- |-----------|-----------|------|
418
- | ๋Ÿฐํƒ€์ž„ | Node.js โ‰ฅ 18 | MCP SDK ํ˜ธํ™˜์„ฑ |
419
- | ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค | SQLite via [sql.js](https://github.com/sql-js/sql.js) (WASM) | ๋„ค์ดํ‹ฐ๋ธŒ ์˜์กด์„ฑ ์ œ๋กœ, ํฌ๋กœ์Šค ํ”Œ๋žซํผ, ๋นŒ๋“œ ๋ถˆํ•„์š” |
420
- | ์ž„๋ฒ ๋”ฉ | [Ollama](https://ollama.ai) + nomic-embed-text | ๋กœ์ปฌ, ๋น ๋ฆ„, ๋ฌด๋ฃŒ, ์„ ํƒ์‚ฌํ•ญ |
421
- | ํ”„๋กœํ† ์ฝœ | [MCP](https://modelcontextprotocol.io) (Model Context Protocol) | ํ‘œ์ค€ AI ๋„๊ตฌ ํ”„๋กœํ† ์ฝœ |
422
- | ๊ฒ€์ฆ | [Zod](https://zod.dev) | ๋Ÿฐํƒ€์ž„ ํƒ€์ž… ์•ˆ์ „ ์Šคํ‚ค๋งˆ ๊ฒ€์ฆ |
423
-
424
- ## ๊ด€๋ จ ํ”„๋กœ์ ํŠธ
425
-
426
- | ํ”„๋กœ์ ํŠธ | ๊ด€๊ณ„ |
427
- |---------|------|
428
- | [n2-soul](https://github.com/choihyunsus/soul) | AI ์—์ด์ „ํŠธ ์˜ค์ผ€์ŠคํŠธ๋ ˆ์ดํ„ฐ โ€” QLN์€ Soul์˜ "๋„๊ตฌ ๋ธŒ๋ ˆ์ธ" ์—ญํ•  |
429
-
430
- ## ์‹ค์ „ ๊ฒ€์ฆ ์™„๋ฃŒ
431
-
432
- ์ฃผ๋ง ํ”„๋กœํ† ํƒ€์ž…์ด ์•„๋‹™๋‹ˆ๋‹ค. QLN์€ **2๊ฐœ์›” ์ด์ƒ ์šด์˜ ํ™˜๊ฒฝ์—์„œ ๊ฒ€์ฆ**๋˜์—ˆ์œผ๋ฉฐ, [n2-soul](https://github.com/choihyunsus/soul)์˜ ํ•ต์‹ฌ ๋„๊ตฌ ๋ผ์šฐํ„ฐ๋กœ ๋งค์ผ ์‹ค์‚ฌ์šฉ๋˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.
433
-
434
- **Rose** ๐ŸŒน ์ œ์ž‘ โ€” N2์˜ ์ฒซ ๋ฒˆ์งธ AI ์—์ด์ „ํŠธ. ํ•˜๋ฃจ์— ์ˆ˜๋ฐฑ ๋ฒˆ QLN์„ ํ†ตํ•ด ๋ผ์šฐํŒ…ํ•ฉ๋‹ˆ๋‹ค.
435
-
436
- ๋ฌธ์ œ๊ฐ€ ์žˆ๊ฑฐ๋‚˜ ์•„์ด๋””์–ด๊ฐ€ ์žˆ๋‹ค๋ฉด ์ด์Šˆ๋ฅผ ์—ด์–ด์ฃผ์„ธ์š”. ์—ฌ๋Ÿฌ๋ถ„์˜ ํ™œ์šฉ ์‚ฌ๋ก€๋ฅผ ๋“ฃ๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค.
437
-
438
- ## FAQ
439
-
440
- **"์™œ ํ”„๋กœ์ ํŠธ๋ฅผ ์ด๋ ‡๊ฒŒ ์ž์ฃผ ์˜ฌ๋ฆฌ๋‚˜์š”?"**
441
-
442
- N2 ์ƒํƒœ๊ณ„๋Š” 4๊ฐœ์›” ์ด์ƒ ํ™œ๋ฐœํžˆ ๊ฐœ๋ฐœ๋˜์–ด ์™”์Šต๋‹ˆ๋‹ค. Soul, QLN, Ark โ€” ๋ณด์ด๋Š” ๋ชจ๋“  ํ”„๋กœ์ ํŠธ๋Š” ๊ณต๊ฐœ ์ „์— ์‹ค์ œ ์—…๋ฌด์—์„œ ์ถฉ๋ถ„ํžˆ ํ…Œ์ŠคํŠธ๋˜๊ณ  ๊ฒ€์ฆ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ์•ž์œผ๋กœ ๋” ๋‚˜์˜ฌ ์˜ˆ์ •์ด์ง€๋งŒ, ๋„๋ฐฐ๊ฐ€ ์•„๋‹ˆ๋ผ ์ด๋ฏธ ๋งŒ๋“ค์–ด์ ธ์„œ ๊ฒ€์ฆ ์™„๋ฃŒ๋œ ๊ฒƒ๋“ค์ด ๋งŽ๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค.
443
-
444
- ํ˜ผ์ž์„œ ๊ฐœ๋ฐœํ•˜๊ณ  ๋ฐฐํฌํ•˜๋Š” ํ”„๋กœ์ ํŠธ์ž…๋‹ˆ๋‹ค. ๋นŒ๋“œ, ํ…Œ์ŠคํŠธ, ๋ฌธ์„œํ™”๋ฅผ ํ˜ผ์ž ํ•˜๋‹ค ๋ณด๋‹ˆ ์‹œ๊ฐ„์ด ๋งŽ์ด ๊ฑธ๋ ธ์Šต๋‹ˆ๋‹ค. ๊ด€์‹ฌ๊ณผ ์ธ๋‚ด์— ๊ฐ์‚ฌ๋“œ๋ฆฝ๋‹ˆ๋‹ค ๐Ÿ™
445
-
446
- ## ๊ธฐ์—ฌํ•˜๊ธฐ
447
-
448
- ๊ธฐ์—ฌ๋ฅผ ํ™˜์˜ํ•ฉ๋‹ˆ๋‹ค! ์‹œ์ž‘ํ•˜๋Š” ๋ฐฉ๋ฒ•:
449
-
450
- 1. ์ €์žฅ์†Œ๋ฅผ Forkํ•ฉ๋‹ˆ๋‹ค
451
- 2. ๊ธฐ๋Šฅ ๋ธŒ๋žœ์น˜๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค (`git checkout -b feature/amazing-feature`)
452
- 3. ๋ณ€๊ฒฝ์‚ฌํ•ญ์„ ์ปค๋ฐ‹ํ•ฉ๋‹ˆ๋‹ค (`git commit -m 'feat: add amazing feature'`)
453
- 4. ๋ธŒ๋žœ์น˜์— Pushํ•ฉ๋‹ˆ๋‹ค (`git push origin feature/amazing-feature`)
454
- 5. Pull Request๋ฅผ ์—ฝ๋‹ˆ๋‹ค
455
-
456
- ## Star History
457
-
458
- QLN์ด ๋„์›€์ด ๋˜์—ˆ๋‹ค๋ฉด Star๋ฅผ ๋ˆŒ๋Ÿฌ์ฃผ์„ธ์š”! โญ
459
-
460
- ## ๋ผ์ด์„ ์Šค
461
-
462
- Apache-2.0
463
-
464
- ---
465
-
466
- > *"1,000๊ฐœ ๋„๊ตฌ๋ฅผ 200 ํ† ํฐ์œผ๋กœ. ์ด๊ฑด ์ตœ์ ํ™”๊ฐ€ ์•„๋‹ˆ๋ผ ํŒจ๋Ÿฌ๋‹ค์ž„ ์ „ํ™˜์ด๋‹ค."*
467
-
468
- ๐ŸŒ [nton2.com](https://nton2.com) ยท ๐Ÿ“ฆ [npm](https://www.npmjs.com/package/n2-qln) ยท โœ‰๏ธ lagi0730@gmail.com
469
-
470
- <sub>๐ŸŒน Rose๊ฐ€ ๋งŒ๋“ค์—ˆ์Šต๋‹ˆ๋‹ค โ€” N2์˜ ์ฒซ ๋ฒˆ์งธ AI ์—์ด์ „ํŠธ. ํ•˜๋ฃจ์— ์ˆ˜๋ฐฑ ๋ฒˆ QLN์œผ๋กœ ๊ฒ€์ƒ‰ํ•˜๊ณ , ์ด README๋„ ์ง์ ‘ ์ž‘์„ฑํ–ˆ์Šต๋‹ˆ๋‹ค.</sub>
1
+ ๐Ÿ‡บ๐Ÿ‡ธ [English](README.md)
2
+
3
+ # n2-qln
4
+
5
+ [![npm](https://img.shields.io/npm/v/n2-qln?color=brightgreen)](https://www.npmjs.com/package/n2-qln) [![license](https://img.shields.io/npm/l/n2-qln)](LICENSE) [![node](https://img.shields.io/node/v/n2-qln?color=brightgreen)](https://nodejs.org) [![downloads](https://img.shields.io/npm/dm/n2-qln?color=blue)](https://www.npmjs.com/package/n2-qln)
6
+
7
+ **QLN** = **Q**uery **L**ayer **N**etwork โ€” AI์™€ ๋„๊ตฌ ์‚ฌ์ด์— ์œ„์น˜ํ•˜๋Š” ์‹œ๋งจํ‹ฑ ๊ฒ€์ƒ‰ ๋ ˆ์ด์–ด.
8
+
9
+ > **1,000๊ฐœ ์ด์ƒ์˜ ๋„๊ตฌ๋ฅผ 1๊ฐœ์˜ MCP ๋„๊ตฌ๋กœ ๋ผ์šฐํŒ…ํ•ฉ๋‹ˆ๋‹ค.** AI๋Š” ๋ผ์šฐํ„ฐ ํ•˜๋‚˜๋งŒ ๋ด…๋‹ˆ๋‹ค โ€” 1,000๊ฐœ ์ „์ฒด๊ฐ€ ์•„๋‹™๋‹ˆ๋‹ค.
10
+
11
+ ![QLN Architecture โ€” Without vs With](docs/architecture.png)
12
+
13
+ ## ๋ชฉ์ฐจ
14
+
15
+ - [๊ธฐ๋Šฅ](#๊ธฐ๋Šฅ)
16
+ - [๋ฌธ์ œ์ ](#๋ฌธ์ œ์ )
17
+ - [์„ค์น˜](#์„ค์น˜)
18
+ - [์„ค์ •](#์„ค์ •)
19
+ - [์ž‘๋™ ๋ฐฉ์‹](#์ž‘๋™-๋ฐฉ์‹)
20
+ - [API ๋ ˆํผ๋Ÿฐ์Šค](#api-๋ ˆํผ๋Ÿฐ์Šค)
21
+ - [์„ค์ • ํŒŒ์ผ](#์„ค์ •-ํŒŒ์ผ)
22
+ - [์‹œ๋งจํ‹ฑ ๊ฒ€์ƒ‰ ์„ค์ •](#์‹œ๋งจํ‹ฑ-๊ฒ€์ƒ‰-์„ค์ •-์„ ํƒ์‚ฌํ•ญ)
23
+ - [ํ”„๋กœ์ ํŠธ ๊ตฌ์กฐ](#ํ”„๋กœ์ ํŠธ-๊ตฌ์กฐ)
24
+ - [์‹ค์ „ ๊ฒ€์ฆ ์™„๋ฃŒ](#์‹ค์ „-๊ฒ€์ฆ-์™„๋ฃŒ)
25
+ - [FAQ](#faq)
26
+ - [๊ธฐ์—ฌํ•˜๊ธฐ](#๊ธฐ์—ฌํ•˜๊ธฐ)
27
+
28
+ ## ๊ธฐ๋Šฅ
29
+
30
+ **ํ•˜๋‚˜์˜ ๋„๊ตฌ๋กœ ๋ชจ๋“  ๊ฒƒ์„** โ€” AI๋Š” `n2_qln_call` (~200 ํ† ํฐ)๋งŒ ๋ด…๋‹ˆ๋‹ค. 1,000๊ฐœ์˜ ๊ฐœ๋ณ„ ๋„๊ตฌ๊ฐ€ ์•„๋‹™๋‹ˆ๋‹ค. 99.6% ์ปจํ…์ŠคํŠธ ์ ˆ๊ฐ.
31
+
32
+ **5ms ์ดํ•˜ ๊ฒ€์ƒ‰** โ€” 3๋‹จ๊ณ„ ๊ฒ€์ƒ‰ ์—”์ง„ (ํŠธ๋ฆฌ๊ฑฐ + BM25 ํ‚ค์›Œ๋“œ + ์‹œ๋งจํ‹ฑ)์ด 1,000๊ฐœ ์ด์ƒ์˜ ๋„๊ตฌ์—์„œ๋„ 5ms ์ด๋‚ด์— ์ตœ์  ๋„๊ตฌ๋ฅผ ์ฐพ์Šต๋‹ˆ๋‹ค.
33
+
34
+ **BM25 ํ‚ค์›Œ๋“œ ๋žญํ‚น** *(v3.4)* โ€” Stage 2์— [Okapi BM25](https://en.wikipedia.org/wiki/Okapi_BM25) ์•Œ๊ณ ๋ฆฌ์ฆ˜ ์ ์šฉ. ํฌ๊ท€ํ•œ ๋‹จ์–ด์ผ์ˆ˜๋ก ๋†’์€ ์ ์ˆ˜, ๋ฌธ์„œ ๊ธธ์ด ์ •๊ทœํ™”. Google, Elasticsearch, Wikipedia ๊ฒ€์ƒ‰์˜ ํ•ต์‹ฌ ์•Œ๊ณ ๋ฆฌ์ฆ˜.
35
+
36
+ **์ž๋™ ํ•™์Šต ๋žญํ‚น** โ€” ๋งŽ์ด ์‚ฌ์šฉ๋˜๊ณ  ์„ฑ๊ณต๋ฅ ์ด ๋†’์€ ๋„๊ตฌ๋Š” ์ž๋™์œผ๋กœ ์ƒ์œ„์— ๋žญํฌ๋ฉ๋‹ˆ๋‹ค. ์ˆ˜๋™ ํŠœ๋‹ ๋ถˆํ•„์š”.
37
+
38
+ **๋Ÿฐํƒ€์ž„ ๋™์  ๊ด€๋ฆฌ** โ€” ์„œ๋ฒ„ ์žฌ์‹œ์ž‘ ์—†์ด ๋„๊ตฌ๋ฅผ ์ถ”๊ฐ€, ์ˆ˜์ •, ์‚ญ์ œํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. Provider ๋‹จ์œ„ ์ผ๊ด„ ๊ด€๋ฆฌ ์ง€์›.
39
+
40
+ **๊ฐ•์ œ ํ’ˆ์งˆ ๊ฒ€์ฆ** โ€” ๋„๊ตฌ ๋“ฑ๋ก ์‹œ ์—„๊ฒฉํ•œ ๊ฒ€์ฆ: `verb_target` ๋„ค์ด๋ฐ, ์ตœ์†Œ ์„ค๋ช… ๊ธธ์ด, ์นดํ…Œ๊ณ ๋ฆฌ ์ œ์•ฝ. ์ž˜๋ชป๋œ ๋„๊ตฌ๋Š” ๊ฑฐ๋ถ€๋ฉ๋‹ˆ๋‹ค.
41
+
42
+ **์‹œ๋งจํ‹ฑ ๊ฒ€์ƒ‰ (์„ ํƒ)** โ€” [Ollama](https://ollama.ai) ์ถ”๊ฐ€ ์‹œ ๋ฒกํ„ฐ ์œ ์‚ฌ๋„ ๊ฒ€์ƒ‰ ํ™œ์„ฑํ™”. ์—†์–ด๋„ Stage 1 + 2๋งŒ์œผ๋กœ ์ถฉ๋ถ„ํ•œ ๊ฒฐ๊ณผ. Ollama๊ฐ€ ๋‹ค์šด๋˜์–ด๋„ ๊ฒ€์ƒ‰์€ ์ •์ƒ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค.
43
+
44
+ **๋„ค์ดํ‹ฐ๋ธŒ ์˜์กด์„ฑ ์ œ๋กœ** โ€” [sql.js](https://github.com/sql-js/sql.js) (WASM) ๊ธฐ๋ฐ˜. `node-gyp` ๋นŒ๋“œ ์—†์Œ, ํ”Œ๋žซํผ๋ณ„ ๋ฐ”์ด๋„ˆ๋ฆฌ ์—†์Œ. `npm install`์ด๋ฉด ๋.
45
+
46
+ **์ด์ค‘ ์‹คํ–‰** โ€” ๋„๊ตฌ๋ฅผ ๋กœ์ปฌ ํ•จ์ˆ˜ ๋˜๋Š” HTTP ์—”๋“œํฌ์ธํŠธ๋กœ ์‹คํ–‰. ํ•ธ๋“ค๋Ÿฌ๋ฅผ ์ง์ ‘ ๋“ฑ๋กํ•˜๊ฑฐ๋‚˜ ์›๊ฒฉ ์„œ๋น„์Šค๋ฅผ ์—ฐ๊ฒฐ. ํ˜ผํ•ฉ๋„ ๊ฐ€๋Šฅ.
47
+
48
+ **Provider ์ž๋™ ์ธ๋ฑ์‹ฑ** *(v3.3)* โ€” `providers/`์— JSON ๋งค๋‹ˆํŽ˜์ŠคํŠธ๋ฅผ ๋„ฃ์œผ๋ฉด ๋ถ€ํŒ… ์‹œ ์ž๋™ ๋“ฑ๋ก. ์ฝ”๋“œ ์ˆ˜์ • ๋ถˆํ•„์š”, ์ˆ˜๋™ `create` ํ˜ธ์ถœ ๋ถˆํ•„์š”. ๋ฉฑ๋“ฑ์„ฑ ๋ณด์žฅ ๋ฐ ์—๋Ÿฌ ๊ฒฉ๋ฆฌ.
49
+
50
+ **10,000๊ฐœ ์ด์ƒ ํ™•์žฅ** โ€” ์นดํ…Œ๊ณ ๋ฆฌ๋ณ„ centroid hierarchy ํŒŒํ‹ฐ์…”๋‹. 100๊ฐœ ~1ms, 1,000๊ฐœ ~3ms, 10,000๊ฐœ ~5ms.
51
+
52
+ **๋ฒ”์šฉ MCP** โ€” Claude Desktop, Cursor, n2-soul ๋˜๋Š” ๋ชจ๋“  MCP ํ˜ธํ™˜ ํด๋ผ์ด์–ธํŠธ์—์„œ ๋™์ž‘. ํ‘œ์ค€ stdio ์ „์†ก.
53
+
54
+ ## ๋ฌธ์ œ์ 
55
+
56
+ MCP ๋„๊ตฌ๋ฅผ ๋“ฑ๋กํ•  ๋•Œ๋งˆ๋‹ค AI ์ปจํ…์ŠคํŠธ ํ† ํฐ์„ ์†Œ๋ชจํ•ฉ๋‹ˆ๋‹ค. 10๊ฐœ๋Š” ๊ดœ์ฐฎ์Šต๋‹ˆ๋‹ค. 100๊ฐœ๋ฉด ๋А๋ ค์ง‘๋‹ˆ๋‹ค. **1,000๊ฐœ๋ฉด ๋ถˆ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค** โ€” ๋Œ€ํ™”๊ฐ€ ์‹œ์ž‘๋˜๊ธฐ๋„ ์ „์— ์ปจํ…์ŠคํŠธ ์œˆ๋„์šฐ๊ฐ€ ๊ฐ€๋“ ์ฐน๋‹ˆ๋‹ค.
57
+
58
+ QLN์€ **์‹œ๋งจํ‹ฑ ๊ฒ€์ƒ‰ ๋ผ์šฐํ„ฐ**๋กœ ์ด ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•ฉ๋‹ˆ๋‹ค:
59
+
60
+ 1. ๋ชจ๋“  ๋„๊ตฌ๋ฅผ QLN์˜ SQLite ์ธ๋ฑ์Šค์— ๋“ฑ๋ก
61
+ 2. AI๋Š” **ํ•˜๋‚˜์˜ ๋„๊ตฌ**๋งŒ ๋ด…๋‹ˆ๋‹ค: `n2_qln_call` (~200 ํ† ํฐ)
62
+ 3. AI๊ฐ€ ๋„๊ตฌ๊ฐ€ ํ•„์š”ํ•˜๋ฉด **๊ฒ€์ƒ‰** โ†’ **์ตœ์  ๋งค์นญ** โ†’ **์‹คํ–‰**
63
+
64
+ **๊ฒฐ๊ณผ: ~50,000 ํ† ํฐ ๋Œ€์‹  ~200 ํ† ํฐ. 99.6% ์ ˆ๊ฐ.**
65
+
66
+ ---
67
+
68
+ ## ์„ค์น˜
69
+
70
+ ```bash
71
+ npm install n2-qln
72
+ ```
73
+
74
+ **์š”๊ตฌ์‚ฌํ•ญ:** Node.js โ‰ฅ 18
75
+
76
+ **์„ ํƒ์‚ฌํ•ญ:** ์‹œ๋งจํ‹ฑ ๋ฒกํ„ฐ ๊ฒ€์ƒ‰(Stage 3)์„ ์œ„ํ•ด [Ollama](https://ollama.ai) ์„ค์น˜. [์‹œ๋งจํ‹ฑ ๊ฒ€์ƒ‰ ์„ค์ •](#์‹œ๋งจํ‹ฑ-๊ฒ€์ƒ‰-์„ค์ •-์„ ํƒ์‚ฌํ•ญ) ์ฐธ์กฐ.
77
+
78
+ ---
79
+
80
+ ## ์„ค์ •
81
+
82
+ QLN์€ MCP ์„œ๋ฒ„์ž…๋‹ˆ๋‹ค. ๋ชจ๋“  MCP ํ˜ธํ™˜ AI ํด๋ผ์ด์–ธํŠธ์— ์—ฐ๊ฒฐํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
83
+
84
+ ### Claude Desktop
85
+
86
+ Claude Desktop ์„ค์ • ํŒŒ์ผ์„ ํŽธ์ง‘ํ•ฉ๋‹ˆ๋‹ค:
87
+
88
+ - **macOS:** `~/Library/Application Support/Claude/claude_desktop_config.json`
89
+ - **Windows:** `%APPDATA%\Claude\claude_desktop_config.json`
90
+
91
+ ```json
92
+ {
93
+ "mcpServers": {
94
+ "n2-qln": {
95
+ "command": "npx",
96
+ "args": ["-y", "n2-qln"]
97
+ }
98
+ }
99
+ }
100
+ ```
101
+
102
+ Claude Desktop์„ ์žฌ์‹œ์ž‘ํ•˜๋ฉด `n2_qln_call` ๋„๊ตฌ๊ฐ€ ๋ชฉ๋ก์— ๋‚˜ํƒ€๋‚ฉ๋‹ˆ๋‹ค.
103
+
104
+ ### Cursor
105
+
106
+ **Settings โ†’ MCP Servers โ†’ Add Server**์—์„œ ์„ค์ •:
107
+
108
+ ```json
109
+ {
110
+ "name": "n2-qln",
111
+ "command": "npx",
112
+ "args": ["-y", "n2-qln"]
113
+ }
114
+ ```
115
+
116
+ ### n2-soul
117
+
118
+ Soul `config.local.js`์— ์ถ”๊ฐ€:
119
+
120
+ ```javascript
121
+ module.exports = {
122
+ mcpServers: {
123
+ 'n2-qln': {
124
+ command: 'node',
125
+ args: ['<path-to-qln>/index.js'],
126
+ }
127
+ }
128
+ };
129
+ ```
130
+
131
+ npm์œผ๋กœ ์„ค์น˜ํ•œ ๊ฒฝ์šฐ:
132
+
133
+ ```javascript
134
+ module.exports = {
135
+ mcpServers: {
136
+ 'n2-qln': {
137
+ command: 'npx',
138
+ args: ['-y', 'n2-qln'],
139
+ }
140
+ }
141
+ };
142
+ ```
143
+
144
+ ### ๊ธฐํƒ€ MCP ํด๋ผ์ด์–ธํŠธ
145
+
146
+ QLN์€ **stdio ์ „์†ก** โ€” ํ‘œ์ค€ MCP ํ†ต์‹  ๋ฐฉ์‹์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ๋ชจ๋“  MCP ํ˜ธํ™˜ ํด๋ผ์ด์–ธํŠธ์—์„œ ์—ฐ๊ฒฐ ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค:
147
+
148
+ ```
149
+ command: npx
150
+ args: ["-y", "n2-qln"]
151
+ ```
152
+
153
+ ์†Œ์Šค๋ฅผ ํด๋ก ํ•œ ๊ฒฝ์šฐ:
154
+
155
+ ```
156
+ command: node
157
+ args: ["/absolute/path/to/n2-qln/index.js"]
158
+ ```
159
+
160
+ > ** ํŒ:** ๊ฐ€์žฅ ์‰ฌ์šด ์„ค์ • ๋ฐฉ๋ฒ•? **๊ทธ๋ƒฅ AI ์—์ด์ „ํŠธ์—๊ฒŒ ๋ถ€ํƒํ•˜์„ธ์š”.** *"n2-qln์„ ๋‚ด MCP ์„ค์ •์— ์ถ”๊ฐ€ํ•ด์ค˜"* โ€” ์—์ด์ „ํŠธ๊ฐ€ ์•Œ์•„์„œ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค.
161
+
162
+ ---
163
+
164
+ ## ์ž‘๋™ ๋ฐฉ์‹
165
+
166
+ ### ๋‹จ๊ณ„๋ณ„ ์˜ˆ์‹œ
167
+
168
+ ```
169
+ ์‚ฌ์šฉ์ž: "์ด ํŽ˜์ด์ง€ ์Šคํฌ๋ฆฐ์ƒท ์ฐ์–ด"
170
+
171
+ Step 1 โ†’ AI ํ˜ธ์ถœ: n2_qln_call(action: "search", query: "screenshot page")
172
+ QLN์ด 1,000๊ฐœ ์ด์ƒ์˜ ๋„๊ตฌ๋ฅผ <5ms์— ๊ฒ€์ƒ‰
173
+ ์‘๋‹ต: take_screenshot (score: 8.0)
174
+
175
+ Step 2 โ†’ AI ํ˜ธ์ถœ: n2_qln_call(action: "exec", tool: "take_screenshot", args: {fullPage: true})
176
+ QLN์ด ์‹ค์ œ ๋„๊ตฌ๋กœ ๋ผ์šฐํŒ… ๋ฐ ์‹คํ–‰
177
+ ์‘๋‹ต: ์Šคํฌ๋ฆฐ์ƒท ์ €์žฅ๋จ
178
+ ```
179
+
180
+ AI๋Š” `n2_qln_call`๋งŒ ์‚ฌ์šฉํ–ˆ์Šต๋‹ˆ๋‹ค. ๋‚˜๋จธ์ง€ 999๊ฐœ ๋„๊ตฌ๋Š” ์ „ํ˜€ ๋ณด์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค.
181
+
182
+ ### 3๋‹จ๊ณ„ ๊ฒ€์ƒ‰ ์—”์ง„
183
+
184
+ QLN์€ ์„ธ ๋‹จ๊ณ„์˜ ๊ฒ€์ƒ‰์œผ๋กœ ์ ํ•ฉํ•œ ๋„๊ตฌ๋ฅผ ์ฐพ์Šต๋‹ˆ๋‹ค:
185
+
186
+ | ๋‹จ๊ณ„ | ๋ฐฉ์‹ | ์†๋„ | ์ž‘๋™ ์›๋ฆฌ |
187
+ |:---:|--------|:---:|---------|
188
+ | **1** | ํŠธ๋ฆฌ๊ฑฐ ๋งค์นญ | <1ms | ๋„๊ตฌ ์ด๋ฆ„๊ณผ ํŠธ๋ฆฌ๊ฑฐ ํ‚ค์›Œ๋“œ ์ •ํ™• ๋งค์นญ |
189
+ | **2** | BM25 ํ‚ค์›Œ๋“œ | 1-3ms | [Okapi BM25](https://en.wikipedia.org/wiki/Okapi_BM25) ๋žญํ‚น ๊ฒ€์ƒ‰ โ€” IDF ๊ฐ€์ค‘์น˜ + ๋ฌธ์„œ ๊ธธ์ด ์ •๊ทœํ™” *(v3.4)* |
190
+ | **3** | ์‹œ๋งจํ‹ฑ ๊ฒ€์ƒ‰ | 5-15ms | ์ž„๋ฒ ๋”ฉ ๋ฒกํ„ฐ ์œ ์‚ฌ๋„ ๊ฒ€์ƒ‰ *(์„ ํƒ, Ollama ํ•„์š”)* |
191
+
192
+ ๋ชจ๋“  ๋‹จ๊ณ„์˜ ๊ฒฐ๊ณผ๋ฅผ ๋ณ‘ํ•ฉ ํ›„ ๋žญํ‚น:
193
+
194
+ ```
195
+ final_score = trigger_score ร— 3.0
196
+ + bm25_keyword_score ร— 1.0
197
+ + semantic_score ร— 2.0
198
+ + log2(usage_count + 1) ร— 0.5
199
+ + success_rate ร— 1.0
200
+ ```
201
+
202
+ ๋งŽ์ด ์‚ฌ์šฉ๋˜๊ณ  ์„ฑ๊ณต๋ฅ ์ด ๋†’์€ ๋„๊ตฌ๊ฐ€ ์‹œ๊ฐ„์ด ์ง€๋‚ ์ˆ˜๋ก ์ƒ์œ„์— ๋žญํฌ๋ฉ๋‹ˆ๋‹ค.
203
+
204
+ ---
205
+
206
+ ## API ๋ ˆํผ๋Ÿฐ์Šค
207
+
208
+ QLN์€ **ํ•˜๋‚˜์˜ MCP ๋„๊ตฌ** โ€” `n2_qln_call` โ€” 5๊ฐœ์˜ ์•ก์…˜์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.
209
+
210
+ ### search โ€” ์ž์—ฐ์–ด๋กœ ๋„๊ตฌ ๊ฒ€์ƒ‰
211
+
212
+ ```javascript
213
+ n2_qln_call({
214
+ action: "search",
215
+ query: "take a screenshot", // ์ž์—ฐ์–ด ์ฟผ๋ฆฌ (ํ•„์ˆ˜)
216
+ category: "capture", // ์นดํ…Œ๊ณ ๋ฆฌ ํ•„ํ„ฐ (์„ ํƒ)
217
+ topK: 5 // ์ตœ๋Œ€ ๊ฒฐ๊ณผ ์ˆ˜, ๊ธฐ๋ณธ: 5 (์„ ํƒ)
218
+ })
219
+ ```
220
+
221
+ ### exec โ€” ์ด๋ฆ„์œผ๋กœ ๋„๊ตฌ ์‹คํ–‰
222
+
223
+ ```javascript
224
+ n2_qln_call({
225
+ action: "exec",
226
+ tool: "take_screenshot", // ๋„๊ตฌ ์ด๋ฆ„ (ํ•„์ˆ˜)
227
+ args: { // ๋„๊ตฌ ์ธ์ˆ˜ (์„ ํƒ)
228
+ fullPage: true,
229
+ format: "png"
230
+ }
231
+ })
232
+ ```
233
+
234
+ ### create โ€” ์ƒˆ ๋„๊ตฌ ๋“ฑ๋ก
235
+
236
+ ```javascript
237
+ n2_qln_call({
238
+ action: "create",
239
+ name: "read_pdf", // ํ•„์ˆ˜, verb_target ํ˜•์‹
240
+ description: "Read and extract text from PDF files", // ํ•„์ˆ˜, ์ตœ์†Œ 10์ž
241
+ category: "data", // ํ•„์ˆ˜, ์•„๋ž˜ ์นดํ…Œ๊ณ ๋ฆฌ ์ฐธ์กฐ
242
+ provider: "pdf-tools", // ์„ ํƒ, ์†Œ์Šค๋ณ„ ๋„๊ตฌ ๊ทธ๋ฃนํ™”
243
+ tags: ["pdf", "read", "extract", "document"], // ์„ ํƒ, ๊ฒ€์ƒ‰ ๊ฐœ์„ 
244
+ examples: [ // ์„ ํƒ, ํ‚ค์›Œ๋“œ ๊ฒ€์ƒ‰์— ์ƒ‰์ธ
245
+ "read this PDF file",
246
+ "extract text from PDF",
247
+ "open the PDF"
248
+ ],
249
+ endpoint: "http://127.0.0.1:3100", // ์„ ํƒ, HTTP ๊ธฐ๋ฐ˜ ๋„๊ตฌ์šฉ
250
+ toolSchema: { filePath: { type: "string" } } // ์„ ํƒ, ์ž…๋ ฅ ์Šคํ‚ค๋งˆ
251
+ })
252
+ ```
253
+
254
+ **๊ฒ€์ฆ ๊ทœ์น™ (๊ฐ•์ œ โ€” ์œ„๋ฐ˜ ์‹œ ๊ฑฐ๋ถ€):**
255
+
256
+ | ๊ทœ์น™ | ์š”๊ตฌ์‚ฌํ•ญ | ์˜ˆ์‹œ |
257
+ |------|---------|------|
258
+ | **์ด๋ฆ„** | `verb_target` ํ˜•์‹ (์†Œ๋ฌธ์ž + ๋ฐ‘์ค„) | `read_pdf`, `take_screenshot` |
259
+ | **์„ค๋ช…** | ์ตœ์†Œ 10์ž | `"Read and extract text from PDF files"` |
260
+ | **์นดํ…Œ๊ณ ๋ฆฌ** | ์œ ํšจํ•œ ์นดํ…Œ๊ณ ๋ฆฌ ์ค‘ ํ•˜๋‚˜ | `"data"` |
261
+ | **๊ณ ์œ ์„ฑ** | ์ค‘๋ณต ์ด๋ฆ„ ๋ถˆ๊ฐ€ | โ€” |
262
+
263
+ **์œ ํšจ ์นดํ…Œ๊ณ ๋ฆฌ:** `web` ยท `data` ยท `file` ยท `dev` ยท `ai` ยท `capture` ยท `misc`
264
+
265
+ ### update โ€” ๊ธฐ์กด ๋„๊ตฌ ์ˆ˜์ •
266
+
267
+ ```javascript
268
+ n2_qln_call({
269
+ action: "update",
270
+ tool: "read_pdf", // ์ˆ˜์ •ํ•  ๋„๊ตฌ (ํ•„์ˆ˜)
271
+ description: "Enhanced PDF text extractor", // ๋ณ€๊ฒฝํ•  ํ•„๋“œ๋งŒ ์ œ๊ณต
272
+ examples: ["read this PDF", "parse PDF"],
273
+ tags: ["pdf", "read", "parse"]
274
+ })
275
+ ```
276
+
277
+ ๋ณ€๊ฒฝ๋œ ํ•„๋“œ๋งŒ ์ œ๊ณตํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค. ๋ฏธ๋ณ€๊ฒฝ ํ•„๋“œ๋Š” ๊ธฐ์กด ๊ฐ’ ์œ ์ง€. ๋™์ผํ•œ ๊ฒ€์ฆ ๊ทœ์น™ ์ ์šฉ.
278
+
279
+ ### delete โ€” ๋„๊ตฌ ์‚ญ์ œ
280
+
281
+ ```javascript
282
+ // ์ด๋ฆ„์œผ๋กœ ๋‹จ์ผ ๋„๊ตฌ ์‚ญ์ œ
283
+ n2_qln_call({
284
+ action: "delete",
285
+ tool: "read_pdf"
286
+ })
287
+
288
+ // Provider์˜ ๋ชจ๋“  ๋„๊ตฌ ์ผ๊ด„ ์‚ญ์ œ
289
+ n2_qln_call({
290
+ action: "delete",
291
+ provider: "pdf-tools"
292
+ })
293
+ // โ†’ Deleted 3 tools from provider: pdf-tools
294
+ ```
295
+
296
+ ---
297
+
298
+ ## ์„ค์ • ํŒŒ์ผ
299
+
300
+ QLN์€ ์„ค์ • ์—†์ด ๋ฐ”๋กœ ๋™์ž‘ํ•ฉ๋‹ˆ๋‹ค. ์ปค์Šคํ„ฐ๋งˆ์ด์ฆˆํ•˜๋ ค๋ฉด QLN ๋””๋ ‰ํ† ๋ฆฌ์— `config.local.js`๋ฅผ ์ƒ์„ฑํ•˜์„ธ์š”:
301
+
302
+ ```javascript
303
+ module.exports = {
304
+ dataDir: './data', // SQLite DB ์ €์žฅ ์œ„์น˜
305
+ embedding: {
306
+ enabled: true, // Stage 3 ์‹œ๋งจํ‹ฑ ๊ฒ€์ƒ‰ ํ™œ์„ฑํ™”
307
+ provider: 'ollama',
308
+ model: 'nomic-embed-text',
309
+ baseUrl: 'http://127.0.0.1:11434',
310
+ },
311
+ };
312
+ ```
313
+
314
+ > **์ฐธ๊ณ :** `config.local.js`๋Š” gitignore ์ฒ˜๋ฆฌ๋ฉ๋‹ˆ๋‹ค. ๋กœ์ปฌ ์„ค์ •์€ ์ปค๋ฐ‹๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
315
+
316
+ ---
317
+
318
+ ## ์‹œ๋งจํ‹ฑ ๊ฒ€์ƒ‰ ์„ค์ • (์„ ํƒ์‚ฌํ•ญ)
319
+
320
+ Ollama ์—†์ด๋„ QLN์€ Stage 1 (ํŠธ๋ฆฌ๊ฑฐ) + Stage 2 (ํ‚ค์›Œ๋“œ) ๋งค์นญ์„ ์‚ฌ์šฉํ•˜๋ฉฐ, ๋Œ€๋ถ€๋ถ„์˜ ๊ฒฝ์šฐ ์ถฉ๋ถ„ํ•œ ๊ฒฐ๊ณผ๋ฅผ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.
321
+
322
+ ์ตœ๋Œ€ ์ •ํ™•๋„๋ฅผ ์›ํ•œ๋‹ค๋ฉด ์‹œ๋งจํ‹ฑ ๋ฒกํ„ฐ ๊ฒ€์ƒ‰(Stage 3)์„ ์ถ”๊ฐ€ํ•˜์„ธ์š”:
323
+
324
+ ### 1. Ollama ์„ค์น˜
325
+
326
+ [ollama.ai](https://ollama.ai)์—์„œ ๋‹ค์šด๋กœ๋“œ ํ›„ ์„ค์น˜.
327
+
328
+ ### 2. ์ž„๋ฒ ๋”ฉ ๋ชจ๋ธ ๋‹ค์šด๋กœ๋“œ
329
+
330
+ ```bash
331
+ ollama pull nomic-embed-text
332
+ ```
333
+
334
+ ### 3. ์„ค์ • ํ™œ์„ฑํ™”
335
+
336
+ `config.local.js` ์ƒ์„ฑ:
337
+
338
+ ```javascript
339
+ module.exports = {
340
+ embedding: {
341
+ enabled: true,
342
+ provider: 'ollama',
343
+ model: 'nomic-embed-text',
344
+ baseUrl: 'http://127.0.0.1:11434',
345
+ },
346
+ };
347
+ ```
348
+
349
+ ### ๋น„๊ต
350
+
351
+ | ์„ค์ • | ๊ฒ€์ƒ‰ ๋‹จ๊ณ„ | ์ •ํ™•๋„ | ์˜์กด์„ฑ |
352
+ |:------|:---:|:---:|:---:|
353
+ | **๊ธฐ๋ณธ** (Ollama ์—†์Œ) | Stage 1 + 2 | ํ›Œ๋ฅญ | ์—†์Œ |
354
+ | **Ollama ํฌํ•จ** | Stage 1 + 2 + 3 | ์™„๋ฒฝ | Ollama ์‹คํ–‰ ํ•„์š” |
355
+
356
+ ### ๋‹ค๊ตญ์–ด ์‚ฌ์šฉ์ž
357
+
358
+ `nomic-embed-text`๋Š” ์˜์–ด์— ์ตœ์ ํ™”๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค. **ํ•œ๊ตญ์–ด, ์ผ๋ณธ์–ด, ์ค‘๊ตญ์–ด** ๋“ฑ ๋‹ค๋ฅธ ์–ธ์–ด๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค๋ฉด ๋‹ค๊ตญ์–ด ๋ชจ๋ธ๋กœ ๊ต์ฒดํ•˜์„ธ์š”:
359
+
360
+ ```bash
361
+ ollama pull bge-m3
362
+ ```
363
+
364
+ ```javascript
365
+ // config.local.js
366
+ module.exports = {
367
+ embedding: {
368
+ enabled: true,
369
+ model: 'bge-m3', // ๋‹ค๊ตญ์–ด ์ง€์› (100๊ฐœ ์ด์ƒ ์–ธ์–ด)
370
+ },
371
+ };
372
+ ```
373
+
374
+ ์ฝ”๋“œ ์ˆ˜์ • ์—†์ด config์˜ ๋ชจ๋ธ๋ช…๋งŒ ๋ฐ”๊พธ๋ฉด ๋ฉ๋‹ˆ๋‹ค.
375
+
376
+ ### ํด๋ผ์šฐ๋“œ ๋™๊ธฐํ™”
377
+
378
+ ๋„๊ตฌ ์ธ๋ฑ์Šค๋ฅผ ์—ฌ๋Ÿฌ ๊ธฐ๊ธฐ์—์„œ ๋™๊ธฐํ™”ํ•˜๊ณ  ์‹ถ๋‹ค๋ฉด `dataDir`์„ ํด๋ผ์šฐ๋“œ ํด๋”๋กœ ์ง€์ •ํ•˜์„ธ์š”:
379
+
380
+ ```javascript
381
+ // config.local.js
382
+ module.exports = {
383
+ dataDir: 'G:/My Drive/n2-qln', // Google Drive, OneDrive, Dropbox, NAS...
384
+ };
385
+ ```
386
+
387
+ [n2-soul ํด๋ผ์šฐ๋“œ ์Šคํ† ๋ฆฌ์ง€](https://github.com/choihyunsus/soul#%EF%B8%8F-cloud-storage--store-your-ai-memory-anywhere)์™€ ๋™์ผํ•œ ๋ฐฉ์‹์ž…๋‹ˆ๋‹ค. SQLite ํŒŒ์ผ์ด ํ•ด๋‹น ํด๋”์— ์ €์žฅ๋˜๊ณ , ๋™๊ธฐํ™” ์„œ๋น„์Šค๊ฐ€ ๋‚˜๋จธ์ง€๋ฅผ ์ฒ˜๋ฆฌํ•ฉ๋‹ˆ๋‹ค.
388
+
389
+ ---
390
+
391
+ ## ํ”„๋กœ์ ํŠธ ๊ตฌ์กฐ
392
+
393
+ ```
394
+ n2-qln/
395
+ โ”œโ”€โ”€ index.js # MCP ์„œ๋ฒ„ ์ง„์ž…์ 
396
+ โ”œโ”€โ”€ lib/
397
+ โ”‚ โ”œโ”€โ”€ config.js # ์„ค์ • ๋กœ๋” (๊ธฐ๋ณธ + ๋กœ์ปฌ ๋ณ‘ํ•ฉ)
398
+ โ”‚ โ”œโ”€โ”€ store.js # SQLite ์Šคํ† ๋ฆฌ์ง€ ์—”์ง„ (sql.js WASM)
399
+ โ”‚ โ”œโ”€โ”€ schema.js # ๋„๊ตฌ ์Šคํ‚ค๋งˆ ์ •๊ทœํ™” + ๊ฒ€์ƒ‰ ํ…์ŠคํŠธ ๋นŒ๋”
400
+ โ”‚ โ”œโ”€โ”€ validator.js # ๊ฐ•์ œ ๊ฒ€์ฆ (์ด๋ฆ„, ์„ค๋ช…, ์นดํ…Œ๊ณ ๋ฆฌ)
401
+ โ”‚ โ”œโ”€โ”€ registry.js # ๋„๊ตฌ CRUD + ์‚ฌ์šฉ๋Ÿ‰ ์ถ”์  + ์ž„๋ฒ ๋”ฉ ์บ์‹œ
402
+ โ”‚ โ”œโ”€โ”€ router.js # 3๋‹จ๊ณ„ ๊ฒ€์ƒ‰ ์—”์ง„ (BM25 v3.4)
403
+ โ”‚ โ”œโ”€โ”€ vector-index.js # Float32 ๋ฒกํ„ฐ ์ธ๋ฑ์Šค (centroid hierarchy)
404
+ โ”‚ โ”œโ”€โ”€ embedding.js # Ollama ์ž„๋ฒ ๋”ฉ ํด๋ผ์ด์–ธํŠธ (nomic-embed-text)
405
+ โ”‚ โ”œโ”€โ”€ executor.js # HTTP/ํ•จ์ˆ˜ ๋„๊ตฌ ์‹คํ–‰๊ธฐ
406
+ โ”‚ โ””โ”€โ”€ provider-loader.js # ๋ถ€ํŒ… ์‹œ providers/*.json ์ž๋™ ์ธ๋ฑ์‹ฑ
407
+ โ”œโ”€โ”€ tools/
408
+ โ”‚ โ””โ”€โ”€ qln-call.js # ํ†ตํ•ฉ MCP ๋„๊ตฌ (search/exec/create/update/delete)
409
+ โ”œโ”€โ”€ providers/ # ๋„๊ตฌ provider ๋งค๋‹ˆํŽ˜์ŠคํŠธ (์ผ๊ด„ ๋“ฑ๋ก์šฉ)
410
+ โ”œโ”€โ”€ config.local.js # ๋กœ์ปฌ ์„ค์ • ์˜ค๋ฒ„๋ผ์ด๋“œ (gitignored)
411
+ โ””โ”€โ”€ data/ # SQLite ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค (gitignored, ์ž๋™ ์ƒ์„ฑ)
412
+ ```
413
+
414
+ ## ๊ธฐ์ˆ  ์Šคํƒ
415
+
416
+ | ์ปดํฌ๋„ŒํŠธ | ๊ธฐ์ˆ  | ์ด์œ  |
417
+ |-----------|-----------|------|
418
+ | ๋Ÿฐํƒ€์ž„ | Node.js โ‰ฅ 18 | MCP SDK ํ˜ธํ™˜์„ฑ |
419
+ | ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค | SQLite via [sql.js](https://github.com/sql-js/sql.js) (WASM) | ๋„ค์ดํ‹ฐ๋ธŒ ์˜์กด์„ฑ ์ œ๋กœ, ํฌ๋กœ์Šค ํ”Œ๋žซํผ, ๋นŒ๋“œ ๋ถˆํ•„์š” |
420
+ | ์ž„๋ฒ ๋”ฉ | [Ollama](https://ollama.ai) + nomic-embed-text | ๋กœ์ปฌ, ๋น ๋ฆ„, ๋ฌด๋ฃŒ, ์„ ํƒ์‚ฌํ•ญ |
421
+ | ํ”„๋กœํ† ์ฝœ | [MCP](https://modelcontextprotocol.io) (Model Context Protocol) | ํ‘œ์ค€ AI ๋„๊ตฌ ํ”„๋กœํ† ์ฝœ |
422
+ | ๊ฒ€์ฆ | [Zod](https://zod.dev) | ๋Ÿฐํƒ€์ž„ ํƒ€์ž… ์•ˆ์ „ ์Šคํ‚ค๋งˆ ๊ฒ€์ฆ |
423
+
424
+ ## ๊ด€๋ จ ํ”„๋กœ์ ํŠธ
425
+
426
+ | ํ”„๋กœ์ ํŠธ | ๊ด€๊ณ„ |
427
+ |---------|------|
428
+ | [n2-soul](https://github.com/choihyunsus/soul) | AI ์—์ด์ „ํŠธ ์˜ค์ผ€์ŠคํŠธ๋ ˆ์ดํ„ฐ โ€” QLN์€ Soul์˜ "๋„๊ตฌ ๋ธŒ๋ ˆ์ธ" ์—ญํ•  |
429
+
430
+ ## ์‹ค์ „ ๊ฒ€์ฆ ์™„๋ฃŒ
431
+
432
+ ์ฃผ๋ง ํ”„๋กœํ† ํƒ€์ž…์ด ์•„๋‹™๋‹ˆ๋‹ค. QLN์€ **2๊ฐœ์›” ์ด์ƒ ์šด์˜ ํ™˜๊ฒฝ์—์„œ ๊ฒ€์ฆ**๋˜์—ˆ์œผ๋ฉฐ, [n2-soul](https://github.com/choihyunsus/soul)์˜ ํ•ต์‹ฌ ๋„๊ตฌ ๋ผ์šฐํ„ฐ๋กœ ๋งค์ผ ์‹ค์‚ฌ์šฉ๋˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.
433
+
434
+ **Rose** ์ œ์ž‘ โ€” N2์˜ ์ฒซ ๋ฒˆ์งธ AI ์—์ด์ „ํŠธ. ํ•˜๋ฃจ์— ์ˆ˜๋ฐฑ ๋ฒˆ QLN์„ ํ†ตํ•ด ๋ผ์šฐํŒ…ํ•ฉ๋‹ˆ๋‹ค.
435
+
436
+ ๋ฌธ์ œ๊ฐ€ ์žˆ๊ฑฐ๋‚˜ ์•„์ด๋””์–ด๊ฐ€ ์žˆ๋‹ค๋ฉด ์ด์Šˆ๋ฅผ ์—ด์–ด์ฃผ์„ธ์š”. ์—ฌ๋Ÿฌ๋ถ„์˜ ํ™œ์šฉ ์‚ฌ๋ก€๋ฅผ ๋“ฃ๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค.
437
+
438
+ ## FAQ
439
+
440
+ **"์™œ ํ”„๋กœ์ ํŠธ๋ฅผ ์ด๋ ‡๊ฒŒ ์ž์ฃผ ์˜ฌ๋ฆฌ๋‚˜์š”?"**
441
+
442
+ N2 ์ƒํƒœ๊ณ„๋Š” 4๊ฐœ์›” ์ด์ƒ ํ™œ๋ฐœํžˆ ๊ฐœ๋ฐœ๋˜์–ด ์™”์Šต๋‹ˆ๋‹ค. Soul, QLN, Ark โ€” ๋ณด์ด๋Š” ๋ชจ๋“  ํ”„๋กœ์ ํŠธ๋Š” ๊ณต๊ฐœ ์ „์— ์‹ค์ œ ์—…๋ฌด์—์„œ ์ถฉ๋ถ„ํžˆ ํ…Œ์ŠคํŠธ๋˜๊ณ  ๊ฒ€์ฆ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ์•ž์œผ๋กœ ๋” ๋‚˜์˜ฌ ์˜ˆ์ •์ด์ง€๋งŒ, ๋„๋ฐฐ๊ฐ€ ์•„๋‹ˆ๋ผ ์ด๋ฏธ ๋งŒ๋“ค์–ด์ ธ์„œ ๊ฒ€์ฆ ์™„๋ฃŒ๋œ ๊ฒƒ๋“ค์ด ๋งŽ๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค.
443
+
444
+ ํ˜ผ์ž์„œ ๊ฐœ๋ฐœํ•˜๊ณ  ๋ฐฐํฌํ•˜๋Š” ํ”„๋กœ์ ํŠธ์ž…๋‹ˆ๋‹ค. ๋นŒ๋“œ, ํ…Œ์ŠคํŠธ, ๋ฌธ์„œํ™”๋ฅผ ํ˜ผ์ž ํ•˜๋‹ค ๋ณด๋‹ˆ ์‹œ๊ฐ„์ด ๋งŽ์ด ๊ฑธ๋ ธ์Šต๋‹ˆ๋‹ค. ๊ด€์‹ฌ๊ณผ ์ธ๋‚ด์— ๊ฐ์‚ฌ๋“œ๋ฆฝ๋‹ˆ๋‹ค
445
+
446
+ ## ๊ธฐ์—ฌํ•˜๊ธฐ
447
+
448
+ ๊ธฐ์—ฌ๋ฅผ ํ™˜์˜ํ•ฉ๋‹ˆ๋‹ค! ์‹œ์ž‘ํ•˜๋Š” ๋ฐฉ๋ฒ•:
449
+
450
+ 1. ์ €์žฅ์†Œ๋ฅผ Forkํ•ฉ๋‹ˆ๋‹ค
451
+ 2. ๊ธฐ๋Šฅ ๋ธŒ๋žœ์น˜๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค (`git checkout -b feature/amazing-feature`)
452
+ 3. ๋ณ€๊ฒฝ์‚ฌํ•ญ์„ ์ปค๋ฐ‹ํ•ฉ๋‹ˆ๋‹ค (`git commit -m 'feat: add amazing feature'`)
453
+ 4. ๋ธŒ๋žœ์น˜์— Pushํ•ฉ๋‹ˆ๋‹ค (`git push origin feature/amazing-feature`)
454
+ 5. Pull Request๋ฅผ ์—ฝ๋‹ˆ๋‹ค
455
+
456
+ ## Star History
457
+
458
+ QLN์ด ๋„์›€์ด ๋˜์—ˆ๋‹ค๋ฉด Star๋ฅผ ๋ˆŒ๋Ÿฌ์ฃผ์„ธ์š”!
459
+
460
+ ## ๋ผ์ด์„ ์Šค
461
+
462
+ Apache-2.0
463
+
464
+ ---
465
+
466
+ > *"1,000๊ฐœ ๋„๊ตฌ๋ฅผ 200 ํ† ํฐ์œผ๋กœ. ์ด๊ฑด ์ตœ์ ํ™”๊ฐ€ ์•„๋‹ˆ๋ผ ํŒจ๋Ÿฌ๋‹ค์ž„ ์ „ํ™˜์ด๋‹ค."*
467
+
468
+ [nton2.com](https://nton2.com) ยท [npm](https://www.npmjs.com/package/n2-qln) ยท lagi0730@gmail.com
469
+
470
+ <sub> Rose๊ฐ€ ๋งŒ๋“ค์—ˆ์Šต๋‹ˆ๋‹ค โ€” N2์˜ ์ฒซ ๋ฒˆ์งธ AI ์—์ด์ „ํŠธ. ํ•˜๋ฃจ์— ์ˆ˜๋ฐฑ ๋ฒˆ QLN์œผ๋กœ ๊ฒ€์ƒ‰ํ•˜๊ณ , ์ด README๋„ ์ง์ ‘ ์ž‘์„ฑํ–ˆ์Šต๋‹ˆ๋‹ค.</sub>