116 lines
3.7 KiB
Markdown
116 lines
3.7 KiB
Markdown
# search-engine-widget(技术计划)
|
||
|
||
## 1. 计划目标
|
||
|
||
在 **WIDGET** 场景实现确定性的 Beam Search(文档 9.2):
|
||
|
||
- 每一行扩展时只保留 TopK partial layouts(beam)
|
||
- 每步扩展断点数 M 受控(更强裁剪)
|
||
- 支持 `widthMode='MEASURE' | 'APPROX'`
|
||
- 结束时从 `pos==N` 的 beams 中选最优;若无解返回可解释的失败原因(最终由 `overflow-fallback` 统一语义)
|
||
|
||
## 2. 确定性与性能约束
|
||
|
||
### 2.1 确定性(必须)
|
||
|
||
- beams 的遍历顺序固定(按当前 beams 排序后的顺序)
|
||
- nextPos 候选顺序固定(`pos` 升序)
|
||
- pruning 固定(先按候选优先级/位置排序,再取前 M)
|
||
- beam 的 TopK 维护固定:`score` 降序;再 `tieKey`;再 `breaks` 字典序
|
||
|
||
### 2.2 性能参数(写死默认值)
|
||
|
||
来自文档 9.3:
|
||
|
||
- `beamK=5`
|
||
- `expandM=12`
|
||
|
||
## 3. Beam Search 设计(对应文档 9.2)
|
||
|
||
令 `N=tokens.length`,token 边界为 `pos in [0..N]`。
|
||
|
||
### 3.1 beam 状态
|
||
|
||
一个 beam(partial layout)包含:
|
||
|
||
- `pos`:当前已覆盖到的 token 边界
|
||
- `breaks: number[]`
|
||
- `lines: LineInfo[]`
|
||
- `score` + `tieKey`
|
||
- `meta`(可选):debug Top-3 terms、approx reason 等
|
||
|
||
### 3.2 扩展 nextPos(每步最多 M)
|
||
|
||
对每个 beam,从 `pos` 扩展到若干 `nextPos`:
|
||
|
||
- nextPos 来源:`breakpoints[].pos > pos`(按 pos 升序)
|
||
- 额外包含 `nextPos=N`(结束边界)
|
||
- 为控制复杂度:对候选 nextPos 进行裁剪,仅保留前 `expandM`
|
||
|
||
裁剪规则(确定性,首版简单可控):
|
||
|
||
- 先取 `nextPos` 最小的 `expandM` 个(最短前缀优先,利于早结束)
|
||
|
||
> 注:后续可升级为“优先级 + 距理想切分点近”裁剪,但首版以确定性与稳定为主。
|
||
|
||
### 3.3 宽度模式
|
||
|
||
- `widthMode='MEASURE'`:
|
||
- 若提供测量能力:使用 `measureSliceWidthCached` 获取 lineWidth
|
||
- 若测量不可用/失败:降级为 approx(记录 `reason=WIDTH_UNKNOWN` 或 `MEASURE_FAILED`),lineWidth 采用近似值
|
||
- `widthMode='APPROX'`:
|
||
- 不调用测量;lineWidth 使用近似值:
|
||
- EN:`tokenCount`
|
||
- TC:`charCount`
|
||
- meta 标记 `reason=WIDTH_UNKNOWN`
|
||
|
||
### 3.4 硬约束(最小集)
|
||
|
||
与 App 一致的最小硬约束:
|
||
|
||
- 禁止空行:`nextPos > pos`
|
||
- 最大行数:lineIndex 不超过 `maxLines`
|
||
- TC 禁止行首标点(H6):若 `tokens[nextPos]` 属于 `tcPunctuations` 则该转移无效
|
||
- 超宽约束:
|
||
- MEASURE 模式下若 width 可用且 `lineWidth > availableWidth`,转移无效
|
||
- APPROX 模式下不执行超宽硬过滤(因为单位不一致),交给评分处理
|
||
|
||
### 3.5 每轮保留 beamK
|
||
|
||
对所有扩展出来的新 beams:
|
||
|
||
- 使用 TopK 维护(去重同 breaks,排序按 score/tieKey/breaks)
|
||
- 全局只保留 `beamK` 个作为下一轮 beams
|
||
|
||
### 3.6 结束选择
|
||
|
||
重复扩展最多 `maxLines` 轮后:
|
||
|
||
- 优先从 beams 中选 `pos==N` 的最优
|
||
- 若无 `pos==N`:返回 `NO_CANDIDATE`(由 overflow-fallback 统一兜底语义)
|
||
|
||
## 4. 代码落位(客户端)
|
||
|
||
- `client/src/features/textWrap/searchWidget/`
|
||
- `types.ts`
|
||
- `beam.ts`
|
||
- `topK.ts`(可复用 App 逻辑,首版复制一份避免耦合)
|
||
- `constraints.ts`
|
||
- `index.ts`
|
||
- `__tests__/searchWidget.test.ts`
|
||
|
||
## 5. 测试计划(Vitest)
|
||
|
||
- 确定性:同输入重复执行输出一致
|
||
- 性能约束:beamK/expandM 生效(可通过构造大量断点断言扩展次数上限)
|
||
- widthMode=APPROX:仍能产出结果,且 meta.reason=WIDTH_UNKNOWN
|
||
- TC H6:行首标点转移被禁止
|
||
|
||
## 6. 完成定义(DoD)
|
||
|
||
- Beam Search 可运行,且确定性单测通过
|
||
- 宽度模式与降级 meta 符合 spec
|
||
- 性能参数默认值写死且可覆盖
|
||
- 更新 overview 标记阶段性完成并记录变更文件
|
||
|