Skip to content

feat: 实现非实时语音识别与热词管理 - #212

Closed
andywu188 wants to merge 1 commit into
cnblogs:mainfrom
andywu188:cursor/speech-asr-vocabulary-6580
Closed

andywu188 wants to merge 1 commit into
cnblogs:mainfrom
andywu188:cursor/speech-asr-vocabulary-6580

Conversation

@andywu188

Copy link
Copy Markdown

非实时语音识别:异步文件转写(Paraformer / Fun-ASR)、Fun-ASR-Flash 同步 / SSE、speech-biasing 热词 CRUD
配套 Sample、RawHttp 快照单测,以及 EN / ZH README 说明

Copilot AI lite review requested due to automatic review settings September 20, 2026 08:12

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

🟡 Changes recommended

The client creates unmanaged HttpClient instances per core instance, risking handler and socket accumulation.

Get a fresh assessment by requesting another Copilot review.

Review effort: Lite
Findings: 1 High severity

Open (1)
What changed in this PR

Adds non-real-time speech transcription, Flash recognition, speech vocabulary CRUD APIs, tests, samples, and bilingual documentation.

Changes:

  • Added speech recognition, transcription, and vocabulary APIs/models.
  • Added serialization tests and raw HTTP fixtures.
  • Added samples and EN/ZH README guidance.
