@jungtz/wiki-router 1.0.1 → 1.0.4
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.md +134 -40
- package/dist/index.cjs +155 -209
- package/dist/index.d.ts +27 -2
- package/dist/index.mjs +154 -210
- package/dist/prompts.cjs +17 -168
- package/dist/prompts.mjs +17 -168
- package/package.json +3 -2
- package/src/types.d.ts +27 -2
package/README.md
CHANGED
|
@@ -14,83 +14,142 @@ npm install @jungtz/wiki-router
|
|
|
14
14
|
## 運作流程
|
|
15
15
|
|
|
16
16
|
```
|
|
17
|
-
|
|
17
|
+
知識來源 -> build() -> LLM 生成 Wiki -> getContext(prompt) -> LLM 路由 -> 相關上下文
|
|
18
18
|
```
|
|
19
19
|
|
|
20
|
-
1. **build()**:
|
|
20
|
+
1. **build()**: 將知識來源 (JSON/Markdown) 送交 LLM,拆分成結構化 `.md` 維基頁面
|
|
21
21
|
2. **getContext(prompt)**: 根據使用者問題,由 LLM 從 Index.md 中選擇相關檔案,回傳合併後的上下文
|
|
22
22
|
|
|
23
|
-
|
|
23
|
+
知識的「來源」與 wiki 的「儲存位置」皆透過 **adapter** 介面抽象,可使用內建檔案系統 adapter,亦可自訂 (例如 API + 資料庫),方便支援多租戶 / 多資料集場景。
|
|
24
|
+
|
|
25
|
+
## 快速開始(檔案系統)
|
|
24
26
|
|
|
25
27
|
```js
|
|
26
28
|
const { createWikiRouter } = require('@jungtz/wiki-router')
|
|
27
29
|
const { createRouter } = require('@jungtz/ai-router')
|
|
28
30
|
|
|
29
|
-
// 1. 準備 AI Router
|
|
30
31
|
const router = createRouter({
|
|
31
32
|
providers: {
|
|
32
|
-
'ollama-local': {
|
|
33
|
-
type: 'local',
|
|
34
|
-
baseURL: 'http://localhost:11434',
|
|
35
|
-
},
|
|
33
|
+
'ollama-local': { type: 'local', baseURL: 'http://localhost:11434' },
|
|
36
34
|
},
|
|
37
35
|
})
|
|
38
36
|
|
|
39
|
-
// 2. 建立 WikiRouter
|
|
40
37
|
const wiki = createWikiRouter({
|
|
41
|
-
router,
|
|
42
|
-
knowledgeDir: './knowledge',
|
|
43
|
-
outputDir:
|
|
44
|
-
modelId:
|
|
45
|
-
routerModelId: 'ollama-local/gemma4:31b', // 路由選擇模型 (可選)
|
|
46
|
-
|
|
38
|
+
router,
|
|
39
|
+
knowledgeDir: './knowledge', // fs 來源(簡寫)
|
|
40
|
+
outputDir: './wiki-output', // fs 儲存(簡寫)
|
|
41
|
+
modelId: 'ollama-local/gemma4:31b',
|
|
47
42
|
})
|
|
48
43
|
|
|
49
|
-
// 3. 建構/更新 Wiki
|
|
50
44
|
await wiki.build()
|
|
51
|
-
|
|
52
|
-
// 4. 查詢相關上下文
|
|
53
45
|
const ctx = await wiki.getContext('住宿有什麼規定?')
|
|
54
|
-
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
## 進階:自訂 adapter(多租戶 / API + DB)
|
|
49
|
+
|
|
50
|
+
當知識來自 API、wiki 要存到資料庫時,傳入 `source` / `store` adapter:
|
|
51
|
+
|
|
52
|
+
```js
|
|
53
|
+
const { createWikiRouter } = require('@jungtz/wiki-router')
|
|
54
|
+
|
|
55
|
+
function wikiOf(hotelId) {
|
|
56
|
+
return createWikiRouter({
|
|
57
|
+
router,
|
|
58
|
+
modelId: 'ollama-local/gemma4:31b',
|
|
59
|
+
source: {
|
|
60
|
+
async list() { return ['base.json'] },
|
|
61
|
+
async read() {
|
|
62
|
+
const res = await fetch(`/api/hotels/${hotelId}/knowledge`)
|
|
63
|
+
return { type: 'json', content: await res.text() }
|
|
64
|
+
},
|
|
65
|
+
},
|
|
66
|
+
store: {
|
|
67
|
+
async list() { return await db.wiki.list(hotelId) },
|
|
68
|
+
async read(filename) { return await db.wiki.read(hotelId, filename) },
|
|
69
|
+
async write(name, body) { await db.wiki.upsert(hotelId, name, body) },
|
|
70
|
+
},
|
|
71
|
+
})
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
const wikiA = wikiOf(4) // 旅館 A
|
|
75
|
+
const wikiB = wikiOf(7) // 旅館 B
|
|
55
76
|
```
|
|
56
77
|
|
|
57
78
|
## API
|
|
58
79
|
|
|
59
80
|
### `createWikiRouter(config)`
|
|
60
81
|
|
|
61
|
-
建立 WikiRouter 實例。
|
|
62
|
-
|
|
63
82
|
| 參數 | 類型 | 必要 | 說明 |
|
|
64
83
|
|------|------|------|------|
|
|
65
84
|
| `router` | `AIProviderRouter` | ✅ | AI Router 實例 |
|
|
66
|
-
| `
|
|
67
|
-
| `
|
|
85
|
+
| `source` | `Source` | ✱ | Knowledge 來源 adapter(與 `knowledgeDir` 二選一) |
|
|
86
|
+
| `store` | `Store` | ✱ | Wiki 儲存 adapter(與 `outputDir` 二選一) |
|
|
87
|
+
| `knowledgeDir` | `string` | ✱ | 簡寫:等同 `source: fsSource(dir)` |
|
|
88
|
+
| `outputDir` | `string` | ✱ | 簡寫:等同 `store: fsStore(dir)` |
|
|
68
89
|
| `modelId` | `string` | | Wiki 生成模型,格式 `provider/model` |
|
|
69
90
|
| `routerModelId` | `string` | | 路由選擇模型,預設同 `modelId` |
|
|
91
|
+
| `timeout` | `number` | | LLM 對話逾時毫秒數,預設 `300000` (5 分鐘) |
|
|
92
|
+
| `splitPrompt` | `string` | | 自訂 Split prompt |
|
|
93
|
+
| `mergePrompt` | `string` | | 自訂 Merge prompt |
|
|
94
|
+
| `routerPrompt` | `string` | | 自訂 Router prompt |
|
|
70
95
|
|
|
96
|
+
✱ `source` 與 `knowledgeDir` 至少擇一;`store` 與 `outputDir` 至少擇一。
|
|
71
97
|
|
|
72
98
|
### `wiki.build()`
|
|
73
99
|
|
|
74
100
|
建構或增量更新 Wiki 知識庫。回傳 `Promise<boolean>`。
|
|
75
101
|
|
|
76
|
-
-
|
|
77
|
-
-
|
|
102
|
+
- 首次(`store.list()` 為空):對 JSON 來源執行 split prompt,拆分成多個 `.md`
|
|
103
|
+
- 後續:使用 merge prompt,將新來源合併到既有檔案
|
|
78
104
|
|
|
79
105
|
### `wiki.getContext(prompt)`
|
|
80
106
|
|
|
81
107
|
根據使用者問題取得相關 Wiki 上下文。回傳 `Promise<string>`。
|
|
82
108
|
|
|
83
|
-
- 若
|
|
84
|
-
- 由 LLM 根據 Index.md 選擇最相關的檔案
|
|
85
|
-
- 回傳合併後的 Markdown
|
|
109
|
+
- 若 store 為空,自動調用 `build()`
|
|
110
|
+
- 由 LLM 根據 `Index.md` 選擇最相關的檔案
|
|
111
|
+
- 回傳合併後的 Markdown 內容;無相關檔案時回傳空字串
|
|
112
|
+
|
|
113
|
+
## Adapter 介面
|
|
114
|
+
|
|
115
|
+
### `Source`
|
|
116
|
+
|
|
117
|
+
```ts
|
|
118
|
+
interface Source {
|
|
119
|
+
list(): Promise<string[]> // 來源 key 清單
|
|
120
|
+
read(key: string): Promise<{ type: 'json' | 'markdown', content: string }>
|
|
121
|
+
}
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
### `Store`
|
|
125
|
+
|
|
126
|
+
```ts
|
|
127
|
+
interface Store {
|
|
128
|
+
list(): Promise<string[]> // 已生成的 wiki 檔名(含 .md)
|
|
129
|
+
read(filename: string): Promise<string | null> // 不存在回 null
|
|
130
|
+
write(filename: string, content: string): Promise<void>
|
|
131
|
+
}
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
### 內建 adapter
|
|
135
|
+
|
|
136
|
+
```js
|
|
137
|
+
import { fsSource, fsStore } from '@jungtz/wiki-router'
|
|
138
|
+
|
|
139
|
+
createWikiRouter({
|
|
140
|
+
router,
|
|
141
|
+
source: fsSource('./knowledge'),
|
|
142
|
+
store: fsStore('./wiki-output'),
|
|
143
|
+
})
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
`knowledgeDir` / `outputDir` 簡寫即在內部分別包成 `fsSource` / `fsStore`。
|
|
86
147
|
|
|
87
148
|
## 子模組
|
|
88
149
|
|
|
89
150
|
### 解析器
|
|
90
151
|
|
|
91
152
|
```js
|
|
92
|
-
const { parseWikiOutput } = require('@jungtz/wiki-router')
|
|
93
|
-
// 或
|
|
94
153
|
import { parseWikiOutput } from '@jungtz/wiki-router/parser'
|
|
95
154
|
|
|
96
155
|
const files = parseWikiOutput(llmResponse)
|
|
@@ -99,22 +158,57 @@ const files = parseWikiOutput(llmResponse)
|
|
|
99
158
|
|
|
100
159
|
### 提示詞模板
|
|
101
160
|
|
|
161
|
+
三個內建 prompt 定義於 `src/prompts/*.md`,build 時自動 inline 進 dist:
|
|
162
|
+
|
|
163
|
+
| 檔案 | 匯出名稱 | 用途 |
|
|
164
|
+
|------|----------|------|
|
|
165
|
+
| `src/prompts/split.md` | `SPLIT_PROMPT` | 將 JSON 資料拆分為多個 `.md` 檔案 |
|
|
166
|
+
| `src/prompts/merge.md` | `MERGE_PROMPT` | 將新內容合併到既有 Wiki 檔案 |
|
|
167
|
+
| `src/prompts/router.md` | `ROUTER_PROMPT` | 根據使用者問題選擇相關檔案 |
|
|
168
|
+
|
|
102
169
|
```js
|
|
103
170
|
import { SPLIT_PROMPT, MERGE_PROMPT, ROUTER_PROMPT } from '@jungtz/wiki-router/prompts'
|
|
104
171
|
```
|
|
105
172
|
|
|
106
|
-
|
|
173
|
+
#### 自訂 Prompt
|
|
174
|
+
|
|
175
|
+
於 `createWikiRouter` 設定中傳入 `splitPrompt` / `mergePrompt` / `routerPrompt` 字串可在 runtime 動態覆蓋;不傳則使用內建預設。
|
|
107
176
|
|
|
177
|
+
```js
|
|
178
|
+
const wiki = createWikiRouter({
|
|
179
|
+
router,
|
|
180
|
+
knowledgeDir: './knowledge',
|
|
181
|
+
outputDir: './wiki-output',
|
|
182
|
+
mergePrompt: readFileSync('./my-custom-merge.md', 'utf-8'),
|
|
183
|
+
})
|
|
108
184
|
```
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
185
|
+
|
|
186
|
+
## 範例
|
|
187
|
+
|
|
188
|
+
- `examples/basic.js` — 檔案系統用法
|
|
189
|
+
- `examples/multi-tenant.js` — 多租戶 (API + DB) 用法
|
|
190
|
+
|
|
191
|
+
## 互動預覽
|
|
192
|
+
|
|
193
|
+
內建互動式 TUI,可在終端直接問答測試 Wiki 路由效果:
|
|
194
|
+
|
|
195
|
+
```bash
|
|
196
|
+
npm run preview
|
|
197
|
+
|
|
198
|
+
# 自訂路徑
|
|
199
|
+
npm run preview -- --knowledge ./my-knowledge --output ./my-wiki
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
支援指令:`:list` 查看維基頁面、`:build` 重建維基、`:files` 顯示檔案、`:quit` 離開。
|
|
203
|
+
|
|
204
|
+
## 發布腳本
|
|
205
|
+
|
|
206
|
+
```bash
|
|
207
|
+
npm run bump:patch # 版號 patch +1 並自動 git commit + tag
|
|
208
|
+
npm run bump:minor # 版號 minor +1
|
|
209
|
+
npm run bump:major # 版號 major +1
|
|
210
|
+
npm run push:version # 推送 commit 與 tag 至 remote
|
|
211
|
+
npm run release # bump:patch + push:version
|
|
118
212
|
```
|
|
119
213
|
|
|
120
214
|
## 錯誤處理
|