feat: Add Expert Transformation Agent with multi-expert perspective system
- Backend: Add expert transformation router with 3-step SSE pipeline - Step 0: Generate diverse expert team (random domains) - Step 1: Each expert generates keywords for attributes - Step 2: Batch generate descriptions for expert keywords - Backend: Add simplified prompts for reliable JSON output - Frontend: Add TransformationPanel with React Flow visualization - Frontend: Add TransformationInputPanel for expert configuration - Expert count (2-8), keywords per expert (1-3) - Custom expert domains support - Frontend: Add expert keyword nodes with expert badges - Frontend: Improve description card layout (wider cards, more spacing) - Frontend: Add fallback for missing descriptions with visual indicators 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
78
backend/app/prompts/expert_transformation_prompt.py
Normal file
78
backend/app/prompts/expert_transformation_prompt.py
Normal file
@@ -0,0 +1,78 @@
|
||||
"""Expert Transformation Agent 提示詞模組"""
|
||||
|
||||
from typing import List, Optional
|
||||
|
||||
|
||||
def get_expert_generation_prompt(
|
||||
query: str,
|
||||
categories: List[str],
|
||||
expert_count: int,
|
||||
custom_experts: Optional[List[str]] = None
|
||||
) -> str:
|
||||
"""Step 0: 生成專家團隊(不依賴主題,純隨機多元)"""
|
||||
custom_text = ""
|
||||
if custom_experts and len(custom_experts) > 0:
|
||||
custom_text = f"(已指定:{', '.join(custom_experts[:expert_count])})"
|
||||
|
||||
return f"""/no_think
|
||||
隨機組建 {expert_count} 個來自完全不同領域的專家團隊{custom_text}。
|
||||
|
||||
回傳 JSON:
|
||||
{{"experts": [{{"id": "expert-0", "name": "職業", "domain": "領域", "perspective": "角度"}}, ...]}}
|
||||
|
||||
規則:
|
||||
- id 為 expert-0 到 expert-{expert_count - 1}
|
||||
- name 填寫職業名稱(非人名),2-5字
|
||||
- 各專家的 domain 必須來自截然不同的領域,越多元越好"""
|
||||
|
||||
|
||||
def get_expert_keyword_generation_prompt(
|
||||
category: str,
|
||||
attribute: str,
|
||||
experts: List[dict], # List[ExpertProfile]
|
||||
keywords_per_expert: int = 1
|
||||
) -> str:
|
||||
"""Step 1: 專家視角關鍵字生成"""
|
||||
experts_info = ", ".join([f"{exp['id']}:{exp['name']}({exp['domain']})" for exp in experts])
|
||||
|
||||
return f"""/no_think
|
||||
專家團隊:{experts_info}
|
||||
屬性:「{attribute}」({category})
|
||||
|
||||
每位專家從自己的專業視角為此屬性生成 {keywords_per_expert} 個創新關鍵字(2-6字)。
|
||||
關鍵字要反映該專家領域的獨特思考方式。
|
||||
|
||||
回傳 JSON:
|
||||
{{"keywords": [{{"keyword": "詞彙", "expert_id": "expert-X", "expert_name": "名稱"}}, ...]}}
|
||||
|
||||
共需 {len(experts) * keywords_per_expert} 個關鍵字。"""
|
||||
|
||||
|
||||
def get_expert_batch_description_prompt(
|
||||
query: str,
|
||||
category: str,
|
||||
expert_keywords: List[dict] # List[ExpertKeyword]
|
||||
) -> str:
|
||||
"""Step 2: 批次生成專家關鍵字的描述"""
|
||||
keywords_info = ", ".join([
|
||||
f"{kw['expert_name']}:{kw['keyword']}"
|
||||
for kw in expert_keywords
|
||||
])
|
||||
|
||||
# 建立 keyword -> (expert_id, expert_name) 的對照
|
||||
keyword_expert_map = ", ".join([
|
||||
f"{kw['keyword']}→{kw['expert_id']}/{kw['expert_name']}"
|
||||
for kw in expert_keywords
|
||||
])
|
||||
|
||||
return f"""/no_think
|
||||
物件:「{query}」
|
||||
關鍵字(專家:詞彙):{keywords_info}
|
||||
對照:{keyword_expert_map}
|
||||
|
||||
為每個關鍵字生成創新描述(15-30字),說明如何將該概念應用到「{query}」上。
|
||||
|
||||
回傳 JSON:
|
||||
{{"descriptions": [{{"keyword": "詞彙", "expert_id": "expert-X", "expert_name": "名稱", "description": "應用描述"}}, ...]}}
|
||||
|
||||
共需 {len(expert_keywords)} 個描述。"""
|
||||
97
backend/app/prompts/transformation_prompt.py
Normal file
97
backend/app/prompts/transformation_prompt.py
Normal file
@@ -0,0 +1,97 @@
|
||||
"""Transformation Agent 提示詞模組"""
|
||||
|
||||
from typing import List
|
||||
|
||||
|
||||
def get_keyword_generation_prompt(
|
||||
category: str,
|
||||
attributes: List[str],
|
||||
keyword_count: int = 3
|
||||
) -> str:
|
||||
"""
|
||||
Step 1: 生成新關鍵字
|
||||
|
||||
給定類別和現有屬性,生成全新的、有創意的關鍵字。
|
||||
不考慮原始查詢,只專注於類別本身可能的延伸。
|
||||
"""
|
||||
attrs_text = "、".join(attributes)
|
||||
|
||||
return f"""/no_think
|
||||
你是一個創意發想專家。給定一個類別和該類別下的現有屬性,請生成全新的、有創意的關鍵字或描述片段。
|
||||
|
||||
【類別】{category}
|
||||
【現有屬性】{attrs_text}
|
||||
|
||||
【重要規則】
|
||||
1. 生成 {keyword_count} 個全新的關鍵字
|
||||
2. 關鍵字必須符合「{category}」這個類別的範疇
|
||||
3. 關鍵字要有創意,不能與現有屬性重複或太相似
|
||||
4. 不要考慮任何特定物件,只專注於這個類別本身可能的延伸
|
||||
5. 每個關鍵字應該是 2-6 個字的詞彙或短語
|
||||
|
||||
只回傳 JSON:
|
||||
{{
|
||||
"keywords": ["關鍵字1", "關鍵字2", "關鍵字3"]
|
||||
}}"""
|
||||
|
||||
|
||||
def get_description_generation_prompt(
|
||||
query: str,
|
||||
category: str,
|
||||
keyword: str
|
||||
) -> str:
|
||||
"""
|
||||
Step 2: 結合原始查詢生成描述
|
||||
|
||||
用新關鍵字創造一個與原始查詢相關的創新應用描述。
|
||||
"""
|
||||
return f"""/no_think
|
||||
你是一個創新應用專家。請將一個新的關鍵字概念應用到特定物件上,創造出創新的應用描述。
|
||||
|
||||
【物件】{query}
|
||||
【類別】{category}
|
||||
【新關鍵字】{keyword}
|
||||
|
||||
【任務】
|
||||
請用「{keyword}」這個概念,為「{query}」創造一個創新的應用描述。
|
||||
描述應該是一個完整的句子或短語,說明如何將這個新概念應用到物件上。
|
||||
|
||||
【範例格式】
|
||||
- 如果物件是「腳踏車」,關鍵字是「監視」,可以生成「腳踏車監視騎乘者的身體健康狀況」
|
||||
- 如果物件是「雨傘」,關鍵字是「發電」,可以生成「雨傘利用雨滴撞擊發電」
|
||||
|
||||
只回傳 JSON:
|
||||
{{
|
||||
"description": "創新應用描述"
|
||||
}}"""
|
||||
|
||||
|
||||
def get_batch_description_prompt(
|
||||
query: str,
|
||||
category: str,
|
||||
keywords: List[str]
|
||||
) -> str:
|
||||
"""
|
||||
批次生成描述(可選的優化版本,一次處理多個關鍵字)
|
||||
"""
|
||||
keywords_text = "、".join(keywords)
|
||||
keywords_json = ", ".join([f'"{k}"' for k in keywords])
|
||||
|
||||
return f"""/no_think
|
||||
你是一個創新應用專家。請將多個新的關鍵字概念應用到特定物件上,為每個關鍵字創造創新的應用描述。
|
||||
|
||||
【物件】{query}
|
||||
【類別】{category}
|
||||
【新關鍵字】{keywords_text}
|
||||
|
||||
【任務】
|
||||
為每個關鍵字創造一個與「{query}」相關的創新應用描述。
|
||||
每個描述應該是一個完整的句子或短語。
|
||||
|
||||
只回傳 JSON:
|
||||
{{
|
||||
"descriptions": [
|
||||
{{"keyword": "關鍵字1", "description": "描述1"}},
|
||||
{{"keyword": "關鍵字2", "description": "描述2"}}
|
||||
]
|
||||
}}"""
|
||||
Reference in New Issue
Block a user