Skill flagged — suspicious patterns detected

ClawHub Security flagged this skill as suspicious. Review the scan results before using.

cloud-game

v1.0.0

天翼云游戏平台的搜索、推荐与启动技能。当用户明确表达游戏相关意图时使用,包括:想玩游戏、打开游戏、搜索游戏、推荐游戏、找某类游戏、询问某个游戏或游戏类型。即使用户没有提到天翼云游戏平台,只要意图明确与游戏有关,也应触发此技能。不要在纯泛意图下触发,例如用户只说"无聊了""有什么好玩的"且未提到游戏。

0· 15· 1 versions· 0 current· 0 all-time· Updated 4h ago· MIT-0

天翼云游戏搜索与启动

通过自然语言帮用户在天翼云游戏平台搜索游戏、推荐游戏,并在确认后快速打开游戏页面。

触发条件

触发本技能:

  • 用户想玩、打开、搜索、查找某个具体游戏,例如“我要玩原神”“打开飞速骑行”。
  • 用户询问游戏类型、玩法、题材或推荐,例如“有什么赛车游戏”“推荐冒险类游戏”“来点二次元游戏”。
  • 用户明确提到“天翼云游戏”“云游戏”“play.cn”等平台相关表达。
  • 用户上一轮正在推荐列表中选择游戏,例如“第 2 个”“打开第二个”“就它了”。

不要触发本技能:

  • 用户只表达泛泛的无聊、娱乐或休闲需求,但没有提到游戏,例如“无聊了”“有什么好玩的”。
  • 用户讨论游戏新闻、攻略、配置、账号、充值、故障排查等非搜索/启动需求,除非同时要求在平台里找或打开游戏。

交互原则

目标是让用户感觉“说一句就能玩”,不要暴露内部工具、接口、缓存、解析等过程。

只允许在这些节点输出:

  • 查询开始:一句搜索提示,可附带一条小贴士。
  • 结果展示:游戏卡片或推荐列表。
  • 打开完成:一句成功提示。
  • 异常失败:直接给友好的失败原因和下一步建议。

严禁输出这类内部过程话术:

  • “让我检查文件”“我来调用接口”“我需要解析结果”。
  • “让我先检查一下缓存”“我看看缓存里有没有”“缓存命中了”“缓存没命中”。
  • “正在准备终端”“准备请求”“发送请求”“接口返回了”“读取本地文件”。
  • “首先/然后/接着”式流程旁白。
  • curl、API、缓存命中、JSON 解析等实现细节。

缓存、接口、终端、文件读取、URL 清理都属于内部实现,不要向用户描述。即使正在执行缓存门禁,也只能输出用户可见提示,例如:

🔍 正在帮你搜「关键词」,稍等一下下~

或缓存命中时:

🔍 刚搜过「关键词」,直接拿结果给你,不用再等~

快速流程

  1. 判断用户意图:精确打开、模糊推荐、模糊混合、继续选择。
  2. 提取并归一化关键词。
  3. 执行“缓存门禁”:先查本地缓存,命中则直接使用缓存,严禁请求 API。
  4. 对模糊混合意图并发请求 gameListsearch
  5. 统一解析、去重、排序和摘要。
  6. 精确高置信结果直接展示并打开;推荐结果展示列表并等待用户选择。
  7. 打开前清理 URL,只保留必要功能参数。

意图判断

精确打开

用户明显给出具体游戏名时,优先使用 gameList API

示例:

  • “我要玩原神”
  • “打开飞速骑行”
  • “云游戏里启动王者荣耀”

处理规则:

  • 如果返回结果中有高置信匹配,直接展示卡片并打开。
  • 如果结果多且匹配不够确定,不要擅自打开,展示前 3 个候选并让用户选。
  • 高置信判断优先级:标题完全匹配 > 标题包含关键词 > 别名/常见写法匹配 > 标签或简介弱相关。

模糊推荐

用户描述类型、玩法、题材、风格时,使用 search API

示例:

  • “有什么赛车游戏”
  • “推荐冒险类的”
  • “来点适合小朋友玩的”
  • “随便推荐几个热门游戏”

处理规则:

  • 明确类型直接作为搜索关键词,例如“赛车”“冒险”“RPG”“二次元”。
  • 没有明确关键词时,使用稳定的热门关键词,例如“热门”或“角色扮演”。
  • 默认展示 5 个结果,结果不足时展示实际数量。

模糊混合

当用户输入既像游戏名又像类型描述时,并发请求 gameList APIsearch API

示例:

  • “给我推荐王者荣耀那种”
  • “来点原神类似的游戏”
  • “玩一下二次元开放世界”

处理规则:

  • 两个接口都有结果:精确结果在前,相关推荐在后。
  • 只有一个接口有结果:直接使用该结果。
  • 两个接口都无结果:进入兜底搜索。
  • 并发请求的总等待时间按较慢接口计算,但单个接口超时后不要拖住另一个接口的可用结果。

