feat: 支持多租户多模型对话及文档去重优化
This commit is contained in:
@@ -5,13 +5,10 @@ import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"rag/consts/model"
|
||||
|
||||
"github.com/cloudwego/eino-ext/components/model/qwen"
|
||||
"github.com/cloudwego/eino/components/prompt"
|
||||
"github.com/cloudwego/eino/schema"
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
"github.com/gogf/gf/v2/os/glog"
|
||||
"github.com/gogf/gf/v2/util/gconv"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -19,48 +16,15 @@ const (
|
||||
)
|
||||
|
||||
var (
|
||||
globalChatModel *qwen.ChatModel
|
||||
ragPromptTemplate prompt.ChatTemplate // EINO 官方模板
|
||||
)
|
||||
|
||||
func init() {
|
||||
ctx := context.Background()
|
||||
// 初始化大模型
|
||||
if err := initChatModel(ctx); err != nil {
|
||||
glog.Errorf(ctx, "初始化大模型失败: %v", err)
|
||||
}
|
||||
// 初始化 EINO 提示词模板
|
||||
initRAGPromptTemplate()
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// 初始化通义千问
|
||||
func initChatModel(ctx context.Context) error {
|
||||
if globalChatModel != nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
apiKey := g.Cfg().MustGet(ctx, "eino.chatmodel.apiKey").String()
|
||||
model := g.Cfg().MustGet(ctx, "eino.chatmodel.model").String()
|
||||
|
||||
cm, err := qwen.NewChatModel(ctx, &qwen.ChatModelConfig{
|
||||
APIKey: apiKey,
|
||||
Model: model,
|
||||
BaseURL: "https://dashscope.aliyuncs.com/compatible-mode/v1",
|
||||
Timeout: 60 * 1e9,
|
||||
Temperature: gconv.PtrFloat32(0.7), // 客服最佳
|
||||
MaxTokens: gconv.PtrInt(1024), // 最长回答
|
||||
TopP: gconv.PtrFloat32(1.0),
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
globalChatModel = cm
|
||||
return nil
|
||||
}
|
||||
|
||||
// 初始化 EINO 官方提示词模板(最关键!)
|
||||
func initRAGPromptTemplate() {
|
||||
ragPromptTemplate = prompt.FromMessages(
|
||||
@@ -69,7 +33,7 @@ func initRAGPromptTemplate() {
|
||||
&schema.Message{
|
||||
Role: schema.System,
|
||||
Content: `你是专业客服,语气友好简洁。
|
||||
请严格依据参考知识回答,不知道就说:抱歉,我暂时无法回答这个问题。
|
||||
请依据参考知识回答,不知道就说:抱歉,我暂时无法回答这个问题。
|
||||
|
||||
参考知识:
|
||||
{knowledge}`,
|
||||
@@ -83,7 +47,7 @@ func initRAGPromptTemplate() {
|
||||
}
|
||||
|
||||
// NewChatModel 只处理逻辑,不复用创建模型
|
||||
func NewChatModel(ctx context.Context, question string, docs []*schema.Document, history []*schema.Message) (replyMsg *schema.Message, err error) {
|
||||
func NewChatModel(ctx context.Context, question string, docs []*schema.Document, history []*schema.Message, chatModel model.ModelConfigType) (replyMsg *schema.Message, err error) {
|
||||
// 1. 构建参考知识
|
||||
knowledge := buildKnowledgeAndSources(docs)
|
||||
// 2. 历史精简
|
||||
@@ -101,7 +65,7 @@ func NewChatModel(ctx context.Context, question string, docs []*schema.Document,
|
||||
msgs = append(msgs[:1], append(history, msgs[1:]...)...)
|
||||
}
|
||||
// 5. 🔥 直接使用全局单例,不重复创建
|
||||
replyMsg, err = streamGenerateAnswer(ctx, globalChatModel, msgs)
|
||||
replyMsg, err = streamGenerateAnswer(ctx, msgs, chatModel)
|
||||
|
||||
return
|
||||
}
|
||||
@@ -133,9 +97,14 @@ func buildKnowledgeAndSources(docs []*schema.Document) string {
|
||||
}
|
||||
|
||||
// streamGenerateAnswer 流式生成
|
||||
func streamGenerateAnswer(ctx context.Context, chatModel *qwen.ChatModel, msgs []*schema.Message) (reply *schema.Message, err error) {
|
||||
func streamGenerateAnswer(ctx context.Context, msgs []*schema.Message, chatModel model.ModelConfigType) (reply *schema.Message, err error) {
|
||||
|
||||
sr, err := chatModel.Stream(ctx, msgs)
|
||||
cm, err := GetTenantChatModelByType(ctx, chatModel)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
sr, err := cm.Stream(ctx, msgs)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("stream failed: %w", err)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user