feat(knowledge): multi-query retrieval with LLM query rewrite
Add a shared structured query builder (knowledge_query.go) and switch all generation paths to it, so retrieval queries carry task intent (type, brand, region, keywords, key points) instead of a raw prompt. ResolveContext now rewrites the query into multiple sub-questions via the URL-markdown model, embeds and searches each, and merges/dedupes candidates before rerank; falls back to parsed fallback questions when rewrite is unavailable or returns too few. Resolve logs gain query list, count, and rewrite stage/model for observability. - knowledge_query.go/_test.go: BuildKnowledgeQuery + intent normalization - knowledge_service.go: per-query embed/search loop, query rewrite, logs - template_prompt/template_service/prompt_generate/article_imitation/ kol_generation_worker: adopt the shared query builder - generation_observability: richer task error logging
This commit is contained in:
@@ -718,7 +718,7 @@ func (s *PromptRuleGenerationService) failGeneration(ctx context.Context, job pr
|
||||
now := time.Now()
|
||||
logCtx := promptRuleGenerationJobLogContext(job, stage, "", "failed", GenerationTaskResultFailure)
|
||||
RecordGenerationTaskEvent(GenerationTaskEventFailure, logCtx)
|
||||
LogGenerationTaskWarn(s.logger, "prompt rule generation failed", logCtx, zap.Error(genErr))
|
||||
LogGenerationTaskWarn(s.logger, "prompt rule generation failed", logCtx, GenerationTaskErrorFields(genErr)...)
|
||||
failureTitle := strings.TrimSpace(extractString(job.InputParams, "task_name"))
|
||||
if failureTitle == "" {
|
||||
failureTitle = title
|
||||
@@ -857,41 +857,28 @@ func buildPromptRuleGenerationPrompt(rule *promptRuleGenerationRecord, params ma
|
||||
}
|
||||
|
||||
func buildPromptRuleKnowledgeQuery(rule *promptRuleGenerationRecord, params map[string]interface{}) string {
|
||||
parts := make([]string, 0, 6)
|
||||
intent := knowledgeQueryIntent{
|
||||
TaskType: "自定义生成",
|
||||
Title: firstNonEmptyPromptString(params, "task_name", "title", "topic", "subject"),
|
||||
Topic: firstNonEmptyPromptString(params, "topic", "subject", "title"),
|
||||
BrandName: extractString(params, "brand_name"),
|
||||
PrimaryKeyword: extractString(params, "primary_keyword"),
|
||||
Keywords: mergeKnowledgeQueryKeywords(params["keywords"], params["primary_keyword"]),
|
||||
KeyPoints: extractString(params, "key_points"),
|
||||
Extra: extractString(params, "extra_requirements"),
|
||||
}
|
||||
if rule != nil {
|
||||
if text := strings.TrimSpace(rule.Name); text != "" {
|
||||
parts = append(parts, text)
|
||||
if name := strings.TrimSpace(rule.Name); name != "" {
|
||||
intent.TemplateName = name
|
||||
if intent.Title == "" {
|
||||
intent.Title = name
|
||||
}
|
||||
}
|
||||
if rule.Scene != nil && strings.TrimSpace(*rule.Scene) != "" {
|
||||
parts = append(parts, strings.TrimSpace(*rule.Scene))
|
||||
intent.TaskType = strings.TrimSpace(*rule.Scene)
|
||||
}
|
||||
}
|
||||
if taskName := strings.TrimSpace(extractString(params, "task_name")); taskName != "" {
|
||||
parts = append(parts, taskName)
|
||||
}
|
||||
for _, key := range []string{
|
||||
"title",
|
||||
"topic",
|
||||
"subject",
|
||||
"brand_name",
|
||||
"product_name",
|
||||
"primary_keyword",
|
||||
"key_points",
|
||||
"extra_requirements",
|
||||
} {
|
||||
if text := strings.TrimSpace(extractString(params, key)); text != "" {
|
||||
parts = append(parts, text)
|
||||
}
|
||||
}
|
||||
if keywords := extractStringList(params["keywords"], 16); len(keywords) > 0 {
|
||||
parts = append(parts, strings.Join(keywords, "\n"))
|
||||
}
|
||||
if rule != nil {
|
||||
if text := strings.TrimSpace(rule.PromptContent); text != "" {
|
||||
parts = append(parts, text)
|
||||
}
|
||||
}
|
||||
return strings.Join(parts, "\n")
|
||||
return buildKnowledgeQueryInputText(intent)
|
||||
}
|
||||
|
||||
func extractGenerateCount(extra map[string]interface{}) int {
|
||||
|
||||
Reference in New Issue
Block a user