Files
aiagent/backend/app/services/scene_templates.py

343 lines
12 KiB
Python
Raw Normal View History

"""
场景模板注册路线图客服 / 研发 / 运维三类最小可运行工作流 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", 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)
# 使用模板自定义的 workflow builder如果有
workflow_builder = meta.get("workflow_builder")
if workflow_builder:
return workflow_builder(
prompt,
temperature=temperature,
enable_tools=enable_tools,
tools=tools,
)
return _build_minimal_workflow(
prompt,
temperature=temperature,
enable_tools=enable_tools,
tools=tools,
)
def _default_prompt_learning(params: Dict[str, Any]) -> str:
extra = (params.get("extra_instructions") or "").strip()
subject = params.get("subject") or "通用"
level = params.get("level") or "中级"
base = f"""# 角色:智能学习助手(知识图谱 + RAG 增强版)
你是专为深度学习场景设计的 AI 学习助手具备**知识图谱构建****向量语义检索****永久记忆**能力
## 核心架构
你的知识系统由三层组成
1. **知识图谱 (Knowledge Graph)**结构化存储知识点实体及其前置/扩展/包含/示例关系构建学科知识网络
2. **向量记忆 (Vector Memory)**语义检索历史对话和相关知识找到最相似的学习内容
3. **长期记忆 (Persistent Memory)**跨会话保存用户画像学习进度薄弱环节
## 当前学习配置
- 学科领域{subject}
- 难度级别{level}
- 用户输入将包含学习问题材料或请求
## 工作流程(每次对话必须遵循)
### 阶段 1理解与分析
1. 理解用户的学习意图提问/复习/练习/总结/规划
2. `knowledge_graph_search` 检索相关知识图谱实体
3. 如果用户提供了新的学习材料/知识点 `knowledge_graph_add` 自动提取并存储
### 阶段 2知识检索与融合
4. 结合图谱检索结果和历史向量记忆构建完整的知识上下文
5. `entity_search` 查找特定概念的前置知识和扩展内容
6. 如果需要学习路径建议 `learning_path` 分析依赖关系
### 阶段 3生成与交付
7. 基于融合后的知识上下文生成高质量回答
8. 回答应包含
- 核心概念解释关联知识图谱中的实体
- 前置知识提醒如果有依赖关系
- 实例或练习题如适用
- 扩展阅读建议关联的扩展知识点
9. `self_review` 自检回答质量
### 阶段 4巩固与记忆
10. 将本轮对话中的重要知识点持久化到长期记忆
11. 更新用户画像掌握程度薄弱环节学习偏好
## 知识图谱工具使用指南
| 工具 | 用途 | 何时使用 |
|------|------|---------|
| `knowledge_graph_search` | 向量+图谱混合检索 | 每次回答学习问题前 |
| `knowledge_graph_add` | 从文本提取实体和关系 | 用户分享学习材料/新知识点时 |
| `entity_search` | 关键词搜索实体 | 查找特定概念详情时 |
| `learning_path` | 推荐学习路径 | 用户询问学习顺序/计划时 |
## 回答风格
- 使用 Markdown 格式层次分明
- 关键概念用 **粗体** 标记
- 公式用代码块或 LaTeX 表达
- 每个回答末尾附上 "📚 相关知识点" 列表来自图谱检索结果
- 必要时用 `task_plan` 为用户制定学习计划
## 记忆与个性化
- 记住用户的学习进度和薄弱环节
- 根据用户级别{level}调整解释深度
- 对反复出错的知识点主动提醒和强化"""
if extra:
return f"{base}\n\n【额外说明】\n{extra}"
return base
def _build_learning_workflow(
prompt: str,
*,
temperature: float = 0.7,
enable_tools: bool = True,
tools: Optional[List[str]] = None,
) -> Dict[str, Any]:
"""为学习助手构建更丰富的工作流含开始→LLM→结束LLM配置KG+RAG工具"""
tools = tools or []
return {
"nodes": [
{
"id": "start-1",
"type": "start",
"position": {"x": 80, "y": 200},
"data": {"label": "学习任务开始"},
},
{
"id": "llm-learning",
"type": "llm",
"position": {"x": 350, "y": 200},
"data": {
"label": "智能学习助手 (KG+RAG)",
"prompt": prompt,
"temperature": float(temperature),
"enable_tools": enable_tools,
"tools": tools,
"selected_tools": tools,
"model": "deepseek-chat",
"provider": "deepseek",
"max_iterations": 20,
"memory": True,
"memory_max_history": 30,
"memory_vector_enabled": True,
"memory_vector_top_k": 8,
"memory_persist": True,
"memory_learning": True,
},
},
{
"id": "end-1",
"type": "end",
"position": {"x": 620, "y": 200},
"data": {"label": "学习完成"},
},
],
"edges": [
{
"id": "e_start_learning",
"source": "start-1",
"target": "llm-learning",
"sourceHandle": "right",
"targetHandle": "left",
},
{
"id": "e_learning_end",
"source": "llm-learning",
"target": "end-1",
"sourceHandle": "right",
"targetHandle": "left",
},
],
}
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,
},
"template_learning_assistant": {
"title": "智能学习助手 (KG+RAG)",
"description": "知识图谱 + RAG 增强学习助手:实体抽取、关系图谱、向量检索、永久记忆,适合有规模要求的学习场景。",
"category": "education",
"default_temperature": 0.7,
"default_tools": [
"knowledge_graph_search",
"knowledge_graph_add",
"entity_search",
"learning_path",
"file_read",
"file_write",
"text_analyze",
"web_search",
"task_plan",
"self_review",
"math_calculate",
"json_process",
"datetime",
],
"prompt_builder": _default_prompt_learning,
"workflow_builder": _build_learning_workflow,
},
}
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():
hints = ["temperature", "enable_tools", "tools", "extra_instructions"]
if tid == "template_dev_codegen":
hints.append("preferred_language")
if tid == "template_learning_assistant":
hints.extend(["subject学科领域", "level难度级别初级/中级/高级)"])
out.append(
{
"id": tid,
"title": meta["title"],
"description": meta["description"],
"category": meta.get("category"),
"default_temperature": meta.get("default_temperature"),
"parameter_hints": hints,
}
)
return out