09 Apr, 2026
4 commits
-
2. 删掉自动推断 taxonomy profile的逻辑,build_index_content_fields() 3. 所有 taxonomy profile 都输出 zh/en”,并把按行业切语言的逻辑去掉 只接受显式传入的 category_taxonomy_profile
-
本次迭代对检索系统的内容复化模块进行了较大规模的重构,将原先硬编码的“仅服饰(apparel)”品类拓展至 taxonomy.md 中定义的所有品类,同时优化了代码结构,降低了扩展新品类的成本。核心设计采用注册表模式(profile registry),按品类 profile 分组进行批处理,并明确区分双语(zh+en)与仅英文(en)输出策略。 【修改内容】 1. 品类支持范围扩展 - 新增支持的品类:3c、bags、pet_supplies、electronics、outdoor、home_appliances、home_living、wigs、beauty、accessories、toys、shoes、sports、others - 所有新品类在 taxonomy 输出阶段仅返回 en 字段,避免多语言字段膨胀 - 保留服饰(apparel)品类的双语输出(zh + en),维持原有业务兼容性 2. 核心代码重构 - `indexer/product_enrich.py` - 新增 `TAXONOMY_PROFILES` 注册表,以数据驱动方式定义每个品类的输出语言、prompt 映射、taxonomy 字段集合 - 重写 `_enrich_taxonomy_batch`:按 profile 分组批量调用 LLM,避免为每个品类编写独立分支 - 引入 `_infer_profile_from_category()` 函数,从 SPU 的 category 字段自动推断所属 profile(用于内部索引路径,解决混合目录默认 fallback 到服饰的问题) - `indexer/product_enrich_prompts.py` - 将原有单一服饰 prompt 重构为 `PROMPT_TEMPLATES` 字典,按 profile 存储不同提示词 - 所有非服饰品类共享一套精简提示模板,仅要求输出 en 字段 - `indexer/document_transformer.py` - 在构建 enrichment 请求时传递 category 信息,供下游按 profile 路由 - 调整 `_build_enrich_batch` 逻辑,使批量请求支持混合品类并正确分组 - `indexer/indexer.py`(API 层) - `/indexer/enrich-content` 接口的请求模型增加可选的 `category_profile` 字段,允许调用方显式指定品类;未指定时由服务端自动推断 - 更新参数校验与错误处理,新增对 `others` 等兜底品类的支持 3. 文档同步更新 - `docs/搜索API对接指南-05-索引接口(Indexer).md`:增加品类 profile 参数说明,标注非服饰品类 taxonomy 仅返回 en 字段 - `docs/搜索API对接指南-07-微服务接口(Embedding-Reranker-Translation).md`:更新 enrichment 微服务的调用示例,体现多品类分组批处理 - `taxonomy.md`:补充各品类的字段清单,明确 en 字段为所有非服饰品类的唯一输出 【技术细节】 - **注册表设计**: ```python TAXONOMY_PROFILES = { "apparel": {"lang": ["zh", "en"], "prompt_key": "apparel", "fields": [...]}, "3c": {"lang": ["en"], "prompt_key": "default", "fields": [...]}, \# ... } ``` 新增品类只需在注册表中添加一项,并确保 `PROMPT_TEMPLATES` 中存在对应的 prompt_key,无需修改控制流逻辑。 - **按 profile 分组批处理**: - 原有实现:所有产品混在一起,使用同一套服饰 prompt,导致非服饰产品被错误填充。 - 重构后:`_enrich_taxonomy_batch` 先根据每个产品的 profile 分组,每组独立构造 LLM 请求,响应结果再按原始顺序合并。分组粒度可配置,避免小分组带来的过多请求开销。 - **自动品类推断**: - 对于内部索引(非显式调用 enrichment 接口的场景),通过 `_infer_profile_from_category` 解析 SPU 的 `category_l1/l2/l3` 字段,映射到最匹配的 profile。映射规则基于关键词匹配(如“手机”->“3c”,“狗粮”->“pet_supplies”),未匹配时 fallback 到 `apparel` 以保证系统平稳过渡。 - **输出字段裁剪**: - 由于 Elasticsearch mapping 中 `enriched_taxonomy_attributes.value` 字段仅存储单个值(不分语言),非服饰品类的 LLM 输出直接写入该字段;服饰品类则使用动态模板 `value.zh` 和 `value.en`。代码中通过 `_apply_lang_output` 函数统一处理。 - **代码量与可维护性**: - 虽然因新增大量品类定义导致总行数略有增长(~+180 行),但条件分支数量从 5 处减少到 1 处(仅 profile 查找)。新增品类的平均成本仅为注册表 3 行 + prompt 模板 10 行,无需改动核心 enrichment 循环。 【影响文件】 - `indexer/product_enrich.py` - `indexer/product_enrich_prompts.py` - `indexer/document_transformer.py` - `indexer/indexer.py` - `docs/搜索API对接指南-05-索引接口(Indexer).md` - `docs/搜索API对接指南-07-微服务接口(Embedding-Reranker-Translation).md` - `taxonomy.md` - `tests/test_product_enrich_partial_mode.py`(适配多 profile 测试用例) - `tests/test_llm_enrichment_batch_fill.py` - `tests/test_process_products_batching.py` 【测试验证】 - 执行单元测试与集成测试:`pytest tests/test_product_enrich_partial_mode.py tests/test_llm_enrichment_batch_fill.py tests/test_process_products_batching.py tests/ci/test_service_api_contracts.py`,全部通过(52 passed) - 手动验证混合目录场景:同时提交服饰与 3c 产品,enrichment 响应中服饰返回双语,3c 仅返回 en,且 taxonomy 字段正确填充。 - 编译检查:`py_compile` 所有修改模块无语法错误。 【注意事项】 - 本次重构未改变现有服饰品类的行为,API 向后兼容(未指定 profile 时仍按服饰处理)。 - 若后续需为某品类增加双语支持,只需修改注册表中的 `lang` 列表并补充 prompt 模板,无需改动其他逻辑。 -
category_taxonomy_profile - 原 analysis_kinds 混用了“增强类型”(content/taxonomy)与“品类特定配置”,不利于扩展不同品类的 taxonomy 分析(如 3C、家居等) - 新增 enrichment_scopes 参数:支持 generic(通用增强,产出 qanchors/enriched_tags/enriched_attributes)和 category_taxonomy(品类增强,产出 enriched_taxonomy_attributes) - 新增 category_taxonomy_profile 参数:指定品类增强使用哪套 profile(当前内置 apparel),每套 profile 包含独立的 prompt、输出列定义、解析规则及缓存版本 - 保留 analysis_kinds 作为兼容别名,避免破坏现有调用方 - 重构内部 taxonomy 分析为 profile registry 模式:新增 _get_taxonomy_schema(profile_name) 函数,根据 profile 动态返回对应的 AnalysisSchema - 缓存 key 现在按“分析类型 + profile + schema 指纹 + 输入字段哈希”隔离,确保不同品类、不同 prompt 版本自动失效 - 更新 API 文档及微服务接口文档,明确新参数语义与使用示例 技术细节: - 修改入口:api/routes/indexer.py 中 enrich-content 端点,解析新参数并向下传递 - 核心逻辑:indexer/product_enrich.py 中 enrich_products_batch 增加 profile 参数;_process_batch_for_schema 根据 scope 和 profile 动态获取 schema - 兼容层:若请求同时提供 analysis_kinds,则映射为 enrichment_scopes(content→generic,taxonomy→category_taxonomy),category_taxonomy_profile 默认为 "apparel" - 测试覆盖:新增 enrichment_scopes 组合、profile 切换及兼容模式测试
-
- `/indexer/enrich-content` 路由`enriched_taxonomy_attributes` 与 `enriched_attributes` 一并返回 - 新增请求参数 `analysis_kinds`(可选,默认 `["content", "taxonomy"]`),允许调用方按需选择内容分析类型,为后续扩展和成本控制预留空间 - 重构缓存策略:将 `content` 与 `taxonomy` 两类分析的缓存完全隔离,缓存 key 包含 prompt 模板、表头、输出字段定义(即 schema 指纹),确保提示词或解析规则变更时自动失效 - 缓存 key 仅依赖真正参与 LLM 输入的字段(`title`、`brief`、`description`),`image_url`、`tenant_id`、`spu_id` 不再污染缓存键,提高缓存命中率 - 更新 API 文档(`docs/搜索API对接指南-05-索引接口(Indexer).md`),说明新增参数与返回字段 技术细节: - 路由层调整:在 `api/routes/indexer.py` 的 enrich-content 端点中,将 `product_enrich.enrich_products_batch` 返回的 `enriched_taxonomy_attributes` 字段显式加入 HTTP 响应体 - `analysis_kinds` 参数透传至底层 `enrich_products_batch`,支持按需跳过某一类分析(如仅需 taxonomy 时减少 LLM 调用) - 缓存指纹计算位于 `product_enrich.py` 的 `_get_cache_key` 函数,对每种 `AnalysisSchema` 独立生成;版本号通过 `schema.version` 或 prompt 内容哈希隐式包含 - 测试覆盖:新增 `analysis_kinds` 组合场景及缓存隔离测试
30 Mar, 2026
1 commit
27 Mar, 2026
2 commits
26 Mar, 2026
1 commit
21 Mar, 2026
1 commit
20 Mar, 2026
3 commits