# 快速开始
用沙箱密钥完成第一次评测,读出总分,维度分与逐字分数。
来源:https://open.shengzhiai.com/sdk/v2/quickstart/
## 准备工作
| 项 | 要求 |
|---|---|
| 密钥 | 开放平台签发的 appKey 与 secretKey。联调期间用沙箱密钥,每把每天 200 次,不扣套餐与余额,申请方式见[沙箱环境](https://open.shengzhiai.com/sdk/v2/sandbox/) |
| 音频 | 一段 1 秒以上的 WAV 录音,16 kHz,16 位,单声道。可以直接用[示例音频](https://open.shengzhiai.com/sdk/v2/spec/fixtures/audio/zh_short.wav),朗读的参考文本为 `今天天气很好` |
| 运行环境 | Java 11,安卓 5.0,iOS 13,Chrome 73,Node.js 20,微信基础库 `2.20.1`。Node.js 18 需要传入 `crypto` 选项,各端完整要求见[版本兼容](https://open.shengzhiai.com/sdk/v2/compatibility/) |
> 注意:secretKey 只放在接入方服务端或可信环境。网页,小程序与移动端联调时可以用签名,例如小程序写 `auth: { appKey, secretKey }`,正式上线改用 token,做法见[鉴权](https://open.shengzhiai.com/sdk/v2/authentication/)。
## 接入步骤
### Java
#### 五分钟快速开始
分三步执行。需要 JDK 11 或更高版本与 Maven 3.6 或更高版本,一段 3 秒左右的 16 kHz,16 位,单声道 WAV 录音,以及开放平台签发的 appKey 与 secretKey,联调期间用沙箱密钥,申请方式见 [`SANDBOX.md`](https://open.shengzhiai.com/sdk/v2/sandbox/)。
1. 新建工程目录 `yugu-quickstart`,在其中新建 `pom.xml`:
```xml
4.0.0
com.example
yugu-quickstart
1.0
11
UTF-8
shengzhiai
https://open.shengzhiai.com/maven/
com.shengzhiai.yugu
yugu-java-sdk
2.1.0
org.apache.maven.plugins
maven-compiler-plugin
3.13.0
org.codehaus.mojo
exec-maven-plugin
3.5.0
QuickStart
```
2. 新建 `src/main/java/QuickStart.java`:
```java
import com.shengzhiai.yugu.YuguClient;
import com.shengzhiai.yugu.errors.YuguException;
import com.shengzhiai.yugu.model.EvalResult;
import com.shengzhiai.yugu.model.EvaluateConfig;
import java.nio.file.Path;
public class QuickStart {
public static void main(String[] args) {
try (YuguClient client = YuguClient.builder()
.apiKey(System.getenv("YUGU_APP_KEY"), System.getenv("YUGU_SECRET_KEY"))
.build()) {
EvalResult r = client.evaluate(Path.of("audio.wav"),
new EvaluateConfig(EvaluateConfig.CORE_SENTENCE, "今天天气很好", "zh-CN"));
System.out.println("总分 " + r.getOverall());
System.out.println("发音 " + r.getDims().getPronunciation());
System.out.println("流利度 " + r.getDims().getFluency());
System.out.println("完整度 " + r.getDims().getIntegrity());
r.getWords().forEach(w -> System.out.println(w.getWord() + " " + w.getScores().getOverall()));
} catch (YuguException e) {
System.err.println(e.getCategory() + " " + e.getCode() + " " + e.getRawMessage());
}
}
}
```
3. 把录音放到工程目录,命名为 `audio.wav`,设置密钥后运行,控制台输出总分,分项与逐字分数:
```bash
YUGU_APP_KEY=沙箱appKey YUGU_SECRET_KEY=沙箱secretKey mvn -q compile exec:java
```
`demos/java-cli` 是同样流程的完整工程,带命令行参数,可直接运行。
### 安卓
#### 安装
在 `settings.gradle` 里加入优谷雅言 Maven 仓库:
```groovy
dependencyResolutionManagement {
repositories {
google()
mavenCentral()
maven { url "https://open.shengzhiai.com/maven/" }
}
}
```
在模块的 `build.gradle` 里声明依赖:
```groovy
dependencies {
implementation "com.shengzhiai.yugu:yugu-android-sdk:2.1.0"
}
```
Kotlin DSL 写法:
```kotlin
// settings.gradle.kts
dependencyResolutionManagement {
repositories {
google()
mavenCentral()
maven { url = uri("https://open.shengzhiai.com/maven/") }
}
}
// app/build.gradle.kts
dependencies {
implementation("com.shengzhiai.yugu:yugu-android-sdk:2.1.0")
}
```
工程仍在顶层 `build.gradle` 的 `allprojects` 里声明仓库时,把同一行 `maven { url "https://open.shengzhiai.com/maven/" }` 加进那里。
仓库里的每个版本发布后不再改动,依赖写成具体版本号即可锁定,需要回退时改回历史版本号。每个文件都附带 `.md5`,`.sha1`,`.sha256`,`.sha512` 校验和,另有源码包 `-sources.jar` 与接口文档包 `-javadoc.jar`。`1.x` 版本没有发布到 Maven 仓库,源码包仍可在 `https://open.shengzhiai.com/sdk/` 下载,已停止维护。
SDK 自带 R8 混淆保留规则,接入方不需要额外配置。
#### 权限
SDK 的清单文件已声明 `INTERNET`,构建时自动合并。使用录音器时,宿主应用需要声明录音权限:
```xml
```
Android 6.0 起录音权限需要在运行时申请:
```kotlin
if (Build.VERSION.SDK_INT >= 23 &&
checkSelfPermission(Manifest.permission.RECORD_AUDIO) != PackageManager.PERMISSION_GRANTED
) {
requestPermissions(arrayOf(Manifest.permission.RECORD_AUDIO), 1001)
}
```
把 `Context` 传给 `Recorder` 后,SDK 在开始录音前检查权限,没有权限时抛 `PermissionException`,错误码 90201。
#### 五分钟快速开始
第一步,创建客户端。整个应用共用一个实例即可。
```kotlin
val client = YuguClient.builder()
.auth(Auth.appKey("YOUR_APP_KEY", "YOUR_SECRET_KEY"))
.build()
```
第二步,准备一段 16 kHz,16 位,单声道的 WAV 音频,调用整段评测。REST 方法是阻塞调用,放在后台线程执行:
```kotlin
thread {
val result = client.evaluate(
EvaluateConfig(CoreType.SENTENCE, "今天天气很好", Language.ZH_CN),
File(filesDir, "sample.wav"),
)
Log.i("yugu", "总分 ${result.overall},发音 ${result.dimensions.pronunciation}")
}
```
也可以使用异步方法,回调默认在主线程执行,可以直接更新界面:
```kotlin
client.evaluateAsync(
EvaluateConfig(CoreType.SENTENCE, "今天天气很好", Language.ZH_CN),
AudioInput.fromFile(File(filesDir, "sample.wav")),
object : YuguCallback {
override fun onSuccess(result: EvalResult) {
scoreView.text = "总分 ${result.overall}"
}
override fun onFailure(error: YuguException) {
scoreView.text = "评测失败 ${error.code} ${error.message}"
}
},
)
```
第三步,应用退出或不再评测时关闭客户端:
```kotlin
client.close()
```
完整的可运行工程见 demos/android-demo,包含录音评测,示例音频评测与实时评测。
### iOS
#### 安装
##### Xcode 添加依赖
1. 在 Xcode 菜单 File 中选择 Add Package Dependencies。
2. 在搜索框输入 `https://open.shengzhiai.com/git/yugu-ios-sdk.git`。
3. Dependency Rule 选择 Up to Next Major Version,版本填 `2.1.0`。
4. 产品勾选 `YuguSDK`,点击 Add Package。
##### Package.swift 声明
```swift
// swift-tools-version:5.9
import PackageDescription
let package = Package(
name: "MyApp",
platforms: [.iOS(.v13)],
dependencies: [
.package(url: "https://open.shengzhiai.com/git/yugu-ios-sdk.git", from: "2.1.0"),
],
targets: [
.target(name: "MyApp", dependencies: [
.product(name: "YuguSDK", package: "yugu-ios-sdk"),
]),
]
)
```
包标识取仓库地址的最后一段,所以 `package:` 参数写 `yugu-ios-sdk`。
#### 麦克风权限
使用录音器的 App 必须在 Info.plist 中声明麦克风用途,缺少这一项时 iOS 在首次录音时终止 App。
```xml
NSMicrophoneUsageDescription
录制朗读音频,用于语音评测
```
macOS App 开启了沙盒时,另需在 entitlements 中打开 `com.apple.security.device.audio-input`。只评测已有音频时不需要麦克风权限。
#### 五分钟上手
```swift
import YuguSDK
// 创建客户端,App 内复用同一个实例
let client = YuguClient(options: YuguClientOptions(
auth: .appKey("", secretKey: "")))
// 评测一段 16 kHz 单声道 WAV
let config = EvaluateConfig(coreType: .sentence, referenceText: "今天天气很好", language: "zh-CN")
let result = try await client.evaluate(audio: .file(wavURL), config: config)
// 读取分数
print("总分", result.overall ?? 0)
print("流利度", result.dimensions.fluency ?? 0, "完整度", result.dimensions.integrity ?? 0)
for word in result.words {
print(word.word ?? "", word.overall ?? 0)
}
// 不再使用时释放
client.close()
```
不使用 `async` 时用完成回调写法,回调在 `callbackQueue` 上执行,缺省为主队列:
```swift
client.evaluate(audio: .file(wavURL), config: config) { outcome in
switch outcome {
case .success(let result): print(result.overall ?? 0)
case .failure(let error): print(error.category, error.code, error.message)
}
}
```
用麦克风录音再评测:
```swift
let recorder = YuguRecorder()
YuguRecorder.requestPermission { granted in
guard granted else { return }
try? recorder.start()
}
// 用户读完后
if let recording = recorder.stop() {
client.evaluate(audio: recording.audioInput, config: config) { outcome in
// 处理结果
}
}
recorder.release()
```
### 网页
#### 安装
##### npm 仓库安装
SDK 发布在优谷雅言自建 npm 仓库 `https://open.shengzhiai.com/npm/`。仓库公开读取,安装不需要账号或令牌。在项目根目录的 `.npmrc` 写入一行:
```ini
@shengzhiai:registry=https://open.shengzhiai.com/npm/
```
然后安装指定版本:
```bash
npm install @shengzhiai/yugu-web-sdk@2.1.0
```
`pnpm` 与 Yarn 1 读取同一个 `.npmrc`,Yarn 2 及以上版本在 `.yarnrc.yml` 的 `npmScopes` 里配置同一个地址。查看全部可用版本用 `npm view @shengzhiai/yugu-web-sdk versions`,回退到历史版本时把 `@2.1.0` 换成目标版本号。
##### script 标签引入
安装后的 `dist` 目录带有 UMD 构建,不需要打包工具。把 `node_modules/@shengzhiai/yugu-web-sdk/dist/yugu-sdk.umd.min.js` 复制到站点静态目录后引用,全局对象为 `YuguSDK`:
```html
```
#### 五分钟快速开始
1. 准备环境:Node.js 20 或更高版本,一段 3 秒左右的 16 kHz 单声道 WAV 录音,沙箱环境的 appKey 与 secretKey。沙箱密钥的申请方式与每日额度见 [`SANDBOX.md`](https://open.shengzhiai.com/sdk/v2/sandbox/),Node.js 18 的做法见 [Node.js 用法](https://open.shengzhiai.com/sdk/v2/sdks/web/#nodejs-用法)。
2. 新建工程,安装 SDK:
```bash
mkdir yugu-quickstart && cd yugu-quickstart
npm init -y
echo "@shengzhiai:registry=https://open.shengzhiai.com/npm/" > .npmrc
npm install @shengzhiai/yugu-web-sdk@2.1.0
```
3. 新建 `quickstart.mjs`:
```js
import { readFile } from 'node:fs/promises';
import { YuguClient } from '@shengzhiai/yugu-web-sdk';
const client = new YuguClient({
appKey: process.env.YUGU_APP_KEY,
secretKey: process.env.YUGU_SECRET_KEY,
});
const audio = await readFile(process.argv[2] || 'hello.wav');
const result = await client.evaluate(audio, {
coreType: 'sentence',
referenceText: '今天天气很好',
language: 'zh-CN',
});
console.log('总分', result.overall, '各维度', result.dims);
await client.close();
```
4. 运行脚本,查看分数:
```bash
YUGU_APP_KEY=沙箱appKey YUGU_SECRET_KEY=沙箱secretKey node quickstart.mjs hello.wav
```
5. 浏览器里试用时,在同一目录新建 `index.html`,用任意静态服务器打开,例如 `python3 -m http.server 8080` 后访问 `http://localhost:8080/`:
```html
```
包含录音,实时评测与结果展示的完整页面见仓库 `demos/web-demo` 目录。
### 小程序
#### 安装
在小程序工程的根目录,即 `project.config.json` 所在目录,执行:
```bash
echo "@shengzhiai:registry=https://open.shengzhiai.com/npm/" >> .npmrc
npm install @shengzhiai/yugu-miniprogram-sdk@2.1.0
```
工程里还没有 `package.json` 时先执行 `npm init -y`。npm 源不需要账号,已发布的版本不会被覆盖,退回历史版本时把版本号换成目标版本重新安装即可。
安装后在微信开发者工具中构建 npm:
1. 打开工程,点击菜单“工具”,选择“构建 npm”。
2. 构建完成后工程里出现 `miniprogram_npm/@shengzhiai/yugu-miniprogram-sdk` 目录。
3. 代码中按包名引用:
```js
const { YuguClient } = require('@shengzhiai/yugu-miniprogram-sdk');
```
`project.config.json` 设置了 `miniprogramRoot` 时,`package.json` 放在该目录下,或者在 `setting.packNpmRelationList` 里登记 `package.json` 与 `miniprogram_npm` 的位置。升级 SDK 后要重新构建 npm。
#### 合法域名
SDK 只通过 `wx.request` 与 `wx.connectSocket` 访问平台,上线前在小程序管理后台的“开发管理”,“开发设置”,“服务器域名”中配置:
| 类型 | 域名 |
|---|---|
| request 合法域名 | `https://open.shengzhiai.com` |
| socket 合法域名 | `wss://open.shengzhiai.com` |
SDK 2.0 不再使用 `wx.uploadFile`,不需要配置 uploadFile 合法域名。开发阶段可以在开发者工具的“详情”,“本地设置”里勾选“不校验合法域名,web-view,TLS 版本以及 HTTPS 证书”,真机预览与发布前要改回。
录音需要麦克风权限。在小程序管理后台的“用户隐私保护指引”中声明使用麦克风,首次录音时微信弹出授权框,用户拒绝后录音器报 `PermissionException`,错误码 90201。
#### 五分钟上手
整段评测:录一段音,上传评测,打印总分。
```js
const { YuguClient } = require('@shengzhiai/yugu-miniprogram-sdk');
const client = new YuguClient({
auth: { token: '<由自有服务端下发的短期 token>' },
});
const recorder = client.createRecorder();
Page({
onRecordStart() {
recorder.start();
},
async onRecordStop() {
const recording = await recorder.stop();
const result = await client.evaluate({
coreType: 'sentence',
referenceText: '今天天气很好',
language: 'zh-CN',
audio: recording,
});
console.log('总分', result.overall, '发音', result.dims.pronunciation, '流利', result.dims.fluency);
},
onUnload() {
client.close();
},
});
```
实时评测:录音帧直接推入会话,停止录音时自动结束会话。
```js
const session = client.streamEvaluate(
{ coreType: 'sentence', referenceText: '今天天气很好', language: 'zh-CN' },
{
onResult(result) { console.log('总分', result.overall); },
onError(err) { console.log('评测失败', err.code, err.message); },
},
);
recorder.pipeTo(session);
recorder.start();
// 用户读完后
recorder.stop();
```
### cURL
没有 SDK 的语言直接调用 REST 接口。签名用 HMAC-SHA256,`openssl` 一行即可算出,被签名参数与拼接规则见[签名与鉴权](https://open.shengzhiai.com/sdk/v2/api/authentication/)。
```bash
export YUGU_APP_KEY=沙箱appKey YUGU_SECRET_KEY=沙箱secretKey
curl -sSO https://open.shengzhiai.com/sdk/v2/spec/fixtures/audio/zh_short.wav && mv zh_short.wav audio.wav
```
在 `audio.wav` 所在目录执行:
```snippet
docs/site/snippets/evaluate.sh
```
## 返回结果
整段评测成功时直接返回结果对象,不包信封。常用字段如下,各评测模式的完整字段见[评测结果字段](https://open.shengzhiai.com/sdk/v2/api/results/)。
| 字段 | 含义 |
|---|---|
| `recordId` | 评测记录号,报告查询与问题排查使用 |
| `result.overall` | 总分,百分制。连读题型的总分在 `result.connected_overall` |
| `result.pronunciation`,`result.fluency`,`result.integrity` | 发音,流利度,完整度 |
| `result.tone`,`result.rear_tone` | 中文声调分与句末语调 |
| `result.words` | 逐字或逐词分数,含拼音,音素与起止时间,时间单位 10 毫秒 |
| `warnings` | 音频质量警告码,例如 1002 音量过低,评分照常返回 |
```json
{
"recordId": "eval_a31712f40cbf",
"eof": 1,
"result": {
"paragraphs": [],
"kernel_version": "1.0.0",
"resource_version": "1.0.0",
"overall": 88.9,
"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"
}
],
"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": []
}
]
}
],
"compositeReport": {
"compositeScore": 88.9,
"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": 89,
"toneScore": 100,
"completenessScore": 100,
"skillSuggest": "重音变化不够明显,关键词应当适度强调(音高提升 / 时长延长 / 加强气流)。",
"emotionSuggest": "第三声(上声)调值偏低。练习时走 214 曲线,先降再升。推荐练习『你好/美好/小狗』等词。",
"initialScore": 83.5,
"finalScore": 83.5
},
"yuguScores": {
"overall": 88.9,
"integrity": 100,
"accuracy": {
"overall": 100,
"tone": 100,
"nasal": 98,
"phoneme": 100,
"initial": 83.5,
"final": 83.5
},
"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
},
"initialScore": 83.5,
"finalScore": 83.5,
"nasalsScore": 98,
"nasals": 98,
"accuracy": 100,
"reading_skill": 78,
"emotion": 76
},
"report": {
"dimensionSuggestions": {
"integrity": [],
"accuracy": [],
"fluency": [],
"reading_skill": [
"重音变化不够明显,关键词应当适度强调(音高提升 / 时长延长 / 加强气流)。",
"先标出停连位置、句子重音和语调走向,再按标记朗读并回听节奏是否清楚。"
],
"emotion": [
"第三声(上声)调值偏低。练习时走 214 曲线,先降再升。推荐练习『你好/美好/小狗』等词。",
"先判断语句的情绪基调,选定符合语义的表达方式朗读;录音回听情感是否与内容一致。"
]
},
"dimensionScores": {
"accuracy": 100,
"fluency": 96,
"integrity": 100,
"reading_skill": 78,
"affect": 76,
"speechRate": 85,
"readSpeedRaw": 225
},
"dimensionEvidence": {
"accuracy": [
{
"word": "很",
"type": "pitchLow",
"detail": "声调 1 分(低于 60)"
}
],
"fluency": [],
"integrity": [],
"affect": [],
"speechRate": []
},
"rubricVersion": "v20260707b",
"scores": {
"compositeScore": 88.9
},
"dimensions": {
"accuracy": "声调:整句调型判定 100 分;其中“很”(字级调型 1 分)的调型与标准读音有偏差,需对照标准音重点纠正,其余字词调型整体稳定。",
"reading_skill": "停连、重音、语调和节奏基本可控,细节仍可加强。",
"emotion": "情感表达基本到位,语气起伏与文本内容大体匹配,变化幅度还可以更明显。"
}
},
"standardAudio": {},
"asrText": {},
"warnings": []
}
```
## 下一步
- [实时评测](https://open.shengzhiai.com/sdk/v2/guides/streaming/):边录边传的会话,状态机,心跳与断线重连
- [错误处理](https://open.shengzhiai.com/sdk/v2/guides/errors/):错误类别,异常类型与可重试判定
- [鉴权](https://open.shengzhiai.com/sdk/v2/authentication/):签名与 token 两种方式,密钥存放位置
- [上线检查清单](https://open.shengzhiai.com/sdk/v2/guides/production/):从沙箱切到生产之前逐项核对