# 声通兼容整段评测 路径与参数名沿用声通命名,返回声通风格的结果。 来源:https://open.shengzhiai.com/sdk/v2/api/evaluate-compat/ `POST https://open.shengzhiai.com/{coreType}` ## 请求示例 cURL: ```bash # 声通兼容整段评测。被签名参数为全部文本表单字段,按键名排序 REF_TEXT='今天天气很好' TS=$(date +%s) NONCE=$(openssl rand -hex 16) SIGN=$(printf 'language=zh-CN&refText=%s' "$REF_TEXT" | openssl dgst -sha256 -hmac "$YUGU_SECRET_KEY" -binary | base64) curl -sS https://open.shengzhiai.com/sent.eval.cn \ -H "X-App-Key: $YUGU_APP_KEY" \ -H "X-Timestamp: $TS" \ -H "X-Nonce: $NONCE" \ -H "X-Signature: $SIGN" \ -H "Idempotency-Key: $(openssl rand -hex 16)" \ -F "audio=@audio.wav" \ -F "refText=$REF_TEXT" \ -F "language=zh-CN" ``` 安卓平替: ```java SkEgnManager manager = SkEgnManager.getInstance(context); EngineSetting setting = EngineSetting.getInstance(context); setting.setOnInitEngineListener(initListener); manager.initEngine("优谷雅言 appKey", "优谷雅言 secretKey", userId, setting); ``` iOS 平替: ```swift let engine = KYTestEngine.sharedInstance()! let config = KYStartEngineConfig() config.appKey = "优谷雅言 appKey" config.secretKey = "优谷雅言 secretKey" engine.initEngine(KY_CloudEngine, startEngineConfig: config) { ok, message in print(ok, message ?? "") } let test = KYTestConfig() test.coreTypeNS = "sent.eval" test.refText = "How are you" let tokenId = engine.start(with: test, result: { json in print(json ?? "") }) { ok, str in print(ok, str ?? "") } engine.stop() engine.delete() ``` ## 返回示例 ```json { "recordId": "eval_9cd006ba7b68", "result": { "paragraphs": [], "kernel_version": "1.0.0", "resource_version": "1.0.0", "overall": 94.6, "pronunciation": 100, "tone": 83, "fluency": 96, "rhythm": 78, "integrity": 100, "speed": 225, "rear_tone": "fall", "duration": "1.920", "numeric_duration": 1.92, "warning": [], "words": [ { "word": "今", "pinyin": "jin", "rawpinyin": "jin1", "symbolpinyin": "jīn", "charType": 0, "readType": 0, "tone": "tone1", "scores": { "overall": 78, "pronunciation": 78, "tone": 100, "overall_pron": 78, "prominence": 0 }, "span": { "start": 15, "end": 31 }, "pause": { "type": 0, "duration": 0 }, "phonemes": [ { "phoneme": "J", "phone": "j", "category": 0, "pronunciation": 78, "tone_index": "0", "span": { "start": 15, "end": 23 } }, { "phoneme": "IN", "phone": "in", "category": 1, "pronunciation": 78, "tone_index": "1", "span": { "start": 23, "end": 31 } } ], "normalized_syllables": [ { "syllables": "今", "pinyin": "jin", "tone": "tone1", "tone_sandhi": "tone1", "phoneme_span": [ 0, 1 ] } ], "word_parts": [ { "part": "今", "charType": 0, "beginIndex": 0, "endIndex": 0 } ], "phonics": [], "linkable": false, "syllables": [], "evidence": { "scored": false, "rms_db": -32.7, "rel_db": -0.5, "dur_ms": 160, "dur_ratio": 0.8, "sfgop": 0.625 }, "readStatus": "correct", "read_status": "correct" }, { "word": "天", "pinyin": "tian", "rawpinyin": "tian1", "symbolpinyin": "tiān", "charType": 0, "readType": 0, "tone": "tone1", "scores": { "overall": 95, "pronunciation": 95, "tone": 100, "overall_pron": 95, "prominence": 0 }, "span": { "start": 31, "end": 57 }, "pause": { "type": 0, "duration": 0 }, "phonemes": [ { "phoneme": "T", "phone": "t", "category": 0, "pronunciation": 95, "tone_index": "0", "span": { "start": 31, "end": 43 } }, { "phoneme": "IAN", "phone": "ian", "category": 1, "pronunciation": 95, "tone_index": "1", "span": { "start": 43, "end": 55 } } ], "normalized_syllables": [ { "syllables": "天", "pinyin": "tian", "tone": "tone1", "tone_sandhi": "tone1", "phoneme_span": [ 0, 1 ] } ], "word_parts": [ { "part": "天", "charType": 0, "beginIndex": 0, "endIndex": 0 } ], "phonics": [], "linkable": false, "syllables": [], "evidence": { "scored": false, "rms_db": -31.8, "rel_db": 0.5, "dur_ms": 240, "dur_ratio": 1.2, "sfgop": 0.917 }, "readStatus": "correct", "read_status": "correct" }, { "word": "天", "pinyin": "tian", "rawpinyin": "tian1", "symbolpinyin": "tiān", "charType": 0, "readType": 0, "tone": "tone1", "scores": { "overall": 85, "pronunciation": 85, "tone": 100, "overall_pron": 85, "prominence": 0 }, "span": { "start": 57, "end": 71 }, "pause": { "type": 0, "duration": 0 }, "phonemes": [ { "phoneme": "T", "phone": "t", "category": 0, "pronunciation": 85, "tone_index": "0", "span": { "start": 57, "end": 64 } }, { "phoneme": "IAN", "phone": "ian", "category": 1, "pronunciation": 85, "tone_index": "1", "span": { "start": 64, "end": 71 } } ], "normalized_syllables": [ { "syllables": "天", "pinyin": "tian", "tone": "tone1", "tone_sandhi": "tone1", "phoneme_span": [ 0, 1 ] } ], "word_parts": [ { "part": "天", "charType": 0, "beginIndex": 0, "endIndex": 0 } ], "phonics": [], "linkable": false, "syllables": [], "evidence": { "scored": false, "rms_db": -34, "rel_db": -1.7, "dur_ms": 140, "dur_ratio": 0.7, "sfgop": 0.75 }, "readStatus": "correct", "read_status": "correct" }, { "word": "气", "pinyin": "qi", "rawpinyin": "qi4", "symbolpinyin": "qì", "charType": 0, "readType": 0, "tone": "tone4", "scores": { "overall": 76, "pronunciation": 76, "tone": 100, "overall_pron": 76, "prominence": 0 }, "span": { "start": 71, "end": 91 }, "pause": { "type": 0, "duration": 0 }, "phonemes": [ { "phoneme": "Q", "phone": "q", "category": 0, "pronunciation": 76, "tone_index": "0", "span": { "start": 71, "end": 81 } }, { "phoneme": "I", "phone": "i", "category": 1, "pronunciation": 76, "tone_index": "4", "span": { "start": 81, "end": 91 } } ], "normalized_syllables": [ { "syllables": "气", "pinyin": "qi", "tone": "tone4", "tone_sandhi": "tone4", "phoneme_span": [ 0, 1 ] } ], "word_parts": [ { "part": "气", "charType": 0, "beginIndex": 0, "endIndex": 0 } ], "phonics": [], "linkable": false, "syllables": [], "evidence": { "scored": false, "rms_db": -35, "rel_db": -2.7, "dur_ms": 200, "dur_ratio": 1, "sfgop": 0.6 }, "readStatus": "correct", "read_status": "correct" }, { "word": "很", "pinyin": "hen", "rawpinyin": "hen3", "symbolpinyin": "hěn", "charType": 0, "readType": 0, "tone": "tone3", "scores": { "overall": 94, "pronunciation": 94, "tone": 1, "overall_pron": 94, "prominence": 0 }, "span": { "start": 91, "end": 111 }, "pause": { "type": 0, "duration": 0 }, "phonemes": [ { "phoneme": "H", "phone": "h", "category": 0, "pronunciation": 94, "tone_index": "0", "span": { "start": 91, "end": 101 } }, { "phoneme": "EN", "phone": "en", "category": 1, "pronunciation": 94, "tone_index": "3", "span": { "start": 101, "end": 111 } } ], "normalized_syllables": [ { "syllables": "很", "pinyin": "hen", "tone": "tone3", "tone_sandhi": "tone2", "phoneme_span": [ 0, 1 ] } ], "word_parts": [ { "part": "很", "charType": 0, "beginIndex": 0, "endIndex": 0 } ], "phonics": [], "linkable": false, "syllables": [], "evidence": { "scored": false, "rms_db": -30.8, "rel_db": 1.4, "dur_ms": 200, "dur_ratio": 1, "sfgop": 0.9 }, "readStatus": "correct", "read_status": "correct" }, { "word": "好", "pinyin": "hao", "rawpinyin": "hao3", "symbolpinyin": "hǎo", "charType": 0, "readType": 0, "tone": "tone3", "scores": { "overall": 73, "pronunciation": 73, "tone": 100, "overall_pron": 73, "prominence": 0 }, "span": { "start": 111, "end": 155 }, "pause": { "type": 0, "duration": 0 }, "phonemes": [ { "phoneme": "H", "phone": "h", "category": 0, "pronunciation": 73, "tone_index": "0", "span": { "start": 111, "end": 133 } }, { "phoneme": "AO", "phone": "ao", "category": 1, "pronunciation": 73, "tone_index": "3", "span": { "start": 133, "end": 155 } } ], "normalized_syllables": [ { "syllables": "好", "pinyin": "hao", "tone": "tone3", "tone_sandhi": "tone3", "phoneme_span": [ 0, 1 ] } ], "word_parts": [ { "part": "好", "charType": 0, "beginIndex": 0, "endIndex": 0 } ], "phonics": [], "linkable": false, "syllables": [], "evidence": { "scored": false, "rms_db": -20.3, "rel_db": 12, "dur_ms": 445, "dur_ratio": 2.225, "sfgop": 0.545 }, "readStatus": "correct", "read_status": "correct" } ], "sentences": [ { "sentence": "今天天气很好", "index": 0, "scores": { "overall": 89, "pronunciation": 100, "fluency": 96, "integrity": 100 }, "details": [ { "word": "今", "pinyin": "jin", "rawpinyin": "jin1", "symbolpinyin": "jīn", "charType": 0, "readType": 0, "tone": "tone1", "scores": { "overall": 78, "pronunciation": 78, "tone": 100, "overall_pron": 78, "prominence": 0 }, "span": { "start": 15, "end": 31 }, "pause": { "type": 0, "duration": 0 }, "phonemes": [ { "phoneme": "J", "phone": "j", "category": 0, "pronunciation": 78, "tone_index": "0", "span": { "start": 15, "end": 23 } }, { "phoneme": "IN", "phone": "in", "category": 1, "pronunciation": 78, "tone_index": "1", "span": { "start": 23, "end": 31 } } ], "normalized_syllables": [ { "syllables": "今", "pinyin": "jin", "tone": "tone1", "tone_sandhi": "tone1", "phoneme_span": [ 0, 1 ] } ], "word_parts": [ { "part": "今", "charType": 0, "beginIndex": 0, "endIndex": 0 } ], "phonics": [], "linkable": false, "syllables": [] }, { "word": "天", "pinyin": "tian", "rawpinyin": "tian1", "symbolpinyin": "tiān", "charType": 0, "readType": 0, "tone": "tone1", "scores": { "overall": 95, "pronunciation": 95, "tone": 100, "overall_pron": 95, "prominence": 0 }, "span": { "start": 31, "end": 57 }, "pause": { "type": 0, "duration": 0 }, "phonemes": [ { "phoneme": "T", "phone": "t", "category": 0, "pronunciation": 95, "tone_index": "0", "span": { "start": 31, "end": 43 } }, { "phoneme": "IAN", "phone": "ian", "category": 1, "pronunciation": 95, "tone_index": "1", "span": { "start": 43, "end": 55 } } ], "normalized_syllables": [ { "syllables": "天", "pinyin": "tian", "tone": "tone1", "tone_sandhi": "tone1", "phoneme_span": [ 0, 1 ] } ], "word_parts": [ { "part": "天", "charType": 0, "beginIndex": 0, "endIndex": 0 } ], "phonics": [], "linkable": false, "syllables": [] }, { "word": "天", "pinyin": "tian", "rawpinyin": "tian1", "symbolpinyin": "tiān", "charType": 0, "readType": 0, "tone": "tone1", "scores": { "overall": 85, "pronunciation": 85, "tone": 100, "overall_pron": 85, "prominence": 0 }, "span": { "start": 57, "end": 71 }, "pause": { "type": 0, "duration": 0 }, "phonemes": [ { "phoneme": "T", "phone": "t", "category": 0, "pronunciation": 85, "tone_index": "0", "span": { "start": 57, "end": 64 } }, { "phoneme": "IAN", "phone": "ian", "category": 1, "pronunciation": 85, "tone_index": "1", "span": { "start": 64, "end": 71 } } ], "normalized_syllables": [ { "syllables": "天", "pinyin": "tian", "tone": "tone1", "tone_sandhi": "tone1", "phoneme_span": [ 0, 1 ] } ], "word_parts": [ { "part": "天", "charType": 0, "beginIndex": 0, "endIndex": 0 } ], "phonics": [], "linkable": false, "syllables": [] }, { "word": "气", "pinyin": "qi", "rawpinyin": "qi4", "symbolpinyin": "qì", "charType": 0, "readType": 0, "tone": "tone4", "scores": { "overall": 76, "pronunciation": 76, "tone": 100, "overall_pron": 76, "prominence": 0 }, "span": { "start": 71, "end": 91 }, "pause": { "type": 0, "duration": 0 }, "phonemes": [ { "phoneme": "Q", "phone": "q", "category": 0, "pronunciation": 76, "tone_index": "0", "span": { "start": 71, "end": 81 } }, { "phoneme": "I", "phone": "i", "category": 1, "pronunciation": 76, "tone_index": "4", "span": { "start": 81, "end": 91 } } ], "normalized_syllables": [ { "syllables": "气", "pinyin": "qi", "tone": "tone4", "tone_sandhi": "tone4", "phoneme_span": [ 0, 1 ] } ], "word_parts": [ { "part": "气", "charType": 0, "beginIndex": 0, "endIndex": 0 } ], "phonics": [], "linkable": false, "syllables": [] }, { "word": "很", "pinyin": "hen", "rawpinyin": "hen3", "symbolpinyin": "hěn", "charType": 0, "readType": 0, "tone": "tone3", "scores": { "overall": 94, "pronunciation": 94, "tone": 1, "overall_pron": 94, "prominence": 0 }, "span": { "start": 91, "end": 111 }, "pause": { "type": 0, "duration": 0 }, "phonemes": [ { "phoneme": "H", "phone": "h", "category": 0, "pronunciation": 94, "tone_index": "0", "span": { "start": 91, "end": 101 } }, { "phoneme": "EN", "phone": "en", "category": 1, "pronunciation": 94, "tone_index": "3", "span": { "start": 101, "end": 111 } } ], "normalized_syllables": [ { "syllables": "很", "pinyin": "hen", "tone": "tone3", "tone_sandhi": "tone2", "phoneme_span": [ 0, 1 ] } ], "word_parts": [ { "part": "很", "charType": 0, "beginIndex": 0, "endIndex": 0 } ], "phonics": [], "linkable": false, "syllables": [] }, { "word": "好", "pinyin": "hao", "rawpinyin": "hao3", "symbolpinyin": "hǎo", "charType": 0, "readType": 0, "tone": "tone3", "scores": { "overall": 73, "pronunciation": 73, "tone": 100, "overall_pron": 73, "prominence": 0 }, "span": { "start": 111, "end": 155 }, "pause": { "type": 0, "duration": 0 }, "phonemes": [ { "phoneme": "H", "phone": "h", "category": 0, "pronunciation": 73, "tone_index": "0", "span": { "start": 111, "end": 133 } }, { "phoneme": "AO", "phone": "ao", "category": 1, "pronunciation": 73, "tone_index": "3", "span": { "start": 133, "end": 155 } } ], "normalized_syllables": [ { "syllables": "好", "pinyin": "hao", "tone": "tone3", "tone_sandhi": "tone3", "phoneme_span": [ 0, 1 ] } ], "word_parts": [ { "part": "好", "charType": 0, "beginIndex": 0, "endIndex": 0 } ], "phonics": [], "linkable": false, "syllables": [] } ] } ], "compositeReport": { "compositeScore": 94.6, "integrityScore": 100, "accuracyScore": 100, "toneVoiceScore": 83, "nasalsScore": 98, "pronunciationScore": 100, "phonemeScore": 100, "fluencyScore": 96, "fluentScore": 96, "readSpeedScore": 85, "readSpeed": 225, "skillScore": 78, "stopConnScore": 85, "stressScore": 32, "intonationScore": 100, "emotionScore": 76, "literalTotal": 95, "toneScore": 100, "completenessScore": 100, "skillSuggest": "重音变化不够明显,关键词应当适度强调(音高提升 / 时长延长 / 加强气流)。", "emotionSuggest": "第三声(上声)调值偏低。练习时走 214 曲线,先降再升。推荐练习『你好/美好/小狗』等词。" }, "yuguScores": { "overall": 88.9, "integrity": 100, "accuracy": { "overall": 100, "tone": 100, "nasal": 98, "phoneme": 100 }, "fluency": { "overall": 96, "speed_score": 85, "naturalness": 100 }, "reading_skill": { "overall": 78, "pause": 85, "stress": 32, "intonation": 100 }, "prosody": 78, "emotion": 76, "tone": 83, "rear_tone": "fall", "speed": 225, "duration_s": 1.92 }, "accuracy": 100, "reading_skill": 78 }, "audioUrl": "https://open.shengzhiai.com/rec/20261008/eval_9cd006ba7b68-7ea7c9bb6dfe7b5cde9e7fccd7ab3cf6.wav", "eof": 1 } ``` ## 错误示例 ```json { "code": 40001, "message": "coreType=pinyin 时 refPinyin 必填(如 \"chong2 qing4\")", "timestamp": 1791447692255 } ``` `multipart/form-data` 请求,`audio` 为文件段,业务参数为文本段,字段名沿用声通命名。另可带文本段 `request`,内容为 JSON,其顶层标量字段并入业务参数。兼容接口必须带 `X-App-Key`,只接受签名鉴权,被签名参数为实际发送的全部文本表单字段,音频不参与。 ## 路径参数 | 参数 | 类型 | 必填 | 说明 | |---|---|---|---| | `coreType` | string | 是 | `word.eval`,`word.eval.pro`,`sent.eval`,`sent.eval.pro`,`para.eval`,`alpha.eval`,`word.eval.cn`,`sent.eval.cn`,`para.eval.cn`,`pinyin`,`open.eval.cn` | ## 表单字段 | 字段 | 类型 | 必填 | 说明 | |---|---|---|---| | `audio` | 文件 | 是 | 音频文件,建议 WAV,PCM 16 位,16 kHz,单声道 | | `refText` | string | 否 | 参考文本。英文题必填,中文题设置了 `refPinyin` 时可以为空。`open.eval.cn` 必填,填用竖线隔开的参考答案或题目 | | `language` | string | 否 | 语种,例如 `zh-CN`,`en-US` | | `refPinyin` | string | 否 | 拼音,pinyin 题必填,例如 `chong2 qing4` | | `agegroup` | string | 否 | 年龄段,`1` 学前,`2` 小学,`3` 中学及以上 | | `scale` | string | 否 | 分制,1 到 100 | | `precision` | string | 否 | 精度,大于 0 到 1 | | `slack` | string | 否 | 松紧度,-1 到 1 | | `paragraph_need_word_score` | string | 否 | 段落题是否返回逐字或逐词详情,`1` 或 `0` | | `phoneme_output` | string | 否 | 音素级输出,`1` 或 `0` | | `attachAudioUrl` | string | 否 | `1` 时返回体顶层带录音下载地址 `audioUrl`,保留 7 天 | | `dict_type`,`dict_dialect`,`customized_lexicon`,`customized_pron` | string | 否 | 词典与自定义发音,原样传给评测引擎,`dict_dialect` 取 `en_br` 或 `en_us` | | `output_rawtext` | string | 否 | 原文输出,`1` 或 `0` | | `readtype_diagnosis` | string | 否 | `1` 时 `words` 另含增读与重复读,默认只含参考文本里的字词 | | `qType` | string | 否 | 只用于 `open.eval.cn`,`5` 看图说话,`6` 情景问答,其他取值或不带时为自由表达 | | `taskType` | string | 否 | 只用于 `open.eval.cn`,`picture`,`situational` 或 `free`,带了就不看 `qType` | | `keypoints`,`keywords` | string | 否 | 只用于 `open.eval.cn`,采分点,JSON 数组或用竖线隔开,两项合计最多 20 个 | | `request` | string | 否 | JSON 文本,顶层标量字段并入业务参数 | | `timing` | string | 否 | `1` 时结果顶层附 `timing`,见下方分段耗时 | ## 返回 成功时返回声通风格结果 `{"recordId": ..., "eof": 1, "result": {...}}`,`result` 内的字段与[原生整段评测](https://open.shengzhiai.com/sdk/v2/api/evaluate/)一致,段落题按 `paragraph_need_word_score` 决定是否带逐词详情。请求带 `attachAudioUrl=1` 时顶层另有 `audioUrl`,为录音下载地址,保留 7 天,同一个幂等键重放时地址不变。兼容接口不返回示范音,服务端也不合成。固定内容题型的 `words` 只含参考文本里的字词,请求带 `readtype_diagnosis=1` 时另含增读与重复读,`readType` 分别为 1 与 3。 `open.eval.cn` 是中文开放题,与原生 `coreType` 为 `open` 的开放题用同一套评分,语言固定为中文。`refText` 与声通的用法相同,可以填一条或多条参考答案,多条用竖线隔开,也可以填题目或任务提示,由评分模型判断是哪一种。是参考答案时,作答与任意一条意思一致就算答对,不要求逐字相同,作答简短不扣分,复述参考答案也不按念题处理,意思不同或答非所问时总分不超过 45。是题目时与原生开放题的评分相同。`qType` 为 5 时按看图说话评,为 6 时按情景问答评,其他取值或不带时按自由表达评,也可以直接带 `taskType`。兼容接口不收图片,看图说话按自由表达的细则评分,`openTaskAudit.pictureUngrounded` 为 true。`keypoints` 与 `keywords` 是采分点,写成 JSON 数组或用竖线隔开,合计最多 20 个,评分时参考,也用来提高这些词的识别率,参考答案不用来提高识别率。`negative_keypoints` 与 `keypoints_weight` 不参与评分。`result` 含原生开放题的全部字段,`openTaskAudit.refKind` 为 `answers` 或 `question`,是评分模型的判断。另有与声通相同的扁平字段:`pronunciation` 与 `fluency` 取自 `delivery`,`integrity` 取自 `content.task_achievement`,`coherence` 取自 `content.coherence`,`speed` 为每分钟字数。没有 `words` 与 `sentences`。实时评测不下发朗读进度,带 `realtime_feedback` 时中间帧只有 `bytes`。 状态码与[原生整段评测](https://open.shengzhiai.com/sdk/v2/api/evaluate/#状态码)相同,没有 415。 ## 分段耗时 兼容接口的 REST 响应头带 `Server-Timing: total;dur=5321, engine;dur=4100, platform;dur=1221`,单位毫秒。`total` 从服务端开始处理已收到的请求算起,到结果备好为止,`engine` 是评测引擎这一段,`platform` 是其余部分。 请求带 `timing=1` 时,结果顶层另有 `timing` 对象,REST 用文本段,实时评测写在参数帧里,见[声通兼容实时评测](https://open.shengzhiai.com/sdk/v2/api/ws-compat/): ```json "timing": {"receivedAt": 1791800000123, "totalMs": 5321, "engineMs": 4100, "platformMs": 1221, "engineStages": {"text_frontend_ms": 1909.3, "asr_ms": 595.0}, "audioBytes": 528000, "wsFirstAudioAt": 1791799990000} ``` - `receivedAt` 是服务端开始处理的时刻,毫秒时间戳。REST 为请求体收完时,实时评测为收到结束帧时。 - `engineStages` 是引擎各环节的耗时,键名随引擎版本变化,可能缺省。 - `audioBytes` 是服务端收到的音频字节数。 - `wsFirstAudioAt` 只在实时评测出现,是这一轮第一个音频帧到达服务端的时刻。 - 不带 `timing=1` 时结果不变。错误帧不带 `timing`,重放结果带首次评测的 `timing`。客户端应忽略不认识的键。