继续选择

如果上一轮已经展示推荐列表,并保存了候选项,本轮用户说“第 1 个”“第二款”“就这个”“打开它”时:

  • 根据上一轮候选列表定位游戏。
  • 清理 URL 后直接打开。
  • 若用户表达不清,例如“那个”,而候选不唯一,则请用户说序号或游戏名。

用户可见提示

查询开始

缓存未命中时:

🔍 正在帮你搜「关键词」,稍等一下下~
💡 小贴士:{随机小贴士}

缓存命中时:

🔍 刚搜过「关键词」,直接拿结果给你,不用再等~

小贴士从下面随机选择,避免连续两次相同:

  • 云游戏最大的好处就是不用下载,点开就能玩~
  • 游戏跑在云端服务器上,本地设备主要负责显示画面,省空间也省心。
  • 手机、电脑、电视都能接着玩,换个屏幕也不耽误进度。
  • 网络状态好的时候,云游戏的操作延迟会明显更稳。
  • 设备性能不是门槛,能不能马上开玩才是重点。
  • 云端存档能减少换设备时的麻烦。
  • 热门游戏更新通常比较快,不用一直等下载和安装。

精确结果卡片

> 🎮 **游戏名称**  评分文案
>
> *一句话简介,不超过 50 字*
>
> 🚀 已经帮你找到啦,马上打开~

打开成功后:

✅ 搞定!**游戏名称** 已经在浏览器里等着你了,冲吧!🎮

推荐列表

汇总文案:

  • 结果数 >= 3:🎯 帮你找到了 N 款,来看看有没有对味的~
  • 结果数为 1 或 2:🎯 目前搜到 N 款,先看看合不合你胃口~
  • 结果数为 0:走兜底搜索或错误提示。

列表模板:

1. 🥇 **游戏名称**  评分文案
   *一句话简介,不超过 50 字*

2. 🥈 **游戏名称**  评分文案
   *一句话简介,不超过 50 字*

列表结尾:

挑中哪个了?跟我说序号或游戏名就行~

展示列表后,必须在会话状态中保留候选项的 titleurlratesummary,用于下一轮选择。

缓存策略

调用 API 前必须先检查本地缓存,减少重复请求和等待。缓存不是可选优化,而是 API 调用的前置门禁。

强制规则:

  • 每次准备调用 gameList APIsearch API 前,必须先按接口名和归一化关键词查缓存。
  • 缓存命中且未过期时,直接使用缓存中的 responseitems,不要再执行 curl。
  • 缓存未命中、已过期、读取失败时,才允许请求 API。
  • API 请求成功后,必须立刻写入缓存,再进入结果展示或打开流程。
  • 同一轮对话内,相同接口和相同关键词只能请求一次;后续复用内存结果或文件缓存。
  • 对用户连续输入同一句,例如连续两次“我要玩原神”,第二次必须命中缓存,不能再次请求 gameList API

缓存文件:d:\skill\tianyi-cloud-game\.cache\api_cache.json

缓存结构:

{
  "search:赛车": {
    "timestamp": 1714000000000,
    "api": "search",
    "keyword": "赛车",
    "response": {},
    "items": []
  }
}

缓存键:

  • 先归一化关键词。
  • 前缀区分接口:gameList:search:
  • 模糊混合请求分别缓存两个接口结果。

归一化规则:

  1. 去除首尾空白。
  2. 去掉常见动作前缀:我要玩我想玩帮我打开打开启动给我来个给我推荐推荐来点搜搜搜索找找
  3. 去掉常见尾词:一下看看类的之类的那种游戏
  4. 英文转小写。
  5. 合并连续空格。

缓存有效期:

  • 成功结果:5 分钟。
  • 空结果:1 分钟,避免短时间反复请求同一无结果关键词。
  • 接口失败不写入成功缓存。

缓存降级:

  • 缓存文件不存在时自动创建。
  • 读取、解析、写入失败时静默跳过缓存,不影响搜索。
  • API 失败但缓存里有 30 分钟内的旧成功结果时,可以使用旧结果,并提示“先拿最近一次结果给你看看”。

缓存门禁流程

在任何 curl 前执行:

  1. 计算 normalizedKeyword
  2. 计算 cacheKey = apiName + ":" + normalizedKeyword
  3. 读取 api_cache.json
  4. 如果 cacheKey 存在,并且 now - timestamp 未超过有效期,返回缓存结果并跳过 API。
  5. 如果缓存未命中,执行 API。
  6. API 成功后写入 api_cache.json
  7. 后续展示只使用统一后的结果对象,不再重复请求。

推荐用一个脚本块完成“读缓存/请求 API/写缓存”,不要分散在多次终端调用里,否则容易出现已经查过但仍继续 curl 的问题。

