258 lines
8.9 KiB
Python
258 lines
8.9 KiB
Python
#!/usr/bin/env python3
|
|
"""MCN 创意灵感接口 — Dify chat-messages 调用脚本。
|
|
|
|
两种用法:
|
|
1. 联网搜索(search) — 输入创作意图 + 搜索内容,联网获取最新信息
|
|
2. 查询事件库(recall) — 输入创作意图 + 搜索标签和内容,查询事件库中的知识
|
|
|
|
用法示例:
|
|
|
|
# 方式一:联网搜索
|
|
$env:DIFY_MCN_CYLG_KEY="app-xxxx"
|
|
python scripts/MCN_CYLG_API.py search \\
|
|
--intent "为萌宠账号写一个猫咪应激的搞笑短视频" \\
|
|
--content "抖音上'耄耋猫'是什么梗,有哪些爆款视频" \\
|
|
--timeout 300
|
|
|
|
# 方式二:查询事件库
|
|
$env:DIFY_MCN_CYLG_KEY="app-xxxx"
|
|
python scripts/MCN_CYLG_API.py recall \\
|
|
--intent "为萌宠账号写一个猫咪应激的搞笑短视频" \\
|
|
--tags "萌宠,搞笑,应激,反差萌" \\
|
|
--content "猫咪应激反应的表现和常见搞笑场景" \\
|
|
--timeout 300
|
|
|
|
接口文档: references/接口调用/MCN_CYLG_python.md
|
|
"""
|
|
|
|
import argparse
|
|
import json
|
|
import os
|
|
import sys
|
|
import urllib.request
|
|
import urllib.error
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# 默认值
|
|
# ---------------------------------------------------------------------------
|
|
|
|
DIFY_URL = os.environ.get("DIFY_URL", "https://mydify.youmanvideo.com/v1")
|
|
DIFY_ENDPOINT = f"{DIFY_URL.rstrip('/')}/chat-messages"
|
|
DEFAULT_MODEL = os.environ.get("DIFY_MCN_MODEL", "gemini")
|
|
DEFAULT_TIMEOUT = 1200 # 秒
|
|
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# query 构造
|
|
# ---------------------------------------------------------------------------
|
|
|
|
def build_search_query(intent: str, content: str) -> str:
|
|
"""构造联网搜索模式的 query。
|
|
|
|
Args:
|
|
intent: 创作意图(账号定位、视频目标等)
|
|
content: 需要搜索的内容(热词释义、热点趋势、竞品分析等)
|
|
|
|
Returns:
|
|
组装后的 query 字符串
|
|
"""
|
|
return (
|
|
f"联网搜索\n"
|
|
f"创作意图:{intent}\n"
|
|
f"搜索内容:{content}"
|
|
)
|
|
|
|
|
|
def build_recall_query(intent: str, tags: str, content: str) -> str:
|
|
"""构造查询事件库模式的 query。
|
|
|
|
Args:
|
|
intent: 创作意图(账号定位、视频目标等)
|
|
tags: 搜索标签(逗号分隔的关键词,用于事件库检索匹配)
|
|
content: 搜索内容(需要查询的具体事件/知识描述)
|
|
|
|
Returns:
|
|
组装后的 query 字符串
|
|
"""
|
|
return (
|
|
f"查询事件库\n"
|
|
f"创作意图:{intent}\n"
|
|
f"搜索标签:{tags}\n"
|
|
f"搜索内容:{content}"
|
|
)
|
|
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# 核心调用
|
|
# ---------------------------------------------------------------------------
|
|
|
|
def call_dify(
|
|
query: str,
|
|
is_think: str = "0",
|
|
is_online: str = "0",
|
|
model: str = DEFAULT_MODEL,
|
|
response_mode: str = "blocking",
|
|
user: str = "wb-skill-001",
|
|
timeout: int = DEFAULT_TIMEOUT,
|
|
) -> dict:
|
|
"""调用 Dify 创意灵感接口,返回解析后的 JSON 响应。
|
|
|
|
Args:
|
|
query: 组装后的完整 query
|
|
is_think: 是否深度思考 ("0" 或 "1")
|
|
is_online: 是否联网搜索 ("0" 或 "1")
|
|
model: 模型名称
|
|
response_mode: "blocking" 或 "streaming"
|
|
user: 用户唯一标识
|
|
timeout: HTTP 读取超时(秒)
|
|
|
|
Returns:
|
|
dict: API 原始响应
|
|
|
|
Raises:
|
|
SystemExit: 缺少密钥、网络错误、API 返回非 200 时退出
|
|
"""
|
|
api_key = os.environ.get("DIFY_MCN_CYLG_KEY", "").strip()
|
|
if not api_key:
|
|
print("ERROR: 环境变量 DIFY_MCN_CYLG_KEY 未设置。", file=sys.stderr)
|
|
print("请先执行: $env:DIFY_MCN_CYLG_KEY=\"app-xxxx\"", file=sys.stderr)
|
|
sys.exit(1)
|
|
|
|
payload = json.dumps({
|
|
"inputs": {
|
|
"is_think": is_think,
|
|
"is_online": is_online,
|
|
"model": model,
|
|
},
|
|
"query": query,
|
|
"response_mode": response_mode,
|
|
"user": user,
|
|
}).encode("utf-8")
|
|
|
|
req = urllib.request.Request(
|
|
DIFY_ENDPOINT,
|
|
data=payload,
|
|
headers={
|
|
"Authorization": f"Bearer {api_key}",
|
|
"Content-Type": "application/json; charset=utf-8",
|
|
},
|
|
method="POST",
|
|
)
|
|
|
|
try:
|
|
with urllib.request.urlopen(req, timeout=timeout) as resp:
|
|
body = resp.read().decode("utf-8")
|
|
return json.loads(body)
|
|
except urllib.error.HTTPError as e:
|
|
print(f"ERROR: HTTP {e.code} — {e.reason}", file=sys.stderr)
|
|
try:
|
|
print(e.read().decode("utf-8", errors="replace")[:500], file=sys.stderr)
|
|
except Exception:
|
|
pass
|
|
sys.exit(2)
|
|
except urllib.error.URLError as e:
|
|
print(f"ERROR: 网络请求失败 — {e.reason}", file=sys.stderr)
|
|
sys.exit(3)
|
|
except Exception as e:
|
|
print(f"ERROR: {e}", file=sys.stderr)
|
|
sys.exit(4)
|
|
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# CLI — 子命令模式
|
|
# ---------------------------------------------------------------------------
|
|
|
|
def cmd_search(args: argparse.Namespace) -> None:
|
|
"""联网搜索模式:is_online=1,提示词中说明"联网搜索"。"""
|
|
query = build_search_query(args.intent, args.content)
|
|
result = call_dify(
|
|
query=query,
|
|
is_think=args.is_think,
|
|
is_online="1", # 联网搜索固定开启
|
|
model=args.model,
|
|
response_mode=args.response_mode,
|
|
user=args.user,
|
|
timeout=args.timeout,
|
|
)
|
|
print(json.dumps(result, ensure_ascii=False, indent=2))
|
|
|
|
|
|
def cmd_recall(args: argparse.Namespace) -> None:
|
|
"""查询事件库模式:is_online=0,提示词中写明'查询事件库'。"""
|
|
query = build_recall_query(args.intent, args.tags, args.content)
|
|
result = call_dify(
|
|
query=query,
|
|
is_think=args.is_think,
|
|
is_online="0", # 不联网,走事件库查询
|
|
model=args.model,
|
|
response_mode=args.response_mode,
|
|
user=args.user,
|
|
timeout=args.timeout,
|
|
)
|
|
print(json.dumps(result, ensure_ascii=False, indent=2))
|
|
|
|
|
|
def main() -> None:
|
|
parser = argparse.ArgumentParser(
|
|
description="MCN 创意灵感 — Dify chat-messages 调用工具",
|
|
formatter_class=argparse.RawDescriptionHelpFormatter,
|
|
epilog="""
|
|
示例:
|
|
# 联网搜索
|
|
python MCN_CYLG_API.py search \\
|
|
--intent "为萌宠账号写猫咪应激搞笑短视频" \\
|
|
--content "抖音耄耋猫是什么梗,有哪些爆款" \\
|
|
--timeout 300
|
|
|
|
# 查询事件库
|
|
python MCN_CYLG_API.py recall \\
|
|
--intent "为萌宠账号写猫咪应激搞笑短视频" \\
|
|
--tags "萌宠,搞笑,应激,反差萌" \\
|
|
--content "猫咪应激反应的表现和搞笑场景" \\
|
|
--timeout 300
|
|
""",
|
|
)
|
|
|
|
subparsers = parser.add_subparsers(dest="mode", required=True, help="调用模式")
|
|
|
|
# 公共参数
|
|
def add_common_args(sub):
|
|
sub.add_argument("--is-think", default="0", choices=["0", "1"],
|
|
help="是否深度思考 (0=否, 1=是)")
|
|
sub.add_argument("--model", default=DEFAULT_MODEL, help="模型名称")
|
|
sub.add_argument("--response-mode", default="blocking", choices=["blocking", "streaming"],
|
|
help="响应模式")
|
|
sub.add_argument("--user", default="wb-skill-001", help="用户唯一标识")
|
|
sub.add_argument("--timeout", type=int, default=DEFAULT_TIMEOUT, help="HTTP 超时(秒)")
|
|
|
|
# 子命令: search(联网搜索)
|
|
p_search = subparsers.add_parser(
|
|
"search", help="联网搜索模式 — 输入创作意图+搜索内容,联网获取最新信息"
|
|
)
|
|
p_search.add_argument("--intent", required=True,
|
|
help="创作意图(账号定位、视频目标等)")
|
|
p_search.add_argument("--content", required=True,
|
|
help="需要搜索的内容(热词释义、热点趋势、竞品分析等)")
|
|
add_common_args(p_search)
|
|
p_search.set_defaults(func=cmd_search)
|
|
|
|
# 子命令: recall(查询事件库)
|
|
p_recall = subparsers.add_parser(
|
|
"recall", help="查询事件库模式 — 输入创作意图+搜索标签+搜索内容,查询事件库"
|
|
)
|
|
p_recall.add_argument("--intent", required=True,
|
|
help="创作意图(账号定位、视频目标等)")
|
|
p_recall.add_argument("--tags", required=True,
|
|
help="搜索标签(逗号分隔的关键词,用于事件库检索匹配)")
|
|
p_recall.add_argument("--content", required=True,
|
|
help="需要查询的具体事件/知识描述")
|
|
add_common_args(p_recall)
|
|
p_recall.set_defaults(func=cmd_recall)
|
|
|
|
args = parser.parse_args()
|
|
args.func(args)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|