Compare commits
2 Commits
a155cb1e01
...
e5bbddd58d
| Author | SHA1 | Date |
|---|---|---|
|
|
e5bbddd58d | |
|
|
6c7ee0a666 |
5
go.mod
5
go.mod
|
|
@ -33,6 +33,8 @@ require (
|
|||
github.com/spf13/viper v1.17.0
|
||||
github.com/stretchr/testify v1.11.1
|
||||
github.com/tmc/langchaingo v0.1.13
|
||||
github.com/unidoc/unioffice v1.39.0
|
||||
github.com/volcengine/volcengine-go-sdk v1.2.9
|
||||
github.com/xuri/excelize/v2 v2.10.0
|
||||
golang.org/x/sync v0.17.0
|
||||
google.golang.org/grpc v1.64.0
|
||||
|
|
@ -75,6 +77,7 @@ require (
|
|||
github.com/hashicorp/hcl v1.0.0 // indirect
|
||||
github.com/jinzhu/inflection v1.0.0 // indirect
|
||||
github.com/jinzhu/now v1.1.5 // indirect
|
||||
github.com/jmespath/go-jmespath v0.4.0 // indirect
|
||||
github.com/json-iterator/go v1.1.12 // indirect
|
||||
github.com/klauspost/compress v1.17.9 // indirect
|
||||
github.com/klauspost/cpuid/v2 v2.2.9 // indirect
|
||||
|
|
@ -112,6 +115,7 @@ require (
|
|||
github.com/valyala/bytebufferpool v1.0.0 // indirect
|
||||
github.com/valyala/fasthttp v1.51.0 // indirect
|
||||
github.com/valyala/tcplisten v1.0.0 // indirect
|
||||
github.com/volcengine/volc-sdk-golang v1.0.23 // indirect
|
||||
github.com/wk8/go-ordered-map/v2 v2.1.8 // indirect
|
||||
github.com/xuri/efp v0.0.1 // indirect
|
||||
github.com/xuri/nfp v0.0.2-0.20250530014748-2ddeb826f9a9 // indirect
|
||||
|
|
@ -128,5 +132,6 @@ require (
|
|||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240604185151-ef581f913117 // indirect
|
||||
google.golang.org/protobuf v1.34.1 // indirect
|
||||
gopkg.in/ini.v1 v1.67.0 // indirect
|
||||
gopkg.in/yaml.v2 v2.4.0 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
)
|
||||
|
|
|
|||
18
go.sum
18
go.sum
|
|
@ -101,6 +101,7 @@ github.com/aliyun/credentials-go v1.4.6 h1:CG8rc/nxCNKfXbZWpWDzI9GjF4Tuu3Es14qT8
|
|||
github.com/aliyun/credentials-go v1.4.6/go.mod h1:Jm6d+xIgwJVLVWT561vy67ZRP4lPTQxMbEYRuT2Ti1U=
|
||||
github.com/andybalholm/brotli v1.1.0 h1:eLKJA0d02Lf0mVpIDgYnqXcUn0GqVmEFny3VuID1U3M=
|
||||
github.com/andybalholm/brotli v1.1.0/go.mod h1:sms7XGricyQI9K10gOSf56VKKWS4oLer58Q+mhRPtnY=
|
||||
github.com/avast/retry-go v3.0.0+incompatible/go.mod h1:XtSnn+n/sHqQIpZ10K1qAevBhOOCWBLXXy3hyiqqBrY=
|
||||
github.com/bahlo/generic-list-go v0.2.0 h1:5sz/EEAK+ls5wF+NeqDpk5+iNdMDXrh3z3nPnH1Wvgk=
|
||||
github.com/bahlo/generic-list-go v0.2.0/go.mod h1:2KvAjgMlE5NNynlg/5iLrrCCZ2+5xWbdbCW3pNTGyYg=
|
||||
github.com/bitly/go-simplejson v0.5.0/go.mod h1:cXHtHw4XUPsvGaxgjIAn8PhEWG9NfngEKAMDJEczWVA=
|
||||
|
|
@ -237,6 +238,7 @@ github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvq
|
|||
github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8=
|
||||
github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
|
||||
github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
|
||||
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
|
||||
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
||||
github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
||||
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
|
||||
|
|
@ -248,6 +250,7 @@ github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/
|
|||
github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
|
||||
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
|
||||
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||
|
|
@ -266,6 +269,7 @@ github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLe
|
|||
github.com/google/pprof v0.0.0-20201218002935-b9804c9f04c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
|
||||
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
|
||||
github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
|
||||
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/google/wire v0.7.0 h1:JxUKI6+CVBgCO2WToKy/nQk0sS+amI9z9EjVmdaocj4=
|
||||
|
|
@ -293,6 +297,10 @@ github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD
|
|||
github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc=
|
||||
github.com/jinzhu/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ=
|
||||
github.com/jinzhu/now v1.1.5/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
|
||||
github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg=
|
||||
github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo=
|
||||
github.com/jmespath/go-jmespath/internal/testify v1.5.1 h1:shLQSRRSCCPj3f2gpwzGwWFoC7ycTf1rcQZHOlsJ6N8=
|
||||
github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U=
|
||||
github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y=
|
||||
github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
||||
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
|
||||
|
|
@ -310,6 +318,7 @@ github.com/klauspost/cpuid/v2 v2.2.9/go.mod h1:rqkxqrZ1EhYM9G+hXH7YdowN5R5RGN6NK
|
|||
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||
github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg=
|
||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||
github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
|
||||
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
|
||||
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
|
||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
|
|
@ -443,12 +452,18 @@ github.com/tmc/langchaingo v0.1.13 h1:rcpMWBIi2y3B90XxfE4Ao8dhCQPVDMaNPnN5cGB1Ca
|
|||
github.com/tmc/langchaingo v0.1.13/go.mod h1:vpQ5NOIhpzxDfTZK9B6tf2GM/MoaHewPWM5KXXGh7hg=
|
||||
github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI=
|
||||
github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08=
|
||||
github.com/unidoc/unioffice v1.39.0 h1:Wo5zvrzCqhyK/1Zi5dg8a5F5+NRftIMZPnFPYwruLto=
|
||||
github.com/unidoc/unioffice v1.39.0/go.mod h1:Axz6ltIZZTUUyHoEnPe4Mb3VmsN4TRHT5iZCGZ1rgnU=
|
||||
github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw=
|
||||
github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
|
||||
github.com/valyala/fasthttp v1.51.0 h1:8b30A5JlZ6C7AS81RsWjYMQmrZG6feChmgAolCl1SqA=
|
||||
github.com/valyala/fasthttp v1.51.0/go.mod h1:oI2XroL+lI7vdXyYoQk03bXBThfFl2cVdIA3Xl7cH8g=
|
||||
github.com/valyala/tcplisten v1.0.0 h1:rBHj/Xf+E1tRGZyWIWwJDiRY0zc1Js+CV5DqwacVSA8=
|
||||
github.com/valyala/tcplisten v1.0.0/go.mod h1:T0xQ8SeCZGxckz9qRXTfG43PvQ/mcWh7FwZEA7Ioqkc=
|
||||
github.com/volcengine/volc-sdk-golang v1.0.23 h1:anOslb2Qp6ywnsbyq9jqR0ljuO63kg9PY+4OehIk5R8=
|
||||
github.com/volcengine/volc-sdk-golang v1.0.23/go.mod h1:AfG/PZRUkHJ9inETvbjNifTDgut25Wbkm2QoYBTbvyU=
|
||||
github.com/volcengine/volcengine-go-sdk v1.2.9 h1:du2gnImtyWXKkQFnJW/GXCs+UBibGGOXIbP1Ams2pB8=
|
||||
github.com/volcengine/volcengine-go-sdk v1.2.9/go.mod h1:oxoVo+A17kvkwPkIeIHPVLjSw7EQAm+l/Vau1YGHN+A=
|
||||
github.com/wk8/go-ordered-map/v2 v2.1.8 h1:5h/BUHu93oj4gIdvHHHGsScSTMijfx5PeYkE/fJgbpc=
|
||||
github.com/wk8/go-ordered-map/v2 v2.1.8/go.mod h1:5nJHM5DyteebpVlHnWMV0rPz6Zp7+xBAnxjb1X5vnTw=
|
||||
github.com/x-cray/logrus-prefixed-formatter v0.5.2 h1:00txxvfBM9muc0jiLIEAkAcIMJzfthRT6usrui8uGmg=
|
||||
|
|
@ -839,11 +854,14 @@ google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2
|
|||
google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
||||
google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4=
|
||||
google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
|
||||
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
|
||||
google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
|
||||
google.golang.org/protobuf v1.34.1 h1:9ddQBjfCyZPOHPUiPxpYESBLc+T8P3E+Vo4IbKZgFWg=
|
||||
google.golang.org/protobuf v1.34.1/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos=
|
||||
gopkg.in/bsm/ratelimit.v1 v1.0.0-20160220154919-db14e161995a/go.mod h1:KF9sEfUPAXdG8Oev9e99iLGnl2uJMjc5B+4y3O7x610=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
|
||||
|
|
|
|||
|
|
@ -0,0 +1,153 @@
|
|||
package biz
|
||||
|
||||
import (
|
||||
"ai_scheduler/internal/biz/llm_service/third_party"
|
||||
"ai_scheduler/internal/entitys"
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
"strings"
|
||||
|
||||
"github.com/volcengine/volcengine-go-sdk/service/arkruntime/model"
|
||||
"github.com/volcengine/volcengine-go-sdk/volcengine"
|
||||
)
|
||||
|
||||
type AdviceBiz struct {
|
||||
hsyq *third_party.Hsyq
|
||||
}
|
||||
|
||||
func NewAdviceBiz(hsyq *third_party.Hsyq) *AdviceBiz {
|
||||
return &AdviceBiz{
|
||||
hsyq: hsyq,
|
||||
}
|
||||
}
|
||||
|
||||
const (
|
||||
key = "236ba4b6-9daa-4755-b22f-2fd274cd223a"
|
||||
modelName = "doubao-seed-1-8-251228"
|
||||
)
|
||||
|
||||
var dataMap = map[string]string{
|
||||
"DialectFeatures": (&entitys.DialectFeatures{}).Example(),
|
||||
"SentencePatterns": (&entitys.SentencePatterns{}).Example(),
|
||||
"PersonalityTags": (&entitys.PersonalityTags{}).Example(),
|
||||
"ToneTags": (&entitys.ToneTags{}).Example(),
|
||||
"SignatureDialogues": (&entitys.SignatureDialogues{}).Example(),
|
||||
"RegionValue": (&entitys.RegionValue{}).Example(),
|
||||
"CompetitionComparison": (&entitys.CompetitionComparison{}).Example(),
|
||||
"CoreSellingPoints": (&entitys.CoreSellingPoints{}).Example(),
|
||||
"SupportingFacilities": (&entitys.SupportingFacilities{}).Example(),
|
||||
"DeveloperBacking": (&entitys.DeveloperBacking{}).Example(),
|
||||
"NeedsMining": (&entitys.NeedsMining{}).Example(),
|
||||
"PainPointResponse": (&entitys.PainPointResponse{}).Example(),
|
||||
"ValueBuilding": (&entitys.ValueBuilding{}).Example(),
|
||||
"ClosingTechniques": (&entitys.ClosingTechniques{}).Example(),
|
||||
"CommunicationRhythm": (&entitys.CommunicationRhythm{}).Example(),
|
||||
}
|
||||
|
||||
func (a *AdviceBiz) WordAna(ctx context.Context, wordContent string) error {
|
||||
examples := a.getAllExamples()
|
||||
prompt := a.buildSimplePrompt(wordContent, examples)
|
||||
anaContent, err := a.callLlm(ctx, prompt)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
data := a.parseResponse(anaContent)
|
||||
jsonData, _ := json.MarshalIndent(data, "", " ")
|
||||
os.WriteFile("extracted.json", jsonData, 0644)
|
||||
fmt.Println("✅ 数据已保存到 extracted.json")
|
||||
return nil
|
||||
}
|
||||
|
||||
func (a *AdviceBiz) callLlm(ctx context.Context, prompt string) (string, error) {
|
||||
var message = make([]*model.ChatCompletionMessage, 1)
|
||||
message[0] = &model.ChatCompletionMessage{
|
||||
Role: model.ChatMessageRoleSystem,
|
||||
Content: &model.ChatCompletionMessageContent{
|
||||
StringValue: volcengine.String(prompt),
|
||||
},
|
||||
}
|
||||
|
||||
res, err := a.hsyq.RequestHsyq(ctx, key, modelName, message)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return *res.Choices[0].Message.Content.StringValue, nil
|
||||
}
|
||||
|
||||
func (a *AdviceBiz) getAllExamples() map[string]string {
|
||||
return dataMap
|
||||
}
|
||||
|
||||
func (a *AdviceBiz) buildSimplePrompt(wordContent string, examples map[string]string) string {
|
||||
// 最简单的提示词模板
|
||||
template := `分析以下房地产销售对话,按指定格式提取信息:
|
||||
|
||||
对话内容:
|
||||
%s
|
||||
|
||||
请按照以下` + fmt.Sprintf("%d", len(examples)) + `个格式生成JSON数据,每个格式用===分隔:
|
||||
|
||||
%s
|
||||
|
||||
输出要求:
|
||||
1. 每个结构体一个JSON对象
|
||||
2. 严格按照示例格式
|
||||
3. 用空行分隔不同结构体`
|
||||
|
||||
// 构建格式部分
|
||||
var formats strings.Builder
|
||||
for name, example := range examples {
|
||||
formats.WriteString(fmt.Sprintf("=== %s ===\n示例:%s\n\n", name, example))
|
||||
}
|
||||
|
||||
return fmt.Sprintf(template, wordContent, formats.String())
|
||||
}
|
||||
|
||||
func (a *AdviceBiz) parseResponse(response string) map[string]interface{} {
|
||||
result := make(map[string]interface{})
|
||||
|
||||
// 按空行分割
|
||||
parts := strings.Split(response, "\n\n")
|
||||
|
||||
for _, part := range parts {
|
||||
part = strings.TrimSpace(part)
|
||||
if part == "" || !strings.Contains(part, "{") {
|
||||
continue
|
||||
}
|
||||
|
||||
// 找到第一个 { 和最后一个 }
|
||||
start := strings.Index(part, "{")
|
||||
end := strings.LastIndex(part, "}")
|
||||
|
||||
if start == -1 || end == -1 || end <= start {
|
||||
continue
|
||||
}
|
||||
|
||||
jsonStr := part[start : end+1]
|
||||
|
||||
// 尝试解析
|
||||
var data interface{}
|
||||
if err := json.Unmarshal([]byte(jsonStr), &data); err == nil {
|
||||
// 判断是什么结构体
|
||||
for _, name := range getStructNames() {
|
||||
if strings.Contains(jsonStr, `"`+name+`"`) || strings.Contains(part, name) {
|
||||
result[name] = data
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
func getStructNames() []string {
|
||||
var res = make([]string, 0, len(dataMap))
|
||||
for k, _ := range dataMap {
|
||||
res = append(res, k)
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
|
@ -3,6 +3,7 @@ package biz
|
|||
import (
|
||||
"ai_scheduler/internal/biz/do"
|
||||
"ai_scheduler/internal/biz/llm_service"
|
||||
"ai_scheduler/internal/biz/llm_service/third_party"
|
||||
|
||||
"github.com/google/wire"
|
||||
)
|
||||
|
|
@ -21,4 +22,6 @@ var ProviderSetBiz = wire.NewSet(
|
|||
NewQywxAppBiz,
|
||||
NewGroupConfigBiz,
|
||||
do.NewMacro,
|
||||
NewAdviceBiz,
|
||||
third_party.NewHsyq,
|
||||
)
|
||||
|
|
|
|||
|
|
@ -18,4 +18,7 @@ var ProviderImpl = wire.NewSet(
|
|||
NewBotGroupConfigImpl,
|
||||
NewBotGroupQywxImpl,
|
||||
NewReportDailyCacheImpl,
|
||||
NewAdviceAdvicerImplImpl,
|
||||
NewAdviceProjectImpl,
|
||||
NewAdviceTalkImpl,
|
||||
)
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ type RouterServer struct {
|
|||
// SetupRoutes 设置路由
|
||||
func SetupRoutes(app *fiber.App, ChatService *services.ChatService, sessionService *services.SessionService, task *services.TaskService,
|
||||
gateway *gateway.Gateway, callbackService *services.CallbackService, chatHist *services.HistoryService,
|
||||
capabilityService *services.CapabilityService,
|
||||
capabilityService *services.CapabilityService, advice *services.AdviceService,
|
||||
) {
|
||||
app.Use(func(c *fiber.Ctx) error {
|
||||
// 设置 CORS 头
|
||||
|
|
@ -98,6 +98,9 @@ func SetupRoutes(app *fiber.App, ChatService *services.ChatService, sessionServi
|
|||
// 能力
|
||||
r.Post("/capability/product/ingest", capabilityService.ProductIngest) // 商品数据提取
|
||||
r.Post("/capability/product/ingest/:thread_id/confirm", capabilityService.ProductIngestConfirm) // 商品数据提取确认
|
||||
|
||||
advicer := r.Group("advice/")
|
||||
advicer.Post("file/word", advice.WordAna)
|
||||
}
|
||||
|
||||
func routerSocket(app *fiber.App, chatService *services.ChatService) {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,62 @@
|
|||
package services
|
||||
|
||||
import (
|
||||
"ai_scheduler/internal/biz"
|
||||
"ai_scheduler/internal/config"
|
||||
"ai_scheduler/internal/entitys"
|
||||
"ai_scheduler/internal/pkg/file_download"
|
||||
"context"
|
||||
"errors"
|
||||
|
||||
"net/url"
|
||||
|
||||
"github.com/gofiber/fiber/v2"
|
||||
)
|
||||
|
||||
// ChatHandler 聊天处理器
|
||||
type AdviceService struct {
|
||||
adviceBiz *biz.AdviceBiz
|
||||
cfg *config.Config
|
||||
}
|
||||
|
||||
// NewChatHandler 创建聊天处理器
|
||||
func NewAdviceService(
|
||||
adviceBiz *biz.AdviceBiz,
|
||||
cfg *config.Config,
|
||||
) *AdviceService {
|
||||
return &AdviceService{
|
||||
adviceBiz: adviceBiz,
|
||||
cfg: cfg,
|
||||
}
|
||||
}
|
||||
|
||||
func (a *AdviceService) WordAna(c *fiber.Ctx) error {
|
||||
req := &entitys.WordAnaReq{}
|
||||
if err := c.BodyParser(req); err != nil {
|
||||
return err
|
||||
}
|
||||
// URL 解码
|
||||
fileURL, err := url.PathUnescape(req.WordFileUrl)
|
||||
if err != nil {
|
||||
return errors.New("URL 解码失败")
|
||||
}
|
||||
result, _, err := file_download.GetWordTextFromURL(fileURL, file_download.IsWordFile)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return a.adviceBiz.WordAna(c.UserContext(), result)
|
||||
}
|
||||
|
||||
func (a *AdviceService) WordAnat(path string) error {
|
||||
|
||||
// URL 解码
|
||||
fileURL, err := url.PathUnescape(path)
|
||||
if err != nil {
|
||||
return errors.New("URL 解码失败")
|
||||
}
|
||||
result, _, err := file_download.GetWordTextFromURL(fileURL, file_download.IsWordFile)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return a.adviceBiz.WordAna(context.Background(), result)
|
||||
}
|
||||
|
|
@ -6,6 +6,7 @@ import (
|
|||
dingtalk2 "ai_scheduler/internal/biz/handle/dingtalk"
|
||||
"ai_scheduler/internal/biz/handle/qywx"
|
||||
"ai_scheduler/internal/biz/llm_service"
|
||||
"ai_scheduler/internal/biz/llm_service/third_party"
|
||||
"ai_scheduler/internal/biz/tools_regis"
|
||||
"ai_scheduler/internal/config"
|
||||
"ai_scheduler/internal/data/impl"
|
||||
|
|
@ -29,13 +30,13 @@ import (
|
|||
)
|
||||
|
||||
func Test_Report(t *testing.T) {
|
||||
run()
|
||||
Run()
|
||||
a := cronService.CronReportSendDingTalk(context.Background())
|
||||
t.Log(a)
|
||||
}
|
||||
|
||||
func Test_Report_QYWX(t *testing.T) {
|
||||
run()
|
||||
Run()
|
||||
a := cronService.CronReportSendQywx(context.Background())
|
||||
t.Log(a)
|
||||
}
|
||||
|
|
@ -48,7 +49,7 @@ var (
|
|||
)
|
||||
|
||||
// run 函数是程序的入口函数,负责初始化和配置各个组件
|
||||
func run() {
|
||||
func Run() {
|
||||
// 加载测试配置
|
||||
// configConfig, err = config.LoadConfigWithTest()
|
||||
configConfig, err = config.LoadConfigWithEnv()
|
||||
|
|
@ -62,6 +63,7 @@ func run() {
|
|||
botConfigImpl := impl.NewBotConfigImpl(db)
|
||||
botGroupImpl := impl.NewBotGroupImpl(db)
|
||||
botUserImpl := impl.NewBotUserImpl(db)
|
||||
reportDailyCacheImpl := impl.NewReportDailyCacheImpl(db)
|
||||
// 初始化Do业务对象
|
||||
doDo := do.NewDo(sessionImpl, sysImpl, taskImpl, chatHisImpl, configConfig)
|
||||
// 初始化Ollama客户端
|
||||
|
|
@ -92,7 +94,7 @@ func run() {
|
|||
// 初始化Ollama服务
|
||||
ollamaService := llm_service.NewOllamaGenerate(client, utils_vllmClient, configConfig, chatHisImpl)
|
||||
// 初始化工具管理器
|
||||
manager := tools.NewManager(configConfig, client)
|
||||
manager := tools.NewManager(configConfig, client, rdb)
|
||||
// 初始化钉钉联系人客户端
|
||||
contactClient, _ := dingtalk.NewContactClient(configConfig)
|
||||
// 初始化钉钉记事本客户端
|
||||
|
|
@ -117,11 +119,15 @@ func run() {
|
|||
botGroupConfigImpl := impl.NewBotGroupConfigImpl(db)
|
||||
botGroupQywxImpl := impl.NewBotGroupQywxImpl(db)
|
||||
qywxAuth := qywx.NewAuth(configConfig, rdb)
|
||||
macro := do.NewMacro(botGroupImpl, reportDailyCacheImpl, configConfig, rdb)
|
||||
group := qywx.NewGroup(botGroupQywxImpl, qywxAuth)
|
||||
other := qywx.NewOther(qywxAuth)
|
||||
qywxAppBiz := biz.NewQywxAppBiz(configConfig, botGroupQywxImpl, group, other)
|
||||
groupConfigBiz := biz.NewGroupConfigBiz(toolRegis, utils_ossClient, botGroupConfigImpl, registry, configConfig, impl.NewReportDailyCacheImpl(db), rdb)
|
||||
dingTalkBotBiz := biz.NewDingTalkBotBiz(doDo, handle, botConfigImpl, botGroupImpl, user, botChatHisImpl, impl.NewReportDailyCacheImpl(db), manager, configConfig, sendCardClient, groupConfigBiz)
|
||||
groupConfigBiz := biz.NewGroupConfigBiz(toolRegis, utils_ossClient, botGroupConfigImpl, registry, configConfig, reportDailyCacheImpl, rdb, macro, manager, handle)
|
||||
dingTalkBotBiz := biz.NewDingTalkBotBiz(doDo, handle, botConfigImpl, botGroupImpl, user, botChatHisImpl, reportDailyCacheImpl, manager, configConfig, sendCardClient, groupConfigBiz, macro)
|
||||
// 初始化钉钉机器人服务
|
||||
cronService = NewCronService(configConfig, dingTalkBotBiz, qywxAppBiz, groupConfigBiz)
|
||||
hsyq := third_party.NewHsyq()
|
||||
advicerbiz := biz.NewAdviceBiz(hsyq)
|
||||
advicer = NewAdviceService(advicerbiz, configConfig)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,4 +15,5 @@ var ProviderSetServices = wire.NewSet(
|
|||
NewHistoryService,
|
||||
NewCapabilityService,
|
||||
NewCronService,
|
||||
NewAdviceService,
|
||||
)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,108 @@
|
|||
package test
|
||||
|
||||
import (
|
||||
"runtime"
|
||||
"testing"
|
||||
)
|
||||
|
||||
// 测试用的结构体
|
||||
type Person struct {
|
||||
Name string
|
||||
Age int
|
||||
Address string
|
||||
Email string
|
||||
Phone string
|
||||
Balance float64
|
||||
Active bool
|
||||
}
|
||||
|
||||
// 返回指针
|
||||
func NewPersonPtr(name string, age int) *Person {
|
||||
return &Person{
|
||||
Name: name,
|
||||
Age: age,
|
||||
Address: "Some Address",
|
||||
Email: "test@example.com",
|
||||
Phone: "1234567890",
|
||||
Balance: 1000.0,
|
||||
Active: true,
|
||||
}
|
||||
}
|
||||
|
||||
// 返回值
|
||||
func NewPersonValue(name string, age int) Person {
|
||||
return Person{
|
||||
Name: name,
|
||||
Age: age,
|
||||
Address: "Some Address",
|
||||
Email: "test@example.com",
|
||||
Phone: "1234567890",
|
||||
Balance: 1000.0,
|
||||
Active: true,
|
||||
}
|
||||
}
|
||||
|
||||
var globalPtr *Person
|
||||
var globalValue Person
|
||||
|
||||
func BenchmarkSmallStruct(b *testing.B) {
|
||||
runtime.GC()
|
||||
b.Run("ValueWithSmallStruct", func(b *testing.B) {
|
||||
for i := 0; i < b.N; i++ {
|
||||
p := NewPersonValue("John", 30)
|
||||
globalValue = p
|
||||
}
|
||||
})
|
||||
|
||||
runtime.Gosched()
|
||||
runtime.GC()
|
||||
b.Run("PointerWithSmallStruct", func(b *testing.B) {
|
||||
for i := 0; i < b.N; i++ {
|
||||
p := NewPersonPtr("John", 30)
|
||||
globalPtr = p
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
var globalLargePtr *LargeStruct
|
||||
var globalLargeValue LargeStruct
|
||||
|
||||
func BenchmarkLargeStruct(b *testing.B) {
|
||||
runtime.GC()
|
||||
b.Run("ValueWithLargeStruct", func(b *testing.B) {
|
||||
b.ReportAllocs()
|
||||
for i := 0; i < b.N; i++ {
|
||||
s := NewLargeValue(1)
|
||||
globalLargeValue = s
|
||||
}
|
||||
})
|
||||
|
||||
runtime.Gosched()
|
||||
runtime.GC()
|
||||
b.Run("PointerWithLargeStruct", func(b *testing.B) {
|
||||
b.ReportAllocs()
|
||||
for i := 0; i < b.N; i++ {
|
||||
p := NewLargePtr(1)
|
||||
globalLargePtr = p
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func NewLargePtr(id int) *LargeStruct {
|
||||
return &LargeStruct{
|
||||
ID: id,
|
||||
}
|
||||
}
|
||||
|
||||
// 返回值
|
||||
func NewLargeValue(id int) LargeStruct {
|
||||
return LargeStruct{
|
||||
ID: id,
|
||||
}
|
||||
}
|
||||
|
||||
// Benchmark 大结构体指针
|
||||
type LargeStruct struct {
|
||||
Data [1024]byte
|
||||
ID int
|
||||
}
|
||||
Loading…
Reference in New Issue