QUICKSTART.md 23.6 KB

开发与配置指南

新人入口:环境、服务、模块、请求示例、基础配置、Provider 架构、模块扩展规范,一文档搞定。

建议:首次参与开发请先阅读 DEVELOPER_GUIDE.md 建立项目全貌与协作规范,再使用本文做环境与配置速查。


为什么这样整合

以下文档已删除,其核心内容已并入本文与 DEVELOPER_GUIDE.md §7:原 PROVIDER_ARCHITECTURE.mdMODULE_EXTENSION_SPEC.md基础配置指南.md。本文保留环境、服务、基础配置、Provider 与模块扩展的速查;协议与新增后端清单见 DEVELOPER_GUIDE §7。

关于 docs/Usage-Guide.md:保留为运行/运维手册更清晰(日志、故障排查、多环境切换、建议索引运行细节),本文只保留开发常用且高频的信息,避免一个文档同时承担“开发规范 + 运维 runbook”导致冗长和混乱。


目录

  1. 快速上手
  2. 基础配置与搜索行为
  3. Provider 架构
  4. 模块扩展规范(Embedding / Rerank)
  5. 验证、日志与常见排障入口
  6. 相关文档
  7. 持续集成测试(最小可维护方案)

1. 快速上手

1.1 环境准备

source activate.sh
# 首次创建环境:
./scripts/create_venv.sh

# embedding 服务独立环境(推荐)
./scripts/setup_embedding_venv.sh

# reranker 服务独立环境(Qwen3-vLLM)
./scripts/setup_reranker_venv.sh

# CN-CLIP 独立环境
./scripts/setup_cnclip_venv.sh

依赖:Python 3.8+、Elasticsearch 8.x、MySQL、Redis(可选,缓存用途)。

更详细的系统要求、Python 环境、外部服务与生产凭证见 1.4–1.8

1.2 服务与端口

