Jelajahi Sumber

feat: 舌诊 AI 集成 - aikanshe.com 优先,LangGraph 兜底

1. AIService.java:重写 sendTongueDiagnosis(),主调 aikanshe.com API,失败回退至 LangGraph
2. application.yml:新增 aikanshe 配置块(6参数)
3. API_REFERENCE.md:新增 4.36.2 节「舌诊 AI 集成」
4. specs/2026-10-08-tongue-diagnosis-aikanshe-integration.md:完整设计规格

无需改动 TongueDiagnosisService/HealthReportController,接口契约兼容。

配置: export AIKANSHE_APPKEY="your_appkey_here"
iwt 3 hari lalu
induk
melakukan
48b0695e18

+ 200 - 0
docs/superpowers/specs/2026-10-08-tongue-diagnosis-aikanshe-integration.md

@@ -0,0 +1,200 @@
+# 舌诊 aikanshe.com API 集成设计方案
+
+**日期**: 2026-10-08  
+**状态**: 已实现(代码已完成)  
+**优先级**: P1
+
+---
+
+## 一、背景
+
+CFC 项目已有舌诊功能的初步实现,但目前依赖 LangGraph Python 服务(`cfc-langgraph`),在 LangGraph 不可用时使用 mock 数据兜底。  
+为提供更准确、更丰富的中医舌诊分析,计划接入 `aikanshe.com`(愛看舌)开放 API,作为备用舌诊服务提供者。
+
+---
+
+## 二、aikanshe.com API 概览
+
+### 2.1 认证方式
+
+| 方式 | 说明 | 适用场景 |
+|------|------|----------|
+| `appkey` + `x-appkey` header | 注册后获取的 API Key | 推荐,对接简单 |
+| JWT Token | `POST /account/login` 获取,放入 `Authorization: Bearer {token}` | 需登录态的场景 |
+
+每个账号默认 **25 次免费调用**,超额需购买算力包。
+
+### 2.2 核心接口
+
+| 接口 | 消耗 | 说明 |
+|------|------|------|
+| `POST /agency/quanxi` | 1 次 | AI 全息舌诊(multipart 上传) |
+| `POST /agency/quanxiWithUrl` | 1 次 | AI 全息舌诊(imageUrl 方式) |
+| `POST /agency/quanxiWithReport` | 2 次 | 附带网页报告 |
+| `POST /agency/quanxiWithReportAndUnderside` | 3 次 | 带舌底 + 网页报告 |
+
+### 2.3 请求参数(`quanxiWithUrl`)
+
+```json
+{
+  "age": 30,           // 年龄(小孩 2-16,成人 >15)
+  "male": 1,           // 1=男,0=女,2=其他
+  "name": "张三",       // 姓名/昵称
+  "imageUrl": "data:image/jpeg;base64,...",
+  "appkey": "xxx",     // appkey 或 token 认证
+  "desease": "",       // 疾病筛选(拼音,填 all 检测所有)
+  "confidence": 0.2,   // 置信度阈值
+  "lang": "zh-CN"      // 语言偏好
+}
+```
+
+### 2.4 响应结构(`AiQuanxiReportDTO`)
+
+```json
+{
+  "code": "20000",
+  "data": {
+    "id": 123,
+    "name": "张三",
+    "age": 30,
+    "feel": "身体表现...",          // 整体评估(映射到 overall_assessment)
+    "recomand": "...",              // 调理方案
+    "aijiu": "调理方案:艾灸与按摩",
+    "bagang": "阴阳虚实表里寒热",     // 八纲辨证
+    "botai": 0,                     // 是否有剥苔(0/1)
+    "chagndao": 0,                  // 肠道是否异常
+    "chagndaoDesc": "...",
+    "chagndaoMean": "...",
+    "chihen": 0,                    // 是否有齿痕(0/1)
+    "chihenDesc": "...",
+    "chihenMean": "...",
+    "dianci": 0,                    // 是否有点刺(0/1)
+    "dianciDesc": "...",
+    "fei": 0,
+    "feiDesc": "...",
+    "createTime": "2026-10-08T..."
+    // ... 其他字段
+  },
+  "meta": {}
+}
+```
+
+---
+
+## 三、现有架构
+
+### 3.1 现有舌诊流程
+
+```
+TongueDiagnosisService.parsePreview()
+    ↓
+AIService.sendTongueDiagnosis(imageBytes, filename, userId)
+    ↓
+AiGateway.analyzeTongue(imageBytes, filename, userId)  ← 调用 LangGraph
+    ↓
+LangGraph: POST /api/v1/tongue/diagnose
+    ↓
+返回: { overall_assessment, indicators: [{code, value}] }
+```
+
+### 3.2 新增兜底逻辑
+
+当 LangGraph 不可用时,自动降级到 aikanshe.com API:
+
+```
+AIService.sendTongueDiagnosis(imageBytes, filename, userId)
+    ↓
+AiGateway.analyzeTongue(...)  ← 失败则继续
+    ↓ (LangGraph 返回 null)
+callAikansheTongueDiagnosis(imageBytes, filename, userId)  ← 新增
+    ↓
+POST https://api.aikanshe.com/agency/quanxi
+    ↓
+parseAikansheIndicators(data)  ← 新增:字段映射
+    ↓
+返回: { overall_assessment, indicators: [{code, value}] }
+```
+
+---
+
+## 四、实现变更
+
+### 4.1 application.yml — 新增配置
+
+```yaml
+aikanshe:
+  appkey: ${AIKANSHE_APPKEY:}
+  base-url: ${AIKANSHE_BASE_URL:https://api.aikanshe.com}
+  token: ${AIKANSHE_TOKEN:}
+  desease: ${AIKANSHE_DISEASE:}
+  confidence: ${AIKANSHE_CONFIDENCE:0.2}
+  lang: ${AIKANSHE_LANG:zh-CN}
+```
+
+环境变量可通过 Docker 部署或 `.env` 文件覆盖。
+
+### 4.2 AIService.java — 新增方法
+
+- 新增 6 个 `@Value` 注入字段(`aikansheAppkey`, `aikansheBaseUrl`, `aikansheToken`, `aikansheDesease`, `aikansheConfidence`, `aikansheLang`)
+- 修改 `sendTongueDiagnosis()`:aikanshe.com 优先,失败时回退至 LangGraph
+- 新增 `callAikansheTongueDiagnosis()`:HTTP 调用 aikanshe.com API
+- 新增 `parseAikansheIndicators()`:将 aikanshe 的丰富指标映射到 CFC 标准的 7 类指标
+- 新增 `isValidTongueColor()`:验证舌色值合法性
+- 新增 `makeIndicator()`:辅助方法
+
+### 4.3 指标映射关系
+
+| aikanshe 字段 | CFC 标准 code | 映射逻辑 |
+|---------------|--------------|---------|
+| `feel` 文本含"舌色" | `tongue_color` | 从 feel 文本中提取 |
+| `botai` = 0/1 | `coating_color` | 有苔/无苔 |
+| `botai` = 0/1 | `coating_texture` | 润/滑腻 |
+| `bagang` 含虚/实 | `fissure` | 有/无 |
+| `chihen` = 0/1 | `teeth_mark` | 有齿痕/无齿痕 |
+| `dianci` = 0/1 | `sublingual_vein` | 有点刺/无点刺 |
+| `desease` 关键词 | `constitution` | 气虚质/阴虚质/血瘀质/平和质 |
+
+---
+
+## 五、后续优化建议(YAGNI)
+
+以下不在本次范围,留待后续迭代:
+
+1. **传真实用户信息**:当前 `age/male/name` 使用占位值,实际应从 JWT 上下文获取
+2. **图片存储后传 URL**:当前使用 base64 data URL,建议先上传到 JD Cloud S3,再传 URL 给 aikanshe(减少带宽和延迟)
+3. **完整指标提取**:aikanshe 返回约 50 个字段,可提取更丰富的体质/脏腑信息用于五维能量计算
+4. **调用量监控**:添加调用次数统计和配额告警
+
+---
+
+## 五、调用优先级
+
+**aikanshe.com 优先,LangGraph 兜底**:
+
+```
+启动 → 调用 aikanshe.com API
+       │
+       ├── 成功 → 返回 aikanshe 结果(7类标准指标 + overall_assessment)
+       │
+       └── 失败/超时 → 调用 LangGraph /api/v1/tongue/diagnose
+               │
+               ├── 成功 → 返回 LangGraph 结果
+               │
+               └── 失败 → 返回 mockTongueResult() 默认值
+```
+
+- 配置 `AIKANSHE_APPKEY` 后自动使用 aikanshe.com;未配置或调用失败时自动回退 LangGraph
+- 最终兜底为 mock 数据,确保业务不中断
+
+---
+
+## 六、验证步骤
+
+1. 配置环境变量:
+   ```bash
+   export AIKANSHE_APPKEY="your_appkey_here"
+   export AIKANSHE_BASE_URL="https://api.aikanshe.com"
+   ```
+2. 启动后端:`mvn spring-boot:run`
+3. 测试端点:`POST /api/tongue/diagnose/parse-preview`(上传舌象图片)
+4. 验证返回结构包含 `overall_assessment` 和 `indicators` 数组