File Summary
test/​Cnblogs.DashScope.Tests.Shared/​Utils/​Sut.cs Test client utilities
test/​Cnblogs.DashScope.Tests.Shared/​Utils/​Snapshots.Speech.cs Speech snapshots
test/​Cnblogs.DashScope.Tests.Shared/​RawHttpData/​speech-vocabulary-update-nosse.response.header.txt Vocabulary update response headers
test/​Cnblogs.DashScope.Tests.Shared/​RawHttpData/​speech-vocabulary-update-nosse.response.body.txt Vocabulary update response
test/​Cnblogs.DashScope.Tests.Shared/​RawHttpData/​speech-vocabulary-update-nosse.request.header.txt Vocabulary update request headers
test/​Cnblogs.DashScope.Tests.Shared/​RawHttpData/​speech-vocabulary-update-nosse.request.body.json Vocabulary update request
test/​Cnblogs.DashScope.Tests.Shared/​RawHttpData/​speech-vocabulary-query-nosse.response.header.txt Vocabulary query response headers
test/​Cnblogs.DashScope.Tests.Shared/​RawHttpData/​speech-vocabulary-query-nosse.response.body.txt Vocabulary query response
test/​Cnblogs.DashScope.Tests.Shared/​RawHttpData/​speech-vocabulary-query-nosse.request.header.txt Vocabulary query request headers
test/​Cnblogs.DashScope.Tests.Shared/​RawHttpData/​speech-vocabulary-query-nosse.request.body.json Vocabulary query request
test/​Cnblogs.DashScope.Tests.Shared/​RawHttpData/​speech-vocabulary-list-nosse.response.header.txt Vocabulary list response headers
test/​Cnblogs.DashScope.Tests.Shared/​RawHttpData/​speech-vocabulary-list-nosse.response.body.txt Vocabulary list response
test/​Cnblogs.DashScope.Tests.Shared/​RawHttpData/​speech-vocabulary-list-nosse.request.header.txt Vocabulary list request headers
test/​Cnblogs.DashScope.Tests.Shared/​RawHttpData/​speech-vocabulary-list-nosse.request.body.json Vocabulary list request
test/​Cnblogs.DashScope.Tests.Shared/​RawHttpData/​speech-vocabulary-delete-nosse.response.header.txt Vocabulary delete response headers
test/​Cnblogs.DashScope.Tests.Shared/​RawHttpData/​speech-vocabulary-delete-nosse.response.body.txt Vocabulary delete response
test/​Cnblogs.DashScope.Tests.Shared/​RawHttpData/​speech-vocabulary-delete-nosse.request.header.txt Vocabulary delete request headers
test/​Cnblogs.DashScope.Tests.Shared/​RawHttpData/​speech-vocabulary-delete-nosse.request.body.json Vocabulary delete request
test/​Cnblogs.DashScope.Tests.Shared/​RawHttpData/​speech-vocabulary-create-nosse.response.header.txt Vocabulary create response headers
test/​Cnblogs.DashScope.Tests.Shared/​RawHttpData/​speech-vocabulary-create-nosse.response.body.txt Vocabulary create response
test/​Cnblogs.DashScope.Tests.Shared/​RawHttpData/​speech-vocabulary-create-nosse.request.header.txt Vocabulary create request headers
test/​Cnblogs.DashScope.Tests.Shared/​RawHttpData/​speech-vocabulary-create-nosse.request.body.json Vocabulary create request
test/​Cnblogs.DashScope.Tests.Shared/​RawHttpData/​speech-transcription-result-nosse.response.header.txt Transcription result response headers
test/​Cnblogs.DashScope.Tests.Shared/​RawHttpData/​speech-transcription-result-nosse.response.body.txt Transcription result response
test/​Cnblogs.DashScope.Tests.Shared/​RawHttpData/​speech-transcription-result-nosse.request.header.txt Transcription result request headers
test/​Cnblogs.DashScope.Tests.Shared/​RawHttpData/​speech-transcription-result-nosse.request.body.json Transcription result request
test/​Cnblogs.DashScope.Tests.Shared/​RawHttpData/​speech-transcription-get-task-nosse.response.header.txt Transcription task response headers
test/​Cnblogs.DashScope.Tests.Shared/​RawHttpData/​speech-transcription-get-task-nosse.response.body.txt Transcription task response
test/​Cnblogs.DashScope.Tests.Shared/​RawHttpData/​speech-transcription-get-task-nosse.request.header.txt Transcription task request headers
test/​Cnblogs.DashScope.Tests.Shared/​RawHttpData/​speech-transcription-get-task-nosse.request.body.json Transcription task request
test/​Cnblogs.DashScope.Tests.Shared/​RawHttpData/​speech-transcription-create-oss-nosse.response.header.txt OSS transcription response headers
test/​Cnblogs.DashScope.Tests.Shared/​RawHttpData/​speech-transcription-create-oss-nosse.response.body.txt OSS transcription response
test/​Cnblogs.DashScope.Tests.Shared/​RawHttpData/​speech-transcription-create-oss-nosse.request.header.txt OSS transcription request headers
test/​Cnblogs.DashScope.Tests.Shared/​RawHttpData/​speech-transcription-create-oss-nosse.request.body.json OSS transcription request
test/​Cnblogs.DashScope.Tests.Shared/​RawHttpData/​speech-transcription-create-nosse.response.header.txt Transcription creation response headers
test/​Cnblogs.DashScope.Tests.Shared/​RawHttpData/​speech-transcription-create-nosse.response.body.txt Transcription creation response
test/​Cnblogs.DashScope.Tests.Shared/​RawHttpData/​speech-transcription-create-nosse.request.header.txt Transcription creation request headers
test/​Cnblogs.DashScope.Tests.Shared/​RawHttpData/​speech-transcription-create-nosse.request.body.json Transcription creation request
test/​Cnblogs.DashScope.Tests.Shared/​RawHttpData/​speech-recognition-flash-sse.response.header.txt Flash SSE response headers
test/​Cnblogs.DashScope.Tests.Shared/​RawHttpData/​speech-recognition-flash-sse.response.body.txt Flash SSE response
test/​Cnblogs.DashScope.Tests.Shared/​RawHttpData/​speech-recognition-flash-sse.request.header.txt Flash SSE request headers
test/​Cnblogs.DashScope.Tests.Shared/​RawHttpData/​speech-recognition-flash-sse.request.body.json Flash SSE request
test/​Cnblogs.DashScope.Tests.Shared/​RawHttpData/​speech-recognition-flash-nosse.response.header.txt Flash response headers
test/​Cnblogs.DashScope.Tests.Shared/​RawHttpData/​speech-recognition-flash-nosse.response.body.txt Flash response
test/​Cnblogs.DashScope.Tests.Shared/​RawHttpData/​speech-recognition-flash-nosse.request.header.txt Flash request headers
test/​Cnblogs.DashScope.Tests.Shared/​RawHttpData/​speech-recognition-flash-nosse.request.body.json Flash request
test/​Cnblogs.DashScope.Sdk.UnitTests/​SpeechVocabularySerializationTests.cs Vocabulary serialization tests
test/​Cnblogs.DashScope.Sdk.UnitTests/​SpeechTranscriptionSerializationTests.cs Transcription serialization tests
test/​Cnblogs.DashScope.Sdk.UnitTests/​SpeechRecognitionSerializationTests.cs Recognition serialization tests
src/​Cnblogs.DashScope.Core/​SpeechVocabularyOutput.cs Vocabulary output model
src/​Cnblogs.DashScope.Core/​SpeechVocabularyModels.cs Vocabulary models
src/​Cnblogs.DashScope.Core/​SpeechVocabularyItem.cs Vocabulary item model
src/​Cnblogs.DashScope.Core/​SpeechVocabularyInput.cs Vocabulary input model
src/​Cnblogs.DashScope.Core/​SpeechTranscriptionUsage.cs Transcription usage model
src/​Cnblogs.DashScope.Core/​SpeechTranscriptionSubtaskResult.cs Subtask result model
src/​Cnblogs.DashScope.Core/​SpeechTranscriptionParameters.cs Transcription parameters
src/​Cnblogs.DashScope.Core/​SpeechTranscriptionOutput.cs Transcription output model
src/​Cnblogs.DashScope.Core/​SpeechTranscriptionInput.cs Transcription input model
src/​Cnblogs.DashScope.Core/​SpeechTranscriptionFileResult.cs File result model
src/​Cnblogs.DashScope.Core/​SpeechTranscriptionContextMessage.cs Context message model
src/​Cnblogs.DashScope.Core/​SpeechTranscriptionContextContent.cs Context content model
src/​Cnblogs.DashScope.Core/​SpeechRecognitionParameters.cs Recognition parameters
src/​Cnblogs.DashScope.Core/​SpeechRecognitionOutput.cs Recognition output model
src/​Cnblogs.DashScope.Core/​SpeechRecognitionMessageContent.cs Recognition message content
src/​Cnblogs.DashScope.Core/​SpeechRecognitionMessage.cs Recognition message model
src/​Cnblogs.DashScope.Core/​SpeechRecognitionInput.cs Recognition input model
src/​Cnblogs.DashScope.Core/​ISpeechTranscriptionParameters.cs Transcription parameter contract
src/​Cnblogs.DashScope.Core/​ISpeechRecognitionParameters.cs Recognition parameter contract
src/​Cnblogs.DashScope.Core/​Internals/​ApiLinks.cs Speech endpoint links
src/​Cnblogs.DashScope.Core/​IDashScopeClient.cs Public speech API contract
src/​Cnblogs.DashScope.Core/​DashScopeClientCore.cs Speech API implementation
sample/​Cnblogs.DashScope.Sample/​SpeechSample.cs Speech sample entry point
sample/​Cnblogs.DashScope.Sample/​Speech/​SpeechVocabularySample.cs Vocabulary sample
sample/​Cnblogs.DashScope.Sample/​Speech/​SpeechTranscriptionSample.cs Transcription sample
sample/​Cnblogs.DashScope.Sample/​Speech/​SpeechRecognitionFlashSample.cs Flash recognition sample
README.zh-Hans.md Chinese documentation
README.md English documentation

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread src/Cnblogs.DashScope.Core/DashScopeClientCore.cs Outdated
Add DashScope ASR support for asynchronous file transcription
(Paraformer/Fun-ASR), Fun-ASR-Flash sync/SSE recognition, and
speech-biasing vocabulary CRUD, with samples, tests, and EN/ZH docs.

