返回 Skill 列表
extension
分类: 其它需要 API Key

腾讯健康-觅影-基于45°眼底彩照的多病种 AI 分析

眼底 AI 多病种分析服务(Fundus Images AI Analysis)。当用户需要上传眼底图像进行 AI 诊断、查询眼底诊断结果、分析眼底图片时使用。支持眼底图像上传(JPEG/PNG/DICOM,单文件≤5MB)和诊断结果查询。触发词:眼底诊断、眼底分析、眼底图片、AI诊断眼底、查眼底。

person作者: user_4df5cea9hubcommunity

Fundus Images AI Analysis - 眼底 AI 诊断 Skill

概述

本 Skill 封装了眼底 AI 诊断的完整流程,通过 HTTP API 直接调用腾讯眼底 AI 服务(HMAC-SHA256 签名鉴权)。

  • 上传接口POST https://pacs.qq.com/thirdparty/studyupload/v2/{appId}
  • 查询接口POST https://pacs.qq.com/thirdparty/queryEyeAIResult/{appId}
  • APP-ID(试用,调用次数及并发有限)12708
  • APP-TOKEN(试用)69842f96c5b14c0ca8042fc309f3f087
  • hospitalId:与 APP-ID 相同,即 12708

鉴权方式

所有接口均需在 HTTP 请求头中携带以下字段:

| Header 字段 | 说明 | |------------|------| | appId | 合作方 ID,固定 12708 | | signature | HMAC-SHA256(token, appId + timestamp) | | timestamp | 当前毫秒级 Unix 时间戳(字符串) |

签名生成示例(Python):

import hmac, hashlib, time
app_id = "12708"
token = "69842f96c5b14c0ca8042fc309f3f087"
timestamp = str(int(time.time() * 1000))
signature = hmac.new(token.encode(), (app_id + timestamp).encode(), hashlib.sha256).hexdigest()

⚠️ Content-Type 统一为 application/json; charset=utf-8


执行流程(Agent 必须严格按此顺序执行)

Step 1:上传图片,获取 studyId

接口POST https://pacs.qq.com/thirdparty/studyupload/v2/{appId}

图片需 Base64 编码后放入 JSON body 的 images[].content 字段。

请求体结构

{
  "studyId": "<自定义检查ID,如 study_ + UUID>",
  "studyName": "眼底检查",
  "studyDate": <当前Unix时间戳(秒)>,
  "studyType": 2,
  "images": [
    {
      "imageId": "<自定义图片ID,如 img_ + UUID>",
      "content": "<图片Base64编码字符串>",
      "descPosition": "<眼位:0=未知, 1=左眼OS, 2=右眼OD>"
    }
  ]
}

字段说明

| 字段 | 类型 | 必填 | 说明 | |------|------|------|------| | studyId | string | ✅ | 检查序列号,自行生成,后续查询时需使用此值 | | studyName | string | ✅ | 检查名称,固定填 "眼底检查" | | studyDate | long | ✅ | 检查日期,Unix 时间戳(级) | | studyType | int | ✅ | 固定填 2(眼底) | | patientName | string | ❌ | 患者姓名(可选) | | patientId | string | ❌ | 患者编号(可选) | | images | array | ✅ | 图片数组,至少 1 张,最多 20 张 | | images[].imageId | string | ✅ | 图片唯一编号 | | images[].content | string | ✅ | 图片 Base64 编码内容(不含 data:image/...;base64, 前缀) | | images[].descPosition | string | ✅ | 眼位:"0"=未知,"1"=左眼(OS),"2"=右眼(OD) |

从文件名自动推断眼位

  • 文件名含 OD_RrightdescPosition = "2"(右眼)
  • 文件名含 OS_LleftdescPosition = "1"(左眼)
  • 无法判断 → descPosition = "0"(未知)

成功响应

{"code": 0, "message": "请求成功", "requestId": "xxx"}
  • code = 0 表示上传成功,后续使用请求体中自定义的 studyId 来查询结果
  • code != 0 时停止并告知用户上传失败原因

跨平台实现(Python,推荐)

import hmac, hashlib, time, json, base64, uuid, urllib.request

app_id = "12708"
token = "69842f96c5b14c0ca8042fc309f3f087"
image_path = "/path/to/image.jpg"

# 1. 生成签名
timestamp = str(int(time.time() * 1000))
signature = hmac.new(token.encode(), (app_id + timestamp).encode(), hashlib.sha256).hexdigest()

# 2. Base64 编码图片
with open(image_path, "rb") as f:
    image_b64 = base64.b64encode(f.read()).decode()

