feat: Migrate to React Flow and add Fixed + Dynamic category mode
Frontend: - Migrate MindmapDAG from D3.js to React Flow (@xyflow/react) - Add custom node components (QueryNode, CategoryHeaderNode, AttributeNode) - Add useDAGLayout hook for column-based layout - Add "AI" badge for LLM-suggested categories - Update CategorySelector with Fixed + Dynamic mode option - Improve dark/light theme support Backend: - Add FIXED_PLUS_DYNAMIC category mode - Filter duplicate category names in LLM suggestions - Update prompts to exclude fixed categories when suggesting new ones - Improve LLM service with better error handling and logging - Auto-remove /no_think prefix for non-Qwen models - Add smart JSON format detection for model compatibility - Improve JSON extraction with multiple parsing strategies 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -120,17 +120,26 @@ def get_flat_attribute_prompt(query: str, categories: Optional[List[str]] = None
|
||||
|
||||
# ===== Dynamic category system prompts =====
|
||||
|
||||
def get_step0_category_analysis_prompt(query: str, suggested_count: int = 3) -> str:
|
||||
def get_step0_category_analysis_prompt(
|
||||
query: str,
|
||||
suggested_count: int = 3,
|
||||
exclude_categories: List[str] | None = None
|
||||
) -> str:
|
||||
"""Step 0: LLM 分析建議類別"""
|
||||
exclude_text = ""
|
||||
if exclude_categories:
|
||||
exclude_text = f"\n【禁止使用的類別】{', '.join(exclude_categories)}(這些已經是固定類別,不要重複建議)\n"
|
||||
|
||||
return f"""/no_think
|
||||
分析「{query}」,建議 {suggested_count} 個最適合的屬性類別來描述它。
|
||||
|
||||
【常見類別參考】材料、功能、用途、使用族群、特性、形狀、顏色、尺寸、品牌、價格區間
|
||||
|
||||
【常見類別參考】特性、形狀、顏色、尺寸、品牌、價格區間、重量、風格、場合、季節、技術規格
|
||||
{exclude_text}
|
||||
【重要】
|
||||
1. 選擇最能描述此物件本質的類別
|
||||
2. 類別之間應該有邏輯關係(如:材料→功能→用途)
|
||||
2. 類別之間應該有邏輯關係
|
||||
3. 不要選擇過於抽象或重複的類別
|
||||
4. 必須建議與參考列表不同的、有創意的類別
|
||||
|
||||
只回傳 JSON:
|
||||
{{
|
||||
@@ -213,3 +222,47 @@ def get_step2_dynamic_causal_chain_prompt(
|
||||
|
||||
只回傳 JSON:
|
||||
{json.dumps(json_template, ensure_ascii=False, indent=2)}"""
|
||||
|
||||
|
||||
# ===== DAG relationship prompt =====
|
||||
|
||||
def get_step2_dag_relationships_prompt(
|
||||
query: str,
|
||||
categories: List, # List[CategoryDefinition]
|
||||
attributes_by_category: Dict[str, List[str]],
|
||||
) -> str:
|
||||
"""生成相鄰類別之間的自然關係"""
|
||||
sorted_cats = sorted(categories, key=lambda x: x.order if hasattr(x, 'order') else x.get('order', 0))
|
||||
|
||||
# Build attribute listing
|
||||
attr_listing = "\n".join([
|
||||
f"【{cat.name if hasattr(cat, 'name') else cat['name']}】{', '.join(attributes_by_category.get(cat.name if hasattr(cat, 'name') else cat['name'], []))}"
|
||||
for cat in sorted_cats
|
||||
])
|
||||
|
||||
# Build direction hints
|
||||
direction_hints = " → ".join([cat.name if hasattr(cat, 'name') else cat['name'] for cat in sorted_cats])
|
||||
|
||||
return f"""/no_think
|
||||
分析「{query}」的屬性關係。
|
||||
|
||||
{attr_listing}
|
||||
|
||||
【關係方向】{direction_hints}
|
||||
|
||||
【規則】
|
||||
1. 只建立相鄰類別之間的關係(例如:材料→功能,功能→用途)
|
||||
2. 只輸出真正有因果或關聯關係的配對
|
||||
3. 一個屬性可連接多個下游屬性,也可以不連接任何屬性
|
||||
4. 不需要每個屬性都有連接
|
||||
5. 關係應該合理且有意義
|
||||
|
||||
回傳 JSON:
|
||||
{{
|
||||
"relationships": [
|
||||
{{"source_category": "類別A", "source": "屬性名", "target_category": "類別B", "target": "屬性名"}},
|
||||
...
|
||||
]
|
||||
}}
|
||||
|
||||
只回傳 JSON。"""
|
||||
|
||||
Reference in New Issue
Block a user