【AgentScope Java新手村系列】(20)文字转语音TTS

简介: AgentScope 2.0 移除内置 TTS,教你用 @Tool 包装 DashScope CosyVoice,把文字合成 mp3 写入文件,运行后可直接播放验证。

第二十章 文字转语音 TTS:用 @Tool 包装上游 SDK,框架不再内置 TTS

原因:TTS 的业务差异太大。有的团队用火山引擎,有的用阿里云 CosyVoice,有的用 OpenAI。硬塞进框架等于绑死用户。

2.0 的做法:你自己包装上游 SDK 为一个 @Tool,agent 调工具拿到音频字节,框架只管调度、不管语音合成。

20.1 包装上游 TTS SDK 为 @Tool

业务方做三件事:

  1. 引入上游 SDK(火山 / 阿里云 CosyVoice / OpenAI TTS / Azure Speech)
  2. 写一个 @Tool 调用该 SDK
  3. 注册到 agent / subagent

例:包装阿里云 CosyVoice SDK 为工具:

import com.alibaba.dashscope.audio.tts.SpeechSynthesisParam;
import com.alibaba.dashscope.audio.tts.SpeechSynthesizer;
import io.agentscope.core.message.DataBlock;
import io.agentscope.core.message.Base64Source;
import io.agentscope.core.tool.Tool;
import io.agentscope.core.tool.ToolParam;

import java.nio.ByteBuffer;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Base64;

public class TtsTool {
   

    private final String apiKey;

    public TtsTool(String apiKey) {
   
        this.apiKey = apiKey;
    }

    @Tool(name = "tts_synthesize", description = "把文字转成 mp3 音频,返回 DataBlock")
    public DataBlock synthesize(
            @ToolParam(name = "text") String text,
            @ToolParam(name = "voice", required = false) String voice) {
   

        SpeechSynthesisParam param = SpeechSynthesisParam.builder()
                .apiKey(apiKey)
                .model("cosyvoice-v1")
                .text(text)
                .build();

        SpeechSynthesizer synthesizer = new SpeechSynthesizer();
        ByteBuffer result = synthesizer.call(param);
        byte[] mp3 = new byte[result.remaining()];
        result.get(mp3);

        String b64 = Base64.getEncoder().encodeToString(mp3);
        return DataBlock.builder()
                .source(Base64Source.builder()
                        .data(b64)
                        .mediaType("audio/mp3")
                        .build())
                .name("tts.mp3")
                .build();
    }

    @Tool(name = "tts_to_file", description = "把文字转成 mp3 并写入文件")
    public String synthesizeToFile(
            @ToolParam(name = "text") String text,
            @ToolParam(name = "outPath") String outPath) {
   

        SpeechSynthesisParam param = SpeechSynthesisParam.builder()
                .apiKey(apiKey)
                .model("cosyvoice-v1")
                .text(text)
                .build();

        SpeechSynthesizer synthesizer = new SpeechSynthesizer();
        ByteBuffer result = synthesizer.call(param);
        byte[] mp3 = new byte[result.remaining()];
        result.get(mp3);

        Files.write(Path.of(outPath), mp3);
        return "已写入 " + outPath;
    }
}

注册到 agent:

Toolkit toolkit = new Toolkit();
toolkit.registerTool(new TtsTool());                                 // 注册 TTS 包装工具

HarnessAgent agent = HarnessAgent.builder()
        .name("voice_assistant")
        .sysPrompt("你是语音助理,可以用 tts_to_file 把文字转成 mp3 文件。")  // 告诉 LLM 有 TTS 工具可用
        .model(model())
        .workspace(Path.of("./workspace"))
        .toolkit(toolkit)                                            // 传入注册好的工具
        .build();

LLM 看到用户要"念给我听"时,自动调用 tts_to_file 工具——生成的 tts_output.mp3 直接用播放器打开就能听到。

提示:tts_synthesize 返回 DataBlock,适合把音频推给前端播放;tts_to_file 写入磁盘,适合本地验证。

20.2 与前端的流式推送

Web 端拿到 DataBlock 后:

ws.onmessage = (event) => {
   
  const data = JSON.parse(event.data);
  if (data.toolName === "tts_synthesize") {
   
    const audioB64 = data.result.media.base64;
    const audioBlob = base64ToBlob(audioB64, "audio/mp3");
    const audio = new Audio(URL.createObjectURL(audioBlob));
    audio.play();
  }
};

agent.streamEvents(...) 会把 ToolResultBlock 推给前端;前端按 mediaType 决定是否转成 <audio>

20.3 多 TTS 提供商的策略

如果业务同时接火山、OpenAI、CosyVoice,可以在 tools.json 里按工具名分别包装:

{
   
  "tools": [
    {
   
      "name": "tts_cosyvoice",
      "class": "demo.tts.CosyVoiceTool",
      "description": "中文 TTS(CosyVoice)"
    },
    {
   
      "name": "tts_openai",
      "class": "demo.tts.OpenAiTtsTool",
      "description": "英文 TTS(OpenAI)"
    }
  ]
}

主 agent 在 system prompt 里描述路由规则:

中文场景用 tts_cosyvoice,英文场景用 tts_openai。

20.4 完整可运行示例

本地验证时,建议让 agent 直接调用 tts_to_file,把 mp3 写到磁盘,这样就能用播放器听到真实语音:

public class Chapter20_FullTts {
   

