""" 场景模板注册:路线图「客服 / 研发 / 运维」三类最小可运行工作流,供 API 与脚本一键创建 Agent。 """ from __future__ import annotations from typing import Any, Callable, Dict, List, Optional PromptBuilder = Callable[[Dict[str, Any]], str] def _default_prompt_cs(params: Dict[str, Any]) -> str: extra = (params.get("extra_instructions") or "").strip() base = """你是企业客服场景 Agent。根据用户问题给出清晰、可执行的回答;不确定时先澄清。 用户输入可能包含:{{input}} 或来自前序节点的合并字段。保持礼貌、简洁。""" if extra: return f"{base}\n\n【额外说明】\n{extra}" return base def _default_prompt_dev(params: Dict[str, Any]) -> str: extra = (params.get("extra_instructions") or "").strip() lang = params.get("preferred_language") or "任意合适语言" base = f"""你是研发辅助 Agent,负责代码与设计说明。优先给出可运行示例与步骤;涉及安全/生产变更时明确风险。 偏好语言/栈:{lang}。 用户诉求:{{input}}""" if extra: return f"{base}\n\n【额外说明】\n{extra}" return base def _default_prompt_ops(params: Dict[str, Any]) -> str: extra = (params.get("extra_instructions") or "").strip() base = """你是运维/日志分析场景 Agent。帮助用户解读日志片段、定位可能原因与下一步排查;不要编造未提供的日志内容。 用户输入:{{input}}""" if extra: return f"{base}\n\n【额外说明】\n{extra}" return base def _build_minimal_workflow( prompt: str, *, temperature: float = 0.3, enable_tools: bool = False, tools: Optional[List[str]] = None, ) -> Dict[str, Any]: tools = tools or [] return { "nodes": [ { "id": "start-1", "type": "start", "position": {"x": 80, "y": 120}, "data": {}, }, { "id": "llm-1", "type": "llm", "position": {"x": 320, "y": 120}, "data": { "prompt": prompt, "temperature": float(temperature), "enable_tools": enable_tools, "tools": tools, "selected_tools": tools, }, }, { "id": "end-1", "type": "end", "position": {"x": 560, "y": 120}, "data": {}, }, ], "edges": [ { "id": "e_start_llm", "source": "start-1", "target": "llm-1", "sourceHandle": "right", "targetHandle": "left", }, { "id": "e_llm_end", "source": "llm-1", "target": "end-1", "sourceHandle": "right", "targetHandle": "left", }, ], } def build_workflow_for_template(template_id: str, parameters: Optional[Dict[str, Any]] = None) -> Dict[str, Any]: """ 根据模板 ID 与参数生成 workflow_config(nodes+edges)。 通用参数:temperature, enable_tools, tools(list[str]), extra_instructions, preferred_language(dev) """ parameters = dict(parameters or {}) meta = SCENE_TEMPLATE_REGISTRY.get(template_id) if not meta: raise ValueError(f"未知模板: {template_id}") temperature = float(parameters.get("temperature", meta.get("default_temperature", 0.3))) enable_tools = bool(parameters.get("enable_tools", False)) tools = parameters.get("tools") if tools is not None and not isinstance(tools, list): tools = [] elif tools is None: tools = list(meta.get("default_tools") or []) prompt_fn: PromptBuilder = meta["prompt_builder"] prompt = prompt_fn(parameters) return _build_minimal_workflow( prompt, temperature=temperature, enable_tools=enable_tools, tools=tools if enable_tools else [], ) SCENE_TEMPLATE_REGISTRY: Dict[str, Dict[str, Any]] = { "template_customer_service": { "title": "客服场景", "description": "通用客服问答与澄清(最小 LLM 链)。", "category": "customer_service", "default_temperature": 0.35, "default_tools": [], "prompt_builder": _default_prompt_cs, }, "template_dev_codegen": { "title": "研发 / 代码助手", "description": "代码与设计说明辅助(最小 LLM 链)。", "category": "dev", "default_temperature": 0.25, "default_tools": [], "prompt_builder": _default_prompt_dev, }, "template_ops_log_analysis": { "title": "运维 / 日志分析", "description": "日志解读与排查建议(最小 LLM 链)。", "category": "ops", "default_temperature": 0.3, "default_tools": [], "prompt_builder": _default_prompt_ops, }, } def list_scene_template_meta() -> List[Dict[str, Any]]: """供 GET 接口返回(不含 prompt_builder)。""" out: List[Dict[str, Any]] = [] for tid, meta in SCENE_TEMPLATE_REGISTRY.items(): out.append( { "id": tid, "title": meta["title"], "description": meta["description"], "category": meta.get("category"), "default_temperature": meta.get("default_temperature"), "parameter_hints": [ "temperature", "enable_tools", "tools", "extra_instructions", "preferred_language(仅研发模板)", ], } ) return out