diff --git a/.run/webook.run.xml b/.run/webook.run.xml
index 62190a4..003a6c5 100644
--- a/.run/webook.run.xml
+++ b/.run/webook.run.xml
@@ -4,6 +4,9 @@
+
+
+
diff --git a/internal/ai/internal/domain/jd.go b/internal/ai/internal/domain/jd.go
index 3365f9c..b82bcf7 100644
--- a/internal/ai/internal/domain/jd.go
+++ b/internal/ai/internal/domain/jd.go
@@ -7,8 +7,8 @@ const (
)
type JDEvaluation struct {
- Score int `json:"score"`
- Analysis string `json:"analysis"`
+ Score float64 `json:"score"`
+ Analysis string `json:"analysis"`
}
type JD struct {
diff --git a/internal/ai/internal/integration/llm_service_test.go b/internal/ai/internal/integration/llm_service_test.go
index 8a66dff..d285f57 100644
--- a/internal/ai/internal/integration/llm_service_test.go
+++ b/internal/ai/internal/integration/llm_service_test.go
@@ -643,21 +643,24 @@ func (s *LLMServiceSuite) TestHandler_AnalysisJD() {
return domain.LLMResponse{
Tokens: 1000,
Amount: 100,
- Answer: `{"score": 7, "analysis": "tech"}`,
+ Answer: `score: 6
+这是技术前景`,
}, nil
}
if request.Biz == "analysis_jd_biz" {
return domain.LLMResponse{
Tokens: 100,
Amount: 200,
- Answer: `{"score": 8, "analysis": "biz"}`,
+ Answer: `score: 7
+这是业务前景`,
}, nil
}
if request.Biz == "analysis_jd_position" {
return domain.LLMResponse{
Tokens: 100,
Amount: 100,
- Answer: `{"score": 5, "analysis": "position"}`,
+ Answer: `score: 8
+这是公司地位`,
}, nil
}
return domain.LLMResponse{}, errors.New("unknown biz")
@@ -675,16 +678,16 @@ func (s *LLMServiceSuite) TestHandler_AnalysisJD() {
assert.Equal(t, web.JDResponse{
Amount: 400,
TechScore: &web.JDEvaluation{
- Score: 7,
- Analysis: "tech",
+ Score: 6,
+ Analysis: "这是技术前景",
},
BizScore: &web.JDEvaluation{
- Score: 8,
- Analysis: "biz",
+ Score: 7,
+ Analysis: "这是业务前景",
},
PosScore: &web.JDEvaluation{
- Score: 5,
- Analysis: "position",
+ Score: 8,
+ Analysis: "这是公司地位",
},
}, resp)
diff --git a/internal/ai/internal/service/jd_service.go b/internal/ai/internal/service/jd_service.go
index b52006b..093e947 100644
--- a/internal/ai/internal/service/jd_service.go
+++ b/internal/ai/internal/service/jd_service.go
@@ -2,7 +2,9 @@ package service
import (
"context"
- "encoding/json"
+ "errors"
+ "strconv"
+ "strings"
"sync/atomic"
"github.com/ecodeclub/webook/internal/ai/internal/domain"
@@ -83,10 +85,18 @@ func (j *jdSvc) analysisJd(ctx context.Context, uid int64, biz string, jd string
if err != nil {
return 0, nil, err
}
- var jdEva domain.JDEvaluation
- err = json.Unmarshal([]byte(resp.Answer), &jdEva)
+ answer := strings.SplitN(resp.Answer, "\n", 2)
+ if len(answer) != 2 {
+ return 0, nil, errors.New("不符合预期的大模型响应")
+ }
+ score := answer[0]
+ scoreNum, err := strconv.ParseFloat(strings.TrimSpace(strings.TrimPrefix(score, "score:")), 64)
if err != nil {
- return 0, nil, err
+ return 0, nil, errors.New("分数返回的数据不对")
}
- return resp.Amount, &jdEva, nil
+
+ return resp.Amount, &domain.JDEvaluation{
+ Score: scoreNum,
+ Analysis: strings.TrimSpace(strings.TrimPrefix(answer[1], "analysis:")),
+ }, nil
}
diff --git a/internal/ai/internal/web/vo.go b/internal/ai/internal/web/vo.go
index da2002b..4735c6b 100644
--- a/internal/ai/internal/web/vo.go
+++ b/internal/ai/internal/web/vo.go
@@ -22,8 +22,8 @@ type JDResponse struct {
}
type JDEvaluation struct {
- Score int `json:"score"`
- Analysis string `json:"analysis"`
+ Score float64 `json:"score"`
+ Analysis string `json:"analysis"`
}
type Config struct {
diff --git a/internal/resume/internal/domain/analysis.go b/internal/resume/internal/domain/analysis.go
index 8a9b66f..7de71b4 100644
--- a/internal/resume/internal/domain/analysis.go
+++ b/internal/resume/internal/domain/analysis.go
@@ -1,12 +1,13 @@
package domain
const (
- BizResumeSkillKeyPoints = "biz_resume_skill_keypoints"
- BizSkillsRewrite = "biz_skills_rewrite"
- BizResumeProjectKeyPoints = "biz_resume_project_keypoints"
- BizResumeProjectRewrite = "biz_resume_project_rewrite"
- BizResumeJobsKeyPoints = "biz_resume_jobs_keypoints"
- BizResumeJobsRewrite = "biz_resume_jobs_rewrite"
+ BizResumeSkillKeyPoints = "biz_resume_skill_keypoints"
+ BizSkillsRewrite = "biz_resume_skill_rewrite"
+ // BizResumeProjectEvaluation 评价项目经历
+ BizResumeProjectEvaluation = "biz_resume_project_evaluation"
+ BizResumeProjectRewrite = "biz_resume_project_rewrite"
+ //BizResumeJobsKeyPoints = "biz_resume_job_keypoints"
+ BizResumeJobsRewrite = "biz_resume_job_rewrite"
)
type ResumeAnalysis struct {
diff --git a/internal/resume/internal/integration/analysis_handler_test.go b/internal/resume/internal/integration/analysis_handler_test.go
index f5c7e87..8009c40 100644
--- a/internal/resume/internal/integration/analysis_handler_test.go
+++ b/internal/resume/internal/integration/analysis_handler_test.go
@@ -47,29 +47,23 @@ func (a *AnalysisTestSuite) SetupSuite() {
Amount: 200,
Answer: fmt.Sprintf("%s:%s", req.Input[0], req.Input[1]),
}, nil
- case domain.BizResumeProjectKeyPoints:
+ case domain.BizResumeProjectEvaluation:
return ai.LLMResponse{
Tokens: 150,
Amount: 150,
- Answer: fmt.Sprintf("project的keypoints %s", req.Input[0]),
+ Answer: fmt.Sprintf("project的评估 %s", req.Input[0]),
}, nil
case domain.BizResumeProjectRewrite:
return ai.LLMResponse{
Tokens: 220,
Amount: 220,
- Answer: fmt.Sprintf("%s:%s", req.Input[0], req.Input[1]),
- }, nil
- case domain.BizResumeJobsKeyPoints:
- return ai.LLMResponse{
- Tokens: 300,
- Amount: 300,
- Answer: fmt.Sprintf("jobs的keypoints %s", req.Input[0]),
+ Answer: fmt.Sprintf("project的重写 %s", req.Input[0]),
}, nil
case domain.BizResumeJobsRewrite:
return ai.LLMResponse{
Tokens: 400,
Amount: 400,
- Answer: fmt.Sprintf("%s:%s", req.Input[0], req.Input[1]),
+ Answer: fmt.Sprintf("工作经历重写%s", req.Input[0]),
}, nil
default:
return ai.LLMResponse{}, errors.New("mock Err")
@@ -107,10 +101,10 @@ func (a *AnalysisTestSuite) TestAnalysis() {
wantCode: 200,
wantResp: test.Result[web.AnalysisResp]{
Data: web.AnalysisResp{
- Amount: 1370,
- RewriteSkills: "resume:skill的keypoints resume",
- RewriteJobs: "resume:jobs的keypoints resume",
- RewriteProject: "resume:project的keypoints resume",
+ Amount: 1070,
+ RewriteSkills: ":skill的keypoints resume",
+ RewriteJobs: "工作经历重写resume",
+ RewriteProject: "project的重写 resume\n## 综合评价\nproject的评估 project的重写 resume",
},
},
},
diff --git a/internal/resume/internal/service/analysis.go b/internal/resume/internal/service/analysis.go
index 2d53c50..781b309 100644
--- a/internal/resume/internal/service/analysis.go
+++ b/internal/resume/internal/service/analysis.go
@@ -35,12 +35,13 @@ func (r *analysisService) Analysis(ctx context.Context, uid int64, resume string
var rewriteSKills, rewriteProject, rewriteJobs string
// 重写技能
eg.Go(func() error {
- keyPointsAmount, keyPoints, err := r.getKeyPoints(ctx, uid, domain.BizResumeSkillKeyPoints, fmt.Sprintf("%s_skills_get_keypoints", tid), resume)
+ keyPointsAmount, keyPoints, err := r.skillKeypoint(ctx, uid, fmt.Sprintf("%s_skills_get_keypoints", tid), resume)
if err != nil {
return err
}
atomic.AddInt64(&amount, keyPointsAmount)
- rewriteSkillsAmount, ans, err := r.rewriteSkills(ctx, uid, fmt.Sprintf("%s_skills_rewrite", tid), keyPoints, resume)
+ // 暂时不需要传入原始简历,不然会严重超时,并且上下文太长,搞崩系统
+ rewriteSkillsAmount, ans, err := r.rewriteSkills(ctx, uid, fmt.Sprintf("%s_skills_rewrite", tid), keyPoints, "")
if err != nil {
return err
}
@@ -50,27 +51,30 @@ func (r *analysisService) Analysis(ctx context.Context, uid int64, resume string
})
// 重写项目
eg.Go(func() error {
- keyPointsAmount, keyPoints, err := r.getKeyPoints(ctx, uid, domain.BizResumeProjectKeyPoints, fmt.Sprintf("%s_project_get_keypoints", tid), resume)
+ rewriteProjectAmount, ans, err := r.rewriteProject(ctx, uid, fmt.Sprintf("%s_project_rewrite", tid), resume)
if err != nil {
return err
}
- atomic.AddInt64(&amount, keyPointsAmount)
- rewriteProjectAmount, ans, err := r.rewriteProject(ctx, uid, fmt.Sprintf("%s_project_rewrite", tid), keyPoints, resume)
+ atomic.AddInt64(&amount, rewriteProjectAmount)
+ evaluationAmt, evaluation, err := r.evaluatePrj(ctx, uid,
+ domain.BizResumeProjectEvaluation,
+ fmt.Sprintf("%s_project_get_evaludation", tid), ans)
if err != nil {
return err
}
- atomic.AddInt64(&amount, rewriteProjectAmount)
- rewriteProject = ans
+ atomic.AddInt64(&amount, evaluationAmt)
+ rewriteProject = fmt.Sprintf("%s\n## 综合评价\n%s", ans, evaluation)
return nil
})
// 重写工作经历
eg.Go(func() error {
- keyPointsAmount, keyPoints, err := r.getKeyPoints(ctx, uid, domain.BizResumeJobsKeyPoints, fmt.Sprintf("%s_jobs_get_keypoints", tid), resume)
- if err != nil {
- return err
- }
- atomic.AddInt64(&amount, keyPointsAmount)
- rewriteJobsAmount, ans, err := r.rewriteJobs(ctx, uid, fmt.Sprintf("%s_jobs_rewrite", tid), keyPoints, resume)
+ // 暂时还不需要提取关键字
+ //keyPointsAmount, keyPoints, err := r.evaluatePrj(ctx, uid, domain.BizResumeJobsKeyPoints, fmt.Sprintf("%s_jobs_get_keypoints", tid), resume)
+ //if err != nil {
+ // return err
+ //}
+ //atomic.AddInt64(&amount, keyPointsAmount)
+ rewriteJobsAmount, ans, err := r.rewriteJobs(ctx, uid, fmt.Sprintf("%s_jobs_rewrite", tid), "", resume)
if err != nil {
return err
}
@@ -92,14 +96,27 @@ func (r *analysisService) Analysis(ctx context.Context, uid int64, resume string
}
-// 提取关键字
-func (r *analysisService) getKeyPoints(ctx context.Context, uid int64, biz, tid, resume string) (int64, string, error) {
- // 首先提取关键字
+func (r *analysisService) evaluatePrj(ctx context.Context, uid int64, biz, tid, rewritePrj string) (int64, string, error) {
aiReq := ai.LLMRequest{
Uid: uid,
Tid: tid,
Biz: biz,
// 标题,标准答案,输入
+ Input: []string{rewritePrj},
+ }
+ resp, err := r.aiSvc.Invoke(ctx, aiReq)
+ if err != nil {
+ return 0, "", err
+ }
+ return resp.Amount, resp.Answer, nil
+}
+
+// 提取关键字
+func (r *analysisService) skillKeypoint(ctx context.Context, uid int64, tid, resume string) (int64, string, error) {
+ aiReq := ai.LLMRequest{
+ Uid: uid,
+ Tid: tid,
+ Biz: domain.BizResumeSkillKeyPoints,
Input: []string{resume},
}
resp, err := r.aiSvc.Invoke(ctx, aiReq)
@@ -131,7 +148,7 @@ func (r *analysisService) rewriteSkills(ctx context.Context, uid int64, tid, key
}
// 重写项目
-func (r *analysisService) rewriteProject(ctx context.Context, uid int64, tid, keyPoints, resume string) (int64, string, error) {
+func (r *analysisService) rewriteProject(ctx context.Context, uid int64, tid, resume string) (int64, string, error) {
aiReq := ai.LLMRequest{
Uid: uid,
Tid: tid,
@@ -139,7 +156,6 @@ func (r *analysisService) rewriteProject(ctx context.Context, uid int64, tid, ke
// 标题,标准答案,输入
Input: []string{
resume,
- keyPoints,
},
}
resp, err := r.aiSvc.Invoke(ctx, aiReq)
diff --git a/ioc/admin.go b/ioc/admin.go
index cb750ee..aba8d06 100644
--- a/ioc/admin.go
+++ b/ioc/admin.go
@@ -18,6 +18,8 @@ import (
"net/http"
"strings"
+ "github.com/ecodeclub/webook/internal/ai"
+
"github.com/ecodeclub/webook/internal/cases"
baguwen "github.com/ecodeclub/webook/internal/question"
@@ -43,7 +45,9 @@ func InitAdminServer(prj *project.AdminHandler,
queSet *baguwen.AdminQuestionSetHandler,
caseHdl *cases.AdminCaseHandler,
caseSetHdl *cases.AdminCaseSetHandler,
- mark *marketing.AdminHandler) AdminServer {
+ mark *marketing.AdminHandler,
+ aiHdl *ai.AdminHandler,
+) AdminServer {
res := egin.Load("admin").Build()
res.Use(cors.New(cors.Config{
ExposeHeaders: []string{"X-Refresh-Token", "X-Access-Token"},
@@ -73,6 +77,7 @@ func InitAdminServer(prj *project.AdminHandler,
que.PrivateRoutes(res.Engine)
caseHdl.PrivateRoutes(res.Engine)
caseSetHdl.PrivateRoutes(res.Engine)
+ aiHdl.RegisterRoutes(res.Engine)
return res
}
diff --git a/ioc/wire.go b/ioc/wire.go
index 30d70fd..2bf3903 100644
--- a/ioc/wire.go
+++ b/ioc/wire.go
@@ -92,7 +92,7 @@ func InitApp() (*App, error) {
wire.FieldsOf(new(*bff.Module), "Hdl"),
resume.InitModule,
wire.FieldsOf(new(*resume.Module), "PrjHdl", "AnalysisHandler"),
- wire.FieldsOf(new(*ai.Module), "Hdl"),
+ wire.FieldsOf(new(*ai.Module), "Hdl", "AdminHandler"),
initLocalActiveLimiterBuilder,
initCronJobs,
diff --git a/ioc/wire_gen.go b/ioc/wire_gen.go
index 1a9234a..9234ffe 100644
--- a/ioc/wire_gen.go
+++ b/ioc/wire_gen.go
@@ -1,6 +1,6 @@
// Code generated by Wire. DO NOT EDIT.
-//go:generate go run -mod=mod github.com/google/wire/cmd/wire
+//go:generate go run github.com/google/wire/cmd/wire
//go:build !wireinject
// +build !wireinject
@@ -143,7 +143,8 @@ func InitApp() (*App, error) {
adminCaseHandler := casesModule.AdminHandler
adminCaseSetHandler := casesModule.AdminSetHandler
adminHandler3 := marketingModule.AdminHdl
- adminServer := InitAdminServer(adminHandler, webAdminHandler, adminHandler2, adminQuestionSetHandler, adminCaseHandler, adminCaseSetHandler, adminHandler3)
+ adminHandler4 := aiModule.AdminHandler
+ adminServer := InitAdminServer(adminHandler, webAdminHandler, adminHandler2, adminQuestionSetHandler, adminCaseHandler, adminCaseSetHandler, adminHandler3, adminHandler4)
closeTimeoutOrdersJob := orderModule.CloseTimeoutOrdersJob
closeTimeoutLockedCreditsJob := creditModule.CloseTimeoutLockedCreditsJob
syncWechatOrderJob := paymentModule.SyncWechatOrderJob