    public static void main(String[] args) {
   
        TtsTool ttsTool = new TtsTool();                            // 业务方包装的 TTS 工具(见 20.1 节)

        Toolkit toolkit = new Toolkit();
        toolkit.registerTool(ttsTool);                              // 通过 Toolkit 注册

        String outPath = Path.of("./workspace").resolve("tts_output.mp3").toString();

        HarnessAgent agent = HarnessAgent.builder()
                .name("voice_assistant")
                .sysPrompt("""
                        你是语音助理。
                        用户让你"念" / "读" / "播放"某段文字时,
                        调 tts_to_file 把 mp3 保存到:
                        """ + outPath)
                .model(model())
                .workspace(Path.of("./workspace"))
                .toolkit(toolkit)                                   // 传入注册好的工具
                .build();

        String reply = agent.call(
                        new UserMessage("把'杭州今天 22 度'念给我听,保存成 mp3 文件。"),
                        RuntimeContext.empty())                     // 无 session,单次调完即走
                .block()
                .getTextContent();

        System.out.println(reply);
        System.out.println("音频已保存:" + outPath);                  // 可直接用播放器打开
    }
}

运行后打开 ./workspace/tts_output.mp3 即可听到合成语音。

20.5 本章小结

  • 2.0 移除了内置 TTS 模块。推荐业务方包装上游 SDK 为 @Tool
  • 本地验证用 tts_to_file 把 mp3 写到磁盘,可直接播放;上线后可用 tts_synthesize 返回 DataBlock 推给前端。
  • 多个 TTS 提供商共存时,按工具名路由即可。
目录
相关文章
|
1天前
|
人工智能
Qwen3.8抢先体验!正式版即将发布并开源!
千问Qwen3.8即将开源,参数达2.4T,进化速度以“天”计,实力媲美Fable 5。预览版Qwen3.8-Max已上线阿里Token Plan等平台,限时优惠:日间Credits低至1折,夜间更优,个人/团队版月付仅35元起!
370 15
|
1天前
|
安全 调度
代驾系统开发如何帮助平台提升接单效率与用户留存
本文围绕代驾系统开发展开,分析其在订单匹配、高峰调度、状态同步、费用展示、司机端体验和用户留存等方面的作用。通过优化接单流程、提升调度效率、完善服务闭环,代驾平台可以在用户等待、司机履约和平台运营之间形成更顺畅的协同。
|
1天前
|
PyTorch Linux 网络安全
新服务器从0到1完整部署实践:openEuler环境搭建ChatGLM2大模型完整流程.175
本文详述基于openEuler 22.03的Dell PowerEdge R740服务器从零部署大模型服务全流程:涵盖硬件核查、多网卡精准识别与静态IP配置、Python 3.11源码编译安装、PyTorch/Transformers/ModelScope等依赖适配、FastAPI接口搭建及防火墙放行,附典型报错解析与标准化解决方案,助新手快速落地。
|
1天前
|
人工智能 关系型数据库 分布式数据库
记忆张量MemOS + 阿里云PolarDB一站式记忆管理方案发布:给AI装上不断片的记忆
AI智能体需长期记忆支撑持续服务,但面临跨会话丢失、多模态数据管理与弹性扩展难题。阿里云PolarDB-PG(集成关系/向量/图能力)与MemOS记忆操作系统协同,提供“稳”底座与“活”调度,实现记忆提取、存储、召回、治理全链路,支持千万级用户与多租户隔离。
51 0
记忆张量MemOS + 阿里云PolarDB一站式记忆管理方案发布:给AI装上不断片的记忆
|
1天前
|
人工智能 测试技术 API
Agentforce 模型配置与选择指南
Agentforce 模型和 Prompts 完整指南。涵盖四大核心组件(Prompt Builder/AI Models/Models API/Agentforce 模型选择)、四家提供商全模型列表(Bedrock Claude/OpenAI GPT/Vertex AI Gemini/Embeddings)、BYOLLM 和 LLM Open Connector、模型选择四大标准(能力/成本/质量/速度)、上下文窗口限制、Geo-aware 路由、Beta 模型管理、弃用和重路由策略。
Agentforce 模型配置与选择指南
|
1天前
|
运维 安全 前端开发
公用事业条码 / QR 码支付新型电信诈骗攻击链路与全域防御体系研究
本文剖析2026年PG&E披露的新型公用事业条码诈骗:犯罪分子通过VOIP伪造客服电话恐吓用户,再以短信/邮件发送伪造缴费二维码,诱导其至商超柜台线下扫码支付,成功绕过线上风控。文章首次系统拆解“语音恐吓—条码投递—线下支付”五阶段攻击链,揭示通信、金融、企业与商户四方防控盲区,并提出覆盖通信拦截、企业风控、支付校验、用户宣教及跨部门协同的五维闭环防御体系。(239字)
19 0
|
1天前
|
数据采集 人工智能 数据挖掘
企业有多个AI应用,员工却不知道怎么用:一次AI工作助理路由改造实践
当一个任务能够被拆解、调用、评估、人工确认并持续改进时,智能体才真正从Demo进入业务。
|
1天前
|
测试技术 Shell 开发工具
前台服务适配与线上排查:通知权限、启动限制和任务保活
本文详解前台服务的合规实现:涵盖通知权限适配、后台启动限制规避、多版本系统兼容及线上问题排查方法,强调按场景选型(如导航/播放用前台服务,同步用WorkManager),避免滥用保活,助你构建稳定长任务能力。
22 0

热门文章

最新文章