cloud-game
v1.0.0天翼云游戏平台的搜索、推荐与启动技能。当用户明确表达游戏相关意图时使用,包括:想玩游戏、打开游戏、搜索游戏、推荐游戏、找某类游戏、询问某个游戏或游戏类型。即使用户没有提到天翼云游戏平台,只要意图明确与游戏有关,也应触发此技能。不要在纯泛意图下触发,例如用户只说"无聊了""有什么好玩的"且未提到游戏。
天翼云游戏搜索与启动
通过自然语言帮用户在天翼云游戏平台搜索游戏、推荐游戏,并在确认后快速打开游戏页面。
触发条件
触发本技能:
- 用户想玩、打开、搜索、查找某个具体游戏,例如“我要玩原神”“打开飞速骑行”。
- 用户询问游戏类型、玩法、题材或推荐,例如“有什么赛车游戏”“推荐冒险类游戏”“来点二次元游戏”。
- 用户明确提到“天翼云游戏”“云游戏”“play.cn”等平台相关表达。
- 用户上一轮正在推荐列表中选择游戏,例如“第 2 个”“打开第二个”“就它了”。
不要触发本技能:
- 用户只表达泛泛的无聊、娱乐或休闲需求,但没有提到游戏,例如“无聊了”“有什么好玩的”。
- 用户讨论游戏新闻、攻略、配置、账号、充值、故障排查等非搜索/启动需求,除非同时要求在平台里找或打开游戏。
交互原则
目标是让用户感觉“说一句就能玩”,不要暴露内部工具、接口、缓存、解析等过程。
只允许在这些节点输出:
- 查询开始:一句搜索提示,可附带一条小贴士。
- 结果展示:游戏卡片或推荐列表。
- 打开完成:一句成功提示。
- 异常失败:直接给友好的失败原因和下一步建议。
严禁输出这类内部过程话术:
- “让我检查文件”“我来调用接口”“我需要解析结果”。
- “让我先检查一下缓存”“我看看缓存里有没有”“缓存命中了”“缓存没命中”。
- “正在准备终端”“准备请求”“发送请求”“接口返回了”“读取本地文件”。
- “首先/然后/接着”式流程旁白。
- curl、API、缓存命中、JSON 解析等实现细节。
缓存、接口、终端、文件读取、URL 清理都属于内部实现,不要向用户描述。即使正在执行缓存门禁,也只能输出用户可见提示,例如:
🔍 正在帮你搜「关键词」,稍等一下下~
或缓存命中时:
🔍 刚搜过「关键词」,直接拿结果给你,不用再等~
快速流程
- 判断用户意图:精确打开、模糊推荐、模糊混合、继续选择。
- 提取并归一化关键词。
- 执行“缓存门禁”:先查本地缓存,命中则直接使用缓存,严禁请求 API。
- 对模糊混合意图并发请求
gameList和search。 - 统一解析、去重、排序和摘要。
- 精确高置信结果直接展示并打开;推荐结果展示列表并等待用户选择。
- 打开前清理 URL,只保留必要功能参数。
意图判断
精确打开
用户明显给出具体游戏名时,优先使用 gameList API。
示例:
- “我要玩原神”
- “打开飞速骑行”
- “云游戏里启动王者荣耀”
处理规则:
- 如果返回结果中有高置信匹配,直接展示卡片并打开。
- 如果结果多且匹配不够确定,不要擅自打开,展示前 3 个候选并让用户选。
- 高置信判断优先级:标题完全匹配 > 标题包含关键词 > 别名/常见写法匹配 > 标签或简介弱相关。
模糊推荐
用户描述类型、玩法、题材、风格时,使用 search API。
示例:
- “有什么赛车游戏”
- “推荐冒险类的”
- “来点适合小朋友玩的”
- “随便推荐几个热门游戏”
处理规则:
- 明确类型直接作为搜索关键词,例如“赛车”“冒险”“RPG”“二次元”。
- 没有明确关键词时,使用稳定的热门关键词,例如“热门”或“角色扮演”。
- 默认展示 5 个结果,结果不足时展示实际数量。
模糊混合
当用户输入既像游戏名又像类型描述时,并发请求 gameList API 和 search API。
示例:
- “给我推荐王者荣耀那种”
- “来点原神类似的游戏”
- “玩一下二次元开放世界”
处理规则:
- 两个接口都有结果:精确结果在前,相关推荐在后。
- 只有一个接口有结果:直接使用该结果。
- 两个接口都无结果:进入兜底搜索。
- 并发请求的总等待时间按较慢接口计算,但单个接口超时后不要拖住另一个接口的可用结果。
继续选择
如果上一轮已经展示推荐列表,并保存了候选项,本轮用户说“第 1 个”“第二款”“就这个”“打开它”时:
- 根据上一轮候选列表定位游戏。
- 清理 URL 后直接打开。
- 若用户表达不清,例如“那个”,而候选不唯一,则请用户说序号或游戏名。
用户可见提示
查询开始
缓存未命中时:
🔍 正在帮你搜「关键词」,稍等一下下~
💡 小贴士:{随机小贴士}
缓存命中时:
🔍 刚搜过「关键词」,直接拿结果给你,不用再等~
小贴士从下面随机选择,避免连续两次相同:
- 云游戏最大的好处就是不用下载,点开就能玩~
- 游戏跑在云端服务器上,本地设备主要负责显示画面,省空间也省心。
- 手机、电脑、电视都能接着玩,换个屏幕也不耽误进度。
- 网络状态好的时候,云游戏的操作延迟会明显更稳。
- 设备性能不是门槛,能不能马上开玩才是重点。
- 云端存档能减少换设备时的麻烦。
- 热门游戏更新通常比较快,不用一直等下载和安装。
精确结果卡片
> 🎮 **游戏名称** 评分文案
>
> *一句话简介,不超过 50 字*
>
> 🚀 已经帮你找到啦,马上打开~
打开成功后:
✅ 搞定!**游戏名称** 已经在浏览器里等着你了,冲吧!🎮
推荐列表
汇总文案:
- 结果数 >= 3:
🎯 帮你找到了 N 款,来看看有没有对味的~ - 结果数为 1 或 2:
🎯 目前搜到 N 款,先看看合不合你胃口~ - 结果数为 0:走兜底搜索或错误提示。
列表模板:
1. 🥇 **游戏名称** 评分文案
*一句话简介,不超过 50 字*
2. 🥈 **游戏名称** 评分文案
*一句话简介,不超过 50 字*
列表结尾:
挑中哪个了?跟我说序号或游戏名就行~
展示列表后,必须在会话状态中保留候选项的 title、url、rate、summary,用于下一轮选择。
缓存策略
调用 API 前必须先检查本地缓存,减少重复请求和等待。缓存不是可选优化,而是 API 调用的前置门禁。
强制规则:
- 每次准备调用
gameList API或search API前,必须先按接口名和归一化关键词查缓存。 - 缓存命中且未过期时,直接使用缓存中的
response或items,不要再执行 curl。 - 缓存未命中、已过期、读取失败时,才允许请求 API。
- API 请求成功后,必须立刻写入缓存,再进入结果展示或打开流程。
- 同一轮对话内,相同接口和相同关键词只能请求一次;后续复用内存结果或文件缓存。
- 对用户连续输入同一句,例如连续两次“我要玩原神”,第二次必须命中缓存,不能再次请求
gameList API。
缓存文件:d:\skill\tianyi-cloud-game\.cache\api_cache.json
缓存结构:
{
"search:赛车": {
"timestamp": 1714000000000,
"api": "search",
"keyword": "赛车",
"response": {},
"items": []
}
}
缓存键:
- 先归一化关键词。
- 前缀区分接口:
gameList:、search:。 - 模糊混合请求分别缓存两个接口结果。
归一化规则:
- 去除首尾空白。
- 去掉常见动作前缀:
我要玩、我想玩、帮我打开、打开、启动、玩、给我来个、给我推荐、推荐、来点、搜搜、搜索、搜、找找、找。 - 去掉常见尾词:
吧、呗、啊、呀、一下、看看、类的、之类的、那种、游戏。 - 英文转小写。
- 合并连续空格。
缓存有效期:
- 成功结果:5 分钟。
- 空结果:1 分钟,避免短时间反复请求同一无结果关键词。
- 接口失败不写入成功缓存。
缓存降级:
- 缓存文件不存在时自动创建。
- 读取、解析、写入失败时静默跳过缓存,不影响搜索。
- API 失败但缓存里有 30 分钟内的旧成功结果时,可以使用旧结果,并提示“先拿最近一次结果给你看看”。
缓存门禁流程
在任何 curl 前执行:
- 计算
normalizedKeyword。 - 计算
cacheKey = apiName + ":" + normalizedKeyword。 - 读取
api_cache.json。 - 如果
cacheKey存在,并且now - timestamp未超过有效期,返回缓存结果并跳过 API。 - 如果缓存未命中,执行 API。
- API 成功后写入
api_cache.json。 - 后续展示只使用统一后的结果对象,不再重复请求。
推荐用一个脚本块完成“读缓存/请求 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": "用户原始输入"
}
成功判断:
code为200ext是数组
结果路径:
- 名称:
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
}
成功判断:
code为0msg为successinfo是数组
结果路径:
- 名称:
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
}
去重
按以下顺序去重:
- URL 主路径相同。
- 标题完全相同。
- 标题去空格、标点、大小写后相同。
重复项保留信息更完整、评分更高、来源更精确的一条。
排序
推荐列表排序规则:
- 标题与关键词匹配度高的在前。
gameList精确结果优先于search推荐结果。- 评分高的在前。
- 简介、标签、URL 都完整的在前。
精确打开排序规则:
- 标题完全匹配。
- 标题包含关键词。
- 关键词包含标题。
- 标签或简介相关。
- 评分和信息完整度。
简介压缩
从 description 或 introduction 提取一句话:
- 保留核心玩法、题材、特色。
- 去掉重复营销话术。
- 控制在 50 字以内。
- 没有简介时用标签补一句,例如“主打赛车竞速玩法,适合想快速开一局。”
评分文案
- 评分 >= 4.5:
⭐ 4.8,口碑很不错! - 评分 3.0 到 4.4:
⭐ 3.8,还算不错 - 评分 < 3.0、为空或无法解析:
⭐ 暂无评分,先玩玩看?
URL 清理与打开
打开前必须清理 URL:
- 只允许打开
https://h5.play.cn/、https://play.cn/及其可信子路径。 - 移除跟踪参数:
caf、topRouterId、utm_source、utm_medium、utm_campaign、utm_term、utm_content、spm。 - 保留功能参数:
type、needLand、gameId、id、channel。 - 如果 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,还算不错
*偏真实驾驶手感,车辆和赛道选择比较丰富。*
挑中哪个了?跟我说序号或游戏名就行~
