ai_scheduler/internal/services/capability.go

130 lines
3.7 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 services
import (
"ai_scheduler/internal/config"
errorcode "ai_scheduler/internal/data/error"
"ai_scheduler/internal/pkg/util"
"ai_scheduler/internal/pkg/utils_ollama"
"context"
"fmt"
"strings"
"time"
"github.com/gofiber/fiber/v2"
"github.com/ollama/ollama/api"
)
// CapabilityService 统一回调入口
type CapabilityService struct {
cfg *config.Config
}
func NewCapabilityService(cfg *config.Config) *CapabilityService {
return &CapabilityService{
cfg: cfg,
}
}
// 产品数据提取入参
type ProductIngestReq struct {
Url string `json:"url"` // 商品详情页URL
Title string `json:"title"` // 商品标题
Text string `json:"text"` // 商品描述
Images []string `json:"images"` // 商品图片URL列表
Timestamp int64 `json:"timestamp"` // 商品发布时间戳
}
const (
// 货易通商品属性模板-中文
HYTProductPropertyTemplateZH = `{
"条码": "string", // 商品编号
"分类名称": "string", // 商品分类
"货品名称": "string", // 商品名称
"货品编号": "string", // 商品编号
"商品货号": "string", // 商品编号
"品牌": "string", // 商品品牌
"单位": "string", // 商品单位,若无则使用'个'
"规格参数": "string", // 商品规格参数
"货品说明": "string", // 商品说明
"保质期": "string", // 商品保质期
"保质期单位": "string", // 商品保质期单位
"链接": "string", //
"货品图片": ["string"], // 商品多图取1-2个即可
"电商销售价格": "decimal(10,2)", // 商品电商销售价格
"销售价": "decimal(10,2)", // 商品销售价格
"供应商报价": "decimal(10,2)", // 商品供应商报价
"税率": "number%", // 商品税率 x%
"默认供应商": "", // 空即可
"默认存放仓库": "", // 空即可
"备注": "", // 备注
"长": "string", // 商品长度decimal(10,2)+单位
"宽": "string", // 商品宽度decimal(10,2)+单位
"高": "string", // 商品高度decimal(10,2)+单位
"重量": "string", // 商品重量(kg)
"SPU名称": "string", // 商品SPU名称
"SPU编码": "string" // 编码串jd_{timestamp}_rand(1000-999)
}`
SystemPrompt = `你是一个专业的商品属性提取助手,你的任务是根据用户输入提取商品的属性信息。
目标属性模板:%s。
最终输出格式为纯JSON字符串键值对对应目标属性和提取到的属性值。
最终输出不要携带markdown标识不要携带回车换行`
)
// ProductIngest 产品数据提取
func (s *CapabilityService) ProductIngest(c *fiber.Ctx) error {
// 读取头
token := strings.TrimSpace(c.Get("X-Source-Key"))
ts := strings.TrimSpace(c.Get("X-Timestamp"))
// 时间窗口校验
if ts != "" && !util.IsInTimeWindow(ts, 5*time.Minute) {
// return errorcode.AuthNotFound
}
// token校验
if token == "" || token != "A7f9KQ3mP2X8LZC4R5e" {
// return errorcode.KeyErr()
}
// 解析请求参数
req := ProductIngestReq{}
if err := c.BodyParser(&req); err != nil {
return errorcode.ParamErr("invalid request body: %v", err)
}
// 必要参数校验
if req.Text == "" {
return errorcode.ParamErr("missing required fields")
}
// 模型调用
client, cleanup, err := utils_ollama.NewClient(s.cfg)
if err != nil {
return err
}
defer cleanup()
res, err := client.Chat(context.Background(), []api.Message{
{
Role: "system",
Content: fmt.Sprintf(SystemPrompt, HYTProductPropertyTemplateZH),
},
{
Role: "user",
Content: req.Text,
},
{
Role: "user",
Content: "商品图片URL列表" + strings.Join(req.Images, ","),
},
})
if err != nil {
return err
}
// 解析模型输出
c.JSON(res.Message.Content)
return nil
}