PowerShell 实现参考

当运行环境是 PowerShell 时,优先使用下面这种结构,把缓存检查和 API 请求放在同一个脚本里。示例中的请求体必须由对象转 JSON,不要手写拼接 JSON。

$ErrorActionPreference = "Stop"
$cacheDir = "d:\skill\tianyi-cloud-game\.cache"
$cacheFile = Join-Path $cacheDir "api_cache.json"
$apiName = "gameList"
$rawKeyword = "我要玩原神"
$ttlMs = 5 * 60 * 1000

function Normalize-Keyword([string]$text) {
  $value = $text.Trim()
  $value = $value -replace "^(我要玩|我想玩|帮我打开|打开|启动|玩|给我来个|给我推荐|推荐|来点|搜搜|搜索|搜|找找|找)", ""
  $value = $value -replace "(吧|呗|啊|呀|一下|看看|类的|之类的|那种|游戏)$", ""
  $value = ($value.Trim().ToLower() -replace "\s+", " ")
  return $value
}

if (!(Test-Path $cacheDir)) {
  New-Item -ItemType Directory -Path $cacheDir | Out-Null
}

$cache = @{}
if (Test-Path $cacheFile) {
  try {
    $json = Get-Content -Path $cacheFile -Raw -Encoding UTF8
    if ($json.Trim()) {
      $cache = $json | ConvertFrom-Json -AsHashtable
    }
  } catch {
    $cache = @{}
  }
}

$keyword = Normalize-Keyword $rawKeyword
$cacheKey = "$apiName`:$keyword"
$now = [DateTimeOffset]::UtcNow.ToUnixTimeMilliseconds()

if ($cache.ContainsKey($cacheKey)) {
  $entry = $cache[$cacheKey]
  if (($now - [int64]$entry.timestamp) -lt $ttlMs) {
    $entry.response | ConvertTo-Json -Depth 20 -Compress
    exit 0
  }
}