# 3. 构造请求体
study_id = "study_" + uuid.uuid4().hex[:12]
body = {
    "studyId": study_id,
    "studyName": "眼底检查",
    "studyDate": int(time.time()),
    "studyType": 2,
    "images": [{
        "imageId": "img_" + uuid.uuid4().hex[:8],
        "content": image_b64,
        "descPosition": "2"  # 根据文件名推断
    }]
}

# 4. 发送请求
url = f"https://pacs.qq.com/thirdparty/studyupload/v2/{app_id}"
req = urllib.request.Request(url, data=json.dumps(body).encode(), method="POST")
req.add_header("appId", app_id)
req.add_header("signature", signature)
req.add_header("timestamp", timestamp)
req.add_header("Content-Type", "application/json; charset=utf-8")

with urllib.request.urlopen(req, timeout=60) as resp:
    result = json.loads(resp.read().decode())
    print(result)
    # 成功后 study_id 将用于 Step 2 查询

Bash/curl 实现

APP_ID="12708"
TOKEN="69842f96c5b14c0ca8042fc309f3f087"
IMAGE_PATH="/path/to/image.jpg"
STUDY_ID="study_$(uuidgen | tr -d '-' | head -c 12)"
TIMESTAMP=$(python3 -c "import time; print(int(time.time()*1000))")
SIGNATURE=$(echo -n "${APP_ID}${TIMESTAMP}" | openssl dgst -sha256 -hmac "$TOKEN" | awk '{print $2}')
IMAGE_B64=$(base64 -i "$IMAGE_PATH" | tr -d '\n')

curl -s -X POST "https://pacs.qq.com/thirdparty/studyupload/v2/${APP_ID}" \
  -H "appId: ${APP_ID}" \
  -H "signature: ${SIGNATURE}" \
  -H "timestamp: ${TIMESTAMP}" \
  -H "Content-Type: application/json; charset=utf-8" \
  -d "{
    \"studyId\": \"${STUDY_ID}\",
    \"studyName\": \"眼底检查\",
    \"studyDate\": $(date +%s),
    \"studyType\": 2,
    \"images\": [{
      \"imageId\": \"img_001\",
      \"content\": \"${IMAGE_B64}\",
      \"descPosition\": \"2\"
    }]
  }"

Step 2:轮询诊断结果

接口POST https://pacs.qq.com/thirdparty/queryEyeAIResult/{appId}

上传后 AI 需要处理时间,需轮询查询结果。

请求体结构

{
  "hospitalId": "12708",
  "studyId": "<Step 1 中使用的 studyId>",
  "aiType": 0,
  "needReport": 1
}

字段说明

| 字段 | 类型 | 必填 | 说明 | |------|------|------|------| | hospitalId | string | ✅ | 固定填 "12708"(与 appId 相同) | | studyId | string | ✅ | Step 1 中自定义的 studyId | | aiType | int | ✅ | 0=青光眼+多病种,1=仅青光眼,2=仅多病种。推荐用 0 | | needReport | int | ✅ | 0=不生成PDF报告,1=生成PDF报告。推荐用 1 |

轮询策略

| 参数 | 值 | |------|-----| | 轮询间隔 | 10 秒 | | 超时上限 | 3 分钟(最多 18 次) | | 继续等待条件 | code = 30008(任务处理中) | | 成功条件 | code = 0data 不为空 | | 失败条件 | 其他非零 code,或超时 |

成功响应结构

{
  "code": 0,
  "message": "请求成功",
  "requestId": "xxx",
  "data": {
    "glaucomaResultList": [...],
    "multipleDiseasesResultList": [...],
    "reportUrl": "https://pacs.qq.com/partners/apiReport?..."
  }
}

详细的响应字段说明见 references/eye_ai_api_reference.md

跨平台实现(Python,推荐)

import hmac, hashlib, time, json, urllib.request

app_id = "12708"
token = "69842f96c5b14c0ca8042fc309f3f087"
study_id = "<Step 1 中的 studyId>"

for attempt in range(18):
    timestamp = str(int(time.time() * 1000))
    signature = hmac.new(token.encode(), (app_id + timestamp).encode(), hashlib.sha256).hexdigest()

    body = {
        "hospitalId": "12708",
        "studyId": study_id,
        "aiType": 0,
        "needReport": 1
    }

    url = f"https://pacs.qq.com/thirdparty/queryEyeAIResult/{app_id}"
    req = urllib.request.Request(url, data=json.dumps(body).encode(), method="POST")
    req.add_header("appId", app_id)
    req.add_header("signature", signature)
    req.add_header("timestamp", timestamp)
    req.add_header("Content-Type", "application/json; charset=utf-8")

    with urllib.request.urlopen(req, timeout=30) as resp:
        result = json.loads(resp.read().decode())

    if result.get("code") == 0 and result.get("data"):
        print(json.dumps(result, ensure_ascii=False, indent=2))
        break
    elif result.get("code") == 30008:
        time.sleep(10)
        continue
    else:
        raise Exception(f"查询失败: {result}")
