# Chunk 重新 Embedding 脚本

## 脚本路径

```text
scripts/reembed_chunks.php
```

## 脚本作用

根据 PostgreSQL 中已有的 `chunks.text`，重新生成 embedding，并把结果写回 `chunks.embedding_*` 字段。

脚本会做这些事：

1. 判断当前是“断点续跑”还是“全量重建”。
2. 把需要恢复的 chunk 状态置回 `pending`。
3. 逐个 archive 拉取待处理 chunk，并按 embedding request batch 调用现有 handler。
4. 输出基于 chunk 数的进度条、batch 明细和最终统计结果。

## 断点续跑语义

默认模式下，脚本会尽量**保留已经完成的 `embedded` 进度**：

- 只把 `queued / processing / failed_retryable` 的 chunk 重新置回 `pending`
- 已经是 `embedded` 的 chunk 不会重复生成
- `failed_terminal` 也不会自动重试

这意味着如果中途断电、断网、进程被杀：

- 已经成功写回 embedding 的 chunk 进度不会丢
- 未完成的那部分在下次重跑脚本时会继续

如果你明确想从头开始全部重新 embedding，可以手动加 `--reset`。

## 运行前提

- PostgreSQL 可连接。
- BigModel / Zhipu embedding API 配置可用。
- 项目依赖已安装完成。
- 从项目根目录执行命令。

## 运行命令

默认断点续跑：

```bash
php scripts/reembed_chunks.php
```

强制从头全量重新 embedding：

```bash
php scripts/reembed_chunks.php --reset
```

只处理一个 archive：

```bash
php scripts/reembed_chunks.php --archive_uid=01KQHVREB6XPYF604RVZAP9NNY
```

## 成功输出示例

```text
Progress granularity: embedding request batches (up to 32 chunks each)
Re-embedding [================================] 100.0% (14/14)
Batch #1 archive=01KQHVREB6XPYF604RVZAP9NNY chunks=14 progress=14/14
Chunk re-embedding completed.
Archive filter: (all chunks)
Mode: resume
Eligible chunks: 14
Embedding batch size: 32
Reset chunks: 2
Processed archives: 1
Processed batches: 1
Embedded chunk rows now marked embedded: 14
Terminal failures: 0
Archives: 01KQHVREB6XPYF604RVZAP9NNY
Next step: refresh OpenSearch vectors with `php scripts/reindex_opensearch.php`
```

## 关于进度条为什么可能“0 到 100”

这个脚本的进度条是按 **chunk 数** 计算的，但刷新粒度是 **一次 embedding request batch 完成后**。

所以如果：

- 当前只有一个 archive 需要处理
- 且该 archive 的待处理 chunk 数小于等于 `LLM_EMBEDDING_BATCH_SIZE`

那么整个 archive 会在 1 次请求里完成，终端看起来就会像是从 `0` 直接跳到 `100`。这不是进度丢失，而是因为这次实际只跑了 `1` 个 batch。

## reset 行为

加 `--reset` 后，会把目标范围内的 chunk：

- `embedding_status` 重置为 `pending`
- 清空 `embedding_ref`
- 清空 `embedding_model`
- 清空 `embedding_error`
- 同时把 `search_index_status` 置回 `pending`

所以 `--reset` 的语义是：**把 embedding 和后续索引链路都当成需要重建**。

## 重要限制

这个脚本不会直接重建 OpenSearch。

重新 embedding 完成后，如果你希望 OpenSearch 中也使用新的向量，请继续执行：

```bash
php scripts/reindex_opensearch.php
```
