142 lines
4.4 KiB
Python
142 lines
4.4 KiB
Python
|
|
#!/usr/bin/env python3
|
|||
|
|
"""
|
|||
|
|
创建/更新「主控台Main Agent」:负责需求分流,不直接执行重任务。
|
|||
|
|
|
|||
|
|
输出协议(末行单行 JSON):
|
|||
|
|
{
|
|||
|
|
"action": "route_agent" | "clarify" | "answer_directly",
|
|||
|
|
"target_agent_name": "知你客服16号",
|
|||
|
|
"target_agent_id": "",
|
|||
|
|
"input": {"query": "...", "user_id": "..."},
|
|||
|
|
"reason": "路由原因",
|
|||
|
|
"reply": "给用户看的话"
|
|||
|
|
}
|
|||
|
|
"""
|
|||
|
|
from __future__ import annotations
|
|||
|
|
|
|||
|
|
import copy
|
|||
|
|
import json
|
|||
|
|
import os
|
|||
|
|
import sys
|
|||
|
|
from typing import Any, Dict, Optional
|
|||
|
|
|
|||
|
|
import requests
|
|||
|
|
|
|||
|
|
BASE = os.getenv("PLATFORM_BASE_URL", "http://127.0.0.1:8037").rstrip("/")
|
|||
|
|
USER = os.getenv("PLATFORM_USERNAME", "admin")
|
|||
|
|
PWD = os.getenv("PLATFORM_PASSWORD", "123456")
|
|||
|
|
SOURCE_NAME = os.getenv("SOURCE_AGENT_NAME", "知你客服14号")
|
|||
|
|
TARGET_NAME = os.getenv("TARGET_NAME", "主控台Main Agent")
|
|||
|
|
|
|||
|
|
PROMPT_MAIN = """
|
|||
|
|
你是企业 Agent 主控台入口。你负责把用户请求路由到最合适的场景 Agent。
|
|||
|
|
|
|||
|
|
路由建议:
|
|||
|
|
- 需求分析/代码开发/多步执行:优先路由「知你客服16号」
|
|||
|
|
- 普通客服问答:可路由「知你客服14号」
|
|||
|
|
- 若信息不足,先澄清再路由
|
|||
|
|
|
|||
|
|
必须输出一行合法 JSON(无 markdown):
|
|||
|
|
{
|
|||
|
|
"action": "route_agent" | "clarify" | "answer_directly",
|
|||
|
|
"target_agent_name": "知你客服16号",
|
|||
|
|
"target_agent_id": "",
|
|||
|
|
"input": {"query": "{{user_input}}", "user_id": "{{user_id}}"},
|
|||
|
|
"reason": "为何这样路由",
|
|||
|
|
"reply": "给用户看的一句话"
|
|||
|
|
}
|
|||
|
|
""".strip()
|
|||
|
|
|
|||
|
|
|
|||
|
|
def _find_agent_id_by_name(h: Dict[str, str], name: str) -> Optional[str]:
|
|||
|
|
r = requests.get(f"{BASE}/api/v1/agents", params={"search": name, "limit": 50}, headers=h, timeout=30)
|
|||
|
|
if r.status_code != 200:
|
|||
|
|
return None
|
|||
|
|
for a in r.json() or []:
|
|||
|
|
if a.get("name") == name:
|
|||
|
|
return a.get("id")
|
|||
|
|
return None
|
|||
|
|
|
|||
|
|
|
|||
|
|
def _patch_main_llm(wf: Dict[str, Any]) -> None:
|
|||
|
|
for n in wf.get("nodes") or []:
|
|||
|
|
if n.get("id") != "llm-unified":
|
|||
|
|
continue
|
|||
|
|
d = n.setdefault("data", {})
|
|||
|
|
d["prompt"] = PROMPT_MAIN
|
|||
|
|
d["enable_tools"] = False
|
|||
|
|
d["tools"] = []
|
|||
|
|
d["selected_tools"] = []
|
|||
|
|
d["temperature"] = 0.2
|
|||
|
|
return
|
|||
|
|
print("警告: 未找到节点 llm-unified", file=sys.stderr)
|
|||
|
|
|
|||
|
|
|
|||
|
|
def main() -> int:
|
|||
|
|
r = requests.post(
|
|||
|
|
f"{BASE}/api/v1/auth/login",
|
|||
|
|
data={"username": USER, "password": PWD},
|
|||
|
|
headers={"Content-Type": "application/x-www-form-urlencoded"},
|
|||
|
|
timeout=15,
|
|||
|
|
)
|
|||
|
|
if r.status_code != 200:
|
|||
|
|
print("登录失败:", r.status_code, r.text[:500], file=sys.stderr)
|
|||
|
|
return 1
|
|||
|
|
token = r.json().get("access_token")
|
|||
|
|
if not token:
|
|||
|
|
print("无 access_token", file=sys.stderr)
|
|||
|
|
return 1
|
|||
|
|
h = {"Authorization": f"Bearer {token}", "Content-Type": "application/json"}
|
|||
|
|
|
|||
|
|
src_id = _find_agent_id_by_name(h, SOURCE_NAME)
|
|||
|
|
if not src_id:
|
|||
|
|
print(f"未找到源 Agent: {SOURCE_NAME}", file=sys.stderr)
|
|||
|
|
return 1
|
|||
|
|
|
|||
|
|
existing = _find_agent_id_by_name(h, TARGET_NAME)
|
|||
|
|
if existing:
|
|||
|
|
new_id = existing
|
|||
|
|
g = requests.get(f"{BASE}/api/v1/agents/{new_id}", headers=h, timeout=30)
|
|||
|
|
if g.status_code != 200:
|
|||
|
|
print("读取失败:", g.text[:600], file=sys.stderr)
|
|||
|
|
return 1
|
|||
|
|
agent = g.json()
|
|||
|
|
print("已存在,更新:", TARGET_NAME, new_id)
|
|||
|
|
else:
|
|||
|
|
dup = requests.post(
|
|||
|
|
f"{BASE}/api/v1/agents/{src_id}/duplicate",
|
|||
|
|
headers=h,
|
|||
|
|
json={"name": TARGET_NAME},
|
|||
|
|
timeout=60,
|
|||
|
|
)
|
|||
|
|
if dup.status_code != 201:
|
|||
|
|
print("复制失败:", dup.status_code, dup.text[:800], file=sys.stderr)
|
|||
|
|
return 1
|
|||
|
|
agent = dup.json()
|
|||
|
|
new_id = agent["id"]
|
|||
|
|
print("已创建:", TARGET_NAME, new_id)
|
|||
|
|
|
|||
|
|
wf = copy.deepcopy(agent["workflow_config"])
|
|||
|
|
_patch_main_llm(wf)
|
|||
|
|
|
|||
|
|
desc = (
|
|||
|
|
"主控台路由Agent:仅做任务理解与场景路由,输出结构化 action JSON;"
|
|||
|
|
"默认建议需求分析/代码开发路由到知你客服16号。"
|
|||
|
|
)
|
|||
|
|
up = requests.put(
|
|||
|
|
f"{BASE}/api/v1/agents/{new_id}",
|
|||
|
|
headers=h,
|
|||
|
|
json={"description": desc, "workflow_config": wf},
|
|||
|
|
timeout=120,
|
|||
|
|
)
|
|||
|
|
if up.status_code != 200:
|
|||
|
|
print("更新失败:", up.status_code, up.text[:1000], file=sys.stderr)
|
|||
|
|
return 1
|
|||
|
|
|
|||
|
|
print(json.dumps({"id": new_id, "name": TARGET_NAME}, ensure_ascii=False))
|
|||
|
|
return 0
|
|||
|
|
|
|||
|
|
|
|||
|
|
if __name__ == "__main__":
|
|||
|
|
raise SystemExit(main())
|