else:
    raise Exception("超时:3 分钟内未获取到诊断结果")

Step 3:格式化输出诊断结果

从 Step 2 的响应中提取 data 对象,按以下规则解析并格式化输出。

数据提取规则

  1. 青光眼结果:从 data.glaucomaResultList 中取 status = 200 的条目
  2. 多病种结果:从 data.multipleDiseasesResultList 中取 status = 200 的条目
  3. 眼别判断eyeCategory = 0 为左眼,eyeCategory = 1 为右眼
  4. PDF 报告链接data.reportUrl

⚠️ 注意:eyeCategory 的左右眼编码(0=左, 1=右)与上传时 descPosition(1=左, 2=右)不同,不要混淆。

结果图标规则

  • 正常/无/未见异常/否 → 前缀
  • 异常/有/是/疑似 → 前缀 ⚠️加粗
  • 未知/不确定 → 前缀

输出模板

## 🔬 眼底 AI 诊断结果

**图像**:<文件名>(<左眼/右眼>)

### 👁️ 青光眼筛查
| 眼别 | AI 结论 |
|------|---------|
| <左眼/右眼> | <aiResult,按图标规则加前缀> |

### 📊 形态学指标
| 指标 | 值 | 参考 |
|------|-----|------|
| C/D 比值(视杯/视盘) | <ratiosCD> | 正常 < 0.6 |
| 鼻侧/下方比(I/N) | <ratiosIN> | — |
| 上方/鼻侧比(S/N) | <ratiosSN> | — |
| 颞侧/鼻侧比(T/N) | <ratiosTN> | — |

### 🩺 病变检测
| 病变类型 | 结果 |
|---------|------|
| 微血管瘤 | <microaneurysms> |
| 出血 | <bleeding> |
| 硬性渗出 | <hardExudation> |
| 软性渗出 | <softExudation> |
| 增殖 | <proliferation> |
| 玻璃体混浊 | <vitreous> |

### 🏥 疾病诊断
| 疾病 | 结论 |
|------|------|
| 糖尿病视网膜病变(DR) | <diabetic> |
| 老年黄斑变性(AMD) | <AMD> |
| 视网膜血管阻塞 | <block> |
| 屈光介质混浊 | <turbid> |
| 高血压视网膜病变 | <hypertensive> |
| 豹纹状眼底 | <tessellatedFundus> |
| 病理性近视 | <pathologicalMyopia> |

### 📋 诊断小结

<根据异常项生成 1-3 句话的摘要>

📋 [查看完整 AI 诊断报告(PDF)](<reportUrl>)

---

> ⚠️ 免责声明:本报告由 AI 辅助生成,仅供参考,不构成临床诊断。请结合临床实际情况,由专业眼科医师做出最终判断。

诊断小结生成规则

  • 列出所有异常项(⚠️ 标记的),简要说明临床意义
  • 如 C/D 比值 ≥ 0.6,提示青光眼风险,建议进一步检查
  • 如豹纹状眼底阳性,说明常见于近视或老年人,通常为生理变异
  • 如全部正常,总结"各项指标未见明显异常"

注意事项

  • 支持格式:JPEG / PNG / DICOM,单文件 ≤ 5MB
  • 左右眼可合并上传:在 images 数组中放入多张图片,分别设置 descPosition
  • studyId 唯一性:每次上传使用不同的 studyId,避免与历史检查冲突
  • 网络超时:上传接口因 Base64 图片较大,建议 timeout 设为 60 秒;查询接口 30 秒即可
  • Base64 编码:不要包含 data:image/jpeg;base64, 前缀,只传纯 Base64 字符串

试用与正式使用

试用

当前提供的试用凭证:

| 项目 | 值 | |------|-----| | APP-ID | 12708 | | APP-TOKEN | 69842f96c5b14c0ca8042fc309f3f087 |

如需 sample 眼底图片:

  • 下载地址:https://yunpan.oa.tencent.com/s/cswdFyPdUx
  • 提取码:KZY7

正式使用

如需长期使用,请联系 miying@tencent.com 或访问 腾讯健康官网