Skip to content

Commit

Permalink
Cases 案例集和进度功能添加 (#249)
Browse files Browse the repository at this point in the history
* 添加案例集

* 添加候选案例

* 为案例集添加进度

* maka check

* 添加githubrepo
  • Loading branch information
juniaoshaonian authored Aug 7, 2024
1 parent 4ea6f7b commit 0a37181
Show file tree
Hide file tree
Showing 44 changed files with 3,708 additions and 426 deletions.
12 changes: 10 additions & 2 deletions internal/ai/handlers.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,8 +56,16 @@ func InitQuestionExamineHandler(
// log -> cfg -> credit -> record -> question_examine -> platform
builder := biz.NewQuestionExamineBizHandlerBuilder()
common = append(common, builder)
res := biz.NewCombinedBizHandler("question_examine", common, platform)
return res
return biz.NewCombinedBizHandler("question_examine", common, platform)

}
func InitCaseExamineHandler(
common []handler.Builder,
// platform 就是真正的出口
platform handler.Handler) *biz.CompositionHandler {
builder := biz.NewCaseExamineBizHandlerBuilder()
common = append(common, builder)
return biz.NewCombinedBizHandler("case_examine", common, platform)
}

func InitCommonHandlers(log *log.HandlerBuilder,
Expand Down
1 change: 1 addition & 0 deletions internal/ai/internal/domain/llm.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package domain

const BizQuestionExamine = "question_examine"
const BizCaseExamine = "case_examine"

type LLMRequest struct {
Biz string
Expand Down
89 changes: 87 additions & 2 deletions internal/ai/internal/integration/llm_service_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ func (s *LLMServiceSuite) SetupSuite() {
db := testioc.InitDB()
s.db = db
err := dao.InitTables(db)
require.NoError(s.T(), err)
s.NoError(err)
s.logDao = dao.NewGORMLLMLogDAO(db)

// 先插入 BizConfig
Expand All @@ -56,7 +56,16 @@ func (s *LLMServiceSuite) SetupSuite() {
Ctime: now,
Utime: now,
}).Error
assert.NoError(s.T(), err)
s.NoError(err)
err = s.db.Create(&dao.BizConfig{
Biz: domain.BizCaseExamine,
MaxInput: 100,
PromptTemplate: "这是案例 %s,这是用户输入 %s",
KnowledgeId: knowledgeId,
Ctime: now,
Utime: now,
}).Error
s.NoError(err)
}

func (s *LLMServiceSuite) TearDownSuite() {
Expand Down Expand Up @@ -154,6 +163,82 @@ func (s *LLMServiceSuite) TestService() {
}, creditLogModel)
},
},
{
name: "案例测试-成功",
req: domain.LLMRequest{
Biz: domain.BizCaseExamine,
Uid: 123,
Tid: "13",
Input: []string{
"案例1",
"用户输入1",
},
},
assertFunc: assert.NoError,
before: func(t *testing.T,
ctrl *gomock.Controller) (llmHandler.Handler, credit.Service) {
llmHdl := hdlmocks.NewMockHandler(ctrl)
llmHdl.EXPECT().Handle(gomock.Any(), gomock.Any()).
Return(domain.LLMResponse{
Tokens: 100,
Amount: 100,
Answer: "aians",
}, nil)
creditSvc := creditmocks.NewMockService(ctrl)
creditSvc.EXPECT().GetCreditsByUID(gomock.Any(), gomock.Any()).Return(credit.Credit{
TotalAmount: 1000,
}, nil)
creditSvc.EXPECT().TryDeductCredits(gomock.Any(), gomock.Any()).Return(11, nil)
creditSvc.EXPECT().ConfirmDeductCredits(gomock.Any(), int64(123), int64(11)).Return(nil)
return llmHdl, creditSvc
},
after: func(t *testing.T, resp domain.LLMResponse) {
ctx, cancel := context.WithTimeout(context.Background(), time.Second*3)
defer cancel()
// 校验response写入的内容是否正确
assert.Equal(t, domain.LLMResponse{
Tokens: 100,
Amount: 100,
Answer: "aians",
}, resp)
var logModel dao.LLMRecord
err := s.db.WithContext(ctx).Where("tid = ?", "13").First(&logModel).Error
require.NoError(t, err)
logModel.Id = 0
s.assertLog(dao.LLMRecord{
Id: 0,
Tid: "13",
Uid: 123,
Biz: domain.BizCaseExamine,
Tokens: 100,
Amount: 100,
KnowledgeId: knowledgeId,
Input: sqlx.JsonColumn[[]string]{
Valid: true,
Val: []string{
"案例1",
"用户输入1",
},
},
Status: 1,
PromptTemplate: sqlx.NewNullString("这是案例 %s,这是用户输入 %s"),
Answer: sqlx.NewNullString("aians"),
}, logModel)
// 校验credit写入的内容是否正确
var creditLogModel dao.LLMCredit
err = s.db.WithContext(ctx).Where("tid = ?", "13").First(&creditLogModel).Error
require.NoError(t, err)
assert.True(t, creditLogModel.Id != 0)
creditLogModel.Id = 0
s.assertCreditLog(dao.LLMCredit{
Tid: "13",
Uid: 123,
Biz: domain.BizCaseExamine,
Amount: 100,
Status: 1,
}, creditLogModel)
},
},
{
name: "积分不足",
req: domain.LLMRequest{
Expand Down
2 changes: 2 additions & 0 deletions internal/ai/internal/integration/startup/wire.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,9 @@ func InitModule(db *egorm.Component,

func InitHandlerFacade(common []handler.Builder, llm handler.Handler) *biz.FacadeHandler {
que := ai.InitQuestionExamineHandler(common, llm)
ca := ai.InitCaseExamineHandler(common, llm)
return biz.NewHandler(map[string]handler.Handler{
ca.Biz(): ca,
que.Biz(): que,
})
}
Expand Down
4 changes: 3 additions & 1 deletion internal/ai/internal/integration/startup/wire_gen.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

33 changes: 33 additions & 0 deletions internal/ai/internal/service/llm/handler/biz/case_examine.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package biz

import (
"context"
"fmt"
"unicode/utf8"

"github.com/ecodeclub/webook/internal/ai/internal/domain"
"github.com/ecodeclub/webook/internal/ai/internal/service/llm/handler"
)

type CaseExamineBizHandlerBuilder struct {
}

func NewCaseExamineBizHandlerBuilder() *CaseExamineBizHandlerBuilder {
return &CaseExamineBizHandlerBuilder{}
}

func (h *CaseExamineBizHandlerBuilder) Next(next handler.Handler) handler.Handler {
return handler.HandleFunc(func(ctx context.Context, req domain.LLMRequest) (domain.LLMResponse, error) {
title := req.Input[0]
userInput := req.Input[1]
userInputLen := utf8.RuneCount([]byte(userInput))

if userInputLen > req.Config.MaxInput {
return domain.LLMResponse{}, fmt.Errorf("输入太长,最常不超过 %d,现有长度 %d", req.Config.MaxInput, userInputLen)
}
// 把 input 和 prompt 结合起来
prompt := fmt.Sprintf(req.Config.PromptTemplate, title, userInput)
req.Prompt = prompt
return next.Handle(ctx, req)
})
}
22 changes: 22 additions & 0 deletions internal/cases/internal/domain/case_set.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package domain

import "github.com/ecodeclub/ekit/slice"

type CaseSet struct {
ID int64
Uid int64
// 标题
Title string
// 描述
Description string
Biz string
BizId int64
Cases []Case
Utime int64
}

func (set CaseSet) Cids() []int64 {
return slice.Map(set.Cases, func(idx int, src Case) int64 {
return src.Id
})
}
5 changes: 4 additions & 1 deletion internal/cases/internal/domain/cases.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@ type Case struct {
Introduction string
Title string
Content string
CodeRepo string
GithubRepo string
GiteeRepo string
// 关键字,辅助记忆,提取重点
Keywords string
// 速记,口诀
Expand All @@ -24,6 +25,8 @@ type Case struct {
// 引导点
Guidance string
Status CaseStatus
Biz string
BizId int64
Ctime time.Time
Utime time.Time
}
Expand Down
5 changes: 5 additions & 0 deletions internal/cases/internal/domain/const.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package domain

var (
DefaultBiz = "baguwen"
)
31 changes: 31 additions & 0 deletions internal/cases/internal/domain/examine.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package domain

type ExamineCaseResult struct {
Cid int64
Result CaseResult
// 原始回答,源自 AI
RawResult string

// 使用的 token 数量
Tokens int64
// 花费的金额
Amount int64
Tid string
}

type CaseResult uint8

func (r CaseResult) ToUint8() uint8 {
return uint8(r)
}

const (
// ResultFailed 完全没通过,或者完全没有考过,我们不需要区别这两种状态
ResultFailed CaseResult = iota
// ResultBasic 只回答出来了 15K 的部分
ResultBasic
// ResultIntermediate 回答了 25K 部分
ResultIntermediate
// ResultAdvanced 回答出来了 35K 部分
ResultAdvanced
)
2 changes: 2 additions & 0 deletions internal/cases/internal/errs/code.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ package errs

var (
SystemError = ErrorCode{Code: 505001, Msg: "系统错误"}
// InsufficientCredits 这个不管说是客户端错误还是服务端错误,都有点勉强,所以随便用一个 5
InsufficientCredits = ErrorCode{Code: 505002, Msg: "积分不足"}
)

type ErrorCode struct {
Expand Down
6 changes: 4 additions & 2 deletions internal/cases/internal/event/event.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,8 @@ type Case struct {
Labels []string `json:"labels"`
Title string `json:"title"`
Content string `json:"content"`
CodeRepo string `json:"code_repo"`
GithubRepo string `json:"github_repo"`
GiteeRepo string `json:"gitee_repo"`
Keywords string `json:"keywords"`
Shorthand string `json:"shorthand"`
Highlight string `json:"highlight"`
Expand All @@ -59,7 +60,8 @@ func newCase(ca domain.Case) Case {
Labels: ca.Labels,
Title: ca.Title,
Content: ca.Content,
CodeRepo: ca.CodeRepo,
GithubRepo: ca.GithubRepo,
GiteeRepo: ca.GiteeRepo,
Keywords: ca.Keywords,
Shorthand: ca.Shorthand,
Highlight: ca.Highlight,
Expand Down
Loading

0 comments on commit 0a37181

Please sign in to comment.