siluzan-cso-cli 1.1.11-beta.5 → 1.1.11-beta.7
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 +1 -1
- package/dist/index.js +114 -7
- package/dist/skill/SKILL.md +49 -6
- package/dist/skill/_meta.json +2 -2
- package/dist/skill/references/rag.md +154 -25
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -50,7 +50,7 @@ siluzan-cso init -d /path/to/skills # 写入自定义目录
|
|
|
50
50
|
siluzan-cso init --force # 强制覆盖已存在文件
|
|
51
51
|
```
|
|
52
52
|
|
|
53
|
-
> **注意**:当前为测试版(1.1.11-beta.
|
|
53
|
+
> **注意**:当前为测试版(1.1.11-beta.7),供内部测试使用。正式发布后安装命令将改为 `npm install -g siluzan-cso-cli`。
|
|
54
54
|
|
|
55
55
|
| 助手 | 建议 `--ai` |
|
|
56
56
|
|------|-------------|
|
package/dist/index.js
CHANGED
|
@@ -6010,18 +6010,12 @@ ${hint}`);
|
|
|
6010
6010
|
console.log("\n\u63D0\u793A\uFF1A\u5B8C\u6574 styleGuide\uFF08Markdown\uFF09\u8BF7\u4F7F\u7528 --json \u67E5\u770B\u6BCF\u6761\u8BB0\u5F55\u7684 styleGuide \u5B57\u6BB5\u3002");
|
|
6011
6011
|
}
|
|
6012
6012
|
|
|
6013
|
-
// src/types/rag.ts
|
|
6014
|
-
var RAG_THREE_LIB_TAGS = ["\u6D41\u91CF\u56E0\u5B50\u5E93", "\u4EA7\u54C1\u8D44\u4EA7\u5E93", "\u70F9\u8C03\u65B9\u6CD5\u5E93"];
|
|
6015
|
-
|
|
6016
6013
|
// src/commands/rag.ts
|
|
6017
6014
|
function splitCsv(s) {
|
|
6018
6015
|
if (!s) return [];
|
|
6019
6016
|
return s.split(",").map((x) => x.trim()).filter(Boolean);
|
|
6020
6017
|
}
|
|
6021
6018
|
function resolveTags(tagsOption) {
|
|
6022
|
-
if (tagsOption === void 0) {
|
|
6023
|
-
return [...RAG_THREE_LIB_TAGS];
|
|
6024
|
-
}
|
|
6025
6019
|
return splitCsv(tagsOption);
|
|
6026
6020
|
}
|
|
6027
6021
|
function unwrapQueryKnowledges(raw) {
|
|
@@ -6237,6 +6231,110 @@ async function runRagQuery(options) {
|
|
|
6237
6231
|
console.log(`
|
|
6238
6232
|
${header}${body}`);
|
|
6239
6233
|
}
|
|
6234
|
+
var RAG_ROOT_FOLDER_ID = "88888888-8888-8888-0000-888888888888";
|
|
6235
|
+
async function runRagList(options) {
|
|
6236
|
+
const config = loadConfig(options.token);
|
|
6237
|
+
let belongToId = String(options.belongToId ?? "").trim();
|
|
6238
|
+
if (!belongToId) {
|
|
6239
|
+
const me = await fetchSiluzanCurrentUser(config.apiBaseUrl, config);
|
|
6240
|
+
belongToId = (me?.companyId ?? "").trim();
|
|
6241
|
+
}
|
|
6242
|
+
if (!belongToId) {
|
|
6243
|
+
console.error(
|
|
6244
|
+
"\n\u274C \u65E0\u6CD5\u786E\u5B9A\u4F01\u4E1A ID\uFF1A\u8BF7\u4F20\u5165 --belong-to-id\uFF0C\u6216\u786E\u4FDD GET /query/account/me \u54CD\u5E94\u4E2D\u542B companyId\u3002"
|
|
6245
|
+
);
|
|
6246
|
+
process.exit(1);
|
|
6247
|
+
}
|
|
6248
|
+
const p = new URLSearchParams({
|
|
6249
|
+
belongTo: "0",
|
|
6250
|
+
belongToId,
|
|
6251
|
+
showCut: "true",
|
|
6252
|
+
isGlobal: "true",
|
|
6253
|
+
orderBy: "createTime",
|
|
6254
|
+
isDesc: "true",
|
|
6255
|
+
pageIndex: "1",
|
|
6256
|
+
pageSize: "999",
|
|
6257
|
+
folderId: RAG_ROOT_FOLDER_ID
|
|
6258
|
+
});
|
|
6259
|
+
const url = `${config.csoBaseUrl}/cutapi/v1/material/querylist?${p.toString()}`;
|
|
6260
|
+
let raw;
|
|
6261
|
+
try {
|
|
6262
|
+
raw = await apiFetch2(
|
|
6263
|
+
url,
|
|
6264
|
+
config,
|
|
6265
|
+
{},
|
|
6266
|
+
Boolean(options.verbose)
|
|
6267
|
+
);
|
|
6268
|
+
} catch (e) {
|
|
6269
|
+
console.error(`
|
|
6270
|
+
\u274C \u8BF7\u6C42\u5931\u8D25\uFF1A${e.message}`);
|
|
6271
|
+
if (!options.verbose) console.error(" \u52A0 --verbose \u53C2\u6570\u53EF\u67E5\u770B\u8BE6\u7EC6\u9519\u8BEF\u4FE1\u606F");
|
|
6272
|
+
process.exit(1);
|
|
6273
|
+
}
|
|
6274
|
+
if (raw.code !== 1) {
|
|
6275
|
+
console.error(`
|
|
6276
|
+
\u274C \u83B7\u53D6\u77E5\u8BC6\u5E93\u5217\u8868\u5931\u8D25\uFF1A${raw.message || `\u4E1A\u52A1\u7801 ${raw.code}`}`);
|
|
6277
|
+
process.exit(1);
|
|
6278
|
+
}
|
|
6279
|
+
let folders = raw.data?.folders ?? [];
|
|
6280
|
+
if (options.ragOnly) {
|
|
6281
|
+
folders = folders.filter((f) => f.ragStatus === true);
|
|
6282
|
+
}
|
|
6283
|
+
if (options.json) {
|
|
6284
|
+
console.log(
|
|
6285
|
+
JSON.stringify(
|
|
6286
|
+
{
|
|
6287
|
+
belongToId,
|
|
6288
|
+
total: folders.length,
|
|
6289
|
+
folders: folders.map((f) => ({
|
|
6290
|
+
id: f.id,
|
|
6291
|
+
name: f.name,
|
|
6292
|
+
ragStatus: f.ragStatus,
|
|
6293
|
+
createTime: f.createTime
|
|
6294
|
+
}))
|
|
6295
|
+
},
|
|
6296
|
+
null,
|
|
6297
|
+
2
|
|
6298
|
+
)
|
|
6299
|
+
);
|
|
6300
|
+
return;
|
|
6301
|
+
}
|
|
6302
|
+
if (folders.length === 0) {
|
|
6303
|
+
console.log(options.ragOnly ? "\n\u6682\u65E0\u5DF2\u5EFA RAG \u7D22\u5F15\u7684\u77E5\u8BC6\u5E93\u3002\n" : "\n\u6682\u65E0\u77E5\u8BC6\u5E93\u6587\u4EF6\u5939\u3002\n");
|
|
6304
|
+
return;
|
|
6305
|
+
}
|
|
6306
|
+
const ragTag = (s) => s === true ? "\u2705 \u5DF2\u7D22\u5F15" : "\u2014";
|
|
6307
|
+
const rows = folders.map((f) => ({
|
|
6308
|
+
id: f.id,
|
|
6309
|
+
name: f.name,
|
|
6310
|
+
ragStatus: ragTag(f.ragStatus),
|
|
6311
|
+
createTime: formatTime(f.createTime)
|
|
6312
|
+
}));
|
|
6313
|
+
const colWidths = {
|
|
6314
|
+
id: Math.max(36, ...rows.map((r) => r.id.length)),
|
|
6315
|
+
name: Math.max(4, ...rows.map((r) => [...r.name].length)),
|
|
6316
|
+
ragStatus: Math.max(6, ...rows.map((r) => [...r.ragStatus].length)),
|
|
6317
|
+
createTime: Math.max(10, ...rows.map((r) => r.createTime.length))
|
|
6318
|
+
};
|
|
6319
|
+
const pad = (s, w) => s + " ".repeat(Math.max(0, w - [...s].length));
|
|
6320
|
+
const sep2 = `+-${"-".repeat(colWidths.id)}-+-${"-".repeat(colWidths.name)}-+-${"-".repeat(colWidths.ragStatus)}-+-${"-".repeat(colWidths.createTime)}-+`;
|
|
6321
|
+
const header = `| ${pad("ID", colWidths.id)} | ${pad("\u540D\u79F0", colWidths.name)} | ${pad("RAG", colWidths.ragStatus)} | ${pad("\u521B\u5EFA\u65F6\u95F4", colWidths.createTime)} |`;
|
|
6322
|
+
const lines = [
|
|
6323
|
+
`
|
|
6324
|
+
\u77E5\u8BC6\u5E93\u5217\u8868\uFF08belongToId=${belongToId}\uFF0C\u5171 ${folders.length} \u6761\uFF09
|
|
6325
|
+
`,
|
|
6326
|
+
sep2,
|
|
6327
|
+
header,
|
|
6328
|
+
sep2,
|
|
6329
|
+
...rows.map(
|
|
6330
|
+
(r) => `| ${pad(r.id, colWidths.id)} | ${pad(r.name, colWidths.name)} | ${pad(r.ragStatus, colWidths.ragStatus)} | ${pad(r.createTime, colWidths.createTime)} |`
|
|
6331
|
+
),
|
|
6332
|
+
sep2,
|
|
6333
|
+
"",
|
|
6334
|
+
options.ragOnly ? "\u{1F4A1} \u4F7F\u7528 --folder-id <id> \u6307\u5B9A\u4E0A\u65B9\u4EFB\u610F\u77E5\u8BC6\u5E93\u8FDB\u884C\u68C0\u7D22\uFF08rag query \u547D\u4EE4\uFF09\u3002\n" : "\u{1F4A1} \u4EC5\u663E\u793A RAG \u5DF2\u7D22\u5F15\u7684\u77E5\u8BC6\u5E93\uFF1A\u52A0 --rag-only \u53C2\u6570\u3002\n \u7528 --folder-id <id> \u5728 rag query \u4E2D\u6307\u5B9A\u68C0\u7D22\u8303\u56F4\u3002\n"
|
|
6335
|
+
];
|
|
6336
|
+
console.log(lines.join("\n"));
|
|
6337
|
+
}
|
|
6240
6338
|
|
|
6241
6339
|
// src/commands/config.ts
|
|
6242
6340
|
import * as fs10 from "fs";
|
|
@@ -6444,6 +6542,15 @@ personaCmd.command("list").description("\u62C9\u53D6\u4EBA\u8BBE\u5217\u8868\uFF
|
|
|
6444
6542
|
});
|
|
6445
6543
|
});
|
|
6446
6544
|
var ragCmd = program.command("rag").description("RAG \u77E5\u8BC6\u5E93\u68C0\u7D22\uFF08\u4EC5\u5199\u7A3F/\u4E09\u5E93\uFF1B\u9ED8\u8BA4 belongToId=account/me \u7684 companyId\uFF0C\u9ED8\u8BA4 tags=\u4E09\u5E93\uFF09");
|
|
6545
|
+
ragCmd.command("list").description("\u5217\u51FA\u5F53\u524D\u4F01\u4E1A\u4E0B\u6240\u6709\u77E5\u8BC6\u5E93\u6587\u4EF6\u5939\uFF08GET cutapi/v1/material/querylist\uFF09\uFF0C\u4F9B AI \u9009\u62E9\u68C0\u7D22\u8303\u56F4").option("--belong-to-id <id>", "\u4F01\u4E1A ID\uFF1B\u4E0D\u4F20\u5219\u4ECE GET /query/account/me \u53D6 companyId").option("--rag-only", "\u4EC5\u663E\u793A\u5DF2\u5EFA RAG \u5411\u91CF\u7D22\u5F15\uFF08ragStatus=true\uFF09\u7684\u77E5\u8BC6\u5E93", false).option("-t, --token <token>", "Token\uFF08\u53EF\u9009\uFF1B\u4F18\u5148\u4E8E ~/.siluzan/config.json\uFF09").option("--json", "\u8F93\u51FA\u5B8C\u6574 JSON", false).option("--verbose", "\u663E\u793A\u8BE6\u7EC6\u9519\u8BEF\u4FE1\u606F", false).action(async (opts) => {
|
|
6546
|
+
await runRagList({
|
|
6547
|
+
belongToId: opts.belongToId,
|
|
6548
|
+
ragOnly: opts.ragOnly,
|
|
6549
|
+
token: opts.token,
|
|
6550
|
+
json: opts.json,
|
|
6551
|
+
verbose: opts.verbose
|
|
6552
|
+
});
|
|
6553
|
+
});
|
|
6447
6554
|
ragCmd.command("query").description("\u6309\u5173\u952E\u8BCD\u68C0\u7D22\u5DF2\u7EB3\u5165\u5411\u91CF\u7684\u77E5\u8BC6\u7247\u6BB5\uFF08GET cutapi/v1/material/queryknowledges\uFF09").requiredOption("-q, --query <text>", "\u68C0\u7D22\u5173\u952E\u8BCD\u6216\u95EE\u53E5").option(
|
|
6448
6555
|
"--belong-to-id <id>",
|
|
6449
6556
|
"\u4F01\u4E1A ID\uFF1B\u4E0D\u4F20\u5219\u4ECE GET /query/account/me \u53D6 companyId"
|
|
@@ -6452,7 +6559,7 @@ ragCmd.command("query").description("\u6309\u5173\u952E\u8BCD\u68C0\u7D22\u5DF2\
|
|
|
6452
6559
|
"\u7D20\u6750\u6587\u4EF6 ID\uFF0C\u9017\u53F7\u5206\u9694\uFF08\u53EF\u9009\uFF0Cqueryknowledges \u7684 sourceid\uFF09"
|
|
6453
6560
|
).option("--folder-id <ids>", "\u6587\u4EF6\u5939 ID\uFF0C\u9017\u53F7\u5206\u9694\uFF08\u53EF\u9009\uFF0Ccomid\uFF09").option("--top-k <n>", "\u8FD4\u56DE\u6761\u6570\uFF0C3\u201330\uFF08\u9ED8\u8BA4 7\uFF09", "7").option("--belong-to <n>", "\u5F52\u5C5E\u7C7B\u578B\uFF08\u9ED8\u8BA4 0\uFF0C\u4F01\u4E1A\uFF09", "0").option(
|
|
6454
6561
|
"--tags <tags>",
|
|
6455
|
-
"\u6807\u7B7E\u8FC7\u6EE4\uFF0C\u9017\u53F7\u5206\u9694\uFF1B\u4E0D\u4F20\u5219\
|
|
6562
|
+
"\u6807\u7B7E\u8FC7\u6EE4\uFF0C\u9017\u53F7\u5206\u9694\uFF1B\u4E0D\u4F20\u5219\u4E0D\u8FC7\u6EE4\u6807\u7B7E\uFF08\u5168\u91CF\u68C0\u7D22\uFF09"
|
|
6456
6563
|
).option("--category <categories>", "\u5206\u7C7B\u8FC7\u6EE4\uFF0C\u9017\u53F7\u5206\u9694").option("-t, --token <token>", "Token\uFF08\u53EF\u9009\uFF1B\u4F18\u5148\u4E8E ~/.siluzan/config.json\uFF09").option("--json", "\u8F93\u51FA\u5B8C\u6574 JSON", false).option("--unicode", "\u4F7F\u7528 Unicode \u7EBF\u6846\u8868\u683C\uFF08\u9ED8\u8BA4 ASCII +-|\uFF09", false).option("--verbose", "\u663E\u793A\u8BE6\u7EC6\u9519\u8BEF\u4FE1\u606F", false).action(async (opts) => {
|
|
6457
6564
|
await runRagQuery({
|
|
6458
6565
|
query: opts.query,
|
package/dist/skill/SKILL.md
CHANGED
|
@@ -1,9 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: siluzan-cso
|
|
3
|
-
description:
|
|
4
|
-
当用户提问的内容涉及以下内容时,可以使用本SKILL
|
|
5
|
-
(1)多媒体平台内容(视频/图文)发布与运营(YouTube、TikTok、Instagram、LinkedIn、X、视频号),以及账号授权、数据报表、任务管理;
|
|
6
|
-
(2)公众号,小红薯等内容文案/选题生成——选题/拆解/口播成稿,三库选题。
|
|
3
|
+
description: 当用户提问的内容涉及以下内容时,可以使用本SKILL(1)多媒体平台内容(视频/图文)发布与运营(YouTube、TikTok、Instagram、LinkedIn、X、视频号),以及账号授权、数据报表、任务管理;2)公众号,小红薯等内容文案/选题生成——选题/拆解/口播成稿,三库选题。
|
|
7
4
|
compatibility: Requires siluzan-cso-cli installed and authenticated via `siluzan-cso login`
|
|
8
5
|
---
|
|
9
6
|
|
|
@@ -58,7 +55,8 @@ compatibility: Requires siluzan-cso-cli installed and authenticated via `siluzan
|
|
|
58
55
|
| `siluzan-cso authorize --media-type <平台>` | 发起媒体账号 OAuth 授权 | `references/authorize.md` |
|
|
59
56
|
| `siluzan-cso list-accounts` | 列出媒体账号,获取账号 ID / 数据总览 | `references/list-accounts.md` |
|
|
60
57
|
| `siluzan-cso persona list` | 拉取 CSO 人设列表(含 styleGuide Markdown) | `references/persona.md` |
|
|
61
|
-
| `siluzan-cso rag
|
|
58
|
+
| `siluzan-cso rag list` | 列出所有知识库文件夹(供 AI 按用户意图选择检索范围) | `references/rag.md` |
|
|
59
|
+
| `siluzan-cso rag query` | RAG 知识库检索(仅写稿;可配合 `rag list` 选定 `--folder-id`) | `references/rag.md` |
|
|
62
60
|
| `siluzan-cso account-group list/create/add-accounts/remove-accounts/update/delete` | 账号分组管理 | `references/account-group.md` |
|
|
63
61
|
| `siluzan-cso upload -f <file>` | 上传视频 / 图片到素材库 | `references/upload.md` |
|
|
64
62
|
| `siluzan-cso extract-cover -f <video> -p <平台>` | 从视频截取封面帧 | `references/extract-cover.md` |
|
|
@@ -88,7 +86,7 @@ compatibility: Requires siluzan-cso-cli installed and authenticated via `siluzan
|
|
|
88
86
|
| AI 内容规划 | `references/planning.md` |
|
|
89
87
|
| 需要给用户提供后台页面链接 | `references/web-pages.md` |
|
|
90
88
|
| 拉取人设 / styleGuide(写稿前) | `references/persona.md` |
|
|
91
|
-
| 写稿时检索素材库 RAG 片段(三库拆素材等) | `references/rag.md` |
|
|
89
|
+
| 写稿时检索素材库 RAG 片段(三库拆素材等) | `references/rag.md`(先 `rag list` 选库,再多次 `rag query` 拆词检索) |
|
|
92
90
|
| 选题 / 三库拆解 / 口播文案/其他文案 / 人设卡 / 代表作品反推人设 | `three-lib-content-workflow/content-writer.workflow.md` |
|
|
93
91
|
|
|
94
92
|
---
|
|
@@ -102,10 +100,55 @@ publish ──提交后查状态──► task ──失败重授权──► au
|
|
|
102
100
|
|
|
103
101
|
report ──需要 mediaCustomerId──► list-accounts
|
|
104
102
|
account-group ──需要 mediaCustomerId──► list-accounts
|
|
103
|
+
|
|
104
|
+
rag query ──需要知识库 ID──► rag list(按用户意图自动选择)
|
|
105
105
|
```
|
|
106
106
|
|
|
107
107
|
---
|
|
108
108
|
|
|
109
|
+
## RAG 知识库检索工作流
|
|
110
|
+
|
|
111
|
+
> 详细检索策略见 `references/rag.md`,以下为决策摘要。
|
|
112
|
+
|
|
113
|
+
### 何时使用 RAG
|
|
114
|
+
|
|
115
|
+
- ✅ 询问特定品牌/产品知识、写需要品牌素材的文案 → **必须先 RAG**
|
|
116
|
+
- ✅ 执行三库内容工作流 → **按三库分库检索**
|
|
117
|
+
- ❌ 询问平台操作方法、纯通用创作、用户明确不需要 → **跳过 RAG**
|
|
118
|
+
|
|
119
|
+
### 四步执行流程
|
|
120
|
+
|
|
121
|
+
**Step 1 — 获取知识库**(只在任务开始时调用一次)
|
|
122
|
+
|
|
123
|
+
```bash
|
|
124
|
+
siluzan-cso rag list --rag-only --json
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
**Step 2 — 选择知识库**(按名称语义匹配)
|
|
128
|
+
|
|
129
|
+
- 用户提到品牌名 → 找最匹配的文件夹,记录 `id`
|
|
130
|
+
- 多品牌 → `--folder-id id1,id2`
|
|
131
|
+
- 无明确品牌 → 不传 `--folder-id`
|
|
132
|
+
|
|
133
|
+
**Step 3 — 拆词多轮检索**(2–5 个子查询,每个聚焦一个维度)
|
|
134
|
+
|
|
135
|
+
```bash
|
|
136
|
+
# 默认不传 --tags = 全量检索(适用于绝大多数场景)
|
|
137
|
+
siluzan-cso rag query -q "产品核心卖点" --folder-id <id> --top-k 10
|
|
138
|
+
siluzan-cso rag query -q "用户使用场景" --folder-id <id>
|
|
139
|
+
siluzan-cso rag query -q "品牌差异优势" --folder-id <id>
|
|
140
|
+
|
|
141
|
+
# 知识库已按三库打标时,才按标签精确筛选
|
|
142
|
+
siluzan-cso rag query -q "抖音爆款钩子" --tags "流量因子库"
|
|
143
|
+
siluzan-cso rag query -q "产品卖点故事" --tags "产品资产库"
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
**Step 4 — 合成使用**
|
|
147
|
+
|
|
148
|
+
将多轮结果去重 → 按相关度(score 越小越相关)排序 → 作为写稿/回答的事实依据,重新组织表达(不直接粘贴原文)。
|
|
149
|
+
|
|
150
|
+
---
|
|
151
|
+
|
|
109
152
|
## AI 行为规范
|
|
110
153
|
|
|
111
154
|
### 执行任务的标准流程
|
package/dist/skill/_meta.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"slug": "siluzan-cso",
|
|
3
|
-
"version": "1.1.11-beta.
|
|
4
|
-
"publishedAt":
|
|
3
|
+
"version": "1.1.11-beta.7",
|
|
4
|
+
"publishedAt": 1776330316575,
|
|
5
5
|
"homepage": "https://www.siluzan.com",
|
|
6
6
|
"source": "https://dev.azure.com/jack4it/Sammamish/_git/siluzan-skill",
|
|
7
7
|
"requiredBinaries": [
|
|
@@ -1,37 +1,166 @@
|
|
|
1
|
-
# rag:RAG
|
|
1
|
+
# rag:RAG 知识库检索
|
|
2
2
|
|
|
3
|
-
与 Siluzan-RAG-sys-ui `MultiFileChat.vue` / `queryKnowledges`
|
|
3
|
+
与 Siluzan-RAG-sys-ui `MultiFileChat.vue` / `queryKnowledges` 一致,用于写稿、产品知识问答、三库素材提取等场景。
|
|
4
4
|
|
|
5
|
-
##
|
|
5
|
+
## 命令速览
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
```bash
|
|
8
|
+
# 第一步:列出所有已建索引的知识库(--rag-only 只显示可检索的)
|
|
9
|
+
siluzan-cso rag list --rag-only
|
|
8
10
|
|
|
9
|
-
|
|
11
|
+
# 第二步:按关键词检索
|
|
12
|
+
siluzan-cso rag query -q "<关键词>" --folder-id <id> --tags ""
|
|
13
|
+
siluzan-cso rag query -q "<关键词>" # 全库 + 三库标签过滤
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
## 参数说明
|
|
17
|
+
|
|
18
|
+
| 选项 | 默认 | 说明 |
|
|
19
|
+
|------|------|------|
|
|
20
|
+
| `-q, --query` | 必填 | 检索关键词或短句(越具体越好,避免长段落) |
|
|
21
|
+
| `--folder-id` | 全库 | 指定一个或多个文件夹 ID(逗号分隔),锁定检索范围 |
|
|
22
|
+
| `--tags` | 不过滤 | 不传 = 全量检索(无标签限制);传具体标签 = 只返回含该标签的片段 |
|
|
23
|
+
| `--top-k` | 7 | 每次返回条数,3–30;复杂问题建议调高到 10–15 |
|
|
24
|
+
| `--json` | false | 输出完整 JSON,适合程序处理 |
|
|
25
|
+
|
|
26
|
+
---
|
|
27
|
+
|
|
28
|
+
## AI 检索策略指南
|
|
29
|
+
|
|
30
|
+
> 以下规则指导 AI 如何将用户意图转化为高质量的 RAG 检索。
|
|
31
|
+
|
|
32
|
+
### 1. 判断是否需要 RAG
|
|
33
|
+
|
|
34
|
+
**需要 RAG 的场景:**
|
|
35
|
+
- 用户询问特定品牌/产品的信息("海科佳的产品有哪些卖点")
|
|
36
|
+
- 需要基于公司素材库写文案、口播稿、选题
|
|
37
|
+
- 执行三库内容工作流(流量因子库/产品资产库/烹调方法库)
|
|
38
|
+
|
|
39
|
+
**不需要 RAG 的场景:**
|
|
40
|
+
- 询问平台功能、操作方法(查 references 文档即可)
|
|
41
|
+
- 纯创意写作、无需依赖品牌素材的通用内容
|
|
42
|
+
- 用户明确说"不用查知识库"
|
|
43
|
+
|
|
44
|
+
---
|
|
45
|
+
|
|
46
|
+
### 2. 选择知识库(`rag list` → `--folder-id`)
|
|
47
|
+
|
|
48
|
+
先运行 `siluzan-cso rag list --rag-only --json` 获取列表,再按以下规则匹配:
|
|
10
49
|
|
|
11
|
-
|
|
|
12
|
-
|
|
13
|
-
|
|
|
14
|
-
|
|
|
15
|
-
|
|
|
50
|
+
| 用户意图 | 文件夹选择策略 |
|
|
51
|
+
|----------|----------------|
|
|
52
|
+
| 明确提到某品牌/产品名 | 找名称最匹配的文件夹,用 `--folder-id <id>` 锁定 |
|
|
53
|
+
| 没有指定品牌,做通用内容 | 不传 `--folder-id`(全库检索) |
|
|
54
|
+
| 需要公司公共素材(总部公共库) | 不传 `--folder-id`,isGlobal 已覆盖公共库 |
|
|
55
|
+
| 用户提到多个品牌 | `--folder-id <id1>,<id2>` 同时检索 |
|
|
16
56
|
|
|
17
|
-
|
|
57
|
+
> 文件夹名称匹配优先:语义近似 > 包含关键词 > 不确定时全库。
|
|
18
58
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
59
|
+
---
|
|
60
|
+
|
|
61
|
+
### 3. 标签策略(`--tags`)
|
|
62
|
+
|
|
63
|
+
**默认行为(不传 `--tags`)= 不过滤标签 = 全量检索**,适用于绝大多数场景。
|
|
64
|
+
|
|
65
|
+
只有在知识库**已按标签打标**,且用户明确需要**精确筛选某类内容**时,才传具体标签:
|
|
66
|
+
|
|
67
|
+
```bash
|
|
68
|
+
# 只检索打了"流量因子库"标签的片段
|
|
69
|
+
siluzan-cso rag query -q "抖音爆款钩子" --tags "流量因子库"
|
|
70
|
+
|
|
71
|
+
# 同时检索两个标签
|
|
72
|
+
siluzan-cso rag query -q "产品卖点" --tags "产品资产库,烹调方法库"
|
|
73
|
+
|
|
74
|
+
# 不限标签(默认行为,通常省略 --tags)
|
|
75
|
+
siluzan-cso rag query -q "海科佳产品特点"
|
|
23
76
|
```
|
|
24
77
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
78
|
+
---
|
|
79
|
+
|
|
80
|
+
### 4. 查询拆解(Query Decomposition)
|
|
81
|
+
|
|
82
|
+
单次检索语义受限,**同一个问题应拆分为 2–5 个独立关键词并行检索**,每个关键词聚焦一个子维度:
|
|
83
|
+
|
|
84
|
+
**示例 1:写产品口播文案**
|
|
85
|
+
```
|
|
86
|
+
用户意图 → "帮我写海科佳产品的口播文案"
|
|
87
|
+
|
|
88
|
+
拆解检索(--folder-id 海科佳ID,--tags ""):
|
|
89
|
+
"产品核心卖点"
|
|
90
|
+
"用户痛点 解决方案"
|
|
91
|
+
"产品使用场景"
|
|
92
|
+
"品牌差异化优势"
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
**示例 2:三库选题(知识库已按三库打标)**
|
|
96
|
+
```
|
|
97
|
+
用户意图 → "给我找抖音爆款选题角度"
|
|
98
|
+
|
|
99
|
+
拆解检索(知识库已打三库标签,按标签精确分库):
|
|
100
|
+
siluzan-cso rag query -q "抖音 爆款 钩子" --tags "流量因子库"
|
|
101
|
+
siluzan-cso rag query -q "产品 卖点 故事" --tags "产品资产库"
|
|
102
|
+
siluzan-cso rag query -q "内容结构 情绪" --tags "烹调方法库"
|
|
103
|
+
|
|
104
|
+
若知识库未打标签,直接不传 --tags,一次全量检索即可。
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
**示例 3:回答品牌知识问题**
|
|
108
|
+
```
|
|
109
|
+
用户意图 → "成功易是做什么的"
|
|
110
|
+
|
|
111
|
+
拆解检索(--folder-id 成功易ID,--tags ""):
|
|
112
|
+
"公司简介 主营业务"
|
|
113
|
+
"产品类型"
|
|
114
|
+
"服务对象 客户"
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
**拆词规则:**
|
|
118
|
+
- 每个子查询 **2–6 个字**,过长的句子效果反而差
|
|
119
|
+
- 避免重复语义("卖点"和"优势"只选一个)
|
|
120
|
+
- 优先具体名词,避免虚词(不要查"的"、"是"、"如何")
|
|
121
|
+
- 需要回答某个具体问题时,先查核心实体,再查修饰属性
|
|
122
|
+
|
|
123
|
+
---
|
|
124
|
+
|
|
125
|
+
### 5. 结果合成与使用
|
|
126
|
+
|
|
127
|
+
检索完成后,按以下方式处理多次检索的结果:
|
|
128
|
+
|
|
129
|
+
1. **去重**:相似度分数相同且内容高度重合的片段只保留一条
|
|
130
|
+
2. **分类归档**:按检索关键词分组(例如:卖点类、场景类、情绪类)
|
|
131
|
+
3. **优先级**:相似度分数(`score` 字段,越接近 0 越相关)较低的片段排前
|
|
132
|
+
4. **引用而非复制**:将片段作为信息来源重新组织表达,不直接粘贴原文
|
|
133
|
+
5. **结果为空时**:尝试更换关键词(同义替换、扩大范围),或告知用户知识库中暂无相关内容
|
|
134
|
+
|
|
135
|
+
---
|
|
136
|
+
|
|
137
|
+
## 完整调用示例
|
|
138
|
+
|
|
139
|
+
```bash
|
|
140
|
+
# 场景:用户问"帮我写一篇关于海科佳产品的抖音口播稿"
|
|
141
|
+
|
|
142
|
+
# Step 1: 找知识库
|
|
143
|
+
siluzan-cso rag list --rag-only --json
|
|
144
|
+
|
|
145
|
+
# Step 2: 假设找到 id=affe64c5...,多轮拆词检索(不传 --tags,全量)
|
|
146
|
+
siluzan-cso rag query -q "产品核心卖点" --folder-id affe64c5-d3d4-4cec-ab33-196035916894 --top-k 10
|
|
147
|
+
siluzan-cso rag query -q "用户痛点解决方案" --folder-id affe64c5-d3d4-4cec-ab33-196035916894
|
|
148
|
+
siluzan-cso rag query -q "产品使用场景" --folder-id affe64c5-d3d4-4cec-ab33-196035916894
|
|
149
|
+
|
|
150
|
+
# Step 3: 汇总结果,结合写稿流程生成口播稿
|
|
151
|
+
# (参考 three-lib-content-workflow/content-writer.workflow.md)
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
---
|
|
155
|
+
|
|
156
|
+
## 与三库工作流的关系
|
|
32
157
|
|
|
33
|
-
|
|
158
|
+
三库写稿流程(见 `three-lib-content-workflow/content-writer.workflow.md`)可以调用 RAG 检索作为素材来源。若知识库已按三库体系打标,可按标签精确分库:
|
|
34
159
|
|
|
35
|
-
|
|
160
|
+
| 三库 | 对应 `--tags` | 检索内容 |
|
|
161
|
+
|------|--------------|----------|
|
|
162
|
+
| 流量因子库 | `--tags "流量因子库"` | 平台趋势、爆款钩子、流量密码 |
|
|
163
|
+
| 产品资产库 | `--tags "产品资产库"` | 产品特性、卖点、品牌故事 |
|
|
164
|
+
| 烹调方法库 | `--tags "烹调方法库"` | 内容结构、创作手法、情绪设计 |
|
|
36
165
|
|
|
37
|
-
|
|
166
|
+
**若知识库未打三库标签,直接不传 `--tags`,全量检索后按内容性质自行归类。**
|
package/package.json
CHANGED