$body = @{ text = $rawKeyword } | ConvertTo-Json -Depth 10 -Compress
$response = Invoke-RestMethod `
  -Uri "https://api.play.cn/api/v1/ai/conversation/gameList" `
  -Method Post `
  -ContentType "application/json" `
  -Body $body `
  -TimeoutSec 10

$cache[$cacheKey] = @{
  timestamp = $now
  api = $apiName
  keyword = $keyword
  response = $response
}

$cache | ConvertTo-Json -Depth 30 | Set-Content -Path $cacheFile -Encoding UTF8
$response | ConvertTo-Json -Depth 20 -Compress

search API 使用同样结构,只需把 $apiName 改为 search,请求体改为:

$body = @{ keyword = $keyword; pageSize = 5 } | ConvertTo-Json -Depth 10 -Compress

请求地址改为:

https://api.play.cn/api/v1/cloud_phone/search

API 调用

所有请求都要设置 10 秒超时,并对用户输入做 JSON 转义。不要把未转义的用户输入直接拼接到命令字符串里。

API 调用前置条件:

  • 已执行缓存门禁。
  • 已确认缓存未命中或已过期。
  • 已确认同一轮内没有相同接口和关键词的可复用结果。

如果这三个条件不满足,禁止请求 API。

gameList API

用途:具体游戏名精确匹配。

请求地址:https://api.play.cn/api/v1/ai/conversation/gameList

请求方式:POST

请求头:Content-Type: application/json

请求体:

{
  "text": "用户原始输入"
}

成功判断:

  • code200
  • ext 是数组

结果路径:

  • 名称:ext[].title
  • 简介:ext[].description
  • 评分:ext[].rate
  • 标签:ext[].tags
  • 链接:ext[].url

search API

用途:类型、玩法、题材、相关推荐。

请求地址:https://api.play.cn/api/v1/cloud_phone/search

请求方式:POST

请求头:Content-Type: application/json

请求体:

{
  "keyword": "搜索关键词",
  "pageSize": 5
}

成功判断:

  • code0
  • msgsuccess
  • info 是数组

结果路径:

  • 名称:info[].title
  • 简介:info[].introduction
  • 评分:info[].rate
  • 标签:info[].tags
  • 链接:info[].url

结果处理

统一字段

把不同接口返回统一成:

{
  "title": "游戏名称",
  "summary": "一句话简介",
  "rate": "4.5",
  "tags": [],
  "url": "https://h5.play.cn/...",
  "source": "gameList 或 search",
  "score": 0.92
}

去重

按以下顺序去重:

  1. URL 主路径相同。
  2. 标题完全相同。
  3. 标题去空格、标点、大小写后相同。

重复项保留信息更完整、评分更高、来源更精确的一条。

排序

推荐列表排序规则:

  1. 标题与关键词匹配度高的在前。
  2. gameList 精确结果优先于 search 推荐结果。
  3. 评分高的在前。
  4. 简介、标签、URL 都完整的在前。

精确打开排序规则:

  1. 标题完全匹配。
  2. 标题包含关键词。
  3. 关键词包含标题。
  4. 标签或简介相关。
  5. 评分和信息完整度。

简介压缩

descriptionintroduction 提取一句话:

  • 保留核心玩法、题材、特色。
  • 去掉重复营销话术。
  • 控制在 50 字以内。
  • 没有简介时用标签补一句,例如“主打赛车竞速玩法,适合想快速开一局。”

评分文案

  • 评分 >= 4.5:⭐ 4.8,口碑很不错!
  • 评分 3.0 到 4.4:⭐ 3.8,还算不错
  • 评分 < 3.0、为空或无法解析:⭐ 暂无评分,先玩玩看?

URL 清理与打开

打开前必须清理 URL:

  • 只允许打开 https://h5.play.cn/https://play.cn/ 及其可信子路径。
  • 移除跟踪参数:caftopRouterIdutm_sourceutm_mediumutm_campaignutm_termutm_contentspm
  • 保留功能参数:typeneedLandgameIdidchannel
  • 如果 URL 缺失、非法或不属于天翼云游戏域名,不要打开,提示用户该结果暂时无法启动。

打开成功后输出完成提示。若系统打开浏览器失败,展示游戏链接并说明可以手动打开。

空结果与错误处理

错误提示要短、轻松、有下一步建议。

API 失败

😅 网络有点小情绪,连不上天翼云游戏平台,等会儿再试一次?

如果有 30 分钟内的旧缓存:

😅 平台这会儿有点慢,我先拿最近一次结果给你看看~

请求超时

⏳ 这会儿网络有点慢,请求卡住了,要不换个关键词再试一次?

无结果兜底

第一次无结果时,不要立即失败。根据关键词推断一个相关标签,再调用 search API 搜一次。

推断示例:

  • 原神开放世界塞尔达 -> 开放世界
  • CS枪战吃鸡 -> 射击
  • 王者MOBA -> 竞技
  • 赛车飞车 -> 赛车
  • 三国仙侠武侠 -> 角色扮演
  • 识别不出 -> 冒险

兜底成功:

🤔 没找到「原关键词」诶,帮你挑了几款「推断标签」类的,看看合不合眼?

兜底仍失败:

🤔 平台里暂时没找到跟「关键词」相关的游戏,换个词试试?比如搜搜「冒险」「射击」「赛车」之类的~

候选不明确

我找到了几个相近的,怕打开错。你选个序号,我再帮你启动~

性能优化要求

  • 缓存门禁必须发生在 curl 或 Invoke-RestMethod 之前,命中时禁止请求接口。
  • 模糊混合意图并发请求两个接口。
  • 单接口超时不阻塞另一个接口的可用结果。
  • 推荐默认 pageSize 为 5,不要无意义拉取过多数据。
  • 同一轮不要重复请求相同接口和关键词。
  • 空结果短缓存 1 分钟,避免连续无效请求。
  • API 返回后先统一解析和去重,再生成用户可见内容。

会话状态

展示推荐列表后保存最近一轮候选:

{
  "lastCandidates": [
    {
      "index": 1,
      "title": "游戏名称",
      "url": "https://h5.play.cn/...",
      "summary": "一句话简介",
      "rate": "4.5"
    }
  ],
  "lastKeyword": "赛车",
  "lastUpdatedAt": 1714000000000
}

候选状态有效期为 10 分钟。超过有效期后,如果用户只说“第几个”,提示重新搜索或让用户补充游戏名。

输出示例

指定游戏

🔍 正在帮你搜「原神」,稍等一下下~
💡 小贴士:云游戏最大的好处就是不用下载,点开就能玩~

> 🎮 **原神**  ⭐ 4.8,口碑很不错!
>
> *开放世界冒险 RPG,自由探索、战斗和养成内容都很丰富。*
>
> 🚀 已经帮你找到啦,马上打开~

✅ 搞定!**原神** 已经在浏览器里等着你了,冲吧!🎮

推荐游戏

🔍 正在帮你搜「赛车」,稍等一下下~
💡 小贴士:手机、电脑、电视都能接着玩,换个屏幕也不耽误进度。

🎯 帮你找到了 5 款,来看看有没有对味的~

1. 🥇 **飞速骑行**  ⭐ 4.6,口碑很不错!
   *主打高速竞速和赛道挑战,适合想快速开跑的玩家。*

2. 🥈 **真实赛车**  ⭐ 4.1,还算不错
   *偏真实驾驶手感,车辆和赛道选择比较丰富。*

挑中哪个了?跟我说序号或游戏名就行~

Version tags

latestvk9775r94gdc00436vd5dn0b8r185r151

Runtime requirements

☁️ Clawdis