@yosai/cli 0.0.0-stage → 0.2.0

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,220 @@
1
+ ---
2
+ name: yos-retrieval
3
+ description: YOS 知识检索链路(search 定位 → read 取原文 → 带引用作答,含 grep/outline/neighbors 与 URN 规则、全参数表、真实报错)。用户问公司制度/流程/资料、要引用原文、要找某编号或条款、问有哪些文档时使用
4
+ ---
5
+
6
+ # YOS 检索链路(retrieve)
7
+
8
+ 五个原语:`search`(语义定位)→ `read`(取权威原文)→ `grep`(正则精确定位)→ `outline`(库清单/章节树)→ `neighbors`(配套文档)。
9
+
10
+ **引用铁律**:`search`/`grep`/`outline`/`neighbors` 的返回都只是线索,**能进答案的素材必须来自 `retrieve read` 的原文**,并附 `标题 + 行号区间 + URN`。
11
+
12
+ ## 0. URN 语法(所有 target 参数都按这个格式)
13
+
14
+ | 级别 | 格式 | 示例 |
15
+ |---|---|---|
16
+ | 库 | `cortex://kb/{kb_code}` | `cortex://kb/KB20260921000001` |
17
+ | 文档 | `cortex://kb/{kb_code}/doc/{node_code}` | `cortex://kb/KB20260921000001/doc/ND20260921000307` |
18
+ | 文档 + 行区间(仅 `read` 位置参数支持) | 上面 + `:起-止` | `...doc/ND20260921000307:40-100` |
19
+ | 章节 | 文档 URN + `/section/{层级编号}` | `...doc/ND20261010000030/section/1.1` |
20
+
21
+ 硬规则:
22
+
23
+ - **必须传完整 URN**,只传 `ND20261010000027` 短码不报错但拿不到内容:`{"results":[{"error":"非法 URN:ND20261010000027"}]}`(exit **0**);`outline`/`grep` 则报 `工具执行失败:非法 URN:ND20261010000027`(exit 1)
24
+ - URN 里的 `kb_code` 必须与该文档实际所属库一致,写错库 → `工具执行失败:文档不存在`
25
+ - `search` 返回的 `candidates[].urn` 可直接用于 `read`/`grep`/`outline`/`neighbors`,不要自己拼
26
+ - 检索结果里可能混入 cortex 侧编码(`cortex://kb/kb-meeting/doc/DOCMTMIO6W87DLS`):这类 URN **能 read 能引用**,但 `docs tree`/`docs content` 不认(属于另一套命名空间,CLI 无映射能力)。别承诺能在知识库目录里定位或搬运它
27
+ - `search` 的 `--kb` 传的是**库编码**(`KB2026...`),不是 URN
28
+
29
+ ## 1. CLI flag ↔ 工具参数对照(写错会被本地拦截并导航)
30
+
31
+ | 命令 | CLI flag | 工具参数 | 类型/范围 | 缺省 |
32
+ |---|---|---|---|---|
33
+ | search | 位置 `<query...>` | `query` | 1~4000 字,多词自动空格拼接 | 必填 |
34
+ | search | `--kb`(可重复) | `kb_ids` | JSON 数组,1~10 个库编码 | 当前用户可见全域 |
35
+ | search | `--dir`(可重复) | `dirs` | JSON 数组,1~50 个目录编码路径,如 `/ND001/ND005`,前缀匹配含子目录 | 不收窄 |
36
+ | search | `--top-k` | `top_k` | 1~25(传 999 静默钳 25,传 0 仍返 1 条,传负数报英文解析错) | 10 |
37
+ | search | `--entity`(可重复) | `entity_keywords` | JSON 数组,图谱实体名 | 不给 |
38
+ | search | `--topic`(可重复) | `topic_keywords` | JSON 数组,图谱主题词 | 不给 |
39
+ | search | `--type`(可重复) | `content_types` | JSON 数组,MIME,如 `application/pdf` | 不限 |
40
+ | search | `--labels` | `labels` | JSON 对象字符串,如 `{"部门":["风控"]}`:维度间 AND、维度内 OR,**取值只能取自候选已出现的标签** | 不收窄 |
41
+ | search | `--occurred-after/-before` | `occurred_after/before` | `yyyy-MM-dd`,含当日;下界会排除无事件日期的文档 | 不过滤 |
42
+ | search | `--effective-after/-before` | `effective_after/before` | `yyyy-MM-dd`;查某日当时适用版本要和 `--include-inactive` 同用 | 不过滤 |
43
+ | search | `--include-inactive` | `include_inactive` | 布尔开关(不传即 false) | false |
44
+ | grep | 位置 `<target> <pattern>` | `target`, `pattern` | **顺序是「先范围后正则」,与 Unix grep 相反**;RE2,≤256 字符,不支持反向引用/环视,库级须含字面词 | 必填 |
45
+ | grep | `--context` | `context` | 0~10 | 3 |
46
+ | grep | `--before` / `--after` | `before` / `after` | 0~10,非对称上下文,覆盖 `--context` 对应方向 | — |
47
+ | grep | `--ignore-case` | `case_insensitive` | 布尔(默认大小写敏感) | false |
48
+ | grep | `--mode` | `output_mode` | `content` \| `count`;`count` 仅文档级支持,库级 → `kb 级目标不支持 count 模式(count 仅 doc 级支持)` | content |
49
+ | grep | `--offset` | `offset` | 0~1000,按命中序分页,仅 content 模式 | 0 |
50
+ | grep | `--limit` | `limit` | 1~100 | 20 |
51
+ | read | 位置 `<target[:起-止]...>` | `items` | 1~10 项,第 11 项 → `错误: 单次最多读取 10 个区间(实际 11 个)` | 必填 |
52
+ | read | `--items` | `items` | 原样 JSON 数组,与位置参数**互斥**(同时传 → `错误: --items 与位置参数互斥`) | — |
53
+ | neighbors | 位置 `<target>` | `target` | 文档级 URN | 必填 |
54
+ | neighbors | `--kind` | `kind` | `related` \| `sibling`,**必填**;非法 → `参数非法(应为 sibling/related 之一):kind` | — |
55
+ | neighbors | `--limit` | `limit` | 1~50 | 20 |
56
+ | neighbors | `--include-inactive` | `include_inactive` | 布尔 | false |
57
+ | outline | 位置 `<target>` | `target` | 库级或文档级 URN | 必填 |
58
+ | outline | `--depth` | `depth` | 1~3,仅文档级生效 | 2 |
59
+ | outline | `--expand`(可重复) | `expand` | JSON 数组,章节层级编号如 `["2","2.1"]`;命中节点子树全量展开,仅对当前 `--depth` 窗口内可见节点生效 | — |
60
+ | outline | `--labels` | `labels` | 同 search,仅库级生效 | — |
61
+ | outline | `--occurred-*` / `--effective-*` | 同名 snake_case | `yyyy-MM-dd`,仅库级生效;缺该日期的文档不入清单并计入 `undated` | — |
62
+
63
+ ## 2. `retrieve search` — 入口
64
+
65
+ ```bash
66
+ yos retrieve search '报销标准' --json # 全域语义检索
67
+ yos retrieve search '报销标准' --kb KB20260921000001 --json # 限定单库
68
+ yos retrieve search '项目决议' --kb KB1 --kb KB2 --top-k 5 --json # 多库用重复 flag
69
+ yos retrieve search '8 月的项目决议' --json # 「上周」「8 月」直接给,服务端解析并在 timeWindow 回显
70
+ yos retrieve search '差旅制度' --occurred-after 2026-08-01 --occurred-before 2026-08-31 --json
71
+ yos retrieve search '旧版报销标准' --include-inactive --json # 查历史版本/失效文档
72
+ yos retrieve search '报销' --labels '{"部门":["风控"]}' --json # 候选过多时按已出现的标签收窄
73
+ ```
74
+
75
+ `<query>` 是变参:多词自动空格拼接成一个 query,**要整体加引号**避免被 shell 拆散;写成检索短语而非整段对话(服务端限 4000 字)。
76
+
77
+ 真实响应(逐字段,`--json` 时需二次解析信封):
78
+
79
+ ```json
80
+ {"traceId":"e163e48d...","candidates":[{
81
+ "urn":"cortex://kb/KB20260921000001/doc/ND20260921000307","kbId":"KB20260921000001","docId":"ND20260921000307",
82
+ "title":"福利政策","contentType":"text/plain","lineCount":12,"wordCount":193,"brief":true,
83
+ "snippet":"工作日加班至 22:00 以后,可申请报销交通费…\n非工作日加班时长超过 4 小时…",
84
+ "keywords":["可申请报","加班"],"labels":[],
85
+ "modifiedAt":"2026-10-08 14:19:52","occurredAt":null,"effectiveAt":null,"expiresAt":null,
86
+ "score":0.024705882352941175,"hitSpans":[{"lineStart":1,"lineEnd":11}]
87
+ }],"kg":{"entities":[{"name":"…","type":"…","description":"…"}],"relations":[{"source":"…","target":"…","description":"…","keywords":"…"}],"fragments":[{"urn":"…","title":"…","lineStart":1,"lineEnd":9,"text":"…"}]},
88
+ "reranked":false,"timeWindow":null,"tookMs":210}
89
+ ```
90
+
91
+ 消费要点:
92
+
93
+ - 候选**已按相关性排好序,按顺序消费,不要按 `score` 重排**
94
+ - `score` 数值很小(实测 0.015~0.033)且**无相关度下限**:库里没有对应内容时也会返回若干条不相关候选(实测搜「太空人津贴标准」返回 3 条,top1 score 0.0229)。**必须读 `snippet` 判断是否真相关**,全部不相关就说「没找到」,不要硬引用
95
+ - `hitSpans[].lineStart/lineEnd` 就是下一步 `read` 的行号依据(注意字段名是 `hitSpans`,不是 `hit_spans`)
96
+ - `brief: true` 表示该文档较短,可整篇读;`expiresAt`/`effectiveAt` 判时效,`expiresAt` 已过要提示用户「该文档可能已失效」
97
+ - 空结果不是定论:换关键词(同义词/上位词/更短的词)、放宽 `--kb`、去掉过滤再试一次,仍无才回答没有
98
+
99
+ ## 3. `retrieve read` — 取权威原文
100
+
101
+ ```bash
102
+ yos retrieve read 'cortex://kb/KB20260921000001/doc/ND20260921000307:40-100' --json
103
+ yos retrieve read 'cortex://kb/KB20260921000001/doc/ND20260921000307' --json # 缺省读 1~200 行
104
+ yos retrieve read 'cortex://...ND1:1-20' 'cortex://...ND2:5-30' --json # 多篇/多处一次读完(≤10 项)
105
+ yos retrieve read 'cortex://...ND.../section/2.1' --json # 按节读(含子节)
106
+ yos retrieve read --items '[{"target":"cortex://kb/KB1/doc/ND1","offset":10,"limit":50}]' --json
107
+ ```
108
+
109
+ - 位置参数的 `:起-止` 是 CLI 简写,会被换算成 `{target, offset, limit}`(`limit = 止-起+1`);`--items` 里**不支持** `:起-止` 简写,字段必须是 `{target, offset, limit}` 三个整数,写成 `line_start/line_end` → `Input should be a valid integer`
110
+ - 区间非法在本地就被拦:止 < 起 → `错误: 行号区间非法(止 < 起):<URN>:50-10` + `提示: 区间格式 <target>:起-止,如 cortex://kb/KB1/doc/ND1:10-50`(exit 2);起 < 1 同理
111
+ - 一次能读 1~10 项,**多处命中/多篇文档要合并进同一次调用**,不要拆成多次
112
+
113
+ 真实响应(每项独立成败,`error` 与 `fragment` 二选一):
114
+
115
+ ```json
116
+ {"traceId":"2b5fede8...","results":[{
117
+ "target":"cortex://kb/KB20260921000001/doc/ND20260921000307:1-5",
118
+ "error":null,
119
+ "fragment":{"urn":"…","kbId":"…","docId":"…","title":"福利政策","updatedAt":"…",
120
+ "occurredAt":null,"effectiveAt":null,"expiresAt":null,
121
+ "lineStart":1,"lineEnd":5,"text":"工作日加班至 22:00 以后,可申请报销交通费…","sectionPath":[],"page":null},
122
+ "pageBreaks":[],"lineCount":5,"hasMore":false,"truncated":false}]}
123
+ ```
124
+
125
+ - `results` 顺序与传入项一一对应;某项失败不影响其他项
126
+ - 常见 `error` 文案:`非法 URN:<原样>`、`章节不存在;该文档可用编号:(该文档无章节结构,用 doc URN 按行号读)`(此时改用文档 URN + 行号)
127
+ - **`exit=0` 但 `results[].error` 非空就是失败**,逐检查再作答
128
+ - 续读判据:`hasMore` 或 `truncated` 为 `true` → 下一次 `offset = fragment.lineEnd + 1`
129
+ - `sectionPath`/`page` 用于给出「第 2.1 节 / 第 3 页」这类出处
130
+
131
+ ## 4. `retrieve grep` — 一字不差的定位
132
+
133
+ ```bash
134
+ yos retrieve grep 'cortex://kb/KB20260921000001/doc/ND20260921000307' '22:00' --json
135
+ yos retrieve grep 'cortex://kb/KB20260921000001' '渝欧文字第.*号' --context 2 --json # 不知道在哪篇 → 库级定位
136
+ yos retrieve grep 'cortex://...doc/ND...' '报销' --mode count --json # 数命中行总数(仅文档级)
137
+ yos retrieve grep 'cortex://...doc/ND...' 'xyz' --ignore-case --json
138
+ yos retrieve grep 'cortex://...doc/ND...' -- '-123' --json # pattern 以 - 开头必须用 -- 分隔
139
+ ```
140
+
141
+ - 参数顺序 **`<target> <pattern>`**,与 Unix `grep <pattern> <file>` 相反。写反了会报 `工具执行失败:非法 URN:宁缺毋滥`(exit 1)——把报错里的短串当成 target 就说明顺序错了
142
+ - 文档级按行号升序返回;库级按相关性排序且**不保证列全**(`truncated: true` 表示还有未列出,要列全改用 `outline`)
143
+ - `--mode count` 只支持文档级;库级报错 `kb 级目标不支持 count 模式(count 仅 doc 级支持)`
144
+ - `--mode` 非法值报 `参数非法(应为 content/count 之一):output_mode`
145
+
146
+ 真实响应:
147
+
148
+ ```json
149
+ {"traceId":"…","target":"cortex://kb/KB20260921000001","matches":[
150
+ {"urn":"cortex://...doc/ND20260928000002","line":8,"lineStart":8,"lineEnd":9,"text":"| 李四 渝欧智选 2026/9/16 待复核 | …"}],
151
+ "matchCount":null,"truncated":false}
152
+ ```
153
+
154
+ **`matchCount` 实测恒为 `null`**,不要用它判命中数;命中数看 `matches.length`,总数诉求用 `--mode count`(文档级)。
155
+
156
+ ## 5. `retrieve outline` — 列全与结构
157
+
158
+ ```bash
159
+ yos retrieve outline 'cortex://kb/KB20260921000001' --json # 库级:文档清单(回答「有哪些/共几份」)
160
+ yos retrieve outline 'cortex://kb/KB20260921000001/doc/ND20261010000030' --depth 3 --json # 文档级:章节树
161
+ yos retrieve outline 'cortex://...doc/ND...' --expand 2 --expand 2.1 --json # 渐进展开某支
162
+ ```
163
+
164
+ 库级响应:`{"traceId":"…","target":"…","docs":[{"urn":"…","docId":"…","title":"…","labels":[],"occurredAt":null,"effectiveAt":null,"expiresAt":null,"lineCount":12}],"sections":[],"total":3,"truncated":false,"undated":0}`
165
+
166
+ 文档级响应:`{"…","docs":[],"sections":[{"urn":"cortex://...doc/ND.../section/1","title":"技能文档实测","lineStart":1,"lineEnd":7,"firstSentence":"## 一、段落","children":[{"urn":"…/section/1.1","title":"一、段落","…":[]}],"childrenTruncated":false}],"total":0,"truncated":false,"undated":0}`
167
+
168
+ 要点:
169
+
170
+ - `docs[].lineCount` 用来决定「整篇读」还是「按节读」(短的直接 `read` 全文)
171
+ - `total` 与 `docs.length` 不等时说明被截断(`truncated: true`),要加日期/标签过滤或翻页式收窄
172
+ - 库级清单**不按时效过滤**,自己看 `expiresAt`;`undated` 是缺日期被排除的篇数
173
+ - 无标题层级的文档返回 `sections:[], total:0` —— 这是文档本身没结构,不是故障,改用文档 URN 按行号读
174
+ - `sections[].urn` 可直接作为 `read` 的节级 target;`sections[].lineStart/lineEnd` 可作为行区间 target
175
+
176
+ ## 6. `retrieve neighbors` — 找配套材料
177
+
178
+ ```bash
179
+ yos retrieve neighbors 'cortex://kb/KB20260921000001/doc/ND20260921000307' --kind related --json
180
+ yos retrieve neighbors 'cortex://...doc/ND...' --kind sibling --limit 10 --json
181
+ ```
182
+
183
+ `--kind` 必填:`related` 按正文内容跨目录找最相关(多数场景用它,返回 `score` 与 `sharedEntities`);`sibling` 仅列同目录兄弟、按入库时间倒序(只在已知该库按批次分目录归档时用)。
184
+
185
+ 响应:`{"traceId":"…","target":"…","siblings":[],"related":[{"urn":"…","title":"…","score":0.31,"sharedEntities":["报销"],"expiresAt":null}],"truncated":false,"tookMs":…}`
186
+
187
+ 邻居只是线索,要引用仍需 `read` 取原文。
188
+
189
+ ## 7. 标准工作流(找答案带引用)
190
+
191
+ ```bash
192
+ # 1) 定位
193
+ yos retrieve search '加班 交通费 报销 标准' --json
194
+ # → 读 snippet 判断相关性;记录 candidates[0].urn 与 hitSpans
195
+ # 2) 精读命中段(多处/多篇合并一次调用)
196
+ yos retrieve read 'cortex://kb/KB20260921000001/doc/ND20260921000307:1-11' 'cortex://kb/KB.../doc/ND...:5-40' --json
197
+ # 3) hasMore/truncated 为 true 就续读(offset = lineEnd+1)
198
+ # 4) 答案里给出:结论 + 《标题》第 1-11 行 + URN
199
+ # 需要更全的上下文时插入:outline(章节定位)/ grep(编号条款)/ neighbors(配套材料)
200
+ ```
201
+
202
+ ## 8. 报错速查
203
+
204
+ | 报错原文(截取自实测) | 真因 | 正确写法 |
205
+ |---|---|---|
206
+ | `错误: 缺少参数 <query>`(exit 2) | 没给检索词 | `yos retrieve search '<词>'` |
207
+ | `错误: --top_k 是底层工具参数名,命令内请用 --top-k`(exit 2) | flag 写成 snake_case | 用 kebab-case:`--top-k` `--ignore-case` `--include-inactive` |
208
+ | `错误: --top-k 低于下限 1:-1`;裸写 `-1` 时报 `错误: 参数 --top-k 的取值以 - 开头,需写成 --top-k=<值>`(exit 2) | 传了 0 或负数 | 只传 1~25 |
209
+ | `错误: target 不是合法 URN:ND20261010000027`(exit 2) | target 传了短码 | 补成 `cortex://kb/<kbCode>/doc/<nodeCode>`,从 `search` 结果直接取 |
210
+ | `错误: 行号区间非法(止 < 起):…`(exit 2) | `:50-10` | 起 ≤ 止,行号从 1 开始 |
211
+ | `错误: 单次最多读取 10 个区间(实际 11 个)`(exit 2) | 一次读太多 | 拆两次调用 |
212
+ | `错误: --items 与位置参数互斥`(exit 2) | 两种传法混用 | 二选一 |
213
+ | `错误: 参数顺序疑似颠倒:第 1 个参数不是 URN`(exit 2) | grep 参数顺序颠倒 | `yos retrieve grep <target> <pattern>` |
214
+ | `kb 级目标不支持 count 模式(count 仅 doc 级支持)`(exit 1) | 库级数命中 | 改文档级 URN,或用 `matches.length` |
215
+ | `章节不存在;该文档可用编号:(该文档无章节结构,用 doc URN 按行号读)` | 对无标题文档传 section URN | 用文档 URN + 行区间 |
216
+ | `错误: 缺少 --kind`(exit 2) | neighbors 漏必填 | `--kind related` |
217
+
218
+ ## 9. 做不到的事(别反复试)
219
+
220
+ 无跨转写全文检索(`retrieve` 不覆盖会议记录,转写正文走 `yos transcript detail`);无 `--min-score` 相关度阈值;无按编辑时间排序;不能把检索结果的 `score` 当成可信度百分比对外表述。
@@ -0,0 +1,185 @@
1
+ ---
2
+ name: yos-shared
3
+ description: YOS CLI 共享约定(登录配置、--json 双重解析、退出码、报错分类、通用参数规则、安全与权限)。使用任何 yos 命令前读本文件;遇到报错或不确定参数写法也查这里
4
+ ---
5
+
6
+ # YOS CLI 共享约定
7
+
8
+ 命令形态:`yos <领域> <动作> [位置参数] [--flag 值]`。领域:`kb` / `docs` / `retrieve` / `support` / `transcript` / `tool` / 基础命令(login、doctor、ping、skill)。
9
+
10
+ ## 1. 前置检查(会话内只做一次)
11
+
12
+ ```bash
13
+ yos doctor # 七项全 ✓ 才能继续;任一项 ✗ 按下方「未登录/连通失败」处理
14
+ ```
15
+
16
+ `yos doctor` 真实输出(七项检查,退出码即结论):
17
+
18
+ ```
19
+ ✓ 配置文件: 已找到
20
+ ✓ 服务端点: https://yos-bff.linkduoo.com(来自 内置缺省)
21
+ ✓ 访问令牌: xxxxxxxx****xxxx
22
+ ✓ 服务连通: 身份 张三(U00000001)
23
+ ✓ Skill 安装: ~/.claude/skills, ~/.qoder-cn/skills
24
+ ✓ CLI 版本: 0.2.0(endpoint=https://yos-bff.linkduoo.com)
25
+ ✓ Skill 同步: 与 CLI 一致(2 个目录)
26
+ ```
27
+
28
+ | doctor 结果 | 处理 |
29
+ |---|---|
30
+ | `command not found: yos` | CLI 未安装或全局 bin 不在 PATH,按 `yos-install` skill 引导安装(`npm install -g @yosai/cli` → `yos login` → 验证),不要继续猜命令 |
31
+ | `✗ 配置文件: 未找到,请执行 yos login` | 执行 `yos login --key <令牌>`(令牌由用户在 YOS 客户端「个人设置-访问令牌」页创建并复制,40 位小写 hex) |
32
+ | `✗ 访问令牌: 未配置访问令牌` | 同上;CI/容器可改为设置环境变量 `YOS_API_KEY` |
33
+ | `✗ 服务连通: ...` | 看错误类型:网络不可达(退出码 3)→ 检查端点与网络;鉴权失败(4)→ 令牌失效,重新 `yos login` |
34
+ | `✗ Skill 安装: 尚未安装,执行 yos skill install` | 执行 `yos skill install`,未探测到目录时 `--target ~/.claude/skills` |
35
+
36
+ 配置细节(排障时才需要):
37
+
38
+ - 配置文件 `~/.config/yos/config.json`(目录 0700、文件 0600),字段 `{endpoint, apiKey, installedSkillDirs}`
39
+ - 环境变量优先级:`YOS_API_KEY` > 配置文件 `apiKey`;`YOS_ENDPOINT` > 配置文件 `endpoint`;`YOS_CONFIG_DIR` 覆盖配置目录(测试隔离用)
40
+ - 端点缺省 `https://yos-bff.linkduoo.com`,切换用 `yos login --endpoint <url>`(本地联调 `http://localhost:8080`);实际请求基址为 `<endpoint>/open-apis`
41
+ - 令牌格式先本地校验:`yos login` 粘贴了非 40 位小写 hex 会直接报 `错误: 令牌格式不正确(应为 40 位小写 hex)`,不会落盘
42
+
43
+ **安全**:绝不把令牌写进命令历史可见的日志、代码仓库或对用户的回复里;`--key` 传令牌仅用于无交互场景,回复中一律用掩码形式(`xxxxxxxx****xxxx`)。
44
+
45
+ ## 2. 输出与解析规则(最容易踩坑)
46
+
47
+ | 形态 | 实际内容 | 解析方式 |
48
+ |---|---|---|
49
+ | 默认(不加 `--json`) | 直接打印服务端返回文本:多数命令是**单行紧凑 JSON**,少数是纯文本提示;`kb list` 特化为两列表格(`KB编码 名称`) | 人读用;给程序处理请改用 `--json` |
50
+ | `--json` | 固定信封 `{"text": "...", "isError": false}` | **需要二次解析**:`text` 是 JSON **字符串**,业务数据要再 `JSON.parse(text)`;`isError: true` 时 `text` 是错误文案(纯文本,不可 parse) |
51
+
52
+ ```bash
53
+ # 取第一个知识库编码(信封 → text → records 三层)
54
+ yos kb list --json | node -e 'let d="";process.stdin.on("data",c=>d+=c).on("end",()=>{const r=JSON.parse(JSON.parse(d).text);console.log(r.records[0].kbCode)})'
55
+ ```
56
+
57
+ 字段命名不统一,按命令区分(不要凭感觉改大小写):
58
+
59
+ - 知识库/文档/转写/升级等业务对象:`camelCase`(`kbCode`、`kbName`、`resourceCode`、`transcriptionUserId`、`releaseDate`)
60
+ - 检索原语(retrieve)响应:`camelCase`(`hitSpans`、`lineStart`、`hasMore`、`childrenTruncated`),但 `retrieve_read` 的**入参** `items` 内是 `snake_case`(`target`/`offset`/`limit`)
61
+ - 分页壳不统一:`kb list` / `support upgrade-log` 是 `{records, total, page, size}`;`transcript list` 是 `{list, total, current, size, pages}`
62
+
63
+ 标识编码的真实形态(构造示例或校验时照此,不要写成 `KBxxx`):
64
+
65
+ | 编码 | 形态 | 示例 |
66
+ |---|---|---|
67
+ | 知识库 `kbCode` | `KB` + yyyyMMdd + 6 位序号 | `KB20260921000001` |
68
+ | 节点 `resourceCode` / `nodeCode` | `ND` + yyyyMMdd + 6 位序号 | `ND20260921000307` |
69
+ | 检索 URN | `cortex://kb/{kbCode}/doc/{nodeCode}` | `cortex://kb/KB20260921000001/doc/ND20260921000307` |
70
+ | 转写记录 ID | 19 位数字字符串 `transcriptionUserId` | `2105108032979103745` |
71
+ | 手册节点 ID | 19 位数字(`support manual` 目录树里的 `id`) | `2100513671581945858` |
72
+
73
+ **两套编码命名空间不互通**(跨域引用时的硬约束):
74
+
75
+ | 侧 | 形态 | 能被哪些命令用 |
76
+ |---|---|---|
77
+ | BFF 侧 | `KB20260921000001` / `ND20260921000307` | `kb *`、`docs *`、`retrieve *` 全部可用 |
78
+ | cortex 侧 | `kb-meeting` / `DOCMTMIO6W87DLS`(检索结果里也可能出现) | 只有 `retrieve read/grep/outline/neighbors` 认;`docs tree kb-meeting` → `知识库不存在:kb-meeting`(exit 1),`docs content DOCMTMIO6W87DLS` → `文档不存在`(exit 1) |
79
+
80
+ CLI 对两套编码原样透出不做映射。遇到 cortex 侧编码时:可正常读原文与引用作答,但**不要**承诺能在知识库目录里定位它或移动/归类它,需向用户说明该来源不在知识库管理范围内。
81
+
82
+ ## 3. 退出码(用于判定,不要只看输出文本)
83
+
84
+ | 码 | 含义 | 真实样例(stderr 或 stdout) | 动作 |
85
+ |---|---|---|---|
86
+ | 0 | 成功 | — | 继续 |
87
+ | 1 | 业务失败(服务端拒绝/资源不存在) | `工具执行失败:知识库不存在:KB不存在`<br>`节点类型不符:ND... 实际是文档,本操作要求文件夹` | 按文案修参数,不要盲目重试 |
88
+ | 2 | 参数/用法错误(CLI 本地拦截,未发请求) | `错误: 缺少 --kind`<br>`提示: 用法: yos retrieve neighbors <target> --kind <值> ...` | 照 `提示:` 里的用法改写 |
89
+ | 3 | 网络错误/服务不可达 | `错误: fetch failed`(或超时文案) | 确认端点与网络连通,`yos ping` 复测 |
90
+ | 4 | 鉴权失败 | `错误: 鉴权失败...`<br>`提示: 请执行 \`yos login\` 重新配置访问令牌` | 令牌无效/吊销/过期 → 让用户重新创建后 `yos login` |
91
+
92
+ `1` 与 `2` 的关键差别:**2 根本没发请求**,改法一定写在 `提示:` 里;**1 是服务端结论**,文案里带具体编码,直接引用给用户。
93
+
94
+ exit=1 的文案偶有服务端内部字段名(如 `kb_code`、`output_mode`),与 CLI 的 `--kb`、`--mode` 不一一对应;按下面的各领域说明翻译成 CLI 参数,不要照抄进命令。
95
+
96
+ ## 3.5 仍需自行校验内容的场景(exit=0 但结果可能不可用)
97
+
98
+ 参数类错误已由 CLI 本地拦截为 exit=2(枚举非法、数值越界、日期倒置、URN 非法、必填缺失一律不发请求),退出码可信。以下场景**退出码为 0,但结果需要校验后再下结论**:
99
+
100
+ | 命令 | 行为 | 必做的校验 |
101
+ |---|---|---|
102
+ | `retrieve search` | 低分候选照常返回(实测 score 0.016 的不相关文档也在列表里) | 看 `score`,低于 0.3 的结果不要当依据;必要时 `retrieve read` 核对原文 |
103
+ | `docs content`(上传的 file 类型节点) | `content` 为空,返回体带 `contentHint` 说明该节点无内联正文 | 读上传文件正文改用 `retrieve read`,取原文件用 `docs download` |
104
+ | `retrieve grep --mode count` | `matchCount` 可能为 null(cortex 侧未回该字段) | 需要命中数时用 `--mode content` 数 `matches` 长度 |
105
+ | 任何检索/查询 | 空结果与「参数写错但恰好合法」不可区分(如 `--kb` 传了无权限的库) | 结果为空时先确认编码与权限,再回答「没有相关资料」 |
106
+
107
+ **规则**:命令成功(exit=0)≠ 拿到数据。任何用于回答或后续写入的结果,都要检查关键字段非空、计数符合预期,再向用户下结论。
108
+
109
+ 数值型 flag(`--top-k` / `--page` / `--size` / `--limit` / `--context`)**不接受负数**:传 `-1` 报 `错误: --top-k 低于下限 1:-1`(exit=2)。负数没有合法语义,直接改成正数或去掉该参数。取值以 `-` 开头时必须写成 `--top-k=-1` 形式,否则报 `参数 --top-k 的取值以 - 开头,需写成 --top-k=<值>`。
110
+
111
+ ## 4. 通用参数规则
112
+
113
+ - **flag 名用 kebab-case,位置参数名/工具参数名是 snake_case**。写了底层参数名会被本地拦截并导航:
114
+ ```
115
+ $ yos retrieve search 报销 --top_k 5
116
+ 错误: 未知参数 --top_k
117
+ 提示: --top_k 是底层工具参数名,命令内请用 --top-k(yos retrieve search --help 查看完整参数)
118
+ ```
119
+ - **可重复 flag**(`--kb` / `--dir` / `--entity` / `--topic` / `--type` / `--expand`)重复传即聚合为 JSON 数组字符串,无需自己写 `[...]`:`--kb KB1 --kb KB2`
120
+ - **数字 flag** 传非数字:`错误: --top-k 需要数字,实际:abc`(退出码 2)
121
+ - **以 `-` 开头的位置参数**用 `--` 分隔:`yos retrieve grep -- "-特殊"`
122
+ - **未知参数/子命令都有引导**:`yos <领域> <猜的动作>` 会打印该域全部子命令(退出码 2);`yos <猜的领域>` 打印总帮助。看到这类输出说明命令名写错,照清单改,不要换写法再猜
123
+ - 所有域命令都支持 `--json`;`--help` 输出「用法 / 说明 / 参数 / 风险」四段,风险标注为 `只读` / `写入` / `高危`
124
+
125
+ ## 5. 编码发现路径(先拿编码,再执行)
126
+
127
+ 不要凭记忆或猜测拼编码,按链路取真值:
128
+
129
+ ```bash
130
+ yos kb list # → kbCode(表格左列)
131
+ yos docs tree KB20260921000001 # → resourceCode(树里每个节点的编码)
132
+ yos retrieve outline 'cortex://kb/KB20260921000001' # → 文档 URN(含行号,检索决策用)
133
+ yos transcript list # → transcriptionUserId
134
+ yos support manual # → 手册节点 id
135
+ ```
136
+
137
+ `--keyword` 缩小范围:`yos kb list --keyword 报销`。
138
+
139
+ ## 6. 权限与写操作规则
140
+
141
+ 服务端按知识库角色校验,CLI 不做本地校验,权限不足直接返回业务失败(退出码 1):
142
+
143
+ | 操作 | 最低角色(实测取值) |
144
+ |---|---|
145
+ | `docs mkdir` / `docs create` / `docs update` / `docs rename` | `edit`(编辑者)及以上 |
146
+ | `docs move` / `docs delete` / `docs restore` / `kb update` | `admin`(管理员)及以上 |
147
+ | `kb list` / `docs tree` / `retrieve *` / `transcript *` / `support manual*` / `upgrade*` | 只读即可 |
148
+
149
+ - `kb list` / `docs tree` 返回的 `role` 字段实测取值:`owner`(所有者)/ `admin` / `edit` / `read`(只读分享),无直接角色时为 `null`
150
+ - 权限不足是**运行时**返回的业务失败(exit 1),文案形如 `没有该资源的访问权限:MOVE_DELETE_RESOURCE.ND20261010000018`:含节点编码但不告诉你缺什么角色。正确做法:先 `yos kb detail <kbCode>` 看 `role`,再决定是否执行;只有 `read`/`null` 时直接告知用户需要申请编辑或管理权限
151
+ - **建库与删库都不在 CLI 内**(服务端未提供 `kb_create` / `kb_delete` 工具):用户要新建或删除知识库,引导其去 YOS 客户端手动操作;建好库后用 `yos kb list` 取编码继续后续动作
152
+ - `retrieve` 只能命中当前用户可见的文档:跨库检索范围随登录身份变化,换令牌结果就不同
153
+
154
+ ## 7. 删除与安全纪律(强制)
155
+
156
+ 1. 删除前必须先查影响面并向用户报告,拿到明确确认才执行:
157
+ ```bash
158
+ yos docs count ND20260921000163 # → {"affected_document_count":N}
159
+ ```
160
+ 未确认前执行删除属于越权操作,禁止。
161
+ 2. `docs delete` 是级联操作(文件夹连带全部子孙进回收站,90 天可恢复);恢复用 `yos docs restore ND1 ND2 ...`(≤100 个,只能恢复顶层删除项)
162
+ 3. 写入类命令(`kb update`、`docs mkdir/create/update/rename/move/restore`、`kb upload`、`support feedback`)在用户没有明确要求时不擅自执行;`support feedback` 会真实提交工单,必须原文让用户确认内容后再发
163
+ 4. 正文内容含用户数据时注意:`--content` 会进入 shell 历史,长文本/多行文本一律改走 `--file <路径>`
164
+
165
+ ## 8. 底层工具通道(领域命令覆盖不到时才用)
166
+
167
+ ```bash
168
+ yos tool list # 全部工具,按领域分组(动态获取,以实际输出为准)
169
+ yos tool schema retrieve_search # 完整描述 + 入参表 + 返参 + 调用示例
170
+ yos tool call docs_tree --params '{"kb_code":"KB20260921000001"}'
171
+ ```
172
+
173
+ - `tool schema` 的入参说明会截断到 50 字,要全文用 `--json`:`yos tool schema retrieve_search --json`
174
+ - `tool call` 的 `--params` 必须是合法 JSON 字符串,参数名用工具 schema 里的 **snake_case**
175
+ - 工具名容忍空格与连字符写法:`yos tool schema docs tree` / `support manual-read` 都会归一化为 `docs_tree` / `support_manual_read`
176
+ - 域命令是工具的一一映射(`kb upload` 除外,走 multipart 直传),能用域命令就别用 `tool call`
177
+
178
+ ## 9. 升级与重装
179
+
180
+ ```bash
181
+ npm install -g @yosai/cli # 公共 npmjs,需 Node >= 18(见 yos-install)
182
+ yos skill install # 升级后必须重装 Skill,让 Agent 目录里的说明同步
183
+ ```
184
+
185
+ `yos skill install` 会覆盖写入各 Agent 技能目录,装完需**重启 Agent 工具**才生效;`yos doctor` 的「Skill 安装」项可确认已安装目录。
@@ -0,0 +1,141 @@
1
+ ---
2
+ name: yos-support
3
+ description: YOS 帮助与支持(manual/manual-read/manual-search 帮助手册,upgrade/upgrade-log 客户端版本,feedback 提交反馈)。用户问 YOS 怎么用、要客户端最新版本、要报问题时使用
4
+ ---
5
+
6
+ # YOS 帮助与支持(support)
7
+
8
+ 五个只读命令 + 一个写命令。手册回答「YOS 怎么用」,`upgrade*` 回答「客户端最新版是什么」,`feedback` 把诉求登记给客服。
9
+
10
+ **领域内 ID 精度坑(三条命令都涉及)**:`manual` 目录树里的 `id` 是**带引号的字符串**,可安全使用;`manual-read` 与 `manual-search` 返回的 `id` 是**无引号的 19 位数字**,一旦 `JSON.parse` 就丢精度(`2100513671581945858` → `2100513671581945900`)。因此节点 ID 一律**从 `yos support manual` 的目录树取**,不要把 search/read 输出解析后再回传给 `manual-read`。
11
+
12
+ ## 1. `support manual` — 手册目录树(先调这个)
13
+
14
+ ```bash
15
+ yos support manual # 无参数,返回完整树
16
+ ```
17
+
18
+ 真实响应(数组,非分页壳):
19
+
20
+ ```json
21
+ [{"id":"2100511993159897090","parentId":null,"type":"FOLDER","title":"开始使用","sortOrder":0,
22
+ "children":[{"id":"2100513671581945858","parentId":"2100511993159897090","type":"FILE","title":"YOS 是什么","sortOrder":0,"children":[]},
23
+ {"id":"2100511408478113794","type":"FILE","title":"快速开始","sortOrder":1,"children":[]}]}]
24
+ ```
25
+
26
+ - `type`:`FOLDER`(无正文)/ `FILE`(文章)。只有 `FILE` 的 `id` 能传给 `manual-read`
27
+ - 递归字段是 `children`(叶子为 `[]`,不是 `null`);`parentId` 顶层为 `null`
28
+ - 全文目录一次性返回,没有分页参数、没有关键字过滤 → 想按标题找文章就在本地遍历 `title`,或直接改用 `manual-search`
29
+
30
+ ## 2. `support manual-read <node_id>` — 读文章正文
31
+
32
+ ```bash
33
+ yos support manual-read 2100513671581945858 # 「YOS 是什么」
34
+ ```
35
+
36
+ | 位置参数 | 工具参数 | 说明 |
37
+ |---|---|---|
38
+ | `<node_id>` | `node_id` | 文章节点 ID,来自 `manual` 目录树的 `id` 字段(字符串那一份) |
39
+
40
+ 正常响应:
41
+
42
+ ```json
43
+ {"id":2100513671581945858,"type":"FILE","title":"YOS 是什么","content":"YOS 是渝欧数智自主研发的企业级 AI 操作系统,……"}
44
+ ```
45
+
46
+ - `content` 是**富文本清洗后的纯文本**:没有 Markdown 标题符号、列表符号和图片地址,向用户复述时可直接引用,但不要承诺格式还原
47
+ - 传 `FOLDER` 节点的 ID **不报错(exit 0)**,返回 `{"id":…,"type":"FOLDER","title":"开始使用","content":"","message":"文件夹无正文,请根据目录树选择其下的文章节点"}` → 见到 `content:""` 就回目录树换 `FILE` 节点,别重复请求
48
+ - ID 不存在:`工具执行失败:帮助手册节点不存在:999`(exit 1)→ 说明 ID 取错或精度已丢,重新从 `manual` 取
49
+
50
+ ## 3. `support manual-search <keyword>` — 关键词检索
51
+
52
+ ```bash
53
+ yos support manual-search 登录
54
+ yos support manual-search 知识库
55
+ ```
56
+
57
+ | 位置参数 | 工具参数 | 说明 |
58
+ |---|---|---|
59
+ | `<keyword>` | `keyword` | 单个关键词。标题或正文命中其一即算,大小写不敏感;**没有分词/多词/正则能力** |
60
+
61
+ 真实响应:
62
+
63
+ ```json
64
+ {"keyword":"登录","total":6,"records":[
65
+ {"id":2100513705551613953,"title":"常见问题","path":"帮助","snippet":"按主题分组。找不到答案时,通过问题反馈提交。\n\n安装与登录\n\n下载被浏览器拦截\n\n用 Chrome 下载;提示有害时点击 操作 → 保留 → …"}]}
66
+ ```
67
+
68
+ - `path` 是**所在目录名**(如 `帮助`),不是完整路径链;要层级关系回到 `manual` 树里查
69
+ - `snippet` 是正文摘录,**不等于全文**:确定要引用的操作细节必须再用 `manual-read`(ID 从 `manual` 取)
70
+ - 实测各主题命中量:`转写=10`、`更新=9`、`设置=8`、`版本=7`、`登录=6`、`知识库=5`、`上传=4`
71
+ - **`total:0` 是常见结论,不是失败**:实测 `令牌` 和 `访问令牌` 都是 `0`(手册里没有访问令牌主题)。此时直接按 `yos` 总入口的登录步骤回答(客户端「个人设置-访问令牌」),不要反复换近义词空转
72
+ - 检索是**子串式关键词匹配**:`--` 之类符号、英文短语(`MCP`)请按用户原词与可能的中英文写法各试一次,两次为 `0` 就停手走 `feedback`
73
+
74
+ ## 4. `support upgrade` / `support upgrade-log` — 客户端版本
75
+
76
+ ```bash
77
+ yos support upgrade --platform MAC_ARM64 # 该平台对当前用户可见的最新版
78
+ yos support upgrade-log # 全部升级记录(新发布在前)
79
+ yos support upgrade-log --platform WIN --page 1 --size 5
80
+ yos support upgrade-log --start 2026-10-01 --end 2026-10-10 # 按发布日期区间
81
+ ```
82
+
83
+ | flag | 工具参数 | 说明 | 缺省 |
84
+ |---|---|---|---|
85
+ | `--platform` | `platform` | `upgrade` **必填**;`upgrade-log` 可选(不传=全平台)。取值只有 `WIN` / `MAC_X64` / `MAC_ARM64`,**没有 LINUX** | — |
86
+ | `--start` / `--end` | `start_date` / `end_date` | 严格 `yyyy-MM-dd`,含当日;中文时间表达需自行换算。格式非法 → `错误: --start 日期格式应为 yyyy-MM-dd:本周`;起晚于止 → `错误: 日期区间非法:--start 晚于 --end`(均 exit 2) | 不过滤 |
87
+ | `--page` / `--size` | `page` / `size` | `size` 1~50,越界 → `错误: --size 低于下限 1:0` + `提示: 取值范围 1~50`(exit 2) | 1 / 10 |
88
+
89
+ 真实响应:
90
+
91
+ ```json
92
+ // upgrade
93
+ {"id":"2108510276780978177","version":"v0.2.0-test.14","platform":"MAC_ARM64","platformName":"macOS Apple Silicon 版",
94
+ "releaseDate":"2026-10-09","isForceUpdate":false,"content":null}
95
+
96
+ // upgrade-log
97
+ {"records":[{"id":"2108722559616446465","version":"v0.2.0-test.14","platform":"WIN","platformName":"Windows",
98
+ "releaseDate":"2026-10-10","isForceUpdate":false,"content":""}],
99
+ "total":107,"page":1,"size":2}
100
+ ```
101
+
102
+ - 平台取值只有三个,写错由 CLI 本地拦下(不发请求,exit 2):`错误: --platform 取值非法:NOSUCH` + `提示: 可选:WIN / MAC_X64 / MAC_ARM64`;`upgrade` 漏传 → `错误: 缺少 --platform`(exit 2)
103
+ - `content` 是**公告全文纯文本**,但**可能为 `null` 或 `""`**(实测两平台同版本一为 `null` 一为 `""`)→ 没有公告时只报版本号与日期,不要编造更新内容;用户问「更新了什么」就换 `upgrade-log` 找有公告的记录
104
+ - `upgrade` 只给三平台的当前可见最新版,**灰度中的版本仅白名单用户可见**:用户说「同事有 x 版本我没有」时,先 `upgrade-log` 确认该版本是否存在,再解释灰度,不要判定为版本不存在
105
+ - `isForceUpdate` 对应客户端是否强制更新,回答升级建议时值得带上
106
+ - 返回的 `version` 是 **YOS 桌面客户端**版本(形如 `v0.2.0-test.14`,测试环境带 `-test`),与 `@yosai/cli` 自身的 npm 版本是两回事(CLI 自身版本用 `yos version` 查),不要混用
107
+
108
+ ## 5. `support feedback '<内容>'` — 提交反馈(写操作)
109
+
110
+ ```bash
111
+ yos support feedback '知识库上传 20MB 以上的 PDF 会失败,希望支持大文件分片'
112
+ yos support feedback -- '转写结果说话人识别不准,希望提供纠错入口' # 内容以 - 开头时必须加 --
113
+ ```
114
+
115
+ - 位置参数 `content`(variadic,多个位置参数以空格拼接为一个字符串),上限 **2000 字**
116
+ - **写入类操作**:内容会自动关联当前用户与其所属企业并进入客服工单流程。调用前必须把最终原文给用户看过并取得明确同意
117
+ - 空内容:`错误: 反馈内容不能为空` + `提示: 用法: yos support feedback <内容...>`(exit 2);超 2000 字:`错误: 反馈内容超长(实际 2001 字,上限 2000 字)`(exit 2)→ 压缩为一条诉求或拆成多次提交(先问用户)
118
+ - 成功:`反馈提交成功,反馈编号:2108742524868513794` → 把编号回给用户,这是唯一可追溯凭证
119
+ - **编号无法再查询**:CLI 没有反馈详情/进度/撤回命令,提交后不要承诺「帮你跟进这条反馈的状态」
120
+ - 无附件:日志、截图只能靠用户在客户端内提交,CLI 路径只收文本
121
+
122
+ ## 6. 标准流程
123
+
124
+ ```bash
125
+ # 用户问「YOS 怎么用 / X 功能在哪」
126
+ yos support manual-search '<关键词>' # 1. 定位候选文章
127
+ yos support manual # 2. 从目录树取该文章 id(字符串形态那份)
128
+ yos support manual-read <FILE 节点 id> # 3. 读正文后再回答
129
+
130
+ # 用户问「客户端最新版本 / 更新了什么」
131
+ yos support upgrade --platform MAC_ARM64 # 单平台最新版
132
+ yos support upgrade-log --platform MAC_ARM64 --size 5 # 公告 content 为 null 时改查这里
133
+
134
+ # 用户报问题或提诉求
135
+ 先 manual-search 确认不是已有文档的用法问题 → 把手册答案给用户
136
+ 确认为缺陷/新需求 → 与用户确认原文 → yos support feedback '<原文>'
137
+ ```
138
+
139
+ ## 7. 做不到的事
140
+
141
+ 不提供手册编辑/新增;不把 `path` 展开为完整目录链;不按功能名反查版本号(只能按平台/日期过滤后人工比对公告);不下载客户端安装包;不查询反馈进度、不撤回反馈;反馈不带附件。有这类诉求时说明边界,并可用 `yos support feedback` 登记。