feat(m8): P2 pgvector + Ollama 向量化与语义检索
- PostgreSQL 切换 pgvector/pgvector:pg17 镜像;迁移 000024 建 vector 扩展、 knowledge_chunks.embedding vector(1024) + HNSW 余弦索引,retrieval_mode 放宽三态 - OllamaEmbedder 本地 bge-m3 批量嵌入,404 惰性 pull 重试,维度/超时校验,可整体关闭 - SemanticRetriever/HybridRetriever + NewRetriever 按 retrieval_mode 分发,缺 embedder 回退 FTS - 文档入库同步批量向量化;Ollama 故障降级入库 + embedding_failed 事件 - 修复 pgx CopyFrom 对 vector 列二进制编码误读:COPY 基础列后同事务 unnest 批量回填 - 修复降级路径 embeddings=nil 索引越界 panic(Add 与 Reprocess) - 知识库列表 vectorized_chunk_count + 前端三态检索模式选择与向量化覆盖率 - 单测 embedder/retrievers + 集成 TestKnowledgeVectorLifecycle 全绿 Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -122,3 +122,14 @@
|
||||
- Compose(dev + production)新增 `minio` 服务与 `minio-data` 卷;nginx `client_max_body_size` 32m→256m 盖过 128 MiB 上传上限;`.env.example` / `production.env.example` 补 `S3_*`。
|
||||
- 端到端验证:上传→列表→下载往返一致→删除后桶无孤儿;admin 读 portal 文件 404;`TestFileObjectLifecycle` 集成测试连真实 MinIO+PostgreSQL 通过;`go build ./...`、`go vet ./...`、全量单测通过。
|
||||
- 管理端"文件管理"与门户端"文件仓库"菜单由服务端动态菜单下发。
|
||||
|
||||
## 已完成:M8 基础设施层(P2 向量化与语义检索)
|
||||
|
||||
- PostgreSQL 换 `pgvector/pgvector:pg17` 镜像(数据卷兼容,先备份再切换);迁移 `000024` `CREATE EXTENSION vector`、`knowledge_chunks.embedding vector(1024)` 列 + HNSW 余弦索引,并把 `retrieval_mode` CHECK 放宽为 `('postgres_fts','vector','hybrid')` 三态。
|
||||
- 本地 Ollama(`bge-m3`,1024 维)生成嵌入,Compose 新增 `ollama` 服务与 `ollama-models` 卷;`OllamaEmbedder` 批量调 `/api/embed`,首见 404 惰性 `/api/pull` 重试一次,按批校验维度,超时 `EMBEDDING_TIMEOUT`;`EMBEDDINGS_ENABLED=false` 可整体关闭。
|
||||
- `SemanticRetriever`(`embedding <=> $1::vector` 余弦距离 + `embedding IS NOT NULL` 过滤)与 `HybridRetriever`(FTS + 语义按 chunk 去重融合)实现;`NewRetriever(service, embedder)` 按知识库 `retrieval_mode` 分发,embedder 为 nil 时自动回退纯 FTS(不因缺少 Ollama 而报错)。
|
||||
- 文档入库/重新分块时在 vector/hybrid 模式下同步批量计算向量(每文档一次 `/api/embed` 收数组);Ollama 故障时优雅降级:文档照常入库、embedding 置 NULL,并在事务内发 `knowledge_document.embedding_failed` 事件。
|
||||
- 踩坑并修复:pgx v5 `CopyFrom` 对未知 OID(vector)列走二进制编码,字面量随 COPY 上传会被 `vector_recv` 误读为维度数而报 `vector cannot have more than 16000 dimensions`;改为 COPY 仅基础列,随后在同一事务内用 `UPDATE ... FROM unnest($1::uuid[], $2::text[])` 批量回填向量,避免 2 MiB 文档上千条逐条 INSERT。
|
||||
- 知识库列表新增 `vectorized_chunk_count`(`count(c.embedding)`),管理端展示"已向量化切片/总切片"覆盖率;创建/编辑知识库可三态选择检索模式,未向量化分块需重新处理才被语义召回。
|
||||
- `EMBEDDINGS_*` 配置(`OLLAMA_BASE_URL` 默认 `http://ollama:11434`、`EMBEDDING_MODEL` bge-m3、`EMBEDDING_DIM` 须与 `vector(1024)` 一致、批大小、超时)写入两个 `.env.example` 与 compose anchor。
|
||||
- 单测 `embedder_test.go`/`retrievers_test.go`(httptest 假 Ollama:批量切分、维度不符、404→pull→重试、降级分发)与集成 `TestKnowledgeVectorLifecycle`(真 pgvector+Ollama:导入即向量化、语义命中、embedder 失败时入库 + `embedding_failed` 事件)全部通过;`go build ./...`、`go vet ./...` 通过。
|
||||
|
||||
Reference in New Issue
Block a user