73 lines
1.7 KiB
Go
73 lines
1.7 KiB
Go
|
|
package eino
|
|||
|
|
|
|||
|
|
import (
|
|||
|
|
"context"
|
|||
|
|
"io"
|
|||
|
|
"strings"
|
|||
|
|
|
|||
|
|
"github.com/cloudwego/eino/compose"
|
|||
|
|
"github.com/cloudwego/eino/schema"
|
|||
|
|
)
|
|||
|
|
|
|||
|
|
// sentenceDelimiters 句子分隔符集合。
|
|||
|
|
var sentenceDelimiters = map[rune]bool{
|
|||
|
|
'。': true,
|
|||
|
|
'!': true,
|
|||
|
|
'?': true,
|
|||
|
|
'\n': true,
|
|||
|
|
'.': true,
|
|||
|
|
'!': true,
|
|||
|
|
'?': true,
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// NewSplitterLambda 创建句子分割 Transform Lambda 节点。
|
|||
|
|
// 输入: StreamReader[string](LLM 完整文本的单帧流)→ 输出: StreamReader[[]string](句子数组流)
|
|||
|
|
//
|
|||
|
|
// 在 Stream 模式下,框架自动将 ChatModel 的 StreamReader[*schema.Message]
|
|||
|
|
// concat 为 string 后传入此节点。此节点将文本按句子边界切分,
|
|||
|
|
// 每切出一个句子就输出一次,供 TTS 节点实时合成。
|
|||
|
|
func NewSplitterLambda() *compose.Lambda {
|
|||
|
|
return compose.TransformableLambda(func(ctx context.Context, input *schema.StreamReader[string]) (*schema.StreamReader[[]string], error) {
|
|||
|
|
sr, sw := schema.Pipe[[]string](8)
|
|||
|
|
|
|||
|
|
go func() {
|
|||
|
|
defer sw.Close()
|
|||
|
|
|
|||
|
|
var buffer strings.Builder
|
|||
|
|
|
|||
|
|
for {
|
|||
|
|
chunk, err := input.Recv()
|
|||
|
|
if err != nil {
|
|||
|
|
if err == io.EOF {
|
|||
|
|
// 流结束,flush 剩余缓冲
|
|||
|
|
if buffer.Len() > 0 {
|
|||
|
|
text := strings.TrimSpace(buffer.String())
|
|||
|
|
if text != "" {
|
|||
|
|
sw.Send([]string{text}, nil)
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
return
|
|||
|
|
}
|
|||
|
|
sw.Send(nil, err)
|
|||
|
|
return
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// chunk 是 concat 后的完整文本(单帧流)
|
|||
|
|
// 逐字符累积,按句子分隔符切分
|
|||
|
|
for _, r := range chunk {
|
|||
|
|
buffer.WriteRune(r)
|
|||
|
|
if sentenceDelimiters[r] {
|
|||
|
|
text := strings.TrimSpace(buffer.String())
|
|||
|
|
if text != "" {
|
|||
|
|
sw.Send([]string{text}, nil)
|
|||
|
|
}
|
|||
|
|
buffer.Reset()
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}()
|
|||
|
|
|
|||
|
|
return sr, nil
|
|||
|
|
})
|
|||
|
|
}
|