01 Apr, 2026

1 commit

  • 现在的行为(按你的路径)
    用途	路径(相对仓库根 PROJECT_ROOT)
    评估主日志(CLI + framework 的 INFO)	logs/eval.log
    LLM 全量 prompt / 原始响应	logs/verbose/eval_verbose.log
    实现要点:
    
    constants.py:EVAL_LOG_DIR、EVAL_VERBOSE_LOG_DIR、EVAL_LOG_FILE、EVAL_VERBOSE_LOG_FILE。
    logging_setup.py:setup_eval_logging() 给名为 search_eval 的 logger 挂
    文件 + stderr,只初始化一次;build_annotation_set.py / serve_eval_web.py
    走的 eval_framework.cli.main() 开头会先调用。
    cli.py:原来的 print 改为 search_eval.cli 的 logging.info;启动时写一条
    CLI start command=... log_file=... 到 logs/eval.log。
    framework.py:rebuild 相关 print 改为 search_eval.framework 的
    logging.info。
    clients.py:verbose 改为写入
    logs/verbose/eval_verbose.log;首次需要时调用 setup_eval_logging(),并用
    search_eval.info 提示 verbose 文件路径(不再用 print)。
    tangwang
     

30 Mar, 2026

2 commits


23 Mar, 2026

2 commits


19 Mar, 2026

3 commits

  • tangwang
     
  • tangwang
     
  • 推理”,不再是先按原始输入条数切块。也就是说,如果 100 条请求分句后变成
    150 个 segments,batch_size=64 时会按 64 + 64 + 22
    三批推理,推理完再按原始分句计划合并并还原成 100 条返回。这个改动在
    local_seq2seq.py (line 241) 和 local_ctranslate2.py (line 391)。
    
    日志这边也补上了两层你要的关键信息:
    
    分句摘要日志:Translation segmentation
    summary,会打印输入条数、非空条数、发生分句的输入数、总 segments
    数、当前 batch_size、每条输入分成多少段的统计,见 local_seq2seq.py (line
    216) 和 local_ctranslate2.py (line 366)。
    每个预测批次日志:Translation inference
    batch,会打印第几批、总批数、该批 segment
    数、长度统计、首条预览。CTranslate2 另外还会打印 Translation model batch
    detail,补充 token 长度和 max_decoding_length,见 local_ctranslate2.py
    (line 294)。
    我也补了测试,覆盖了“分句后再
    batching”和“日志中有分句摘要与每批推理日志”,在
    test_translation_local_backends.py (line 358)。
    tangwang
     

18 Mar, 2026

2 commits

  • tangwang
     
  • 核心改动在 rerank_client.py (line 99):fuse_scores_and_resort 现在按
    rerank * knn * text 的平滑乘法公式计算,优先从 hit["matched_queries"]
    里取 base_query 和 knn_query,并把 _text_score / _knn_score
    一并写回调试字段。为了让 KNN 也有名字,我给 top-level knn 加了 name:
    "knn_query",见 es_query_builder.py (line 273)。搜索执行时会在 rerank
    窗口内打开 include_named_queries_score,并在显式排序时加上
    track_scores,见 searcher.py (line 400) 和 es_client.py (line 224)。
    tangwang
     

17 Mar, 2026

3 commits

  • tangwang
     
  • 多个独立翻译能力”重构。现在业务侧不再把翻译当 provider
    选型,QueryParser 和 indexer 统一通过 6006 的 translator service client
    调用;真正的能力选择、启用开关、model + scene 路由,都收口到服务端和新的
    translation/ 目录里了。
    
    这次的核心改动在
    config/services_config.py、providers/translation.py、api/translator_app.py、config/config.yaml
    和新的 translation/service.py。配置从旧的
    services.translation.provider/providers 改成了 service_url +
    default_model + default_scene + capabilities,每个能力可独立
    enabled;服务端新增了统一的 backend 管理与懒加载,真实实现集中到
    translation/backends/qwen_mt.py、translation/backends/llm.py、translation/backends/deepl.py,旧的
    query/qwen_mt_translate.py、query/llm_translate.py、query/deepl_provider.py
    只保留兼容导出。接口上,/translate 现在标准支持 scene,context
    作为兼容别名继续可用,健康检查会返回默认模型、默认场景和已启用能力。
    tangwang
     
  • - Rename indexer/product_annotator.py to indexer/product_enrich.py and remove CSV-based CLI entrypoint, keeping only in-memory analyze_products API
    - Introduce dedicated product_enrich logging with separate verbose log file for full LLM requests/responses
    - Change indexer and /indexer/enrich-content API wiring to use indexer.product_enrich instead of indexer.product_annotator, updating tests and docs accordingly
    - Switch translate_prompts to share SUPPORTED_INDEX_LANGUAGES from tenant_config_loader and reuse that mapping for language code → display name
    - Remove hard SUPPORTED_LANGS constraint from LLM content-enrichment flow, driving languages directly from tenant/indexer configuration
    - Redesign LLM prompt generation to support multi-round, multi-language tables: first round in English, subsequent rounds translate the entire table (headers + cells) into target languages using English instructions
    tangwang
     

