feat(rag): v1 rerank 精排 + bge-m3 多语言切换(T6/T11 架构审查整改)
- T6 (Issue6): RerankConfig(enabled/model=BAAI/bge-reranker-v2-m3/device)
- rag-layer-design §6.3 Rerank 精排:窗口=RRF top-10、候选≤top_k 跳过、
故障降级 RRF 原序;原 §6.3-6.6 顺延 6.4-6.7
- config-design §5 新增 rerank 段;design §5.5 检索策略加 rerank
- T11 (OV2): EmbeddingConfig.model 默认 bge-small-zh-v1.5 → BAAI/bge-m3(日文语料)
- rag-layer-design 选型表/依赖表/manifest/流程图同步 + 新增 §2.3 日文样本验证
- design.md / implementation-plan 4.3 / config-design embedding 同步
- 新增 test_rag_design_consistency.py 一致性门禁(6 用例防文档漂移)
- TDD: RED(默认模型仍旧 + rerank 字段不存在)→ GREEN → 全量 198 passed / 100.00%(996 stmts/252 br)
This commit is contained in:
@@ -77,3 +77,4 @@
|
||||
| 2026-08-11 | Agent 实现 | T8(架构审查整改):LLM 客户端全异步化(Issue9)。client.py 由同步 httpx.Client 全异步化:LLMClient Protocol chat → async def;HttpLLMClient 用 httpx.AsyncClient + asyncio.sleep 退避(消除 time.sleep 阻塞 asyncio 任务池);__enter__/__exit__ → __aenter__/__aexit__(async with 生命周期闭环);engine.py chat/chat_structured/_call 全部 async + await;FakeLLMClient.chat → async;测试基建用 anyio pytest 插件(@pytest.mark.anyio);test_inference_engine.py 32 用例脚本批量转换 async + NotConfiguredClient 同步 client 转 async;test_inference_client.py 10 用例转 async;同步 inference-engine-design spec 与 milestone3-inference-review httpx 描述(防文档漂移);TDD 验证 RED(async 接口缺失 TypeError)→ GREEN(聚焦 67 passed)→ 全量 182 passed 覆盖 100.00%(987 stmts/252 br),fail_under=99 达标 | src/genesis/inference/client.py, src/genesis/inference/engine.py, tests/test_inference_client.py, tests/test_inference_engine.py, tests/inference_helpers.py, docs/superpowers/specs/2026-08-09-inference-engine-design.md, docs/milestone3-inference-review.md, _AI_USAGE_LOG.md | deepseek-v4-flash-free |
|
||||
| 2026-08-11 | Agent 实现 | T9(架构审查整改):CJK 保守 token 估算(Issue11)。token.py approximate_token_count 重写:新增 _is_cjk_char(CJK 统一表意/扩展A/假名/韩文/兼容/全角六大 Unicode 范围)+ _CJK_TOKENS_PER_CHAR=1.5(旧逻辑 4 字符 1 token 对中文/日文严重低估,裁剪失效致 API 超限);CJK 字符按 1.5 token/字符,其余仍 4 字符 1 token,最少 1 token;同步 config-design.md token_estimation 注释;新增 4 用例(纯 CJK 保守/ASCII 不回归/混合文本/全角符号);TDD 验证 RED((設計)4 字符仅 1 token)→ GREEN(聚焦 11 passed)→ 全量 186 passed 覆盖 100.00%(995 stmts/252 br),fail_under=99 达标 | src/genesis/inference/token.py, tests/test_inference_token.py, docs/config-design.md, _AI_USAGE_LOG.md | deepseek-v4-flash-free |
|
||||
| 2026-08-11 | Agent 实现 | T5(架构审查整改):删死配置 + 同步文档(Issue5 + OV1)。config.py 删除 QdrantStoreConfig 类与 VectorStoreConfig.qdrant 字段、AppConfig.task_queue.redis_url;同步更新 6 处文档(api-design §1/§4.3/§5.2/§5.3/§6.2:TaskQueue 标注 v1 仅 InMemory、Redis/Valkey 为 v2 预留;rag-layer §9:Storage Adapter 仅 ChromaAdapter、移除切换流程/工厂 qdrant 分支;agent-runtime §3.1/§3.5;design §5.5/§8.4.1;config-design env/app.yaml/rag.yaml/docker compose;web-ui §4.1)+ tests/fixtures/rag.yaml 去 qdrant 段;历史评审记录(design-review/web-ui-review/phase1 plan)保留原样不改写;新增 3 用例(QdrantStoreConfig 已删/vector_store 无 qdrant 字段/task_queue 无 redis_url)+ 同步 2 个既有 qdrant 依赖用例;TDD 验证 RED(三处死配置存在)→ GREEN(聚焦 10 passed)→ 全量 189 passed 覆盖 100.00%(991 stmts/252 br),fail_under=99 达标 | src/genesis/config.py, tests/test_config.py, tests/fixtures/rag.yaml, docs/api-design.md, docs/rag-layer-design.md, docs/agent-runtime-design.md, docs/design.md, docs/config-design.md, docs/web-ui-design.md, _AI_USAGE_LOG.md | deepseek-v4-flash-free |
|
||||
| 2026-08-11 | Agent 实现 | T6+T11(架构审查整改,Lane B):v1 rerank 精排 + bge-m3 多语言切换(Issue6 + OV2)。config.py 新增 RerankConfig(enabled=True/model=BAAI/bge-reranker-v2-m3/device=cpu)挂入 RagConfig;EmbeddingConfig.model 默认 bge-small-zh-v1.5 → BAAI/bge-m3(实际语料日文);rag-layer-design.md 新增 §2.3 多语言与日文样本验证、§6.3 Rerank 精排(窗口=RRF top-10、候选≤top_k 跳过、故障降级 RRF 原序),原 §6.3-6.6 顺延 6.4-6.7;选型表/依赖表/manifest/流程图 bge-small-zh → bge-m3;config-design.md embedding 默认 + 新增 rerank 段;design.md §5.5 与 implementation-plan 4.3 同步;新增 tests/test_rag_design_consistency.py 一致性门禁(6 用例:代码默认/fixture 同步/4 文档用 bge-m3+reranker/无 legacy 引用);TDD 验证 RED(默认模型仍旧+rerank 字段不存在)→ GREEN(聚焦 13 passed)→ 全量 198 passed 覆盖 100.00%(996 stmts/252 br),fail_under=99 达标 | src/genesis/config.py, tests/test_config.py, tests/test_rag_design_consistency.py, tests/fixtures/rag.yaml, docs/rag-layer-design.md, docs/config-design.md, docs/design.md, docs/implementation-plan.md, _AI_USAGE_LOG.md | deepseek-v4-flash-free |
|
||||
|
||||
+10
-5
@@ -156,10 +156,10 @@ prompt_registry:
|
||||
```yaml
|
||||
# config/rag.yaml
|
||||
embedding:
|
||||
model: BAAI/bge-small-zh-v1.5 # 可切 BAAI/bge-m3
|
||||
device: cpu # cpu | cuda
|
||||
max_batch_size: 32 # 编码批大小
|
||||
cache_dir: /data/shared/models # 模型缓存目录
|
||||
model: BAAI/bge-m3 # 多语言(中/日/英),适配日文语料(OV2/T11)
|
||||
device: cpu # cpu | cuda
|
||||
max_batch_size: 32 # 编码批大小
|
||||
cache_dir: /data/shared/models # 模型缓存目录
|
||||
|
||||
vector_store: # StorageAdapter 配置(rag-layer §9.4)
|
||||
adapter: chroma # v1 仅 chroma(qdrant 为 v2 预留)
|
||||
@@ -176,7 +176,12 @@ retrieval:
|
||||
channel_top_k: 10 # 双通道各取 top-10
|
||||
rrf_k: 60 # RRF 融合常数(rag-layer §6.2)
|
||||
default_top_k: 5 # 融合后默认返回数
|
||||
contextual_enrichment: true # 上下文增强开关(§6.3)
|
||||
contextual_enrichment: true # 上下文增强开关(§6.4)
|
||||
|
||||
rerank: # Rerank 精排(rag-layer §6.3,v1 新增 I6/T6)
|
||||
enabled: true # false 时跳过精排,直接取 RRF 前 top_k
|
||||
model: BAAI/bge-reranker-v2-m3 # 多语言 Cross-Encoder
|
||||
device: cpu # cpu | cuda
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
+2
-2
@@ -708,10 +708,10 @@ Parser 处理时分为:
|
||||
| 设计点 | 决策 |
|
||||
|--------|------|
|
||||
| 向量数据库 | Chroma(v1 唯一;Qdrant 切换为 v2 预留,Scope 缩减裁定)|
|
||||
| Embedding | bge-small-zh-v1.5(本地),可切换 bge-m3 |
|
||||
| Embedding | bge-m3(多语言,适配日文语料;OV2/T11)|
|
||||
| 实现方式 | 手写(chromadb + rank_bm25 + sentence-transformers)|
|
||||
| 分割策略 | 按格式适配(Word 标题层级 / Excel 规则块 / PPT 1-2 页)|
|
||||
| 检索策略 | 双通道(向量 top-10 + BM25 top-10)+ RRF 融合 |
|
||||
| 检索策略 | 双通道(向量 top-10 + BM25 top-10)+ RRF 融合 + rerank 精排(bge-reranker-v2-m3)|
|
||||
| 分类存储 | 分 Collection 隔离(rules-write / rules-design / ref-docs)|
|
||||
| 版本管理 | 文档级增量 + 版本组合(hash 对比,只重建变化文档)|
|
||||
| 版本路由 | 会话开始锁版本 |
|
||||
|
||||
@@ -122,7 +122,7 @@ Wordテンプレート・ルール文書・PPTルール文書・現行システ
|
||||
|---|-------|------|
|
||||
| 4.1 | ルール文書のインデックス化 | 分類済みルールの分割(Word/Excel/PPT フォーマット適応)→ Embedding → ベクトルストア構築(詳細: docs/rag-layer-design.md §3, §4) |
|
||||
| 4.2 | StorageAdapter 実装 | VectorStoreAdapter 抽象+ChromaAdapter+MockAdapter(詳細: docs/rag-layer-design.md §9) |
|
||||
| 4.3 | ハイブリッド検索API | ベクトル(bge-small-zh-v1.5)+BM25 双チャネル+RRF 融合の実装(詳細: docs/rag-layer-design.md §6) |
|
||||
| 4.3 | ハイブリッド検索API | ベクトル(bge-m3,日文対応)+BM25 双チャネル+RRF 融合+rerank 精排(bge-reranker-v2-m3)の実装(詳細: docs/rag-layer-design.md §6) |
|
||||
| 4.4 | ルールハンドブックのバージョン管理 | ドキュメント級インクリメンタル更新(hash比較)+manifest+セッションロックバージョン(詳細: docs/rag-layer-design.md §5) |
|
||||
| 4.5 | ルール衝突検出・ユーザー確認 | ConflictDetector+ユーザー確認フロー+意思決定記録(詳細: docs/rag-layer-design.md §7) |
|
||||
| 4.6 | 「ルールを更新」UI連携 | Web UI からの更新トリガー → 再インデックス化 |
|
||||
|
||||
+47
-10
@@ -50,7 +50,8 @@ RAG 层存储三类内容,分类在 Parser 解析时完成:
|
||||
| 选型点 | 决策 | 说明 |
|
||||
|--------|------|------|
|
||||
| 向量数据库 | **Chroma(v1 唯一)** | 初期用 Chroma(轻量本地,嵌入进程,Docker 部署最简);通过 Storage Adapter 抽象保留接口,Qdrant 切换为 v2 预留(Scope 缩减裁定,T5 整改)|
|
||||
| Embedding 模型 | **bge-small-zh-v1.5**(本地运行) | 中文小模型(1024维,~100MB),CPU 可跑;统一配置 `config/rag.yaml` 的 `embedding.model`(见 docs/config-design.md §5)可切换为 `BAAI/bge-m3`(多语言更好) |
|
||||
| Embedding 模型 | **bge-m3**(本地运行) | 多语言模型(中/日/英),适配实际日文语料(OV2/T11);统一配置 `config/rag.yaml` 的 `embedding.model`(见 docs/config-design.md §5);稠密向量 1024 维,CPU 可跑 |
|
||||
| Rerank 模型 | **bge-reranker-v2-m3**(v1 引入,I6/T6) | 精排阶段使用;统一配置 `config/rag.yaml` 的 `rerank.model`;默认启用,可通过 `rerank.enabled=false` 关闭降级为纯 RRF 结果 |
|
||||
| 实现方式 | **手写实现**(不引入 LangChain/LlamaIndex) | chromadb + rank_bm25 + sentence-transformers 直接实现;依赖轻、可控性强、与现有轻量技术栈一致 |
|
||||
|
||||
### 2.1 为什么手写而非框架
|
||||
@@ -68,11 +69,22 @@ RAG 层存储三类内容,分类在 Parser 解析时完成:
|
||||
|
||||
```
|
||||
chromadb # 向量存储(Chroma)
|
||||
sentence-transformers # Embedding 编码(bge-small-zh-v1.5)
|
||||
sentence-transformers # Embedding 编码(bge-m3)+ Rerank 精排(bge-reranker-v2-m3)
|
||||
rank_bm25 # BM25 关键词检索
|
||||
pydantic # 数据模型(RuleChunk 等)
|
||||
```
|
||||
|
||||
### 2.3 多语言与日文样本验证(OV2/T11)
|
||||
|
||||
实际规则语料为**日文**(要件定义/概要设计/记入规则),因此:
|
||||
|
||||
- Embedding 采用多语言模型 **bge-m3**(支持中/日/英,稠密向量 1024 维)
|
||||
- Rerank 采用多语言精排模型 **bge-reranker-v2-m3**(Cross-Encoder,query×chunk 打分)
|
||||
- **日文样本验证**(Phase4 实施时执行):用真实日文规则片段(如「見出しは「1.1」形式で記述する」)构造检索用例,断言:
|
||||
1. 语义近义日文 query 能召回对应规则(top-5 命中)
|
||||
2. rerank 后相关片段排位不低于 RRF 原始排位(不劣化)
|
||||
3. 日英混合/片假名术语 query 不空召回
|
||||
|
||||
---
|
||||
|
||||
## 3. 文档分割策略
|
||||
@@ -181,8 +193,8 @@ Chunking Pipeline
|
||||
{"name": "设计方针.docx", "hash": "sha256:...", "type": "design", "built": "reuse_from_v2"}
|
||||
],
|
||||
"collections": {
|
||||
"rules-write": {"chunk_count": 130, "embedding_model": "bge-small-zh-v1.5"},
|
||||
"rules-design": {"chunk_count": 45, "embedding_model": "bge-small-zh-v1.5"}
|
||||
"rules-write": {"chunk_count": 130, "embedding_model": "bge-m3", "rerank_model": "bge-reranker-v2-m3"},
|
||||
"rules-design": {"chunk_count": 45, "embedding_model": "bge-m3", "rerank_model": "bge-reranker-v2-m3"}
|
||||
},
|
||||
"active_previous": "v2"
|
||||
}
|
||||
@@ -296,12 +308,15 @@ v3 会复制未变化文档的 embeddings。对规则文档几 MB 的量级,
|
||||
│ │
|
||||
│ 双通道检索: │
|
||||
│ ├── VectorRetriever(向量语义检索 top-10) │
|
||||
│ │ 使用 bge-small-zh 编码查询 │
|
||||
│ │ 使用 bge-m3 编码查询 │
|
||||
│ └── BM25Retriever(关键词检索 top-10) │
|
||||
│ │
|
||||
│ RRF Fusion(结果融合) │
|
||||
│ └── 合并两通道结果,按 RRF 公式排序 │
|
||||
│ └── 输出 top-N 个 RuleChunk │
|
||||
│ │
|
||||
│ Rerank 精排(v1 新增,I6/T6) │
|
||||
│ └── bge-reranker-v2-m3 对候选重打分 │
|
||||
│ └── 输出 top-N 个 RuleChunk │
|
||||
└──────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
@@ -320,7 +335,29 @@ RRF_score(d) = Σ 1 / (k + rank(d)) # k=60 常用值
|
||||
融合后 top-k = 调用方传参(默认 5)
|
||||
```
|
||||
|
||||
### 6.3 上下文增强(Contextual Enrichment)
|
||||
### 6.3 Rerank 精排(v1 新增,I6/T6)
|
||||
|
||||
RRF 融合后、注入 LLM prompt 前,对候选做 **Cross-Encoder 精排**(2026 主流实践:向量→rerank→精排):
|
||||
|
||||
```
|
||||
RRF 候选(默认 top-10 窗口)
|
||||
│
|
||||
▼
|
||||
bge-reranker-v2-m3(Cross-Encoder)
|
||||
│ 对每对 (query, chunk) 打分,输出相关性分数
|
||||
▼
|
||||
按分数降序重排 → 截取最终 top_k(默认 5)
|
||||
```
|
||||
|
||||
| 项目 | 决策 |
|
||||
|------|------|
|
||||
| 模型 | `BAAI/bge-reranker-v2-m3`(多语言 Cross-Encoder,与日文语料匹配) |
|
||||
| 开关 | `rerank.enabled`(默认 true);false 时跳过精排,直接取 RRF 前 top_k |
|
||||
| 打分窗口 | RRF 融合后 top-10 候选(与通道 top-k 一致,避免重排成本随全文增长) |
|
||||
| 候选过少 | 候选 ≤ top_k 时跳过 rerank(无重排必要,节省推理) |
|
||||
| 故障降级 | rerank 推理异常 → 降级为 RRF 原始顺序,不阻断检索(同 §10 容错策略) |
|
||||
|
||||
### 6.4 上下文增强(Contextual Enrichment)
|
||||
|
||||
检索时不仅用 query 文本,还拼入当前上下文:
|
||||
|
||||
@@ -330,7 +367,7 @@ RRF_score(d) = Σ 1 / (k + rank(d)) # k=60 常用值
|
||||
| Impact | 「要素 F001 与 TB001 的关系」推理 → query + 要素类型 + 要素描述 |
|
||||
| QA | 「校验某段内容的规则遵守」→ query + 待校验段落 |
|
||||
|
||||
### 6.4 各 Agent 查询构造规范
|
||||
### 6.5 各 Agent 查询构造规范
|
||||
|
||||
| 调用方 | query 构造方式 |
|
||||
|--------|--------------|
|
||||
@@ -338,7 +375,7 @@ RRF_score(d) = Σ 1 / (k + rank(d)) # k=60 常用值
|
||||
| Impact | query = 要素类型 + 要素描述 + 待推论的关联方向 |
|
||||
| QA | query = 待校验段落内容 + 所属章 |
|
||||
|
||||
### 6.5 top_k 配置
|
||||
### 6.6 top_k 配置
|
||||
|
||||
`top_k` 由调用方传参,允许按章差异配置:
|
||||
|
||||
@@ -348,7 +385,7 @@ RRF_score(d) = Σ 1 / (k + rank(d)) # k=60 常用值
|
||||
| DB 设计章 | 8 |
|
||||
| 其余章 | 5 |
|
||||
|
||||
### 6.6 检索结果上下文组装
|
||||
### 6.7 检索结果上下文组装
|
||||
|
||||
检索出的 chunk 注入 LLM prompt 时,保留结构信息:
|
||||
|
||||
|
||||
+10
-1
@@ -81,7 +81,8 @@ class InferenceConfig(BaseModel):
|
||||
|
||||
|
||||
class EmbeddingConfig(BaseModel):
|
||||
model: str = "BAAI/bge-small-zh-v1.5"
|
||||
# OV2/T11:实际语料为日文,bge-small-zh 面向中文 → 默认多语言 bge-m3(中/日/英)
|
||||
model: str = "BAAI/bge-m3"
|
||||
device: str = "cpu"
|
||||
max_batch_size: int = 32
|
||||
cache_dir: str = "/data/shared/models"
|
||||
@@ -110,11 +111,19 @@ class RetrievalConfig(BaseModel):
|
||||
contextual_enrichment: bool = True
|
||||
|
||||
|
||||
class RerankConfig(BaseModel):
|
||||
# I6/T6:v1 引入 rerank 精排(2026 主流实践:向量→rerank→精排)
|
||||
enabled: bool = True
|
||||
model: str = "BAAI/bge-reranker-v2-m3"
|
||||
device: str = "cpu"
|
||||
|
||||
|
||||
class RagConfig(BaseModel):
|
||||
embedding: EmbeddingConfig = Field(default_factory=EmbeddingConfig)
|
||||
vector_store: VectorStoreConfig = Field(default_factory=VectorStoreConfig)
|
||||
chunking: ChunkingConfig = Field(default_factory=ChunkingConfig)
|
||||
retrieval: RetrievalConfig = Field(default_factory=RetrievalConfig)
|
||||
rerank: RerankConfig = Field(default_factory=RerankConfig)
|
||||
|
||||
|
||||
# ---------- 加载辅助 ----------
|
||||
|
||||
Vendored
+5
-2
@@ -1,8 +1,11 @@
|
||||
embedding:
|
||||
model: BAAI/bge-small-zh-v1.5
|
||||
model: BAAI/bge-m3
|
||||
vector_store:
|
||||
adapter: chroma
|
||||
chroma:
|
||||
persist_dir: /data/shared/rules-handbook/chroma
|
||||
retrieval:
|
||||
rrf_k: 42
|
||||
rrf_k: 42
|
||||
rerank:
|
||||
enabled: true
|
||||
model: BAAI/bge-reranker-v2-m3
|
||||
+26
-3
@@ -35,7 +35,7 @@ def test_from_dir_maps_yaml_fields():
|
||||
assert s.inference.models.primary.name == "deepseek-chat"
|
||||
assert s.inference.llm_calls.max_context_tokens == 16000
|
||||
assert s.inference.structured_output.max_parse_retry == 3
|
||||
assert s.rag.embedding.model == "BAAI/bge-small-zh-v1.5"
|
||||
assert s.rag.embedding.model == "BAAI/bge-m3"
|
||||
assert s.rag.retrieval.rrf_k == 42
|
||||
|
||||
|
||||
@@ -45,7 +45,7 @@ def test_defaults_when_dir_empty(tmp_path):
|
||||
assert s.app.server.max_upload_mb == 100
|
||||
assert s.app.task_queue["backend"] == "memory"
|
||||
assert s.inference.models.primary.name == "deepseek-chat"
|
||||
assert s.rag.embedding.model == "BAAI/bge-small-zh-v1.5"
|
||||
assert s.rag.embedding.model == "BAAI/bge-m3"
|
||||
assert s.rag.retrieval.rrf_k == 60
|
||||
|
||||
|
||||
@@ -82,4 +82,27 @@ def test_expand_env_list_branch(monkeypatch):
|
||||
data = {"models": [{"name": "a", "key": "${SOME_API_KEY}"}, "plain"]}
|
||||
out = _expand_env(data)
|
||||
assert out["models"][0]["key"] == "sk-list-xyz"
|
||||
assert out["models"][1] == "plain"
|
||||
assert out["models"][1] == "plain"
|
||||
|
||||
|
||||
# ---------- T6/T11: rerank 精排 + bge-m3 多语言(I6/OV2) ----------
|
||||
|
||||
def test_embedding_default_model_is_bge_m3():
|
||||
"""OV2:bge-small-zh 面向中文、实际语料为日文 → 默认切换多语言 bge-m3。"""
|
||||
s = Settings()
|
||||
assert s.rag.embedding.model == "BAAI/bge-m3"
|
||||
|
||||
|
||||
def test_rerank_config_defaults():
|
||||
"""I6:v1 引入 rerank 精排(bge-reranker-v2-m3),默认启用、device=cpu。"""
|
||||
s = Settings()
|
||||
assert s.rag.rerank.enabled is True
|
||||
assert s.rag.rerank.model == "BAAI/bge-reranker-v2-m3"
|
||||
assert s.rag.rerank.device == "cpu"
|
||||
|
||||
|
||||
def test_rerank_env_override(monkeypatch):
|
||||
monkeypatch.setenv("GENESIS_RAG__RERANK__ENABLED", "false")
|
||||
s = Settings.from_dir(FIXTURES)
|
||||
assert s.rag.rerank.enabled is False
|
||||
assert s.rag.rerank.model == "BAAI/bge-reranker-v2-m3"
|
||||
@@ -0,0 +1,84 @@
|
||||
"""RAG 模型选型一致性门禁:T6/T11 整改(I6/OV2)的机器契约。
|
||||
|
||||
- T6(I6):v1 引入 rerank 精排 bge-reranker-v2-m3
|
||||
- T11(OV2):embedding 默认切换多语言 bge-m3(实际语料为日文)
|
||||
|
||||
防文档漂移:代码默认值、fixture、当前设计文档四处必须一致;
|
||||
当前设计文档不得残留 bge-small-zh-v1.5(历史评审记录/计划快照不改写,故不扫描)。
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from pathlib import Path
|
||||
|
||||
import yaml
|
||||
|
||||
from genesis.config import Settings
|
||||
|
||||
ROOT = Path(__file__).resolve().parents[1]
|
||||
FIXTURES = Path(__file__).parent / "fixtures"
|
||||
|
||||
# 当前设计文档(排除历史评审记录 docs/design-review.md、docs/*-review*.md、
|
||||
# docs/superpowers/plans/* 等历史快照)
|
||||
_CURRENT_DOCS = [
|
||||
"docs/rag-layer-design.md",
|
||||
"docs/config-design.md",
|
||||
"docs/design.md",
|
||||
"docs/implementation-plan.md",
|
||||
]
|
||||
|
||||
EMBEDDING_MODEL = "BAAI/bge-m3"
|
||||
RERANK_MODEL = "BAAI/bge-reranker-v2-m3"
|
||||
# 设计文档用短名(bge-m3);全名含短名子串,故 token 宽松匹配
|
||||
_EMBEDDING_TOKEN = "bge-m3"
|
||||
_RERANK_TOKEN = "bge-reranker-v2-m3"
|
||||
|
||||
|
||||
def _doc_text(name: str) -> str:
|
||||
return (ROOT / name).read_text(encoding="utf-8")
|
||||
|
||||
|
||||
def _fixture_rag() -> dict:
|
||||
with (FIXTURES / "rag.yaml").open("r", encoding="utf-8") as f:
|
||||
return yaml.safe_load(f) or {}
|
||||
|
||||
|
||||
# ---------- 代码默认值(T11) ----------
|
||||
|
||||
def test_code_default_embedding_is_bge_m3():
|
||||
s = Settings()
|
||||
assert s.rag.embedding.model == EMBEDDING_MODEL
|
||||
|
||||
|
||||
# ---------- 代码默认值(T6) ----------
|
||||
|
||||
def test_code_rerank_config_defaults():
|
||||
s = Settings()
|
||||
assert s.rag.rerank.enabled is True
|
||||
assert s.rag.rerank.model == RERANK_MODEL
|
||||
|
||||
|
||||
# ---------- fixture 与代码一致 ----------
|
||||
|
||||
def test_fixture_synced_with_code_defaults():
|
||||
rag = _fixture_rag()
|
||||
assert rag["embedding"]["model"] == EMBEDDING_MODEL
|
||||
assert rag["rerank"]["enabled"] is True
|
||||
assert rag["rerank"]["model"] == RERANK_MODEL
|
||||
|
||||
|
||||
# ---------- 文档与选型一致(T6/T11) ----------
|
||||
|
||||
def test_docs_use_bge_m3():
|
||||
missing = [name for name in _CURRENT_DOCS if _EMBEDDING_TOKEN not in _doc_text(name)]
|
||||
assert not missing, f"以下当前设计文档缺失 {_EMBEDDING_TOKEN}:{missing}"
|
||||
|
||||
|
||||
def test_docs_use_rerank_model():
|
||||
missing = [name for name in _CURRENT_DOCS if _RERANK_TOKEN not in _doc_text(name)]
|
||||
assert not missing, f"以下当前设计文档缺失 {_RERANK_TOKEN}:{missing}"
|
||||
|
||||
|
||||
def test_docs_no_legacy_bge_small_zh():
|
||||
legacy = [name for name in _CURRENT_DOCS if "bge-small-zh-v1.5" in _doc_text(name)]
|
||||
assert not legacy, f"当前设计文档残留旧模型 bge-small-zh-v1.5(请同步为 bge-m3):{legacy}"
|
||||
Reference in New Issue
Block a user