Files
aiagent/backend/app/services/scene_templates.py
renjianbo 0608161c82 feat: 完善企业场景多线路由与执行稳定性
补齐平台模板与场景 DSL、预算控制、执行看板和企业场景脚本,增强 Windows 启动/迁移与前端代理和聊天会话记忆,修复执行创建阶段 500 与异步链路排障体验。

Made-with: Cursor
2026-04-09 21:58:53 +08:00

172 lines
5.8 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""
场景模板注册:路线图「客服 / 研发 / 运维」三类最小可运行工作流,供 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_confignodes+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