16 Mar, 2026

2 commits


13 Mar, 2026

5 commits


12 Mar, 2026

1 commit


11 Mar, 2026

3 commits


10 Mar, 2026

4 commits

  • tangwang
     
  • - 配置改为“字段基名 + 动态语言后缀”方案,已不再依赖旧 `indexes`。
    [config.yaml](/data/saas-search/config/config.yaml#L17)
    - `search_fields` / `text_query_strategy` 已进入强校验与解析流程。
    [config_loader.py](/data/saas-search/config/config_loader.py#L254)
    
    2. 查询语言计划与翻译等待策略
    - `QueryParser` 现在产出
      `query_text_by_lang`、`search_langs`、`source_in_index_languages`。
    [query_parser.py](/data/saas-search/query/query_parser.py#L41)
    - 你要求的两种翻译路径都在:
      - 源语言不在店铺 `index_languages`:`translate_multi_async` + 等待
        future
      - 源语言在 `index_languages`:`translate_multi(...,
        async_mode=True)`,尽量走缓存
    [query_parser.py](/data/saas-search/query/query_parser.py#L284)
    
    3. ES 查询统一文本策略(无 AST 分支)
    - 主召回按 `search_langs` 动态拼 `field.{lang}`,翻译语种做次权重
      `should`。
    [es_query_builder.py](/data/saas-search/search/es_query_builder.py#L454)
    - 布尔 AST 路径已删除,仅保留统一文本策略。
    [es_query_builder.py](/data/saas-search/search/es_query_builder.py#L185)
    
    4. LanguageDetector 优化
    - 从“拉丁字母默认英文”升级为:脚本优先 +
      拉丁语系打分(词典/变音/后缀)。
    [language_detector.py](/data/saas-search/query/language_detector.py#L68)
    
    5. 布尔能力清理(补充)
    - 已删除废弃模块:
    [boolean_parser.py](/data/saas-search/search/boolean_parser.py)
    - `search/__init__` 已无相关导出。
    [search/__init__.py](/data/saas-search/search/__init__.py)
    
    6. `indexes` 过时收口(补充)
    - 兼容函数改为基于动态字段生成,不再依赖 `config.indexes`。
    [utils.py](/data/saas-search/config/utils.py#L24)
    - Admin 配置接口改为返回动态字段配置,不再暴露 `num_indexes`。
    [admin.py](/data/saas-search/api/routes/admin.py#L52)
    
    7. suggest
    tangwang
     
  • tangwang
     
  • 1. 新增 `scripts/init_env.sh`
    - 若 `.env` 不存在,从 `.env.example` 复制生成
    - 支持 `--force`:覆盖 `.env` 并备份为 `.env.bak`
    - 首次搭建时统一执行:`./scripts/init_env.sh`
    
     2. 统一加载逻辑 `scripts/lib/load_env.sh`
    - 移除 `activate.sh` 和 `service_ctl.sh` 中的重复解析逻辑
    - 使用共享的 `load_env_file`,并改为 `eval "$(printf 'export %s=%q\n'
      "$key" "$value")"` 安全导出
    - 支持含 ``、`$`、空格等特殊字符的值(需在 `.env` 中用引号包裹)
    
     3. 使用方式
    - **activate.sh**:`source scripts/lib/load_env.sh` 后调用
      `load_env_file`
    - **service_ctl.sh**:同上,去掉内联的 `load_env_file` 实现
    - **create_tenant_index.sh**:改为使用共享 loader,不再用 `set -a;
      source .env`
    
     4. 文档更新
    - **README.md**:在快速开始中加入 `./scripts/init_env.sh`
    - **docs/QUICKSTART.md**:说明 `init_env.sh`
      用法,并强调含特殊字符的密码需加引号
    - **.env.example**:补充注释说明引号规则
    
     5. setup.sh
    - 用 `./scripts/init_env.sh` 替代原先的 `cp .env.example .env`
    
    ---
    
    **推荐流程**:
    ```bash
    ./scripts/create_venv.sh
    ./scripts/init_env.sh     从 .env.example 生成本地 .env
    source activate.sh
    ./run.sh
    ```
    
    **密码写法**:若密码包含 ``、`$`、`&`、空格等,需加引号,例如:
    ```env
    DB_PASSWORD="qY8tgodLoA&KTyQ"
    ES_PASSWORD="4hOaLaf41y2VuI8y"
    ```
    tangwang
     

09 Mar, 2026

2 commits


06 Mar, 2026

1 commit


02 Mar, 2026

3 commits

  • - 新增 suggestion 模块(mapping/builder/service),支持按租户构建 `search_suggestions_tenant_{tenant_id}` 索引
    - 新增 `main.py build-suggestions` CLI 与 `scripts/build_suggestions.sh`,支持基于商品 title/qanchors 与近 365 天搜索日志的全量构建
    - 实现 `/search/suggestions` 接口(多语言 + 结果直达),并接入前端自动补全使用新的后端 API
    - 为 suggestion 增加 `README` / `RUNBOOK` / `TROUBLESHOOTING` 文档,更新搜索 API 对接指南与速查表
    - 补充 `tests/test_suggestions.py` 单元测试,覆盖语言解析和 SuggestionService 查询流程
    
    Made-with: Cursor
    tangwang
     
  • - 新增 `suggestion` 模块:
      - `suggestion/mapping.py`:`search_suggestions` mapping 生成(多语言 `completion` + `search_as_you_type`)
      - `suggestion/builder.py`:全量构建程序(扫描 `search_products` 的 `title/qanchors` + MySQL `shoplazza_search_log`)
      - `suggestion/service.py`:在线查询服务(suggestion 检索 + 结果直达商品二次查询)
      - `suggestion/__init__.py`
    
    - 接入 API 服务初始化:
      - `api/app.py` 新增 `SuggestionService` 初始化和 `get_suggestion_service()`
    
    - 接口实现:
      - `api/routes/search.py` 的 `GET /search/suggestions` 从“空框架”改为真实调用
      - 支持参数:
        - `q`, `size`, `language`
        - `with_results`(是否直达商品)
        - `result_size`(每条 suggestion 商品数)
        - `debug`
      - 继续要求 `X-Tenant-ID`(或 query 的 `tenant_id`)
    
    - 模型补充:
      - `api/models.py` 增加 suggestion 请求/响应字段(`language`, `resolved_language`, `with_results`, `result_size`)
    
    - CLI 全量构建命令:
      - `main.py` 新增 `build-suggestions`
      - 使用方式:
        - `python main.py build-suggestions --tenant-id 1 --recreate`
        - 可选:`--days 30 --batch-size 500 --min-query-len 1 --es-host ...`
    
    ---
    
     关键实现逻辑(已编码)
    
    - 语言归属优先级(按你要求):
      - `shoplazza_search_log.language` > `request_params.language` > 脚本/模型兜底
    - 候选词聚合键:
      - `(tenant_id, lang, text_norm)`(文档唯一)
    - 评分:
      - 基于 `query_count_30d/7d + qanchor_doc_count + title_doc_count` 的离线分
    - 结果直达:
      - 对每条 suggestion 在 `search_products_tenant_{id}` 做二次查询(`qanchors/title` 组合)
    
    ---
    
     变更文件
    
    - `api/app.py`
    - `api/models.py`
    - `api/routes/search.py`
    - `main.py`
    - `suggestion/__init__.py`
    - `suggestion/mapping.py`
    - `suggestion/builder.py`
    - `suggestion/service.py`
    tangwang
     
  • - 新增 /indexer/build-docs 与 /indexer/build-docs-from-db 接口:前者接收上游传入的 SPU/SKU/Option 原始行数据构建 ES doc(不写 ES),后者在测试场景下基于 tenant_id+spu_ids 内部查库并复用同一套文档构建逻辑
    - 调整增量与全量索引 SQL 与聚合逻辑:移除 shoplazza_product_spu.compare_at_price 读取,统一从 SKU 表聚合最大 compare_at_price,修复 1054 列不存在错误,保证 ES 字段 compare_at_price 来源与索引字段说明v2 保持一致
    - 更新 SPUDocumentTransformer:完善价格区间计算、compare_at_price 聚合以及多语言字段输出,确保输出结构与 mappings/search_products.json、Java 侧 ProductIndexDocument 完全对齐
    - 为 indexer 模块补充 README 与 prompts:系统化说明 Java 调度 + Python 富化的职责划分、翻译缓存方案(Redis translation:{tenant_id}:{target_lang}:{md5(text)})以及 HTTP 接口使用方式
    - 更新顶层 README、搜索API对接指南与测试Pipeline说明:增加关于 indexer 专用服务(serve-indexer, 端口6004)、正式文档构建接口以及手动链路验证(MySQL → build-docs → ES 查询对比)的说明
    - 清理并修正 ES 诊断脚本 docs/常用查询 - ES.md:统一改为 per-tenant 索引 search_products_tenant_{tenant_id},修正过期字段名(keywords 等)和分面聚合字段(去掉 .keyword,使用当前 mapping 中的字段)
    
    Made-with: Cursor
    tangwang
     

06 Feb, 2026

1 commit

  • ---
    
     1. `search/es_query_builder.py`:`_all` 分支
    
    - **普通字段**(如 `tags_all`, `category1_name_all`):
      - 键以 `_all` 结尾时,先去掉后缀得到 ES 字段名。
      - 若值为**数组**:生成 `bool.must`,内含多个 `term`,即多值 **AND**。
      - 若值为**单值**:生成一个 `term`。
    - **specifications_all**:
      - 值为 `[{name, value}, ...]` 时,为每一项生成一个 nested 查询,全部放入同一个 `bool.must`,即列表内所有规格条件都要满足(AND)。
    
    原有逻辑不变:不带 `_all` 的字段,数组仍为 OR(`terms`),单值仍为 `term`。
    
     2. `api/models.py`:filters 说明
    
    - 在 `filters` 的 `description` 中补充:
      - 字段名加 `_all` 表示 AND(如 `tags_all: ['A','B']` 表示同时包含 A 和 B)。
      - `specifications_all` 表示列表内所有规格条件都要满足。
    
     3. `docs/搜索API对接指南.md`:文档
    
    - 在 3.3.1 开头说明:任意字段名可加 `_all` 后缀表示多值 AND。
    - 在格式示例中增加 `tags_all`、`category1_name_all` 示例。
    - 在「支持的值类型」中说明:数组在带 `_all` 时为 AND。
    - 新增小节「`*_all` 语义(多值 AND)」:说明用法及 `specifications_all` 行为。
    - 在「常用过滤字段」中补充:以上字段均可加 `_all` 后缀。
    
    ---
    
    **使用示例**
    
    ```json
    {
      "filters": {
        "tags": ["手机", "促销"],
        "tags_all": ["手机", "促销", "新品"]
      }
    }
    ```
    
    - `tags`:命中「手机」或「促销」或两者都有(OR)。
    - `tags_all`:必须同时包含「手机」「促销」「新品」三个标签(AND)。
    tangwang
     

05 Feb, 2026

2 commits

  • tangwang
     
  • - API:新增请求参数 ai_search,开启时在窗口内走重排流程
    - 配置:RerankConfig 移除 enabled/expression/description,仅保留 rerank_window 及
      service_url/timeout_sec/weight_es/weight_ai;默认超时 15s
    - 重排流程:ai_search 且 from+size<=rerank_window 时,ES 取前 rerank_window 条,
      调用外部 /rerank 服务,融合 ES 与重排分数后按 from/size 分页;否则不重排
    - search/rerank_client:新增模块,封装 build_docs、call_rerank_service、
      fuse_scores_and_resort、run_rerank;超时单独捕获并简短日志
    - search/searcher:移除 RerankEngine,enable_rerank=ai_search,使用 config.rerank 参数
    - 删除 search/rerank_engine.py(本地表达式重排),统一为外部服务一种实现
    - 文档:搜索 API 对接指南补充 ai_search 与 relevance_score 说明
    - 测试:conftest 中 rerank 配置改为新结构
    
    Co-authored-by: Cursor <cursoragent@cursor.com>
    tangwang
     


26 Jan, 2026

1 commit


24 Jan, 2026

1 commit