refactor: 重构advice模块并优化对话功能
This commit is contained in:
parent
46049475c1
commit
9590721d30
File diff suppressed because one or more lines are too long
|
|
@ -35,10 +35,10 @@ func NewAdviceAdvicerBiz(
|
|||
}
|
||||
}
|
||||
|
||||
func (a *AdviceAdvicerBiz) Update(ctx context.Context, data *entitys.AdvicerInitReq) error {
|
||||
func (a *AdviceAdvicerBiz) Update(ctx context.Context, data *entitys.AdvicerInitReq) (int32, error) {
|
||||
birth, err := time.Parse("2006-01-02", data.Birth)
|
||||
if err != nil {
|
||||
return err
|
||||
return 0, err
|
||||
}
|
||||
param := &model.AiAdviceAdvicer{
|
||||
AdvicerID: data.AdvicerID,
|
||||
|
|
@ -49,13 +49,13 @@ func (a *AdviceAdvicerBiz) Update(ctx context.Context, data *entitys.AdvicerInit
|
|||
WorkingYears: data.WorkingYears,
|
||||
}
|
||||
if param.AdvicerID == 0 {
|
||||
_, err = a.advicerImpl.Add(param)
|
||||
err = a.advicerImpl.AddWithData(param)
|
||||
} else {
|
||||
cond := builder.NewCond()
|
||||
cond = cond.And(builder.Eq{"advicer_id": param.AdvicerID})
|
||||
err = a.advicerImpl.UpdateByCond(&cond, param)
|
||||
}
|
||||
return err
|
||||
return param.AdvicerID, err
|
||||
}
|
||||
|
||||
func (a *AdviceAdvicerBiz) List(ctx context.Context, data *entitys.AdvicerListReq) ([]map[string]interface{}, error) {
|
||||
|
|
@ -66,14 +66,14 @@ func (a *AdviceAdvicerBiz) List(ctx context.Context, data *entitys.AdvicerListRe
|
|||
return list, err
|
||||
}
|
||||
|
||||
func (a *AdviceAdvicerBiz) VersionAdd(ctx context.Context, param *entitys.AdvicerVersionAddReq) (err error) {
|
||||
func (a *AdviceAdvicerBiz) VersionAdd(ctx context.Context, param *entitys.AdvicerVersionAddReq) (id interface{}, err error) {
|
||||
cond := builder.NewCond()
|
||||
cond = cond.And(builder.Eq{"advicer_id": param.AdvicerID})
|
||||
_, err = a.advicerImpl.GetOneBySearch(&cond)
|
||||
if err != nil {
|
||||
return errors.New("顾问不存在")
|
||||
return 0, errors.New("顾问不存在")
|
||||
}
|
||||
_, err = a.mongo.Co(a.advicerVersionMongo).InsertOne(ctx, &mongo_model.AdvicerVersionMongo{
|
||||
res, err := a.mongo.Co(a.advicerVersionMongo).InsertOne(ctx, &mongo_model.AdvicerVersionMongo{
|
||||
AdvicerId: param.AdvicerID,
|
||||
VersionDesc: param.VersionDesc,
|
||||
DialectFeatures: param.DialectFeatures,
|
||||
|
|
@ -83,8 +83,10 @@ func (a *AdviceAdvicerBiz) VersionAdd(ctx context.Context, param *entitys.Advice
|
|||
SignatureDialogues: param.SignatureDialogues,
|
||||
LastUpdateTime: time.Now(),
|
||||
})
|
||||
|
||||
return err
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return res.InsertedID, err
|
||||
}
|
||||
|
||||
func (a *AdviceAdvicerBiz) VersionUpdate(ctx context.Context, param *entitys.AdvicerVersionUpdateReq) (err error) {
|
||||
|
|
@ -118,7 +120,7 @@ func (a *AdviceAdvicerBiz) VersionList(ctx context.Context, param *entitys.Advic
|
|||
filter := bson.M{}
|
||||
// 1. advicer_id 条件
|
||||
if param.AdvicerId != 0 {
|
||||
filter["AdvicerId"] = param.AdvicerId
|
||||
filter["advicerId"] = param.AdvicerId
|
||||
}
|
||||
|
||||
// 2. _id 条件
|
||||
|
|
@ -133,7 +135,7 @@ func (a *AdviceAdvicerBiz) VersionList(ctx context.Context, param *entitys.Advic
|
|||
// 3. version_desc 模糊查询
|
||||
if len(param.VersionDesc) != 0 {
|
||||
// 正确的方式:指定字段名
|
||||
filter["VersionDesc"] = bson.M{
|
||||
filter["versionDesc"] = bson.M{
|
||||
"$regex": primitive.Regex{
|
||||
Pattern: param.VersionDesc,
|
||||
Options: "i",
|
||||
|
|
|
|||
|
|
@ -2,83 +2,278 @@ package biz
|
|||
|
||||
import (
|
||||
"ai_scheduler/internal/biz/llm_service/third_party"
|
||||
"ai_scheduler/internal/data/constants"
|
||||
"ai_scheduler/internal/data/mongo_model"
|
||||
|
||||
"ai_scheduler/internal/data/impl"
|
||||
dbmodel "ai_scheduler/internal/data/model"
|
||||
"ai_scheduler/internal/entitys"
|
||||
"ai_scheduler/internal/pkg"
|
||||
"ai_scheduler/utils"
|
||||
"context"
|
||||
"encoding/json"
|
||||
"strings"
|
||||
"time"
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"github.com/google/uuid"
|
||||
"github.com/volcengine/volcengine-go-sdk/service/arkruntime/model"
|
||||
"github.com/volcengine/volcengine-go-sdk/service/arkruntime/model/responses"
|
||||
"github.com/volcengine/volcengine-go-sdk/volcengine"
|
||||
"go.mongodb.org/mongo-driver/bson"
|
||||
"go.mongodb.org/mongo-driver/mongo/options"
|
||||
"xorm.io/builder"
|
||||
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
type AdviceChatBiz struct {
|
||||
hsyq *third_party.Hsyq
|
||||
rdb *utils.Rdb
|
||||
hsyq *third_party.Hsyq
|
||||
rdb *utils.Rdb
|
||||
aiAdviceSessionImpl *impl.AiAdviceSessionImpl
|
||||
aiAdviceModelSupImpl *impl.AiAdviceModelSupImpl
|
||||
advicerChatHisMongo *mongo_model.AdvicerChatHisMongo
|
||||
mongo *pkg.Mongo
|
||||
}
|
||||
|
||||
func NewAdviceChatBiz(
|
||||
hsyq *third_party.Hsyq,
|
||||
rdb *utils.Rdb,
|
||||
aiAdviceSessionImpl *impl.AiAdviceSessionImpl,
|
||||
aiAdviceModelSupImpl *impl.AiAdviceModelSupImpl,
|
||||
advicerChatHisMongo *mongo_model.AdvicerChatHisMongo,
|
||||
mongo *pkg.Mongo,
|
||||
) *AdviceChatBiz {
|
||||
return &AdviceChatBiz{
|
||||
hsyq: hsyq,
|
||||
rdb: rdb,
|
||||
hsyq: hsyq,
|
||||
rdb: rdb,
|
||||
aiAdviceSessionImpl: aiAdviceSessionImpl,
|
||||
aiAdviceModelSupImpl: aiAdviceModelSupImpl,
|
||||
advicerChatHisMongo: advicerChatHisMongo,
|
||||
mongo: mongo,
|
||||
}
|
||||
}
|
||||
|
||||
func (a *AdviceChatBiz) Regis(ctx context.Context, chatData *entitys.ChatData) (string, error) {
|
||||
sessionId := uuid.New().String()
|
||||
prompt, err := a.buildBasePrompt(ctx, chatData)
|
||||
func (a *AdviceChatBiz) contextCache(ctx context.Context, chatData *entitys.ChatData, req *entitys.AdvicerChatRegistReq, projectInfo *entitys.AdvicerProjectInfoRes) (promptJson string, contextCache string, err error) {
|
||||
switch constants.Mode(projectInfo.ModelInfo.Mode) {
|
||||
case constants.ModeResponse:
|
||||
prompt, err := a.buildBasePromptResponse(ctx, chatData, req)
|
||||
if err != nil {
|
||||
return "", "", err
|
||||
}
|
||||
cache, err := a.hsyq.CreateResponse(ctx, projectInfo.ModelInfo.Key, projectInfo.ModelInfo.ChatModel, prompt, "", true)
|
||||
if err != nil {
|
||||
return "", "", err
|
||||
}
|
||||
contextCache = cache.Id
|
||||
promptJson = pkg.JsonStringIgonErr(prompt)
|
||||
case constants.ModeContext:
|
||||
prompt, err := a.buildBasePromptContext(ctx, chatData, req)
|
||||
if err != nil {
|
||||
return "", "", err
|
||||
}
|
||||
contextCache, err = a.hsyq.CreateContextCache(ctx, projectInfo.ModelInfo.Key, projectInfo.ModelInfo.ChatModel, prompt)
|
||||
if err != nil {
|
||||
return "", "", err
|
||||
}
|
||||
promptJson = pkg.JsonStringIgonErr(prompt)
|
||||
default:
|
||||
return "", "", fmt.Errorf("未知的mode类型:%d", projectInfo.ModelInfo.Mode)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (a *AdviceChatBiz) Regis(ctx context.Context, chatData *entitys.ChatData, req *entitys.AdvicerChatRegistReq, projectInfo *entitys.AdvicerProjectInfoRes) (string, error) {
|
||||
promptJson, contextCache, err := a.contextCache(ctx, chatData, req, projectInfo)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
err = a.rdb.Rdb.SetEx(ctx, sessionId, pkg.JsonStringIgonErr(prompt), 3600*time.Second).Err()
|
||||
sessionId := uuid.New().String()
|
||||
//创建会话
|
||||
_, err = a.aiAdviceSessionImpl.Add(&dbmodel.AiAdviceSession{
|
||||
SessionID: sessionId,
|
||||
ProjectID: projectInfo.Base.ProjectID,
|
||||
SupID: projectInfo.Base.ModelSupID,
|
||||
AdvicerVersionID: req.AdvicerVersionId,
|
||||
ClientID: req.ClientId,
|
||||
TalkSkillID: req.TalkSkillId,
|
||||
Mission: req.Mission,
|
||||
ContextCache: contextCache,
|
||||
CreateAt: time.Now(),
|
||||
})
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
err = a.rdb.Rdb.SetEx(ctx, sessionId, promptJson, 3600*time.Second).Err()
|
||||
|
||||
return sessionId, err
|
||||
}
|
||||
|
||||
func (a *AdviceChatBiz) Chat(ctx context.Context, chat *entitys.AdvicerChatReq) ([]string, error) {
|
||||
func (a *AdviceChatBiz) Chat(ctx context.Context, chat *entitys.AdvicerChatReq) (assistant mongo_model.Assistant, err error) {
|
||||
var session dbmodel.AiAdviceSession
|
||||
cond := builder.NewCond()
|
||||
cond = cond.And(builder.Eq{"session_id": chat.SessionId})
|
||||
err = a.aiAdviceSessionImpl.GetOneBySearchToStrut(&cond, &session)
|
||||
if err != nil {
|
||||
return assistant, err
|
||||
}
|
||||
if session.SessionID == "" {
|
||||
return assistant, errors.New("未找到会话信息")
|
||||
}
|
||||
if len(chat.Content) == 0 {
|
||||
return nil, nil
|
||||
return assistant, nil
|
||||
}
|
||||
basePromptJson, err := a.getChatDataFromStringSessionId(ctx, chat.SessionId)
|
||||
var modelInfo dbmodel.AiAdviceModelSup
|
||||
cond = builder.NewCond()
|
||||
cond = cond.And(builder.Eq{"sup_id": session.SupID})
|
||||
err = a.aiAdviceModelSupImpl.GetOneBySearchToStrut(&cond, &modelInfo)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return assistant, err
|
||||
}
|
||||
prompt, err := a.setContent(ctx, basePromptJson, chat.Content)
|
||||
if modelInfo.SupID == 0 {
|
||||
return assistant, errors.New("未找到模型信息")
|
||||
}
|
||||
//basePromptJson, err := a.getChatDataFromStringSessionId(ctx, chat.SessionId)
|
||||
//if err != nil {
|
||||
// return nil, err
|
||||
//}
|
||||
chatHis, err := a.getChatHis(ctx, session.SessionID, 6)
|
||||
prompt, err := a.buildChatPromptResponse(ctx, chat, &session, chatHis)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return assistant, err
|
||||
}
|
||||
resContent, err := a.callLlm(ctx, prompt, fileModel)
|
||||
resContent, err := a.callLlmResponse(ctx, prompt, modelInfo.Key, modelInfo.ChatModel, session.ContextCache)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return assistant, err
|
||||
}
|
||||
resSlice := strings.Split(resContent, "\n")
|
||||
return resSlice, nil
|
||||
|
||||
result := resContent.Output[0].GetOutputMessage().Content[0].GetText().GetText()
|
||||
if err = json.Unmarshal([]byte(result), &assistant); err != nil {
|
||||
return assistant, err
|
||||
}
|
||||
chatCtx, cancel := context.WithCancel(context.Background())
|
||||
go func(session dbmodel.AiAdviceSession) {
|
||||
defer cancel()
|
||||
_, _ = a.mongo.Co(a.advicerChatHisMongo).InsertOne(chatCtx, &mongo_model.AdvicerChatHisMongo{
|
||||
SessionId: chat.SessionId,
|
||||
User: chat.Content,
|
||||
Assistant: assistant,
|
||||
InToken: resContent.Usage.InputTokens,
|
||||
OutToken: resContent.Usage.OutputTokens,
|
||||
CreatAt: time.Now(),
|
||||
})
|
||||
if assistant.MissionStatus == "fail" || assistant.MissionStatus == "complete" {
|
||||
cond = builder.NewCond()
|
||||
cond = cond.And(builder.Eq{"session_id": chat.SessionId})
|
||||
session.MissionStatus = assistant.MissionStatus
|
||||
session.MissionCompleteDesc = assistant.MissionCompleteDesc
|
||||
_ = a.aiAdviceSessionImpl.UpdateByCond(&cond, session)
|
||||
}
|
||||
}(session)
|
||||
return
|
||||
}
|
||||
|
||||
func (a *AdviceChatBiz) buildBasePrompt(ctx context.Context, chatData *entitys.ChatData) ([]*model.ChatCompletionMessage, error) {
|
||||
var message = make([]*model.ChatCompletionMessage, 3)
|
||||
func (a *AdviceChatBiz) buildChatPromptResponse(ctx context.Context, chat *entitys.AdvicerChatReq, session *dbmodel.AiAdviceSession, chatList []mongo_model.AdvicerChatHisMongoEntity) ([]*responses.InputItem, error) {
|
||||
|
||||
var message = make([]*responses.InputItem, 3)
|
||||
message[0] = &responses.InputItem{
|
||||
Union: &responses.InputItem_EasyMessage{
|
||||
EasyMessage: &responses.ItemEasyMessage{
|
||||
Role: responses.MessageRole_system,
|
||||
Content: &responses.MessageContent{Union: &responses.MessageContent_StringValue{StringValue: a.taskPrompt(session)}},
|
||||
},
|
||||
},
|
||||
}
|
||||
message[1] = &responses.InputItem{
|
||||
Union: &responses.InputItem_EasyMessage{
|
||||
EasyMessage: &responses.ItemEasyMessage{
|
||||
Role: responses.MessageRole_system,
|
||||
Content: &responses.MessageContent{Union: &responses.MessageContent_StringValue{StringValue: "历史聊天记录:\n" + pkg.JsonStringIgonErr(chatList)}},
|
||||
},
|
||||
},
|
||||
}
|
||||
message[2] = &responses.InputItem{
|
||||
Union: &responses.InputItem_EasyMessage{
|
||||
EasyMessage: &responses.ItemEasyMessage{
|
||||
Role: responses.MessageRole_user,
|
||||
Content: &responses.MessageContent{Union: &responses.MessageContent_StringValue{StringValue: chat.Content}},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
return message, nil
|
||||
}
|
||||
func (a *AdviceChatBiz) getChatHis(ctx context.Context, sessionId string, limit int64) (chatList []mongo_model.AdvicerChatHisMongoEntity, err error) {
|
||||
chatList = make([]mongo_model.AdvicerChatHisMongoEntity, 0)
|
||||
filter := bson.M{}
|
||||
filter["sessionId"] = sessionId
|
||||
cursor, err := a.mongo.Co(a.advicerChatHisMongo).Find(ctx, filter, options.Find().SetLimit(limit))
|
||||
if err != nil {
|
||||
return chatList, err
|
||||
}
|
||||
for cursor.Next(ctx) {
|
||||
var chatHIS mongo_model.AdvicerChatHisMongo
|
||||
if err := cursor.Decode(&chatHIS); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
chatList = append(chatList, chatHIS.Entity())
|
||||
}
|
||||
|
||||
if err := cursor.Err(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (a *AdviceChatBiz) buildChatPrompt(ctx context.Context, chat *entitys.AdvicerChatReq, session *dbmodel.AiAdviceSession, modelInfo *dbmodel.AiAdviceModelSup) (model.ContextChatCompletionRequest, error) {
|
||||
var message = make([]*model.ChatCompletionMessage, 2)
|
||||
message[0] = &model.ChatCompletionMessage{
|
||||
Role: model.ChatMessageRoleUser,
|
||||
Content: &model.ChatCompletionMessageContent{
|
||||
StringValue: volcengine.String(chat.Content),
|
||||
},
|
||||
}
|
||||
message[1] = &model.ChatCompletionMessage{
|
||||
Role: model.ChatMessageRoleAssistant,
|
||||
Content: &model.ChatCompletionMessageContent{
|
||||
StringValue: volcengine.String(a.taskPrompt(session)),
|
||||
},
|
||||
}
|
||||
|
||||
req := model.ContextChatCompletionRequest{
|
||||
ContextID: session.ContextCache,
|
||||
Model: modelInfo.ChatModel,
|
||||
Messages: message,
|
||||
Stream: false,
|
||||
}
|
||||
return req, nil
|
||||
}
|
||||
|
||||
func (a *AdviceChatBiz) taskPrompt(session *dbmodel.AiAdviceSession) string {
|
||||
//type mission struct {
|
||||
// missionName string
|
||||
// status string
|
||||
// missionCompleteDesc string
|
||||
//}
|
||||
//var m = &mission{
|
||||
// missionName: session.Mission,
|
||||
// status: pkg.Ter(session.MissionStatus == 1, "进行中", "已完成"),
|
||||
// missionCompleteDesc: session.MissionCompleteDesc,
|
||||
//}
|
||||
//missionJon, _ := json.Marshal(m)
|
||||
return "[当前时间]" + time.Now().Format("2006-01-02 15:04:05")
|
||||
}
|
||||
|
||||
func (a *AdviceChatBiz) buildBasePromptContext(ctx context.Context, chatData *entitys.ChatData, req *entitys.AdvicerChatRegistReq) ([]*model.ChatCompletionMessage, error) {
|
||||
var message = make([]*model.ChatCompletionMessage, 2)
|
||||
message[0] = &model.ChatCompletionMessage{
|
||||
Role: model.ChatMessageRoleSystem,
|
||||
Content: &model.ChatCompletionMessageContent{
|
||||
StringValue: volcengine.String(a.sysPrompt(chatData)),
|
||||
StringValue: volcengine.String(a.sysPrompt(chatData, req)),
|
||||
},
|
||||
}
|
||||
|
||||
message[1] = &model.ChatCompletionMessage{
|
||||
Role: model.ChatMessageRoleUser,
|
||||
Content: &model.ChatCompletionMessageContent{
|
||||
StringValue: volcengine.String("{{chat_content}}"),
|
||||
},
|
||||
}
|
||||
|
||||
message[2] = &model.ChatCompletionMessage{
|
||||
Role: model.ChatMessageRoleAssistant,
|
||||
Role: model.ChatMessageRoleSystem,
|
||||
Content: &model.ChatCompletionMessageContent{
|
||||
StringValue: volcengine.String(a.assistantPrompt(chatData)),
|
||||
},
|
||||
|
|
@ -86,7 +281,28 @@ func (a *AdviceChatBiz) buildBasePrompt(ctx context.Context, chatData *entitys.C
|
|||
return message, nil
|
||||
}
|
||||
|
||||
func (a *AdviceChatBiz) setContent(ctx context.Context, basePromptJson string, content string) ([]*model.ChatCompletionMessage, error) {
|
||||
func (a *AdviceChatBiz) buildBasePromptResponse(ctx context.Context, chatData *entitys.ChatData, req *entitys.AdvicerChatRegistReq) ([]*responses.InputItem, error) {
|
||||
var message = make([]*responses.InputItem, 2)
|
||||
message[0] = &responses.InputItem{
|
||||
Union: &responses.InputItem_EasyMessage{
|
||||
EasyMessage: &responses.ItemEasyMessage{
|
||||
Role: responses.MessageRole_system,
|
||||
Content: &responses.MessageContent{Union: &responses.MessageContent_StringValue{StringValue: a.sysPrompt(chatData, req)}},
|
||||
},
|
||||
},
|
||||
}
|
||||
message[1] = &responses.InputItem{
|
||||
Union: &responses.InputItem_EasyMessage{
|
||||
EasyMessage: &responses.ItemEasyMessage{
|
||||
Role: responses.MessageRole_system,
|
||||
Content: &responses.MessageContent{Union: &responses.MessageContent_StringValue{StringValue: a.assistantPrompt(chatData)}},
|
||||
},
|
||||
},
|
||||
}
|
||||
return message, nil
|
||||
}
|
||||
|
||||
func (a *AdviceChatBiz) setContent(ctx context.Context, basePromptJson string, content string, session *dbmodel.AiAdviceSession) ([]*model.ChatCompletionMessage, error) {
|
||||
promptJson := strings.ReplaceAll(basePromptJson, "{{chat_content}}", content)
|
||||
var basePrompt []*model.ChatCompletionMessage
|
||||
err := json.Unmarshal([]byte(promptJson), &basePrompt)
|
||||
|
|
@ -97,8 +313,14 @@ func (a *AdviceChatBiz) setContent(ctx context.Context, basePromptJson string, c
|
|||
return basePrompt, nil
|
||||
}
|
||||
|
||||
func (a *AdviceChatBiz) sysPrompt(chatData *entitys.ChatData) string {
|
||||
return "【场景】现在你是专业的顾问,我们在聊天软件里面聊天,当前时间是2026/01/30 16:13:30\n【要求】提供的json内容包含顾问,项目,对话技巧,客户信息,请根据json内容进行模仿真人进行对话,** 绝对不能让对方看出来你是ai!**\n【规则】\n1.必须模仿顾问的聊天方式,不能有markdown格式,聊天内容必须贴近聊天软件的正常聊天,非客户要求不要自顾自的介绍项目!开场白不要太长!\n2.不要有任何特殊格式,有比较长的对话内容注意提行\n3.尽量邀约对方来项目上来\n4.不能有任何画外音的文字格式出现!比如(等待对方回复)"
|
||||
func (a *AdviceChatBiz) sysPrompt(chatData *entitys.ChatData, req *entitys.AdvicerChatRegistReq) string {
|
||||
var prompt strings.Builder
|
||||
prompt.WriteString(constants.BasePrompt)
|
||||
prompt.WriteString(req.Mission)
|
||||
prompt.WriteString(constants.BasePrompt2)
|
||||
|
||||
return prompt.String()
|
||||
|
||||
}
|
||||
|
||||
func (a *AdviceChatBiz) assistantPrompt(chatData *entitys.ChatData) string {
|
||||
|
|
@ -115,10 +337,18 @@ func (a *AdviceChatBiz) getChatDataFromStringSessionId(ctx context.Context, sess
|
|||
return cache.Val(), cache.Err()
|
||||
}
|
||||
|
||||
func (a *AdviceChatBiz) callLlm(ctx context.Context, prompt []*model.ChatCompletionMessage, modelName string) (string, error) {
|
||||
res, err := a.hsyq.RequestHsyq(ctx, key, modelName, prompt)
|
||||
func (a *AdviceChatBiz) callLlm(ctx context.Context, request model.ContextChatCompletionRequest, key string) (string, error) {
|
||||
res, err := a.hsyq.ChatWithRequest(ctx, key, request)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return *res.Choices[0].Message.Content.StringValue, nil
|
||||
}
|
||||
|
||||
func (a *AdviceChatBiz) callLlmResponse(ctx context.Context, request []*responses.InputItem, key string, modelName string, id string) (*responses.ResponseObject, error) {
|
||||
res, err := a.hsyq.CreateResponse(ctx, key, modelName, request, id, false)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return res, nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -29,9 +29,9 @@ func NewAdviceClientBiz(
|
|||
}
|
||||
}
|
||||
|
||||
func (a *AdviceClientBiz) Add(ctx context.Context, param *entitys.AdvicerClientAddReq) (err error) {
|
||||
func (a *AdviceClientBiz) Add(ctx context.Context, param *entitys.AdvicerClientAddReq) (id interface{}, err error) {
|
||||
|
||||
_, err = a.mongo.Co(a.AdvicerClientMongo).InsertOne(ctx, &mongo_model.AdvicerClientMongo{
|
||||
res, err := a.mongo.Co(a.AdvicerClientMongo).InsertOne(ctx, &mongo_model.AdvicerClientMongo{
|
||||
ProjectId: param.ProjectId,
|
||||
AdvicerId: param.AdvicerId,
|
||||
PersonalInfo: param.PersonalInfo,
|
||||
|
|
@ -41,8 +41,10 @@ func (a *AdviceClientBiz) Add(ctx context.Context, param *entitys.AdvicerClientA
|
|||
DecisionProfile: param.DecisionProfile,
|
||||
LastUpdateTime: time.Now(),
|
||||
})
|
||||
|
||||
return err
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return res.InsertedID, err
|
||||
}
|
||||
|
||||
func (a *AdviceClientBiz) Update(ctx context.Context, param *entitys.AdvicerrClientUpdateReq) (err error) {
|
||||
|
|
|
|||
|
|
@ -149,7 +149,7 @@ func (a *AdviceFileBiz) callLlm(ctx context.Context, prompt string, modelName st
|
|||
StringValue: volcengine.String(prompt),
|
||||
},
|
||||
}
|
||||
res, err := a.hsyq.RequestHsyq(ctx, key, modelName, message)
|
||||
res, err := a.hsyq.Chat(ctx, key, modelName, message)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,10 +1,11 @@
|
|||
package biz
|
||||
|
||||
import (
|
||||
"ai_scheduler/internal/data/impl"
|
||||
"ai_scheduler/internal/data/model"
|
||||
"ai_scheduler/internal/data/mongo_model"
|
||||
"ai_scheduler/internal/entitys"
|
||||
"ai_scheduler/internal/pkg"
|
||||
"errors"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
|
|
@ -12,26 +13,60 @@ import (
|
|||
|
||||
"go.mongodb.org/mongo-driver/bson"
|
||||
"go.mongodb.org/mongo-driver/bson/primitive"
|
||||
"xorm.io/builder"
|
||||
)
|
||||
|
||||
type AdviceProjectBiz struct {
|
||||
AdvicerProjectMongo *mongo_model.AdvicerProjectMongo
|
||||
mongo *pkg.Mongo
|
||||
AdvicerProjectMongo *mongo_model.AdvicerProjectMongo
|
||||
adviceProjectImpl *impl.AdviceProjectImpl
|
||||
aiAdviceModelSupImpl *impl.AiAdviceModelSupImpl
|
||||
mongo *pkg.Mongo
|
||||
}
|
||||
|
||||
func NewAdviceProjectBiz(
|
||||
advicerProjectMongo *mongo_model.AdvicerProjectMongo,
|
||||
adviceProjectImpl *impl.AdviceProjectImpl,
|
||||
aiAdviceModelSupImpl *impl.AiAdviceModelSupImpl,
|
||||
mongo *pkg.Mongo,
|
||||
) *AdviceProjectBiz {
|
||||
return &AdviceProjectBiz{
|
||||
AdvicerProjectMongo: advicerProjectMongo,
|
||||
mongo: mongo,
|
||||
AdvicerProjectMongo: advicerProjectMongo,
|
||||
mongo: mongo,
|
||||
adviceProjectImpl: adviceProjectImpl,
|
||||
aiAdviceModelSupImpl: aiAdviceModelSupImpl,
|
||||
}
|
||||
}
|
||||
|
||||
func (a *AdviceProjectBiz) Add(ctx context.Context, param *entitys.AdvicerProjectAddReq) (err error) {
|
||||
func (a *AdviceProjectBiz) BaseAdd(ctx context.Context, param *entitys.AdvicerProjectBaseAddReq) (res *entitys.AdvicerProjectBaseAddRes, err error) {
|
||||
add := &model.AiAdviceProject{
|
||||
Name: param.Name,
|
||||
ModelSupID: param.ModelSupId,
|
||||
}
|
||||
err = a.adviceProjectImpl.AddWithData(add)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &entitys.AdvicerProjectBaseAddRes{
|
||||
ProjectId: add.ProjectID,
|
||||
}, err
|
||||
}
|
||||
|
||||
_, err = a.mongo.Co(a.AdvicerProjectMongo).InsertOne(ctx, &mongo_model.AdvicerProjectMongo{
|
||||
func (a *AdviceProjectBiz) BaseUpdate(ctx context.Context, param *entitys.AdvicerProjectBaseUpdateReq) (err error) {
|
||||
if param.ProjectId == 0 {
|
||||
return
|
||||
}
|
||||
cond := builder.NewCond()
|
||||
cond = cond.And(builder.Eq{"project_id": param.ProjectId})
|
||||
err = a.adviceProjectImpl.UpdateByCond(&cond, &model.AiAdviceProject{
|
||||
Name: param.Name,
|
||||
ModelSupID: param.ModelSupId,
|
||||
})
|
||||
return err
|
||||
}
|
||||
|
||||
func (a *AdviceProjectBiz) Add(ctx context.Context, param *entitys.AdvicerProjectAddReq) (id interface{}, err error) {
|
||||
|
||||
res, err := a.mongo.Co(a.AdvicerProjectMongo).InsertOne(ctx, &mongo_model.AdvicerProjectMongo{
|
||||
ProjectId: param.ProjectId,
|
||||
ProjectInfo: param.ProjectInfo,
|
||||
RegionValue: param.RegionValue,
|
||||
|
|
@ -42,22 +77,27 @@ func (a *AdviceProjectBiz) Add(ctx context.Context, param *entitys.AdvicerProjec
|
|||
LastUpdateTime: time.Now(),
|
||||
})
|
||||
|
||||
return err
|
||||
return res.InsertedID, err
|
||||
}
|
||||
|
||||
func (a *AdviceProjectBiz) Update(ctx context.Context, param *entitys.AdvicerrProjectUpdateReq) (err error) {
|
||||
filter := bson.M{}
|
||||
if len(param.Id) == 0 {
|
||||
return errors.New("ID不能为空")
|
||||
if len(param.Id) != 0 {
|
||||
objectID, err := primitive.ObjectIDFromHex(param.Id)
|
||||
if err != nil {
|
||||
return fmt.Errorf("ID转换失败: %w", err)
|
||||
}
|
||||
filter["_id"] = objectID
|
||||
}
|
||||
objectID, err := primitive.ObjectIDFromHex(param.Id)
|
||||
if err != nil {
|
||||
return fmt.Errorf("ID转换失败: %w", err)
|
||||
if param.ProjectId != 0 {
|
||||
|
||||
filter["projectId"] = param.ProjectId
|
||||
}
|
||||
filter["_id"] = objectID
|
||||
|
||||
update := bson.M{
|
||||
"$set": &mongo_model.AdvicerProjectMongo{
|
||||
ProjectId: param.ProjectId,
|
||||
ProjectInfo: param.ProjectInfo,
|
||||
RegionValue: param.RegionValue,
|
||||
CompetitionComparison: param.CompetitionComparison,
|
||||
CoreSellingPoints: param.CoreSellingPoints,
|
||||
|
|
@ -70,7 +110,53 @@ func (a *AdviceProjectBiz) Update(ctx context.Context, param *entitys.AdvicerrPr
|
|||
return res.Err()
|
||||
}
|
||||
|
||||
func (a *AdviceProjectBiz) Info(ctx context.Context, param *entitys.AdvicerProjectInfoReq) (info mongo_model.AdvicerProjectMongo, err error) {
|
||||
func (a *AdviceProjectBiz) Info(ctx context.Context, param *entitys.AdvicerProjectInfoReq) (info *entitys.AdvicerProjectInfoRes, err error) {
|
||||
configInfo, err := a.ConfigInfo(ctx, param)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
baseInfo, err := a.BaseInfo(configInfo.ProjectId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
supInfo, err := a.ModelInfo(baseInfo.ModelSupID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &entitys.AdvicerProjectInfoRes{
|
||||
ConfigInfo: configInfo,
|
||||
Base: baseInfo,
|
||||
ModelInfo: supInfo,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (a *AdviceProjectBiz) BaseInfo(projectId int32) (baseInfo model.AiAdviceProject, err error) {
|
||||
if projectId == 0 {
|
||||
return
|
||||
}
|
||||
cond := builder.NewCond()
|
||||
cond = cond.And(builder.Eq{"project_id": projectId})
|
||||
err = a.adviceProjectImpl.GetOneBySearchToStrut(&cond, &baseInfo)
|
||||
if err != nil {
|
||||
return baseInfo, err
|
||||
}
|
||||
return baseInfo, nil
|
||||
}
|
||||
|
||||
func (a *AdviceProjectBiz) ModelInfo(supId int32) (supInfo model.AiAdviceModelSup, err error) {
|
||||
if supId == 0 {
|
||||
return
|
||||
}
|
||||
cond := builder.NewCond()
|
||||
cond = cond.And(builder.Eq{"sup_id": supId})
|
||||
err = a.aiAdviceModelSupImpl.GetOneBySearchToStrut(&cond, &supInfo)
|
||||
if err != nil {
|
||||
return supInfo, err
|
||||
}
|
||||
return supInfo, nil
|
||||
}
|
||||
|
||||
func (a *AdviceProjectBiz) ConfigInfo(ctx context.Context, param *entitys.AdvicerProjectInfoReq) (info mongo_model.AdvicerProjectMongo, err error) {
|
||||
filter := bson.M{}
|
||||
|
||||
if param.ProjectId != 0 {
|
||||
|
|
|
|||
|
|
@ -29,9 +29,9 @@ func NewAdviceSkillBiz(
|
|||
}
|
||||
}
|
||||
|
||||
func (a *AdviceSkillBiz) VersionAdd(ctx context.Context, param *entitys.AdvicerTalkSkillAddReq) (err error) {
|
||||
func (a *AdviceSkillBiz) VersionAdd(ctx context.Context, param *entitys.AdvicerTalkSkillAddReq) (id interface{}, err error) {
|
||||
|
||||
_, err = a.mongo.Co(a.AdvicerTalkSkillMongo).InsertOne(ctx, &mongo_model.AdvicerTalkSkillMongo{
|
||||
res, err := a.mongo.Co(a.AdvicerTalkSkillMongo).InsertOne(ctx, &mongo_model.AdvicerTalkSkillMongo{
|
||||
ProjectId: param.ProjectId,
|
||||
AdvicerId: param.AdvicerId,
|
||||
Desc: param.Desc,
|
||||
|
|
@ -42,8 +42,10 @@ func (a *AdviceSkillBiz) VersionAdd(ctx context.Context, param *entitys.AdvicerT
|
|||
CommunicationRhythm: param.CommunicationRhythm,
|
||||
LastUpdateTime: time.Now(),
|
||||
})
|
||||
|
||||
return err
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return res.InsertedID, err
|
||||
}
|
||||
|
||||
func (a *AdviceSkillBiz) VersionUpdate(ctx context.Context, param *entitys.AdvicerTalkSkillUpdateReq) (err error) {
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ import (
|
|||
"github.com/volcengine/volcengine-go-sdk/service/arkruntime"
|
||||
"github.com/volcengine/volcengine-go-sdk/service/arkruntime/model"
|
||||
"github.com/volcengine/volcengine-go-sdk/service/arkruntime/model/responses"
|
||||
"github.com/volcengine/volcengine-go-sdk/volcengine"
|
||||
)
|
||||
|
||||
type Hsyq struct {
|
||||
|
|
@ -38,7 +39,7 @@ func (h *Hsyq) getClient(key string) *arkruntime.Client {
|
|||
}
|
||||
|
||||
// 火山引擎
|
||||
func (h *Hsyq) RequestHsyq(ctx context.Context, key string, modelName string, prompt []*model.ChatCompletionMessage) (model.ChatCompletionResponse, error) {
|
||||
func (h *Hsyq) Chat(ctx context.Context, key string, modelName string, prompt []*model.ChatCompletionMessage) (model.ChatCompletionResponse, error) {
|
||||
req := model.CreateChatCompletionRequest{
|
||||
Model: modelName,
|
||||
Messages: prompt,
|
||||
|
|
@ -54,6 +55,68 @@ func (h *Hsyq) RequestHsyq(ctx context.Context, key string, modelName string, pr
|
|||
return resp, err
|
||||
}
|
||||
|
||||
// 火山引擎
|
||||
func (h *Hsyq) ChatWithRequest(ctx context.Context, key string, request model.ContextChatCompletionRequest) (model.ChatCompletionResponse, error) {
|
||||
|
||||
resp, err := h.getClient(key).CreateContextChatCompletion(ctx, request)
|
||||
if err != nil {
|
||||
return model.ChatCompletionResponse{ID: ""}, err
|
||||
}
|
||||
log.Info("token用量:", resp.Usage.TotalTokens, "输入:", resp.Usage.PromptTokens, "输出:", resp.Usage.CompletionTokens)
|
||||
return resp, err
|
||||
}
|
||||
|
||||
func (h *Hsyq) CreateContextCache(ctx context.Context, key string, modelName string, prompt []*model.ChatCompletionMessage) (string, error) {
|
||||
req := model.CreateContextRequest{
|
||||
Model: modelName,
|
||||
Messages: prompt,
|
||||
TTL: volcengine.Int(3600),
|
||||
Mode: model.ContextModeSession,
|
||||
TruncationStrategy: &model.TruncationStrategy{Type: model.TruncationStrategyTypeRollingTokens},
|
||||
}
|
||||
|
||||
resp, err := h.getClient(key).CreateContext(ctx, req)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
log.Info("token用量:", resp.Usage.TotalTokens, "输入:", resp.Usage.PromptTokens, "输出:", resp.Usage.CompletionTokens)
|
||||
return resp.ID, err
|
||||
}
|
||||
|
||||
func (h *Hsyq) CreateResponse(ctx context.Context, key string, modelName string, prompt []*responses.InputItem, id string, isRegis bool) (*responses.ResponseObject, error) {
|
||||
|
||||
req := &responses.ResponsesRequest{
|
||||
Model: modelName,
|
||||
Input: &responses.ResponsesInput{
|
||||
Union: &responses.ResponsesInput_ListValue{
|
||||
ListValue: &responses.InputItemList{ListValue: prompt},
|
||||
},
|
||||
},
|
||||
Stream: new(bool),
|
||||
Thinking: &responses.ResponsesThinking{Type: responses.ThinkingType_disabled.Enum()},
|
||||
}
|
||||
if isRegis {
|
||||
prefix := true
|
||||
req.Caching = &responses.ResponsesCaching{Type: responses.CacheType_enabled.Enum(), Prefix: &prefix}
|
||||
req.ExpireAt = volcengine.Int64(time.Now().Unix() + 3600)
|
||||
}
|
||||
if len(id) != 0 {
|
||||
req.PreviousResponseId = &id
|
||||
//req.Text = &responses.ResponsesText{
|
||||
// Format: &responses.TextFormat{
|
||||
// Type: responses.TextType_json_object,
|
||||
// Schema:
|
||||
// }
|
||||
//}
|
||||
}
|
||||
resp, err := h.getClient(key).CreateResponses(ctx, req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
log.Info("token用量:", resp.Usage.TotalTokens, "输入:", resp.Usage.InputTokens, "输出:", resp.Usage.OutputTokens)
|
||||
return resp, err
|
||||
}
|
||||
|
||||
func (h *Hsyq) RequestHsyqJson(ctx context.Context, key string, modelName string, prompt []*responses.InputItem) (*responses.ResponseObject, error) {
|
||||
req := responses.ResponsesRequest{
|
||||
Model: modelName,
|
||||
|
|
|
|||
|
|
@ -0,0 +1,25 @@
|
|||
package constants
|
||||
|
||||
type SupWay int32
|
||||
|
||||
const (
|
||||
SupWayHsyq SupWay = iota + 1
|
||||
)
|
||||
|
||||
type Mode int32
|
||||
|
||||
const (
|
||||
ModeResponse Mode = 1
|
||||
ModeContext Mode = 2
|
||||
)
|
||||
|
||||
const BasePrompt = `**[场景]**现在你是专业的顾问,我们在聊天软件里面聊天
|
||||
**[要求]**提供的json内容包含顾问,项目,对话技巧,客户信息,请根据json内容进行模仿真人进行对话,** 绝对不能让对方看出来你是ai!**
|
||||
**[规则]**
|
||||
1.必须模仿顾问的聊天方式,不能有markdown格式,聊天内容必须贴近聊天软件的正常聊天,非客户要求不要自顾自的介绍项目!开场白不要太长!
|
||||
2.不要有任何特殊格式,有比较长的对话内容注意提行
|
||||
3.结合[任务内容]信息,若任务状态为"in_progress",则在对话中尽量完成任务;如果任务状态为"completed"或"fail",则主动结束对话,且该轮对话中不再更新任务状态,mission_complete_desc记录最终结果且不再更改。不要每一句对话都包含任务内容,不要目的性太强!
|
||||
4.不能有任何画外音的文字格式出现!比如(等待对方回复)
|
||||
**[任务内容]**`
|
||||
|
||||
const BasePrompt2 = "**[输出格式]**\n- **格式类型**:严格输出json格式字符串,不需要其他任何格式和内容\n- **数据结构**:\n {\n \"result\": \"{{chat_content}}\",\n \"mission\": \"{{mission}}\"\n \"mission_status\": \"{{mission_status}}\",\n \"mission_complete_desc\": \"{{mission_complete_desc}}\"\n }\n\n**[字段说明]**\n1. **result** (字符串)\n - 对应变量:`{{chat_content}}`\n - 内容:顾问的实际对话内容\n - 要求:自然语言回复,面向用户\n\n2. **mission** (字符串)\n - 对应变量:`{{mission}}`\n - 取值:任务内容\n - 说明:需要完成的任务内容\n\n3. **mission_status** (字符串)\n - 对应变量:`{{mission_status}}`\n - 取值:`\"completed\"` 或 `\"in_progress\"` 或 `\"fail\"`\n - 说明:标识当前任务完成状态\n - `\"completed\"`:任务已全部完成\n - `\"in_progress\"`:任务仍在进行中\n - `\"fail\"`:任务失败,客户已经明确拒绝或者对任务内容表达反对\n\n4. **mission_complete_desc** (字符串)\n - 对应变量:`{{mission_complete_desc}}`\n - 内容:根据mission_status提供相应描述\n - 当`mission_status: \"completed\"`时:简要总结任务完成情况\n - 当`mission_status: \"in_progress\"`时:说明下一步需要做什么\n\n**[示例]**\n{\n\"result\": \"需要我给您安排时间吗\",\n\"mission\": \"邀请客户到售楼部\",\n\"mission_status\": \"in_progress\",\n\"mission_complete_desc\": \"需要用户确认什么时候到售楼部\"\n}\n\n{\n\"result\": \"好的,那就周日下午两点,我到时候在售楼部等您,来了记得给我打电话\",\n\"mission_status\": \"completed\",\n\"mission_complete_desc\": \"客户确认周日下午两点到售楼部\"\n}\n\n**[强制要求]**\n1. 必须输出完整、有效的JSON对象\n2. 所有字段均为必需字段,不可省略\n3. JSON格式必须严格正确,无语法错误\n4. `mission_status`只能使用指定的两个值\n5. `result`字段内容需符合对话语境"
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
package impl
|
||||
|
||||
import (
|
||||
"ai_scheduler/internal/data/model"
|
||||
"ai_scheduler/tmpl/dataTemp"
|
||||
"ai_scheduler/utils"
|
||||
)
|
||||
|
||||
type AiAdviceModelSupImpl struct {
|
||||
dataTemp.DataTemp
|
||||
}
|
||||
|
||||
func NewAiAdviceModelSupImpl(db *utils.Db) *AiAdviceModelSupImpl {
|
||||
return &AiAdviceModelSupImpl{
|
||||
DataTemp: *dataTemp.NewDataTemp(db, new(model.AiAdviceModelSup)),
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
package impl
|
||||
|
||||
import (
|
||||
"ai_scheduler/internal/data/model"
|
||||
"ai_scheduler/tmpl/dataTemp"
|
||||
"ai_scheduler/utils"
|
||||
)
|
||||
|
||||
type AiAdviceSessionImpl struct {
|
||||
dataTemp.DataTemp
|
||||
}
|
||||
|
||||
func NewAiAdviceSessionImpl(db *utils.Db) *AiAdviceSessionImpl {
|
||||
return &AiAdviceSessionImpl{
|
||||
DataTemp: *dataTemp.NewDataTemp(db, new(model.AiAdviceSession)),
|
||||
}
|
||||
}
|
||||
|
|
@ -24,4 +24,6 @@ var ProviderImpl = wire.NewSet(
|
|||
NewAdviceTalkImpl,
|
||||
NewAdviceAdvicerVersionImpl,
|
||||
NewAdviceClientImpl,
|
||||
NewAiAdviceSessionImpl,
|
||||
NewAiAdviceModelSupImpl,
|
||||
)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,29 @@
|
|||
// Code generated by gorm.io/gen. DO NOT EDIT.
|
||||
// Code generated by gorm.io/gen. DO NOT EDIT.
|
||||
// Code generated by gorm.io/gen. DO NOT EDIT.
|
||||
|
||||
package model
|
||||
|
||||
import (
|
||||
"time"
|
||||
)
|
||||
|
||||
const TableNameAiAdviceModelSup = "ai_advice_model_sup"
|
||||
|
||||
// AiAdviceModelSup mapped from table <ai_advice_model_sup>
|
||||
type AiAdviceModelSup struct {
|
||||
SupID int32 `gorm:"column:sup_id;primaryKey;autoIncrement:true" json:"sup_id"`
|
||||
SupName string `gorm:"column:sup_name;not null;comment:备注" json:"sup_name"` // 备注
|
||||
SupWay int32 `gorm:"column:sup_way;not null;comment:供应方,1:火山引擎" json:"sup_way"` // 供应方,1:火山引擎
|
||||
Key string `gorm:"column:key;not null" json:"key"`
|
||||
FileModel string `gorm:"column:file_model;not null;comment:文件读取model" json:"file_model"` // 文件读取model
|
||||
JSONModel string `gorm:"column:json_model;not null;comment:json格式处理model" json:"json_model"` // json格式处理model
|
||||
ChatModel string `gorm:"column:chat_model;not null;comment:对话模型" json:"chat_model"` // 对话模型
|
||||
Mode int32 `gorm:"column:mode;not null;comment:模式" json:"mode"` // 模式
|
||||
CreateAt time.Time `gorm:"column:create_at;default:CURRENT_TIMESTAMP" json:"create_at"`
|
||||
}
|
||||
|
||||
// TableName AiAdviceModelSup's table name
|
||||
func (*AiAdviceModelSup) TableName() string {
|
||||
return TableNameAiAdviceModelSup
|
||||
}
|
||||
|
|
@ -12,14 +12,10 @@ const TableNameAiAdviceProject = "ai_advice_project"
|
|||
|
||||
// AiAdviceProject mapped from table <ai_advice_project>
|
||||
type AiAdviceProject struct {
|
||||
ProjectID int32 `gorm:"column:project_id;primaryKey;autoIncrement:true" json:"project_id"`
|
||||
Name string `gorm:"column:name;not null;comment:姓名" json:"name"` // 姓名
|
||||
RegionValue string `gorm:"column:region_value;comment:区域价值话术库" json:"region_value"` // 区域价值话术库
|
||||
CompetitionComparison string `gorm:"column:competition_comparison;comment:竞品对比话术" json:"competition_comparison"` // 竞品对比话术
|
||||
CoreSellingPoints string `gorm:"column:core_selling_points;comment:项目核心卖点" json:"core_selling_points"` // 项目核心卖点
|
||||
SupportingFacilities string `gorm:"column:supporting_facilities;comment:配套体系" json:"supporting_facilities"` // 配套体系
|
||||
DeveloperBacking string `gorm:"column:developer_backing;comment:开发商背书" json:"developer_backing"` // 开发商背书
|
||||
CreateAt time.Time `gorm:"column:create_at;default:CURRENT_TIMESTAMP" json:"create_at"`
|
||||
ProjectID int32 `gorm:"column:project_id;primaryKey;autoIncrement:true" json:"project_id"`
|
||||
Name string `gorm:"column:name;not null;comment:姓名" json:"name"` // 姓名
|
||||
ModelSupID int32 `gorm:"column:model_sup_id;not null;comment:模型提供方配置,关联advicer_model_sup" json:"model_sup_id"` // 模型提供方配置,关联advicer_model_sup
|
||||
CreateAt time.Time `gorm:"column:create_at;default:CURRENT_TIMESTAMP" json:"create_at"`
|
||||
}
|
||||
|
||||
// TableName AiAdviceProject's table name
|
||||
|
|
|
|||
|
|
@ -0,0 +1,32 @@
|
|||
// Code generated by gorm.io/gen. DO NOT EDIT.
|
||||
// Code generated by gorm.io/gen. DO NOT EDIT.
|
||||
// Code generated by gorm.io/gen. DO NOT EDIT.
|
||||
|
||||
package model
|
||||
|
||||
import (
|
||||
"time"
|
||||
)
|
||||
|
||||
const TableNameAiAdviceSession = "ai_advice_session"
|
||||
|
||||
// AiAdviceSession mapped from table <ai_advice_session>
|
||||
type AiAdviceSession struct {
|
||||
ID int32 `gorm:"column:id;primaryKey;autoIncrement:true" json:"id"`
|
||||
SessionID string `gorm:"column:session_id;not null" json:"session_id"`
|
||||
ProjectID int32 `gorm:"column:project_id;not null" json:"project_id"`
|
||||
SupID int32 `gorm:"column:sup_id;not null" json:"sup_id"`
|
||||
AdvicerVersionID string `gorm:"column:advicer_version_id;not null;comment:顾问版本" json:"advicer_version_id"` // 顾问版本
|
||||
ClientID string `gorm:"column:client_id;not null;comment:客户信息id" json:"client_id"` // 客户信息id
|
||||
TalkSkillID string `gorm:"column:talk_skill_id;not null;comment:聊天话术id" json:"talk_skill_id"` // 聊天话术id
|
||||
ContextCache string `gorm:"column:context_cache;not null;comment:上下文缓存信息(火山引擎)" json:"context_cache"` // 上下文缓存信息(火山引擎)
|
||||
Mission string `gorm:"column:mission;not null;comment:任务" json:"mission"` // 任务
|
||||
MissionStatus string `gorm:"column:mission_status;not null;default:1;comment:任务状态" json:"mission_status"` // 任务状态
|
||||
MissionCompleteDesc string `gorm:"column:mission_complete_desc;not null;comment:任务完成描述" json:"mission_complete_desc"` // 任务完成描述
|
||||
CreateAt time.Time `gorm:"column:create_at;default:CURRENT_TIMESTAMP" json:"create_at"`
|
||||
}
|
||||
|
||||
// TableName AiAdviceSession's table name
|
||||
func (*AiAdviceSession) TableName() string {
|
||||
return TableNameAiAdviceSession
|
||||
}
|
||||
|
|
@ -0,0 +1,46 @@
|
|||
package mongo_model
|
||||
|
||||
import (
|
||||
"time"
|
||||
)
|
||||
|
||||
type AdvicerChatHisMongo struct {
|
||||
SessionId string `json:"sessionId" bson:"sessionId"`
|
||||
User string `json:"User" bson:"User"`
|
||||
Assistant Assistant `json:"assistant" bson:"assistant"`
|
||||
InToken int64 `json:"inToken" bson:"inToken"`
|
||||
OutToken int64 `json:"outToken" bson:"outToken"`
|
||||
CreatAt time.Time `json:"creatAt" bson:"creatAt"`
|
||||
}
|
||||
|
||||
func NewAdvicerChatHisMongo() *AdvicerChatHisMongo {
|
||||
return &AdvicerChatHisMongo{}
|
||||
}
|
||||
|
||||
func (a *AdvicerChatHisMongo) MongoTableName() string {
|
||||
return "advicer_chat_his"
|
||||
}
|
||||
|
||||
type AdvicerChatHisMongoEntity struct {
|
||||
User string `json:"user"`
|
||||
Assistant string `json:"assistant"`
|
||||
MissionStatus string `json:"missionStatus"`
|
||||
MissionNext string `json:"missionNext"`
|
||||
CreateAt string `json:"createAt"`
|
||||
}
|
||||
|
||||
func (a *AdvicerChatHisMongo) Entity() AdvicerChatHisMongoEntity {
|
||||
return AdvicerChatHisMongoEntity{
|
||||
User: a.User,
|
||||
Assistant: a.Assistant.Result,
|
||||
MissionStatus: a.Assistant.MissionStatus,
|
||||
MissionNext: a.Assistant.MissionCompleteDesc,
|
||||
CreateAt: a.CreatAt.Format(time.DateTime),
|
||||
}
|
||||
}
|
||||
|
||||
type Assistant struct {
|
||||
Result string `json:"result"`
|
||||
MissionStatus string `json:"mission_status"`
|
||||
MissionCompleteDesc string `json:"mission_complete_desc"`
|
||||
}
|
||||
|
|
@ -7,4 +7,5 @@ var ProviderSetMongo = wire.NewSet(
|
|||
NewAdvicerTalkSkillMongo,
|
||||
NewAdvicerProjectMongo,
|
||||
NewAdvicerClientMongo,
|
||||
NewAdvicerChatHisMongo,
|
||||
)
|
||||
|
|
|
|||
|
|
@ -1,14 +1,17 @@
|
|||
package entitys
|
||||
|
||||
import "ai_scheduler/internal/data/mongo_model"
|
||||
import (
|
||||
"ai_scheduler/internal/data/model"
|
||||
"ai_scheduler/internal/data/mongo_model"
|
||||
)
|
||||
|
||||
type AdvicerInitReq struct {
|
||||
AdvicerID int32 `json:"AdvicerId"`
|
||||
ProjectID int32 `json:"ProjectId"`
|
||||
AdvicerID int32 `json:"advicerId"`
|
||||
ProjectID int32 `json:"projectId"`
|
||||
Name string `json:"name"` // 姓名
|
||||
Birth string `json:"birth"` // 用户名称
|
||||
Gender int32 `json:"gender"` // 1:男,2:女
|
||||
WorkingYears int32 `json:"WorkingYears"` // 工作年限
|
||||
WorkingYears int32 `json:"workingYears"` // 工作年限
|
||||
}
|
||||
|
||||
type AdvicerInfoReq struct {
|
||||
|
|
@ -16,7 +19,7 @@ type AdvicerInfoReq struct {
|
|||
}
|
||||
|
||||
type AdvicerListReq struct {
|
||||
ProjectId int32 `json:"ProjectId"`
|
||||
ProjectId int32 `json:"projectId"`
|
||||
}
|
||||
|
||||
type AdvicerVersionAddReq struct {
|
||||
|
|
@ -92,6 +95,21 @@ type AdvicerTalkSkillInfoReq struct {
|
|||
Id string `json:"id"`
|
||||
}
|
||||
|
||||
type AdvicerProjectBaseAddReq struct {
|
||||
Name string `json:"name"`
|
||||
ModelSupId int32 `json:"modelSupId"`
|
||||
}
|
||||
|
||||
type AdvicerProjectBaseAddRes struct {
|
||||
ProjectId int32 `json:"projectId"`
|
||||
}
|
||||
|
||||
type AdvicerProjectBaseUpdateReq struct {
|
||||
ProjectId int32 `json:"projectId"`
|
||||
Name string `json:"name"`
|
||||
ModelSupId int32 `json:"modelSupId"`
|
||||
}
|
||||
|
||||
type AdvicerProjectAddReq struct {
|
||||
ProjectId int32 `json:"projectId" bson:"projectId"`
|
||||
ProjectInfo mongo_model.ProjectInfo `json:"projectInfo" bson:"projectInfo"`
|
||||
|
|
@ -118,6 +136,12 @@ type AdvicerProjectInfoReq struct {
|
|||
ProjectId int32 `json:"projectId" bson:"projectId"`
|
||||
}
|
||||
|
||||
type AdvicerProjectInfoRes struct {
|
||||
Base model.AiAdviceProject
|
||||
ConfigInfo mongo_model.AdvicerProjectMongo
|
||||
ModelInfo model.AiAdviceModelSup
|
||||
}
|
||||
|
||||
type AdvicerClientAddReq struct {
|
||||
ProjectId int32 `json:"projectId" bson:"projectId"`
|
||||
AdvicerId int32 `json:"advicerId" bson:"advicerId"`
|
||||
|
|
@ -157,6 +181,7 @@ type AdvicerChatRegistReq struct {
|
|||
AdvicerVersionId string `json:"advicerVersionId"`
|
||||
ClientId string `json:"clientId"`
|
||||
TalkSkillId string `json:"talkSkillId"`
|
||||
Mission string `json:"mission"`
|
||||
}
|
||||
|
||||
type AdvicerChatRegistRes struct {
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ func HandleResponse(c *fiber.Ctx, data interface{}, e error) (err error) {
|
|||
case error:
|
||||
err = data.(error)
|
||||
case int, int32, int64, float32, float64, string, bool:
|
||||
c.Response().SetBody([]byte(fmt.Sprintf("%s", data)))
|
||||
c.Response().SetBody([]byte(fmt.Sprintf("%v", data)))
|
||||
case []byte:
|
||||
c.Response().SetBody(data.([]byte))
|
||||
default:
|
||||
|
|
|
|||
|
|
@ -111,11 +111,13 @@ func SetupRoutes(app *fiber.App, ChatService *services.ChatService, sessionServi
|
|||
advicer.Post("skill/list", adviceTalkSkill.TalkSkillList)
|
||||
advicer.Post("skill/add", adviceTalkSkill.TalkSkillAdd)
|
||||
advicer.Post("skill/update", adviceTalkSkill.TalkSkillUpdate)
|
||||
advicer.Post("skill/del", adviceTalkSkill.TalkSkillUpdate)
|
||||
advicer.Post("skill/del", adviceTalkSkill.TalkSkillDel)
|
||||
|
||||
//项目
|
||||
advicer.Post("project/add", adviceProject.Add)
|
||||
advicer.Post("project/update", adviceProject.Update)
|
||||
advicer.Post("project/base/init", adviceProject.BaseInit)
|
||||
advicer.Post("project/base/update", adviceProject.BaseUpdate)
|
||||
advicer.Post("project/info/add", adviceProject.Add)
|
||||
advicer.Post("project/info/update", adviceProject.Update)
|
||||
advicer.Post("project/info", adviceProject.Info)
|
||||
|
||||
//客户
|
||||
|
|
@ -124,7 +126,7 @@ func SetupRoutes(app *fiber.App, ChatService *services.ChatService, sessionServi
|
|||
advicer.Post("client/list", adviceClient.List)
|
||||
advicer.Post("client/del", adviceClient.Del)
|
||||
|
||||
//客户
|
||||
//会话
|
||||
advicer.Post("chat/regis", adviceChat.Regis)
|
||||
advicer.Post("chat/chat", adviceChat.Chat)
|
||||
|
||||
|
|
@ -185,6 +187,9 @@ func registerCommon(c *fiber.Ctx, err error) error {
|
|||
}
|
||||
|
||||
body := c.Response().Body()
|
||||
if c.Locals("skip_response_wrap") == true {
|
||||
return c.JSON(string(body))
|
||||
}
|
||||
var rawData json.RawMessage
|
||||
if len(body) > 0 {
|
||||
if err := json.Unmarshal(body, &rawData); err != nil {
|
||||
|
|
|
|||
|
|
@ -31,7 +31,8 @@ func (d *AdvicerService) AdvicerUpdate(c *fiber.Ctx) error {
|
|||
if err := c.BodyParser(req); err != nil {
|
||||
return err
|
||||
}
|
||||
return d.adviceBiz.Update(c.UserContext(), req)
|
||||
id, err := d.adviceBiz.Update(c.UserContext(), req)
|
||||
return pkg.HandleResponse(c, int(id), err)
|
||||
}
|
||||
|
||||
func (d *AdvicerService) AdvicerList(c *fiber.Ctx) error {
|
||||
|
|
@ -48,7 +49,8 @@ func (d *AdvicerService) AdvicerVersionAdd(c *fiber.Ctx) error {
|
|||
if err := c.BodyParser(req); err != nil {
|
||||
return err
|
||||
}
|
||||
return d.adviceBiz.VersionAdd(c.UserContext(), req)
|
||||
id, err := d.adviceBiz.VersionAdd(c.UserContext(), req)
|
||||
return pkg.HandleResponse(c, id, err)
|
||||
}
|
||||
|
||||
func (d *AdvicerService) AdvicerVersionUpdate(c *fiber.Ctx) error {
|
||||
|
|
|
|||
|
|
@ -53,6 +53,10 @@ func (a *ChatService) Regis(c *fiber.Ctx) error {
|
|||
if len(req.TalkSkillId) == 0 {
|
||||
return errorcode.ParamErr("talkSkillId is empty")
|
||||
}
|
||||
if len(req.Mission) == 0 {
|
||||
return errorcode.ParamErr("misiion is empty")
|
||||
}
|
||||
|
||||
//顾问版本信息
|
||||
versionInfo, err := a.adviceAdvicerBiz.VersionInfo(c.UserContext(), &entitys.AdvicerVersionInfoReq{
|
||||
Id: req.AdvicerVersionId,
|
||||
|
|
@ -68,6 +72,7 @@ func (a *ChatService) Regis(c *fiber.Ctx) error {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
//项目信息
|
||||
projectInfo, err := a.adviceProjectBiz.Info(c.UserContext(), &entitys.AdvicerProjectInfoReq{
|
||||
ProjectId: advicerInfo.ProjectID,
|
||||
|
|
@ -75,6 +80,15 @@ func (a *ChatService) Regis(c *fiber.Ctx) error {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if len(projectInfo.ModelInfo.Key) == 0 {
|
||||
return errorcode.ParamErr("项目未设置模型key")
|
||||
}
|
||||
|
||||
if len(projectInfo.ModelInfo.ChatModel) == 0 {
|
||||
return errorcode.ParamErr("项目未设置模型对话模型")
|
||||
}
|
||||
|
||||
//销售技巧
|
||||
talkSkill, err := a.adviceSkillBiz.Info(c.UserContext(), &entitys.AdvicerTalkSkillInfoReq{
|
||||
Id: req.TalkSkillId,
|
||||
|
|
@ -96,11 +110,12 @@ func (a *ChatService) Regis(c *fiber.Ctx) error {
|
|||
chat := entitys.ChatData{
|
||||
ClientInfo: clientInfo.Entity(),
|
||||
TalkSkill: talkSkill.Entity(),
|
||||
ProjectInfo: projectInfo.Entity(),
|
||||
ProjectInfo: projectInfo.ConfigInfo.Entity(),
|
||||
AdvicerInfo: advicerInfo.Entity(),
|
||||
AdvicerVersion: versionInfo.Entity(),
|
||||
}
|
||||
sessionId, err := a.adviceChatBiz.Regis(c.UserContext(), &chat)
|
||||
sessionId, err := a.adviceChatBiz.Regis(c.UserContext(), &chat, req, projectInfo)
|
||||
|
||||
log.Info(sessionId)
|
||||
return pkg.HandleResponse(c, sessionId, err)
|
||||
}
|
||||
|
|
@ -110,7 +125,28 @@ func (a *ChatService) Chat(c *fiber.Ctx) error {
|
|||
if err := c.BodyParser(req); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if len(req.SessionId) == 0 {
|
||||
return errorcode.ParamErr("SessionId is empty")
|
||||
}
|
||||
if len(req.Content) == 0 {
|
||||
return errorcode.ParamErr("Content is empty")
|
||||
}
|
||||
res, err := a.adviceChatBiz.Chat(c.UserContext(), req)
|
||||
log.Info(res)
|
||||
return pkg.HandleResponse(c, res, err)
|
||||
}
|
||||
|
||||
func (a *ChatService) ChatContext(c *fiber.Ctx) error {
|
||||
req := &entitys.AdvicerChatReq{}
|
||||
if err := c.BodyParser(req); err != nil {
|
||||
return err
|
||||
}
|
||||
if len(req.SessionId) == 0 {
|
||||
return errorcode.ParamErr("SessionId is empty")
|
||||
}
|
||||
if len(req.Content) == 0 {
|
||||
return errorcode.ParamErr("Content is empty")
|
||||
}
|
||||
res, err := a.adviceChatBiz.Chat(c.UserContext(), req)
|
||||
log.Info(res)
|
||||
return pkg.HandleResponse(c, res, err)
|
||||
|
|
|
|||
|
|
@ -31,7 +31,8 @@ func (d *ClientService) Add(c *fiber.Ctx) error {
|
|||
if err := c.BodyParser(req); err != nil {
|
||||
return err
|
||||
}
|
||||
return d.AdviceClientBiz.Add(c.UserContext(), req)
|
||||
id, err := d.AdviceClientBiz.Add(c.UserContext(), req)
|
||||
return pkg.HandleResponse(c, id, err)
|
||||
}
|
||||
|
||||
func (d *ClientService) Update(c *fiber.Ctx) error {
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ package advice
|
|||
import (
|
||||
"ai_scheduler/internal/biz"
|
||||
"ai_scheduler/internal/config"
|
||||
errorcode "ai_scheduler/internal/data/error"
|
||||
"ai_scheduler/internal/entitys"
|
||||
"ai_scheduler/internal/pkg"
|
||||
|
||||
|
|
@ -26,12 +27,33 @@ func NewProjectService(
|
|||
}
|
||||
}
|
||||
|
||||
func (d *ProjectService) BaseInit(c *fiber.Ctx) error {
|
||||
req := &entitys.AdvicerProjectBaseAddReq{}
|
||||
if err := c.BodyParser(req); err != nil {
|
||||
return err
|
||||
}
|
||||
add, err := d.adviceProjectBiz.BaseAdd(c.UserContext(), req)
|
||||
return pkg.HandleResponse(c, add, err)
|
||||
}
|
||||
|
||||
func (d *ProjectService) BaseUpdate(c *fiber.Ctx) error {
|
||||
req := &entitys.AdvicerProjectBaseUpdateReq{}
|
||||
if err := c.BodyParser(req); err != nil {
|
||||
return err
|
||||
}
|
||||
if req.ProjectId == 0 {
|
||||
return errorcode.ParamErr("projectId is empty")
|
||||
}
|
||||
return d.adviceProjectBiz.BaseUpdate(c.UserContext(), req)
|
||||
}
|
||||
|
||||
func (d *ProjectService) Add(c *fiber.Ctx) error {
|
||||
req := &entitys.AdvicerProjectAddReq{}
|
||||
if err := c.BodyParser(req); err != nil {
|
||||
return err
|
||||
}
|
||||
return d.adviceProjectBiz.Add(c.UserContext(), req)
|
||||
id, err := d.adviceProjectBiz.Add(c.UserContext(), req)
|
||||
return pkg.HandleResponse(c, id, err)
|
||||
}
|
||||
|
||||
func (d *ProjectService) Update(c *fiber.Ctx) error {
|
||||
|
|
|
|||
|
|
@ -31,7 +31,8 @@ func (d *TalkSkillService) TalkSkillAdd(c *fiber.Ctx) error {
|
|||
if err := c.BodyParser(req); err != nil {
|
||||
return err
|
||||
}
|
||||
return d.adviceSkillBiz.VersionAdd(c.UserContext(), req)
|
||||
id, err := d.adviceSkillBiz.VersionAdd(c.UserContext(), req)
|
||||
return pkg.HandleResponse(c, id, err)
|
||||
}
|
||||
|
||||
func (d *TalkSkillService) TalkSkillUpdate(c *fiber.Ctx) error {
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
package dataTemp
|
||||
|
||||
import (
|
||||
"ai_scheduler/internal/pkg/mapstructure"
|
||||
"ai_scheduler/utils"
|
||||
"context"
|
||||
"database/sql"
|
||||
|
|
@ -10,7 +9,6 @@ import (
|
|||
|
||||
"github.com/go-kratos/kratos/v2/log"
|
||||
"gorm.io/gorm"
|
||||
|
||||
"xorm.io/builder"
|
||||
)
|
||||
|
||||
|
|
@ -62,18 +60,17 @@ func (k DataTemp) GetById(id int32) (data map[string]interface{}, err error) {
|
|||
}
|
||||
|
||||
func (k DataTemp) Add(data interface{}) (id int, err error) {
|
||||
var primary *PrimaryKey
|
||||
|
||||
add := k.Db.Model(k.Model).Create(data)
|
||||
_ = mapstructure.Decode(data, &primary)
|
||||
return primary.Id, add.Error
|
||||
return 0, add.Error
|
||||
}
|
||||
|
||||
func (k DataTemp) AddWithData(data interface{}) (interface{}, error) {
|
||||
func (k DataTemp) AddWithData(data interface{}) error {
|
||||
result := k.Db.Model(k.Model).Create(data)
|
||||
if result.Error != nil {
|
||||
return data, result.Error
|
||||
return result.Error
|
||||
}
|
||||
return data, nil
|
||||
return nil
|
||||
}
|
||||
|
||||
func (k DataTemp) GetList(cond *builder.Cond, pageBoIn *ReqPageBo) (list []map[string]interface{}, pageBoOut *RespPageBo, err error) {
|
||||
|
|
|
|||
Loading…
Reference in New Issue