# 开发者开放指南

本文档面向**后续参与开发的工程师**，用于快速建立项目全貌、理解设计原则与规范，保证所有迭代在统一框架内进行，减少设计分叉与冗余代码，产出可持续继承的高质量代码。

**阅读建议**：首次请按顺序通读第一至第五节；扩展能力或新增模块时重点阅读第六、七节；日常开发与 Code Review 可依赖第八、九节。

---

## 目录

1. [文档说明与阅读路径](#1-文档说明与阅读路径)
2. [项目定位与核心价值](#2-项目定位与核心价值)
3. [总体架构](#3-总体架构)
4. [核心模块与职责](#4-核心模块与职责)
5. [设计原则与约束](#5-设计原则与约束)
6. [配置体系](#6-配置体系)
7. [扩展规范（能力与后端）](#7-扩展规范能力与后端)
8. [代码规范与质量](#8-代码规范与质量)
9. [迭代检查清单](#9-迭代检查清单)
10. [文档与资源索引](#10-文档与资源索引)

---

## 1. 文档说明与阅读路径

### 1.1 本指南的角色

- **唯一入口**：新人应首先阅读本指南，建立“框架全貌 + 规范”的认知。
- **规范聚合**：设计原则、配置约定、扩展方式、代码质量要求均在此汇总，并指向更细的专项文档。
- **迭代约束**：所有新功能、新模块、重构都应在符合本指南的前提下进行，Code Review 时可对照第九节检查清单。

### 1.2 推荐阅读路径

| 阶段 | 阅读内容 | 目的 |
|------|----------|------|
| 入职/接手 | 本指南 §1–§5 | 建立全貌：项目是什么、架构怎样、模块边界 |
| 开发前 | 本指南 §5–§7 + 相关专项文档 | 理解原则与配置、扩展方式，避免造轮子与分叉 |
| 开发中 | 本指南 §8 + QUICKSTART / API 文档 | 编码风格、测试要求、接口约定 |
| 提测/合入前 | 本指南 §9 | 自检是否满足框架与规范 |

### 1.3 与本指南配套的专项文档

以下文档由本指南引用，按需深入：

- [QUICKSTART.md](./QUICKSTART.md) — 环境、服务、模块、请求示例；§2–§4 含基础配置与 Provider/模块扩展
- [翻译模块说明.md](./翻译模块说明.md) — translator service、capability 配置、本地模型部署与接口契约
- 索引与数据流：[索引方案.md](./索引方案.md)、[索引字段说明v2.md](./索引字段说明v2.md)、[MySQL到ES文档映射说明.md](./MySQL到ES文档映射说明.md)
- [搜索API对接指南-00-总览与快速开始.md](./搜索API对接指南-00-总览与快速开始.md) — 搜索/索引/管理/微服务 API（分册入口；分册列表见 README）
- [搜索API对接指南-速查表.md](./搜索API对接指南-速查表.md) — 搜索 API 参数速查
- [QUICKSTART.md](./QUICKSTART.md) §1.4–1.8 — 系统要求、Python 环境、外部服务与生产凭证、店匠数据源
- [Usage-Guide.md](./Usage-Guide.md) — 运维、日志、多环境、故障排查

---

## 2. 项目定位与核心价值

### 2.1 项目是什么

- **产品形态**：面向跨境独立站（如店匠 Shoplazza）的**多租户可配置搜索 SaaS**，提供搜索后端与索引富化能力。
- **核心交付**：
  - **搜索服务**：文本搜索、图片搜索、建议（suggestions）、过滤、分面、排序、分层粗排/可选精排（fine rank）/重排。
  - **索引服务**：将 MySQL 中的店匠标准表（SPU/SKU）富化为符合 ES mapping 的文档（多语言、翻译、向量、规格聚合等），支持全量/增量及“仅构建 doc、由上游写 ES”的对接方式。
  - **支撑服务**：向量服务（embedding）、翻译服务（translator）、重排服务（reranker），可独立部署、通过配置切换。

### 2.2 核心价值与边界

- **多租户**：单套代码与索引结构，通过 `tenant_id` 隔离数据；租户级配置（如主语言、索引语言）由配置与 tenant_config 支持。
- **可配置**：字段权重、搜索域、排序表达式、查询改写、功能开关等由配置驱动，避免硬编码业务逻辑。
- **可扩展**：embedding / rerank 采用 Provider + 后端可插拔设计；translation 采用 translator service + capability backend 设计。新增实现时遵循协议与配置规范，不破坏现有调用方。
- **不负责**：商品主数据同步、店铺配置写库、全量/增量调度策略由上游（如 Java 索引程序）负责；本仓库专注“如何查、如何建 doc”。

---

## 3. 总体架构

### 3.1 数据流（简化）

```
MySQL (店匠 SPU/SKU)
    → Indexer（富化：多语言、翻译、向量、规格聚合）
    → Elasticsearch（按租户索引：search_products_tenant_<id>）
    → 搜索 API（QueryParser → Searcher：粗排 coarse_rank → 可选精排 fine_rank → 重排 rerank）
    → 前端 / 上游业务
```

- **索引侧**：Java 或脚本决定“对哪些 SPU 做索引”；Python indexer 负责“单条/批量 SPU → ES 文档”的完整逻辑，或通过 `/indexer/build-docs` 仅返回 doc、由调用方写 ES。
- **搜索侧**：请求经 QueryParser（解析、改写、翻译、向量化）→ Searcher（ES 召回与查询构建、`coarse_rank` 融合文本/KNN、可选 `fine_rank`、`rerank` 与分数融合）→ 结果格式化 → 返回。

### 3.2 服务拓扑与端口

| 服务 | 端口 | 说明 | 默认随 run.sh 启动 |
|------|------|------|--------------------|
| backend | 6002 | 搜索 API（含 admin） | ✓ |
| indexer | 6004 | 索引 API（reindex/build-docs 等） | ✓ |
| frontend | 6003 | 调试 UI | ✓ |
| eval-web | 6010 | 搜索评估 Web（`scripts/evaluation/`） | ✓ |
| embedding | 6005 | 文本向量服务 | 可选 |
| embedding-image | 6008 | 图片向量服务 | 可选 |
| translator | 6006 | 翻译服务（`POST /translate` 支持单条或批量 list；批量失败用 `null` 占位） | 可选 |
| reranker | 6007 | 重排服务 | 可选 |

- 启动：`./run.sh all` 会按 `scripts/service_ctl.sh` 定义拉起可选依赖（tei、cnclip、embedding 等）与核心服务（backend、indexer、frontend、**eval-web**）；仅需核心时可 `./run.sh backend indexer frontend`（不启 eval-web）。
- 停止：统一使用 `./scripts/stop.sh all`（或 `service_ctl.sh down`），会停止当前目标集合内各服务占用的端口与 monitor。
- 详见 [QUICKSTART.md](./QUICKSTART.md) 与 [Usage-Guide.md](./Usage-Guide.md)。

### 3.3 仓库目录结构（与架构对应）

```
api/                 # FastAPI 应用：搜索路由、管理路由、索引路由（indexer_app）
config/              # 配置加载与解析：config.yaml、services、env
indexer/             # MySQL → ES 管道：mapping、transformer、bulk、增量、build-docs
query/               # 查询解析：规范化、改写、翻译、embedding 调用、语言计划生成
search/              # 搜索执行：多语言查询构建、Searcher、粗排/精排/重排与分数融合
embeddings/          # 向量化：服务端（server）、文本/图像后端、协议与配置
reranker/            # 重排：服务端（server）、后端（backends）、配置
providers/           # 能力提供者：向量/重排的客户端抽象与工厂
translation/         # 翻译：服务客户端、服务编排、后端实现、本地模型接入
suggestion/          # 建议：索引构建、建议检索
utils/               # 共享工具：ES 客户端、DB 连接等
mappings/            # ES 索引 mapping 定义（如 search_products.json）
scripts/             # 脚本：环境、服务启停、数据、运维
frontend/            # 调试用前端静态资源
tests/               # 单元与集成测试
docs/                # 文档（含本指南）
```

- **约定**：业务逻辑按能力放入对应顶层包；新增“能力”时优先考虑是否属于现有某包、`translation/` 或 providers，避免随意新建顶层包导致分叉。

---

## 4. 核心模块与职责

### 4.1 api

- **职责**：对外 HTTP 入口；挂载搜索、管理、索引等路由；中间件（限流、CORS、安全头等）；不承载具体搜索/索引算法。
- **入口**：`api/app.py`（搜索 + 管理）、`api/indexer_app.py`（索引），均由 `main.py` 的 `serve` / `serve-indexer` 启动。
- **原则**：路由层只做参数校验、租户解析、调用 search/query/indexer 等模块，不写复杂业务逻辑；配置与能力访问通过 config 与 providers 统一获取。

### 4.2 config

- **职责**：加载与解析 `config/config.yaml`（搜索行为、字段权重、分面、function_score、rerank 融合参数等）；提供 `ConfigLoader` 与 `SearchConfig` 等数据结构；**服务级**配置（翻译/向量/重排的 provider、URL、后端）由 `config/services_config.py` 从 `config.yaml` 的 `services` 块及环境变量解析。
- **原则**：索引结构由 `mappings/search_products.json` 定义；搜索行为与能力配置以 config 为主、环境变量覆盖，不在业务代码中散落硬编码。

### 4.3 indexer

- **职责**：将 MySQL 行或上游传入的 SPU/SKU/options 转为符合 `mappings/search_products.json` 的 ES 文档；含多语言组织、翻译调用、向量生成、规格/SKU 聚合、类目路径等；支持全量/增量写入 ES，以及仅返回 doc（build-docs）供上游写 ES。
- **对接**：调用方通过 `providers` 获取翻译、向量等能力；索引名通过 `indexer/mapping_generator.get_tenant_index_name(tenant_id)` 与 `ES_INDEX_NAMESPACE` 一致。
- **详见**：`indexer/README.md`、[索引方案.md](./索引方案.md)、[索引字段说明v2.md](./索引字段说明v2.md)、[MySQL到ES文档映射说明.md](./MySQL到ES文档映射说明.md)。

### 4.4 query

- **职责**：查询解析与预处理：规范化、语言检测、改写（词典）、翻译、文本向量化；输出解析事实（如 `rewritten_query`、`detected_language`、`translations`、`query_vector`），不再承担 ES 语言计划拼装。
- **原则**：翻译/向量通过 `providers` 获取，不直接依赖具体服务 URL 或实现；支持按配置关闭翻译/向量（如短查询、typing 场景）。

### 4.5 search

- **职责**：构建多语言 ES 查询、执行检索、分层排序（`coarse_rank` → 可选 `fine_rank` → `rerank`）与分数融合、结果格式化；分面、过滤、排序、SKU 维度筛选等。
- **原则**：精排/重排通过 `search/rerank_client.py` 与配置中的 `service_profile` 区分调用；与 ES 的交互封装在 Searcher 内，便于 mock 与测试。参数见 `config/config.yaml` 的 `coarse_rank` / `fine_rank` / `rerank`。

### 4.6 embeddings

- **职责**：提供向量服务（FastAPI）：文本服务默认监听 `6005`，图片服务默认监听 `6008`；对外暴露 `POST /embed/text`、`POST /embed/image`、`GET /health`、`GET /ready`；服务内按配置加载文本后端（如 Qwen3-Embedding-0.6B）与图像后端（如 clip-as-service 或本地 CN-CLIP），实现协议即可插拔。
- **原则**：图片后端实现 `embeddings/protocols.ImageEncoderProtocol`；文本后端与参数统一从 `config/config.yaml -> services.embedding.backend(s)` 读取；文本与图片流量应通过独立进程和独立 inflight limit 做隔离。
- **详见**：`embeddings/README.md`、本指南 §7.5–§7.6。

### 4.7 reranker

- **职责**：提供重排服务（FastAPI）：`POST /rerank`（query + docs → scores）；服务内按配置加载一个重排后端（如 BGE 或 Qwen3-vLLM），实现 `score_with_meta(query, docs, normalize)` 协议。
- **原则**：对外 HTTP 契约固定；新增后端只在 `reranker/backends` 中实现协议并注册，不修改调用方。
- **详见**：本指南 §7.5–§7.6。

### 4.8 providers

- **职责**：统一“能力”的调用方式。向量、重排仍是标准 provider 工厂；翻译侧通过 `translation.create_translation_client()` 获取 translator service client，由 6006 服务统一承接后端选择与路由。
- **原则**：业务代码只依赖调用接口，不依赖具体 URL 或服务内后端类型；翻译能力新增时优先扩展 `translation/backends/` 与 `services.translation.capabilities`，而不是在业务侧新增 provider 分支。
- **详见**：本指南 §7.2；[QUICKSTART.md](./QUICKSTART.md) §3。

补充约定（翻译 client）：

- `translate(text=...)` 支持 `str` 与 `List[str]` 两种输入；当输入为列表时，输出必须与输入 **等长且顺序对应**，失败位置为 `None`（HTTP JSON 表现为 `null`）。
- client / backend 可暴露 `supports_batch: bool`（property）用于标识其是否支持直接批量调用；上层在处理 `text` 为列表时可优先走 batch，否则逐条拆分调用。

### 4.9 suggestion

- **职责**：建议索引的构建与检索：从 ES 商品索引与 MySQL 日志等构建 suggestion 索引；搜索 API 的 `/search/suggestions` 使用本模块。
- **原则**：索引命名与租户、环境命名空间一致；构建入口可通过 `main.py build-suggestions` 或脚本封装调用。

### 4.10 utils / mappings

- **utils**：ES 客户端、DB 连接等通用工具；避免在业务包内重复实现。
- **mappings**：ES 索引 mapping 的 JSON 定义；所有租户共享同一结构，仅索引名按租户与环境区分。

---

## 5. 设计原则与约束

### 5.1 多租户

- 数据隔离仅通过 `tenant_id` 实现；索引可为单索引多租户或 per-tenant 索引（如 `search_products_tenant_<id>`），由索引名与查询时 filter 统一保证。
- 租户级配置（主语言、索引语言等）从 `tenant_config` 或等价配置读取，不在代码中写死租户 ID 或店铺逻辑。

### 5.2 配置驱动

- 搜索行为（字段权重、搜索域、排序、function_score、重排融合参数等）来自 `config/config.yaml`，由 `ConfigLoader` 加载。
- 能力访问来自 `config.yaml` 的 `services` 块，由 `config/services_config` 解析。
- 其中翻译单独采用“service + capabilities”模型：调用方只配 `service_url` / `default_model` / `default_scene`，服务内通过 `capabilities` 控制启用哪些翻译能力。
- 新增开关或参数时，优先在现有 config 结构下扩展，避免新增散落配置文件。

### 5.3 单一配置源与优先级

- 同一类配置只在一个地方定义默认值；业务行为以 `config/config.yaml` 为唯一来源，敏感信息与端口等部署变量放在环境变量。
- 服务 URL、后端类型等均在 `services.<capability>` 下配置；翻译的 `service_url` / `default_model` / `default_scene` 不再接受环境变量覆盖，避免出现“看配置和实际行为不一致”。

### 5.4 调用方与实现解耦（Client + Backend）

- **调用方**：通过 client/provider 访问能力，不依赖具体 URL 或服务内实现；翻译调用方统一连 translator service。
- **服务内**：通过“后端”实现具体推理（如 qwen-mt、DeepL、LLM、本地模型；或 BGE 与 Qwen3-vLLM）；后端实现协议、在配置与工厂中注册即可插拔。
- 新增“一种调用方式”在 providers 中扩展；新增“一种推理实现”在对应服务的 backends 中扩展，并遵循本指南 §7。

### 5.5 协议契约

- 同类型后端实现同一协议（如重排的 `score_with_meta`、图片的 `ImageEncoderProtocol`）；调用方只依赖协议，不依赖具体类名或实现细节。
- 新增后端时必须满足现有协议（输入输出、顺序、长度、meta 字段等），避免调用方为兼容新后端而改代码。

### 5.6 索引与查询结构统一

- 索引结构以 `mappings/search_products.json` 为唯一来源；indexer 产出的 doc 必须与该 mapping 一致。
- 查询侧使用的字段名、多语言后缀（.zh/.en）、嵌套路径等与 mapping 保持一致；新增字段时同步更新 mapping 与查询/分面/过滤逻辑。

### 5.7 错误处理

- **启动期（fail-fast）**：配置加载、依赖初始化、模型/资源加载失败必须直接启动失败，不允许“继续启动但不可用”。
- **运行期（分层处理）**：
  - 核心链路（ES 主检索）失败：请求直接失败并返回错误，禁止伪装成空结果。
  - 增强链路（翻译/向量/重排）失败：记录 warning，不应拖垮主检索流程。
- 禁止通过“静默回退到另一套实现”掩盖问题；默认行为必须由配置显式给出。

### 5.8 启动初始化约束

- translator service 在进程启动时应完成配置校验并预热默认 backend；其余已启用 capability 可按首次请求懒加载，避免多个本地翻译模型在启动阶段一次性占满显存。
- 若配置声明启用某能力（例如 GPU 后端），但运行资源不满足，应直接启动失败，不自动降级为其它后端。

### 5.9 环境隔离

- 主程序（backend/indexer/frontend）只使用 `.venv`，不引入 `clip-as-service`/`vllm` 的重依赖。
- embedding 服务使用 `.venv-embedding`；reranker 服务使用 `.venv-reranker`；CN-CLIP 使用 `.venv-cnclip`；TEI 使用 Docker 容器。
- 禁止为兼容某个独立服务而降级主 `.venv` 依赖（例如 `setuptools<82` 仅允许出现在隔离环境中）。

---

## 6. 配置体系

### 6.1 主配置文件

- **config/config.yaml**：搜索行为（field_boosts、query_config.search_fields、query_config.text_query_strategy，含翻译失败时的原文兜底 boost、ranking、function_score、rerank 融合参数）、SPU 配置、**services**（翻译 service 与 capabilities、向量/重排的 provider 与 backends）、tenant_config 等。
- **.env**：敏感信息与部署态变量（DB、ES、Redis、API Key、端口等）；不提交敏感值，可提供 `.env.example` 模板。

### 6.2 services 块结构（能力统一约定）

```yaml
services:
  <capability>:
    provider: "http"       # 调用方使用方式：http | direct | ...
    base_url: "http://..."
    providers:
      http: { base_url: "...", ... }
      direct: { ... }
    backend: "tei"         # 服务内后端（可选）
    backends:
      tei: { base_url: "...", ... }
      qwen3_vllm: { ... }
```

翻译是特例，结构为：

```yaml
services:
  translation:
    service_url: "http://127.0.0.1:6006"
    default_model: "llm"
    default_scene: "general"
    timeout_sec: 10.0
    capabilities:
      llm: { enabled: true, backend: "llm", model: "qwen-flash", base_url: "https://dashscope-us.aliyuncs.com/compatible-mode/v1", timeout_sec: 30.0 }
      qwen-mt: { enabled: true, backend: "qwen_mt", model: "qwen-mt-flash", base_url: "https://dashscope-us.aliyuncs.com/compatible-mode/v1", timeout_sec: 10.0, use_cache: true }
      deepl: { enabled: false, backend: "deepl", api_url: "https://api.deepl.com/v2/translate", timeout_sec: 10.0 }
```

- **provider**：调用方如何访问（如 HTTP）。
- **backend / backends**：当能力由本仓库内服务提供时，该服务加载哪个后端及参数。
- **translation.service_url**：业务侧统一调用的翻译服务地址。
- **translation.capabilities**：翻译服务内部可启用的能力注册表。
- **translation 内部静态规则**：scene 集合、语言码映射、LLM prompt 模板、本地模型方向约束统一位于 `translation/`，不是外部 YAML 配置。
- 解析入口：`config/services_config.py` 的 `get_*_config()` 及 `get_*_base_url()` / `get_rerank_service_url()` 等。

### 6.3 环境变量（常用）

- 能力 URL：`EMBEDDING_TEXT_SERVICE_URL`、`EMBEDDING_IMAGE_SERVICE_URL`、`RERANKER_SERVICE_URL`
- 能力选择：`EMBEDDING_PROVIDER`、`EMBEDDING_BACKEND`、`RERANK_PROVIDER`、`RERANK_BACKEND`
- 翻译服务行为：统一查看 `config/config.yaml -> services.translation`
- 环境与索引：`ES_HOST`、`ES_INDEX_NAMESPACE`、`RUNTIME_ENV`、DB 与 Redis 等

详见 [QUICKSTART.md](./QUICKSTART.md) §1.6（.env 与生产凭证）、[Usage-Guide.md](./Usage-Guide.md)。

---

## 7. 扩展规范（能力与后端）

### 7.1 何时看扩展规范

- 新增或替换**向量/重排**的调用方式（如新的 HTTP 客户端、gRPC）：见本指南 §7.2、[QUICKSTART.md](./QUICKSTART.md) §3。
- 新增翻译能力（如新云端模型或本地模型）：见本指南 §7.2 中的 translation 特例说明。
- 新增或替换**向量/重排**的推理实现（如新模型、vLLM）：见本指南 §7.3–§7.6。

### 7.2 新增 Provider（调用方式）

1. 在 `providers/<capability>.py` 中实现新类（与现有 Provider 同接口）。
2. 在 `create_*_provider()` 中按 `config.provider` 或环境变量增加分支。
3. 在 `config/config.yaml` 的 `services.<capability>.providers` 下补充参数。
4. 不修改业务调用方（search/query/indexer 仍通过工厂获取实例）。

翻译不再按这套扩展。新增翻译能力时：

1. 在 `translation/backends/` 中实现新 backend。
2. 在 `translation/service.py` 中注册工厂。
3. 在 `services.translation.capabilities.<name>` 下增加配置，并用 `enabled` 控制是否启用。
4. 业务调用方保持不变，仍只通过 `create_translation_client()` 调 6006。

### 7.3 新增 Backend（推理实现）

1. **实现协议**：在对应目录（如 `reranker/backends/`、`embeddings/`）实现满足协议接口的类。
2. **配置**：在 `config/config.yaml` 的 `services.<capability>.backends` 下增加新后端名及参数；支持环境变量覆盖（如 `RERANK_BACKEND`）。
3. **注册**：在 backends 的工厂（如 `get_rerank_backend(name, config)`）中增加分支并返回实例。
4. **服务启动**：服务（如 `reranker/server.py`）启动时读取 backend 配置并调用工厂，不写死后端类型。
5. **文档与依赖**：在 README 或 docs 中说明新后端的依赖、资源要求；可选依赖放入 `requirements_ml.txt` 或 extra。

详见下文 §7.6 新增后端清单。

### 7.4 禁止做法

- 在业务代码中硬编码服务 URL 或后端类型。
- 新增能力时复制一套独立配置体系或新顶层包，而不纳入 `services` 与 providers/backends；translation 也必须纳入 `services.translation.capabilities` 与 `translation/backends/`。
- 新增后端时破坏现有协议（如修改返回长度、顺序或 meta 约定）。

### 7.5 重排与向量化协议与配置速查

**设计原则**：同类型后端实现同一协议；配置来自 `config/config.yaml` 的 `services` 块，环境变量可覆盖；调用方通过 Provider 访问服务，服务内通过 Backend 完成推理；新增后端 = 实现协议 + 在配置与工厂中注册。

**重排后端协议（服务内）**：所有在 reranker 服务内加载的后端须实现 `score_with_meta(query, docs, normalize=True) -> (scores: List[float], meta: dict)`。返回的 `scores[i]` 与 `docs[i]` 一一对应；meta 至少含 `input_docs`、`usable_docs`、`elapsed_ms` 等。对外 HTTP 契约固定：`POST /rerank` 请求体 `{ "query": str, "docs": [str] }`，响应体 `{ "scores": [float], "meta": object }`；`GET /health` 返回 `status`、`model`、`backend` 等。

**向量化后端协议（服务内）**：文本后端需支持 `encode(sentences: Union[str, List[str]], batch_size, device) -> ndarray | List[ndarray]`，单条与批量输入统一通过一个接口处理；图片后端实现 `embeddings/protocols.ImageEncoderProtocol`：`encode_image_urls(urls, batch_size) -> List[ndarray]`，与 urls 等长，异常直接抛出。

**配置速查**：

| 层次 | 配置键 | 重排 | 向量化 |
|------|--------|------|--------|
| 调用方 | `services.<capability>.provider` | http | http |
| 调用方 | `services.<capability>.providers.http.*_base_url` | 6007 | text=6005 / image=6008 |
| 服务内 | `services.<capability>.backend` | qwen3_vllm / qwen3_transformers / bge / dashscope_rerank | tei / local_st |
| 服务内 | `services.<capability>.backends.<name>` | 模型名、batch、vLLM 参数 | 模型名、device 等 |

### 7.6 新增后端清单（以 Qwen3-Reranker 为例）

1. **实现协议**：在 `reranker/backends/qwen3_vllm.py` 中实现类，提供 `score_with_meta(query, docs, normalize) -> (scores, meta)`，输出与 docs 等长且顺序一致。
2. **配置**：在 `config/config.yaml` 的 `services.rerank.backends` 下增加 `qwen3_vllm` 块（model_name、engine、max_model_len、gpu_memory_utilization、`infer_batch_size`、`sort_by_doc_length`等）；支持环境变量 `RERANK_BACKEND=qwen3_vllm`。
3. **注册**：在 `reranker/backends/__init__.py` 的 `get_rerank_backend(name, config)` 中增加 `qwen3_vllm` 分支。
4. **服务启动**：`reranker/server.py` 启动时根据配置调用 `get_rerank_backend(backend_name, backend_cfg)` 得到实例。
5. **调用方**：无需修改；仅部署时启动使用新后端的 reranker 服务即可。
6. **文档与依赖**：在 `reranker/README.md` 或 docs 中说明依赖（如 vllm）、显存建议；可选依赖放入 `requirements_ml.txt` 或 extra。

### 7.7 配置一致性说明

- **单一路径**：Provider 和 backend 必须由 `config/config.yaml` 的 `services` 块显式指定；未知配置应直接报错。
- **无兼容回退**：不保留“旧配置自动推导/兜底默认值”机制，避免静默行为偏差。
- **环境变量覆盖**：允许环境变量覆盖（如 `RERANKER_SERVICE_URL`、`RERANK_BACKEND`、`RERANK_DASHSCOPE_API_KEY_CN`/`RERANK_DASHSCOPE_API_KEY_US`、`RERANK_DASHSCOPE_ENDPOINT`、`EMBEDDING_TEXT_SERVICE_URL`、`EMBEDDING_IMAGE_SERVICE_URL`、`EMBEDDING_BACKEND`、`TEI_BASE_URL`），但覆盖后仍需满足合法性校验。

---

## 8. 代码规范与质量

### 8.1 风格与结构

- **Python**：遵循 PEP 8；类型注解推荐在公共接口与配置数据结构上使用；模块级文档字符串简要说明职责。
- **包结构**：业务逻辑按能力归属对应顶层包；共享工具放 `utils`；不随意新增与现有包平行的“杂项”包。
- **命名**：模块与类名清晰表意；配置键与 `config.yaml` / 环境变量命名保持一致。

### 8.2 测试

测试流水线的权威说明见 [`docs/测试Pipeline说明.md`](./测试Pipeline说明.md)。核心约定：

- **位置**：`tests/` 下按文件平铺，`tests/ci/` 放 API 契约测试，`tests/manual/` 放需人工起服务的联调脚本（pytest 默认不 collect）。
- **Marker**：`pytest.ini` 里登记了子系统 marker（`search / query / intent / rerank / embedding / translation / indexer / suggestion / eval / contract`）与 `regression` marker；新测试必须贴对应 marker（`--strict-markers` 会强制）。
- **依赖**：测试一律通过注入 fake stub 隔离 ES / DeepL / LLM / Redis 等外部依赖。需要真实依赖的脚本放 `tests/manual/`。
- **运行**：
  - CI 门禁：`./scripts/run_ci_tests.sh`（契约 + search 回归锚点）
  - 发版前：`./scripts/run_regression_tests.sh`（全部 `regression` 锚点；可配 `SUBSYSTEM=<name>`）
  - 全量：`python -m pytest tests/ -q`
- **原则**：新增逻辑应有对应测试；修改协议或配置契约时**同步**更新契约测试。不要在测试里保留"旧 assert 作为兼容"——请直接面向当前实现写断言，失败即意味着契约已变更，需要上层决策。

### 8.3 配置与环境

- 测试用配置优先从 fixture 或临时 config 构造，避免依赖仓库外部的 `.env` 或真实 DB/ES；必要时使用 `clear_services_cache()` 等清理缓存。
- 不在代码中提交敏感信息；敏感项通过 `.env` 或环境变量注入，并在文档中说明。

### 8.4 日志与可观测性

- 关键路径（请求入口、外部调用、失败报错）打日志；日志级别合理（如 debug 用于详细参数，info 用于流程，error 用于失败）。
- 对外接口的耗时、错误码、租户等可考虑结构化日志或后续接入监控，便于运维与排查。

---

## 9. 迭代检查清单

在提交代码或发起 Code Review 前，建议自检以下项，确保迭代符合框架与规范。

### 9.1 架构与模块

- [ ] 新逻辑放在合适的现有包中，未随意新建与现有能力平行的顶层包。
- [ ] 未在业务代码中硬编码服务 URL、后端类型或租户 ID。
- [ ] 调用外部能力时遵循统一入口：translation 使用 `translation.create_translation_client()`，embedding / rerank 使用 providers 工厂，配置来自 `services_config`。

### 9.2 配置与扩展

- [ ] 新增配置项放在 `config.yaml` 或 `services.<capability>` 下，并有环境变量覆盖方式（如需要）。
- [ ] 新增 Provider 或 Backend 时已阅读本指南 §7，并按要求实现协议、注册与配置。
- [ ] 新增后端满足现有协议（输入输出、顺序、长度、meta），未破坏调用方。

### 9.3 索引与查询

- [ ] 索引结构变更已同步到 `mappings/search_products.json`；indexer 产出与 mapping 一致。
- [ ] 查询/分面/过滤使用的字段名与 mapping 一致；多语言字段使用 `.zh`/`.en` 等约定。

### 9.4 测试与质量

- [ ] 新增或修改逻辑有对应测试；修改接口或协议时已更新相关测试与 fixture。
- [ ] 单元测试不依赖真实 ES/DB；集成测试在文档或注释中说明依赖。
- [ ] 无敏感信息提交；敏感配置通过环境变量或 .env 说明。

### 9.5 文档与可维护性

- [ ] 新增模块或重要行为在 README 或 docs 中有简要说明；复杂逻辑有注释或文档引用。
- [ ] 本指南与相关专项文档在需要时已更新（如新增服务、端口、配置项、扩展步骤）。

---

## 10. 文档与资源索引

### 10.1 按用途查找

| 用途 | 文档 |
|------|------|
| 新人上手、环境与请求示例 | [QUICKSTART.md](./QUICKSTART.md) |
| 框架全貌与规范（本文） | 本指南 |
| Provider 与基础配置、模块扩展（协议与后端） | [QUICKSTART.md](./QUICKSTART.md) §2–§4、本指南 §7 |
| 索引结构、字段、MySQL→ES 映射 | [索引方案.md](./索引方案.md)、[索引字段说明v2.md](./索引字段说明v2.md)、[MySQL到ES文档映射说明.md](./MySQL到ES文档映射说明.md) |
| 搜索/索引 API（分册入口） | [搜索API对接指南-00-总览与快速开始.md](./搜索API对接指南-00-总览与快速开始.md) |
| 翻译模块与本地模型 | [翻译模块说明.md](./翻译模块说明.md) |
| 搜索 API 参数速查 | [搜索API对接指南-速查表.md](./搜索API对接指南-速查表.md) |
| 首次部署、新机器环境、生产凭证 | [QUICKSTART.md](./QUICKSTART.md) §1.4–1.8 |
| 运维、日志、多环境、故障 | [Usage-Guide.md](./Usage-Guide.md) |
| 索引模块职责与 Java 对接 | [indexer/README.md](../indexer/README.md) |
| 向量模块与 clip-as-service | [embeddings/README.md](../embeddings/README.md) |
| TEI 服务专项（安装/部署/GPU-CPU 模式） | [TEI_SERVICE说明文档.md](./TEI_SERVICE说明文档.md) |
| CN-CLIP 服务专项（环境/运维/GPU） | [CNCLIP_SERVICE说明文档.md](./CNCLIP_SERVICE说明文档.md) |
| 缓存 / Redis 使用与 key 设计 | [缓存与Redis使用说明.md](./缓存与Redis使用说明.md) |

### 10.2 仓库内入口

- **README.md**：项目简介、快速命令、文档索引。
- **CLAUDE.md**：面向 AI 助手的项目说明与命令汇总，与本指南互补。
- **本指南（docs/DEVELOPER_GUIDE.md）**：面向人的全貌与规范入口。

---

*本文档旨在让所有后续开发在预知框架全貌的前提下，在规范内迭代，减少分叉与冗余，提升可维护性。如有结构或规范变更，请同步更新本指南及相关专项文档。*
