""" Condition 2: Expert-Only (No Attributes) Uses expert perspectives to generate ideas, but without attribute decomposition. Each expert generates ideas directly for the query from their professional perspective. """ import sys from pathlib import Path # Add backend to path for imports sys.path.insert(0, str(Path(__file__).parent.parent.parent / "backend")) from typing import List, Dict, Any from app.services.llm_service import ollama_provider, extract_json_from_response from app.services.expert_source_service import expert_source_service from experiments.config import ( MODEL, TEMPERATURE, EXPERT_COUNT, EXPERT_SOURCE, IDEAS_PER_EXPERT, PROMPT_LANGUAGE ) def get_expert_idea_generation_prompt( query: str, expert_name: str, expert_domain: str, idea_count: int, lang: str = "en" ) -> str: """Generate prompt for expert-based idea generation.""" if lang == "en": domain_text = f" ({expert_domain} field)" if expert_domain else "" return f"""/no_think You are a {expert_name}{domain_text}. Task: Generate {idea_count} creative and innovative ideas for "{query}" from your professional perspective. Requirements: 1. Each idea should reflect your professional expertise and unique viewpoint 2. Think about how concepts from your field could improve or reimagine "{query}" 3. Ideas should be specific and actionable (15-30 words each) 4. Combine your professional knowledge with creative thinking Return JSON only: {{"ideas": ["idea 1", "idea 2", "idea 3", ...]}} Generate exactly {idea_count} ideas from your perspective as a {expert_name}.""" else: domain_text = f"({expert_domain}領域)" if expert_domain else "" return f"""/no_think 你是一位{expert_name}{domain_text}。 任務:從你的專業角度,為「{query}」生成 {idea_count} 個創意點子。 要求: 1. 每個點子要反映你的專業知識和獨特觀點 2. 思考你領域的概念如何改進或重新想像「{query}」 3. 點子要具體可行(每個 15-30 字) 4. 結合專業知識和創意思維 只回傳 JSON: {{"ideas": ["點子1", "點子2", "點子3", ...]}} 從你作為{expert_name}的角度生成正好 {idea_count} 個點子。""" async def generate_ideas( query: str, model: str = None, temperature: float = None, expert_count: int = None, expert_source: str = None, ideas_per_expert: int = None, lang: str = None ) -> Dict[str, Any]: """ Generate ideas using expert perspectives only (C2). Args: query: The object/concept to generate ideas for model: LLM model to use temperature: Generation temperature expert_count: Number of experts to use expert_source: Source of experts (curated, dbpedia, etc.) ideas_per_expert: Ideas each expert generates lang: Language for prompts Returns: Dict with ideas and metadata """ model = model or MODEL temperature = temperature or TEMPERATURE expert_count = expert_count or EXPERT_COUNT expert_source = expert_source or EXPERT_SOURCE ideas_per_expert = ideas_per_expert or IDEAS_PER_EXPERT lang = lang or PROMPT_LANGUAGE # Get experts from curated source experts, actual_source = expert_source_service.get_experts( source=expert_source, count=expert_count, language=lang ) all_ideas = [] expert_details = [] for expert in experts: expert_name = expert.get("name", "Expert") expert_domain = expert.get("domain", "") prompt = get_expert_idea_generation_prompt( query=query, expert_name=expert_name, expert_domain=expert_domain, idea_count=ideas_per_expert, lang=lang ) response = await ollama_provider.generate( prompt=prompt, model=model, temperature=temperature ) result = extract_json_from_response(response) ideas = result.get("ideas", []) # Tag ideas with expert source for idea in ideas: all_ideas.append({ "idea": idea, "expert_name": expert_name, "expert_domain": expert_domain }) expert_details.append({ "name": expert_name, "domain": expert_domain, "ideas_generated": len(ideas) }) return { "condition": "c2_expert_only", "query": query, "ideas": [item["idea"] for item in all_ideas], "ideas_with_source": all_ideas, "idea_count": len(all_ideas), "metadata": { "model": model, "temperature": temperature, "prompt_language": lang, "expert_count": expert_count, "expert_source": actual_source, "ideas_per_expert": ideas_per_expert, "experts": expert_details, "mechanism": "expert_perspectives_only" } } # For testing if __name__ == "__main__": import asyncio async def test(): result = await generate_ideas("Chair") print(f"Generated {result['idea_count']} ideas from {len(result['metadata']['experts'])} experts:") for exp in result['metadata']['experts']: print(f" - {exp['name']}: {exp['ideas_generated']} ideas") print("\nSample ideas:") for i, item in enumerate(result['ideas_with_source'][:5], 1): print(f" {i}. [{item['expert_name']}] {item['idea']}") asyncio.run(test())