Skip to content
omeyang edited this page Sep 17, 2026 · 2 revisions

Sonata

用 Go 编写的实时语音对话引擎核心库。提供流式 ASR → LLM → TTS 管线编排、表驱动媒体状态机、WebRTC VAD 封装和 barge-in 打断检测。核心约 1500 行(不含测试和 sherpa/ 子模块),标准库优先,零框架依赖。

engine.Session 是中央编排器:它不关心音频从哪来(由 engine.Transport 接口决定),也不关心对话内容是什么(由 aiface.DialogEngine 接口决定)。产品层只需实现这两个接口,再接入自己的 ASR / TTS Provider,就能得到一条带打断、静默保护和填充词的完整语音对话链路。

快速开始

需要 Go 1.25 或更新版本(go.mod 声明 go 1.25.7)。

go get github.com/omeyang/Sonata

最小接入:实现 engine.Transport 与 aiface.DialogEngine,接入 ASR / TTS Provider,然后驱动会话。

import (
    "context"

    "github.com/omeyang/Sonata/engine"
    "github.com/omeyang/Sonata/engine/aiface"
    "github.com/omeyang/Sonata/engine/mediafsm"
)

func runCall(ctx context.Context,
    transport engine.Transport,     // 实现 AudioIn / PlayAudio / StopPlayback / Close
    dialogue aiface.DialogEngine,   // 实现 Opening / Process / ProcessStream / Finished
    asr aiface.ASRProvider,         // 实现 StartStream
    tts aiface.TTSProvider,         // 实现 SynthesizeStream / Synthesize / Cancel
) (*engine.Result, error) {
    cfg := engine.Config{
        SessionID:   "session-001",
        Transport:   transport,
        Dialogue:    dialogue,
        ASR:         asr,
        TTS:         tts,
        ASRCfg:      aiface.ASRConfig{SampleRate: 16000, Language: "zh"},
        TTSCfg:      aiface.TTSConfig{SampleRate: 8000},
        Transitions: mediafsm.AppTransitions(),
        Protection: engine.ProtectionConfig{
            MaxDurationSec:         300,
            MaxSilenceSec:          15,
            FirstSilenceTimeoutSec: 6,
        },
    }

    s := engine.New(cfg)
    // AppTransitions 下会话从 Idle 经 EvAnswer 进入 BotSpeaking(播放开场白)。
    if err := s.FSM().Handle(mediafsm.EvAnswer); err != nil {
        return nil, err
    }
    return s.Run(ctx)
}

Run 阻塞直到会话结束,返回 *engine.Result(会话 ID、时长和带时间戳的事件列表)。未设置的 Protection 字段与采样率字段会在 engine.New 中取默认值,详见 架构。

文档导航

页面 内容
架构 数据流、Session 事件循环、goroutine 与 channel 结构、两个解耦接口
接口与扩展 Transport、aiface 各接口的签名与语义、结构化错误、自定义 Provider
媒体状态机 mediafsm 的状态、事件、两套转换表、超时与打断处理
PCM 与 VAD pcm 包:重采样、能量计算、WebRTC VAD、WAV 头、PCM16 与 float32 互转
指标与事件 Metrics 接口、EventType 与 RecordedEvent、接入方式
开发与发布 Taskfile 任务、golangci-lint 要点、测试与基准、Go 版本要求

名字来源

Sonata 即"奏鸣曲",一种由多个乐章组成、以对比与呼应推进的器乐体裁。借用这一意象:一次语音对话也是听与说交替、彼此呼应的多乐章演奏,Session 是指挥,mediafsm 管节奏,DialogEngine 管内容。

模块路径为 github.com/omeyang/Sonata,采用 AGPL-3.0 许可证。

Clone this wiki locally