Use a named IHttpClientFactory client (DI) and a process-wide shared
client (direct usage) for transcription result downloads so scoped
DashScopeClientCore instances do not allocate unmanaged HttpClients.

Co-authored-by: Andy Wu <andywu188@users.noreply.github.com>
@cursor
cursor Bot force-pushed the cursor/speech-asr-vocabulary-6580 branch from b09cd4c to 01a0282 Compare September 20, 2026 08:19
@ikesnowy

Copy link
Copy Markdown
Contributor

为什么要另外注入一个 HttpClient?

@andywu188

Copy link
Copy Markdown
Author

为什么要另外注入一个 ?HttpClient

因为转写结果下载和普通 DashScope API 调用不是一类请求。

主 HttpClient 上挂了 Authorization、X-DashScope-WorkSpace,以及 API 的 BaseAddress。结果文件却来自 OSS 绝对地址(如 dashscope-result-.oss-.aliyuncs.com)。HttpClient 的默认请求头会对每一次请求带上,包括这种外链下载,所以复用同一个客户端会把 API Key 等凭证带到 OSS。

单独注入/共享一个无鉴权的下载客户端,是为了:

不把 Bearer / Workspace 头带出 DashScope
与 API 客户端生命周期解耦(工厂或进程内共享),避免 scoped 实例反复 new HttpClient
主机校验只限制「能下哪些 URL」;隔离客户端解决的是「即使用对了 URL,也不泄漏凭证」。

@ikesnowy

Copy link
Copy Markdown
Contributor

避免 scoped 实例反复 new HttpClient

你是 AI 吧,Vibe Coding?

@andywu188

Copy link
Copy Markdown
Author

避免 scoped 实例反复 new HttpClient

你是 AI 吧,Vibe Coding?

我这边是使用Cursor 进行开发,并使用真实凭证Key进行验证

@ikesnowy

Copy link
Copy Markdown
Contributor

请阅读我们的 https://github.com/cnblogs/dashscope-sdk/blob/main/CONTRIBUTING.md

请不要搞 PR 突袭,我们需要时间来设计实现方案。

@andywu188 andywu188 closed this Sep 24, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants