Commit e39abf7360d3fe2711b0757e54dfa3a7382a3a2a

Authored by tangwang
1 parent 702ba3aa

enrich

app/agents/shopping_agent.py
@@ -59,7 +59,9 @@ SYSTEM_PROMPT = f""" 角色定义 @@ -59,7 +59,9 @@ SYSTEM_PROMPT = f""" 角色定义
59 3. 在最终回复中使用 [SEARCH_RESULTS_REF:ref_id] 内联引用搜索结果: 59 3. 在最终回复中使用 [SEARCH_RESULTS_REF:ref_id] 内联引用搜索结果:
60 1. 搜索工具会返回一个结果引用标识[SEARCH_RESULTS_REF:ref_id],撰写最终答复的时候请直接引用 [SEARCH_RESULTS_REF:ref_id] ,系统会自动在该位置渲染对应的商品卡片列表,无需复述搜索结果。 60 1. 搜索工具会返回一个结果引用标识[SEARCH_RESULTS_REF:ref_id],撰写最终答复的时候请直接引用 [SEARCH_RESULTS_REF:ref_id] ,系统会自动在该位置渲染对应的商品卡片列表,无需复述搜索结果。
61 2. 因为系统会自动将[SEARCH_RESULTS_REF:ref_id]渲染为搜索结果,所以[SEARCH_RESULTS_REF:ref_id]必须独占一行,且只在需要渲染该query完整的搜索结果时才进行引用,同一个结果不要重复引用。 61 2. 因为系统会自动将[SEARCH_RESULTS_REF:ref_id]渲染为搜索结果,所以[SEARCH_RESULTS_REF:ref_id]必须独占一行,且只在需要渲染该query完整的搜索结果时才进行引用,同一个结果不要重复引用。
62 -4. 今天是{datetime.now().strftime("%Y-%m-%d")},所有与当前时间(比如天气、最新或即将发生的事件)相关的问题,都要使用web_search工具)。 62 +4. 所有与当前时间(比如天气、最新或即将发生的事件)相关的问题,都要使用web_search工具)。
  63 +
  64 +当前日期: {datetime.now().strftime("%Y-%m-%d")} 星期{datetime.now().strftime("%w")}
63 """ 65 """
64 66
65 67
offline/product_understanding/graphRAG.md
@@ -137,7 +137,7 @@ graphRAG在商品搜索中如何使用?我想将他用于,对商品的模糊 @@ -137,7 +137,7 @@ graphRAG在商品搜索中如何使用?我想将他用于,对商品的模糊
137 137
138 材质层: 138 材质层:
139 - material 139 - material
140 -- fabric_texture (棉麻感 / 轻薄 / 垂坠) 140 +- fabric_texture
141 141
142 视觉层: 142 视觉层:
143 - main_color 143 - main_color
offline/product_understanding/process_products.py
@@ -65,6 +65,7 @@ def create_prompt(products: List[Dict[str, str]]) -> str: @@ -65,6 +65,7 @@ def create_prompt(products: List[Dict[str, str]]) -> str:
65 8. 材质说明 65 8. 材质说明
66 9. 功能特点 66 9. 功能特点
67 10. 商品卖点:分析和提取一句话核心卖点,用于推荐理由 67 10. 商品卖点:分析和提取一句话核心卖点,用于推荐理由
  68 +11. 锚文本:生成一组能够代表该商品、并可能被用户用于搜索的词语或短语。这些词语应覆盖用户需求的各个维度,如品类、细分标签、功能特性、需求场景等等。
68 69
69 输入商品列表: 70 输入商品列表:
70 71
@@ -73,8 +74,8 @@ def create_prompt(products: List[Dict[str, str]]) -> str: @@ -73,8 +74,8 @@ def create_prompt(products: List[Dict[str, str]]) -> str:
73 prompt_tail = """ 74 prompt_tail = """
74 请严格按照以下markdown表格格式返回,每列内部的多值内容都用逗号分隔,不要添加任何其他说明: 75 请严格按照以下markdown表格格式返回,每列内部的多值内容都用逗号分隔,不要添加任何其他说明:
75 76
76 -| 序号 | 商品中文标题 | 品类路径 | 细分标签 | 适用人群 | 使用场景 | 适用季节 | 关键属性 | 材质说明 | 功能特点 | 商品卖点 |  
77 -|----|----|----|----|----|----|----|----|----|----|----| 77 +| 序号 | 商品中文标题 | 品类路径 | 细分标签 | 适用人群 | 使用场景 | 适用季节 | 关键属性 | 材质说明 | 功能特点 | 商品卖点 | 锚文本 |
  78 +|----|----|----|----|----|----|----|----|----|----|----|----|
78 """ 79 """
79 80
80 for idx, product in enumerate(products, 1): 81 for idx, product in enumerate(products, 1):
@@ -213,7 +214,8 @@ def parse_markdown_table(markdown_content: str) -> List[Dict[str, str]]: @@ -213,7 +214,8 @@ def parse_markdown_table(markdown_content: str) -> List[Dict[str, str]]:
213 "key_attributes": parts[7] if len(parts) > 7 else "", # 关键属性 214 "key_attributes": parts[7] if len(parts) > 7 else "", # 关键属性
214 "material": parts[8] if len(parts) > 8 else "", # 材质说明 215 "material": parts[8] if len(parts) > 8 else "", # 材质说明
215 "features": parts[9] if len(parts) > 9 else "", # 功能特点 216 "features": parts[9] if len(parts) > 9 else "", # 功能特点
216 - "selling_points": parts[10] if len(parts) > 10 else "" # 商品卖点 217 + "selling_points": parts[10] if len(parts) > 10 else "", # 商品卖点
  218 + "anchor_text": parts[11] if len(parts) > 11 else "" # 锚文本
217 } 219 }
218 data.append(row) 220 data.append(row)
219 221
@@ -255,7 +257,8 @@ def process_batch(batch_data: List[Dict[str, str]], batch_num: int) -> List[Dict @@ -255,7 +257,8 @@ def process_batch(batch_data: List[Dict[str, str]], batch_num: int) -> List[Dict
255 "key_attributes": parsed_item.get("key_attributes", ""), # 关键属性 257 "key_attributes": parsed_item.get("key_attributes", ""), # 关键属性
256 "material": parsed_item.get("material", ""), # 材质说明 258 "material": parsed_item.get("material", ""), # 材质说明
257 "features": parsed_item.get("features", ""), # 功能特点 259 "features": parsed_item.get("features", ""), # 功能特点
258 - "selling_points": parsed_item.get("selling_points", "") # 商品卖点 260 + "selling_points": parsed_item.get("selling_points", ""), # 商品卖点
  261 + "anchor_text": parsed_item.get("anchor_text", "") # 锚文本
259 } 262 }
260 results_with_ids.append(result) 263 results_with_ids.append(result)
261 logger.info(f"Mapped: seq={parsed_item['seq_no']} -> original_id={original_id}") 264 logger.info(f"Mapped: seq={parsed_item['seq_no']} -> original_id={original_id}")
@@ -285,7 +288,7 @@ def process_batch(batch_data: List[Dict[str, str]], batch_num: int) -> List[Dict @@ -285,7 +288,7 @@ def process_batch(batch_data: List[Dict[str, str]], batch_num: int) -> List[Dict
285 return [{"id": item["id"], "title": item["title"], 288 return [{"id": item["id"], "title": item["title"],
286 "title_cn": "", "category_path": "", "tags": "", "target_audience": "", 289 "title_cn": "", "category_path": "", "tags": "", "target_audience": "",
287 "usage_scene": "", "season": "", "key_attributes": "", 290 "usage_scene": "", "season": "", "key_attributes": "",
288 - "material": "", "features": "", "selling_points": "", 291 + "material": "", "features": "", "selling_points": "", "anchor_text": "",
289 "error": str(e)} for item in batch_data] 292 "error": str(e)} for item in batch_data]
290 293
291 294
@@ -308,7 +311,7 @@ def write_results(results: List[Dict[str, str]], output_file: Path): @@ -308,7 +311,7 @@ def write_results(results: List[Dict[str, str]], output_file: Path):
308 311
309 fieldnames = ["id", "title", "title_cn", "category_path", "tags", 312 fieldnames = ["id", "title", "title_cn", "category_path", "tags",
310 "target_audience", "usage_scene", "season", 313 "target_audience", "usage_scene", "season",
311 - "key_attributes", "material", "features", "selling_points"] 314 + "key_attributes", "material", "features", "selling_points", "anchor_text"]
312 315
313 with open(output_file, 'w', encoding='utf-8', newline='') as f: 316 with open(output_file, 'w', encoding='utf-8', newline='') as f:
314 writer = csv.DictWriter(f, fieldnames=fieldnames) 317 writer = csv.DictWriter(f, fieldnames=fieldnames)