- Add 灵犀学习助手 Feishu bot (lingxi_app_service + lingxi_ws_handler) - Fix agent_schedule_service missing AgentSchedule import (Celery Beat) - Fix scene_templates default enable_tools=False → True - Fix workflow_engine LLM node: empty tools list now = all tools (consistent with agent node) - Add 创建agent.md guide document Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
172 lines
5.7 KiB
Python
172 lines
5.7 KiB
Python
"""
|
||
场景模板注册:路线图「客服 / 研发 / 运维」三类最小可运行工作流,供 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", True))
|
||
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,
|
||
)
|
||
|
||
|
||
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
|