feat: 新增FAQ条目答案策略字段,支持'all'和'random'两种模式
This commit is contained in:
@@ -22,6 +22,7 @@ type FAQEntry struct {
|
||||
SimilarQuestions []string `json:"similar_questions"`
|
||||
NegativeQuestions []string `json:"negative_questions"`
|
||||
Answers []string `json:"answers"`
|
||||
AnswerStrategy string `json:"answer_strategy"`
|
||||
IndexMode string `json:"index_mode"`
|
||||
UpdatedAt time.Time `json:"updated_at"`
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
@@ -36,6 +37,7 @@ type FAQEntryPayload struct {
|
||||
SimilarQuestions []string `json:"similar_questions,omitempty"`
|
||||
NegativeQuestions []string `json:"negative_questions,omitempty"`
|
||||
Answers []string `json:"answers"`
|
||||
AnswerStrategy *string `json:"answer_strategy,omitempty"`
|
||||
TagID string `json:"tag_id,omitempty"`
|
||||
TagName string `json:"tag_name,omitempty"`
|
||||
IsEnabled *bool `json:"is_enabled,omitempty"`
|
||||
|
||||
@@ -3990,6 +3990,11 @@ func (s *knowledgeService) chunkToFAQEntry(chunk *types.Chunk, kb *types.Knowled
|
||||
if meta == nil {
|
||||
meta = &types.FAQChunkMetadata{StandardQuestion: chunk.Content}
|
||||
}
|
||||
// 默认使用 all 策略
|
||||
answerStrategy := meta.AnswerStrategy
|
||||
if answerStrategy == "" {
|
||||
answerStrategy = types.AnswerStrategyAll
|
||||
}
|
||||
entry := &types.FAQEntry{
|
||||
ID: chunk.ID,
|
||||
ChunkID: chunk.ID,
|
||||
@@ -4002,6 +4007,7 @@ func (s *knowledgeService) chunkToFAQEntry(chunk *types.Chunk, kb *types.Knowled
|
||||
SimilarQuestions: meta.SimilarQuestions,
|
||||
NegativeQuestions: meta.NegativeQuestions,
|
||||
Answers: meta.Answers,
|
||||
AnswerStrategy: answerStrategy,
|
||||
IndexMode: kb.FAQConfig.IndexMode,
|
||||
UpdatedAt: chunk.UpdatedAt,
|
||||
CreatedAt: chunk.CreatedAt,
|
||||
@@ -4110,11 +4116,22 @@ func (s *knowledgeService) resolveTagID(ctx context.Context, kbID string, payloa
|
||||
}
|
||||
|
||||
func sanitizeFAQEntryPayload(payload *types.FAQEntryPayload) (*types.FAQChunkMetadata, error) {
|
||||
// 处理 AnswerStrategy,默认为 all
|
||||
answerStrategy := types.AnswerStrategyAll
|
||||
if payload.AnswerStrategy != nil && *payload.AnswerStrategy != "" {
|
||||
switch *payload.AnswerStrategy {
|
||||
case types.AnswerStrategyAll, types.AnswerStrategyRandom:
|
||||
answerStrategy = *payload.AnswerStrategy
|
||||
default:
|
||||
return nil, werrors.NewBadRequestError("answer_strategy 必须是 'all' 或 'random'")
|
||||
}
|
||||
}
|
||||
meta := &types.FAQChunkMetadata{
|
||||
StandardQuestion: strings.TrimSpace(payload.StandardQuestion),
|
||||
SimilarQuestions: payload.SimilarQuestions,
|
||||
NegativeQuestions: payload.NegativeQuestions,
|
||||
Answers: payload.Answers,
|
||||
AnswerStrategy: answerStrategy,
|
||||
Version: 1,
|
||||
Source: "faq",
|
||||
}
|
||||
|
||||
+44
-31
@@ -11,12 +11,13 @@ import (
|
||||
|
||||
// FAQChunkMetadata 定义 FAQ 条目在 Chunk.Metadata 中的结构
|
||||
type FAQChunkMetadata struct {
|
||||
StandardQuestion string `json:"standard_question"`
|
||||
SimilarQuestions []string `json:"similar_questions,omitempty"`
|
||||
NegativeQuestions []string `json:"negative_questions,omitempty"`
|
||||
Answers []string `json:"answers,omitempty"`
|
||||
Version int `json:"version,omitempty"`
|
||||
Source string `json:"source,omitempty"`
|
||||
StandardQuestion string `json:"standard_question"`
|
||||
SimilarQuestions []string `json:"similar_questions,omitempty"`
|
||||
NegativeQuestions []string `json:"negative_questions,omitempty"`
|
||||
Answers []string `json:"answers,omitempty"`
|
||||
AnswerStrategy AnswerStrategy `json:"answer_strategy,omitempty"`
|
||||
Version int `json:"version,omitempty"`
|
||||
Source string `json:"source,omitempty"`
|
||||
}
|
||||
|
||||
// GeneratedQuestion 表示AI生成的单个问题
|
||||
@@ -162,37 +163,49 @@ func CalculateFAQContentHash(meta *FAQChunkMetadata) string {
|
||||
return hex.EncodeToString(hash[:])
|
||||
}
|
||||
|
||||
// AnswerStrategy 定义答案返回策略
|
||||
type AnswerStrategy string
|
||||
|
||||
const (
|
||||
// AnswerStrategyAll 返回所有答案
|
||||
AnswerStrategyAll AnswerStrategy = "all"
|
||||
// AnswerStrategyRandom 随机返回一个答案
|
||||
AnswerStrategyRandom AnswerStrategy = "random"
|
||||
)
|
||||
|
||||
// FAQEntry 表示返回给前端的 FAQ 条目
|
||||
type FAQEntry struct {
|
||||
ID string `json:"id"`
|
||||
ChunkID string `json:"chunk_id"`
|
||||
KnowledgeID string `json:"knowledge_id"`
|
||||
KnowledgeBaseID string `json:"knowledge_base_id"`
|
||||
TagID string `json:"tag_id"`
|
||||
IsEnabled bool `json:"is_enabled"`
|
||||
IsRecommended bool `json:"is_recommended"`
|
||||
StandardQuestion string `json:"standard_question"`
|
||||
SimilarQuestions []string `json:"similar_questions"`
|
||||
NegativeQuestions []string `json:"negative_questions"`
|
||||
Answers []string `json:"answers"`
|
||||
IndexMode FAQIndexMode `json:"index_mode"`
|
||||
UpdatedAt time.Time `json:"updated_at"`
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
Score float64 `json:"score,omitempty"`
|
||||
MatchType MatchType `json:"match_type,omitempty"`
|
||||
ChunkType ChunkType `json:"chunk_type"`
|
||||
ID string `json:"id"`
|
||||
ChunkID string `json:"chunk_id"`
|
||||
KnowledgeID string `json:"knowledge_id"`
|
||||
KnowledgeBaseID string `json:"knowledge_base_id"`
|
||||
TagID string `json:"tag_id"`
|
||||
IsEnabled bool `json:"is_enabled"`
|
||||
IsRecommended bool `json:"is_recommended"`
|
||||
StandardQuestion string `json:"standard_question"`
|
||||
SimilarQuestions []string `json:"similar_questions"`
|
||||
NegativeQuestions []string `json:"negative_questions"`
|
||||
Answers []string `json:"answers"`
|
||||
AnswerStrategy AnswerStrategy `json:"answer_strategy"`
|
||||
IndexMode FAQIndexMode `json:"index_mode"`
|
||||
UpdatedAt time.Time `json:"updated_at"`
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
Score float64 `json:"score,omitempty"`
|
||||
MatchType MatchType `json:"match_type,omitempty"`
|
||||
ChunkType ChunkType `json:"chunk_type"`
|
||||
}
|
||||
|
||||
// FAQEntryPayload 用于创建/更新 FAQ 条目的 payload
|
||||
type FAQEntryPayload struct {
|
||||
StandardQuestion string `json:"standard_question" binding:"required"`
|
||||
SimilarQuestions []string `json:"similar_questions"`
|
||||
NegativeQuestions []string `json:"negative_questions"`
|
||||
Answers []string `json:"answers" binding:"required"`
|
||||
TagID string `json:"tag_id"`
|
||||
TagName string `json:"tag_name"`
|
||||
IsEnabled *bool `json:"is_enabled,omitempty"`
|
||||
IsRecommended *bool `json:"is_recommended,omitempty"`
|
||||
StandardQuestion string `json:"standard_question" binding:"required"`
|
||||
SimilarQuestions []string `json:"similar_questions"`
|
||||
NegativeQuestions []string `json:"negative_questions"`
|
||||
Answers []string `json:"answers" binding:"required"`
|
||||
AnswerStrategy *AnswerStrategy `json:"answer_strategy,omitempty"`
|
||||
TagID string `json:"tag_id"`
|
||||
TagName string `json:"tag_name"`
|
||||
IsEnabled *bool `json:"is_enabled,omitempty"`
|
||||
IsRecommended *bool `json:"is_recommended,omitempty"`
|
||||
}
|
||||
|
||||
const (
|
||||
|
||||
Reference in New Issue
Block a user