Files
prompts-core/service/build_prompt.go

145 lines
4.2 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package service
import (
"context"
"encoding/json"
"errors"
"fmt"
"prompts-core/model/dto"
"prompts-core/model/entity"
"strings"
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/util/gconv"
)
// 获取请求模型的提示词
func GetModelPrompt(ctx context.Context, Type int) string {
return g.Cfg().MustGet(ctx, "modelPrompts.types."+gconv.String(Type), "").String()
}
// 获取构建提示词
func GetBuildPrompt(ctx context.Context, Type int) string {
return g.Cfg().MustGet(ctx, "buildProject.types."+gconv.String(Type), "").String()
}
// buildInferenceRequest 构建返回请求
func buildInferenceRequest(ctx context.Context, req *dto.ComposeMessagesReq, chatModel *entity.AsynchModel, model *entity.AsynchModel, history []map[string]any) (map[string]any, error) {
messages := []map[string]any{}
switch req.BuildType {
//构建提示词请求
case 1:
//1. 构建系统提示词
messages = append(messages, map[string]any{
"role": "system",
"content": promptBuild(ctx, req, model),
})
// 2. 构建历史会话提示词
for _, msg := range history {
role := gconv.String(msg["role"])
content := gconv.String(msg["content"])
if role != "user" && role != "assistant" {
continue
}
messages = append(messages, map[string]any{
"role": role,
"content": content,
})
}
// 3. 当前用户问题(原来的最后一条)
messages = append(messages, map[string]any{
"role": "user",
"content": buildUserPrompt(ctx, req, GetModelPrompt(ctx, model.ModelType)),
})
//构建节点请求
case 2:
messages = append(messages, map[string]any{
"role": "user",
"content": NodeBuid(ctx, req),
})
default:
return nil, errors.New("不支持的构建类型")
}
// 构建请求体
return map[string]any{
"modelName": chatModel.ModelName,
"bizName": "prompts-core",
"callbackUrl": "/prompt/callback",
"requestPayload": map[string]any{
"model": chatModel.ModelName,
"messages": messages,
"stream": false,
},
}, nil
}
// ============================================
// 构建用户提示词
// ============================================
func buildUserPrompt(ctx context.Context, req *dto.ComposeMessagesReq, prompt string) string {
payload := map[string]any{
"model": req.ModelName,
//数据库提示信息
"promptInfo": prompt,
// 系统表单
"form": req.Form,
// 用户表单
"userForm": req.UserForm,
//文件url
"userFiles": req.UserFiles,
//解读文件(只支持可读类型 如xmljson,yaml
"userFilesText": FetchFileTexts(ctx, req.UserFiles),
//skill 相关(根据传入的 skillName 获取 zip 内所有 md 文件拼接内容)
"skills": SkillMdContent(ctx, req.SkillName),
}
return mustMarshal(payload)
}
// promptBuild 提示词构建
func promptBuild(ctx context.Context, req *dto.ComposeMessagesReq, model *entity.AsynchModel) string {
// 1. 从配置文件读取提示词模板
promptTpl := GetBuildPrompt(ctx, req.BuildType)
if promptTpl == "" {
return ""
}
// 2. 构建字段映射说明
mappingBytes, _ := json.Marshal(model.RequestMapping)
mappingStr := string(mappingBytes)
var mapping map[string]string
_ = json.Unmarshal(mappingBytes, &mapping)
var fieldDesc strings.Builder
for key, path := range mapping {
fieldDesc.WriteString(fmt.Sprintf("- %s → %s\n", key, path))
}
// 3. 拼接 UserForm 全文(必须完整阅读)
var userFormContent strings.Builder
for k, v := range req.UserForm {
userFormContent.WriteString(fmt.Sprintf("%s=%v", k, v))
}
userFormFullText := strings.TrimSuffix(userFormContent.String(), "")
// 4. 双表单信息
formInfo := fmt.Sprintf(`
【系统表单(系统提示词/参数)】
%s
【用户表单全文(必须完整阅读,全部作为用户提示词来源)】
%s
`, formToJSON(req.Form), userFormFullText)
// 5. 格式化最终提示词(替换配置里的 %s
return fmt.Sprintf(promptTpl, mappingStr, fieldDesc.String(), formInfo)
}
// NodeBuid 节点构建
func NodeBuid(ctx context.Context, req *dto.ComposeMessagesReq) string {
promptTpl := GetBuildPrompt(ctx, req.BuildType)
if promptTpl == "" {
return ""
}
formStr := formToJSON(req.Form)
userFormStr := formToJSON(req.UserForm)
return fmt.Sprintf(promptTpl, formStr, userFormStr)
}