服务 端口 默认启动 说明
backend 6002 搜索 API(/search/*)+ 管理接口(/admin/*
indexer 6004 索引 API(/indexer/*
frontend 6003 调试 UI
eval-web 6010 搜索评估 Web(scripts/evaluation/,依赖 backend 联调)
embedding 6005 - 文本向量服务(/embed/text
embedding-image 6008 - 图片向量服务(/embed/image
translator 6006 - 翻译服务(/translate
reranker 6007 - 重排服务(/rerank

启动与停止:

./run.sh all
# 仅为薄封装:等价于 ./scripts/service_ctl.sh up all
# 说明:
# - all = tei cnclip embedding embedding-image translator reranker reranker-fine backend indexer frontend eval-web
# - up 会同时启动 monitor daemon(运行期连续失败自动重启)
# - reranker 为 GPU 强制模式(资源不足会直接启动失败)
# - TEI 默认使用 GPU;当 TEI_DEVICE=cuda 且 GPU 不可用时会直接失败(不会自动降级到 CPU)
# - cnclip 默认使用 cuda;若显式配置为 cuda 且 GPU 不可用会直接失败(不会自动降级到 cpu)

./restart.sh all
# 仅为薄封装:等价于 ./scripts/service_ctl.sh restart all

./scripts/service_ctl.sh status
./scripts/stop.sh all    # 仅为薄封装:等价于 ./scripts/service_ctl.sh down all

服务管理方式(入口职责、默认行为、全量拉起顺序)见:

  • docs/Usage-Guide.md -> 服务管理总览

1.3 常用 API 请求示例

搜索 API(backend 6002)

# 文本搜索
curl -X POST http://localhost:6002/search/ \
  -H "Content-Type: application/json" \
  -H "X-Tenant-ID: 162" \
  -d '{"query": "玩具", "size": 10}'

# 图片搜索
curl -X POST http://localhost:6002/search/image \
  -H "Content-Type: application/json" \
  -H "X-Tenant-ID: 162" \
  -d '{"image_url": "https://example.com/img.jpg", "size": 10}'

# Suggestion
curl "http://localhost:6002/search/suggestions?q=玩&size=5" \
  -H "X-Tenant-ID: 162"

# 健康与统计
curl http://localhost:6002/admin/health
curl http://localhost:6002/admin/stats -H "X-Tenant-ID: 162"

API 文档:http://localhost:6002/docs

索引 API(indexer 6004)

# 创建租户索引
./scripts/create_tenant_index.sh 162

# 全量重建(更新/写入,不删除旧索引)
curl -X POST http://localhost:6004/indexer/reindex \
  -H "Content-Type: application/json" \
  -d '{"tenant_id": "162", "batch_size": 500}'

# 增量索引
curl -X POST http://localhost:6004/indexer/index \
  -H "Content-Type: application/json" \
  -d '{"tenant_id": "162", "spu_ids": ["1001", "1002"]}'

# 构建文档(不写 ES)
curl -X POST http://localhost:6004/indexer/build-docs \
  -H "Content-Type: application/json" \
  -d '{"tenant_id":"162","items":[{"spu":{},"skus":[],"options":[]}]}'

API 文档:http://localhost:6004/docs

Embedding 服务(文本 6005 / 图片 6008)

# TEI(文本向量后端,默认)
# GPU(需 nvidia-container-toolkit)
TEI_DEVICE=cuda ./scripts/start_tei_service.sh

# Embedding API(text 会校验 TEI /health)
./scripts/start_embedding_text_service.sh
./scripts/start_embedding_image_service.sh

curl -X POST http://localhost:6005/embed/text \
  -H "Content-Type: application/json" \
  -d '["衣服", "Bohemian Maxi Dress"]'

curl -X POST http://localhost:6008/embed/image \
  -H "Content-Type: application/json" \
  -d '["https://example.com/img.jpg"]'

说明:

  • TEI 默认镜像按 TEI_VERSION 组装:cuda-<version>(默认 1.9)。
  • TEI_DEVICE=cuda 时会严格校验 Docker GPU runtime;未配置会直接报错退出。
  • /embed/image 依赖 cnclipgrpc://127.0.0.1:51000),未启动时图片 embedding 服务会启动失败。

Translator 服务(6006)

./scripts/setup_translator_venv.sh
./.venv-translator/bin/python scripts/download_translation_models.py --all-local   # 如需本地模型
./scripts/start_translator.sh

curl -X POST http://localhost:6006/translate \
  -H "Content-Type: application/json" \
  -d '{"text":"商品名称","target_lang":"en","source_lang":"zh","model":"qwen-mt","scene":"sku_name"}'

说明:

  • translator service 是翻译统一入口,业务侧不再直接选择翻译 provider。
  • 本地模型默认关闭;需先在 config/config.yaml -> services.translation.capabilities 中启用,再通过 model 指定。

Reranker 服务(6007)

# 默认后端 qwen3_vllm(Qwen3-Reranker-0.6B)
./scripts/start_reranker.sh

curl -X POST http://localhost:6007/rerank \
  -H "Content-Type: application/json" \
  -d '{"query":"wireless mouse","docs":["logitech mx master","usb cable"]}'

1.4 系统要求

  • 操作系统:Linux(推荐 Ubuntu 18.04+)
  • Python:3.10(由 venv 提供)
  • 内存:建议 8GB+(含模型与 ES)
  • 磁盘:10GB+(含模型与索引)

1.5 Python 运行环境(详细)

项目根目录的 activate.sh 激活 .venv 并加载当前目录 .env

cd /data/saas-search
./scripts/create_venv.sh
source activate.sh

主程序 .venv 与模型服务环境隔离:

  • 主程序:.venv./scripts/create_venv.sh
  • embedding 服务:.venv-embedding./scripts/setup_embedding_venv.sh
  • reranker 服务:.venv-reranker./scripts/setup_reranker_venv.sh
  • cnclip:.venv-cnclip./scripts/setup_cnclip_venv.sh
  • TEI:Docker 容器(./scripts/start_tei_service.sh

1.6 外部服务与 .env(含生产凭证)

以下为 AI 生产环境 统一使用的地址与凭证(Redis / ES / MySQL 均以此为准)。本地开发可将 DB_HOST/ES_HOST/REDIS_HOST 改为 localhost(服务在本机时)。

服务 地址(生产) 端口 说明
MySQL 10.200.16.14 / localhost 3316 店匠 SPU/SKU 数据
Redis 10.200.16.14 / localhost 6479 Embedding/翻译缓存
Elasticsearch 10.200.16.14 / localhost 9200 搜索索引

MySQL(AI 生产推荐使用 root,3 个用户均可远程登录):

用户 密码 说明
root qY8tgodLoA&KT#yQ AI 生产推荐
saas 6dlpco6dVGuqztl 业务用户
sa C#HU!GPps7ck8tsM 备用

创建远程用户(如尚未创建):

mysql -uroot -p'qY8tgodLoA&KT#yQ'
CREATE USER 'saas'@'%' IDENTIFIED BY '6dlpco6dVGuqzt^l';
CREATE USER 'sa'@'%' IDENTIFIED BY 'C#HU!GPps7ck8tsM';

Redis

  • 地址:10.200.16.14:6479
  • 密码:dxEkegEZ@C5SXWKv
  • 远程登录示例:redis-cli -h 10.200.16.14 -p 6479 -a 'dxEkegEZ@C5SXWKv' --no-auth-warning

Elasticsearch

  • 用户名/密码:saas / 4hOaLaf41y2VuI8y
  • 访问示例:
curl -u 'saas:4hOaLaf41y2VuI8y' \
  -X GET 'http://localhost:9200/search_products_tenant_111/_search?pretty' \
  -H 'Content-Type: application/json' \
  -d '{
    "size": 11,
    "_source": ["title"],
    "query": {
      "bool": {
        "filter": [
          { "term": {"spu_id" : 206150} }
        ]
      }
    }
  }'

注意(Kibana 运维):应用侧 .envES_USERNAME/ES_PASSWORD 仅用于业务服务访问 ES;Kibana 不应复用该账号。Kibana 推荐在 /etc/kibana/kibana.yml 使用 elasticsearch.serviceAccountToken,否则在 .kibana_* 受限索引迁移阶段可能出现 security_exception 并导致 5601 长时间无响应。

在项目根目录创建 .env

./scripts/init_env.sh   # 从 .env.example 复制(若 .env 不存在)

然后按环境修改 .env含特殊字符(#、$、&、空格)的密码需加引号,例如:

# MySQL(AI 生产 10.200.16.14:3316,推荐 root)
DB_HOST=10.200.16.14
DB_PORT=3316
DB_DATABASE=saas
DB_USERNAME=root
DB_PASSWORD="qY8tgodLoA&KT#yQ"

# Elasticsearch
ES_HOST=http://10.200.16.14:9200
ES_USERNAME=saas
ES_PASSWORD="4hOaLaf41y2VuI8y"

# Redis(可选)
REDIS_HOST=10.200.16.14
REDIS_PORT=6479
REDIS_PASSWORD="dxEkegEZ@C5SXWKv"

# DeepL 翻译(按需)
DEEPL_AUTH_KEY=your-key

# API
API_HOST=0.0.0.0
API_PORT=6002
EVAL_WEB_PORT=6010

生产环境请妥善保管凭证;本地/测试可改用上述值或自建实例。

1.7 店匠数据源说明

saas-search 以 MySQL 中的店匠标准表为权威数据源:

  • shoplazza_product_spu:SPU 商品主表
  • shoplazza_product_sku:SKU 变体表

shoplazza_product_sku 字段节选id, spu_id, shop_id, title, sku, price, compare_at_price, option1/2/3, inventory_quantity, image_src, tenant_id, create_time, update_time, deleted 等。完整字段与 ES 对应关系见 docs/索引字段说明v2.mddocs/MySQL到ES文档映射说明.md

1.8 相关脚本

  • activate.sh(项目根目录):激活 Python 环境并加载 .env,日常开发/部署以本脚本为准。
  • scripts/create_venv.sh:创建主程序 venv(.venv
  • scripts/setup_embedding_venv.sh:创建 embedding 服务 venv(.venv-embedding
  • scripts/setup_reranker_venv.sh:创建 reranker 服务 venv(.venv-reranker
  • scripts/start_tei_service.sh:启动 TEI 容器(文本向量后端)
  • scripts/mock_data.sh:生成 Tenant1 Mock + Tenant2 CSV 并导入 MySQL
  • scripts/create_tenant_index.sh <tenant_id>:创建租户 ES 索引结构
  • POST /indexer/reindex:从 MySQL 全量导入到 ES
  • run.sh / restart.sh / scripts/stop.sh:推荐入口(对应 up/restart/down)
  • scripts/service_ctl.shup/down/start/stop/restart/status/monitor/monitor-start/monitor-stop/monitor-status

更多脚本与验证命令见 docs/Usage-Guide.md

1.9 配置入口总览

  • 搜索行为配置config/config.yaml
  • 索引结构定义mappings/search_products.json
  • provider/服务配置config/config.yamlservices
  • 环境变量.env

---·

2. 基础配置与搜索行为

2.1 总体原则

  • 统一索引结构:所有租户使用同一套 mapping(按租户数据分索引名 + 文档内 tenant_id 隔离)
  • SPU 级索引:每个文档是一个 SPU,包含嵌套 skusspecifications
  • 配置文件驱动:搜索权重、动态多语言字段、重排融合、provider 全在 config/config.yaml,不再以“硬编码配置”为主

2.2 索引结构(Mapping)

文件:mappings/search_products.json

核心字段可分为:

  • 标识字段:tenant_id, spu_id
  • 多语言文本:title.<lang>, brief.<lang>, description.<lang>, vendor.<lang>, category_path.<lang>, category_name_text.<lang>
  • 类目过滤:category1_name, category2_name, category3_name
  • 规格/变体:specifications(nested)、skus(nested)
  • 价格库存:min_price, max_price, total_inventory
  • 向量:title_embedding(dense vector)、image_embedding(nested)

2.3 查询、权重、排序(config/config.yaml

  • field_boosts:字段权重(统一按字段基名配置,运行时按 .{lang} 动态组装)
  • query_config.search_fields:动态多语言检索字段(multilingual/shared/core)
  • query_config.text_query_strategy:文本召回策略参数(minimum_should_match、翻译boost、翻译失败原文兜底boost等)
  • query_config:语言、embedding 开关、source_fields、knn_boost、翻译提示词等
  • function_score:ES 层加权函数
  • rerank:重排窗口、超时、ES/AI 融合权重

2.4 分面与返回字段

  • 分面字段通常包括:category1_namecategory2_namecategory3_namespecifications.*
  • query_config.source_fields 控制返回字段(null=全部,[]=不返回 source,列表=指定字段)
  • 多语言返回遵循请求 language 与字段回退策略

2.5 修改配置时怎么做

修改项 操作
索引结构(mapping) 修改 mappings/search_products.json./scripts/create_tenant_index.sh <tenant_id> → 重新导入
搜索字段/权重/排序/重排 修改 config/config.yaml 对应块
provider 与服务 URL 修改 config/config.yamlservices 块;translation 的 service_url/default_model/default_scene 只认 YAML,embedding/rerank 仍可按需用环境变量覆盖

3. 能力接入架构

目标:调用方稳定、配置可切换、单一配置源。

3.1 当前代码结构

  • 模块:providers/ + translation/
  • 工厂:translation.create_translation_client()create_embedding_provider()create_rerank_provider()
  • 配置解析:config/services_config.py
能力 调用入口 服务内实现
translation translation/client.py translation/service.py + translation/backends/
embedding providers/embedding.py(http) embedding 服务内 backend
rerank providers/rerank.py(http) reranker 服务内 backend

3.2 配置与覆盖

统一在 config/config.yaml

services:
  translation:
    service_url: "http://127.0.0.1:6006"
    default_model: "llm"
    default_scene: "general"
    timeout_sec: 10.0
    capabilities:
      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 }
      llm: { enabled: true, backend: "llm", model: "qwen-flash", base_url: "https://dashscope-us.aliyuncs.com/compatible-mode/v1", timeout_sec: 30.0 }
      deepl: { enabled: false, backend: "deepl", api_url: "https://api.deepl.com/v2/translate", timeout_sec: 10.0 }
      nllb-200-distilled-600m: { enabled: false, backend: "local_nllb", model_id: "facebook/nllb-200-distilled-600M" }
      opus-mt-zh-en: { enabled: false, backend: "local_marian", model_id: "Helsinki-NLP/opus-mt-zh-en" }
      opus-mt-en-zh: { enabled: false, backend: "local_marian", model_id: "Helsinki-NLP/opus-mt-en-zh" }
  embedding:
    provider: "http"
    backend: "tei"
    providers:
      http: { text_base_url: "http://127.0.0.1:6005", image_base_url: "http://127.0.0.1:6008" }
    backends:
      tei: { base_url: "http://127.0.0.1:8080", timeout_sec: 60, model_id: "Qwen/Qwen3-Embedding-0.6B" }
  rerank:
    provider: "http"
    backend: "qwen3_vllm"  # bge | qwen3_vllm | qwen3_transformers | dashscope_rerank
    providers:
      http: { base_url: "http://127.0.0.1:6007", service_url: "http://127.0.0.1:6007/rerank" }

环境变量覆盖(优先级更高):

  • EMBEDDING_TEXT_SERVICE_URL
  • EMBEDDING_IMAGE_SERVICE_URL
  • EMBEDDING_BACKEND
  • TEI_BASE_URL
  • RERANKER_SERVICE_URL
  • RERANK_BACKEND(服务内后端)
  • RERANK_DASHSCOPE_API_KEY_CN / RERANK_DASHSCOPE_API_KEY_USdashscope_rerank 后端鉴权)
  • RERANK_DASHSCOPE_ENDPOINTdashscope_rerank 地域 endpoint 覆盖)

3.3 新增接入能力的最小步骤

  1. translation 新增能力: 在 translation/backends/ 实现 backend,在 translation/service.py 注册,并在 services.translation.capabilities 增加配置。
  2. embedding / rerank 新增调用方式: 在 providers/<capability>.py 实现 provider 类,并在 create_*_provider() 注册。
  3. embedding / rerank 新增服务内模型: 在对应服务的 backends/ 下实现并注册,在 services.<capability>.backends 新增配置。

说明:

  • translation 的 scene 规则、语言码映射、prompt 模板、模型方向约束位于 translation/ 内部,不再放到 config/
  • 翻译公共接口只暴露 model + scene,不暴露 prompt
  • translation 的 service_urldefault_modeldefault_scene 来自 config/config.yaml -> services.translation,不再由环境变量静默覆盖。

4. 模块扩展规范(Embedding / Rerank)

这里重点区分两层:

  • Provider 层(调用方式):调用方如何访问能力(http/direct)
  • Backend 层(推理实现):服务进程内部具体模型实现(tei / local_st / qwen3_vllm / ...)

4.1 Rerank(重排)扩展

调用链:

search/rerank_client.py -> create_rerank_provider() -> HttpRerankProvider -> POST /rerank

服务实现:

  • reranker/server.py
  • reranker/backends/__init__.py(工厂)
  • reranker/backends/bge.py
  • reranker/backends/qwen3_vllm.py
  • reranker/backends/qwen3_transformers.py
  • reranker/backends/dashscope_rerank.py

后端协议(服务内):

  • 实现 score_with_meta(query, docs, normalize) -> (scores, meta)
  • 返回 scores 与输入 docs 等长且顺序一致

配置位置:

config/config.yaml -> services.rerank.backend + services.rerank.backends.<name>

4.2 Embedding(向量化)扩展

调用链:

create_embedding_provider() -> POST /embed/text / POST /embed/image

服务实现:

  • embeddings/server.py(文本和图像可独立加载)
  • 文本后端默认 TEI(Qwen3-Embedding-0.6B)
  • 图像后端支持本地 CLIP 或 clip-as-service

扩展建议:

  • 文本后端统一提供批量编码能力(与输入索引对齐)
  • 图像后端实现 ImageEncoderProtocolencode_image_urls
  • 如后续后端增多,建议与 rerank 一样在 services.embedding.backend(s) 统一配置

选型建议(Qwen3-Embedding-0.6B):

  • 当前仓库默认:TEI(Text Embeddings Inference)
  • 生产高并发优先:TEI 通常比 vLLM 更贴合 embedding-only 场景
  • vLLM 更适合生成式/重排混合场景;若仅做文本 embedding,通常不作为首选

4.3 新增后端检查清单(以 qwen3_vllm 为例)

  1. 实现后端协议(服务内)
  2. 在后端工厂注册(如 get_rerank_backend
  3. 增加 config/config.yaml 对应 backend 配置
  4. 提供健康检查中的 backend/model 可观测信息
  5. 保持外部 HTTP 契约不变,调用方无需改造

5. 验证、日志与常见排障入口

5.1 快速健康检查

curl http://localhost:6002/health
curl http://localhost:6002/admin/health
curl http://localhost:6004/health
curl http://localhost:6005/health
curl http://localhost:6008/health
curl http://localhost:6006/health
curl http://localhost:6007/health
# eval-web(若已启动):根路径可访问即正常
curl -sf -o /dev/null http://localhost:6010/ || true

5.2 常看日志

  • logs/<service>-YYYY-MM-DD.logservice_ctl.sh 按天写入的真实文件)
  • logs/<service>.log(指向当天文件的软链,推荐 tail -F
  • logs/service-monitor.logservice_ctl.sh monitor 运行期健康检查、失败计数、自动重启日志)
  • logs/api.log(backend 进程内日志,按天轮转)
  • logs/backend_verbose.log(backend 大对象详细日志,按天轮转)
  • logs/indexer.log(索引结构化 JSON 日志,按天轮转)

5.3 常用排障命令

./scripts/service_ctl.sh status
curl http://localhost:9200
lsof -i :6002
lsof -i :6004
lsof -i :6010

更完整的运行排障(多环境切换、Suggestion 构建、FAQ)见 docs/Usage-Guide.md

5.4 HanLP 与 transformers 版本(BertTokenizer.encode_plus

若日志出现 AttributeError: BertTokenizer has no attribute encode_plus,通常是 同一 venv 里装了 transformers 5.x,与 HanLP 2.1.x 不兼容(HanLP 仍调用已移除的 encode_plus)。

处理:transformers 固定到 4.x(例如 4.44+),然后重装/校验 HanLP:

source activate.sh
pip install -r requirements_hanlp.txt
python -c "from transformers import BertTokenizer; import transformers as t; print(t.__version__, hasattr(BertTokenizer, 'encode_plus'))"
# 期望:4.x 且 True

说明: 重排/TEI 等若使用 独立 venv(如 .venv-reranker),可与主 venv 的 transformers 版本分离;主 venv 只要装了 HanLP 做查询分词,就不要把 transformers 升到 5。


6. 相关文档

文档 用途
docs/DEVELOPER_GUIDE.md 项目全貌、规范、协作方式
docs/Usage-Guide.md 运行运维手册:日志、多环境、故障排查、Suggestion 运维
docs/搜索API对接指南-速查表.md 搜索 API 参数速查
docs/搜索API对接指南-00-总览与快速开始.md 搜索 API 分册总览(其余见 搜索API对接指南-01-10
indexer/README.md 索引模块职责与接口
embeddings/README.md 向量化服务说明
docs/TEI_SERVICE说明文档.md TEI 专项(安装、部署、GPU/CPU 模式、排障)
docs/CNCLIP_SERVICE说明文档.md CN-CLIP/clip-as-service 专项(环境、GPU、运维)
reranker/README.md 重排服务说明

7. 持续集成测试(最小可维护方案)

目标:让后续开发者在不依赖真实 ES/MySQL/模型服务的前提下,快速验证核心服务契约不被破坏。

7.1 测试范围

tests/ci/test_service_api_contracts.py 覆盖:

  • 搜索接口:/search//search/image/search/suggestions
  • 索引接口:/indexer/reindex/indexer/index/indexer/build-docs
  • 向量服务:/embed/text/embed/image
  • 翻译服务:/translate/health
  • 重排服务:/rerank/health

7.2 运行方式

source activate.sh
python -m pytest tests/ci -q

7.3 设计取舍

  • 使用 mock/stub 注入依赖,确保测试快且稳定
  • 重点测“接口契约与参数行为”,而不是底层模型质量
  • 作为 PR 级门禁;真实环境联调放在运维/预发布流程